#include "pch.h" #include "consoledata.h" ///////////////////////////////////////////////////////////////////////////// // // ModelData // ///////////////////////////////////////////////////////////////////////////// ImodelIGC* ModelData::GetModel() { return (m_pmodel && m_pmodel->GetMission()) ? ((m_pmodel->GetObjectType() == OT_ship) ? ((IshipIGC*)(ImodelIGC*)m_pmodel)->GetSourceShip() : m_pmodel) : NULL; } ObjectType ModelData::GetModelTypeInternal() { ImodelIGC* pmodel = GetModel(); return pmodel ? pmodel->GetObjectType() : OT_invalid; } float ModelData::GetModelType() { return (float)GetModelTypeInternal(); } static ZString s_empty(""); static ZString s_unknown("unknown"); ZString ModelData::GetModelTypeDesc() { ImodelIGC* pmodel = GetModel(); if (pmodel) { IclusterIGC* pcluster = pmodel->GetCluster(); if (pcluster && trekClient.GetShip()->CanSee(pmodel)) return ::GetModelType(pmodel); else if (pmodel->GetObjectType() == OT_ship) { PlayerInfo* ppi = (PlayerInfo*)(((IshipIGC*)pmodel)->GetPrivateData()); HullID hid = ppi->LastSeenShipType(); if (hid != NA) return trekClient.m_pCoreIGC->GetHullType(hid)->GetName(); } } return s_unknown; } TRef ModelData::GetModelTypeIcon() { return Image::GetEmpty(); } ZString ModelData::GetName() { return m_pmodel ? ZString(::GetModelName(m_pmodel)) : s_empty; } ZString ModelData::GetSectorName() { ImodelIGC* pmodel = GetModel(); if (pmodel) { IclusterIGC* pcluster = pmodel->GetCluster(); if (pcluster && trekClient.GetShip()->CanSee(pmodel)) return pcluster->GetName(); else if (pmodel->GetObjectType() == OT_ship) { PlayerInfo* ppi = (PlayerInfo*)(((IshipIGC*)pmodel)->GetPrivateData()); SectorID sid = ppi->LastSeenSector(); if (sid != NA) return trekClient.m_pCoreIGC->GetCluster(sid)->GetName(); } } return s_unknown; } ZString ModelData::GetSideName() { if (m_pmodel) { IsideIGC* pside = m_pmodel->GetSide(); return pside ? ZString(pside->GetName()) : s_empty; } return s_empty; } Color ModelData::GetSideColor() { if (m_pmodel) { IsideIGC* pside = m_pmodel->GetSide(); if (pside) return pside->GetColor(); } return Color(1,1,1); } TRef ModelData::GetSideIcon() { return Image::GetEmpty(); } float ModelData::GetSpeed() { float speed = 0.0f; ImodelIGC* pmodel = GetModel(); if (pmodel && ((pmodel->GetAttributes() & c_mtStatic) == 0)) { IclusterIGC* pcluster = pmodel->GetCluster(); if (pcluster && trekClient.GetShip()->CanSee(pmodel)) speed = pmodel->GetVelocity().Length(); else speed = -1.0f; } return speed; } float ModelData::GetMass() { ImodelIGC* pmodel = GetModel(); return pmodel ? pmodel->GetMass() : 0.f; } float ModelData::GetRange() { float range = -1.0f; ImodelIGC* pmodel = GetModel(); if (pmodel) { IclusterIGC* pcluster = pmodel->GetCluster(); if (pcluster && trekClient.GetShip()->CanSee(pmodel) && (pcluster == trekClient.GetCluster())) { float fSeparation = (pmodel->GetPosition() - trekClient.GetShip()->GetSourceShip()->GetPosition()).Length(); // this is the same code used in radar image. There is something about the rounding mode that // keeps me from being able to just use floorf instead of the cast to int... range = float (int (fSeparation + 0.5f)); } } return range; } float ModelData::GetPercentHitPoints() { ImodelIGC* pmodel = GetModel(); float f = 0.0f; if (pmodel && ((pmodel->GetAttributes() & c_mtDamagable) != 0)) { IclusterIGC* pcluster = pmodel->GetCluster(); if (pcluster && trekClient.GetShip()->CanSee(pmodel) && ((pmodel->GetCluster() == trekClient.GetCluster()) || (pmodel == trekClient.GetShip()->GetStation()))) f = ((IdamageIGC*)pmodel)->GetFraction(); /* //NYI special case for unknown else f = -1.0f; */ } return f; } float ModelData::GetPercentShields() { ImodelIGC* pmodel = GetModel(); float f = 0.0f; if (pmodel) { ObjectType type = pmodel->GetObjectType(); if (type == OT_ship) { IshipIGC* pship = GetShip(); IclusterIGC* pcluster = pship->GetCluster(); if (pcluster && trekClient.GetShip()->CanSee(pship)) { IshieldIGC* pshield = (IshieldIGC*)(pship->GetMountedPart(ET_Shield, 0)); if (pshield) f = pshield->GetFraction(); } /* //NYI special case for unknown else f = -1.0f; */ } else if (type == OT_station) { assert (pmodel->GetCluster()); if (trekClient.GetShip()->CanSee(pmodel) && ((pmodel->GetCluster() == trekClient.GetCluster()) || (pmodel == trekClient.GetShip()->GetStation()))) f = GetStation()->GetShieldFraction(); /* else f = -1.0f; */ } } return f; } float ModelData::GetPercentEnergy() { ObjectType ot = GetModelTypeInternal(); switch (ot) { case OT_ship: return GetShip()->GetEnergy()/GetShip()->GetHullType()->GetMaxEnergy(); default: return 0.f; } } float ModelData::GetAmmo() { ObjectType ot = GetModelTypeInternal(); switch (ot) { case OT_ship: { IshipIGC* pship = GetShip(); const IhullTypeIGC* phullType = pship->GetHullType(); return (float)pship->GetAmmo() / (float)phullType->GetMaxAmmo(); } break; default: return 0; break; } } float ModelData::GetFuel() { ObjectType ot = GetModelTypeInternal(); switch (ot) { case OT_ship: { IshipIGC* pship = GetShip(); const IhullTypeIGC* phullType = pship->GetHullType(); return (float)pship->GetFuel() / (float)phullType->GetMaxFuel(); } break; default: return 0; break; } } float ModelData::GetOre() { ObjectType ot = GetModelTypeInternal(); switch (ot) { case OT_asteroid: return GetAsteroid()->GetOre(); default: return 0.f; } } float ModelData::GetVectorLock() { float vl = 0.0f; if (m_pmodel && m_pmodel->GetObjectType() == OT_ship && (((IshipIGC*)(ImodelIGC*)m_pmodel)->GetParentShip() == NULL)) { vl = ((IshipIGC*)(ImodelIGC*)m_pmodel)->GetVectorLock(); } return vl; } float ModelData::GetCloaking() { float vl = 0.0f; if (m_pmodel && m_pmodel->GetObjectType() == OT_ship && (((IshipIGC*)(ImodelIGC*)m_pmodel)->GetParentShip() == NULL)) { vl = 100.0f * (1.0f - ((IshipIGC*)(ImodelIGC*)m_pmodel)->GetCloaking()); } return vl; } float ModelData::GetNumObservers() { ObjectType ot = GetModelTypeInternal(); switch (ot) { case OT_ship: { int nObservers = 0; for (ShipLinkIGC* psl = GetShip()->GetChildShips()->first(); (psl != NULL); psl = psl->next()) { IshipIGC* pship = psl->data(); if (pship->GetTurretID() == NA) { nObservers++; } } return (float)nObservers; } default: return 0.0f; } } float ModelData::GetRipcordTimeLeft() { ObjectType ot = GetModelTypeInternal(); switch (ot) { case OT_ship: if (GetShip()->fRipcordActive()) return max(1 + (int)trekClient.GetShip()->GetSourceShip()->GetRipcordTimeLeft(), 0); else return 0.0f; default: return 0.0f; } } float ModelData::GetEndurance() { ObjectType ot = GetModelTypeInternal(); switch (ot) { case OT_ship: return GetShip()->GetEndurance(); default: return 1.0f; } } float ModelData::GetSignature() { ImodelIGC* pmodel = GetModel(); return pmodel ? (100.0f * pmodel->GetSignature()) : 100.0f; } float ModelData::IsCloaked() { ObjectType ot = GetModelTypeInternal(); switch (ot) { case OT_ship: return GetShip()->GetCloaking() < 1.0f ? 1.0f : 0.0f; default: return 0.0f; } } float ModelData::IsEjectPod() { ObjectType ot = GetModelTypeInternal(); switch (ot) { case OT_ship: if (GetShip()->GetBaseHullType()->HasCapability(c_habmLifepod) && GetShip()->GetCluster()) return 1.0f; else return 0.0f; default: return 0.0f; } } float ModelData::IsRipcording() { ObjectType ot = GetModelTypeInternal(); switch (ot) { case OT_ship: return (GetShip()->fRipcordActive() ? 1.0f : 0.0f); default: return 0.0f; } } bool ModelData::IsNotNull() { return m_pmodel != NULL; } bool ModelData::IsVisible() { ImodelIGC* pmodel = GetModel(); return pmodel && trekClient.GetShip()->CanSee(pmodel); } ///////////////////////////////////////////////////////////////////////////// // // PartWrapper // ///////////////////////////////////////////////////////////////////////////// ZString PartWrapper::GetPartName() { return m_ppart ? m_ppart->GetPartType()->GetName() : ""; } float PartWrapper::GetRange() { if (!m_ppart) return 0; EquipmentType et = m_ppart->GetPartType()->GetEquipmentType(); if (et == ET_Weapon) { IprojectileTypeIGC* ppt = ((IweaponIGC*)(IpartIGC*)m_ppart)->GetProjectileType(); float range = ppt->GetSpeed()*ppt->GetLifespan(); const GlobalAttributeSet& ga = trekClient.GetSide()->GetGlobalAttributeSet(); range *= ga.GetAttribute((((IweaponIGC*)(IpartIGC*)m_ppart)->GetAmmoPerShot()) ? c_gaSpeedAmmo : c_gaLifespanEnergy); return range; } else if (et == ET_Magazine) { ImissileTypeIGC* pmt = (ImissileTypeIGC*)((IlauncherTypeIGC*)m_ppart->GetPartType())->GetExpendableType(); float range = pmt->GetLifespan()*(pmt->GetInitialSpeed()+0.5f*pmt->GetLifespan()*pmt->GetAcceleration()); return range; } else { ZAssert(false); return 0; } } float PartWrapper::GetDamage() { if (!m_ppart) return 0; EquipmentType et = m_ppart->GetPartType()->GetEquipmentType(); const GlobalAttributeSet& ga = trekClient.GetSide()->GetGlobalAttributeSet(); if (et == ET_Weapon) { IprojectileTypeIGC* ppt = ((IweaponIGC*)(IpartIGC*)m_ppart)->GetProjectileType(); return (ppt->GetPower() + ppt->GetBlastPower()) * ga.GetAttribute(c_gaDamageGuns); } else if (et == ET_Magazine) { ImissileTypeIGC* pmt = (ImissileTypeIGC*)((IlauncherTypeIGC*)m_ppart->GetPartType())->GetExpendableType(); return (pmt->GetPower() + pmt->GetBlastPower()) * ga.GetAttribute(c_gaDamageMissiles); } else { ZAssert(false); return 0; } } float PartWrapper::GetRate() { if (!m_ppart) return 0; EquipmentType et = m_ppart->GetPartType()->GetEquipmentType(); if (et == ET_Weapon) { DataWeaponTypeIGC* pdwt = (DataWeaponTypeIGC*)((IpartTypeIGC*)m_ppart->GetPartType())->GetData(); return (1.0f /pdwt->dtimeBurst); } else { ZAssert(false); return 0; } } float PartWrapper::GetCount() { if (!m_ppart) return 0; else { ObjectType ot = m_ppart->GetObjectType(); if (m_ppart->GetShip() && m_ppart->GetMountID() < 0) { float fCount = 0.0f; IpartTypeIGC *ppartType = m_ppart->GetPartType(); // add up all of the instances of this in the cargo for (Mount mount = -1; mount >= -c_maxCargo; --mount) { IpartIGC* ppart = m_ppart->GetShip()->GetMountedPart(NA, mount); if (ppart && ppart->GetPartType() == ppartType) { fCount += ppart->GetAmount(); } } if (m_ppart->GetObjectType() == OT_pack) { IpackIGC* p = (IpackIGC*)(IpartIGC*)m_ppart; const IhullTypeIGC *pht = m_ppart->GetShip()->GetHullType(); if (pht && p->GetPackType() == c_packAmmo) { fCount /= pht->GetMaxAmmo(); } else { fCount /= pht->GetMaxFuel(); } } return fCount; } else return (float)(m_ppart->GetAmount()); } } float PartWrapper::GetAfterburnerFuelConsumption() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Afterburner) { IafterburnerIGC* pa = (IafterburnerIGC*)(IpartIGC*)m_ppart; return pa->GetFuelConsumption() * pa->GetMaxThrust(); } else { ZAssert(false); return 0; } } float PartWrapper::GetAfterburnerFuelLeft() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Afterburner) { IafterburnerIGC* pa = (IafterburnerIGC*)(IpartIGC*)m_ppart; IshipIGC* pship = trekClient.GetShip()->GetSourceShip(); return pship->GetFuel() / (pa->GetFuelConsumption() * pa->GetMaxThrust()); } else { ZAssert(false); return 0; } } float PartWrapper::GetAfterburnerTopSpeed() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Afterburner) { IafterburnerIGC* pa = (IafterburnerIGC*)(IpartIGC*)m_ppart; const IhullTypeIGC* pht = trekClient.GetShip()->GetSourceShip()->GetHullType(); float maxAfterburnerThrust = pa->GetMaxThrust(); float thrust = pht->GetThrust(); return pht->GetMaxSpeed() * (1.0f + (maxAfterburnerThrust / thrust)); } else { ZAssert(false); return 0; } } float PartWrapper::GetAfterburnerTimeLeft() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Afterburner) { IafterburnerIGC* pa = (IafterburnerIGC*)(IpartIGC*)m_ppart; const IhullTypeIGC* pht = trekClient.GetShip()->GetSourceShip()->GetHullType(); float fuel = trekClient.GetShip()->GetFuel(); float fuelConsumption = pa->GetFuelConsumption(); if (fuelConsumption <= 0){ return -1.0f; } else return fuel / (fuelConsumption * pa->GetMaxThrust()); } else { ZAssert(false); return 0; } } float PartWrapper::GetMaxShieldStrength() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Shield) { IshieldIGC* pshield = (IshieldIGC*)(IpartIGC*)m_ppart; return pshield->GetMaxStrength(); } else { ZAssert(false); return 0; } } float PartWrapper::GetShieldStrength() { float f = 0.0f; if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Shield) { IshieldIGC* pshield = (IshieldIGC*)(IpartIGC*)m_ppart; f = pshield->GetFraction(); return f * pshield->GetMaxStrength(); } else { ZAssert(false); return 0; } } float PartWrapper::GetRegenRate() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Shield) { IshieldIGC* pshield = (IshieldIGC*)(IpartIGC*)m_ppart; return pshield->GetRegeneration() / pshield->GetMaxStrength(); } else { ZAssert(false); return 0; } } float PartWrapper::GetRechargeTime() { float f = 0.0f; float MaxHP = 0.0f; float HP = 0.0f; if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Shield) { IshieldIGC* pshield = (IshieldIGC*)(IpartIGC*)m_ppart; MaxHP = pshield->GetMaxStrength(); f = pshield->GetFraction(); HP = f * pshield->GetMaxStrength(); return (MaxHP - HP) / pshield->GetRegeneration(); } else { ZAssert(false); return 0; } } float PartWrapper::GetCloakTimeLeft() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Cloak) { const IhullTypeIGC* pht = trekClient.GetShip()->GetSourceShip()->GetHullType(); IcloakIGC* pcloak = (IcloakIGC*)(IpartIGC*)m_ppart; float shipEnergy = trekClient.GetShip()->GetEnergy(); float shipEnergyGen = pht->GetRechargeRate(); float cloakConsumption = pcloak->GetEnergyConsumption(); if (cloakConsumption <= shipEnergyGen){ return -1.0f; } else return shipEnergy/(cloakConsumption - shipEnergyGen); } else { ZAssert(false); return 0; } } float PartWrapper::IsEnergyDamage() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Weapon) { //IprojectileTypeIGC* ppt = ((IweaponIGC*)(IpartIGC*)m_ppart)->GetProjectileType(); return 0.0f; } else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Magazine) { //ImissileTypeIGC* pmt = (ImissileTypeIGC*)((IlauncherTypeIGC*)m_ppart->GetPartType())->GetExpendableType(); return 0.0f; } else { ZAssert(false); return 0; } } float PartWrapper::IsShipKiller() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Weapon) { //IprojectileTypeIGC* ppt = ((IweaponIGC*)(IpartIGC*)m_ppart)->GetProjectileType(); return 0.0f; } else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Magazine) { //ImissileTypeIGC* pmt = (ImissileTypeIGC*)((IlauncherTypeIGC*)m_ppart->GetPartType())->GetExpendableType(); return 0.0f; } else { ZAssert(false); return 0; } } float PartWrapper::IsStationKiller() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Weapon) { //IprojectileTypeIGC* ppt = ((IweaponIGC*)(IpartIGC*)m_ppart)->GetProjectileType(); return 0.0f; } else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Magazine) { //ImissileTypeIGC* pmt = (ImissileTypeIGC*)((IlauncherTypeIGC*)m_ppart->GetPartType())->GetExpendableType(); return 0.0f; } else { ZAssert(false); return 0; } } float PartWrapper::IsAsteroidKiller() { if (!m_ppart) return 0; else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Weapon) { //IprojectileTypeIGC* ppt = ((IweaponIGC*)(IpartIGC*)m_ppart)->GetProjectileType(); return 0.0f; } else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Magazine) { //ImissileTypeIGC* pmt = (ImissileTypeIGC*)((IlauncherTypeIGC*)m_ppart->GetPartType())->GetExpendableType(); return 0.0f; } else { ZAssert(false); return 0; } } float PartWrapper::IsSelected() { if (!m_ppart) { return 0; } else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Weapon) { IweaponIGC* pweapon = (IweaponIGC*)(IpartIGC*)m_ppart; bool fSelected; if (pweapon->GetMountID() < 0) { fSelected = false; } else if (trekClient.GetShip() != m_ppart->GetShip()) { fSelected = pweapon->GetGunner() == trekClient.GetShip(); } else { int nMaxFixedWeapons = m_ppart->GetShip()->GetHullType()->GetMaxFixedWeapons(); if (m_ppart->GetMountID() < nMaxFixedWeapons) { int stateM = trekClient.GetShip()->GetStateM(); Mount mountSelected = (stateM & selectedWeaponMaskIGC) >> selectedWeaponShiftIGC; fSelected = trekClient.fGroupFire || (m_ppart->GetMountID() == mountSelected); } } return fSelected ? 1.0f : 0.0f; } else { ZAssert(false); return 0; } } float PartWrapper::IsActive() { if (!m_ppart) return 0; else { return m_ppart->fActive() ? 1.0f : 0.0f; } } float PartWrapper::IsOutOfAmmo() { if (!m_ppart) return 0.0f; ObjectType type = m_ppart->GetObjectType(); if (type == OT_weapon) { return (m_ppart->GetShip()->GetAmmo() == 0) ? 1.0f : 0.0f; } else if (type == OT_afterburner) { return (m_ppart->GetShip()->GetFuel() == 0) ? 1.0f : 0.0f; } else if (IlauncherIGC::IsLauncher(type)) { return (m_ppart->GetAmount() == 0) ? 1.0f : 0.0f; } else { return 0.0f; } } float PartWrapper::GetReadyState() { if (!m_ppart || m_ppart->GetMountID() < 0) return 0; else if (m_ppart->GetMountedFraction() < 1.0f) { return 1; } else if (IlauncherIGC::IsLauncher(m_ppart->GetObjectType()) && ((IlauncherIGC*)(IpartIGC*)m_ppart)->GetArmedFraction() < 1.0f) { return 2; } else { // ready to rock and roll return 3; } } float PartWrapper::GetMountedFraction() { if (!m_ppart || m_ppart->GetMountID() < 0) { return 0; } else { return m_ppart->GetMountedFraction(); } } float PartWrapper::GetArmedFraction() { if (!m_ppart || m_ppart->GetMountID() < 0 || !IlauncherIGC::IsLauncher(m_ppart->GetObjectType())) { return 0; } else { return ((IlauncherIGC*)(IpartIGC*)m_ppart)->GetArmedFraction(); } }