#include "pch.h"
#include "consoledata.h"
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<Image> 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<Image> 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();
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();
}
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();
}
}
else if (type == OT_station)
{
assert (pmodel->GetCluster());
if (trekClient.GetShip()->CanSee(pmodel) &&
((pmodel->GetCluster() == trekClient.GetCluster()) ||
(pmodel == trekClient.GetShip()->GetStation())))
f = GetStation()->GetShieldFraction();
}
}
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);
}
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();
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)
{
return 0.0f;
}
else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Magazine)
{
return 0.0f;
}
else
{
ZAssert(false);
return 0;
}
}
float PartWrapper::IsShipKiller()
{
if (!m_ppart)
return 0;
else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Weapon)
{
return 0.0f;
}
else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Magazine)
{
return 0.0f;
}
else
{
ZAssert(false);
return 0;
}
}
float PartWrapper::IsStationKiller()
{
if (!m_ppart)
return 0;
else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Weapon)
{
return 0.0f;
}
else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Magazine)
{
return 0.0f;
}
else
{
ZAssert(false);
return 0;
}
}
float PartWrapper::IsAsteroidKiller()
{
if (!m_ppart)
return 0;
else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Weapon)
{
return 0.0f;
}
else if (m_ppart->GetPartType()->GetEquipmentType() == ET_Magazine)
{
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
{
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();
}
}