#include "pch.h" const Money moneyLots = 0x7fffffff; ////////////////////////////////////////////////////////////////////////////// // // Loadout // ////////////////////////////////////////////////////////////////////////////// static const char* GetBuyableName(IbuyableIGC* ppt) { const char* name = ppt->GetName(); Money cost = ppt->GetPrice(); if (cost == 0) return name; else { static char bfr[c_cbName + 10]; strcpy(bfr, name); strcat(bfr, " $("); _itoa(cost, bfr + strlen(bfr), 10); strcat(bfr, ")"); return bfr; } } bool g_bTest = false; const int c_midOtherParts = -2; const int ET_Turret = -2; class LoadoutImpl : public Loadout, public EventTargetContainer, public TrekClientEventSink, public ISubmenuEventSink, public IMenuCommandSink { public: ////////////////////////////////////////////////////////////////////////////// // // Slot // ////////////////////////////////////////////////////////////////////////////// class Slot : public Pane, public TrekClientEventSink { private: LoadoutImpl* m_ploadout; TRef m_pimageDefault; TRef m_pimage; EquipmentType m_equipmentType; Mount m_mount; TRef m_ppart; ZString m_strPrefix; public: Slot( LoadoutImpl* ploadout, EquipmentType equipmentType, Mount mount, Image* pimageDefault, const ZString& strPrefix ) : m_equipmentType(equipmentType), m_mount(mount), m_ploadout(ploadout), m_pimageDefault(pimageDefault), m_pimage(pimageDefault), m_strPrefix(strPrefix) { } ////////////////////////////////////////////////////////////////////////////// // // Methods // ////////////////////////////////////////////////////////////////////////////// IpartIGC* GetPart() { return m_ppart; } EquipmentType GetEquipmentType() { if (m_equipmentType == ET_Turret) return ET_Weapon; else return m_equipmentType; } Mount GetMount() { if (m_equipmentType == ET_Turret) return m_mount + m_ploadout->m_phullType->GetMaxFixedWeapons(); else return m_mount; } static bool SlotValidForHull(const IhullTypeIGC* pht, EquipmentType equipmentType, Mount mount) { if (equipmentType == NA) return true; else if (equipmentType == ET_Weapon) return mount < pht->GetMaxFixedWeapons(); else if (equipmentType == ET_Turret) return mount < pht->GetMaxWeapons() - pht->GetMaxFixedWeapons(); else return pht->GetPartMask(equipmentType, mount) != 0; } void SetPart(IpartIGC* ppart) { m_ppart = ppart; if (ppart) { IpartTypeIGC* ppartType = m_ppart->GetPartType(); // // Try to load the bitmap that fits this slot. // ZString str = (m_strPrefix + ZString(ppartType->GetModelName()) + "bmp").ToLower(); m_pimage = GetModeler()->LoadImage(str, false, false); // // If we can't find the right bitmap load the default bitmap. // if (m_pimage == NULL) { ZString str = (ZString("l") + ZString(ppartType->GetModelName()) + "bmp").ToLower(); m_pimage = GetModeler()->LoadImage(str, false); } } else { m_pimage = m_pimageDefault; } NeedPaint(); } ////////////////////////////////////////////////////////////////////////////// // // Pane Methods // ////////////////////////////////////////////////////////////////////////////// void UpdateLayout() { m_pimageDefault->Update(); InternalSetSize( WinPoint(133, 37) //::Cast(m_pimageDefault->GetBounds().GetRect().Size()) ); Pane::UpdateLayout(); } void Paint(Surface* psurface) { psurface->BitBlt(WinPoint(0, 0), m_pimage->GetSurface()); if (m_ppart) { // if this is a turret with a mounted weapon if (m_equipmentType == ET_Turret) { IhullTypeIGC* pht = trekClient.GetShip()->GetBaseHullType(); if (pht) { // display the current gunner for that turret IshipIGC* pshipGunner = trekClient.GetShip()->GetGunner(GetMount() + pht->GetMaxFixedWeapons() - m_ppart->GetShip()->GetBaseHullType()->GetMaxFixedWeapons()); if (pshipGunner) { psurface->DrawString( TrekResources::SmallFont(), MakeColorFromCOLORREF(TrekResources::WhiteColor()), WinPoint(3,24), pshipGunner->GetName() ); } else { psurface->DrawString( TrekResources::SmallFont(), MakeColorFromCOLORREF(TrekResources::WhiteColor()), WinPoint(3,24), "" ); } } } // otherwise, if this is a launcher else { ObjectType type = m_ppart->GetObjectType(); if ((type == OT_pack) || IlauncherIGC::IsLauncher(m_ppart->GetObjectType())) { ZString strText((int)m_ppart->GetAmount()); int nTextWidth = TrekResources::SmallFont()->GetTextExtent(strText).X(); // display the count of expendibles psurface->DrawString( TrekResources::SmallFont(), MakeColorFromCOLORREF(TrekResources::WhiteColor()), WinPoint(130 - nTextWidth, 24), strText ); } } } } ////////////////////////////////////////////////////////////////////////////// // // IMouseInput Methods // ////////////////////////////////////////////////////////////////////////////// void MouseEnter(IInputProvider* pprovider, const Point& point) { m_ploadout->SlotEntered(this); trekClient.PlaySoundEffect(mouseoverSound); } void MouseLeave(IInputProvider* pprovider) { m_ploadout->SlotLeft(this); } MouseResult Button(IInputProvider* pprovider, const Point& point, int button, bool bCaptured, bool bInside, bool bDown) { if (bDown) { //m_ploadout->SlotEntered(this); m_ploadout->SlotClicked(this, button == 0, WinPoint::Cast(point)); } return MouseResult(); } void OnBoardShip(IshipIGC* pshipChild, IshipIGC* pshipParent) { if (pshipParent == trekClient.GetShip() || pshipParent == NULL) { NeedPaint(); } } }; typedef TList > SlotList; ////////////////////////////////////////////////////////////////////////////// // // Members // ////////////////////////////////////////////////////////////////////////////// TRef m_pmodeler; TRef m_ptime; TRef m_ppane; TRef m_ppaneGeo; TRef m_pBlankImage; TRef m_pnsLoadout; TRef m_pnsLoadoutPane; TRef m_pnsDefaultLoadout; SlotList m_listSlots; TRef m_pslotMenu; TRef m_pmenu; TRef m_phullMenu; TRef m_psubmenuEventSink; // // IGC stuff // IshipIGC* m_pship; const IhullTypeIGC* m_phullType; IhullTypeIGC* m_phullTypeBase; float m_fSpecSignature; float m_fSpecMass; // // Geo Pane // TRef m_pcamera; TRef m_pviewport; TRef m_pwrapGeo; TRef m_pwrapImageGeo; /* TRef m_pmaterialCone; TRef m_pvisibleGeoCone; TRef m_ptransformCone; TRef m_pnumberAngleCone; float m_scaleCone; */ TRef m_pstringPartMask; // // Buttons // TRef m_pbuttonDefault; TRef m_pbuttonNext; TRef m_pbuttonPrevious; TRef m_pbuttonLaunch; TRef m_pbuttonBuy; TRef m_pbuttonConfirm; TRef m_pbuttonBack; TRef m_pbuttonHullList; TRef m_ppaneHoverBuy; TRef m_ppaneHoverConfirm; TRef m_ppointBuyButton; // // Exported Values // TRef m_pwrapImagePart; TRef m_pwrapImageCiv; TRef m_pwrapImageHullCiv; TRef m_pstringGunners[c_maxMountedWeapons]; TRef m_pstringTitle ; TRef m_pstringPartName ; TRef m_pstringPartDescription; TRef m_pstringHullDescription; TRef m_pnumberMoney; TRef m_pnumberOldShipCost; TRef m_pnumberNewShipCost; TRef m_pnumberLoadoutShipState; // parts TRef m_pnumberPartID ; TRef m_pnumberPartMask ; TRef m_pnumberEquipmentType ; TRef m_pnumberSignature ; TRef m_pnumberMass ; TRef m_pnumberSignatureNumber ; TRef m_pnumberMassNumber ; TRef m_pnumberWeaponDamage ; TRef m_pnumberWeaponRate ; TRef m_pnumberWeaponRange ; TRef m_pnumberWeaponSpeed ; TRef m_pnumberWeaponDamageNumber ; TRef m_pnumberWeaponRateNumber ; TRef m_pnumberWeaponRangeNumber ; TRef m_pnumberWeaponSpeedNumber ; TRef m_pnumberShieldRegen ; TRef m_pnumberShieldHitPts ; TRef m_pnumberShieldRegenNumber ; TRef m_pnumberShieldHitPtsNumber ; TRef m_pnumberCloakCloaking ; TRef m_pnumberCloakDuration ; TRef m_pnumberCloakCloakingNumber ; TRef m_pnumberCloakDurationNumber ; TRef m_pnumberMagazineDamage ; TRef m_pnumberMagazineRange ; TRef m_pnumberMagazineLockTime ; TRef m_pnumberMagazineMaxLock ; TRef m_pnumberMagazineDamageNumber ; TRef m_pnumberMagazineRangeNumber ; TRef m_pnumberMagazineLockTimeNumber ; TRef m_pnumberMagazineMaxLockNumber ; TRef m_pnumberAfterburnerMaxSpeed ; TRef m_pnumberAfterburnerBurnRate ; TRef m_pnumberAfterburnerMaxSpeedNumber ; TRef m_pnumberAfterburnerBurnRateNumber ; TRef m_pnumberChaffStrength ; TRef m_pnumberChaffStrengthNumber ; TRef m_pnumberPackQuantityNumber ; TRef m_pnumberProbeScanRange ; TRef m_pnumberProbeVisibility ; TRef m_pnumberProbeHitPts ; TRef m_pnumberProbeLifespan ; TRef m_pnumberProbeScanRangeNumber ; TRef m_pnumberProbeVisibilityNumber ; TRef m_pnumberProbeHitPtsNumber ; TRef m_pnumberProbeLifespanNumber ; TRef m_pnumberMineVisibility ; TRef m_pnumberMineVisibilityNumber ; TRef m_pnumberMineDamage ; TRef m_pnumberMineRadius ; TRef m_pnumberMineLifespan ; TRef m_pnumberMineDamageNumber ; TRef m_pnumberMineRadiusNumber ; TRef m_pnumberMineLifespanNumber ; // hull TRef m_pnumberHullMaxSpeed ; TRef m_pnumberHullAcceleration; TRef m_pnumberHullTurnRate ; TRef m_pnumberHullHitPoints ; TRef m_pnumberHullEnergy ; TRef m_pnumberHullScanRange ; TRef m_pnumberHullSignature ; TRef m_pnumberHullMass ; TRef m_pnumberHullMaxSpeedNumber ; TRef m_pnumberHullAccelerationNumber; TRef m_pnumberHullTurnRateNumber ; TRef m_pnumberHullHitPointsNumber ; TRef m_pnumberHullEnergyNumber ; TRef m_pnumberHullScanRangeNumber ; TRef m_pnumberHullSignatureNumber ; TRef m_pnumberHullMassNumber ; TRef m_pnumberBaseHullMaxSpeed ; TRef m_pnumberBaseHullAcceleration; TRef m_pnumberBaseHullTurnRate ; TRef m_pnumberBaseHullHitPoints ; TRef m_pnumberBaseHullEnergy ; TRef m_pnumberBaseHullScanRange ; TRef m_pnumberBaseHullSignature ; TRef m_pnumberBaseHullMass ; TRef m_pnumberBaseHullMaxSpeedNumber ; TRef m_pnumberBaseHullAccelerationNumber; TRef m_pnumberBaseHullTurnRateNumber ; TRef m_pnumberBaseHullHitPointsNumber ; TRef m_pnumberBaseHullEnergyNumber ; TRef m_pnumberBaseHullScanRangeNumber ; TRef m_pnumberBaseHullSignatureNumber ; TRef m_pnumberBaseHullMassNumber ; TRef m_pnumberHullDefenseClass ; TRef m_pnumberBaseHullDefenseClass ; TRef m_pnumberShieldDefenseClass ; TRef m_pnumberWeaponDamageBonus ; TRef m_pnumberMagazineDamageBonus ; // // Imported Values // float m_maxWeaponRate ; float m_maxWeaponPower ; float m_maxWeaponRange ; float m_maxWeaponSpeed ; float m_maxShieldParticle; float m_maxShieldEnergy ; float m_maxShieldRegen ; float m_maxShieldHitPts ; float m_maxCloakEnergy ; float m_maxPartMass ; float m_maxPartSignature ; float m_maxMagazineHitDamage ; float m_maxMagazineAreaDamage ; float m_maxMagazineRange ; float m_maxMagazineLockTime ; float m_maxMagazineMaxLock ; float m_maxAfterburnerMaxThrust; float m_maxAfterburnerBurnRate; float m_maxAfterburnerOnRate; float m_maxChaffStrength; float m_maxProbeScanRange; float m_maxProbeHitPts; float m_maxProbeLifespan; float m_maxMineDamage ; float m_maxMineRadius ; float m_maxMineLifespan ; float m_maxMaxSpeed ; float m_maxAcceleration ; float m_maxTurnRate ; float m_maxHitPoints ; float m_maxEnergy ; float m_maxScanRange ; float m_maxHullSignature; float m_maxHullMass ; ////////////////////////////////////////////////////////////////////////////// // // Constructor // ////////////////////////////////////////////////////////////////////////////// LoadoutImpl(Modeler* pmodeler, Number* ptime) : m_pmodeler(pmodeler), m_ptime(ptime), m_phullType(NULL), m_phullTypeBase(NULL) { // calculate the mass and signature of the default loadout IshipIGC* pshipSource = trekClient.GetShip()->GetSourceShip(); Money budget = moneyLots; m_pship = trekClient.CreateEmptyShip(); trekClient.BuyDefaultLoadout(m_pship, trekClient.GetShip()->GetStation(), pshipSource->GetBaseHullType(), &budget); m_fSpecMass = m_pship->GetMass(); m_fSpecSignature = m_pship->GetSignature(); m_pship->Terminate(); m_pship->Release(); // copy their current loadout, upgrading if we can. m_pship = trekClient.CreateEmptyShip(); trekClient.RestoreLoadout(pshipSource, m_pship, trekClient.GetShip()->GetStation(), trekClient.GetMoney() + pshipSource->GetValue()); InitializeMDL(); InitializePanes(); UpdateHullType(); UpdateCivBitmap(); UpdatePartInfo(NULL, NULL, NULL); UpdateNextAndPrevButtons(); m_psubmenuEventSink = ISubmenuEventSink::CreateDelegate(this); } ~LoadoutImpl() { CloseMenu(); trekClient.SaveLoadout(m_pship); m_pship->Terminate(); m_pship->Release(); m_pmodeler->UnloadNameSpace("defaultloadout"); m_pmodeler->UnloadNameSpace("loadoutpane"); m_pmodeler->UnloadNameSpace("loadout"); m_pmodeler->UnloadNameSpace("loadoutdata"); m_pmodeler->UnloadNameSpace("loadoutinclude"); } ////////////////////////////////////////////////////////////////////////////// // // Initialization // ////////////////////////////////////////////////////////////////////////////// void InitializeMDL() { // // exports // TRef pnsLoadoutData = m_pmodeler->CreateNameSpace("loadoutdata", m_pmodeler->GetNameSpace("effect")); for (int index = 0; index < c_maxMountedWeapons; index++) { pnsLoadoutData->AddMember( "gunner" + ZString(index), m_pstringGunners[index] = new ModifiableString("unmanned") ); } pnsLoadoutData->AddMember("titleString", m_pstringTitle = new ModifiableString(ZString())); pnsLoadoutData->AddMember("hullDescriptionString", m_pstringHullDescription = new ModifiableString(ZString())); pnsLoadoutData->AddMember("partNameString", m_pstringPartName = new ModifiableString(ZString())); pnsLoadoutData->AddMember("partDescriptionString", m_pstringPartDescription = new ModifiableString(ZString())); pnsLoadoutData->AddMember("money", m_pnumberMoney = new ModifiableNumber((float)trekClient.GetMoney())); pnsLoadoutData->AddMember("oldShipCost", m_pnumberOldShipCost = new ModifiableNumber((float)trekClient.GetShip()->GetValue())); pnsLoadoutData->AddMember("newShipCost", m_pnumberNewShipCost = new ModifiableNumber((float)m_pship->GetValue())); pnsLoadoutData->AddMember("loadoutShipState", m_pnumberLoadoutShipState = new ModifiableNumber(0)); pnsLoadoutData->AddMember("partID", m_pnumberPartID = new ModifiableNumber(0)); pnsLoadoutData->AddMember("partMask", m_pnumberPartMask = new ModifiableNumber(0)); //pnsLoadoutData->AddMember("partEquipmentType", m_pnumberEquipmentType = new ModifiableNumber(0)); pnsLoadoutData->AddMember("partSignature", m_pnumberSignature = new ModifiableNumber(0)); pnsLoadoutData->AddMember("partMass", m_pnumberMass = new ModifiableNumber(0)); pnsLoadoutData->AddMember("partSignatureNumber", m_pnumberSignatureNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("partMassNumber", m_pnumberMassNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("weaponDamage", m_pnumberWeaponDamage = new ModifiableNumber(0)); pnsLoadoutData->AddMember("weaponRate", m_pnumberWeaponRate = new ModifiableNumber(0)); pnsLoadoutData->AddMember("weaponRange", m_pnumberWeaponRange = new ModifiableNumber(0)); pnsLoadoutData->AddMember("weaponSpeed", m_pnumberWeaponSpeed = new ModifiableNumber(0)); pnsLoadoutData->AddMember("weaponDamageNumber", m_pnumberWeaponDamageNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("weaponRateNumber", m_pnumberWeaponRateNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("weaponRangeNumber", m_pnumberWeaponRangeNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("weaponSpeedNumber", m_pnumberWeaponSpeedNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("shieldRegen", m_pnumberShieldRegen = new ModifiableNumber(0)); pnsLoadoutData->AddMember("shieldHitPts", m_pnumberShieldHitPts = new ModifiableNumber(0)); pnsLoadoutData->AddMember("shieldRegenNumber", m_pnumberShieldRegenNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("shieldHitPtsNumber", m_pnumberShieldHitPtsNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("equipmentType", m_pnumberEquipmentType = new ModifiableNumber(0)); pnsLoadoutData->AddMember("cloakCloaking", m_pnumberCloakCloaking = new ModifiableNumber(0)); pnsLoadoutData->AddMember("cloakDuration", m_pnumberCloakDuration = new ModifiableNumber(0)); pnsLoadoutData->AddMember("cloakCloakingNumber", m_pnumberCloakCloakingNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("cloakDurationNumber", m_pnumberCloakDurationNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("magazineDamage", m_pnumberMagazineDamage = new ModifiableNumber(0)); pnsLoadoutData->AddMember("magazineRange", m_pnumberMagazineRange = new ModifiableNumber(0)); pnsLoadoutData->AddMember("magazineLockTime", m_pnumberMagazineLockTime = new ModifiableNumber(0)); pnsLoadoutData->AddMember("magazineMaxLock", m_pnumberMagazineMaxLock = new ModifiableNumber(0)); pnsLoadoutData->AddMember("magazineDamageNumber", m_pnumberMagazineDamageNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("magazineRangeNumber", m_pnumberMagazineRangeNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("magazineLockTimeNumber", m_pnumberMagazineLockTimeNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("magazineMaxLockNumber", m_pnumberMagazineMaxLockNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("afterburnerMaxSpeed", m_pnumberAfterburnerMaxSpeed = new ModifiableNumber(0)); pnsLoadoutData->AddMember("afterburnerBurnRate", m_pnumberAfterburnerBurnRate = new ModifiableNumber(0)); pnsLoadoutData->AddMember("afterburnerMaxSpeedNumber", m_pnumberAfterburnerMaxSpeedNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("afterburnerBurnRateNumber", m_pnumberAfterburnerBurnRateNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("chaffStrength", m_pnumberChaffStrength = new ModifiableNumber(0)); pnsLoadoutData->AddMember("chaffStrengthNumber", m_pnumberChaffStrengthNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("packQuantityNumber", m_pnumberPackQuantityNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("probeScanRange", m_pnumberProbeScanRange = new ModifiableNumber(0)); pnsLoadoutData->AddMember("probeVisibility", m_pnumberProbeVisibility = new ModifiableNumber(0)); pnsLoadoutData->AddMember("probeHitPts", m_pnumberProbeHitPts = new ModifiableNumber(0)); pnsLoadoutData->AddMember("probeLifespan", m_pnumberProbeLifespan = new ModifiableNumber(0)); pnsLoadoutData->AddMember("probeScanRangeNumber", m_pnumberProbeScanRangeNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("probeVisibilityNumber", m_pnumberProbeVisibilityNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("probeHitPtsNumber", m_pnumberProbeHitPtsNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("probeLifespanNumber", m_pnumberProbeLifespanNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("mineVisibility", m_pnumberMineVisibility = new ModifiableNumber(0)); pnsLoadoutData->AddMember("mineVisibilityNumber", m_pnumberMineVisibilityNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("mineDamage", m_pnumberMineDamage = new ModifiableNumber(0)); pnsLoadoutData->AddMember("mineRadius", m_pnumberMineRadius = new ModifiableNumber(0)); pnsLoadoutData->AddMember("mineLifespan", m_pnumberMineLifespan = new ModifiableNumber(0)); pnsLoadoutData->AddMember("mineDamageNumber", m_pnumberMineDamageNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("mineRadiusNumber", m_pnumberMineRadiusNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("mineLifespanNumber", m_pnumberMineLifespanNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullMaxSpeed", m_pnumberHullMaxSpeed = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullAcceleration", m_pnumberHullAcceleration = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullTurnRate", m_pnumberHullTurnRate = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullHitPoints", m_pnumberHullHitPoints = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullMaxEnergy", m_pnumberHullEnergy = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullScanRange", m_pnumberHullScanRange = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullSignature", m_pnumberHullSignature = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullMass", m_pnumberHullMass = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullMaxSpeedNumber", m_pnumberHullMaxSpeedNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullAccelerationNumber", m_pnumberHullAccelerationNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullTurnRateNumber", m_pnumberHullTurnRateNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullHitPointsNumber", m_pnumberHullHitPointsNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullMaxEnergyNumber", m_pnumberHullEnergyNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullScanRangeNumber", m_pnumberHullScanRangeNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullSignatureNumber", m_pnumberHullSignatureNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("hullMassNumber", m_pnumberHullMassNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullMaxSpeed", m_pnumberBaseHullMaxSpeed = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullAcceleration", m_pnumberBaseHullAcceleration = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullTurnRate", m_pnumberBaseHullTurnRate = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullHitPoints", m_pnumberBaseHullHitPoints = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullMaxEnergy", m_pnumberBaseHullEnergy = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullScanRange", m_pnumberBaseHullScanRange = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullSignature", m_pnumberBaseHullSignature = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullMass", m_pnumberBaseHullMass = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullMaxSpeedNumber", m_pnumberBaseHullMaxSpeedNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullAccelerationNumber", m_pnumberBaseHullAccelerationNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullTurnRateNumber", m_pnumberBaseHullTurnRateNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullHitPointsNumber", m_pnumberBaseHullHitPointsNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullMaxEnergyNumber", m_pnumberBaseHullEnergyNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullScanRangeNumber", m_pnumberBaseHullScanRangeNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullSignatureNumber", m_pnumberBaseHullSignatureNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullMassNumber", m_pnumberBaseHullMassNumber = new ModifiableNumber(0)); pnsLoadoutData->AddMember("partImage", (Value*)(m_pwrapImagePart = new WrapImage(Image::GetEmpty()))); pnsLoadoutData->AddMember("civImage", (Value*)(m_pwrapImageCiv = new WrapImage(Image::GetEmpty()))); pnsLoadoutData->AddMember("civHullImage", (Value*)(m_pwrapImageHullCiv = new WrapImage(Image::GetEmpty()))); pnsLoadoutData->AddMember("hullDefenseClassNumber", m_pnumberHullDefenseClass = new ModifiableNumber(0)); pnsLoadoutData->AddMember("baseHullDefenseClassNumber", m_pnumberBaseHullDefenseClass = new ModifiableNumber(0)); pnsLoadoutData->AddMember("shieldDefenseClassNumber", m_pnumberShieldDefenseClass = new ModifiableNumber(0)); pnsLoadoutData->AddMember("weaponDamageClassNumber", m_pnumberWeaponDamageBonus = new ModifiableNumber(0)); pnsLoadoutData->AddMember("magazineDamageClassNumber", m_pnumberMagazineDamageBonus = new ModifiableNumber(0)); // // imports // TRef pnsPartInfo = m_pmodeler->GetNameSpace("partinfo"); m_maxWeaponRate = pnsPartInfo->FindNumber("maxWeaponRate"); m_maxWeaponPower = pnsPartInfo->FindNumber("maxWeaponPower"); m_maxWeaponRange = pnsPartInfo->FindNumber("maxWeaponRange"); m_maxWeaponSpeed = pnsPartInfo->FindNumber("maxWeaponSpeed"); m_maxShieldRegen = pnsPartInfo->FindNumber("maxShieldRegen"); m_maxShieldHitPts = pnsPartInfo->FindNumber("maxShieldHitPts"); m_maxCloakEnergy = pnsPartInfo->FindNumber("maxCloakEnergy"); m_maxPartMass = pnsPartInfo->FindNumber("maxPartMass"); m_maxPartSignature = pnsPartInfo->FindNumber("maxPartSignature"); m_maxMagazineHitDamage = pnsPartInfo->FindNumber("maxMagazineHitDamage"); m_maxMagazineAreaDamage = pnsPartInfo->FindNumber("maxMagazineAreaDamage"); m_maxMagazineRange = pnsPartInfo->FindNumber("maxMagazineRange"); m_maxMagazineLockTime = pnsPartInfo->FindNumber("maxMagazineLockTime"); m_maxMagazineMaxLock = pnsPartInfo->FindNumber("maxMagazineMaxLock"); m_maxAfterburnerMaxThrust = pnsPartInfo->FindNumber("maxAfterburnerMaxThrust"); m_maxAfterburnerBurnRate = pnsPartInfo->FindNumber("maxAfterburnerBurnRate"); m_maxAfterburnerOnRate = pnsPartInfo->FindNumber("maxAfterburnerOnRate"); m_maxChaffStrength = pnsPartInfo->FindNumber("maxChaffStrength"); m_maxProbeScanRange = pnsPartInfo->FindNumber("maxProbeScanRange"); m_maxProbeHitPts = pnsPartInfo->FindNumber("maxProbeHitPts"); m_maxProbeLifespan = pnsPartInfo->FindNumber("maxProbeLifespan"); m_maxMineDamage = pnsPartInfo->FindNumber("maxMineDamage"); m_maxMineRadius = pnsPartInfo->FindNumber("maxMineRadius"); m_maxMineLifespan = pnsPartInfo->FindNumber("maxMineLifespan"); m_pmodeler->UnloadNameSpace("partinfo"); TRef pnsHullInfo = m_pmodeler->GetNameSpace("hullinfo"); m_maxMaxSpeed = pnsHullInfo->FindNumber("maxHullMaxSpeed" ); m_maxAcceleration = pnsHullInfo->FindNumber("maxHullAcceleration"); m_maxTurnRate = pnsHullInfo->FindNumber("maxHullTurnRate" ); m_maxHitPoints = pnsHullInfo->FindNumber("maxHullHitPoints" ); m_maxEnergy = pnsHullInfo->FindNumber("maxHullMaxEnergy" ); m_maxScanRange = pnsHullInfo->FindNumber("maxHullScanRange" ); m_maxHullSignature = pnsHullInfo->FindNumber("maxHullSignature" ); m_maxHullMass = pnsHullInfo->FindNumber("maxHullMass" ); m_pmodeler->UnloadNameSpace("hullinfo"); // // we use these namespaces // m_pnsLoadout = m_pmodeler->GetNameSpace("loadout"); m_pnsLoadoutPane = m_pmodeler->GetNameSpace("loadoutpane"); m_pnsDefaultLoadout = m_pmodeler->GetNameSpace("defaultloadout"); } void InitializePanes() { // // Get the pane // CastTo(m_ppane, m_pnsLoadoutPane->FindMember("loadoutPane")); // // Add the Geo Pane // m_ppaneGeo = CreateGeoPane( m_pnsLoadoutPane->FindPoint("geoSize"), m_pnsLoadoutPane->FindPoint("geoPosition") ); m_ppaneGeo->SetOffset(m_pnsLoadoutPane->FindWinPoint("geoPosition")); m_ppane->InsertAtTop(m_ppaneGeo); // // The Buttons // CastTo(m_pbuttonDefault , m_pnsLoadoutPane->FindMember("defaultButtonPane" )); CastTo(m_pbuttonNext , m_pnsLoadoutPane->FindMember("nextButtonPane" )); CastTo(m_pbuttonPrevious, m_pnsLoadoutPane->FindMember("previousButtonPane")); CastTo(m_pbuttonLaunch , m_pnsLoadoutPane->FindMember("launchButtonPane" )); CastTo(m_pbuttonBuy , m_pnsLoadoutPane->FindMember("buyButtonPane" )); CastTo(m_pbuttonConfirm , m_pnsLoadoutPane->FindMember("confirmButtonPane" )); CastTo(m_pbuttonBack , m_pnsLoadoutPane->FindMember("backButtonPane" )); CastTo(m_pbuttonHullList, m_pnsLoadoutPane->FindMember("hullListButtonPane")); CastTo(m_ppaneHoverBuy , m_pnsLoadoutPane->FindMember("buyHoverPane" )); CastTo(m_ppaneHoverConfirm, m_pnsLoadoutPane->FindMember("confirmHoverPane")); CastTo(m_ppointBuyButton , m_pnsLoadoutPane->FindMember("buyBtnPosition" )); m_pbuttonHullList->SetDownTrigger(true); AddEventTarget(OnButtonDefault , m_pbuttonDefault ->GetEventSource()); AddEventTarget(OnButtonNext , m_pbuttonNext ->GetEventSource()); AddEventTarget(OnButtonPrevious, m_pbuttonPrevious->GetEventSource()); AddEventTarget(OnButtonLaunch , m_pbuttonLaunch ->GetEventSource()); AddEventTarget(OnButtonBuy , m_pbuttonBuy ->GetEventSource()); AddEventTarget(OnButtonBuy , m_pbuttonConfirm ->GetEventSource()); AddEventTarget(OnButtonBack , m_pbuttonBack ->GetEventSource()); AddEventTarget(OnButtonHullList, m_pbuttonHullList->GetEventSource()); } ////////////////////////////////////////////////////////////////////////////// // // Screen public methods // ////////////////////////////////////////////////////////////////////////////// Pane* GetPane() { return m_ppane; } void OnFrame() { UpdateButtons(); } ////////////////////////////////////////////////////////////////////////////// // // Methods // ////////////////////////////////////////////////////////////////////////////// void UpdateCivBitmap() { IsideIGC* pside = trekClient.GetSide(); if (pside) { ZString str = ZString(pside->GetCivilization()->GetIconName()).ToLower() + "loadoutpanebmp"; m_pwrapImageCiv->SetImage(GetModeler()->LoadImage(str, false)); ZString str2 = ZString(pside->GetCivilization()->GetIconName()).ToLower() + "hullinfobmp"; m_pwrapImageHullCiv->SetImage(GetModeler()->LoadImage(str2, false)); } else { m_pwrapImageCiv->SetImage(GetModeler()->LoadImage("loadoutpanemp", false)); m_pwrapImageHullCiv->SetImage(GetModeler()->LoadImage("hullinfomp", false)); } } TRef CreateGeoPane(const Point& size, const Point& offset) { m_pcamera = new Camera(); m_pcamera->SetZClip(1, 10000); m_pcamera->SetFOV(RadiansFromDegrees(50)); Rect rect(Point(0, 0), size); TRef prect = new RectValue(rect); m_pviewport = new Viewport(m_pcamera, prect); m_pwrapGeo = new WrapGeo(Geo::GetEmpty()); TRef pimage = new GroupImage( m_pwrapImageGeo = new WrapImage(Image::GetEmpty()), new GeoImage( new TransformGeo( new TransformGeo( m_pwrapGeo, new AnimateRotateTransform( new VectorValue(Vector(0, 1, 0)), Multiply(m_ptime, new Number(1.0)) ) ), new RotateTransform(Vector(1, 0, 0), pi/8) ), m_pviewport, true ), new TranslateImage( m_pwrapImageCiv, Point(-offset.X(), -(600 - size.Y() - offset.Y())) ) ); // // Give this guy a zbuffer // return new AnimatedImagePane( CreatePaneImage( GetEngine(), SurfaceType3D() | SurfaceTypeZBuffer(), false, new AnimatedImagePane( pimage, rect ) ) ); } ////////////////////////////////////////////////////////////////////////////// // // // ////////////////////////////////////////////////////////////////////////////// void SetGeo(Geo* pgeo) { m_pwrapGeo->SetGeo(pgeo); float radius = pgeo->GetRadius(Matrix::GetIdentity()); //m_scaleCone = 0.75f * radius; m_pcamera->SetPosition( Vector( 0, 0, 2.4f * radius ) ); } ////////////////////////////////////////////////////////////////////////////// // // m_pship->SetBaseHullType(phullType); // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // // Gunner Info // ////////////////////////////////////////////////////////////////////////////// void UpdateGunnerInfo() { for (int index = 0; index < c_maxMountedWeapons; index++) { IweaponIGC* pweapon; CastTo(pweapon, m_pship->GetMountedPart(ET_Weapon, index)); if (pweapon) { IshipIGC* pshipGunner = pweapon->GetGunner(); if (pshipGunner) { m_pstringGunners[index]->SetValue(pshipGunner->GetName()); } else { m_pstringGunners[index]->SetValue("unmanned"); } } } } ////////////////////////////////////////////////////////////////////////////// // // Hull Info // ////////////////////////////////////////////////////////////////////////////// void SetHullTitle() { m_pstringTitle->SetValue(ZString(m_phullType->GetName()).ToUpper()); m_pstringHullDescription->SetValue(m_phullType->GetDescription()); } void UpdatePerformanceInfo() { SetHullTitle(); float acceleration = m_phullType->GetThrust() / m_pship->GetMass(); float turnRate = ( m_phullType->GetMaxTurnRate(c_axisYaw) + m_phullType->GetMaxTurnRate(c_axisPitch) + m_phullType->GetMaxTurnRate(c_axisRoll) ) * (180.0f / (3.0f * pi)); float accelerationBase = m_phullTypeBase->GetThrust() / m_fSpecMass; float turnRateBase = ( m_phullTypeBase->GetMaxTurnRate(c_axisYaw) + m_phullTypeBase->GetMaxTurnRate(c_axisPitch) + m_phullTypeBase->GetMaxTurnRate(c_axisRoll) ) * (180.0f / (3.0f * pi)); const GlobalAttributeSet& ga = trekClient.GetSide()->GetGlobalAttributeSet(); float maxSpeed = m_phullType->GetMaxSpeed(); float hitPoints = m_phullType->GetHitPoints(); float maxEnergy = m_phullType->GetMaxEnergy(); float scannerRange = m_phullType->GetScannerRange(); float signature = m_pship->GetSignature() / ga.GetAttribute(c_gaSignature); float specSignature = m_fSpecSignature / ga.GetAttribute(c_gaSignature); m_pnumberHullMaxSpeed ->SetValue(maxSpeed / m_maxMaxSpeed ); m_pnumberHullAcceleration->SetValue(acceleration / m_maxAcceleration ); m_pnumberHullTurnRate ->SetValue(turnRate / m_maxTurnRate ); m_pnumberHullHitPoints ->SetValue(hitPoints / m_maxHitPoints ); m_pnumberHullEnergy ->SetValue(maxEnergy / m_maxEnergy ); m_pnumberHullScanRange ->SetValue(scannerRange / m_maxScanRange ); m_pnumberHullSignature ->SetValue((1/signature) / m_maxHullSignature); m_pnumberHullMass ->SetValue(m_pship->GetMass() / m_maxHullMass ); m_pnumberHullMaxSpeedNumber ->SetValue(maxSpeed); m_pnumberHullAccelerationNumber->SetValue(acceleration); m_pnumberHullTurnRateNumber ->SetValue(turnRate); m_pnumberHullHitPointsNumber ->SetValue(hitPoints); m_pnumberHullEnergyNumber ->SetValue(maxEnergy); m_pnumberHullScanRangeNumber ->SetValue(scannerRange); m_pnumberHullSignatureNumber ->SetValue(signature * 100); m_pnumberHullMassNumber ->SetValue(m_pship->GetMass()); m_pnumberBaseHullMaxSpeed ->SetValue(m_phullTypeBase->GetMaxSpeed() / m_maxMaxSpeed); m_pnumberBaseHullAcceleration->SetValue(accelerationBase / m_maxAcceleration); m_pnumberBaseHullTurnRate ->SetValue(turnRateBase / m_maxTurnRate); m_pnumberBaseHullHitPoints ->SetValue(m_phullTypeBase->GetHitPoints() / m_maxHitPoints); m_pnumberBaseHullEnergy ->SetValue(m_phullTypeBase->GetMaxEnergy() / m_maxEnergy); m_pnumberBaseHullScanRange ->SetValue(m_phullTypeBase->GetScannerRange() / m_maxScanRange); m_pnumberBaseHullSignature ->SetValue((1/specSignature) / m_maxHullSignature); m_pnumberBaseHullMass ->SetValue(m_fSpecMass / m_maxHullMass); m_pnumberBaseHullMaxSpeedNumber ->SetValue(m_phullTypeBase->GetMaxSpeed()); m_pnumberBaseHullAccelerationNumber->SetValue(accelerationBase); m_pnumberBaseHullTurnRateNumber ->SetValue(turnRateBase); m_pnumberBaseHullHitPointsNumber ->SetValue(m_phullTypeBase->GetHitPoints()); m_pnumberBaseHullEnergyNumber ->SetValue(m_phullTypeBase->GetMaxEnergy()); m_pnumberBaseHullScanRangeNumber ->SetValue(m_phullTypeBase->GetScannerRange()); m_pnumberBaseHullSignatureNumber ->SetValue(specSignature * 100); m_pnumberBaseHullMassNumber ->SetValue(m_fSpecMass); m_pnumberHullDefenseClass ->SetValue(m_phullType->GetDefenseType()); m_pnumberBaseHullDefenseClass ->SetValue(m_phullTypeBase->GetDefenseType()); } ////////////////////////////////////////////////////////////////////////////// // // Part Info // ////////////////////////////////////////////////////////////////////////////// void UpdateWeaponPartInfo(IpartTypeIGC* ppartType) { const GlobalAttributeSet& ga = trekClient.GetSide()->GetGlobalAttributeSet(); DataWeaponTypeIGC* pdwt = (DataWeaponTypeIGC*)ppartType->GetData(); IprojectileTypeIGC* ppt = trekClient.GetCore()->GetProjectileType(pdwt->projectileTypeID); float rate = 1.0f / pdwt->dtimeBurst; float power = (ppt->GetPower() + ppt->GetBlastPower()) * rate * ga.GetAttribute(c_gaDamageGuns); bool bAmmo = pdwt->cAmmoPerShot != 0; float speed = ppt->GetSpeed(); if (bAmmo) speed *= ga.GetAttribute(c_gaSpeedAmmo); float range = speed * ppt->GetLifespan(); if (!bAmmo) range *= ga.GetAttribute(c_gaLifespanEnergy); m_pnumberWeaponDamage->SetValue(power / m_maxWeaponPower); m_pnumberWeaponRange ->SetValue(range / m_maxWeaponRange); m_pnumberWeaponSpeed ->SetValue(speed / m_maxWeaponSpeed); m_pnumberWeaponRate ->SetValue(rate / m_maxWeaponRate); m_pnumberWeaponDamageNumber->SetValue(power); m_pnumberWeaponRangeNumber ->SetValue(range); // !!! should get a 'm' suffix m_pnumberWeaponSpeedNumber ->SetValue(speed); // !!! should get a 'mps' suffix m_pnumberWeaponRateNumber ->SetValue(rate); // !!! should get a '/s' suffix m_pnumberWeaponDamageBonus ->SetValue(ppt->GetDamageType()); } void UpdateMagazinePartInfo(IpartTypeIGC* ppartType) { const GlobalAttributeSet& ga = trekClient.GetSide()->GetGlobalAttributeSet(); ImissileTypeIGC* pmt = (ImissileTypeIGC*)((IlauncherTypeIGC*)ppartType)->GetExpendableType(); float power = (pmt->GetPower() + pmt->GetBlastPower()) * ga.GetAttribute(c_gaDamageMissiles); float lifespan = pmt->GetLifespan(); float range = pmt->GetInitialSpeed() * lifespan + 0.5f * (pmt->GetAcceleration() * lifespan * lifespan); float lockTime = pmt->GetLockTime(); float lock = pmt->GetMaxLock(); m_pnumberMagazineDamage ->SetValue(power / (m_maxMagazineHitDamage + m_maxMagazineAreaDamage)); m_pnumberMagazineRange ->SetValue(range / m_maxMagazineRange); m_pnumberMagazineLockTime->SetValue(lockTime / m_maxMagazineLockTime); m_pnumberMagazineMaxLock ->SetValue(lock); m_pnumberMagazineDamageNumber ->SetValue(power); m_pnumberMagazineRangeNumber ->SetValue(range); // !!! Should get a 'm' suffix m_pnumberMagazineLockTimeNumber->SetValue(lockTime); // !!! Should get a 's' suffix m_pnumberMagazineMaxLockNumber ->SetValue(lock * 100.0f); // !!! Should get a '%' suffix m_pnumberMagazineDamageBonus ->SetValue(pmt->GetDamageType()); } void UpdateDispenserPartInfo(IpartTypeIGC* ppartType) { const GlobalAttributeSet& ga = trekClient.GetSide()->GetGlobalAttributeSet(); IexpendableTypeIGC* pet = ((IlauncherTypeIGC*)ppartType)->GetExpendableType(); if (pet->GetObjectType() == OT_probeType) { DataProbeTypeIGC* pdprt = (DataProbeTypeIGC*)(pet->GetData()); float scanRange; { IprojectileTypeIGC* ppt = ((IprobeTypeIGC*)pet)->GetProjectileType(); if (ppt) { //Scan range for something with guns is the gun range scanRange = ppt->GetLifespan() * ppt->GetSpeed() / 1.2f; if (((IprobeTypeIGC*)pet)->GetAmmo() != 0) scanRange *= trekClient.GetSide()->GetGlobalAttributeSet().GetAttribute(c_gaSpeedAmmo); } else scanRange = pdprt->scannerRange * ga.GetAttribute(c_gaScanRange); } float signature = pdprt->signature / ga.GetAttribute(c_gaSignature); m_pnumberProbeScanRange ->SetValue(scanRange / m_maxProbeScanRange); m_pnumberProbeVisibility ->SetValue(signature); m_pnumberProbeHitPts ->SetValue(pdprt->hitPoints / m_maxProbeHitPts); m_pnumberProbeLifespan ->SetValue(pdprt->lifespan / m_maxProbeLifespan); m_pnumberProbeScanRangeNumber ->SetValue(scanRange); //Should get a 'm' suffix m_pnumberProbeVisibilityNumber ->SetValue(signature * 100.0f); //Should get a '%' suffix m_pnumberProbeHitPtsNumber ->SetValue(pdprt->hitPoints); m_pnumberProbeLifespanNumber ->SetValue(pdprt->lifespan); //Should get a 's' suffix } else { DataMineTypeIGC* pdmt = (DataMineTypeIGC*)(pet->GetData()); float signature = pdmt->signature / ga.GetAttribute(c_gaSignature); m_pnumberMineDamage ->SetValue(pdmt->power / m_maxMineDamage); m_pnumberMineVisibility ->SetValue(signature); m_pnumberMineRadius ->SetValue(pdmt->radius / m_maxMineRadius); m_pnumberMineLifespan ->SetValue(pdmt->lifespan / m_maxMineLifespan); m_pnumberMineDamageNumber ->SetValue(pdmt->power); m_pnumberMineVisibilityNumber->SetValue(signature * 100.0f); //Should get a '%' suffix m_pnumberMineRadiusNumber ->SetValue(pdmt->radius); //Should get a 'm' suffix m_pnumberMineLifespanNumber ->SetValue(pdmt->lifespan); //Should get a 's' suffix } } void UpdateChaffLauncherPartInfo(IpartTypeIGC* ppartType) { DataChaffTypeIGC* pdct = (DataChaffTypeIGC*) ((((IlauncherTypeIGC*)ppartType)->GetExpendableType())->GetData()); float effectiveness = (pdct->chaffStrength <= 1.0f) ? pdct->chaffStrength / 2.0f : 1.0f - 1.0f/(2.0f * pdct->chaffStrength); m_pnumberChaffStrength ->SetValue(effectiveness / m_maxChaffStrength); m_pnumberChaffStrengthNumber->SetValue(effectiveness * 100); //Should get a % suffix } void UpdateShieldPartInfo(IpartTypeIGC* ppartType) { const GlobalAttributeSet& ga = trekClient.GetSide()->GetGlobalAttributeSet(); DataShieldTypeIGC* pdst = (DataShieldTypeIGC*)ppartType->GetData(); float maxStrength = pdst->maxStrength * ga.GetAttribute(c_gaMaxShieldShip); float regen = maxStrength / (pdst->rateRegen * ga.GetAttribute(c_gaShieldRegenerationShip)); m_pnumberShieldRegen ->SetValue(regen / m_maxShieldRegen); m_pnumberShieldHitPts ->SetValue(maxStrength / m_maxShieldHitPts); m_pnumberShieldRegenNumber ->SetValue(regen); //Should have a 's' suffix m_pnumberShieldHitPtsNumber ->SetValue(maxStrength); m_pnumberShieldDefenseClass ->SetValue(pdst->defenseType); } void UpdateCloakPartInfo(IpartTypeIGC* ppartType) { DataCloakTypeIGC* pdct = (DataCloakTypeIGC*)ppartType->GetData(); m_pnumberCloakCloaking ->SetValue(pdct->maxCloaking); m_pnumberCloakCloakingNumber ->SetValue(pdct->maxCloaking * 100); //Should get a '%' suffix const IhullTypeIGC* pht = m_pship->GetHullType(); float recharge = pht->GetRechargeRate(); float maxEnergy = pht->GetMaxEnergy(); float duration = pdct->energyConsumption <= recharge ? -1.0f : maxEnergy / (pdct->energyConsumption - recharge); float maxDuration = m_maxCloakEnergy <= recharge ? -1.0 : maxEnergy / (m_maxCloakEnergy - recharge); m_pnumberCloakDuration ->SetValue(duration/maxDuration); m_pnumberCloakDurationNumber ->SetValue(duration); //Should get a 's' suffix } void UpdatePackPartInfo(IpartIGC* ppart, IpartTypeIGC* ppartType) { } void UpdateAfterburnerPartInfo(IpartTypeIGC* ppartType) { DataAfterburnerTypeIGC* pdat = (DataAfterburnerTypeIGC*)ppartType->GetData(); float hullSpeed = m_phullType->GetMaxSpeed(); float hullThrust = m_phullType->GetThrust(); float maxSpeed = hullSpeed * (1.0f + (pdat->maxThrust / hullThrust)); float absoluteMaxSpeed = hullSpeed * (1.0f + (m_maxAfterburnerMaxThrust / hullThrust)); float endurance = m_phullType->GetMaxFuel() / (pdat->maxThrust * pdat->fuelConsumption); m_pnumberAfterburnerMaxSpeed->SetValue(maxSpeed / absoluteMaxSpeed); m_pnumberAfterburnerBurnRate ->SetValue(endurance / m_maxAfterburnerBurnRate); m_pnumberAfterburnerMaxSpeedNumber->SetValue(maxSpeed); //Should have a 'mps' suffix m_pnumberAfterburnerBurnRateNumber ->SetValue(endurance); //Should have a 's' suffix } void UpdatePartInfo(Slot* pslot, IpartIGC* ppart, IpartTypeIGC* ppartType) { if (ppartType) { m_pnumberPartID ->SetValue(ppartType->GetObjectID() ); m_pnumberPartMask ->SetValue(ppartType->GetPartMask() ); if (ppartType->GetEquipmentType() == ET_Dispenser) { if (((IlauncherTypeIGC*)ppartType)->GetExpendableType()->GetObjectType() == OT_probeType) m_pnumberEquipmentType->SetValue(ppartType->GetEquipmentType()); else m_pnumberEquipmentType->SetValue(-4); // equipmentTypeMine } else { m_pnumberEquipmentType->SetValue(ppartType->GetEquipmentType()); } m_pstringPartDescription->SetValue(ppartType->GetDescription() ); float signature = ppartType->GetSignature() / trekClient.GetSide()->GetGlobalAttributeSet().GetAttribute(c_gaSignature); m_pnumberSignature ->SetValue(signature / m_maxPartSignature); m_pnumberMass ->SetValue(ppartType->GetMass() / m_maxPartMass); m_pnumberSignatureNumber ->SetValue(signature * 100); m_pnumberMassNumber ->SetValue(ppartType->GetMass()); //m_pstringPartDescription->SetValue("Part desc"); m_pstringPartName->SetValue(GetBuyableName(ppartType)); ZString str = ZString("l") + ZString(ppartType->GetModelName()) + ZString("bmp").ToLower(); TRef pimage = GetModeler()->LoadImage(str, false); m_pwrapImagePart->SetImage(pimage); switch (ppartType->GetEquipmentType()) { case ET_Weapon: UpdateWeaponPartInfo(ppartType); break; case ET_Magazine: UpdateMagazinePartInfo(ppartType); break; case ET_ChaffLauncher: UpdateChaffLauncherPartInfo(ppartType); break; case ET_Dispenser: UpdateDispenserPartInfo(ppartType); break; case ET_Shield: UpdateShieldPartInfo(ppartType); break; case ET_Cloak: UpdateCloakPartInfo(ppartType); break; case ET_Pack: UpdatePackPartInfo(ppart, ppartType); break; case ET_Afterburner: UpdateAfterburnerPartInfo(ppartType); break; } } else { m_pnumberEquipmentType->SetValue(-3); // equipmentTypeNone ZString str = ZString("ldefaultbmp"); TRef pimage = GetModeler()->LoadImage(str, false); m_pwrapImagePart->SetImage(pimage); if (pslot) { EquipmentType equipmentType = pslot->GetEquipmentType(); if (equipmentType == -1) { m_pnumberPartID->SetValue(-1.0f); } else { m_pnumberPartID->SetValue((float)(-(10 + pslot->GetEquipmentType()))); } } else { m_pnumberPartID->SetValue(0); } } } ////////////////////////////////////////////////////////////////////////////// // // Cone of fire // ////////////////////////////////////////////////////////////////////////////// /* void UpdateCone(Slot* pslot) { //m_pmaterialCone; if ( pslot != NULL && pslot->GetEquipmentType() == ET_Weapon ) { Mount mount = pslot->GetMount(); const HardpointData& hd = m_phullType->GetHardpointData(mount); if ((hd.bFixed != true) && (hd.minDot >= -0.75f)) { m_pvisibleGeoCone->SetVisible(true); m_pnumberAngleCone->SetValue(acos(hd.minDot)); const Vector& position = m_phullType->GetWeaponPosition(mount) * (1 / m_phullType->GetScale()); const Orientation& orient = m_phullType->GetWeaponOrientation(mount); m_ptransformCone->SetValue( Matrix( Orientation(orient.GetBackward()), position, m_scaleCone ) ); return; } } m_pvisibleGeoCone->SetVisible(false); } */ ////////////////////////////////////////////////////////////////////////////// // // Slot callbacks // ////////////////////////////////////////////////////////////////////////////// void SlotEntered(Slot* pslot) { IpartIGC* ppart = pslot->GetPart(); UpdatePartInfo( pslot, ppart, ppart ? ppart->GetPartType() : NULL ); //UpdateCone(pslot); } void SlotLeft(Slot* pslot) { //CloseMenu(); UpdatePartInfo(NULL, NULL, NULL); //UpdateCone(NULL); } void SlotClicked(Slot* pslot, bool bNext, const WinPoint& point) { assert (trekClient.GetShip()->GetStation() != NULL); BuyPartMenu(pslot, point); } ////////////////////////////////////////////////////////////////////////////// // // Slot finder // ////////////////////////////////////////////////////////////////////////////// Slot* FindSlot(EquipmentType equipmentType, Mount mount) { SlotList::Iterator iter(m_listSlots); while (!iter.End()) { Slot* pslot = iter.Value(); if ((pslot->GetMount() == mount) && ((mount < 0) || (pslot->GetEquipmentType() == equipmentType))) { return pslot; } iter.Next(); } return NULL; } ////////////////////////////////////////////////////////////////////////////// // // Buy and sell parts // ////////////////////////////////////////////////////////////////////////////// void OnMoneyChange(PlayerInfo* pPlayerInfo) { if (pPlayerInfo == trekClient.MyPlayerInfo()) { m_pnumberMoney->SetValue((float)trekClient.GetMoney()); } } void SellPart(Slot* pslot) { IpartIGC* ppart = pslot->GetPart(); if (ppart != NULL) { ppart->Terminate(); pslot->SetPart(NULL); } UpdateHullType(); } void BuyPart(Slot* pslot, IpartTypeIGC* ppartType) { SellPart(pslot); short amount; if (IlauncherTypeIGC::IsLauncherType(ppartType->GetEquipmentType())) amount = ((IlauncherTypeIGC*)ppartType)->GetAmount(m_pship); else amount = 0x7fff; IpartIGC* ppart = m_pship->CreateAndAddPart(ppartType, pslot->GetMount(), amount); assert (ppart); pslot->SetPart(ppart); UpdateHullType(); } void BuyHull(IhullTypeIGC* phullType) { trekClient.SaveLoadout(m_pship); // remove all of the current parts { SlotList::Iterator iter(m_listSlots); while (!iter.End()) { Slot* pslot = iter.Value(); if (pslot->GetPart()) { pslot->GetPart()->Terminate(); pslot->SetPart(NULL); } iter.Next(); } assert (m_pship->GetParts()->n() == 0); } // give it the default loadout for this hull trekClient.ReplaceLoadout(m_pship, trekClient.GetShip()->GetStation(), phullType, moneyLots); // recalculate the mass and signature of the default loadout m_fSpecMass = m_pship->GetMass(); m_fSpecSignature = m_pship->GetSignature(); trekClient.PlaySoundEffect(mountSound); UpdateHullType(); } ////////////////////////////////////////////////////////////////////////////// // // buttons // ////////////////////////////////////////////////////////////////////////////// bool OnButtonLaunch() { if ((trekClient.GetShip()->GetValue() + trekClient.GetMoney()) >= m_pship->GetValue()) { if (trekClient.GetShip()->GetParentShip() != NULL) trekClient.DisembarkAndBuy(m_pship, true); else trekClient.BuyLoadout(m_pship, true); } return true; } bool OnButtonBuy() { Money cost = m_pship->GetValue() - (trekClient.GetShip()->GetValue() + trekClient.GetMoney()); if (cost > 0) { trekClient.SetMessageType(BaseClient::c_mtGuaranteed); BEGIN_PFM_CREATE(trekClient.m_fm, pfmRequest, CS, REQUEST_MONEY) END_PFM_CREATE pfmRequest->amount = cost; pfmRequest->hidFor = m_pship->GetBaseHullType()->GetObjectID(); } else if (trekClient.GetShip()->GetParentShip() != NULL) trekClient.DisembarkAndBuy(m_pship, false); else trekClient.BuyLoadout(m_pship, false); return true; } bool OnButtonBack() { //GetWindow()->ToggleOverlayFlags(ofLoadout); GetWindow()->SetViewMode(TrekWindow::vmHangar); return true; } bool OnButtonHullList() { assert(trekClient.GetShip()->GetStation() != NULL); HullMenu(); return true; } ////////////////////////////////////////////////////////////////////////////// // // Button Events // ////////////////////////////////////////////////////////////////////////////// void OnTechTreeChanged(SideID sideID) { if (trekClient.GetSideID() == sideID) UpdateNextAndPrevButtons(); } void UpdateNextAndPrevButtons() { bool bEnableNextAndPrev = (GetNextHullType(true) != m_pship->GetBaseHullType()); m_pbuttonNext->SetEnabled(bEnableNextAndPrev); m_pbuttonPrevious->SetEnabled(bEnableNextAndPrev); } IhullTypeIGC* GetNextHullType(bool bForward) { IhullTypeIGC* phtCurrent = m_pship->GetBaseHullType(); IstationIGC* pstation = trekClient.GetShip()->GetStation(); if (pstation != NULL) { const HullTypeListIGC* phullList = trekClient.m_pCoreIGC->GetHullTypes(); // // Seach for the next buyable hulltype // HullTypeLinkIGC* phtlStart = phullList->find(phtCurrent); assert (phtlStart); HullTypeLinkIGC* phtlNow = phtlStart; while (true) { assert (phtlNow); if (bForward) { phtlNow = phtlNow->next(); if (phtlNow == NULL) phtlNow = phullList->first(); } else { phtlNow = phtlNow->txen(); if (phtlNow == NULL) phtlNow = phullList->last(); } IhullTypeIGC* pht = phtlNow->data(); // if we can buy this hull or if we've come full circle if ((pht == phtCurrent) || (pht->GetGroupID() >= 0) && pstation->CanBuy(pht) && (!pstation->IsObsolete(pht))) { return pht; } } } else { return phtCurrent; } } void NextHull(bool bForward) { IhullTypeIGC* pht = GetNextHullType(bForward); IhullTypeIGC* phtCurrent = m_pship->GetBaseHullType(); if (pht != phtCurrent) BuyHull(pht); } bool OnButtonNext() { NextHull(true); return true; } bool OnButtonPrevious() { NextHull(false); return true; } bool OnButtonDefault() { Money budget = moneyLots; trekClient.BuyDefaultLoadout (m_pship, trekClient.GetShip()->GetStation(), m_phullTypeBase, &budget); UpdateHullType(); return true; } ////////////////////////////////////////////////////////////////////////////// // // // ////////////////////////////////////////////////////////////////////////////// bool CanMount(IpartTypeIGC* pparttype) { if (pparttype->GetEquipmentType() == ET_Pack) { return true; } else if (pparttype->GetEquipmentType() == ET_Weapon) { Mount mountMax = m_phullType->GetMaxWeapons(); for (Mount mount = 0; mount < mountMax; mount++) { if (m_phullType->CanMount(pparttype, mount)) return true; } return false; } else { return m_phullType->CanMount(pparttype, 0); } } void BuyPartMenu(Slot* pslot, const WinPoint& pointLocal) { m_pslotMenu = pslot; if (m_phullMenu) { GetWindow()->GetPopupContainer()->ClosePopup(m_phullMenu); m_phullMenu = NULL; } m_pmenu = CreateMenu( GetModeler(), TrekResources::SmallFont(), IMenuCommandSink::CreateDelegate(this) ); bool bAnyItems = false; if (pslot->GetEquipmentType() == NA) { m_pmenu->AddMenuItem(c_midOtherParts, "Parts For Other Ships", 0, m_psubmenuEventSink); bAnyItems = true; } m_pmenu->AddMenuItem(-1, "-Make Slot Empty-"); IstationIGC* pstation = trekClient.GetShip()->GetStation(); assert(pstation); const PartTypeListIGC* plist = trekClient.m_pCoreIGC->GetPartTypes(); for (PartTypeLinkIGC* ppartTypeNode = plist->first(); ppartTypeNode != NULL; ppartTypeNode = ppartTypeNode->next()) { IpartTypeIGC* ppartType = ppartTypeNode->data(); if ((ppartType->GetGroupID() >= 0) && pstation->CanBuy(ppartType) && !pstation->IsObsolete(ppartType)) { EquipmentType equipmentType = ppartType->GetEquipmentType(); if (pslot->GetEquipmentType() == NA) { if (CanMount(ppartType)) { bAnyItems = true; m_pmenu->AddMenuItem( ppartType->GetObjectID(), GetBuyableName(ppartType) ); } } else { if ((equipmentType == pslot->GetEquipmentType()) && m_phullType->CanMount(ppartType, pslot->GetMount())) { bAnyItems = true; m_pmenu->AddMenuItem( ppartType->GetObjectID(), GetBuyableName(ppartType) ); } } } } if (bAnyItems) { Point point = pslot->TransformLocalToImage(pointLocal); GetWindow()->GetPopupContainer()->OpenPopup(m_pmenu, Rect(point, point), true, false); } } TRef GetSubMenu(IMenuItem* pitem) { assert(pitem->GetID() == c_midOtherParts); TRef pmenu = CreateMenu( GetModeler(), TrekResources::SmallFont(), IMenuCommandSink::CreateDelegate(this) ); // create a menu with every part we can't mount IstationIGC* pstation = trekClient.GetShip()->GetStation(); const PartTypeListIGC* plist = trekClient.m_pCoreIGC->GetPartTypes(); for (PartTypeLinkIGC* ppartTypeNode = plist->first(); ppartTypeNode != NULL; ppartTypeNode = ppartTypeNode->next()) { IpartTypeIGC* ppartType = ppartTypeNode->data(); if ((ppartType->GetGroupID() >= 0) && pstation->CanBuy(ppartType) && !pstation->IsObsolete(ppartType)) { if (!CanMount(ppartType)) { pmenu->AddMenuItem( ppartType->GetObjectID(), GetBuyableName(ppartType) ); } } } return pmenu; } void HullMenu(void) { IhullTypeIGC* phullTypeCurrent = m_pship->GetBaseHullType(); IstationIGC* pstation = trekClient.GetShip()->GetStation(); if (m_pmenu) { GetWindow()->GetPopupContainer()->ClosePopup(m_pmenu); m_pmenu = NULL; m_pslotMenu = NULL; } m_phullMenu = CreateMenu( GetModeler(), TrekResources::SmallFont(), IMenuCommandSink::CreateDelegate(this) ); const HullTypeListIGC* phullList = trekClient.m_pCoreIGC->GetHullTypes(); for ( HullTypeLinkIGC* phullTypeNode = phullList->first(); phullTypeNode != NULL; phullTypeNode = phullTypeNode->next() ) { IhullTypeIGC* phullType = phullTypeNode->data(); if ((phullType == phullTypeCurrent) || ((phullType->GetGroupID() >= 0) && (pstation->CanBuy(phullType)) && (!pstation->IsObsolete(phullType)))) { m_phullMenu->AddMenuItem( phullType->GetObjectID(), GetBuyableName(phullType) ); } #if 0 { const GlobalAttributeSet& ga = trekClient.GetSide()->GetGlobalAttributeSet(); if (pstation->CanBuy(phullType)) { debugf("%s\n", phullType->GetName()); debugf("\tTop speed\t\t%8.2f mps\n", phullType->GetMaxSpeed() * ga.GetAttribute(c_gaMaxSpeed)); debugf("\tAcceleration\t%8.2f mpss\n", phullType->GetThrust() * ga.GetAttribute(c_gaThrust) / phullType->GetMass()); debugf("\tTurn rate\t\t%8.2f degrees/second\n", 180.0f * phullType->GetMaxTurnRate(c_axisYaw) * ga.GetAttribute(c_gaTurnRate) / pi); debugf("\tHit points\t\t%8.2f\n", phullType->GetHitPoints() * ga.GetAttribute(c_gaMaxArmorShip)); debugf("\tScan range\t\t%8.2f m\n", phullType->GetScannerRange() * ga.GetAttribute(c_gaScanRange)); } } #endif } GetWindow()->GetPopupContainer()->OpenPopup(m_phullMenu, Rect(260, 450, 340, 530), true, false); } void CloseMenu() { if (m_pmenu) { GetWindow()->GetPopupContainer()->ClosePopup(m_pmenu); m_pmenu = NULL; m_pslotMenu = NULL; } if (m_phullMenu) { GetWindow()->GetPopupContainer()->ClosePopup(m_phullMenu); m_phullMenu = NULL; } } void OnMenuCommand(IMenuItem* pitem) { // , I don't know why this is getting called twice for the same // menu if (m_pslotMenu != NULL) { SellPart(m_pslotMenu); IpartTypeIGC* ppartType = trekClient.m_pCoreIGC->GetPartType( pitem->GetID() ); if (pitem->GetID() != -1) { IpartTypeIGC* ppartType = trekClient.m_pCoreIGC->GetPartType( pitem->GetID() ); // // !!! make sure the part is available // if (ppartType) { BuyPart(m_pslotMenu, ppartType); } trekClient.PlaySoundEffect(mountSound); } else { trekClient.PlaySoundEffect(unmountSound); } UpdatePartInfo(NULL, NULL, ppartType); CloseMenu(); } else if (m_phullMenu !=NULL) { IhullTypeIGC* phullType = trekClient.m_pCoreIGC->GetHullType(pitem->GetID()); if (phullType != m_pship->GetBaseHullType()) { BuyHull(phullType); } CloseMenu(); } else { ZAssert(m_pmenu == NULL); } } void OnMenuSelect(IMenuItem* pitem) { if (m_pslotMenu != NULL) { if (pitem->GetID() == -1) { UpdatePartInfo(NULL, NULL, NULL); } else { IpartTypeIGC* ppartType = trekClient.m_pCoreIGC->GetPartType( pitem->GetID() ); UpdatePartInfo(NULL, NULL, ppartType); } } } void OnMenuClose(IMenu* pmenu) { UpdatePartInfo(NULL, NULL, NULL); } ////////////////////////////////////////////////////////////////////////////// // // Update Hull Type // // This is called whenever something external has changed the hull, // the game starts, or when a player docks. // ////////////////////////////////////////////////////////////////////////////// void HullSwitched() { // // Fix the hull info // UpdatePerformanceInfo(); // // Remove the old slots // SlotList::Iterator iter(m_listSlots); while (!iter.End()) { Slot* pslot = iter.Value(); pslot->RemoveSelf(); iter.Remove(); } // // Load the Geo // { TRef pns = m_pmodeler->GetNameSpace(m_phullType->GetModelName()); if (pns) { TRef pthing = ThingGeo::Create(m_pmodeler, m_ptime); pthing->LoadMDL(0, pns, NULL); pthing->SetShadeAlways(true); SetGeo(pthing->GetGeo()); } } // // Update the geo image overlay // { ZString str = ZString("loadout") + ZString(m_phullType->GetObjectID()) + ZString("overlay"); TRef pimage = m_pnsLoadout->FindImage(str); if (pimage != NULL) { m_pwrapImageGeo->SetImage(pimage); } else { m_pwrapImageGeo->SetImage(Image::GetEmpty()); } } // // Load the slots // { // // Find the loadout definition // ZString str = ZString("loadout") + ZString(m_phullType->GetObjectID()); TRef plist = m_pnsLoadout->FindList(str); if (plist == NULL) { plist = m_pnsLoadout->FindList("loadoutDefault"); } // // Parse the slot info // plist->GetFirst(); while (plist->GetCurrent() != NULL) { TRef ppair; CastTo(ppair, plist->GetCurrent()); EquipmentType equipmentType = (EquipmentType)(int)GetNumber(ppair->GetNth(0)); Mount mount = (Mount)GetNumber(ppair->GetNth(1)); TRef pstrPrefix = StringValue::Cast((Value*)ppair->GetNth(2)); TRef pimageDefault = Image::Cast((Value*)ppair->GetNth(3)); TRef ppointOffset = PointValue::Cast(ppair->GetLastNth(4)); TRef pRowPane = new RowPane(); // // Does the ship support the slot? // bool bMount = Slot::SlotValidForHull(m_phullType, equipmentType, mount); // // Add the slot if the ship supports it // if (bMount) { TRef pslot = new Slot( this, equipmentType, equipmentType == NA ? (mount - c_maxCargo) : mount, pimageDefault, pstrPrefix->GetValue() ); pslot->SetOffset(WinPoint::Cast(ppointOffset->GetValue())); m_ppane->InsertAtTop(pslot); m_listSlots.PushEnd(pslot); } plist->GetNext(); } } PartsSwitched(); } void PartsSwitched() { // // Update all of the slots to the stuff that is actually on the ship // const PartListIGC* plist = m_pship->GetParts(); for( const PartLinkIGC* ppartLink = plist->first(); ppartLink != NULL; ppartLink = ppartLink->next() ) { IpartIGC* ppart = ppartLink->data(); IpartTypeIGC* ppartType = ppart->GetPartType(); EquipmentType equipmentType = ppart->GetEquipmentType(); Mount mount = ppart->GetMountID(); // // Find the slot // Slot* pslot = FindSlot(equipmentType, mount); if (pslot) { pslot->SetPart(ppart); } } } void UpdateHullType(void) { UpdateButtons(); { // // Close the menu // //CloseMenu(); // // Grab the new hull type // bool bNewHull = (m_phullTypeBase != m_pship->GetBaseHullType()); m_phullType = m_pship->GetHullType(); m_phullTypeBase = m_pship->GetBaseHullType(); if (m_phullTypeBase == NULL) { // // Don't have a hull the game must be exiting // return; } // // Update the slots // if (bNewHull) HullSwitched(); else { // // Empty all of the slots // SlotList::Iterator iter(m_listSlots); while (!iter.End()) { Slot* pslot = iter.Value(); pslot->SetPart(NULL); iter.Next(); } PartsSwitched(); // // Update the performance info // UpdatePerformanceInfo(); } } } void UpdateButtons() { Money cost = m_pship->GetValue(); Money shortfall; if (cost <= trekClient.GetMoney()) shortfall = 0; else shortfall = cost - (trekClient.GetShip()->GetValue() + trekClient.GetMoney()); bool bAlreadyOwn = m_pship->EquivalentShip(trekClient.GetShip()); bool bCanAfford = shortfall <= 0; bool bCanBuy = bCanAfford; if (!bCanBuy) { //Can anyone on the team afford it? for (ShipLinkIGC* psl = trekClient.GetSide()->GetShips()->first(); (psl != NULL); psl = psl->next()) { if (psl->data() != trekClient.GetShip()) { PlayerInfo* ppi = (PlayerInfo*)(psl->data()->GetPrivateData()); if (ppi->GetMoney() >= shortfall) { bCanBuy = true; break; } } } } m_pnumberNewShipCost->SetValue(cost); if (bAlreadyOwn) m_pnumberLoadoutShipState->SetValue(0); else if (cost <= 0) m_pnumberLoadoutShipState->SetValue(1); else if (bCanAfford) m_pnumberLoadoutShipState->SetValue(2); else m_pnumberLoadoutShipState->SetValue(3); m_pbuttonLaunch->SetEnabled(bAlreadyOwn || bCanAfford); m_pbuttonBuy->SetEnabled(!bAlreadyOwn && bCanBuy); m_pbuttonConfirm->SetEnabled(!bAlreadyOwn); if (m_pship->GetValue() != 0){ m_ppaneHoverBuy->SetOffset(WinPoint::Cast(m_ppointBuyButton->GetValue())); m_ppaneHoverConfirm->SetOffset(WinPoint(-100, -100)); } else { m_ppaneHoverBuy->SetOffset(WinPoint(-100, -100)); m_ppaneHoverConfirm->SetOffset(WinPoint::Cast(m_ppointBuyButton->GetValue())); } } void OnPurchaseCompleted(bool bAllPartsBought) { if (!bAllPartsBought) { TRef pmsgBox = CreateMessageBox( "Some of the parts you requested are no longer available"); GetWindow()->GetPopupContainer()->OpenPopup(pmsgBox, false); // copy their new loadout m_pship->Terminate(); m_pship->Release(); m_pship = trekClient.CopyCurrentShip(); } m_pnumberOldShipCost->SetValue(trekClient.GetShip()->GetValue()); UpdateHullType(); } }; ////////////////////////////////////////////////////////////////////////////// // // Constructor // ////////////////////////////////////////////////////////////////////////////// TRef CreateLoadout(Modeler* pmodeler, Number* ptime) { return new LoadoutImpl(pmodeler, ptime); }