#include "pch.h" #include "sounds.h" ////////////////////////////////////////////////////////////////////////////// // // IGCObjectFactory // ////////////////////////////////////////////////////////////////////////////// typedef TRef TRefIObject; //hack for VC5 template class TIGCObjectFactory : public IFunction { private: typedef TRef (ClassType::*PFNMember)(ObjectStack& stack); TRef m_pobj; PFNMember m_pfn; public: TIGCObjectFactory(ClassType* pobj, PFNMember pfn) : m_pobj(pobj), m_pfn(pfn) { } TRefIObject Apply(ObjectStack& stack) { return (m_pobj->*m_pfn)(stack); } }; ////////////////////////////////////////////////////////////////////////////// // // SphericalRegion // ////////////////////////////////////////////////////////////////////////////// class SphericalRegionImpl : public SphericalRegion { private: TRef m_pmodelCenter; float m_radiusSquared; public: SphericalRegionImpl(ImodelIGC* pmodel, float radius) : m_pmodelCenter(pmodel), m_radiusSquared(radius * radius) { } bool InRegion(ImodelIGC* pmodel) { return ((pmodel->GetPosition() - m_pmodelCenter->GetPosition()).LengthSquared() <= m_radiusSquared); } }; TRef SphericalRegion::Create(ImodelIGC* pmodel, float radius) { return new SphericalRegionImpl(pmodel, radius); } ////////////////////////////////////////////////////////////////////////////// // // RegionAdviseEntry // ////////////////////////////////////////////////////////////////////////////// class RegionAdviseEntry : public IObject { private: TRef m_pregion; TMap, bool> m_mapInRegion; TList > m_lstUnadvise; public: RegionAdviseEntry(Region* pregion) : m_pregion(pregion) { } void Advise(ImodelIGC* pmodel) { m_mapInRegion.Set(pmodel, m_pregion->InRegion(pmodel)); m_lstUnadvise.Remove(pmodel); } void Unadvise(ImodelIGC* pmodel) { m_lstUnadvise.PushEnd(pmodel); } void UpdateUnadvise() { TList >::Iterator iter(m_lstUnadvise); while (!iter.End()) { m_mapInRegion.Remove(iter.Value()); iter.Next(); } m_lstUnadvise.SetEmpty(); } void Update(MissionManager* pmanager) { TMap, bool>::Iterator iter(m_mapInRegion); while (!iter.End()) { bool bInRegion = iter.Value(); TRef pmodel = iter.Key(); if (bInRegion != m_pregion->InRegion(pmodel) && !m_lstUnadvise.Find(pmodel)) { if (bInRegion) pmanager->FireOnExitedRegion(pmodel, m_pregion); else pmanager->FireOnEnteredRegion(pmodel, m_pregion); m_mapInRegion.Set(pmodel, !bInRegion); } iter.Next(); } UpdateUnadvise(); } }; ////////////////////////////////////////////////////////////////////////////// // // MissionManager // ////////////////////////////////////////////////////////////////////////////// class MissionManagerImpl : public MissionManager { private: TRef m_pmissionContext; TList > m_lstEventHandlers; TMap, TRef > m_mapRegionAdviseEntries; TRef m_pmissionStage; TRef m_pnsClusters; TRef m_pnsTechTree; short m_clusterIDNext; short m_asteroidIDNext; short m_stationTypeIDNext; short m_hullIDNext; short m_partTypeIDNext; short m_shipIDNext; short m_projectileTypeIDNext; short m_expendableTypeIDNext; public: MissionManagerImpl(MissionContext* pmissionContext) : m_pmissionContext(pmissionContext), m_clusterIDNext(0), m_asteroidIDNext(0), m_hullIDNext(0), m_stationTypeIDNext(0), m_partTypeIDNext(0), m_projectileTypeIDNext(0), m_expendableTypeIDNext(0), m_shipIDNext(0) { } TRef GetHullType(const ZString& strHullType) { TRef phullType; if (m_pnsTechTree) phullType = (IhullTypeIGC*)m_pnsTechTree->FindMember(strHullType); return phullType; } int ReadPartData(IhullTypeIGC* phullType, PartData* ppartData, IObjectList* ppartsList) { Mount rgMounts[ET_MAX - 1]; memset(rgMounts, 0, sizeof(Mount)*(ET_MAX-1)); int nParts = 0; ppartsList->GetFirst(); while (NULL != ppartsList->GetCurrent()) { TRef ppartType = (IpartTypeIGC*)ppartsList->GetCurrent(); EquipmentType et = ppartType->GetEquipmentType(); Mount mountETMax = 1; if (ET_Weapon == et) mountETMax = phullType->GetMaxWeapons(); nParts++; rgMounts[et-1]++; ppartData->partID = ppartType->GetObjectID(); ppartData->mountID = rgMounts[et-1] > mountETMax ? NA : rgMounts[et-1]-1; ppartData->amount = 0; ppartData++; ppartsList->GetNext(); } return nParts; } Drone* CreateDrone(DroneType dt, const ZString& strLoadout, SideID sideID, const ZString& strName, const Vector& pos, IclusterIGC* pcluster) { ZAssert(m_pnsTechTree); TRef pparamList = (IObjectList*)m_pnsTechTree->FindMember(strLoadout); // hulltype TRef phullType = (IhullTypeIGC*)pparamList->GetFirst(); HullID hullID = phullType->GetObjectID(); // parts TRef ppartsList = (IObjectList*)pparamList->GetNext(); PartData partData[10]; memset(partData, 0, sizeof(PartData)*10); int cParts = ReadPartData(phullType, partData, ppartsList); Drone* pdrone = g_drones.Create( m_pmissionContext->GetMissionIGC(), dt, strName, hullID, m_pmissionContext->GetMissionIGC()->GetSide(sideID), cParts, partData, pcluster, pos); return pdrone; } TRef CreateShip(const ZString& strLoadout, SideID sideID, const ZString& strName, ShipID shipID = -1) { ZAssert(m_pnsTechTree); char buf[4096]; DataShipIGC* pdata = (DataShipIGC*)buf; memset(buf, 0, 4096); PartData* ppartData = (PartData*)(buf + sizeof(DataShipIGC)); TRef pparamList = (IObjectList*)m_pnsTechTree->FindMember(strLoadout); TRef phullType = (IhullTypeIGC*)pparamList->GetFirst(); pdata->hullID = phullType->GetObjectID(); pdata->shipID = (shipID == -1) ? m_shipIDNext++ : shipID; pdata->cmLegal = -1; pdata->sideID = sideID; strcpy(pdata->name, strName); pdata->partsOffset = sizeof(DataShipIGC); TRef ppartsList = (IObjectList*)pparamList->GetNext(); pdata->nParts = ReadPartData(phullType, ppartData, ppartsList); IshipIGC* pship = (IshipIGC*)m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_ship, pdata, sizeof(DataShipIGC) + sizeof(PartData)*pdata->nParts); pship->Release(); return pship; } void ReadBuyableData(DataBuyableIGC* pdata, ObjectStack& stack) { pdata->price = (Money)GetNumber((IObject*)stack.Pop()); strcpy(pdata->modelName, GetString((IObject*)stack.Pop())); strcpy(pdata->name, GetString((IObject*)stack.Pop())); strcpy(pdata->description, GetString((IObject*)stack.Pop())); TRef plistRequired; CastTo(plistRequired, (IObject*)stack.Pop()); plistRequired->GetFirst(); while (NULL != plistRequired->GetCurrent()) { pdata->ttbmRequired.SetBit((int)GetNumber((IObject*)plistRequired->GetCurrent())); plistRequired->GetNext(); } TRef plistEffects; CastTo(plistEffects, (IObject*)stack.Pop()); plistEffects->GetFirst(); while (NULL != plistEffects->GetCurrent()) { pdata->ttbmEffects.SetBit((int)GetNumber((IObject*)plistEffects->GetCurrent())); plistEffects->GetNext(); } } void ReadPartTypeData(DataPartTypeIGC* pdata, EquipmentType et, ObjectStack& stack) { ReadBuyableData(pdata, stack); pdata->successorPartID = NA; pdata->partID = m_partTypeIDNext++; pdata->equipmentType = et; pdata->mass = GetNumber((IObject*)stack.Pop()); pdata->signature = GetNumber((IObject*)stack.Pop()); pdata->treasureChance = (short)GetNumber((IObject*)stack.Pop()); } void ReadDataObject(DataObjectIGC* pdata, ObjectStack& stack) { pdata->color.r = pdata->color.g = pdata->color.b = pdata->color.a = 0; //GetColor((IObject*)stack.Pop()); pdata->radius = GetNumber((IObject*)stack.Pop()); pdata->rotation = GetNumber((IObject*)stack.Pop()); strcpy(pdata->modelName, GetString((IObject*)stack.Pop())); strcpy(pdata->textureName, GetString((IObject*)stack.Pop())); } void ReadLauncherDef(LauncherDef* pdata, ObjectStack& stack) { ReadBuyableData(pdata, stack); pdata->signature = GetNumber((IObject*)stack.Pop()); pdata->mass = GetNumber((IObject*)stack.Pop()); } void ReadDataExpendableType(DataExpendableTypeIGC* pdata, ObjectStack& stack) { ReadDataObject(pdata, stack); pdata->expendabletypeID = m_expendableTypeIDNext++; pdata->loadTime = GetNumber((IObject*)stack.Pop()); pdata->lifespan = GetNumber((IObject*)stack.Pop()); pdata->signature = GetNumber((IObject*)stack.Pop()); pdata->hitPoints = (HitPoints)GetNumber((IObject*)stack.Pop()); ReadLauncherDef(&(pdata->launcherDef), stack); } TRef CreateMissileType(ObjectStack& stack) { DataMissileTypeIGC missile; memset(&missile, 0, sizeof(missile)); ReadDataExpendableType(&missile, stack); missile.acceleration = GetNumber((IObject*)stack.Pop()); missile.turnRate = GetNumber((IObject*)stack.Pop()); missile.initialSpeed = GetNumber((IObject*)stack.Pop()); missile.armTime = GetNumber((IObject*)stack.Pop()); missile.lockTime = GetNumber((IObject*)stack.Pop()); missile.readyTime = GetNumber((IObject*)stack.Pop()); missile.dispersion = GetNumber((IObject*)stack.Pop()); missile.lockAngle = GetNumber((IObject*)stack.Pop()); missile.power = GetNumber((IObject*)stack.Pop()); missile.blastPower = GetNumber((IObject*)stack.Pop()); missile.blastRadius = GetNumber((IObject*)stack.Pop()); missile.width = GetNumber((IObject*)stack.Pop()); missile.damageType = (DamageTypeMask)GetNumber((IObject*)stack.Pop()); missile.bDirectional = GetBoolean((IObject*)stack.Pop()); IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_missileType, &missile, sizeof(missile)); pobject->Release(); return pobject; //return NULL; } TRef CreateMissileLauncherType(ObjectStack& stack) { DataLauncherTypeIGC launcher; memset(&launcher, 0, sizeof(launcher)); launcher.partID = m_partTypeIDNext++; launcher.successorPartID = NA; TRef pmissileType = (ImissileTypeIGC*)(IObject*)stack.Pop(); launcher.expendabletypeID = pmissileType->GetObjectID(); launcher.amount = (short)GetNumber((IObject*)stack.Pop()); launcher.treasureChance = (short)GetNumber((IObject*)stack.Pop()); IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_partType, &launcher, sizeof(launcher)); pobject->Release(); return pobject; } TRef CreatePackType(ObjectStack& stack) { DataPackTypeIGC pack; memset(&pack, 0, sizeof(pack)); ReadPartTypeData(&pack, ET_Pack, stack); pack.amount = (short)GetNumber((IObject*)stack.Pop()); pack.packType = (PackType)GetNumber((IObject*)stack.Pop()); IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject( Time::Now(), OT_partType, &pack, sizeof(pack)); pobject->Release(); return pobject; } TRef CreateProjectileType(ObjectStack& stack) { DataProjectileTypeIGC projectile; memset(&projectile, 0, sizeof(projectile)); projectile.projectileTypeID = m_projectileTypeIDNext++; ReadDataObject(&projectile, stack); projectile.power = GetNumber((IObject*)stack.Pop()); projectile.blastPower = GetNumber((IObject*)stack.Pop()); projectile.blastRadius = GetNumber((IObject*)stack.Pop()); projectile.speed = GetNumber((IObject*)stack.Pop()); projectile.lifespan = GetNumber((IObject*)stack.Pop()); projectile.damageType = (DamageTypeMask)GetNumber((IObject*)stack.Pop()); projectile.absoluteF = GetBoolean((IObject*)stack.Pop()); projectile.bDirectional = GetBoolean((IObject*)stack.Pop()); projectile.width = GetNumber((IObject*)stack.Pop()); IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_projectileType, &projectile, sizeof(projectile)); pobject->Release(); return pobject; } TRef CreateStationType(ObjectStack& stack) { DataStationTypeIGC st; memset(&st, 0, sizeof(st)); st.stationTypeID = m_stationTypeIDNext++; st.maxArmorHitPoints = 5000.0f; st.maxShieldHitPoints = 250.0f; st.armorRegeneration = 10.0f; st.shieldRegeneration = 5.0f; strcpy(st.modelName, GetString((IObject*)stack.Pop())); strcpy(st.name, "Mining Platform"); strcpy(st.description, "Mining Platform"); st.price = 1000; st.timeToBuild = 100; st.textureName[0] = '\0'; st.radius = (float)GetNumber((IObject*)stack.Pop()); st.animIdle.start = 0.0f; st.animIdle.stop = 40.0f; st.ttbmRequired.ClearAll(); st.ttbmEffects.ClearAll(); st.ttbmLocal.ClearAll(); st.signature = 2.5f; st.scannerRange = 2000.0f; st.mcStationClass = c_mcStarbase; st.dsuUpgrade.stidUpgrade = NA; st.sabmCapabilities = c_sabmUnload | c_sabmStart | c_sabmRestart | c_sabmRepair | c_sabmLoadoutMenu | c_sabmRipcord | c_sabmReload; IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_stationType, &st, sizeof(st)); pobject->Release(); return pobject; } TRef CreateStation(ObjectStack& stack) { DataStationIGC ds; memset(&ds, 0, sizeof(ds)); // get the clusterid TRef pcluster; CastTo(pcluster, (IObject*)stack.Pop()); ds.clusterID = pcluster->GetObjectID(); // get the station type TRef pstationType; CastTo(pstationType, (IObject*)stack.Pop()); ds.stationTypeID = pstationType->GetObjectID(); strcpy(ds.name, pstationType->GetName()); ds.position = GetVector((IObject*)stack.Pop()); ds.forward = Vector::RandomDirection(); static const Vector xAxis(1.0, 0.0, 0.0); ds.up = CrossProduct(ds.forward, xAxis); if (ds.up.LengthSquared() < 0.1f) { static const Vector zAxis(0.0, 0.0, 1.0); ds.up = CrossProduct(ds.forward, zAxis); } assert (ds.up.LengthSquared() > 0.1f); ds.up.SetNormalize(); ds.rotation.axis(ds.forward); ds.rotation.angle(0.05f + random(0.0f, 0.05f)); ds.sideID = (SideID)GetNumber((IObject*)stack.Pop()); ds.stationID = m_pmissionContext->GetMissionIGC()->GenerateNewStationID(); IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_station, &ds, sizeof(ds)); pobject->Release(); return pobject; } TRef CreateHullType(ObjectStack& stack) { BYTE rgbData[4096]; DataHullTypeIGC* pHullType = (DataHullTypeIGC*)rgbData; memset(pHullType, 0, 4096); pHullType->hullID = m_hullIDNext++; ReadBuyableData(pHullType, stack); pHullType->successorHullID = NA; pHullType->mass = GetNumber((IObject*)stack.Pop()); pHullType->signature = GetNumber((IObject*)stack.Pop()); pHullType->speed = GetNumber((IObject*)stack.Pop()); for (int i = 0; i < 3; i++) pHullType->maxTurnRates[i] = GetNumber((IObject*)stack.Pop()); //yaw, pitch, roll for (i = 0; i < 3; i++) pHullType->turnTorques[i] = GetNumber((IObject*)stack.Pop()); //yaw, pitch, roll pHullType->thrust = GetNumber((IObject*)stack.Pop()); pHullType->sideMultiplier = GetNumber((IObject*)stack.Pop()); pHullType->backMultiplier = GetNumber((IObject*)stack.Pop()); pHullType->scannerRange = GetNumber((IObject*)stack.Pop()); pHullType->maxEnergy = GetNumber((IObject*)stack.Pop()); pHullType->rechargeRate = GetNumber((IObject*)stack.Pop()); pHullType->maxWeapons = (Mount)GetNumber((IObject*)stack.Pop()); pHullType->maxFixedWeapons = pHullType->maxWeapons; pHullType->hitPoints = (HitPoints)GetNumber((IObject*)stack.Pop()); pHullType->length = (short)GetNumber((IObject*)stack.Pop()); pHullType->habmCapabilities = (HullAbilityBitMask)GetNumber((IObject*)stack.Pop()); strcpy(pHullType->textureName, GetString((IObject*)stack.Pop())); pHullType->mcShipClass = (ModelClass)GetNumber((IObject*)stack.Pop()); AnimationData* panimationData = pHullType->animations; TRef plistAnimationData; CastTo(plistAnimationData, (IObject*)stack.Pop()); plistAnimationData->GetFirst(); while (NULL != plistAnimationData->GetCurrent()) { TRef pparams; CastTo(pparams, (IObject*)plistAnimationData->GetCurrent()); panimationData->start = GetNumber((IObject*)pparams->GetFirst()); panimationData->stop = GetNumber((IObject*)pparams->GetSecond()); panimationData++; plistAnimationData->GetNext(); } pHullType->hardpointOffset = sizeof(DataHullTypeIGC); HardpointData* pHardPoint = (HardpointData *) (pHullType + 1); int cHardpoints = 0; TRef plistHardPoints; CastTo(plistHardPoints, (IObject*)stack.Pop()); plistHardPoints->GetFirst(); while (NULL != plistHardPoints->GetCurrent()) { strcpy(pHardPoint->frameName, GetString((IObject*)plistHardPoints->GetCurrent())); pHardPoint->bFixed = true; cHardpoints ++; pHardPoint++; plistHardPoints->GetNext(); } IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_hullType, rgbData, sizeof(DataHullTypeIGC) + sizeof(HardpointData)*cHardpoints); pobject->Release(); return pobject; } TRef CreateWeaponType(ObjectStack& stack) { DataWeaponTypeIGC weapon; memset(&weapon, 0, sizeof(weapon)); ReadPartTypeData(&weapon, ET_Weapon, stack); weapon.dtimeReady = GetNumber((IObject*)stack.Pop()); weapon.dtimeBurst = GetNumber((IObject*)stack.Pop()); weapon.energyPerShot = GetNumber((IObject*)stack.Pop()); weapon.dispersion = GetNumber((IObject*)stack.Pop()); weapon.cAmmoPerShot = (short)GetNumber((IObject*)stack.Pop()); TRef pprojectileType = (IprojectileTypeIGC*)(IObject*)stack.Pop(); weapon.projectileTypeID = pprojectileType->GetObjectID(); weapon.soundID = (short)GetNumber((IObject*)stack.Pop()); IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_partType, &weapon, sizeof(weapon)); pobject->Release(); return pobject; } TRef CreateAfterburnerType(ObjectStack& stack) { DataAfterburnerTypeIGC afterburner; memset(&afterburner, 0, sizeof(afterburner)); ReadPartTypeData(&afterburner, ET_Afterburner, stack); afterburner.fuelConsumption = GetNumber((IObject*)stack.Pop()); afterburner.maxThrust = GetNumber((IObject*)stack.Pop()); afterburner.onRate = GetNumber((IObject*)stack.Pop()); afterburner.offRate = GetNumber((IObject*)stack.Pop()); afterburner.thrustMultiplier = GetNumber((IObject*)stack.Pop()); IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject( Time::Now(), OT_partType, &afterburner, sizeof(afterburner)); pobject->Release(); return pobject; } TRef CreateCluster(ObjectStack& stack) { DataClusterIGC data; memset(&data, 0, sizeof(data)); // assign a new cluster id data.clusterID = m_clusterIDNext++; // name, etc strcpy(data.name, GetString((IObject*)stack.Pop())); strcpy(data.posterName, GetString((IObject*)stack.Pop())); // lighting data.lightDirection = Vector::RandomDirection(); //GetVector((IObject*)stack.Pop()); data.lightColor = 0xffffffff; //D3DRGBA(color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha()); // positioning data.screenX = GetNumber((IObject*)stack.Pop()); data.screenY = GetNumber((IObject*)stack.Pop()); // properties data.starSeed = rand(); data.nDebris = randomInt(250, 750); data.nStars = randomInt(250, 750); data.activeF = false; IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_cluster, &data, sizeof(data)); pobject->Release(); return pobject; } TRef CreateSphericalRegion(ObjectStack& stack) { TRef pmodel; CastTo(pmodel, (IObject*)stack.Pop()); float radius = GetNumber((IObject*)stack.Pop()); return (Region*)SphericalRegion::Create(pmodel, radius); } TRef GetRegion(const ZString& strRegion) { ZAssert(m_pnsClusters); return (Region*)m_pnsClusters->FindMember(strRegion); } TRef CreateDrone(ObjectStack& stack) { // cluster TRef pcluster; CastTo(pcluster, (IObject*)stack.Pop()); // position Vector pos = GetVector((IObject*)stack.Pop()); // name ZString strName = GetString((IObject*)stack.Pop()); //dronetype DroneType dt = (DroneType)(WORD)GetNumber((IObject*)stack.Pop()); //side SideID sideID = (SideID)GetNumber((IObject*)stack.Pop()); // loadout TRef pparamList; CastTo(pparamList, (IObject*)stack.Pop()); // hulltype TRef phullType = (IhullTypeIGC*)pparamList->GetFirst(); HullID hullID = phullType->GetObjectID(); // parts TRef ppartsList = (IObjectList*)pparamList->GetNext(); PartData partData[10]; int cParts = ReadPartData(phullType, partData, ppartsList); Drone* pdrone = g_drones.Create( m_pmissionContext->GetMissionIGC(), dt, strName, hullID, m_pmissionContext->GetMissionIGC()->GetSide(sideID), cParts, partData, pcluster, pos); return pdrone->GetShip(); } TRef CreateAsteroid(ObjectStack& stack) { DataAsteroidIGC data; memset(&data, 0, sizeof(data)); // get the clusterid TRef pcluster; CastTo(pcluster, (IObject*)stack.Pop()); data.clusterID = pcluster->GetObjectID(); // assign a new asteroid id data.asteroidDef.asteroidID = m_asteroidIDNext++; // name, texture, model strcpy(data.name, GetString((IObject*)stack.Pop())); strcpy(data.asteroidDef.modelName, GetString((IObject*)stack.Pop())); strcpy(data.asteroidDef.textureName, GetString((IObject*)stack.Pop())); // properties data.mass = GetNumber((IObject*)stack.Pop()); data.asteroidDef.radius = (short)GetNumber((IObject*)stack.Pop()); data.asteroidDef.hitpoints = (short)GetNumber((IObject*)stack.Pop()); data.asteroidDef.ore = GetNumber((IObject*)stack.Pop()); // positioning data.position = GetVector((IObject*)stack.Pop()); data.forward = Vector::RandomDirection(); static const Vector xAxis(1.0, 0.0, 0.0); data.up = CrossProduct(data.forward, xAxis); if (data.up.LengthSquared() < 0.1f) { static const Vector zAxis(0.0, 0.0, 1.0); data.up = CrossProduct(data.forward, zAxis); } assert (data.up.LengthSquared() > 0.1f); data.up.SetNormalize(); data.rotation.axis(data.forward); data.rotation.angle(0.05f + random(0.0f, 0.05f)); /* data.position = GetVector((IObject*)stack.Pop()); data.up = GetVector((IObject*)stack.Pop()); data.forward = GetVector((IObject*)stack.Pop()); TRef ppair; CastTo(ppair, (IObject*)stack.Pop()); data.rotation = Rotation( GetVector(ppair->GetFirst()), GetNumber(ppair->GetSecond())); */ // capabilites TRef plist; CastTo(plist, (IObject*)stack.Pop()); plist->GetFirst(); while (NULL != plist->GetCurrent()) { data.asteroidDef.aabmCapabilities |= (short)GetNumber((IObject*)plist->GetCurrent()); plist->GetNext(); } IObject* pobject = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_asteroid, &data, sizeof(data)); pobject->Release(); return pobject; } void CreateDefaults() { IObject* pobj; // Default Hull Type DataHullTypeIGC hullType; hullType.hullID = m_hullIDNext++; memset(&hullType, 0, sizeof(hullType)); hullType.successorHullID = NA; strcpy(hullType.modelName, "fig12"); pobj = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_hullType, &hullType, sizeof(hullType)); assert (pobj); pobj->Release(); // Default Station Type DataStationTypeIGC st; st.stationTypeID = 0; st.maxArmorHitPoints = 500.0f; st.maxShieldHitPoints = 250.0f; st.armorRegeneration = 1.0f; st.shieldRegeneration = 5.0f; strcpy(st.modelName, "acs05"); strcpy(st.name, "Station"); strcpy(st.description, "Station"); st.price = 1000; st.timeToBuild = 100; st.textureName[0] = '\0'; st.radius = 125; st.animIdle.start = 0.0f; st.animIdle.stop = 40.0f; st.ttbmRequired.ClearAll(); st.ttbmEffects.ClearAll(); st.ttbmLocal.ClearAll(); st.signature = 2.5f; st.scannerRange = 2000.0f; st.mcStationClass = c_mcStarbase; st.dsuUpgrade.stidUpgrade = NA; st.sabmCapabilities = c_sabmUnload | c_sabmStart | c_sabmRestart | c_sabmLand | c_sabmRepair | c_sabmLoadoutMenu | c_sabmRipcord | c_sabmReload; pobj = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_stationType, &st, sizeof(st)); assert (pobj); pobj->Release(); // Construction Drone DataDroneTypeIGC d; d.timeToBuild = 30; d.droneTypeID = 0; d.hullTypeID = hullType.hullID; d.droneType = c_dtConstruction; d.moveSkill = d.shootSkill = 1.0f; d.bravery = 0.5f; d.nParts = 0; d.price = 500; strcpy(d.modelName, "utl19"); strcpy(d.name, "Construction"); strcpy(d.description, "Construction drone"); d.ttbmRequired.ClearAll(); d.ttbmEffects.ClearAll(); pobj = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_droneType, &d, sizeof(d)); assert (pobj); pobj->Release(); // Create the 3 civilizations static const char* civNames[c_cSidesMax] = {"Rix", "Iron League", "Belorian"}; DataCivilizationIGC c; c.lifepod = hullType.hullID; c.constructionDroneTypeID = 0; c.ttbmBaseTechs.ClearAll(); c.gasBaseAttributes.Initialize(); for (CivID cid = 0; (cid < 3); cid++) { strcpy(c.name, "Iron league"); c.initialStationTypeID = 0; c.civilizationID = cid; pobj = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_civilization, &c, sizeof(c)); assert (pobj); pobj->Release(); } // Create the 3 teams static const float sideColors[3][3] = { {1.0f, 0.5f, 0.0f}, //orange {0.0f, 1.0f, 0.67f},//teal {0.0f, 0.0f, 1.0f}}; //blue static const char* sideNames[c_cSidesMax] = {"Orange", "Teal", "Blue"}; for (SideID sid = 0; (sid < 3); sid++) { IcivilizationIGC* pcivilization = m_pmissionContext->GetMissionIGC()->GetCivilization(sid); DataSideIGC ds; ds.sideID = sid; ds.teamCode = sid; ds.civilizationID = sid; ds.color.SetRGBA(sideColors[sid][0], sideColors[sid][1], sideColors[sid][2]); strcpy(ds.name, sideNames[sid]); ds.gas = pcivilization->GetBaseAttributes(); ds.ttbmDevelopmentTechs = pcivilization->GetBaseTechs(); pobj = m_pmissionContext->GetMissionIGC()->CreateObject(Time::Now(), OT_side, &ds, sizeof(ds)); assert (pobj); pobj->Release(); } // standard sounds Sound::DefineDiscreteSoundEffect(newShipSound, SNDF_NEW_SHIP_ON_SCANNER); Sound::DefineLoopingSoundEffect(inSound, SNDF_FLIGHT_INTERIOR_NOISE); Sound::DefineLoopingSoundEffect(outSound, SNDF_FLIGHT_EXTERIOR_NOISE); Sound::DefineDiscreteSoundEffect(energySound, "ef42" /*SNDF_ENERGY_WEAPON_FIRE*/, false); Sound::DefineDiscreteSoundEffect(particleSound, "ef122" /*SNDF_PARTICLE_WEAPON_FIRE*/, false); Sound::DefineDiscreteSoundEffect(jumpSound, "ef29", false); Sound::DefineDiscreteSoundEffect(particleSound, SNDF_PARTICLE_WEAPON_FIRE, false); Sound::DefineLoopingSoundEffect(turnSound, SNDF_FLIGHT_TURN_NOISE); Sound::DefineLoopingSoundEffect(accelSound, SNDF_FLIGHT_ACCELERATE_NOISE); Sound::DefineDiscreteSoundEffect(myShieldHitSound, SNDF_MY_SHIP_SHIELD_HIT, false); Sound::DefineDiscreteSoundEffect(myHullHitSound, SNDF_MY_SHIP_HULL_HIT, false); Sound::DefineDiscreteSoundEffect(otherShieldHitSound, SNDF_OTHER_SHIP_SHIELD_HIT, false); Sound::DefineDiscreteSoundEffect(otherHullHitSound, SNDF_OTHER_SHIP_HULL_HIT, false); Sound::DefineDiscreteSoundEffect(explosionSound, SNDF_GENERIC_EXPLOSION, false/*, true*/); Sound::DefineDiscreteSoundEffect(explodeStationSound, SNDF_STATION_EXPLOSION, false/*, true*/); Sound::DefineDiscreteSoundEffect(explodeShipSound, SNDF_SHIP_EXPLOSION, false/*, true*/); Sound::DefineLoopingSoundEffect(afterburnerOutSound, SNDF_AFTERBURNER_OFF); Sound::DefineDiscreteSoundEffect(outOfFuelSound, SNDF_SHIP_OUT_OF_FUEL); Sound::DefineDiscreteSoundEffect(hooverSound, SNDF_HOOVER); Sound::DefineDiscreteSoundEffect(mountSound, SNDF_SHIP_MOUNT_PART); Sound::DefineDiscreteSoundEffect(unmountSound, SNDF_SHIP_UNMOUNT_PART); Sound::DefineDiscreteSoundEffect(outOfAmmoSound, SNDF_WEAPON_OUT_OF_AMMO); Sound::DefineDiscreteSoundEffect(collisionSound, SNDF_GENERIC_COLLISION); Sound::DefineDiscreteSoundEffect(exitAlephSound, SNDF_EXIT_ALEPH); Sound::DefineDiscreteSoundEffect(readyWeaponSound, SNDF_WEAPON_READY); Sound::DefineDiscreteSoundEffect(vectorLockSound, SNDF_VECTOR_LOCK); } void SetMissionStage(MissionStage* pstageNew) { FireOnSwitchedMissionStage(pstageNew, m_pmissionStage); m_pmissionStage = pstageNew; } void AdviseRegion(Region* pregion, ImodelIGC* pmodel) { TRef pentry; if (!m_mapRegionAdviseEntries.Find(pregion, pentry)) { pentry = new RegionAdviseEntry(pregion); m_mapRegionAdviseEntries.Set(pregion, pentry); } pentry->Advise(pmodel); // todo: make sure not in delete list } void UnadviseRegion(Region* pregion, ImodelIGC* pmodel) { TRef pentry; ZVerify(m_mapRegionAdviseEntries.Find(pregion, pentry)); pentry->Unadvise(pmodel); // todo: mark this entry to be deleted } void AddMissionEventHandler(MissionEventHandler* phandler) { m_lstEventHandlers.PushEnd(phandler); } void RemoveMissionEventHandler(MissionEventHandler* phandler) { m_lstEventHandlers.Replace(phandler, NULL); } void Update(Time time, float dtime) { // check region collisions... this doesn't handle jumps all the way through a region TMap, TRef >::Iterator iterEntries(m_mapRegionAdviseEntries); while (!iterEntries.End()) { TRef pentry = iterEntries.Value(); pentry->Update(this); iterEntries.Next(); } } void RemoveDeadHandlers() { // remove all of the NULL elements from the list while (m_lstEventHandlers.Remove(NULL)) { } } #define ForEachHandler(fnc) \ TList >::Iterator iter(m_lstEventHandlers); \ while (!iter.End()) \ { \ if (iter.Value() != NULL) \ if (!iter.Value()->fnc) \ RemoveMissionEventHandler(iter.Value()); \ iter.Next(); \ } \ RemoveDeadHandlers(); \ void FireOnModelTerminated(ImodelIGC* pmodel) { ForEachHandler( OnModelTerminated(pmodel) ) } void FireOnModelKilled(ImodelIGC* pmodel) { ForEachHandler( OnModelKilled(pmodel) ) } void FireOnModelDamaged(ImodelIGC* pmodel) { ForEachHandler( OnModelDamaged(pmodel) ) } void FireOnDocked(IshipIGC* pship, IstationIGC* pstation) { ForEachHandler( OnDocked(pship, pstation) ) } void FireOnSwitchSector(IshipIGC* pship, IclusterIGC* pclusterOld, IclusterIGC* pclusterNew) { ForEachHandler( OnSwitchSector(pship, pclusterOld, pclusterNew) ) } void FireOnHitTreasure(IshipIGC* pship, ItreasureIGC* ptreasure) { ForEachHandler( OnHitTreasure(pship, ptreasure) ) } void FireOnEnteredRegion(ImodelIGC* pmodel, Region* pregion) { ForEachHandler( OnEnteredRegion(pmodel, pregion) ) } void FireOnExitedRegion(ImodelIGC* pmodel, Region* pregion) { ForEachHandler( OnExitedRegion(pmodel, pregion) ) } void FireOnDivergedPath(IshipIGC* pship, Path* ppath, float distance, float angle) { ForEachHandler( OnDivergedPath(pship, ppath, distance, angle) ) } void FireOnSwitchedMissionStage(MissionStage* pstageNew, MissionStage* pstageOld) { ForEachHandler( OnSwitchedMissionStage(pstageNew, pstageOld) ) } void LoadClusters(const ZString& strMdlFile) { TRef pns = GetModeler()->CreateNameSpace("mission", GetModeler()->GetNameSpace("model")); pns->AddMember("CreateCluster", new TIGCObjectFactory(this, CreateCluster)); pns->AddMember("CreateAsteroid", new TIGCObjectFactory(this, CreateAsteroid)); pns->AddMember("CreateSphericalRegion", new TIGCObjectFactory(this, CreateSphericalRegion)); pns->AddMember("CreateDrone", new TIGCObjectFactory(this, CreateDrone)); pns->AddMember("CreateStation", new TIGCObjectFactory(this, CreateStation)); m_pnsClusters = GetModeler()->GetNameSpace(strMdlFile); } void LoadTechTree(const ZString& strMdlFile) { TRef pns = GetModeler()->CreateNameSpace("mission", GetModeler()->GetNameSpace("model")); pns->AddMember("CreateStationType", new TIGCObjectFactory(this, CreateStationType)); pns->AddMember("CreateHullType", new TIGCObjectFactory(this, CreateHullType)); pns->AddMember("CreateAfterburnerType", new TIGCObjectFactory(this, CreateAfterburnerType)); pns->AddMember("CreatePackType", new TIGCObjectFactory(this, CreatePackType)); pns->AddMember("CreateProjectileType", new TIGCObjectFactory(this, CreateProjectileType)); pns->AddMember("CreateWeaponType", new TIGCObjectFactory(this, CreateWeaponType)); pns->AddMember("CreateMissileType", new TIGCObjectFactory(this, CreateMissileType)); pns->AddMember("CreateMissileLauncherType", new TIGCObjectFactory(this, CreateMissileLauncherType)); m_pnsTechTree = GetModeler()->GetNameSpace(strMdlFile); } }; TRef MissionManager::Create(MissionContext* pcontext) { return new MissionManagerImpl(pcontext); }