/*============================================================================= Name : Universe.c Purpose : The universe represents the entire game world, including any mission spheres contained within. Created 6/19/1997 by gshaw Copyright Relic Entertainment, Inc. All rights reserved. =============================================================================*/ #include #include #include #include "types.h" #include "debug.h" #include "task.h" #include "file.h" #include "linkedlist.h" #include "spaceobj.h" #include "collision.h" #include "univupdate.h" #include "stats.h" #include "camera.h" #include "cameracommand.h" #include "render.h" #include "statscript.h" #include "ships.h" #include "formation.h" #include "commandlayer.h" #include "mex.h" #include "tweak.h" #include "globals.h" #include "commandnetwork.h" #include "utility.h" #include "levelload.h" #include "aiship.h" #include "gun.h" #include "etg.h" #include "dock.h" #include "universe.h" #include "aiplayer.h" #include "consMgr.h" #include "strings.h" #include "soundevent.h" #include "horserace.h" #include "meshanim.h" #include "multiplayergame.h" #include "gamechat.h" #include "researchapi.h" #include "singleplayer.h" #include "navlights.h" #include "teams.h" #include "captaincy.h" #include "bounties.h" #include "tutor.h" #include "ping.h" #include "SaveGame.h" #include "autodownloadmap.h" #include "LagPrint.h" #include "scenpick.h" #include "fastmath.h" #include "netcheck.h" extern bool cheapShips; extern real32 GLOBAL_SHIP_HEALTH_MODIFIER; extern real32 GLOBAL_SHIP_SPEED_MODIFIER; /*============================================================================= Public Data: =============================================================================*/ Universe universe; AsteroidStaticInfo asteroidStaticInfos[NUM_ASTEROIDTYPES]; DustCloudStaticInfo dustcloudStaticInfos[NUM_DUSTCLOUDTYPES]; GasCloudStaticInfo gascloudStaticInfos[NUM_GASCLOUDTYPES]; NebulaStaticInfo nebulaStaticInfos[NUM_NEBULATYPES]; DerelictStaticInfo derelictStaticInfos[NUM_DERELICTTYPES]; MissileStaticInfo missileStaticInfos[NUM_RACES]; MissileStaticInfo mineStaticInfos[2]; //only race 1 and race 2 have mines struct SphereStaticInfo *sphereStaticInfo = NULL; Camera defaultCamera; real32 maxMineCollSphereSize; //real32 maxShipCollSphereSize; //real32 maxResourceCollSphereSize; //real32 maxDerelictCollSphereSize; //real32 maxCollSphereSize; meshdata *defaultmesh = NULL; #if UNIVERSE_TURBOPAUSE_DEBUG #define UNIVERSE_TURBO_REPEAT 19 bool universeTurbo = FALSE; #endif bool universePause = FALSE; sdword cdMaxShipsAllowed; // max number of ships allowed sdword cdLimitCaps[TOTAL_NUM_SHIPS]; // max number of ships per player allowed sdword cdClassCaps[NUM_CLASSES]; // max number of ships per class allowed bool cdEnabled=TRUE; // flag specifying whether unit caps enabled uword RacesAllowedForGivenShip[TOTAL_NUM_SHIPS] = { R1_VALID|R2_VALID, //AdvanceSupportFrigate R1_VALID|R2_VALID, //AttackBomber R1_VALID|R2_VALID, //Carrier R1_VALID , //CloakedFighter R1_VALID|R2_VALID, //CloakGenerator R1_VALID , //DDDFrigate R2_VALID, //DefenseFighter R2_VALID, //DFGFrigate R1_VALID|R2_VALID, //GravWellGenerator R1_VALID|R2_VALID, //HeavyCorvette R1_VALID|R2_VALID, //HeavyCruiser R1_VALID|R2_VALID, //HeavyDefender R1_VALID|R2_VALID, //HeavyInterceptor R1_VALID|R2_VALID, //IonCannonFrigate R1_VALID|R2_VALID, //LightCorvette R1_VALID|R2_VALID, //LightDefender R1_VALID|R2_VALID, //LightInterceptor R1_VALID|R2_VALID, //MinelayerCorvette R1_VALID|R2_VALID, //MissileDestroyer R1_VALID|R2_VALID, //Mothership R1_VALID|R2_VALID, //MultiGunCorvette R1_VALID|R2_VALID, //Probe R1_VALID|R2_VALID, //ProximitySensor R1_VALID|R2_VALID, //RepairCorvette R1_VALID|R2_VALID, //ResearchShip R1_VALID|R2_VALID, //ResourceCollector R1_VALID|R2_VALID, //ResourceController R1_VALID|R2_VALID, //SalCapCorvette R1_VALID|R2_VALID, //SensorArray R1_VALID|R2_VALID, //StandardDestroyer R1_VALID|R2_VALID, //StandardFrigate R1_VALID , //Drone R1_VALID|R2_VALID, //TargetDrone R1_VALID|R2_VALID, //HeadShotAsteroid R1_VALID|R2_VALID, //CryoTray P1_VALID , //P1Fighter P1_VALID , //P1IonArrayFrigate P1_VALID , //P1MissileCorvette P1_VALID , //P1Mothership P1_VALID , //P1StandardCorvette P2_VALID , //P2AdvanceSwarmer P2_VALID , //P2FuelPod P2_VALID , //P2Mothership P2_VALID , //P2MultiBeamFrigate P2_VALID , //P2Swarmer P3_VALID , //P3Destroyer P3_VALID , //P3Frigate P3_VALID , //P3Megaship Traders_VALID , //FloatingCity Traders_VALID , //CargoBarge Traders_VALID , //MiningBase Traders_VALID , //ResearchStation Traders_VALID , //JunkYardDawg Traders_VALID //JunkYardHQ }; bool universeForceDefaultShip = FALSE; //flag for forcing ships to be loaded as rave borgs #if UNIV_SHIP_LOADFREE_LOG bool univLoadFreeLog = FALSE; #endif /*============================================================================= Private Function prototypes: =============================================================================*/ static void loadMexDataCB(char *directory,char *field,void *dataToFillIn); //static void setRaceCB(char *directory,char *field,void *dataToFillIn); static void setClassCB(char *directory,char *field,void *dataToFillIn); static void scriptSetFramesCB(char *directory,char *field,void *dataToFillIn); static void LODScriptLoad(char *directory,char *field,void *dataToFillIn); static void setExplosionType(char *directory,char *field,void *dataToFillIn); static void scriptSetShipsCB(char *directory,char *field,void *dataToFillIn); static void setGunBindInfo(char *directory,char *field,void *dataToFillIn); static void setAnimationBindInfo(char *directory,char *field,void *dataToFillIn); static void setMadStartInfo(char *directory,char *field,void *dataToFillIn); static void setGunAnimInfo(char *directory,char *field,void *dataToFillIn); static void setDockAnimInfo(char *directory,char *field,void *dataToFillIn); static void setMothershipDoorAnimInfo(char *directory,char *field,void *dataToFillIn); static void setSpecialCaseAnimInfo(char *directory,char *field,void *dataToFillIn); /*============================================================================= Private Data: =============================================================================*/ lodinfo *defaultlod = NULL; // remove later when all stubs are taken out void *defaultmex = NULL; // remove later when all stubs are taken out udword universeUpdateCounter = 0; ShipStaticInfo ShipStaticInfoR1[TOTAL_STD_SHIPS]; ShipStaticInfo ShipStaticInfoR2[TOTAL_STD_SHIPS]; ShipStaticInfo ShipStaticInfoP1[TOTAL_P1_SHIPS]; ShipStaticInfo ShipStaticInfoP2[TOTAL_P2_SHIPS]; ShipStaticInfo ShipStaticInfoP3[TOTAL_P3_SHIPS]; ShipStaticInfo ShipStaticInfoTraders[TOTAL_TRADERS_SHIPS]; ShipStaticInfo *RaceShipStaticInfos[NUM_RACES] = { ShipStaticInfoR1, ShipStaticInfoR2, ShipStaticInfoP1, ShipStaticInfoP2, ShipStaticInfoP3, ShipStaticInfoTraders }; CustShipHeader *shipHeaders[TOTAL_NUM_SHIPS] = { &AdvanceSupportFrigateHeader, //AdvanceSupportFrigate &AttackBomberHeader, //AttackBomber &CarrierHeader, //Carrier &CloakedFighterHeader, //CloakedFighter &CloakGeneratorHeader, //CloakGenerator &DDDFrigateHeader, //DDDFrigate &DefenseFighterHeader, //DefenseFighter &DFGFrigateHeader, //DFGFrigate &GravWellGeneratorHeader, //GravWellGenerator &HeavyCorvetteHeader, //HeavyCorvette &HeavyCruiserHeader, //HeavyCruiser &GenericDefenderHeader, //HeavyDefender &GenericInterceptorHeader, //HeavyInterceptor &IonCannonFrigateHeader, //IonCannonFrigate &LightCorvetteHeader, //LightCorvette &GenericDefenderHeader, //LightDefender &GenericInterceptorHeader, //LightInterceptor &MinelayerCorvetteHeader, //MinelayerCorvette &MissileDestroyerHeader, //MissileDestroyer &MothershipHeader, //Mothership &MultiGunCorvetteHeader, //MultiGunCorvette &ProbeHeader, //Probe &ProximitySensorHeader, //ProximitySensor &RepairCorvetteHeader, //RepairCorvette &ResearchShipHeader, //ResearchShip &ResourceCollectorHeader, //ResourceCollector &ResourceControllerHeader, //ResourceController &SalCapCorvetteHeader, //SalCapCorvette &SensorArrayHeader, //SensorArray &StandardDestroyerHeader, //StandardDestroyer &StandardFrigateHeader, //StandardFrigate &DroneHeader, //Drone &TargetDroneHeader, //TargetDrone (header located in DefaultShip.c) &DoNothingShipHeader, //HeadShotAsteroid &DoNothingShipHeader, //CryoTray &GenericInterceptorHeader, //P1Fighter &P1IonArrayFrigateHeader, //P1IonArrayFrigate &P1MissileCorvetteHeader, //P1MissileCorvette &P1MothershipHeader, //P1Mothership &P1StandardCorvetteHeader, //P1StandardCorvette &P2AdvanceSwarmerHeader, //P2AdvanceSwarmer &P2FuelPodHeader, //P2FuelPod &P2MothershipHeader, //P2Mothership &P2MultiBeamFrigateHeader, //P2MultiBeamFrigate &P2SwarmerHeader, //P2Swarmer &P3StandardShipHeader, //P3Destroyer &P3StandardShipHeader, //P3Frigate &P3StandardShipHeader, //P3Megaship &FloatingCityHeader, //FloatingCity &DefaultShipHeader, //CargoBarge &MiningBaseHeader, //MiningBase &DefaultShipHeader, //ResearchStation &JunkYardDawgHeader, //JunkYardDawg &DoNothingShipHeader, //JunkYardHQ &DoNothingShipHeader, //GhostShip &StationaryGunHeader, //Junk_LGun &StationaryGunHeader, //Junk_SGun &DoNothingShipHeader, //ResearchStationBridge &DoNothingShipHeader //ResearchStationTower }; real32 rowAvoidBy[TOTAL_NUM_SHIPS] = { 1000.0, //AdvanceSupportFrigate 0.0, //AttackBomber 1600.0, //Carrier 0.0, //CloakedFighter 1000.0, //CloakGenerator 1000.0, //DDDFrigate 0.0, //DefenseFighter 1000.0, //DFGFrigate 1000.0, //GravWellGenerator 0.0, //HeavyCorvette 1500.0, //HeavyCruiser 0.0, //HeavyDefender 0.0, //HeavyInterceptor 1000.0, //IonCannonFrigate 0.0, //LightCorvette 0.0, //LightDefender 0.0, //LightInterceptor 0.0, //MinelayerCorvette 1500.0, //MissileDestroyer 2000.0, //Mothership 0.0, //MultiGunCorvette 0.0, //Probe 0.0, //ProximitySensor 0.0, //RepairCorvette 1000.0, //ResearchShip 1000.0, //ResourceCollector 1000.0, //ResourceController 0.0, //SalCapCorvette 1000.0, //SensorArray 1500.0, //StandardDestroyer 1000.0, //StandardFrigate 0.0, //Drone 0.0, //TargetDrone 2000.0, //HeadShotAsteroid 2000.0, //CryoTray 0.0, //P1Fighter 1000.0, //P1IonArrayFrigate 0.0, //P1MissileCorvette 1700.0, //P1Mothership 0.0, //P1StandardCorvette 0.0, //P2AdvanceSwarmer 1000.0, //P2FuelPod 1700.0, //P2Mothership 1000.0, //P2MultiBeamFrigate 0.0, //P2Swarmer 1500.0, //P3Destroyer 1700.0, //P3Frigate 2000.0, //P3Megaship 2000.0, //FloatingCity 1000.0, //CargoBarge 1700.0, //MiningBase 1700.0, //ResearchStation 1000.0, //JunkYardDawg 1000.0, //JunkYardHQ 2000.0, //Junk_LGun 1000.0, //Junk_SGun 2000.0, //ResearchStationBridge 2000.0 //ResearchStationTower }; // rightOfWay for ships. // -1 indicates lowest priority of the low (e.g. pebbles in space) // 0 indicates strikecraft, probes, etc. // 1 indicates frigates // 2 indicates cruisers/destroyers // 3 indicates carriers // 4 indicates mothership sbyte rightOfWays[TOTAL_NUM_SHIPS] = { 1, //AdvanceSupportFrigate 0, //AttackBomber 3, //Carrier 0, //CloakedFighter 1, //CloakGenerator 1, //DDDFrigate 0, //DefenseFighter 1, //DFGFrigate 1, //GravWellGenerator 0, //HeavyCorvette 2, //HeavyCruiser 0, //HeavyDefender 0, //HeavyInterceptor 1, //IonCannonFrigate 0, //LightCorvette 0, //LightDefender 0, //LightInterceptor 0, //MinelayerCorvette 2, //MissileDestroyer 4, //Mothership 0, //MultiGunCorvette 0, //Probe 0, //ProximitySensor 0, //RepairCorvette 2, //ResearchShip 1, //ResourceCollector 2, //ResourceController 0, //SalCapCorvette 1, //SensorArray 2, //StandardDestroyer 1, //StandardFrigate 0, //Drone 0, //TargetDrone 4, //HeadShotAsteroid 4, //CryoTray 0, //P1Fighter 1, //P1IonArrayFrigate 0, //P1MissileCorvette 4, //P1Mothership 0, //P1StandardCorvette 0, //P2AdvanceSwarmer 1, //P2FuelPod 4, //P2Mothership 1, //P2MultiBeamFrigate 0, //P2Swarmer 2, //P3Destroyer 3, //P3Frigate 4, //P3Megaship 4, //FloatingCity 1, //CargoBarge 4, //MiningBase 4, //ResearchStation 1, //JunkYardDawg 2, //JunkYardHQ 1, //Junk_LGun 0, //Junk_SGun 4, //ResearchStationBridge 4 //ResearchStationTower }; scriptEntry ShipStaticCapLimits[] = { { "ShipTotalCaps", scriptSetSdwordCB, &cdMaxShipsAllowed }, { "CapAdvanceSupportFrigate", scriptSetSdwordCB, &(cdLimitCaps[0]) }, { "CapAttackBomber", scriptSetSdwordCB, &cdLimitCaps[1] }, { "CapCarrier", scriptSetSdwordCB, &cdLimitCaps[2] }, { "CapCloakedFighter", scriptSetSdwordCB, &cdLimitCaps[3] }, { "CapCloakGenerator", scriptSetSdwordCB, &cdLimitCaps[4] }, { "CapDDDFrigate", scriptSetSdwordCB, &cdLimitCaps[5] }, { "CapDefenseFighter", scriptSetSdwordCB, &cdLimitCaps[6] }, { "CapDFGFrigate", scriptSetSdwordCB, &cdLimitCaps[7] }, { "CapGravWellGenerator", scriptSetSdwordCB, &cdLimitCaps[8] }, { "CapHeavyCorvette", scriptSetSdwordCB, &cdLimitCaps[9] }, { "CapHeavyCruiser", scriptSetSdwordCB, &cdLimitCaps[10] }, { "CapHeavyDefender", scriptSetSdwordCB, &cdLimitCaps[11] }, { "CapHeavyInterceptor", scriptSetSdwordCB, &cdLimitCaps[12] }, { "CapIonCannonFrigate", scriptSetSdwordCB, &cdLimitCaps[13] }, { "CapLightCorvette", scriptSetSdwordCB, &cdLimitCaps[14] }, { "CapLightDefender", scriptSetSdwordCB, &cdLimitCaps[15] }, { "CapLightInterceptor", scriptSetSdwordCB, &cdLimitCaps[16] }, { "CapMinelayerCorvette", scriptSetSdwordCB, &cdLimitCaps[17] }, { "CapMissileDestroyer", scriptSetSdwordCB, &cdLimitCaps[18] }, { "CapMothership", scriptSetSdwordCB, &cdLimitCaps[19] }, { "CapMultiGunCorvette", scriptSetSdwordCB, &cdLimitCaps[20] }, { "CapProbe", scriptSetSdwordCB, &cdLimitCaps[21] }, { "CapProximitySensor", scriptSetSdwordCB, &cdLimitCaps[22] }, { "CapRepairCorvette", scriptSetSdwordCB, &cdLimitCaps[23] }, { "CapResearchShip", scriptSetSdwordCB, &cdLimitCaps[24] }, { "CapResourceCollector", scriptSetSdwordCB, &cdLimitCaps[25] }, { "CapResourceController", scriptSetSdwordCB, &cdLimitCaps[26] }, { "CapSalCapCorvette", scriptSetSdwordCB, &cdLimitCaps[27] }, { "CapSensorArray", scriptSetSdwordCB, &cdLimitCaps[28] }, { "CapStandardDestroyer", scriptSetSdwordCB, &cdLimitCaps[29] }, { "CapStandardFrigate", scriptSetSdwordCB, &cdLimitCaps[30] }, { "CapDrone", scriptSetSdwordCB, &cdLimitCaps[31] }, { "CapTargetDrone", scriptSetSdwordCB, &cdLimitCaps[32] }, { "CapHeadShotAsteroid", scriptSetSdwordCB, &cdLimitCaps[33] }, { "CapCryoTray", scriptSetSdwordCB, &cdLimitCaps[34] }, { "CapP1Fighter", scriptSetSdwordCB, &cdLimitCaps[35] }, { "CapP1IonArrayFrigate", scriptSetSdwordCB, &cdLimitCaps[36] }, { "CapP1MissileCorvette", scriptSetSdwordCB, &cdLimitCaps[37] }, { "CapP1Mothership", scriptSetSdwordCB, &cdLimitCaps[38] }, { "CapP1StandardCorvette", scriptSetSdwordCB, &cdLimitCaps[39] }, { "CapP2AdvanceSwarmer", scriptSetSdwordCB, &cdLimitCaps[40] }, { "CapP2FuelPod", scriptSetSdwordCB, &cdLimitCaps[41] }, { "CapP2Mothership", scriptSetSdwordCB, &cdLimitCaps[42] }, { "CapP2MultiBeamFrigate", scriptSetSdwordCB, &cdLimitCaps[43] }, { "CapP2Swarmer", scriptSetSdwordCB, &cdLimitCaps[44] }, { "CapP3Destroyer", scriptSetSdwordCB, &cdLimitCaps[45] }, { "CapP3Frigate", scriptSetSdwordCB, &cdLimitCaps[46] }, { "CapP3Megaship", scriptSetSdwordCB, &cdLimitCaps[47] }, { "CapFloatingCity", scriptSetSdwordCB, &cdLimitCaps[48] }, { "CapCargoBarge", scriptSetSdwordCB, &cdLimitCaps[49] }, { "CapMiningBase", scriptSetSdwordCB, &cdLimitCaps[50] }, { "CapResearchStation", scriptSetSdwordCB, &cdLimitCaps[51] }, { "CapJunkYardDawg", scriptSetSdwordCB, &cdLimitCaps[52] }, { "CapJunkYardHQ", scriptSetSdwordCB, &cdLimitCaps[53] }, { "CapGhostShip", scriptSetSdwordCB, &cdLimitCaps[54] }, { "CapJunk_LGun", scriptSetSdwordCB, &cdLimitCaps[55] }, { "CapJunk_SGun", scriptSetSdwordCB, &cdLimitCaps[56] }, { "CapResearchStationBridge", scriptSetSdwordCB, &cdLimitCaps[57] }, { "CapResearchStationTower", scriptSetSdwordCB, &cdLimitCaps[58] }, { "CapCLASS_Mothership", scriptSetSdwordCB, &cdClassCaps[0] }, { "CapCLASS_HeavyCruiser", scriptSetSdwordCB, &cdClassCaps[1] }, { "CapCLASS_Carrier", scriptSetSdwordCB, &cdClassCaps[2] }, { "CapCLASS_Destroyer", scriptSetSdwordCB, &cdClassCaps[3] }, { "CapCLASS_Frigate", scriptSetSdwordCB, &cdClassCaps[4] }, { "CapCLASS_Corvette", scriptSetSdwordCB, &cdClassCaps[5] }, { "CapCLASS_Fighter", scriptSetSdwordCB, &cdClassCaps[6] }, { "CapCLASS_Resource", scriptSetSdwordCB, &cdClassCaps[7] }, { "CapCLASS_NonCombat", scriptSetSdwordCB, &cdClassCaps[8] }, { "MaxJobsPerClass[Mothership]", scriptSetSdwordCB, &cmMaxJobsPerClass[CLASS_Mothership] }, { "MaxJobsPerClass[HeavyCruiser]", scriptSetSdwordCB, &cmMaxJobsPerClass[CLASS_HeavyCruiser]}, { "MaxJobsPerClass[Carrier]", scriptSetSdwordCB, &cmMaxJobsPerClass[CLASS_Carrier]}, { "MaxJobsPerClass[Destroyer]", scriptSetSdwordCB, &cmMaxJobsPerClass[CLASS_Destroyer]}, { "MaxJobsPerClass[Frigate]", scriptSetSdwordCB, &cmMaxJobsPerClass[CLASS_Frigate]}, { "MaxJobsPerClass[Corvette]", scriptSetSdwordCB, &cmMaxJobsPerClass[CLASS_Corvette]}, { "MaxJobsPerClass[Fighter]", scriptSetSdwordCB, &cmMaxJobsPerClass[CLASS_Fighter]}, { "MaxJobsPerClass[Resource]", scriptSetSdwordCB, &cmMaxJobsPerClass[CLASS_Resource]}, { "MaxJobsPerClass[NonCombat]", scriptSetSdwordCB, &cmMaxJobsPerClass[CLASS_NonCombat]}, endEntry }; scriptStructEntry ShipStaticScriptTable[] = { { "LODFile", LODScriptLoad, (udword) &(ShipStaticInfoR1[0].staticheader.LOD), (udword) &(ShipStaticInfoR1[0]) }, { "pMexData", loadMexDataCB, (udword) &(ShipStaticInfoR1[0].staticheader.pMexData), (udword) &(ShipStaticInfoR1[0]) }, { "mass", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.mass), (udword) &(ShipStaticInfoR1[0]) }, { "momentOfInertiaX",scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.momentOfInertiaX), (udword) &(ShipStaticInfoR1[0]) }, { "momentOfInertiaY",scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.momentOfInertiaY), (udword) &(ShipStaticInfoR1[0]) }, { "momentOfInertiaZ",scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.momentOfInertiaZ), (udword) &(ShipStaticInfoR1[0]) }, { "collBoxScaleRight",scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.collBoxScaleRight), (udword) &(ShipStaticInfoR1[0]) }, { "collBoxScaleUp",scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.collBoxScaleUp), (udword) &(ShipStaticInfoR1[0]) }, { "collBoxScaleForward",scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.collBoxScaleForward), (udword) &(ShipStaticInfoR1[0]) }, { "collBoxOffsetX",scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.collBoxOffsetX), (udword) &(ShipStaticInfoR1[0]) }, { "collBoxOffsetY",scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.collBoxOffsetY), (udword) &(ShipStaticInfoR1[0]) }, { "collBoxOffsetZ",scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.collBoxOffsetZ), (udword) &(ShipStaticInfoR1[0]) }, { "immobile", scriptSetBool8, (udword) &(ShipStaticInfoR1[0].staticheader.immobile), (udword) &(ShipStaticInfoR1[0]) }, { "rightOfWay", scriptSetSbyteCB, (udword) &(ShipStaticInfoR1[0].staticheader.rightOfWay), (udword) &(ShipStaticInfoR1[0]) }, { "collspheresize", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.collspheresize), (udword) &(ShipStaticInfoR1[0]) }, { "approxcollmodifier", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.approxcollmodifier), (udword) &(ShipStaticInfoR1[0]) }, { "avoidcollmodifier", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.avoidcollmodifier), (udword) &(ShipStaticInfoR1[0]) }, { "maxvelocity", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.maxvelocity), (udword) &(ShipStaticInfoR1[0]) }, { "maxrot", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].staticheader.maxrot), (udword) &(ShipStaticInfoR1[0]) }, { "bulletRange[0]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].bulletRange[0]), (udword) &(ShipStaticInfoR1[0]) }, { "bulletRange[1]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].bulletRange[1]), (udword) &(ShipStaticInfoR1[0]) }, { "bulletRange[2]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].bulletRange[2]), (udword) &(ShipStaticInfoR1[0]) }, { "minBulletRange[0]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].minBulletRange[0]), (udword) &(ShipStaticInfoR1[0]) }, { "minBulletRange[1]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].minBulletRange[1]), (udword) &(ShipStaticInfoR1[0]) }, { "minBulletRange[2]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].minBulletRange[2]), (udword) &(ShipStaticInfoR1[0]) }, { "blastRadiusShockWave", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].blastRadiusShockWave), (udword) &(ShipStaticInfoR1[0]) }, { "blastRadiusDamage", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].blastRadiusDamage), (udword) &(ShipStaticInfoR1[0]) }, { "passiveRetaliateZone", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].passiveRetaliateZone), (udword) &(ShipStaticInfoR1[0]) }, { "shipclass", setClassCB, (udword) &(ShipStaticInfoR1[0].shipclass), (udword) &(ShipStaticInfoR1[0]) }, { "rotateToRetaliate",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].rotateToRetaliate), (udword) &(ShipStaticInfoR1[0]) }, { "canTargetMultipleTargets",scriptSetBool8,(udword) &(ShipStaticInfoR1[0].canTargetMultipleTargets), (udword) &(ShipStaticInfoR1[0]) }, { "canBuildShips", scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canBuildShips), (udword) &(ShipStaticInfoR1[0]) }, { "canReceiveShips",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canReceiveShips), (udword) &(ShipStaticInfoR1[0]) }, { "canReceiveResources",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canReceiveResources), (udword) &(ShipStaticInfoR1[0]) }, { "canReceiveShipsPermanently",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canReceiveShipsPermanently), (udword) &(ShipStaticInfoR1[0]) }, { "canReceiveShipsForRetire",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canReceiveShipsForRetire), (udword) &(ShipStaticInfoR1[0]) }, { "canBuildBigShips",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canBuildBigShips), (udword) &(ShipStaticInfoR1[0]) }, { "canReceiveFighters",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canReceiveTheseShips[THISSHIPIS_FIGHTER]), (udword) &(ShipStaticInfoR1[0]) }, { "canReceiveCorvettes",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canReceiveTheseShips[THISSHIPIS_CORVETTE]), (udword) &(ShipStaticInfoR1[0]) }, { "canReceiveResourceCollectors",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canReceiveTheseShips[THISSHIPIS_RESOURCER]), (udword) &(ShipStaticInfoR1[0]) }, { "canReceiveOtherNonCapitalShips",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canReceiveTheseShips[THISSHIPIS_OTHERNONCAPITALSHIP]), (udword) &(ShipStaticInfoR1[0]) }, { "canHandleNumShipsDocking",scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].canHandleNumShipsDocking), (udword) &(ShipStaticInfoR1[0]) }, { "canHandleNumShipsDepositingRU",scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].canHandleNumShipsDepositingRU), (udword) &(ShipStaticInfoR1[0]) }, { "svManeuverability",scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].svManeuverability), (udword) &(ShipStaticInfoR1[0]) }, { "svCoverage",scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].svCoverage), (udword) &(ShipStaticInfoR1[0]) }, { "svFirePower",scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].svFirePower), (udword) &(ShipStaticInfoR1[0]) }, { "maxDockableFighters" ,scriptSetSwordCB, (udword) &(ShipStaticInfoR1[0].maxDockableFighters),(udword) &(ShipStaticInfoR1[0])}, { "maxDockableCorvettes",scriptSetSwordCB, (udword) &(ShipStaticInfoR1[0].maxDockableCorvettes),(udword) &(ShipStaticInfoR1[0])}, { "specialActivateIsContinuous",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].specialActivateIsContinuous), (udword) &(ShipStaticInfoR1[0]) }, { "canSpecialBandBoxFriendlies",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canSpecialBandBoxFriendlies), (udword) &(ShipStaticInfoR1[0]) }, { "canSingleClickSpecialActivate",scriptSetBool8, (udword) &(ShipStaticInfoR1[0].canSingleClickSpecialActivate), (udword) &(ShipStaticInfoR1[0]) }, { "buildCost", scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].buildCost), (udword) &(ShipStaticInfoR1[0]) }, { "buildTime", scriptSetFramesCB, (udword) &(ShipStaticInfoR1[0].buildTime), (udword) &(ShipStaticInfoR1[0]) }, { "resourcesAtOneTime", scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].resourcesAtOneTime), (udword) &(ShipStaticInfoR1[0]) }, { "maxresources", scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].maxresources), (udword) &(ShipStaticInfoR1[0]) }, { "harvestAmount", scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].harvestAmount), (udword) &(ShipStaticInfoR1[0]) }, { "harvestRate", scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].harvestRate), (udword) &(ShipStaticInfoR1[0]) }, { "maxhealth", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].maxhealth), (udword) &(ShipStaticInfoR1[0]) }, { "minCollDamage", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].minCollDamage), (udword) &(ShipStaticInfoR1[0]) }, { "maxCollDamage", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].maxCollDamage), (udword) &(ShipStaticInfoR1[0]) }, { "groupSize", scriptSetSdwordCB, (udword) &(ShipStaticInfoR1[0].groupSize), (udword) &(ShipStaticInfoR1[0]) }, { "maxfuel", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].maxfuel), (udword) &(ShipStaticInfoR1[0]) }, { "lowfuelpoint", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].lowfuelpoint), (udword) &(ShipStaticInfoR1[0]) }, { "fuelburnrate", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].fuelburnrate), (udword) &(ShipStaticInfoR1[0]) }, { "attackfuelburnrate", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].attackfuelburnrate), (udword) &(ShipStaticInfoR1[0]) }, { "repairTime", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].repairTime), (udword) &(ShipStaticInfoR1[0]) }, { "repairDamage", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].repairDamage), (udword) &(ShipStaticInfoR1[0]) }, { "repairCombatTime", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].repairCombatTime), (udword) &(ShipStaticInfoR1[0]) }, { "repairCombatDamage", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].repairCombatDamage), (udword) &(ShipStaticInfoR1[0]) }, { "pumpFuelRate", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].pumpFuelRate), (udword) &(ShipStaticInfoR1[0]) }, { "repairOtherShipRate", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].repairOtherShipRate), (udword) &(ShipStaticInfoR1[0]) }, { "repairResourceCollectorRate", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].repairResourceCollectorRate), (udword) &(ShipStaticInfoR1[0]) }, { "dockShipRange", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].dockShipRange), (udword) &(ShipStaticInfoR1[0]) }, { "clearanceDistance", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].clearanceDistance), (udword) &(ShipStaticInfoR1[0]) }, { "clearanceDirection", scriptSetUdwordCB, (udword) &(ShipStaticInfoR1[0].clearanceDirection), (udword) &(ShipStaticInfoR1[0]) }, { "formationPaddingModifier", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].formationPaddingModifier), (udword) &(ShipStaticInfoR1[0]) }, { "cannotForceAttackIfOwnShip",scriptSetBool, (udword) &(ShipStaticInfoR1[0].cannotForceAttackIfOwnShip), (udword) &(ShipStaticInfoR1[0]) }, { "passiveAttackPenaltyExempt",scriptSetBool, (udword) &(ShipStaticInfoR1[0].passiveAttackPenaltyExempt), (udword) &(ShipStaticInfoR1[0]) }, { "isCapitalShip",scriptSetBool, (udword) &(ShipStaticInfoR1[0].shipIsCapital), (udword) &(ShipStaticInfoR1[0]) }, { "cantMoveAndAttack",scriptSetBool, (udword) &(ShipStaticInfoR1[0].cantMoveAndAttack), (udword) &(ShipStaticInfoR1[0]) }, { "repairBeamCapable",scriptSetBool, (udword) &(ShipStaticInfoR1[0].repairBeamCapable), (udword) &(ShipStaticInfoR1[0]) }, { "healthPerSecond", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].healthPerSecond), (udword) &(ShipStaticInfoR1[0]) }, { "CapitalDistanceRepairStart2", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].CapitalDistanceRepairStart2), (udword) &(ShipStaticInfoR1[0]) }, { "CapitalDistanceRepairStart", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].CapitalDistanceRepairStart), (udword) &(ShipStaticInfoR1[0]) }, { "AngleDotProdThreshold", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].AngleDotProdThreshold), (udword) &(ShipStaticInfoR1[0]) }, { "collSideModifiers[TRANS_UP]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].collSideModifiers[TRANS_UP]), (udword) &(ShipStaticInfoR1[0]) }, { "collSideModifiers[TRANS_DOWN]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].collSideModifiers[TRANS_DOWN]), (udword) &(ShipStaticInfoR1[0]) }, { "collSideModifiers[TRANS_RIGHT]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].collSideModifiers[TRANS_RIGHT]), (udword) &(ShipStaticInfoR1[0]) }, { "collSideModifiers[TRANS_LEFT]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].collSideModifiers[TRANS_LEFT]), (udword) &(ShipStaticInfoR1[0]) }, { "collSideModifiers[TRANS_FORWARD]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].collSideModifiers[TRANS_FORWARD]), (udword) &(ShipStaticInfoR1[0]) }, { "collSideModifiers[TRANS_BACK]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].collSideModifiers[TRANS_BACKWARD]), (udword) &(ShipStaticInfoR1[0]) }, { "thruststrength[TRANS_UP]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].thruststrengthstat[TRANS_UP]), (udword) &(ShipStaticInfoR1[0]) }, { "thruststrength[TRANS_DOWN]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].thruststrengthstat[TRANS_DOWN]), (udword) &(ShipStaticInfoR1[0]) }, { "thruststrength[TRANS_RIGHT]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].thruststrengthstat[TRANS_RIGHT]), (udword) &(ShipStaticInfoR1[0]) }, { "thruststrength[TRANS_LEFT]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].thruststrengthstat[TRANS_LEFT]), (udword) &(ShipStaticInfoR1[0]) }, { "thruststrength[TRANS_FORWARD]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].thruststrengthstat[TRANS_FORWARD]), (udword) &(ShipStaticInfoR1[0]) }, { "thruststrength[TRANS_BACK]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].thruststrengthstat[TRANS_BACKWARD]), (udword) &(ShipStaticInfoR1[0]) }, { "rotstrength[ROT_YAWLEFT]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].rotstrengthstat[ROT_YAWLEFT]), (udword) &(ShipStaticInfoR1[0]) }, { "rotstrength[ROT_YAWRIGHT]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].rotstrengthstat[ROT_YAWRIGHT]), (udword) &(ShipStaticInfoR1[0]) }, { "rotstrength[ROT_PITCHUP]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].rotstrengthstat[ROT_PITCHUP]), (udword) &(ShipStaticInfoR1[0]) }, { "rotstrength[ROT_PITCHDOWN]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].rotstrengthstat[ROT_PITCHDOWN]), (udword) &(ShipStaticInfoR1[0]) }, { "rotstrength[ROT_ROLLRIGHT]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].rotstrengthstat[ROT_ROLLRIGHT]), (udword) &(ShipStaticInfoR1[0]) }, { "rotstrength[ROT_ROLLLEFT]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].rotstrengthstat[ROT_ROLLLEFT]), (udword) &(ShipStaticInfoR1[0]) }, { "turnspeed[TURN_YAW]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].turnspeedstat[TURN_YAW]), (udword) &(ShipStaticInfoR1[0]) }, { "turnspeed[TURN_PITCH]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].turnspeedstat[TURN_PITCH]), (udword) &(ShipStaticInfoR1[0]) }, { "turnspeed[TURN_ROLL]", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].turnspeedstat[TURN_ROLL]), (udword) &(ShipStaticInfoR1[0]) }, { "N-LIPS", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].scaleCap), (udword) &(ShipStaticInfoR1[0]) }, // { "scaleCap", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].scaleCap), (udword) &(ShipStaticInfoR1[0]) }, #if SO_CLOOGE_SCALE { "scaleFactor", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].scaleFactor), (udword) &(ShipStaticInfoR1[0]) }, #endif // { "NumRepairDroids", scriptSetUdwordCB, (udword) &(ShipStaticInfoR1[0].nRepairDroids), (udword) &(ShipStaticInfoR1[0]) }, { "trailStyle", scriptSetUdwordCB, (udword) &(ShipStaticInfoR1[0].trailStyle[0]), (udword) &(ShipStaticInfoR1[0]) }, { "trailWidth", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailWidth[0]), (udword) &(ShipStaticInfoR1[0]) }, { "trailHeight", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailHeight[0]), (udword) &(ShipStaticInfoR1[0]) }, { "trailAngle", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailAngle[0]), (udword) &(ShipStaticInfoR1[0]) }, { "trailRibbonAdjust", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailRibbonAdjust[0]), (udword) &(ShipStaticInfoR1[0]) }, { "trailLength", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailLength[0]), (udword) &(ShipStaticInfoR1[0]) }, { "trailScaleCap", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailScaleCap[0]), (udword) &(ShipStaticInfoR1[0]) }, { "trailStyle2", scriptSetUdwordCB, (udword) &(ShipStaticInfoR1[0].trailStyle[1]), (udword) &(ShipStaticInfoR1[0]) }, { "trailWidth2", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailWidth[1]), (udword) &(ShipStaticInfoR1[0]) }, { "trailHeight2", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailHeight[1]), (udword) &(ShipStaticInfoR1[0]) }, { "trailAngle2", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailAngle[1]), (udword) &(ShipStaticInfoR1[0]) }, { "trailRibbonAdjust2", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailRibbonAdjust[1]), (udword) &(ShipStaticInfoR1[0]) }, { "trailLength2", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailLength[1]), (udword) &(ShipStaticInfoR1[0]) }, { "trailScaleCap2", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailScaleCap[1]), (udword) &(ShipStaticInfoR1[0]) }, { "trailStyle3", scriptSetUdwordCB, (udword) &(ShipStaticInfoR1[0].trailStyle[2]), (udword) &(ShipStaticInfoR1[0]) }, { "trailWidth3", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailWidth[2]), (udword) &(ShipStaticInfoR1[0]) }, { "trailHeight3", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailHeight[2]), (udword) &(ShipStaticInfoR1[0]) }, { "trailAngle3", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailAngle[2]), (udword) &(ShipStaticInfoR1[0]) }, { "trailRibbonAdjust3", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailRibbonAdjust[2]), (udword) &(ShipStaticInfoR1[0]) }, { "trailLength3", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailLength[2]), (udword) &(ShipStaticInfoR1[0]) }, { "trailScaleCap3", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailScaleCap[2]), (udword) &(ShipStaticInfoR1[0]) }, { "trailStyle4", scriptSetUdwordCB, (udword) &(ShipStaticInfoR1[0].trailStyle[3]), (udword) &(ShipStaticInfoR1[0]) }, { "trailWidth4", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailWidth[3]), (udword) &(ShipStaticInfoR1[0]) }, { "trailHeight4", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailHeight[3]), (udword) &(ShipStaticInfoR1[0]) }, { "trailAngle4", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailAngle[3]), (udword) &(ShipStaticInfoR1[0]) }, { "trailRibbonAdjust4", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailRibbonAdjust[3]), (udword) &(ShipStaticInfoR1[0]) }, { "trailLength4", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailLength[3]), (udword) &(ShipStaticInfoR1[0]) }, { "trailScaleCap4", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailScaleCap[3]), (udword) &(ShipStaticInfoR1[0]) }, { "trailSpriteRadius", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailSpriteRadius[0]), (udword) &(ShipStaticInfoR1[0]) }, { "trailSpriteRadius2", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailSpriteRadius[1]), (udword) &(ShipStaticInfoR1[0]) }, { "trailSpriteRadius3", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailSpriteRadius[2]), (udword) &(ShipStaticInfoR1[0]) }, { "trailSpriteRadius4", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailSpriteRadius[3]), (udword) &(ShipStaticInfoR1[0]) }, { "trailSpriteOffset", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailSpriteOffset[0]), (udword) &(ShipStaticInfoR1[0]) }, { "trailSpriteOffset2", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailSpriteOffset[1]), (udword) &(ShipStaticInfoR1[0]) }, { "trailSpriteOffset3", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailSpriteOffset[2]), (udword) &(ShipStaticInfoR1[0]) }, { "trailSpriteOffset4", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].trailSpriteOffset[3]), (udword) &(ShipStaticInfoR1[0]) }, { "minimumZoomDistance", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].minimumZoomDistance), (udword) &(ShipStaticInfoR1[0]) }, { "renderlistFade", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].renderlistFade), (udword) &(ShipStaticInfoR1[0]) }, { "renderlistLimit", scriptSetReal32SqrCB, (udword) &(ShipStaticInfoR1[0].renderlistLimitSqr), (udword) &(ShipStaticInfoR1[0]) }, { "dockLightNear", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].dockLightNear), (udword) &(ShipStaticInfoR1[0]) }, { "dockLightFar", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].dockLightFar), (udword) &(ShipStaticInfoR1[0]) }, { "dockLightColor", scriptSetRGBCB, (udword) &(ShipStaticInfoR1[0].dockLightColor), (udword) &(ShipStaticInfoR1[0]) }, { "hyperspaceColor", scriptSetRGBCB, (udword) &(ShipStaticInfoR1[0].hyperspaceColor), (udword) &(ShipStaticInfoR1[0]) }, { "preciseSelection",scriptSetUdwordCB,(udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.preciseSelection), (udword) &(ShipStaticInfoR1[0]) }, { "madGunOpenDamagedHealthThreshold", scriptSetReal32CB,(udword) &(ShipStaticInfoR1[0].madGunOpenDamagedHealthThreshold), (udword) &(ShipStaticInfoR1[0]) }, { "madWingOpenDamagedHealthThreshold", scriptSetReal32CB,(udword) &(ShipStaticInfoR1[0].madWingOpenDamagedHealthThreshold), (udword) &(ShipStaticInfoR1[0]) }, { "NUMBER_OF_SALVAGE_POINTS", scriptSetSalvageStatCB,(udword) &(ShipStaticInfoR1[0]),(udword) &(ShipStaticInfoR1[0]) }, { "Overlay_Selection_Scalar", scriptSetReal32CB, (udword) &(ShipStaticInfoR1[0].tacticalSelectionScale), (udword) &(ShipStaticInfoR1[0]) }, { NULL,NULL,0,0 } }; scriptStructEntry HierarchyBindingTable[] = { { "BindGun", setGunBindInfo, 0, 0 }, { "BindAnimations", setAnimationBindInfo,0, 0 }, { NULL,NULL,0,0 } }; scriptStructEntry MadMaxMadInfoLoad[] = { { "MadStartInfo", setMadStartInfo,0, 0 }, { "MadGunAnims", setGunAnimInfo,0, 0 }, { "MadDockAnims", setDockAnimInfo,0, 0 }, { "MadMothershipDockingAnims", setMothershipDoorAnimInfo,0,0 }, { "MadSpecialCaseAnims", setSpecialCaseAnimInfo,0,0 }, { NULL,NULL,0,0 } }; scriptStructEntry AsteroidStaticScriptTable[] = { { "LODFile", LODScriptLoad, (udword) &(asteroidStaticInfos[0].staticheader.LOD), (udword) &(asteroidStaticInfos[0]) }, { "pMexData", loadMexDataCB, (udword) &(asteroidStaticInfos[0].staticheader.pMexData), (udword) &(asteroidStaticInfos[0]) }, { "mass", scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.mass), (udword) &(asteroidStaticInfos[0]) }, { "momentOfInertiaX",scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.momentOfInertiaX), (udword) &(asteroidStaticInfos[0]) }, { "momentOfInertiaY",scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.momentOfInertiaY), (udword) &(asteroidStaticInfos[0]) }, { "momentOfInertiaZ",scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.momentOfInertiaZ), (udword) &(asteroidStaticInfos[0]) }, { "collBoxScaleRight",scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.staticCollInfo.collBoxScaleRight), (udword) &(asteroidStaticInfos[0]) }, { "collBoxScaleUp",scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.staticCollInfo.collBoxScaleUp), (udword) &(asteroidStaticInfos[0]) }, { "collBoxScaleForward",scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.staticCollInfo.collBoxScaleForward), (udword) &(asteroidStaticInfos[0]) }, { "collBoxOffsetX",scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetX), (udword) &(asteroidStaticInfos[0]) }, { "collBoxOffsetY",scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetY), (udword) &(asteroidStaticInfos[0]) }, { "collBoxOffsetZ",scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetZ), (udword) &(asteroidStaticInfos[0]) }, { "immobile", scriptSetBool8, (udword) &(asteroidStaticInfos[0].staticheader.immobile), (udword) &(asteroidStaticInfos[0]) }, { "rightOfWay", scriptSetSbyteCB, (udword) &(asteroidStaticInfos[0].staticheader.rightOfWay), (udword) &(asteroidStaticInfos[0]) }, { "approxcollmodifier", scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.staticCollInfo.approxcollmodifier), (udword) &(asteroidStaticInfos[0]) }, { "avoidcollmodifier", scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.staticCollInfo.avoidcollmodifier), (udword) &(asteroidStaticInfos[0]) }, { "maxvelocity", scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.maxvelocity), (udword) &(asteroidStaticInfos[0]) }, { "maxrot", scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].staticheader.maxrot), (udword) &(asteroidStaticInfos[0]) }, { "maxhealth", scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].maxhealth), (udword) &(asteroidStaticInfos[0]) }, { "minCollDamage", scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].minCollDamage), (udword) &(asteroidStaticInfos[0]) }, { "maxCollDamage", scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].maxCollDamage), (udword) &(asteroidStaticInfos[0]) }, { "resourcevalue", scriptSetSdwordCB, (udword) &(asteroidStaticInfos[0].resourcevalue), (udword) &(asteroidStaticInfos[0]) }, { "harvestableByMultipleShips", scriptSetUdwordCB, (udword) &(asteroidStaticInfos[0].harvestableByMultipleShips), (udword) &(asteroidStaticInfos[0]) }, { "asteroidCanShrink",scriptSetBool8, (udword) &(asteroidStaticInfos[0].asteroidCanShrink), (udword) &(asteroidStaticInfos[0]) }, { "asteroidCanBreak", scriptSetBool8, (udword) &(asteroidStaticInfos[0].asteroidCanBreak), (udword) &(asteroidStaticInfos[0]) }, { "asteroidMinShrink",scriptSetReal32CB, (udword) &(asteroidStaticInfos[0].asteroidMinShrink), (udword) &(asteroidStaticInfos[0]) }, { "breakinto[Asteroid0]",scriptSetUdwordCB, (udword) &(asteroidStaticInfos[0].breakinto[Asteroid0]), (udword) &(asteroidStaticInfos[0]) }, { "breakinto[Asteroid1]",scriptSetUdwordCB, (udword) &(asteroidStaticInfos[0].breakinto[Asteroid1]), (udword) &(asteroidStaticInfos[0]) }, { "breakinto[Asteroid2]",scriptSetUdwordCB, (udword) &(asteroidStaticInfos[0].breakinto[Asteroid2]), (udword) &(asteroidStaticInfos[0]) }, { "breakinto[Asteroid3]",scriptSetUdwordCB, (udword) &(asteroidStaticInfos[0].breakinto[Asteroid3]), (udword) &(asteroidStaticInfos[0]) }, { "breakinto[Asteroid4]",scriptSetUdwordCB, (udword) &(asteroidStaticInfos[0].breakinto[Asteroid4]), (udword) &(asteroidStaticInfos[0]) }, { "preciseSelection",scriptSetUdwordCB,(udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.preciseSelection), (udword) &(ShipStaticInfoR1[0]) }, { NULL,NULL,0,0 } }; scriptStructEntry DustCloudStaticScriptTable[] = { { "LODFile", LODScriptLoad, (udword) &(dustcloudStaticInfos[0].staticheader.LOD), (udword) &(dustcloudStaticInfos[0]) }, { "pMexData", loadMexDataCB, (udword) &(dustcloudStaticInfos[0].staticheader.pMexData), (udword) &(dustcloudStaticInfos[0]) }, { "mass", scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.mass), (udword) &(dustcloudStaticInfos[0]) }, { "momentOfInertiaX",scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.momentOfInertiaX), (udword) &(dustcloudStaticInfos[0]) }, { "momentOfInertiaY",scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.momentOfInertiaY), (udword) &(dustcloudStaticInfos[0]) }, { "momentOfInertiaZ",scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.momentOfInertiaZ), (udword) &(dustcloudStaticInfos[0]) }, { "collBoxScaleRight",scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.staticCollInfo.collBoxScaleRight), (udword) &(dustcloudStaticInfos[0]) }, { "collBoxScaleUp",scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.staticCollInfo.collBoxScaleUp), (udword) &(dustcloudStaticInfos[0]) }, { "collBoxScaleForward",scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.staticCollInfo.collBoxScaleForward), (udword) &(dustcloudStaticInfos[0]) }, { "collBoxOffsetX",scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetX), (udword) &(dustcloudStaticInfos[0]) }, { "collBoxOffsetY",scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetY), (udword) &(dustcloudStaticInfos[0]) }, { "collBoxOffsetZ",scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetZ), (udword) &(dustcloudStaticInfos[0]) }, { "immobile", scriptSetBool8, (udword) &(dustcloudStaticInfos[0].staticheader.immobile), (udword) &(dustcloudStaticInfos[0]) }, { "approxcollmodifier", scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.staticCollInfo.approxcollmodifier), (udword) &(dustcloudStaticInfos[0]) }, { "avoidcollmodifier", scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.staticCollInfo.avoidcollmodifier), (udword) &(dustcloudStaticInfos[0]) }, { "maxvelocity", scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.maxvelocity), (udword) &(dustcloudStaticInfos[0]) }, { "maxrot", scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].staticheader.maxrot), (udword) &(dustcloudStaticInfos[0]) }, { "maxhealth", scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].maxhealth), (udword) &(dustcloudStaticInfos[0]) }, { "minCollDamage", scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].minCollDamage), (udword) &(dustcloudStaticInfos[0]) }, { "maxCollDamage", scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].maxCollDamage), (udword) &(dustcloudStaticInfos[0]) }, { "resourcevalue", scriptSetSdwordCB, (udword) &(dustcloudStaticInfos[0].resourcevalue), (udword) &(dustcloudStaticInfos[0]) }, { "harvestableByMultipleShips", scriptSetUdwordCB, (udword) &(dustcloudStaticInfos[0].harvestableByMultipleShips), (udword) &(dustcloudStaticInfos[0]) }, { "dustcloudCanShrink",scriptSetBool8, (udword) &(dustcloudStaticInfos[0].dustcloudCanShrink), (udword) &(dustcloudStaticInfos[0]) }, { "dustcloudMinShrink",scriptSetReal32CB, (udword) &(dustcloudStaticInfos[0].dustcloudMinShrink), (udword) &(dustcloudStaticInfos[0]) }, { "preciseSelection",scriptSetUdwordCB,(udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.preciseSelection), (udword) &(ShipStaticInfoR1[0]) }, { NULL,NULL,0,0 } }; scriptStructEntry NebulaStaticScriptTable[] = { { "LODFile", LODScriptLoad, (udword)&(nebulaStaticInfos[0].staticheader.LOD), (udword)&(nebulaStaticInfos[0]) }, { "pMexData", loadMexDataCB, (udword)&(nebulaStaticInfos[0].staticheader.pMexData), (udword)&(nebulaStaticInfos[0]) }, { "mass", scriptSetReal32CB, (udword)&(nebulaStaticInfos[0].staticheader.mass), (udword)&(nebulaStaticInfos[0]) }, { "momentOfInertiaX", scriptSetReal32CB, (udword)&(nebulaStaticInfos[0].staticheader.momentOfInertiaX), (udword)&(nebulaStaticInfos[0]) }, { "momentOfInertiaY", scriptSetReal32CB, (udword)&(nebulaStaticInfos[0].staticheader.momentOfInertiaY), (udword)&(nebulaStaticInfos[0]) }, { "momentOfInertiaZ", scriptSetReal32CB, (udword)&(nebulaStaticInfos[0].staticheader.momentOfInertiaZ), (udword)&(nebulaStaticInfos[0]) }, { "collBoxScaleRight",scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].staticheader.staticCollInfo.collBoxScaleRight), (udword) &(nebulaStaticInfos[0]) }, { "collBoxScaleUp",scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].staticheader.staticCollInfo.collBoxScaleUp), (udword) &(nebulaStaticInfos[0]) }, { "collBoxScaleForward",scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].staticheader.staticCollInfo.collBoxScaleForward), (udword) &(nebulaStaticInfos[0]) }, { "collBoxOffsetX",scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetX), (udword) &(nebulaStaticInfos[0]) }, { "collBoxOffsetY",scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetY), (udword) &(nebulaStaticInfos[0]) }, { "collBoxOffsetZ",scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetZ), (udword) &(nebulaStaticInfos[0]) }, { "immobile", scriptSetBool8, (udword)&(nebulaStaticInfos[0].staticheader.immobile), (udword)&(nebulaStaticInfos[0]) }, { "approxcollmodifier", scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].staticheader.staticCollInfo.approxcollmodifier), (udword) &(nebulaStaticInfos[0]) }, { "avoidcollmodifier", scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].staticheader.staticCollInfo.avoidcollmodifier), (udword) &(nebulaStaticInfos[0]) }, { "maxvelocity", scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].staticheader.maxvelocity), (udword) &(nebulaStaticInfos[0]) }, { "maxrot", scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].staticheader.maxrot), (udword) &(nebulaStaticInfos[0]) }, { "maxhealth", scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].maxhealth), (udword) &(nebulaStaticInfos[0]) }, { "minCollDamage", scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].minCollDamage), (udword) &(nebulaStaticInfos[0]) }, { "maxCollDamage", scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].maxCollDamage), (udword) &(nebulaStaticInfos[0]) }, { "resourcevalue", scriptSetSdwordCB, (udword) &(nebulaStaticInfos[0].resourcevalue), (udword) &(nebulaStaticInfos[0]) }, { "harvestableByMultipleShips", scriptSetUdwordCB, (udword) &(nebulaStaticInfos[0].harvestableByMultipleShips), (udword) &(nebulaStaticInfos[0]) }, { "nebulaCanShrink",scriptSetBool8, (udword) &(nebulaStaticInfos[0].nebulaCanShrink), (udword) &(nebulaStaticInfos[0]) }, { "nebulaMinShrink",scriptSetReal32CB, (udword) &(nebulaStaticInfos[0].nebulaMinShrink), (udword) &(nebulaStaticInfos[0]) }, { "preciseSelection",scriptSetUdwordCB,(udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.preciseSelection), (udword) &(ShipStaticInfoR1[0]) }, { NULL,NULL,0,0 } }; scriptStructEntry GasCloudStaticScriptTable[] = { { "LODFile", LODScriptLoad, (udword) &(gascloudStaticInfos[0].staticheader.LOD), (udword) &(gascloudStaticInfos[0]) }, { "pMexData", loadMexDataCB, (udword) &(gascloudStaticInfos[0].staticheader.pMexData), (udword) &(gascloudStaticInfos[0]) }, { "mass", scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.mass), (udword) &(gascloudStaticInfos[0]) }, { "momentOfInertiaX",scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.momentOfInertiaX), (udword) &(gascloudStaticInfos[0]) }, { "momentOfInertiaY",scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.momentOfInertiaY), (udword) &(gascloudStaticInfos[0]) }, { "momentOfInertiaZ",scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.momentOfInertiaZ), (udword) &(gascloudStaticInfos[0]) }, { "collBoxScaleRight",scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.staticCollInfo.collBoxScaleRight), (udword) &(gascloudStaticInfos[0]) }, { "collBoxScaleUp",scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.staticCollInfo.collBoxScaleUp), (udword) &(gascloudStaticInfos[0]) }, { "collBoxScaleForward",scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.staticCollInfo.collBoxScaleForward), (udword) &(gascloudStaticInfos[0]) }, { "collBoxOffsetX",scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetX), (udword) &(gascloudStaticInfos[0]) }, { "collBoxOffsetY",scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetY), (udword) &(gascloudStaticInfos[0]) }, { "collBoxOffsetZ",scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetZ), (udword) &(gascloudStaticInfos[0]) }, { "immobile", scriptSetBool8, (udword) &(gascloudStaticInfos[0].staticheader.immobile), (udword) &(gascloudStaticInfos[0]) }, { "approxcollmodifier", scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.staticCollInfo.approxcollmodifier), (udword) &(gascloudStaticInfos[0]) }, { "avoidcollmodifier", scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.staticCollInfo.avoidcollmodifier), (udword) &(gascloudStaticInfos[0]) }, { "maxvelocity", scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.maxvelocity), (udword) &(gascloudStaticInfos[0]) }, { "maxrot", scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].staticheader.maxrot), (udword) &(gascloudStaticInfos[0]) }, { "maxhealth", scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].maxhealth), (udword) &(gascloudStaticInfos[0]) }, { "minCollDamage", scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].minCollDamage), (udword) &(gascloudStaticInfos[0]) }, { "maxCollDamage", scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].maxCollDamage), (udword) &(gascloudStaticInfos[0]) }, { "resourcevalue", scriptSetSdwordCB, (udword) &(gascloudStaticInfos[0].resourcevalue), (udword) &(gascloudStaticInfos[0]) }, { "harvestableByMultipleShips", scriptSetUdwordCB, (udword) &(gascloudStaticInfos[0].harvestableByMultipleShips), (udword) &(gascloudStaticInfos[0]) }, { "gascloudCanShrink",scriptSetBool8, (udword) &(gascloudStaticInfos[0].gascloudCanShrink), (udword) &(gascloudStaticInfos[0]) }, { "gascloudMinShrink",scriptSetReal32CB, (udword) &(gascloudStaticInfos[0].gascloudMinShrink), (udword) &(gascloudStaticInfos[0]) }, { "preciseSelection",scriptSetUdwordCB,(udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.preciseSelection), (udword) &(ShipStaticInfoR1[0]) }, { NULL,NULL,0,0 } }; scriptStructEntry DerelictStaticScriptTable[] = { { "LODFile", LODScriptLoad, (udword) &(derelictStaticInfos[0].staticheader.LOD), (udword) &(derelictStaticInfos[0]) }, { "pMexData", loadMexDataCB, (udword) &(derelictStaticInfos[0].staticheader.pMexData), (udword) &(derelictStaticInfos[0]) }, { "mass", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.mass), (udword) &(derelictStaticInfos[0]) }, { "momentOfInertiaX",scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.momentOfInertiaX), (udword) &(derelictStaticInfos[0]) }, { "momentOfInertiaY",scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.momentOfInertiaY), (udword) &(derelictStaticInfos[0]) }, { "momentOfInertiaZ",scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.momentOfInertiaZ), (udword) &(derelictStaticInfos[0]) }, { "collBoxScaleRight",scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.staticCollInfo.collBoxScaleRight), (udword) &(derelictStaticInfos[0]) }, { "collBoxScaleUp",scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.staticCollInfo.collBoxScaleUp), (udword) &(derelictStaticInfos[0]) }, { "collBoxScaleForward",scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.staticCollInfo.collBoxScaleForward), (udword) &(derelictStaticInfos[0]) }, { "collBoxOffsetX",scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetX), (udword) &(derelictStaticInfos[0]) }, { "collBoxOffsetY",scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetY), (udword) &(derelictStaticInfos[0]) }, { "collBoxOffsetZ",scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetZ), (udword) &(derelictStaticInfos[0]) }, { "rightOfWay", scriptSetSbyteCB, (udword) &(derelictStaticInfos[0].staticheader.rightOfWay), (udword) &(derelictStaticInfos[0]) }, { "immobile", scriptSetBool8, (udword) &(derelictStaticInfos[0].staticheader.immobile), (udword) &(derelictStaticInfos[0]) }, { "approxcollmodifier", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.staticCollInfo.approxcollmodifier), (udword) &(derelictStaticInfos[0]) }, { "avoidcollmodifier", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.staticCollInfo.avoidcollmodifier), (udword) &(derelictStaticInfos[0]) }, { "maxvelocity", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.maxvelocity), (udword) &(derelictStaticInfos[0]) }, { "maxrot", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].staticheader.maxrot), (udword) &(derelictStaticInfos[0]) }, { "maxhealth", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].maxhealth), (udword) &(derelictStaticInfos[0]) }, { "minCollDamage", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].minCollDamage), (udword) &(derelictStaticInfos[0]) }, { "maxCollDamage", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].maxCollDamage), (udword) &(derelictStaticInfos[0]) }, { "thruststrength[TRANS_UP]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].thruststrengthstat[TRANS_UP]), (udword) &(derelictStaticInfos[0]) }, { "thruststrength[TRANS_DOWN]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].thruststrengthstat[TRANS_DOWN]), (udword) &(derelictStaticInfos[0]) }, { "thruststrength[TRANS_RIGHT]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].thruststrengthstat[TRANS_RIGHT]), (udword) &(derelictStaticInfos[0]) }, { "thruststrength[TRANS_LEFT]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].thruststrengthstat[TRANS_LEFT]), (udword) &(derelictStaticInfos[0]) }, { "thruststrength[TRANS_FORWARD]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].thruststrengthstat[TRANS_FORWARD]), (udword) &(derelictStaticInfos[0]) }, { "thruststrength[TRANS_BACK]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].thruststrengthstat[TRANS_BACKWARD]), (udword) &(derelictStaticInfos[0]) }, { "rotstrength[ROT_YAWLEFT]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].rotstrengthstat[ROT_YAWLEFT]), (udword) &(derelictStaticInfos[0]) }, { "rotstrength[ROT_YAWRIGHT]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].rotstrengthstat[ROT_YAWRIGHT]), (udword) &(derelictStaticInfos[0]) }, { "rotstrength[ROT_PITCHUP]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].rotstrengthstat[ROT_PITCHUP]), (udword) &(derelictStaticInfos[0]) }, { "rotstrength[ROT_PITCHDOWN]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].rotstrengthstat[ROT_PITCHDOWN]), (udword) &(derelictStaticInfos[0]) }, { "rotstrength[ROT_ROLLRIGHT]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].rotstrengthstat[ROT_ROLLRIGHT]), (udword) &(derelictStaticInfos[0]) }, { "rotstrength[ROT_ROLLLEFT]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].rotstrengthstat[ROT_ROLLLEFT]), (udword) &(derelictStaticInfos[0]) }, { "turnspeed[TURN_YAW]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].turnspeedstat[TURN_YAW]), (udword) &(derelictStaticInfos[0]) }, { "turnspeed[TURN_PITCH]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].turnspeedstat[TURN_PITCH]), (udword) &(derelictStaticInfos[0]) }, { "turnspeed[TURN_ROLL]", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].turnspeedstat[TURN_ROLL]), (udword) &(derelictStaticInfos[0]) }, { "pitchdescend", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].pitchdescend), (udword) &(derelictStaticInfos[0]) }, { "sinbank", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].sinbank), (udword) &(derelictStaticInfos[0]) }, { "pitchturn", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].pitchturn), (udword) &(derelictStaticInfos[0]) }, { "preciseSelection", scriptSetUdwordCB,(udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.preciseSelection), (udword) &(ShipStaticInfoR1[0]) }, { "NUMBER_OF_SALVAGE_POINTS", scriptSetSalvageStatCB,(udword) &(derelictStaticInfos[0]),(udword) &(derelictStaticInfos[0]) }, { "scaleFactor", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].scaleFactor), (udword) &(derelictStaticInfos[0]) }, { "worldRender", scriptSetBool, (udword) &(derelictStaticInfos[0].worldRender), (udword) &(derelictStaticInfos[0]) }, { "salvageable", scriptSetBool, (udword) &(derelictStaticInfos[0].salvageable), (udword) &(derelictStaticInfos[0]) }, { "minimumZoomDistance", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].minimumZoomDistance), (udword) &(derelictStaticInfos[0]) }, { "renderlistFade", scriptSetReal32CB, (udword) &(derelictStaticInfos[0].renderlistFade), (udword) &(derelictStaticInfos[0]) }, { "renderlistLimit", scriptSetReal32SqrCB, (udword) &(derelictStaticInfos[0].renderlistLimitSqr), (udword) &(derelictStaticInfos[0]) }, { NULL,NULL,0,0 } }; scriptStructEntry MissileStaticScriptTable[] = { { "LODFile", LODScriptLoad, (udword) &(missileStaticInfos[0].staticheader.LOD), (udword) &(missileStaticInfos[0]) }, { "pMexData", loadMexDataCB, (udword) &(missileStaticInfos[0].staticheader.pMexData), (udword) &(missileStaticInfos[0]) }, { "mass", scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.mass), (udword) &(missileStaticInfos[0]) }, { "momentOfInertiaX",scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.momentOfInertiaX), (udword) &(missileStaticInfos[0]) }, { "momentOfInertiaY",scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.momentOfInertiaY), (udword) &(missileStaticInfos[0]) }, { "momentOfInertiaZ",scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.momentOfInertiaZ), (udword) &(missileStaticInfos[0]) }, { "collBoxScaleRight",scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.staticCollInfo.collBoxScaleRight), (udword) &(missileStaticInfos[0]) }, { "collBoxScaleUp",scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.staticCollInfo.collBoxScaleUp), (udword) &(missileStaticInfos[0]) }, { "collBoxScaleForward",scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.staticCollInfo.collBoxScaleForward), (udword) &(missileStaticInfos[0]) }, { "collBoxOffsetX",scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetX), (udword) &(missileStaticInfos[0]) }, { "collBoxOffsetY",scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetY), (udword) &(missileStaticInfos[0]) }, { "collBoxOffsetZ",scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetZ), (udword) &(missileStaticInfos[0]) }, { "maxvelocity", scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.maxvelocity), (udword) &(missileStaticInfos[0]) }, { "maxrot", scriptSetReal32CB, (udword) &(missileStaticInfos[0].staticheader.maxrot), (udword) &(missileStaticInfos[0]) }, { "maxhealth", scriptSetReal32CB, (udword) &(missileStaticInfos[0].maxhealth), (udword) &(missileStaticInfos[0]) }, { "minCollDamage", scriptSetReal32CB, (udword) &(missileStaticInfos[0].minCollDamage), (udword) &(missileStaticInfos[0]) }, { "maxCollDamage", scriptSetReal32CB, (udword) &(missileStaticInfos[0].maxCollDamage), (udword) &(missileStaticInfos[0]) }, { "thruststrength[TRANS_UP]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].thruststrengthstat[TRANS_UP]), (udword) &(missileStaticInfos[0]) }, { "thruststrength[TRANS_DOWN]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].thruststrengthstat[TRANS_DOWN]), (udword) &(missileStaticInfos[0]) }, { "thruststrength[TRANS_RIGHT]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].thruststrengthstat[TRANS_RIGHT]), (udword) &(missileStaticInfos[0]) }, { "thruststrength[TRANS_LEFT]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].thruststrengthstat[TRANS_LEFT]), (udword) &(missileStaticInfos[0]) }, { "thruststrength[TRANS_FORWARD]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].thruststrengthstat[TRANS_FORWARD]), (udword) &(missileStaticInfos[0]) }, { "thruststrength[TRANS_BACK]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].thruststrengthstat[TRANS_BACKWARD]), (udword) &(missileStaticInfos[0]) }, { "rotstrength[ROT_YAWLEFT]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].rotstrengthstat[ROT_YAWLEFT]), (udword) &(missileStaticInfos[0]) }, { "rotstrength[ROT_YAWRIGHT]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].rotstrengthstat[ROT_YAWRIGHT]), (udword) &(missileStaticInfos[0]) }, { "rotstrength[ROT_PITCHUP]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].rotstrengthstat[ROT_PITCHUP]), (udword) &(missileStaticInfos[0]) }, { "rotstrength[ROT_PITCHDOWN]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].rotstrengthstat[ROT_PITCHDOWN]), (udword) &(missileStaticInfos[0]) }, { "rotstrength[ROT_ROLLRIGHT]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].rotstrengthstat[ROT_ROLLRIGHT]), (udword) &(missileStaticInfos[0]) }, { "rotstrength[ROT_ROLLLEFT]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].rotstrengthstat[ROT_ROLLLEFT]), (udword) &(missileStaticInfos[0]) }, { "turnspeed[TURN_YAW]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].turnspeedstat[TURN_YAW]), (udword) &(missileStaticInfos[0]) }, { "turnspeed[TURN_PITCH]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].turnspeedstat[TURN_PITCH]), (udword) &(missileStaticInfos[0]) }, { "turnspeed[TURN_ROLL]", scriptSetReal32CB, (udword) &(missileStaticInfos[0].turnspeedstat[TURN_ROLL]), (udword) &(missileStaticInfos[0]) }, { "preciseSelection",scriptSetUdwordCB,(udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.preciseSelection), (udword) &(ShipStaticInfoR1[0]) }, { NULL,NULL,0,0 } }; scriptStructEntry MineStaticScriptTable[] = { { "LODFile", LODScriptLoad, (udword) &(mineStaticInfos[0].staticheader.LOD), (udword) &(mineStaticInfos[0]) }, { "pMexData", loadMexDataCB, (udword) &(mineStaticInfos[0].staticheader.pMexData), (udword) &(mineStaticInfos[0]) }, { "mass", scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.mass), (udword) &(mineStaticInfos[0]) }, { "momentOfInertiaX",scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.momentOfInertiaX), (udword) &(mineStaticInfos[0]) }, { "momentOfInertiaY",scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.momentOfInertiaY), (udword) &(mineStaticInfos[0]) }, { "momentOfInertiaZ",scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.momentOfInertiaZ), (udword) &(mineStaticInfos[0]) }, { "collBoxScaleRight",scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.staticCollInfo.collBoxScaleRight), (udword) &(asteroidStaticInfos[0]) }, { "collBoxScaleUp",scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.staticCollInfo.collBoxScaleUp), (udword) &(asteroidStaticInfos[0]) }, { "collBoxScaleForward",scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.staticCollInfo.collBoxScaleForward), (udword) &(asteroidStaticInfos[0]) }, { "maxvelocity", scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.maxvelocity), (udword) &(mineStaticInfos[0]) }, { "collBoxOffsetX",scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetX), (udword) &(mineStaticInfos[0]) }, { "collBoxOffsetY",scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetY), (udword) &(mineStaticInfos[0]) }, { "collBoxOffsetZ",scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.staticCollInfo.collBoxOffsetZ), (udword) &(mineStaticInfos[0]) }, { "maxvelocity_FORCED", scriptSetReal32CB, (udword) &(mineStaticInfos[0].maxvelocity_FORCED), (udword) &(mineStaticInfos[0]) }, { "maxrot", scriptSetReal32CB, (udword) &(mineStaticInfos[0].staticheader.maxrot), (udword) &(mineStaticInfos[0]) }, { "maxhealth", scriptSetReal32CB, (udword) &(mineStaticInfos[0].maxhealth), (udword) &(mineStaticInfos[0]) }, { "minCollDamage", scriptSetReal32CB, (udword) &(mineStaticInfos[0].minCollDamage), (udword) &(mineStaticInfos[0]) }, { "maxCollDamage", scriptSetReal32CB, (udword) &(mineStaticInfos[0].maxCollDamage), (udword) &(mineStaticInfos[0]) }, { "thruststrength[TRANS_UP]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].thruststrengthstat[TRANS_UP]), (udword) &(mineStaticInfos[0]) }, { "thruststrength[TRANS_DOWN]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].thruststrengthstat[TRANS_DOWN]), (udword) &(mineStaticInfos[0]) }, { "thruststrength[TRANS_RIGHT]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].thruststrengthstat[TRANS_RIGHT]), (udword) &(mineStaticInfos[0]) }, { "thruststrength[TRANS_LEFT]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].thruststrengthstat[TRANS_LEFT]), (udword) &(mineStaticInfos[0]) }, { "thruststrength[TRANS_FORWARD]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].thruststrengthstat[TRANS_FORWARD]), (udword) &(mineStaticInfos[0]) }, { "thruststrength[TRANS_BACK]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].thruststrengthstat[TRANS_BACKWARD]), (udword) &(mineStaticInfos[0]) }, { "rotstrength[ROT_YAWLEFT]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].rotstrengthstat[ROT_YAWLEFT]), (udword) &(mineStaticInfos[0]) }, { "rotstrength[ROT_YAWRIGHT]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].rotstrengthstat[ROT_YAWRIGHT]), (udword) &(mineStaticInfos[0]) }, { "rotstrength[ROT_PITCHUP]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].rotstrengthstat[ROT_PITCHUP]), (udword) &(mineStaticInfos[0]) }, { "rotstrength[ROT_PITCHDOWN]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].rotstrengthstat[ROT_PITCHDOWN]), (udword) &(mineStaticInfos[0]) }, { "rotstrength[ROT_ROLLRIGHT]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].rotstrengthstat[ROT_ROLLRIGHT]), (udword) &(mineStaticInfos[0]) }, { "rotstrength[ROT_ROLLLEFT]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].rotstrengthstat[ROT_ROLLLEFT]), (udword) &(mineStaticInfos[0]) }, { "turnspeed[TURN_YAW]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].turnspeedstat[TURN_YAW]), (udword) &(mineStaticInfos[0]) }, { "turnspeed[TURN_PITCH]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].turnspeedstat[TURN_PITCH]), (udword) &(mineStaticInfos[0]) }, { "turnspeed[TURN_ROLL]", scriptSetReal32CB, (udword) &(mineStaticInfos[0].turnspeedstat[TURN_ROLL]), (udword) &(mineStaticInfos[0]) }, { "MINE_STOP_FRICTION", scriptSetReal32CB, (udword) &(mineStaticInfos[0].MINE_STOP_FRICTION), (udword) &(mineStaticInfos[0]) }, { "MINE_RANGESQR", scriptSetReal32SqrCB, (udword) &(mineStaticInfos[0].MINE_RANGESQR), (udword) &(mineStaticInfos[0]) }, { "MINE_RANGESQR_FORCED", scriptSetReal32SqrCB, (udword) &(mineStaticInfos[0].MINE_RANGESQR_FORCED), (udword) &(mineStaticInfos[0]) }, { "preciseSelection",scriptSetUdwordCB,(udword) &(ShipStaticInfoR1[0].staticheader.staticCollInfo.preciseSelection), (udword) &(ShipStaticInfoR1[0]) }, { NULL,NULL,0,0 } }; /*============================================================================= Private Functions: =============================================================================*/ /*============================================================================= The following functions are callback functions which fill in information in the static structures. They are called by scriptSetStruct =============================================================================*/ //bind a hierarchy element to a gun and set the hierarchy size static void setGunBindInfo(char *directory,char *field,void *dataToFillIn) { ShipStaticInfo *info = (ShipStaticInfo *)dataToFillIn; char *hString, *string, *gString; sdword gunIndex, nScanned, index, nBound; mhbinding *binding; lod *level; udword flags = 0; sdword frequency; //first string is always name of hierarchy member. hString = strtok(field, " ,"); //second string is the gun mex name gString = strtok(NULL, " ,"); nScanned = sscanf(gString, "Gun%d", &gunIndex); //get gun # dbgAssert(nScanned == 1); //verify it dbgAssert(gunIndex >= 0 && gunIndex < info->gunStaticInfo->numGuns); //parse the modifiers while ((string = strtok(NULL, " ,")) != NULL) { if (_stricmp(string, "Azimuth") == 0) { flags |= HBF_Azimuth; } else if (_stricmp(string, "Declination") == 0) { flags |= HBF_Declination; } else if (_stricmp(string, "Recoil") == 0) { flags |= HBF_Recoil; } else if (_stricmp(string, "Frequency") == 0) { string = strtok(NULL, " ,"); dbgAssert(string); nScanned = sscanf(string, "%d", &frequency); dbgAssert(nScanned == 1); dbgAssert(frequency >= 1 && frequency < HB_UpdateFrequencyMax); flags |= frequency; } } info->hierarchySize = lodHierarchySizeCompute(info->staticheader.LOD); nBound = 0; for (index = 0; index < info->staticheader.LOD->nLevels; index++) { //for all levels of detail level = &info->staticheader.LOD->level[index]; binding = NULL; if ((level->flags & LM_LODType) != LT_Mesh) { continue; } while ((binding = meshBindingFindByName(binding, level->hBindings, (meshdata *)level->pData, hString)) != NULL) { binding->function = gunMatrixUpdate; //bind all named members to this gun binding->userData = &info->gunStaticInfo->gunstatics[gunIndex]; binding->userID = gunIndex; binding->flags = flags; nBound++; } } #if MESH_VERBOSE_LEVEL >= 1 if (nBound == 0) { dbgWarningf(DBG_Loc, "Could not bind '%s' to '%s' because object not found.", hString, gString); } #endif #if MESH_VERBOSE_LEVEL >= 2 dbgMessagef("\nsetGunBindInfo: bound '%s' to '%s' %d times", hString, gString, nBound++); #endif } static void setAnimationBindInfo(char *directory,char *field,void *dataToFillIn) { ShipStaticInfo *info = (ShipStaticInfo *)dataToFillIn; char *shipName; char fileName[256]; shipName = ShipTypeToStr(info->shiptype); sprintf(fileName, "%s%s%s", directory, shipName, MAD_Extension);//make path to file info->madStatic = memAlloc(sizeof(madstatic), "madBindings", NonVolatile); memset(info->madStatic,0,sizeof(madstatic)); info->madStatic->header = madFileLoad(fileName); info->hierarchySize = lodHierarchySizeCompute(info->staticheader.LOD); } static void setMadStartInfo(char *directory,char *field,void *dataToFillIn) { ShipStaticInfo *info = (ShipStaticInfo *)dataToFillIn; char madAnimName[256]; udword startFlag; char madAnimName2[256]; udword startFlag2; sscanf(field,"%d , %s , %d , %s",&startFlag,madAnimName,&startFlag2,madAnimName2); if(startFlag == 1) { info->madStatic->needStartPlacedAnimation = TRUE; info->madStatic->startPlacedAnimationIndex = madAnimIndexFindByName(info->madStatic->header, madAnimName); } else { //no need to start and then pause an animation on creation info->madStatic->needStartPlacedAnimation = FALSE; } if(startFlag2 == 1) { info->madStatic->needStartBuiltAnimation = TRUE; info->madStatic->startBuiltAnimationIndex = madAnimIndexFindByName(info->madStatic->header, madAnimName2); } else { //no need to start and then pause an animation on creation info->madStatic->needStartBuiltAnimation = FALSE; } } /* sdword *gunOpenIndexs; //arrays for gunopening/closing animation indexes both damaged and undamaged. So we can support a number of different animationsfor the same ship sdword *gunOpenDamagedIndexes; sdword *gunCloseIndexes; sdword *gunCloseDamagedIndexes; */ static void setGunAnimInfo(char *directory,char *field,void *dataToFillIn) { ShipStaticInfo *info = (ShipStaticInfo *)dataToFillIn; sdword i; char madAnimName[256]; //maximum of 4 animations so far udword numAnims; char *token; char seps[] = ", "; token = strtok(field,seps); //do normal gun opening animations sscanf(token,"%d",&numAnims); info->madStatic->numGunOpenIndexes = numAnims; if(numAnims > 0) { info->madStatic->gunOpenIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"GunOpenMadAnimIndex",NonVolatile); for(i=0;imadStatic->gunOpenIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } token = strtok(NULL,seps); //do normal gun closing animations sscanf(token,"%d",&numAnims); info->madStatic->numGunCloseIndexes = numAnims; if(numAnims > 0) { info->madStatic->gunCloseIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"GunOpenMadAnimIndex",NonVolatile); for(i=0;imadStatic->gunCloseIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } token = strtok(NULL,seps); //do damaged gun opening animations sscanf(token,"%d",&numAnims); info->madStatic->numGunOpenDamagedIndexes = numAnims; if(numAnims > 0) { info->madStatic->gunOpenDamagedIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"GunOpenMadAnimIndex",NonVolatile); for(i=0;imadStatic->gunOpenDamagedIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } token = strtok(NULL,seps); //do damaged gun closing animations sscanf(token,"%d",&numAnims); info->madStatic->numGunCloseDamagedIndexes = numAnims; if(numAnims > 0) { info->madStatic->gunCloseDamagedIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"GunOpenMadAnimIndex",NonVolatile); for(i=0;imadStatic->gunCloseDamagedIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } } static void setDockAnimInfo(char *directory,char *field,void *dataToFillIn) { ShipStaticInfo *info = (ShipStaticInfo *)dataToFillIn; sdword i; char madAnimName[256]; //maximum of 4 animations so far udword numAnims; char *token; char seps[] = ", "; token = strtok(field,seps); //do normal gun opening animations sscanf(token,"%d",&numAnims); info->madStatic->numDockIndexes = numAnims; if(numAnims > 0) { info->madStatic->PostDockIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"GunOpenMadAnimIndex",NonVolatile); for(i=0;imadStatic->PostDockIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } token = strtok(NULL,seps); //do normal gun closing animations sscanf(token,"%d",&numAnims); info->madStatic->numPostDockIndexes = numAnims; if(numAnims > 0) { info->madStatic->DockIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"GunOpenMadAnimIndex",NonVolatile); for(i=0;imadStatic->DockIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } token = strtok(NULL,seps); //do damaged gun closing animations sscanf(token,"%d",&numAnims); info->madStatic->numPostDockDamagedIndexes = numAnims; if(numAnims > 0) { info->madStatic->PostDockDamagedIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"GunOpenMadAnimIndex",NonVolatile); for(i=0;imadStatic->PostDockDamagedIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } token = strtok(NULL,seps); //do damaged gun opening animations sscanf(token,"%d",&numAnims); info->madStatic->numDockDamagedIndexes = numAnims; if(numAnims > 0) { info->madStatic->DockDamagedIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"GunOpenMadAnimIndex",NonVolatile); for(i=0;imadStatic->DockDamagedIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } } void setMothershipDoorAnimInfo(char *directory,char *field,void *dataToFillIn) { ShipStaticInfo *info = (ShipStaticInfo *)dataToFillIn; sdword i; char madAnimName[256]; //maximum of 4 animations so far udword numAnims; char *token; char seps[] = ", "; token = strtok(field,seps); //do normal gun opening animations sscanf(token,"%d",&numAnims); info->madStatic->numDoorOpenIndexes = numAnims; if(numAnims > 0) { info->madStatic->DoorOpenIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"DoorOpenMadAnimIndex",NonVolatile); for(i=0;imadStatic->DoorOpenIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } token = strtok(NULL,seps); //do normal gun closing animations sscanf(token,"%d",&numAnims); info->madStatic->numDoorCloseIndexes = numAnims; if(numAnims > 0) { info->madStatic->DoorCloseIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"DoorCloseMadAnimIndex",NonVolatile); for(i=0;imadStatic->DoorCloseIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } } void setSpecialCaseAnimInfo(char *directory,char *field,void *dataToFillIn) { ShipStaticInfo *info = (ShipStaticInfo *)dataToFillIn; sdword i; char madAnimName[256]; //maximum of 4 animations so far udword numAnims; char *token; char seps[] = ", "; token = strtok(field,seps); //do normal gun opening animations sscanf(token,"%d",&numAnims); info->madStatic->numSpecialOpenIndexes = numAnims; if(numAnims > 0) { info->madStatic->specialOpenIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"SpecialMadAnimIndex",NonVolatile); for(i=0;imadStatic->specialOpenIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } token = strtok(NULL,seps); //do normal gun closing animations sscanf(token,"%d",&numAnims); info->madStatic->numSpecialCloseIndexes = numAnims; if(numAnims > 0) { info->madStatic->specialCloseIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"SpecialMadAnimIndex",NonVolatile); for(i=0;imadStatic->specialCloseIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } token = strtok(NULL,seps); //do damaged gun opening animations sscanf(token,"%d",&numAnims); info->madStatic->numSpecialOpenDamagedIndexes = numAnims; if(numAnims > 0) { info->madStatic->specialOpenDamagedIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"SpecialMadAnimIndex",NonVolatile); for(i=0;imadStatic->specialOpenDamagedIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } token = strtok(NULL,seps); //do damaged gun closing animations sscanf(token,"%d",&numAnims); info->madStatic->numSpecialCloseDamagedIndexes = numAnims; if(numAnims > 0) { info->madStatic->specialCloseDamagedIndexes = (sdword *) memAlloc(sizeof(sdword)*numAnims,"SpecialMadAnimIndex",NonVolatile); for(i=0;imadStatic->specialCloseDamagedIndexes[i] = madAnimIndexFindByName(info->madStatic->header, madAnimName); } } } static void LODScriptLoad(char *directory,char *field,void *dataToFillIn) { if (strcmp(field,"DefaultShip") == 0) { *((lodinfo **)dataToFillIn) = defaultlod; } else { *((lodinfo **)dataToFillIn) = lodTableReadScript(directory, field); } } static void loadMexDataCB(char *directory,char *field,void *dataToFillIn) { char fullfilename[80]; if (strcmp(field,"DefaultShip") == 0) { *((void **)dataToFillIn) = defaultmex; } else { if (directory != NULL) { strcpy(fullfilename,directory); strcat(fullfilename,field); } else { strcpy(fullfilename,field); } if (fileExists(fullfilename,0)) { *((void **)dataToFillIn) = mexLoad(fullfilename); } else { dbgMessagef("\n WARNING: Could not locate mex %s",fullfilename); *((void **)dataToFillIn) = defaultmex; } } } #if 0 static void setRaceCB(char *directory,char *field,void *dataToFillIn) { *((ShipRace *)dataToFillIn) = StrToShipRace(field); } #endif static void setClassCB(char *directory,char *field,void *dataToFillIn) { *((ShipClass *)dataToFillIn) = StrToShipClass(field); } static void scriptSetFramesCB(char *directory,char *field,void *dataToFillIn) { sscanf(field,"%d",(sdword *)dataToFillIn); *((sdword *)dataToFillIn) *= UNIVERSE_UPDATE_RATE; } void gunGetDefaultOrientationFromBindings(GunStatic *gunstatic,ShipStaticInfo *statinfo) { lod *level = &statinfo->staticheader.LOD->level[0]; udword numHierarchys = ((meshdata *)level->pData)->nPolygonObjects; hmatrix concatenated, nonConcatenated; // mhbinding *binding; if (meshFindHierarchyMatrixByUserData(&concatenated, &nonConcatenated, level->hBindings, gunstatic) != FALSE) { matGetMatFromHMat(&gunstatic->defaultgunorientation,&concatenated); matGetMatFromHMat(&gunstatic->defaultGunOrientationNonConcat,&nonConcatenated); if (memcmp(&gunstatic->defaultGunOrientationNonConcat, &gunstatic->defaultgunorientation, sizeof(matrix))) { //if these guys are different bitSet(gunstatic->flags, GF_MultiLevelMatrix); } } else { dbgMessagef("\nWARNING: could not set gunbindings for ship %d",statinfo->shiptype); } /* binding = level->hBindings; // later, take into account multiple hierarchies for a single gun while (numHierarchys > 0) { if (binding->userData == gunstatic) { matGetMatFromHMat(&gunstatic->defaultgunorientation,&binding->object->localMatrix); return; } binding++; numHierarchys--; } */ } void gunSetStaticGunInfoFromBindings(ShipStaticInfo *statinfo) { sdword i; GunStaticInfo *gunStaticInfo = statinfo->gunStaticInfo; sdword numGuns = gunStaticInfo->numGuns; GunStatic *gunstatic; for (i=0;igunstatics[i]; switch (gunstatic->guntype) { case GUN_NewGimble: gunGetDefaultOrientationFromBindings(gunstatic,statinfo); break; default: // ignore break; } } } /*----------------------------------------------------------------------------- Name : precalcStaticHeader Description : precalculates certain useful information in the static header so these calculations don't have to be done every frame Inputs : *staticheader Outputs : *staticheader updated appropriately Return : ----------------------------------------------------------------------------*/ void precalcStaticHeader(StaticHeader *staticheader) { real32 avoidcollsize; mexSetCollisionInfo(&staticheader->staticCollInfo,staticheader->pMexData, staticheader->staticCollInfo.collBoxScaleForward, staticheader->staticCollInfo.collBoxScaleUp, staticheader->staticCollInfo.collBoxScaleRight, staticheader->staticCollInfo.collBoxOffsetX, staticheader->staticCollInfo.collBoxOffsetY, staticheader->staticCollInfo.collBoxOffsetZ); if (staticheader->staticCollInfo.approxcollmodifier != 0.0f) { staticheader->staticCollInfo.approxcollspheresize *= staticheader->staticCollInfo.approxcollmodifier; } if (staticheader->staticCollInfo.avoidcollmodifier != 0.0f) { staticheader->staticCollInfo.avoidcollspheresize *= staticheader->staticCollInfo.avoidcollmodifier; } avoidcollsize = staticheader->staticCollInfo.avoidcollspheresize; staticheader->staticCollInfo.avoidcollspherepad = avoidcollsize * ((avoidcollsize > AISHIP_BIGSHIP) ? AVOID_OBJ_PADDING_SCALE_BIG : AVOID_OBJ_PADDING_SCALE); staticheader->oneOverMass = 1.0f / staticheader->mass; staticheader->oneOverMomentOfInertiaX = 1.0f / staticheader->momentOfInertiaX; staticheader->oneOverMomentOfInertiaY = 1.0f / staticheader->momentOfInertiaY; staticheader->oneOverMomentOfInertiaZ = 1.0f / staticheader->momentOfInertiaZ; } void precalcStaticInfoHealth(StaticInfoHealth *staticinfo) { if ((staticinfo->minCollDamage == 0.0f) && (staticinfo->maxCollDamage == 0.0f)) { // put in defaults: staticinfo->minCollDamage = ((staticinfo->maxhealth) * COLLDAMAGE_DEFAULTMIN_FRACTION); staticinfo->maxCollDamage = ((staticinfo->maxhealth) * COLLDAMAGE_DEFAULTMAX_FRACTION); } if(staticinfo->maxhealth != 0.0f) { //precalc 1/maxhealth..duh staticinfo->oneOverMaxHealth = 1.0f/staticinfo->maxhealth; } } void precalcStaticInfoGuidance(StaticInfoHealthGuidance *staticinfo) { sdword i; for (i=0;ithruststrengthstat[i] *= staticinfo->staticheader.mass * GLOBAL_SHIP_SPEED_MODIFIER; } staticinfo->staticheader.maxvelocity *= GLOBAL_SHIP_SPEED_MODIFIER; staticinfo->rotstrengthstat[ROT_ABOUTXCCW] *= staticinfo->staticheader.momentOfInertiaX; staticinfo->rotstrengthstat[ROT_ABOUTXCW] *= staticinfo->staticheader.momentOfInertiaX; staticinfo->rotstrengthstat[ROT_ABOUTYCCW] *= staticinfo->staticheader.momentOfInertiaY; staticinfo->rotstrengthstat[ROT_ABOUTYCW] *= staticinfo->staticheader.momentOfInertiaY; staticinfo->rotstrengthstat[ROT_ABOUTZCCW] *= staticinfo->staticheader.momentOfInertiaZ; staticinfo->rotstrengthstat[ROT_ABOUTZCW] *= staticinfo->staticheader.momentOfInertiaZ; } /*----------------------------------------------------------------------------- Name : InitStatAsteroidInfo Description : initializes static asteroid information Inputs : asteroidType Outputs : asteroidStatInfo is filled in Return : ----------------------------------------------------------------------------*/ void InitStatAsteroidInfo(AsteroidStaticInfo *asteroidStatInfo,AsteroidType asteroidtype) { char shipname[80]; char directory[80]; char fullshipname[160]; char *asteroidtypestr; asteroidStatInfo->asteroidtype = asteroidtype; asteroidtypestr = AsteroidTypeToStr(asteroidtype); strcpy(directory,"Resources\\Asteroids\\"); // strcat(directory,asteroidtypestr); // strcat(directory,"\\"); strcpy(shipname,asteroidtypestr); strcat(shipname,".shp"); strcpy(fullshipname,directory); strcat(fullshipname,shipname); if (fileExists(fullshipname,0)) { scriptSetStruct(directory,shipname,AsteroidStaticScriptTable,(ubyte *)asteroidStatInfo); precalcStaticHeader(&asteroidStatInfo->staticheader); precalcStaticInfoHealth((StaticInfoHealth *)asteroidStatInfo); // optimization for Asteroid0 if (asteroidtype == Asteroid0) collZeroRectInfo(&asteroidStatInfo->staticheader.staticCollInfo); } } /*----------------------------------------------------------------------------- Name : InitStatDustCloudInfo Description : initializes static dustcloud information Inputs : dustcloudType Outputs : dustcloudStatInfo is filled in Return : ----------------------------------------------------------------------------*/ void InitStatDustCloudInfo(DustCloudStaticInfo *dustcloudStatInfo, DustCloudType dustcloudtype) { char shipname[80]; char directory[80]; char fullshipname[160]; char *dustcloudtypestr; dbgAssert(dustcloudtype < NUM_DUSTCLOUDTYPES); dustcloudStatInfo->dustcloudtype = dustcloudtype; dustcloudtypestr = DustCloudTypeToStr(dustcloudtype); strcpy(directory,"Resources\\DustClouds\\"); // strcat(directory,dustcloudtypestr); // strcat(directory,"\\"); strcpy(shipname,dustcloudtypestr); strcat(shipname,".shp"); strcpy(fullshipname,directory); strcat(fullshipname,shipname); if (fileExists(fullshipname,0)) { StaticCollInfo *coll; real32 r = DUSTCLOUD_RADII[(sdword)dustcloudtype] * DUSTCLOUD_RADIAL_SCALE; scriptSetStruct(directory,shipname,DustCloudStaticScriptTable,(ubyte *)dustcloudStatInfo); precalcStaticHeader(&dustcloudStatInfo->staticheader); precalcStaticInfoHealth((StaticInfoHealth *)dustcloudStatInfo); coll = &dustcloudStatInfo->staticheader.staticCollInfo; collZeroRectInfo(coll); coll->originalcollspheresize = r; coll->approxcollspheresize = r; coll->avoidcollspheresize = r; coll->avoidcollspherepad = r; coll->collspheresize = r; coll->collspheresizeSqr = r * r; } } /*----------------------------------------------------------------------------- Name : InitStatGasCloudInfo Description : initializes static gascloud information Inputs : gascloudType Outputs : gascloudStatInfo is filled in Return : ----------------------------------------------------------------------------*/ void InitStatGasCloudInfo(GasCloudStaticInfo *gascloudStatInfo, GasCloudType gascloudtype) { char shipname[80]; char directory[80]; char fullshipname[160]; char *gascloudtypestr; gascloudStatInfo->gascloudtype = gascloudtype; gascloudtypestr = GasCloudTypeToStr(gascloudtype); strcpy(directory,"Resources\\GasClouds\\"); // strcat(directory,gascloudtypestr); // strcat(directory,"\\"); strcpy(shipname,gascloudtypestr); strcat(shipname,".shp"); strcpy(fullshipname,directory); strcat(fullshipname,shipname); if (fileExists(fullshipname,0)) { scriptSetStruct(directory,shipname,GasCloudStaticScriptTable,(ubyte *)gascloudStatInfo); precalcStaticHeader(&gascloudStatInfo->staticheader); precalcStaticInfoHealth((StaticInfoHealth *)gascloudStatInfo); } } /*----------------------------------------------------------------------------- Name : InitStatNebulaInfo Description : initializes static nebula information Inputs : nebulaType Outputs : nebulaStatInfo is filled in Return : ----------------------------------------------------------------------------*/ void InitStatNebulaInfo(NebulaStaticInfo* nebulaStatInfo, NebulaType nebulatype) { char shipname[80]; char directory[80]; char fullshipname[160]; char* nebulatypestr; dbgAssert(nebulatype < NUM_NEBULATYPES); nebulaStatInfo->nebulatype = nebulatype; nebulatypestr = NebulaTypeToStr(nebulatype); strcpy(directory,"Resources\\Nebulae\\"); // strcat(directory,nebulatypestr); // strcat(directory,"\\"); strcpy(shipname,nebulatypestr); strcat(shipname,".shp"); strcpy(fullshipname,directory); strcat(fullshipname,shipname); if (fileExists(fullshipname,0)) { StaticCollInfo *coll; scriptSetStruct(directory, shipname, NebulaStaticScriptTable, (ubyte*)nebulaStatInfo); precalcStaticHeader(&nebulaStatInfo->staticheader); precalcStaticInfoHealth((StaticInfoHealth*)nebulaStatInfo); coll = &nebulaStatInfo->staticheader.staticCollInfo; collZeroRectInfo(coll); coll->originalcollspheresize = NEB_RADIUS; coll->approxcollspheresize = NEB_RADIUS; coll->avoidcollspheresize = NEB_RADIUS; coll->avoidcollspherepad = NEB_RADIUS; coll->collspheresize = NEB_RADIUS; coll->collspheresizeSqr = NEB_RADIUS * NEB_RADIUS; } } void InitStatHyperspaceGateInfo(DerelictStaticInfo *derelictStatInfo) { StaticCollInfo *sci; real32 r; memset(derelictStatInfo, 0, sizeof(DerelictStaticInfo)); derelictStatInfo->maxhealth = HYPERSPACEGATE_HEALTH; derelictStatInfo->oneOverMaxHealth = (1.0f / derelictStatInfo->maxhealth); derelictStatInfo->renderlistLimitSqr = 5.0e8f; sci = &derelictStatInfo->staticheader.staticCollInfo; sci->uplength = HYPERSPACEGATE_HEIGHT; sci->rightlength = HYPERSPACEGATE_WIDTH; sci->forwardlength = 50.0f; // give it a small thickness for collision's sake vecSet(sci->collrectoffset,-HYPERSPACEGATE_HEIGHT/2,-HYPERSPACEGATE_WIDTH/2,-50.0/2); r = max(HYPERSPACEGATE_HEIGHT,HYPERSPACEGATE_WIDTH); sci->approxcollspheresize = r; sci->avoidcollspheresize = r; sci->avoidcollspherepad = r; sci->avoidcollmodifier = 1.0f; sci->approxcollmodifier = 1.0f; sci->originalcollspheresize = r; sci->collspheresize = r; sci->collspheresizeSqr = r*r; vecSet(sci->collsphereoffset,0.0f,0.0f,0.0f); } /*----------------------------------------------------------------------------- Name : InitStatDerelictInfo Description : initializes static derelict information Inputs : derelicttype Outputs : derelictStatInfo is filled in Return : ----------------------------------------------------------------------------*/ void InitStatDerelictInfo(DerelictStaticInfo *derelictStatInfo, DerelictType derelicttype) { char shipname[80]; char directory[80]; char fullshipname[160]; char *derelicttypestr; if (derelicttype == HyperspaceGate) { InitStatHyperspaceGateInfo(derelictStatInfo); return; } derelicttypestr = DerelictTypeToStr(derelicttype); strcpy(directory,"Derelicts\\"); // strcat(directory,derelicttypestr); // strcat(directory,"\\"); strcpy(shipname,derelicttypestr); strcat(shipname,".shp"); strcpy(fullshipname,directory); strcat(fullshipname,shipname); derelictStatInfo->minimumZoomDistance = 0.0f; derelictStatInfo->renderlistFade = 0.0f; derelictStatInfo->renderlistLimitSqr = 0.0f; if (fileExists(fullshipname,0)) { InitStatDerelictInfoByPath(derelictStatInfo, derelicttype, directory,shipname); } scriptSetNAVLightStatics(directory, shipname, (ShipStaticInfo *)derelictStatInfo); if (derelictStatInfo->navlightStaticInfo != NULL) { mexGetNAVLightStaticInfo(derelictStatInfo->navlightStaticInfo,derelictStatInfo->staticheader.pMexData); } } /*----------------------------------------------------------------------------- Name : InitStatDerelictInfoByPath Description : Init the static info for a derelict based on a type AND a path. Mostly used for creating generic objects for NIS's. Inputs : derelictStatInfo - where to load the data to. derelictType - type of derelict. If only used in NIS, this field is not used. directory - what directory the .shp file is in. shipFile - what .shp file to load in. Outputs : reads in the representative .shp file into derelictStatInfo. Return : void ----------------------------------------------------------------------------*/ void InitStatDerelictInfoByPath(DerelictStaticInfo *derelictStatInfo, DerelictType derelicttype, char *directory, char *shipFile) { bool8 teamColor[MAX_MULTIPLAYER_PLAYERS]; memcpy(teamColor, derelictStatInfo->teamColor, sizeof(teamColor));//save the default team colors derelictStatInfo->derelicttype = derelicttype; memset(derelictStatInfo, 0, sizeof(DerelictStaticInfo)); memcpy(derelictStatInfo->teamColor, teamColor, sizeof(teamColor)); derelictStatInfo->staticheader.rightOfWay = 1; // default to derelicts having a right of way same as frigates derelictStatInfo->salvageable = FALSE; //default salvageability to FALSE! scriptSetStruct(directory,shipFile,DerelictStaticScriptTable,(ubyte *)derelictStatInfo); precalcStaticHeader(&derelictStatInfo->staticheader); precalcStaticInfoHealth((StaticInfoHealth *)derelictStatInfo); precalcStaticInfoGuidance((StaticInfoHealthGuidance *)derelictStatInfo); } /*----------------------------------------------------------------------------- Name : InitStatMissileInfo Description : initializes static missile information Inputs : race Outputs : missileStatInfo is filled in Return : ----------------------------------------------------------------------------*/ void InitStatMissileInfo(MissileStaticInfo *missileStatInfo,ShipRace race) { char directory[80]; char fullshipname[100]; char *shipname = "Missile.shp"; strcpy(directory,ShipRaceToStr(race)); // strcat(directory,"\\Missile\\"); strcat(directory, "\\"); strcpy(fullshipname,directory); strcat(fullshipname,shipname); if (!fileExists(fullshipname,0)) { dbgMessagef("\nWarning: Could not find Missile for %s",ShipRaceToStr(race)); return; } missileStatInfo->turnspeedstat[TURN_YAW] = 1.0f; missileStatInfo->turnspeedstat[TURN_PITCH] = 1.0f; missileStatInfo->turnspeedstat[TURN_ROLL] = 1.0f; missileStatInfo->staticheader.rightOfWay = -1; scriptSetStruct(directory,shipname,MissileStaticScriptTable,(ubyte *)missileStatInfo); precalcStaticHeader(&missileStatInfo->staticheader); precalcStaticInfoHealth((StaticInfoHealth *)missileStatInfo); precalcStaticInfoGuidance((StaticInfoHealthGuidance *)missileStatInfo); //missile trail stuff missileStatInfo->trailWidth = -1.0f; missileStatInfo->trailHeight = -1.0f; missileStatInfo->trailStatic = trailStaticInfoParse(directory, shipname); } /*----------------------------------------------------------------------------- Name : InitStatMineInfo Description : initializes static missile-mine information Inputs : race Outputs : missileStatInfo is filled in Return : ----------------------------------------------------------------------------*/ void InitStatMineInfo(MissileStaticInfo *mineStatInfo,ShipRace race) { char directory[80]; char fullshipname[100]; char *shipname = "Mine.shp"; strcpy(directory,ShipRaceToStr(race)); // strcat(directory,"\\Mine\\"); strcat(directory, "\\"); strcpy(fullshipname,directory); strcat(fullshipname,shipname); if (!fileExists(fullshipname,0)) { dbgMessagef("\nWarning: Could not find Mine for %s",ShipRaceToStr(race)); return; } mineStatInfo->turnspeedstat[TURN_YAW] = 1.0f; mineStatInfo->turnspeedstat[TURN_PITCH] = 1.0f; mineStatInfo->turnspeedstat[TURN_ROLL] = 1.0f; mineStatInfo->staticheader.rightOfWay = -1; scriptSetStruct(directory,shipname,MineStaticScriptTable,(ubyte *)mineStatInfo); mineStatInfo->mineRange = fsqrt(mineStatInfo->MINE_RANGESQR); mineStatInfo->mineRangeForced = fsqrt(mineStatInfo->MINE_RANGESQR_FORCED); precalcStaticHeader(&mineStatInfo->staticheader); precalcStaticInfoHealth((StaticInfoHealth *)mineStatInfo); precalcStaticInfoGuidance((StaticInfoHealthGuidance *)mineStatInfo); } /*----------------------------------------------------------------------------- Name : isStrikeCraft Description : returns TRUE if ship is a strikecraft Inputs : shiptype Outputs : Return : returns TRUE if ship is a strikecraft ----------------------------------------------------------------------------*/ bool isStrikeCraft(ShipType shiptype) { switch (shiptype) { case AttackBomber: case CloakedFighter: case DefenseFighter: case HeavyInterceptor: case LightInterceptor: case HeavyDefender: case LightCorvette: case HeavyCorvette: case MultiGunCorvette: case MinelayerCorvette: case SalCapCorvette: case RepairCorvette: case P1Fighter: case P1MissileCorvette: case P1StandardCorvette: case P2Swarmer: case P2AdvanceSwarmer: return TRUE; default: return FALSE; } } /*----------------------------------------------------------------------------- Name : InitStatShipInfo Description : Initializes static ship information for all ship types. Inputs : type, race Outputs : statinfo is filled in Return : ----------------------------------------------------------------------------*/ void InitStatShipInfo(ShipStaticInfo *statinfo,ShipType type,ShipRace race) { char shipname[80]; char directory[80]; char fullshipname[160]; char *shiptypestr; sdword i; bool stubbedOut; statinfo->shiptype = type; statinfo->shiprace = race; statinfo->custshipheader = *(shipHeaders[type]); dbgAssert((statinfo->custshipheader.shiptype == (ShipType)-1) || (type == statinfo->custshipheader.shiptype)); shiptypestr = ShipTypeToStr(type); strcpy(directory,ShipRaceToStr(race)); // strcat(directory,"\\"); // strcat(directory,shiptypestr); strcat(directory,"\\"); strcpy(shipname,shiptypestr); strcat(shipname,".shp"); strcpy(fullshipname,directory); strcat(fullshipname,shipname); if (!fileExists(fullshipname,0) || universeForceDefaultShip) { //we now disable this ship if we can't find it... SetInfoNeededForShipAndRelatedStaticInfo(type,race,FALSE); rmEnableShip(race, type, FALSE); return; /* #ifndef HW_Release dbgMessagef("\nStubbing out %s\\%s", ShipRaceToStr(race), ShipTypeToStr(type)); #endif strcpy(directory,"DefaultShip\\"); strcpy(shipname,"DefaultShip.shp"); strcpy(fullshipname,directory); strcat(fullshipname,shipname); stubbedOut = TRUE; */ } else { stubbedOut = FALSE; } #if SO_CLOOGE_SCALE statinfo->scaleFactor = 1.0f; #endif statinfo->turnspeedstat[TURN_YAW] = 1.0f; statinfo->turnspeedstat[TURN_PITCH] = 1.0f; statinfo->turnspeedstat[TURN_ROLL] = 1.0f; statinfo->minimumZoomDistance = 0.0f; statinfo->renderlistFade = 0.0f; statinfo->renderlistLimitSqr = 0.0f; statinfo->dockLightNear = 0.0f; statinfo->dockLightFar = 0.1f; statinfo->dockLightColor = colRGB(120, 194, 255); //default blue glow statinfo->hyperspaceColor = colRGB(0,0,0); //default is to use the effect's default statinfo->tacticalSelectionScale = 1.0f; // This is used to scale the R1 probes tactiacl overlay size, and the defenders selection box size if (isStrikeCraft(type)) statinfo->formationPaddingModifier = STRIKECRAFT_PADDING_MODIFIER; // default formation padding modifier else statinfo->formationPaddingModifier = 1.0f; // default formation padding modifier //default to no explosions at all // statinfo->smallExplosion = statinfo->bigExplosion = statinfo->specialExplosion = NULL; // statinfo->bigExplosionFactor = 1.0f; //engine trail defaults for (i = 0; i < MAX_NUM_TRAILS; i++) { statinfo->trailStyle[i] = 1; statinfo->trailWidth[i] = -1.0f; statinfo->trailHeight[i] = -1.0f; statinfo->trailAngle[i] = -1.0f; statinfo->trailRibbonAdjust[i] = -1.0f; statinfo->trailLength[i] = -1.0f; statinfo->trailScaleCap[i] = -1.0f; statinfo->trailSpriteRadius[i] = -1.0f; statinfo->trailSpriteOffset[i] = 0.0f; } statinfo->staticheader.staticCollInfo.preciseSelection = 0xff;//default is no precise selection // collSideModifiers reset for (i=0;icollSideModifiers[i] = 0.0f; } statinfo->staticheader.rightOfWay = rightOfWays[type]; // defaults for right of way scriptSetStruct(directory,shipname,ShipStaticScriptTable,(ubyte *)statinfo); if ((statinfo->repairTime) && (statinfo->repairCombatTime == 0.0f)) { statinfo->repairCombatTime = statinfo->repairTime; } if ((statinfo->repairDamage) && (statinfo->repairCombatDamage == 0.0f)) { statinfo->repairCombatDamage = statinfo->repairDamage; } if (statinfo->collSideModifiers[0] == 0.0f) { // collSideModifiers haven't been explicitly set, so set them: if (isCapitalShipStatic(statinfo)) { for (i=0;icollSideModifiers[i] = capitalSideModifiers[i]; } } else { for (i=0;icollSideModifiers[i] = 1.0f; } } } /* #ifndef HW_Release if ((cheapShips) && (!multiPlayerGame)) { statinfo->buildTime = 1; statinfo->buildCost = 1; } #endif */ if (statinfo->blastRadiusShockWave == 0.0f) { statinfo->blastRadiusShockWave = BLAST_RADIUS_MULTIPLE_DEFAULT; } if (statinfo->passiveRetaliateZone == 0.0f) { statinfo->passiveRetaliateZone = RETALIATE_ZONE; } else if (statinfo->passiveRetaliateZone < 0.0f) { statinfo->passiveRetaliateZone = 0.0f; // turn of retaliation zone feature if -ve } if (statinfo->attackfuelburnrate == 0.0f) { statinfo->attackfuelburnrate = statinfo->fuelburnrate; } statinfo->canReceiveSomething = (bool8)(statinfo->canReceiveResources | statinfo->canReceiveShips | statinfo->canReceiveShipsPermanently | statinfo->canReceiveShipsForRetire); for (i = 0; i < MAX_NUM_TRAILS; i++) { statinfo->trailStatic[i] = trailStaticInfoParse(directory, shipname); } if (mexGetChunk(statinfo->staticheader.pMexData, "Eng", "Eng1") != NULL) { statinfo->multipleEngines = (udword)TRUE; } else { statinfo->multipleEngines = FALSE; } statinfo->lowfuelpoint *= statinfo->maxfuel; precalcStaticHeader(&statinfo->staticheader); #if 1 // comment out when MiningBase properly moved hack, fix later if (type == MiningBase) { StaticCollInfo *staticCollInfo = &statinfo->staticheader.staticCollInfo; staticCollInfo->collsphereoffset.x += MINING_BASE_VERTICAL_DIST_HACK; staticCollInfo->collrectoffset.x += MINING_BASE_VERTICAL_DIST_HACK; } #endif precalcStaticInfoHealth((StaticInfoHealth *)statinfo); precalcStaticInfoGuidance((StaticInfoHealthGuidance *)statinfo); if (statinfo->dockShipRange != 0.0f) { statinfo->dockShipRange += statinfo->staticheader.staticCollInfo.approxcollspheresize; statinfo->dockShipRange *= statinfo->dockShipRange; } aishipPrecalcInfo(statinfo); for (i = 0; i < MAX_NUM_TRAILS; i++) { mexSetEngineNozzle(statinfo->engineNozzleOffset + i, statinfo->staticheader.pMexData, i); } if (stubbedOut == FALSE) { scriptSetDockStatics(directory,shipname,statinfo); scriptSetDockOverideStatics(directory,shipname,statinfo); } if (statinfo->dockStaticInfo != NULL) { mexGetDockStaticInfo(statinfo->dockStaticInfo,statinfo->staticheader.pMexData); } if (stubbedOut == FALSE) { dockInitializeCustomFunctions(statinfo,type,race); } if (ShipCanHarvest(statinfo)) { // find resource collection nozzle statinfo->resNozzleStatic = mexGetResNozzleStatic(statinfo->staticheader.pMexData); } if(statinfo->repairBeamCapable) { //find repair beam nozzle statinfo->repairNozzleStatic = mexGetRepairNozzleStatic(statinfo->staticheader.pMexData); } if(type == SalCapCorvette) { //find tractor beam emmitter statinfo->tractorEmitterStatic = mexGetTractorBeamStatic(statinfo->staticheader.pMexData); } scriptSetNAVLightStatics(directory, shipname, statinfo); if (statinfo->navlightStaticInfo != NULL) { mexGetNAVLightStaticInfo(statinfo->navlightStaticInfo,statinfo->staticheader.pMexData); } scriptSetGunStatics(directory,shipname,statinfo); if (statinfo->gunStaticInfo != NULL) { GunStaticInfo *gunstaticinfo = statinfo->gunStaticInfo; for (i=0;inumGuns;i++) { gunstaticinfo->gunstatics[i].gunindex = i; } mexGetGunStaticInfo(gunstaticinfo,statinfo->staticheader.pMexData); } if (statinfo->bulletRange[0] != 0.0f) { for(i=0;ibulletRangeSquared[i] = statinfo->bulletRange[i] * statinfo->bulletRange[i]; } } //load in the hierarchy binding information scriptSetStruct(directory,shipname,HierarchyBindingTable,(ubyte *)statinfo); //load in More Mesh Animation info //must be AFTER we've loaded in all other MAD stuff, otherwise //I'll get MAD! if(statinfo->madStatic != NULL) { //default these to 0 statinfo->madStatic->needStartPlacedAnimation = 0; statinfo->madStatic->needStartBuiltAnimation = 0; statinfo->madStatic->numGunOpenIndexes=0; statinfo->madStatic->numGunOpenDamagedIndexes=0; statinfo->madStatic->numGunCloseIndexes=0; statinfo->madStatic->numGunCloseDamagedIndexes=0; statinfo->madStatic->numDockIndexes=0; //number of below indices statinfo->madStatic->numDockDamagedIndexes=0; //number of below indices statinfo->madStatic->numPostDockIndexes=0; //number of below indices statinfo->madStatic->numPostDockDamagedIndexes=0; //number of below indices statinfo->madStatic->numDoorOpenIndexes=0; statinfo->madStatic->numDoorCloseIndexes=0; statinfo->madStatic->numSpecialOpenIndexes=0; statinfo->madStatic->numSpecialCloseIndexes=0; statinfo->madStatic->numSpecialOpenDamagedIndexes=0; statinfo->madStatic->numSpecialCloseDamagedIndexes=0; } scriptSetStruct(directory,shipname,MadMaxMadInfoLoad,(ubyte *)statinfo); if (statinfo->gunStaticInfo != NULL && stubbedOut == FALSE) { gunSetStaticGunInfoFromBindings(statinfo); } if (statinfo->custshipheader.CustShipStaticInit != NULL) { statinfo->custshipheader.CustShipStaticInit(directory,shipname,statinfo); } } /*----------------------------------------------------------------------------- Name : InitStatShipInfoPost Description : Initializes static ship information for all ship types. Post operation uses information from previous pass to complete the initialization. Inputs : type, race Outputs : statinfo is filled in Return : ----------------------------------------------------------------------------*/ void InitStatShipInfoPost(ShipStaticInfo *statinfo) { if (GLOBAL_SHIP_HEALTH_MODIFIER != 1.0f) { statinfo->maxhealth = ((statinfo->maxhealth) * GLOBAL_SHIP_HEALTH_MODIFIER); if (statinfo->maxhealth == 0.0f) { statinfo->maxhealth = 1.0f; } statinfo->oneOverMaxHealth = 1.0f/statinfo->maxhealth; } if (statinfo->custshipheader.CustShipStaticInitPost != NULL) { statinfo->custshipheader.CustShipStaticInitPost(statinfo); } } /*----------------------------------------------------------------------------- Name : CloseStatInfo Description : Close base static info Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void CloseStatInfo(StaticInfo *statinfo) { if ((statinfo->staticheader.pMexData != defaultmex) && (statinfo->staticheader.pMexData != NULL)) { mexFree(statinfo->staticheader.pMexData); statinfo->staticheader.pMexData = NULL; } if ((statinfo->staticheader.LOD != defaultlod) && (statinfo->staticheader.LOD != NULL)) { lodFree(statinfo->staticheader.LOD); statinfo->staticheader.LOD = NULL; } //statinfo->staticheader.infoLoaded = statinfo->staticheader.infoNeeded = FALSE; statinfo->staticheader.infoFlags = 0; memset(statinfo, 0, sizeof(StaticInfo)); } /*----------------------------------------------------------------------------- Name : CloseStatShipInfo Description : Closes static ship info Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void CloseStatShipInfo(ShipStaticInfo *statinfo) { sdword i; CloseStatInfo((StaticInfo *)statinfo); for (i = 0; i < MAX_NUM_TRAILS; i++) { if (statinfo->trailStatic[i] != NULL) { trailStaticDelete(statinfo->trailStatic[i]); statinfo->trailStatic[i] = NULL; } } if (statinfo->madStatic != NULL) { if(statinfo->madStatic->gunOpenIndexes != NULL) { memFree(statinfo->madStatic->gunOpenIndexes); } if(statinfo->madStatic->gunCloseIndexes != NULL) { memFree(statinfo->madStatic->gunCloseIndexes); } if(statinfo->madStatic->gunOpenDamagedIndexes != NULL) { memFree(statinfo->madStatic->gunOpenDamagedIndexes); } if(statinfo->madStatic->gunCloseDamagedIndexes != NULL) { memFree(statinfo->madStatic->gunCloseDamagedIndexes); } //dock anims if(statinfo->madStatic->PostDockIndexes != NULL) { memFree(statinfo->madStatic->PostDockIndexes); } if(statinfo->madStatic->DockIndexes != NULL) { memFree(statinfo->madStatic->DockIndexes); } if(statinfo->madStatic->PostDockDamagedIndexes != NULL) { memFree(statinfo->madStatic->PostDockDamagedIndexes); } if(statinfo->madStatic->DockDamagedIndexes != NULL) { memFree(statinfo->madStatic->DockDamagedIndexes); } //mothership door anims if(statinfo->madStatic->DoorOpenIndexes != NULL) { memFree(statinfo->madStatic->DoorOpenIndexes); } if(statinfo->madStatic->DoorCloseIndexes != NULL) { memFree(statinfo->madStatic->DoorCloseIndexes); } //special case if(statinfo->madStatic->specialOpenIndexes != NULL) { memFree(statinfo->madStatic->specialOpenIndexes); } if(statinfo->madStatic->specialCloseIndexes != NULL) { memFree(statinfo->madStatic->specialCloseIndexes); } if(statinfo->madStatic->specialOpenDamagedIndexes != NULL) { memFree(statinfo->madStatic->specialOpenDamagedIndexes); } if(statinfo->madStatic->specialCloseDamagedIndexes != NULL) { memFree(statinfo->madStatic->specialCloseDamagedIndexes); } madHeaderDelete(statinfo->madStatic->header); //... other mesh binding freeing stuffs memFree(statinfo->madStatic); } if(statinfo->dockOverideInfo != NULL) { memFree(statinfo->dockOverideInfo); } if (statinfo->resNozzleStatic != NULL) { memFree(statinfo->resNozzleStatic); statinfo->resNozzleStatic = NULL; } if(statinfo->repairNozzleStatic != NULL) { memFree(statinfo->repairNozzleStatic); statinfo->repairNozzleStatic = NULL; } if (statinfo->salvageStaticInfo != NULL) { memFree(statinfo->salvageStaticInfo); statinfo->salvageStaticInfo = NULL; } if (statinfo->tractorEmitterStatic != NULL) { memFree(statinfo->tractorEmitterStatic); statinfo->tractorEmitterStatic = NULL; } if (statinfo->dockStaticInfo != NULL) { memFree(statinfo->dockStaticInfo); statinfo->dockStaticInfo = NULL; } if (statinfo->navlightStaticInfo != NULL) { navLightStaticInfoDelete(statinfo->navlightStaticInfo); statinfo->navlightStaticInfo = NULL; } if (statinfo->gunStaticInfo != NULL) { memFree(statinfo->gunStaticInfo); statinfo->gunStaticInfo = NULL; } } /*----------------------------------------------------------------------------- Name : CloseStatAsteroidInfo Description : Closes static asteroid info Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void CloseStatAsteroidInfo(AsteroidStaticInfo *asteroidStatInfo) { CloseStatInfo((StaticInfo *)asteroidStatInfo); } /*----------------------------------------------------------------------------- Name : CloseStatDustCloudInfo Description : Closes static dustcloud info Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void CloseStatDustCloudInfo(DustCloudStaticInfo *dustcloudStatInfo) { CloseStatInfo((StaticInfo *)dustcloudStatInfo); } /*----------------------------------------------------------------------------- Name : CloseStatGasCloudInfo Description : Closes static gascloud info Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void CloseStatGasCloudInfo(GasCloudStaticInfo *gascloudStatInfo) { CloseStatInfo((StaticInfo *)gascloudStatInfo); } /*----------------------------------------------------------------------------- Name : CloseStatNebulaInfo Description : Closes static nebula info Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void CloseStatNebulaInfo(NebulaStaticInfo *nebulaStatInfo) { // CloseStatInfo((StaticInfo *)nebulaStatInfo); } /*----------------------------------------------------------------------------- Name : CloseStatDerelictInfo Description : Closes static derelict info Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void CloseStatDerelictInfo(DerelictStaticInfo *derelictStatInfo) { if (derelictStatInfo->salvageStaticInfo != NULL) { memFree(derelictStatInfo->salvageStaticInfo); derelictStatInfo->salvageStaticInfo = NULL; } CloseStatInfo((StaticInfo *)derelictStatInfo); } /*----------------------------------------------------------------------------- Name : CloseStatMissileInfo Description : Closes static missile info Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void CloseStatMissileInfo(MissileStaticInfo *missileStatInfo) { CloseStatInfo((StaticInfo *)missileStatInfo); } /*----------------------------------------------------------------------------- Name : CloseStatMineInfo Description : Closes static mine info Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void CloseStatMineInfo(MissileStaticInfo *mineStatInfo) { CloseStatInfo((StaticInfo *)mineStatInfo); } void CloseStatEffectInfo(etgeffectstatic *effectStatInfo) { // CloseStatInfo((EffectStaticInfo *)effectStatInfo); } /*----------------------------------------------------------------------------- Name : universeInfoNeededSetCB Description : Static info scan callback to flag a static info as needed or not needed. Inputs : info - static info to look at objType - type of object to work with Outputs : modifies the IF_InfoNeeded bit of infoFlags to bNeededParam Return : void ----------------------------------------------------------------------------*/ static sdword bNeededParam; void universeInfoNeededSetCB(StaticInfo *info, ObjType objType) { bitSetTo(info->staticheader.infoFlags, IF_InfoNeeded, bNeededParam); } /*============================================================================= Public Functions: =============================================================================*/ /*----------------------------------------------------------------------------- Name : universeFlagRaceNeeded Description : Marks an entire race of staticinfo's as needed or not Inputs : shiprace - what race to mark bNeeded - TRUE if we need this static info loaded this level Outputs : Return : void Note : Missiles/mines will be turned on/off with the associated ships. ----------------------------------------------------------------------------*/ void universeFlagRaceNeeded(ShipRace shiprace, bool8 bNeeded) { bNeededParam = bNeeded; universeRaceStaticsScan(shiprace, universeInfoNeededSetCB, universeInfoNeededSetCB); } /*----------------------------------------------------------------------------- Name : universeDefaultTeamColors Description : Sets the defualts for what colors the ships can be in - whatever players are that race. Inputs : void Outputs : Return : void ----------------------------------------------------------------------------*/ void universeDefaultTeamColors(void) { bool8 racePlayerTable[NUM_RACES][MAX_MULTIPLAYER_PLAYERS]; sdword index; ShipRace shiprace; ShipType shiptype; ShipType firstshiptype; ShipType lastshiptype; DerelictType derelicttype; ShipStaticInfo *shipstaticinfo; MissileStaticInfo *missileInfo; //make a boolean table of color schemes by race memset(racePlayerTable, 0, sizeof(racePlayerTable)); for (index = 0; index < numPlayers; index++) { racePlayerTable[universe.players[index].race][index] = TRUE; } //!!! somewhat oversimple assignment of default color schemes for the non-player races racePlayerTable[Traders][7] = TRUE; racePlayerTable[P3][6] = TRUE; racePlayerTable[P2][5] = TRUE; racePlayerTable[P1][4] = TRUE; //now plug that default table into all the ship static infos for (shiprace=0;shipraceteamColor, racePlayerTable[shiprace], sizeof(shipstaticinfo->teamColor)); } missileInfo = &missileStaticInfos[shiprace]; memcpy(missileInfo->teamColor, racePlayerTable[shiprace], sizeof(missileInfo->teamColor)); if (shiprace <= R2) { missileInfo = &mineStaticInfos[shiprace]; memcpy(missileInfo->teamColor, racePlayerTable[shiprace], sizeof(missileInfo->teamColor)); } } //plug default team colors into derelicts (last team color scheme, like traders) for (derelicttype = 0; derelicttype < NUM_DERELICTTYPES; derelicttype++) { memcpy(derelictStaticInfos[derelicttype].teamColor, racePlayerTable[Traders], sizeof(racePlayerTable[Traders])); } } /*----------------------------------------------------------------------------- Name : universeFlagEverythingNeeded Description : Flags all static infos to be reloaded during the next level Inputs : void Outputs : sets the infoNeeded flag true for all static infos Return : void ----------------------------------------------------------------------------*/ void universeFlagEverythingNeeded(void) { bNeededParam = TRUE; universeAllStaticsScan(universeInfoNeededSetCB, universeInfoNeededSetCB, universeInfoNeededSetCB, universeInfoNeededSetCB); } /*----------------------------------------------------------------------------- Name : universeRaceStaticsScan Description : Scans all static infos needed for a race and calls appropriate callbacks. Inputs : shiprace - what race to scan forShips - called for ship static infos forMisc - called for other statics, like mines and missiles Outputs : Return : void Note : Missiles/mines will be turned on/off with the associated ships. ----------------------------------------------------------------------------*/ void universeRaceStaticsScan(ShipRace shiprace, univstatcallback forShips, univstatcallback forMisc) { ShipType shiptype; ShipType firstshiptype; ShipType lastshiptype; ShipStaticInfo *shipstaticinfo; firstshiptype = FirstShipTypeOfRace[shiprace]; lastshiptype = LastShipTypeOfRace[shiprace]; for (shiptype=firstshiptype;shiptype<=lastshiptype;shiptype++) { shipstaticinfo = GetShipStaticInfo(shiptype,shiprace); if (forShips) { forShips((StaticInfo *)shipstaticinfo, OBJ_ShipType); } if (forMisc) { if (shiptype == MissileDestroyer) { forMisc((StaticInfo *)&missileStaticInfos[shiprace], OBJ_MissileType); } else if (shiptype == P1MissileCorvette && shiprace == P1) { forMisc((StaticInfo *)&missileStaticInfos[P1], OBJ_MissileType); } else if (shiprace < 2 && shiptype == MinelayerCorvette) { forMisc((StaticInfo *)&mineStaticInfos[shiprace], OBJ_MissileType); } } } } /*----------------------------------------------------------------------------- Name : universeAllStaticsScan Description : Scans through the static info structures for all spaceobj types and calls a callback with that static info. Inputs : forShips - called for ship static infos forDerelicts, forResources, forMisc - same, but for derelicts, resources and whatnot. Outputs : Return : void ----------------------------------------------------------------------------*/ void universeAllStaticsScan(univstatcallback forShips, univstatcallback forDerelicts, univstatcallback forResources, univstatcallback forMisc) { ShipRace shiprace; AsteroidType asteroidtype; DustCloudType dustcloudtype; GasCloudType gascloudtype; NebulaType nebulatype; DerelictType derelicttype; for (shiprace=0;shipracestaticheader.infoFlags, IF_InfoLoaded); // anything loaded is needed data[1] = bitpackTeamColor(shipstatic->teamColor); data[2] = 0; data[3] = 0; SaveInfoNumber(TreatAsUdword(data[0])); } } for (asteroidtype=0;asteroidtypestaticheader.infoFlags, IF_InfoLoaded); data[1] = bitpackTeamColor(dstaticinfo->teamColor); data[2] = 0; data[3] = 0; SaveInfoNumber(TreatAsUdword(data[0])); } for (shiprace=0;shipracestaticheader.infoFlags, IF_InfoLoaded); data[1] = bitpackTeamColor(misstaticinfo->teamColor); data[2] = 0; data[3] = 0; SaveInfoNumber(TreatAsUdword(data[0])); } for (shiprace=0;shiprace<2;shiprace++) { MissileStaticInfo *misstaticinfo = &mineStaticInfos[shiprace]; data[0] = bitTest(misstaticinfo->staticheader.infoFlags, IF_InfoLoaded); data[1] = bitpackTeamColor(misstaticinfo->teamColor); data[2] = 0; data[3] = 0; SaveInfoNumber(TreatAsUdword(data[0])); } SaveInfoNumber(INFO_NEEDED_FLAGS_DELIMITER); } void universeLoadEverythingNeeded(void) { ShipRace shiprace; AsteroidType asteroidtype; DustCloudType dustcloudtype; GasCloudType gascloudtype; NebulaType nebulatype; DerelictType derelicttype; ShipType shiptype; ShipType firstshiptype; ShipType lastshiptype; ShipStaticInfo *shipstatic; udword data; ubyte *datab; datab = (ubyte *)&data; data = LoadInfoNumber(); // sanity check dbgAssert(data == INFO_NEEDED_FLAGS_DELIMITER); for (shiprace=0;shipracestaticheader.infoFlags, IF_InfoNeeded, datab[0]); rmEnableShip(shiprace, shiptype, datab[0]); unbitpackTeamColor(shipstatic->teamColor,datab[1]); } } for (asteroidtype=0;asteroidtypestaticheader.infoFlags, IF_InfoNeeded, datab[0]); unbitpackTeamColor(dstaticinfo->teamColor,datab[1]); } for (shiprace=0;shipracestaticheader.infoFlags, IF_InfoNeeded, datab[0]); unbitpackTeamColor(misstaticinfo->teamColor,datab[1]); } for (shiprace=0;shiprace<2;shiprace++) { MissileStaticInfo *misstaticinfo = &mineStaticInfos[shiprace]; data = LoadInfoNumber(); bitSetTo(misstaticinfo->staticheader.infoFlags, IF_InfoNeeded, datab[0]); unbitpackTeamColor(misstaticinfo->teamColor,datab[1]); } data = LoadInfoNumber(); // sanity check dbgAssert(data == INFO_NEEDED_FLAGS_DELIMITER); } /*----------------------------------------------------------------------------- Name : universeStaticInit Description : Initializes static data for the Universe. Only the ships, resources, missiles etc. that are needed will be loaded. Anything that was previously loaded and is no longer needed will be deleted. Inputs : none Outputs : Return : ----------------------------------------------------------------------------*/ extern void *utyTeaserHeader; void universeStaticInit(void) { ShipRace shiprace; ShipType shiptype; ShipType firstshiptype; ShipType lastshiptype; AsteroidType asteroidtype; DustCloudType dustcloudtype; NebulaType nebulatype; DerelictType derelicttype; ShipStaticInfo *shipstaticinfo; StaticInfo *staticinfo; udword max,count; #if UNIV_SHIP_LOADFREE_LOG FILE *logFile = NULL; if (univLoadFreeLog) { logFile = fopen(UNIV_LOAD_FREE_FILENAME, "at"); } if (logFile) { if (singlePlayerGame) { fprintf(logFile, "\n-----------\nCurrent level = %d\n", singlePlayerGameInfo.currentMission); } } #endif //load some things shared by everyone if (sphereStaticInfo == NULL) { sphereStaticInfo = createSphereStaticInfo(); } if (defaultmesh == NULL) { defaultmesh = meshLoad("DefaultShip\\DefaultShip.geo"); } if (defaultlod == NULL) { defaultlod = lodTableReadScript("DefaultShip\\", "DefaultShip.lod"); } if (defaultmex == NULL) { defaultmex = mexLoad("DefaultShip\\DefaultShip.mex"); } max = 0; for (shiprace=0;shipracestaticheader.infoFlags, IF_InfoNeeded)) { //if this info needed if (!bitTest(shipstaticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //if this info not loaded InitStatShipInfo(shipstaticinfo,shiptype,shiprace); bitSet(shipstaticinfo->staticheader.infoFlags, IF_NotPostLoaded); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Loading ship: %8s %s\n", ShipRaceToStr(shiprace), ShipTypeToStr(shiptype)); } #endif } else { if (shipstaticinfo->staticheader.LOD != NULL) { lodAllMeshesRecolorize(shipstaticinfo->staticheader.LOD); } } } else { //static info not needed this round if (bitTest(shipstaticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //if it's been loaded CloseStatShipInfo(shipstaticinfo); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Freeing ship: %8s %s\n", ShipRaceToStr(shiprace), ShipTypeToStr(shiptype)); } #endif } } } } for (asteroidtype=0;asteroidtypestaticheader.infoFlags, IF_InfoNeeded)) { //if info needed if (!bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info needed and not loaded InitStatAsteroidInfo((AsteroidStaticInfo *)staticinfo,asteroidtype); bitSet(staticinfo->staticheader.infoFlags, IF_InfoLoaded); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Loading asteroid: %s\n", AsteroidTypeToStr(asteroidtype)); } #endif } } else { //info not needed if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info loaded CloseStatAsteroidInfo((AsteroidStaticInfo *)staticinfo); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Freeing asteroid: %s\n", AsteroidTypeToStr(asteroidtype)); } #endif } } count++; } for (dustcloudtype = 0; dustcloudtype < NUM_DUSTCLOUDTYPES; dustcloudtype++) { HorseRaceNext(((real32)count)/((real32)max)); if (hrAbortLoadingGame) { goto abortloadinggame; } staticinfo = (StaticInfo *)&dustcloudStaticInfos[dustcloudtype]; if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoNeeded)) { //if info needed if (!bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info needed and not loaded InitStatDustCloudInfo((DustCloudStaticInfo *)staticinfo, dustcloudtype); bitSet(staticinfo->staticheader.infoFlags, IF_InfoLoaded); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Loading ship: %s\n", DustCloudTypeToStr(dustcloudtype)); } #endif } } else { //info not needed if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info loaded CloseStatDustCloudInfo((DustCloudStaticInfo *)staticinfo); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Freeing dustcloud: %s\n", DustCloudTypeToStr(dustcloudtype)); } #endif } } count++; } #if 0 for (gascloudtype = 0; gascloudtype < NUM_GASCLOUDTYPES; gascloudtype++) { staticinfo = (StaticInfo *)&gascloudStaticInfos[gascloudtype]; if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoNeeded)) { //if info needed if (!bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info needed and not loaded InitStatGasCloudInfo((GasCloudStaticInfo *)staticinfo, gascloudtype); bitSet(staticinfo->staticheader.infoFlags, IF_InfoLoaded); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Loading gas cloud: %s\n", GasCloudTypeToStr(gascloudtype)); } #endif } } else { //info not needed if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info loaded CloseStatGasCloudInfo((GasCloudStaticInfo *)staticinfo); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Freeing gascloud: %s\n", GasCloudTypeToStr(gascloudtype)); } #endif } } } #endif for (nebulatype = 0; nebulatype < NUM_NEBULATYPES; nebulatype++) { HorseRaceNext(((real32)count)/((real32)max)); if (hrAbortLoadingGame) { goto abortloadinggame; } staticinfo = (StaticInfo *)&nebulaStaticInfos[nebulatype]; if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoNeeded)) { //if info needed if (!bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info needed and not loaded InitStatNebulaInfo((NebulaStaticInfo *)staticinfo, nebulatype); bitSet(staticinfo->staticheader.infoFlags, IF_InfoLoaded); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Loading nebula: %s\n", NebulaTypeToStr(nebulatype)); } #endif } } else { //info not needed if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info loaded CloseStatNebulaInfo((NebulaStaticInfo *)staticinfo); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Freeing nebula: %s\n", NebulaTypeToStr(nebulatype)); } #endif } } count++; } for (derelicttype=0;derelicttypestaticheader.infoFlags, IF_InfoNeeded)) { //if info needed if (!bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info needed and not loaded InitStatDerelictInfo((DerelictStaticInfo *)staticinfo,derelicttype); bitSet(staticinfo->staticheader.infoFlags, IF_InfoLoaded); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Loading derelict: %s\n", DerelictTypeToStr(derelicttype)); } #endif } else { if (staticinfo->staticheader.LOD != NULL) { lodAllMeshesRecolorize(staticinfo->staticheader.LOD); } } } else { //info not needed if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info loaded CloseStatDerelictInfo((DerelictStaticInfo *)staticinfo); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Freeing derelict: %s\n", DerelictTypeToStr(derelicttype)); } #endif } } count++; } for (shiprace=0;shipracestaticheader.infoFlags, IF_InfoNeeded)) { //if info needed if (!bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info needed and not loaded InitStatMissileInfo((MissileStaticInfo *)staticinfo,shiprace); bitSet(staticinfo->staticheader.infoFlags, IF_InfoLoaded); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Loading missile: %8s\n", ShipRaceToStr(shiprace)); } #endif } } else { //info not needed if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info loaded CloseStatMissileInfo((MissileStaticInfo *)staticinfo); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Freeing missile: %8s\n", ShipRaceToStr(shiprace)); } #endif } } count++; } maxMineCollSphereSize = 0.0f; for (shiprace=0;shiprace<2;shiprace++) { HorseRaceNext(((real32)count)/((real32)max)); if (hrAbortLoadingGame) { goto abortloadinggame; } staticinfo = (StaticInfo *)&mineStaticInfos[shiprace]; if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoNeeded)) { //if info needed if (!bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info needed and not loaded InitStatMineInfo((MissileStaticInfo *)staticinfo,shiprace); bitSet(staticinfo->staticheader.infoFlags, IF_InfoLoaded); if (mineStaticInfos[shiprace].staticheader.staticCollInfo.collspheresize > maxMineCollSphereSize) { maxMineCollSphereSize = mineStaticInfos[shiprace].staticheader.staticCollInfo.collspheresize; } #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Loading mine: %8s\n", ShipRaceToStr(shiprace)); } #endif } } else { //info not needed if (bitTest(staticinfo->staticheader.infoFlags, IF_InfoLoaded)) { //info loaded CloseStatMineInfo((MissileStaticInfo *)staticinfo); #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fprintf(logFile, "Freeing mine: %8s\n", ShipRaceToStr(shiprace)); } #endif } } count++; } maxMineCollSphereSize *= 2.0f; // InitStatEffectInfo(&effectStaticInfo); abortloadinggame: for (shiprace=0;shipracestaticheader.infoFlags, IF_InfoNeeded)) { if (bitTest(shipstaticinfo->staticheader.infoFlags, IF_NotPostLoaded)) { //if ship just now loaded InitStatShipInfoPost(shipstaticinfo); //shipstaticinfo->staticheader.infoFlags, IF_InfoLoaded) = TRUE; bitClear(shipstaticinfo->staticheader.infoFlags, IF_NotPostLoaded); bitSet(shipstaticinfo->staticheader.infoFlags, IF_InfoLoaded); } } } } #if UNIV_SHIP_LOADFREE_LOG if (logFile) { fclose(logFile); } #endif if (hrAbortLoadingGame) { ; } else { if (singlePlayerGame) { GetShipStaticInfo(Mothership,R1)->staticheader.immobile = TRUE; GetShipStaticInfo(Mothership,R2)->staticheader.immobile = TRUE; } else { GetShipStaticInfo(Mothership,R1)->staticheader.immobile = FALSE; GetShipStaticInfo(Mothership,R2)->staticheader.immobile = FALSE; } } } /*----------------------------------------------------------------------------- Name : universeStaticInit Description : Reinitializes some static data: *.Shp variables Inputs : none Outputs : Return : ----------------------------------------------------------------------------*/ void universeRealTimeTweak(SelectCommand *selection) { ShipRace shiprace; ShipType shiptype; ShipStaticInfo *shipstaticinfo; udword shiparray[100]; udword shiptypedone; udword shipdoneptr=0; udword index; sdword flag = FALSE; for(shiptypedone = 0;shiptypedone < 100; shiptypedone++) { shiparray[shiptypedone] = 99999; //fill with garbage ships } for (index = 0;index < selection->numShips;index++) { shiprace = selection->ShipPtr[index]->staticinfo->shiprace; shiptype = selection->ShipPtr[index]->shiptype; for(shiptypedone = 0;shiptypedone <=shipdoneptr; shiptypedone++) { if(shiparray[shiptypedone] == shiptype) { //shiptype already loaded, so don't load it flag = TRUE; break; } } if(flag == TRUE) { flag = FALSE; continue; } shiparray[shipdoneptr] = shiptype; shipdoneptr++; shipstaticinfo = GetShipStaticInfo(shiptype,shiprace); InitStatShipInfo(shipstaticinfo,shiptype,shiprace); } } void universeSetZeroPlayers(void) { universe.numPlayers = 0; cameraInit(&defaultCamera,5000.0f); } /*----------------------------------------------------------------------------- Name : universeNoStaticLoadedOrNeeded Description : Marks all static static infos as not loaded and not needed in fact, it sets the entire static infos to NULL Inputs : void Outputs : Return : void ----------------------------------------------------------------------------*/ void universeNoStaticLoadedOrNeeded(void) { ShipRace shiprace; ShipType shiptype; ShipStaticInfo *shipStaticInfo; AsteroidStaticInfo *asteroidStaticInfo; DustCloudStaticInfo *dustcloudStaticInfo; GasCloudStaticInfo *gascloudStaticInfo; NebulaStaticInfo *nebulaStaticInfo; DerelictStaticInfo *derelictStaticInfo; MissileStaticInfo *missileStaticInfo; AsteroidType asteroidtype; DustCloudType dustcloudtype; GasCloudType gascloudtype; NebulaType nebulatype; DerelictType derelicttype; ShipType firstshiptype; ShipType lastshiptype; for (shiprace=0;shipracestaticheader.infoFlags, IF_InfoLoaded)) { CloseStatMissileInfo((MissileStaticInfo *)staticInfo); } } for (shiprace=0;shiprace<2;shiprace++) //only two races have mines { staticInfo = (StaticInfo *)&mineStaticInfos[shiprace]; if (bitTest(staticInfo->staticheader.infoFlags, IF_InfoLoaded)) { CloseStatMineInfo((MissileStaticInfo *)staticInfo); } } for (derelicttype=0;derelicttypestaticheader.infoFlags, IF_InfoLoaded)) { CloseStatDerelictInfo((DerelictStaticInfo *)staticInfo); } } for (asteroidtype=0;asteroidtypestaticheader.infoFlags, IF_InfoLoaded)) { CloseStatAsteroidInfo((AsteroidStaticInfo *)staticInfo); } } for (dustcloudtype = 0; dustcloudtype < NUM_DUSTCLOUDTYPES; dustcloudtype++) { staticInfo = (StaticInfo *)&dustcloudStaticInfos[dustcloudtype]; if (bitTest(staticInfo->staticheader.infoFlags, IF_InfoLoaded)) { CloseStatDustCloudInfo((DustCloudStaticInfo *)staticInfo); } } for (gascloudtype = 0; gascloudtype < NUM_GASCLOUDTYPES; gascloudtype++) { staticInfo = (StaticInfo *)&gascloudStaticInfos[gascloudtype]; if (bitTest(staticInfo->staticheader.infoFlags, IF_InfoLoaded)) { CloseStatGasCloudInfo((GasCloudStaticInfo *)staticInfo); } } for (shiprace=0;shipracestaticheader.infoFlags, IF_InfoLoaded)) { CloseStatShipInfo((ShipStaticInfo *)staticInfo); } } } if (defaultlod != NULL) { lodFree(defaultlod); defaultlod = NULL; } if (defaultmex != NULL) { mexFree(defaultmex); defaultmex = NULL; } if (defaultmesh != NULL) { meshFree(defaultmesh); defaultmesh = NULL; } } void universeClose(void) { clClose(&universe.mainCommandLayer); ccClose(&universe.mainCameraCommand); universeClosePlayers(); univupdateClose(); universeStaticCloseAllStatics(); } /*----------------------------------------------------------------------------- Name : universeStaticClose Description : Closes static data of the Universe Inputs : none Outputs : Return : ----------------------------------------------------------------------------*/ void universeStaticClose(void) { } /*----------------------------------------------------------------------------- Name : universeUpdateTask Description : the main loop of the task which updates the universe (all mission spheres) and executes all of the physics stuff and moves all of the ships. This task runs independent of the screen refresh rate. Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ #pragma optimize("gy", off) //turn on stack frame (we need ebp for this function) void universeUpdateTask(void) { static WaitPacketStatus waitpacketstatus; static sdword repeatuniv; static sdword repeattimes; taskYield(0); for(;;) { if ((multiPlayerGame) && (startingGame) && (gameIsRunning) && ((IAmCaptain) && (!multiPlayerGameUnderWay))) { if (checkPlayersReady()) { multiPlayerGameUnderWay = TRUE; } } if (startingGameState == CHECK_AUTODOWNLOAD_MAP) { taskStackSaveCond(0); universeUpdateCounter++; if (!LANGame) chatClose(); if (sigsPlayerIndex == 0) autodownloadmapGotMapName(spScenarios[spCurrentSelected].fileSpec,numPlayers,spScenarios[spCurrentSelected].minplayers,spScenarios[spCurrentSelected].maxplayers); else autodownloadmapGotMapName(tpGameCreated.MapName,numPlayers,0,0); horseRaceInit(); if (autodownloadmapRequired()) { HorseRaceBeginBar(DOWNLOADMAP_BAR); if (sigsPlayerIndex == 0) { autodownloadmapGetFilesOfMap(); } autodownloadmapPrintStatusStart(); startingGameState = AUTODOWNLOAD_MAP; } else { startingGameState = PROCESS_TEXTURES; goto processtextures; } } else if (startingGameState == AUTODOWNLOAD_MAP) { taskStackSaveCond(0); repeatagainwithoutyielding: // for horse race hack we need this silly hack universeUpdateCounter++; autodownloadmapPrintStatus(); if (sigsPlayerIndex == 0) { // for now, lets just bang everything through: if (autodownloadmapSendAFile()) { HorseRaceNext(1.0f); startingGameState = PROCESS_TEXTURES; goto processtextures; } else { HorseRaceNext(autodownloadmapPercentSentFiles()); // don't check for aborting - will mess up everyone since files must be sent! } } else { if (autodownloadmapReceivedAllFiles()) { HorseRaceNext(1.0f); startingGameState = PROCESS_TEXTURES; goto processtextures; } else { HorseRaceNext(autodownloadmapPercentReceivedFiles()); if (hrAbortLoadingGame) { startingGameState = PROCESS_TEXTURES; goto processtextures; } } } goto repeatagainwithoutyielding; } else if (startingGameState == PROCESS_TEXTURES) { taskStackSaveCond(0); universeUpdateCounter++; processtextures: if (!hrAbortLoadingGame) { gameStart(NULL); } horseRaceShutdown(); startingGameState = GAME_STARTED; if (hrAbortLoadingGame) { utyGameQuitToMain(NULL,NULL); hrAbortLoadingGame = FALSE; } else if (multiPlayerGame) { TransferCaptaincyGameStarted(); } taskStackRestoreCond(); } else if (gameIsRunning) { taskStackSaveCond(0); universeUpdateCounter++; if ((multiPlayerGame) || (playPackets|recordFakeSendPackets)) { if (!universe.dontUpdateRenderList) { if ((universe.univUpdateCounter == 1) || ((universeUpdateCounter & REFRESH_RENDERLIST_RATE) == REFRESH_RENDERLIST_FRAME)) { univUpdateRenderList(); } if ((universe.univUpdateCounter == 1) || ((universeUpdateCounter & REFRESH_MINORRENDERLIST_RATE) == REFRESH_MINORRENDERLIST_FRAME)) // make it 3 to mix things up a bit { univUpdateMinorRenderList(); } } if (!(playPackets|recordFakeSendPackets)) { if ((!multiPlayerGameUnderWay) && (!IAmCaptain)) { if (!HaveSentNonCaptainReadyPacket) { SendNonCaptainReadyPacket(sigsPlayerIndex); HaveSentNonCaptainReadyPacket = TRUE; } } } if (multiPlayerGame) { gcPollForNewChat(); TransferCaptaincyUpdate(); KeepAliveUpdate(); if ((universeUpdateCounter & INTERNET_LAG_UPDATERATE) == 0) { lagUpdateInternetLag(); } } if (playPackets|recordFakeSendPackets) { if (universePause) { goto alldone; } } #if UNIVERSE_TURBOPAUSE_DEBUG if ((playPackets|recordFakeSendPackets) && universeTurbo) { repeattimes = UNIVERSE_TURBO_REPEAT>>1; dbgAssert(repeattimes >= 1); } else #endif repeattimes = 1; for (repeatuniv=0;repeatuniv 1)) ) { taskStackRestoreCond(); taskYield(0); taskStackSaveCond(0); } if (!gameIsRunning) { goto alldone; } if (univUpdate(UNIVERSE_UPDATE_PERIOD)) { goto alldone; } } } alldone:; } else { if (!universe.dontUpdateRenderList) { if ((universe.univUpdateCounter == 1) || ((universeUpdateCounter & REFRESH_RENDERLIST_RATE) == REFRESH_RENDERLIST_FRAME)) { univUpdateRenderList(); } if ((universe.univUpdateCounter == 1) || ((universeUpdateCounter & REFRESH_MINORRENDERLIST_RATE) == REFRESH_MINORRENDERLIST_FRAME)) // make it 3 to mix things up a bit { univUpdateMinorRenderList(); } } if (universePause) { goto alldone2; } if((tutorial==TUTORIAL_ONLY) && !tutEnable.bGameRunning) { tutEnable.bKASFrame ^= 1; if(tutEnable.bKASFrame) kasExecute(); // Make sure KAS gets called goto alldone2; } #if (!UNIVERSE_TURBORECORD_ONLY) #if UNIVERSE_TURBOPAUSE_DEBUG if (universeTurbo) { for (repeatuniv=0;repeatuniv= universe.numPlayers) { universe.curPlayerIndex = 0; } universe.curPlayerPtr = &universe.players[universe.curPlayerIndex]; universe.collUpdateAllBlobs = TRUE; //next update will update all blobs dbgMessagef("\nCurrent player: %d %x",universe.curPlayerIndex,universe.curPlayerPtr); } /*----------------------------------------------------------------------------- Name : universeSwitchToPlayer Description : switches current player to player indicated by playerIndex Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void universeSwitchToPlayer(uword playerIndex) { dbgAssert(playerIndex < universe.numPlayers); universe.curPlayerIndex = playerIndex; universe.curPlayerPtr = &universe.players[universe.curPlayerIndex]; } /*----------------------------------------------------------------------------- Name : GetShipStaticInfo Description : returns ShipStaticInfo of shiptype, shiprace Inputs : shiptype, shiprace Outputs : Return : returns ShipStaticInfo of shiptype, shiprace ----------------------------------------------------------------------------*/ ShipStaticInfo *GetShipStaticInfo(ShipType shiptype,ShipRace shiprace) { ShipStaticInfo *raceInfo = RaceShipStaticInfos[shiprace]; sdword offset; dbgAssert(shiprace < NUM_RACES); dbgAssert(shiptype < TOTAL_NUM_SHIPS); offset = shiptype - FirstShipTypeOfRace[shiprace]; dbgAssert(offset >= 0); dbgAssert(offset < NumShipTypesInRace[shiprace]); return &raceInfo[offset]; } /*----------------------------------------------------------------------------- Name : GetShipStaticInfoSafe Description : returns ShipStaticInfo of shiptype, shiprace, NULL if not valid Inputs : shiptype, shiprace Outputs : Return : ----------------------------------------------------------------------------*/ ShipStaticInfo *GetShipStaticInfoSafe(ShipType shiptype,ShipRace shiprace) { ShipStaticInfo *raceInfo = RaceShipStaticInfos[shiprace]; ShipStaticInfo *shipstatic; sdword offset; if ((shiprace >= NUM_RACES)) { return NULL; } if ((shiptype >= TOTAL_NUM_SHIPS)) { return NULL; } offset = shiptype - FirstShipTypeOfRace[shiprace]; if ((offset < 0) || (offset >= NumShipTypesInRace[shiprace])) { return NULL; } shipstatic = &raceInfo[offset]; if (!bitTest(shipstatic->staticheader.infoFlags, IF_InfoLoaded)) { return NULL; } return shipstatic; } /*----------------------------------------------------------------------------- Name : GetValidRaceForShipType Description : returns valid race for shiptype, -1 if none found Inputs : shiptype Outputs : Return : returns valid race for shiptype, -1 if none found ----------------------------------------------------------------------------*/ ShipRace GetValidRaceForShipType(ShipType shiptype) { dbgAssert(shiptype < TOTAL_NUM_SHIPS); if (RacesAllowedForGivenShip[shiptype] & R1_VALID) { return R1; } if (RacesAllowedForGivenShip[shiptype] & R2_VALID) { return R2; } if (RacesAllowedForGivenShip[shiptype] & P1_VALID) { return P1; } if (RacesAllowedForGivenShip[shiptype] & P2_VALID) { return P2; } if (RacesAllowedForGivenShip[shiptype] & P3_VALID) { return P3; } if (RacesAllowedForGivenShip[shiptype] & Traders_VALID) { return Traders; } dbgAssert(FALSE); return R1; } /*----------------------------------------------------------------------------- Name : GetShipStaticInfoValidate Description : returns ShipStaticInfo of shiptype, shiprace. Makes sure data loaded Inputs : shiptype, shiprace Outputs : Return : returns ShipStaticInfo of shiptype, shiprace ----------------------------------------------------------------------------*/ ShipStaticInfo *GetShipStaticInfoValidate(ShipType shiptype,ShipRace shiprace) { ShipStaticInfo *shipstatic = GetShipStaticInfo(shiptype,shiprace); if (!bitTest(shipstatic->staticheader.infoFlags, IF_InfoLoaded)) { dbgFatalf(DBG_Loc,"Ship %s %s not loaded",ShipRaceToStr(shiprace),ShipTypeToStr(shiptype)); } return shipstatic; } /* Unit Capping functions */ /*----------------------------------------------------------------------------- Name : unitCapCreateShip Description : Updates ship totals for player Inputs : uword shiptype, Player *player Outputs : none Return : void -----------------------------------------------------------------------------*/ void unitCapCreateShip(Ship *ship, Player *player) { // if (player->aiPlayer) // { // return; // } // don't keep tabs on these ship types if ((cdEnabled) && (ship->shiptype != Drone) && (ship->shiptype != TargetDrone) && (ship->shiptype != HeadShotAsteroid) && (ship->shiptype != CryoTray) && (! (bitTest(ship->specialFlags2,SPECIAL_2_InUnitCaps)) ) ) { player->totalships++; player->shiptotals[ship->shiptype]++; player->classtotals[ship->staticinfo->shipclass]++; bitSet(ship->specialFlags2,SPECIAL_2_InUnitCaps); } } /*----------------------------------------------------------------------------- Name : unitCapDeleteShip Description : Updates ship totals for player Inputs : uword shiptype, Player *player Outputs : none Return : void -----------------------------------------------------------------------------*/ void unitCapDeleteShip(Ship *ship, Player *player) { // don't keep tabs on these ship types // if (player->aiPlayer) // { // return; // } if ((cdEnabled) && (ship->shiptype != Drone) && (ship->shiptype != TargetDrone) && (ship->shiptype != HeadShotAsteroid) && (ship->shiptype != CryoTray) && ( (bitTest(ship->specialFlags2,SPECIAL_2_InUnitCaps)) )) { player->totalships--; // dbgAssert(player->totalships >= 0); if (player->totalships < 0) { player->totalships = 0; dbgMessagef("\nWarning: total shipcount in unit caps went below 0"); } player->shiptotals[ship->shiptype]--; // dbgAssert(player->shiptotals[ship->shiptype] >= 0); if (player->shiptotals[ship->shiptype] < 0) { player->shiptotals[ship->shiptype] = 0; dbgMessagef("\nWarning: shipcount of shiptype %d went below 0"); } player->classtotals[ship->staticinfo->shipclass]--; // dbgAssert(player->classtotals[ship->staticinfo->shipclass] >= 0); if (player->classtotals[ship->staticinfo->shipclass] < 0) { player->classtotals[ship->staticinfo->shipclass] = 0; dbgMessagef("\nWarning: classtotals of class %d went below 0",ship->staticinfo->shipclass); } bitClear(ship->specialFlags2,SPECIAL_2_InUnitCaps); } } /*----------------------------------------------------------------------------- Name : unitCapCanCreateShip Description : Can we build this ship ?? Inputs : uword shiptype, Player *player Outputs : TRUE if ship is within limit caps FLASE if ship will exceed limit caps Return : bool8 -----------------------------------------------------------------------------*/ bool unitCapCanCreateShip(ShipType ship, shipsinprogress *factory, shipavailable *cmShipsAvail) { Player *player=factory->ship->playerowner; shipsinprogress *allfactories=(shipsinprogress *)factory->node.belongto->head; udword totalships=1, typeships=1, classships=1,index; ShipStaticInfo *statinfo, *shipstatic; if ((!bitTest(tpGameCreated.flag,MG_UnitCapsEnabled)) && (ship!=ResearchShip)&&(!singlePlayerGame)) { return(TRUE); } shipstatic = GetShipStaticInfo(ship, player->race); // total up all ships in the queue but not yet started for (index=0;cmShipsAvail[index].nJobs != -1; index++) { statinfo = GetShipStaticInfo(cmShipsAvail[index].type, player->race); totalships+=cmShipsAvail[index].nJobs; if (cmShipsAvail[index].type == shipstatic->shiptype) typeships+=cmShipsAvail[index].nJobs; if (statinfo->shipclass == shipstatic->shipclass) classships+=cmShipsAvail[index].nJobs; } // walk through list of factories do { // if factory is owned by player then total all ships being built if (allfactories->ship->playerowner==player) { for (index=0;indexrace); totalships+=allfactories->progress[index].nJobs + shiplagtotals[index]; if (index==shipstatic->shiptype) typeships+=allfactories->progress[index].nJobs + shiplagtotals[index]; if (statinfo->shipclass == shipstatic->shipclass) classships+=allfactories->progress[index].nJobs + shiplagtotals[index]; } } // next factory allfactories=(shipsinprogress *)allfactories->node.next; } while (allfactories != NULL); if (player->totalships+totalships > cdMaxShipsAllowed) { speechEventFleet(STAT_F_Const_TotalLimit, 0, player->playerIndex); // player already has too many ships cannot build anymore return(FALSE); } if (cdLimitCaps[shipstatic->shiptype] != -1) { if (player->shiptotals[shipstatic->shiptype]+typeships > cdLimitCaps[shipstatic->shiptype]) { speechEventFleet(STAT_F_Const_UnitLimit, shipstatic->shiptype, player->playerIndex); // player has to many of this type of ship return(FALSE); } } if (player->classtotals[shipstatic->shipclass]+classships > cdClassCaps[shipstatic->shipclass]) { speechEventFleet(STAT_F_Const_UnitLimit, shipstatic->shiptype, player->playerIndex); // player has to many of this class of ship return(FALSE); } return(TRUE); } /*----------------------------------------------------------------------------- Name : unitCapInitialize Description : Initialize the unit totals to zero Inputs : Player *player Outputs : none Return : void -----------------------------------------------------------------------------*/ void unitCapInitialize(Player *player) { player->totalships=0; memset(player->shiptotals, 0,sizeof(sdword)*TOTAL_NUM_SHIPS); memset(player->classtotals,0,sizeof(sdword)*NUM_CLASSES); } /*----------------------------------------------------------------------------- Name : unitCapEnable Description : Enables unit cap tracking Inputs : none Outputs : none Return : void ----------------------------------------------------------------------------*/ void unitCapEnable(void) { cdEnabled = TRUE; } /*----------------------------------------------------------------------------- Name : unitCapDisable Description : disables unit cap tracking Inputs : none Outputs : none Return : void ----------------------------------------------------------------------------*/ void unitCapDisable(void) { cdEnabled = FALSE; } /*----------------------------------------------------------------------------- Name : resourceInjectionTask Description : this is setup to be called at a specified time if it was enabled. Inputs : Outputs : Return : void ----------------------------------------------------------------------------*/ void unitCapInitStatics(udword numplayers) { char temp[128]; sprintf(temp,"UnitLimitCaps%i.script", numplayers); scriptSet(NULL,temp,ShipStaticCapLimits); } /*----------------------------------------------------------------------------- Name : resourceInjectionTask Description : this is setup to be called at a specified time if it was enabled. Inputs : Outputs : Return : void ----------------------------------------------------------------------------*/ void resourceInjectionTask(void) { sdword index; for (index=0;indexgameStats.totalResourcesInGame = 0; universe->gameStats.totalShipsInGame = 0; universe->gameStats.totalKills = 0; universe->gameStats.totalRUsInAllShips = 0; universe->gameStats.totalRUsKilled = 0; universe->gameStats.totalResourceUnitsCollected = 0; universe->gameStats.totalRUsLost = 0; universe->gameStats.updatedRUValuesTime = 0.0f; universe->gameStats.universeRUWorth = 0; for(i=0;inumPlayers;i++) { universe->gameStats.playerStats[i].timeOfDeath = 0; universe->gameStats.playerStats[i].typeOfPlayerDeath = 0; universe->gameStats.playerStats[i].totalResourceUnits = 0; universe->gameStats.playerStats[i].totalResourceUnitsCollected = 0; //[] universe->gameStats.playerStats[i].totalResourceUnitsSpent = 0; //[] universe->gameStats.playerStats[i].totalResourceUnitsGiven = 0; //[] universe->gameStats.playerStats[i].totalResourceUnitsRecieved = 0; universe->gameStats.playerStats[i].totalRegeneratedResourceUnits = 0; //[x] universe->gameStats.playerStats[i].totalInjectedResources = 0; //[x] universe->gameStats.playerStats[i].totalResourceUnitsViaBounties = 0; //[x] universe->gameStats.playerStats[i].totalRUsInCurrentShips = 0; universe->gameStats.playerStats[i].totalShips = 0; universe->gameStats.playerStats[i].totalKills = 0; universe->gameStats.playerStats[i].totalRUsKilled = 0; universe->gameStats.playerStats[i].totalLosses = 0; universe->gameStats.playerStats[i].totalRUsLost = 0; for(j=0;jnumPlayers;j++) { universe->gameStats.playerStats[i].pointsOfDamageDoneToWho[j] = 0.0f; } for(j=0;jgameStats.playerStats[i].totalForEachShip[j]=0; universe->gameStats.playerStats[i].totalKillsForEachShip[j]=0; universe->gameStats.playerStats[i].totalLossesForEachShip[j]=0; } for(j=0;jgameStats.playerStats[i].totalForEachClass[j]=0; universe->gameStats.playerStats[i].totalKillsForEachClass[j]=0; universe->gameStats.playerStats[i].totalLossesForEachClass[j]=0; } } } /*----------------------------------------------------------------------------- Name : gameStatsAddShip Description : Updates stats for ship Inputs : Outputs : Return : ----------------------------------------------------------------------------*/ void gameStatsAddShip(Ship *ship,sdword playerIndex) { universe.gameStats.playerStats[playerIndex].totalShips++; universe.gameStats.playerStats[playerIndex].totalForEachShip[ship->shiptype]++; universe.gameStats.playerStats[playerIndex].totalForEachClass[ship->staticinfo->shipclass]++; universe.gameStats.totalRUsInAllShips += ship->staticinfo->buildCost; universe.gameStats.playerStats[playerIndex].totalRUsInCurrentShips += ship->staticinfo->buildCost; universe.gameStats.totalShipsInGame; } void gameStatsShipDied(Ship *ship) { sdword shipownerindex,killerPlayerIndex; if(ship->playerowner != NULL) shipownerindex = ship->playerowner->playerIndex; else dbgFatalf(DBG_Loc,"\nShip player pointer NULL...shouldn't be"); if(ship->shiptype == Drone) { //we don't want to count drones as kills.. //because they aren't really a critical kill //andthey have no real RU value return; } switch(ship->howDidIDie) { case DEATH_Killed_By_Player: case DEATH_Killed_By_Player_Explosion: case DEATH_I_DIDNT_DIE_I_WAS_SALAVAGED: case DEATH_Killed_By_Kamikaze: killerPlayerIndex = ship->whoKilledMe; universe.gameStats.totalRUsKilled += ship->staticinfo->buildCost; universe.gameStats.totalKills++; break; case DEATH_BY_GAME_END: return; //non player depenedant: Only register losses, not kills case DEATH_Killed_By_Collision: case DEATH_Killed_By_Cloud: case DEATH_Killed_By_Dead_Player: case DEATH_BY_RETIREMENT: case DEATH_BY_AFTER_DEAD: case DEATH_Left_Behind_At_Hyperspace: default: killerPlayerIndex = 99; break; } if(killerPlayerIndex != ship->playerowner->playerIndex && killerPlayerIndex != 99) { //Didn't kill own ships...and we need to register the kills universe.gameStats.playerStats[killerPlayerIndex].totalRUsKilled += ship->staticinfo->buildCost; universe.gameStats.playerStats[killerPlayerIndex].totalKills++; universe.gameStats.playerStats[killerPlayerIndex].totalKillsForEachShip[ship->shiptype]++; universe.gameStats.playerStats[killerPlayerIndex].totalKillsForEachClass[ship->staticinfo->shipclass]++; } universe.gameStats.playerStats[ship->playerowner->playerIndex].totalLosses++; universe.gameStats.playerStats[ship->playerowner->playerIndex].totalLossesForEachShip[ship->shiptype]++; universe.gameStats.playerStats[ship->playerowner->playerIndex].totalLossesForEachClass[ship->staticinfo->shipclass]++; universe.gameStats.playerStats[ship->playerowner->playerIndex].totalRUsLost += ship->staticinfo->buildCost; universe.gameStats.playerStats[ship->playerowner->playerIndex].totalRUsInCurrentShips -= ship->staticinfo->buildCost; universe.gameStats.totalRUsLost += ship->staticinfo->buildCost; universe.gameStats.totalRUsInAllShips -= ship->staticinfo->buildCost; } //DEBUG FUNCTION #ifdef DEBUG_GAME_STATS char gamestatsfilename[] = "gamestats.log"; sdword needToInit=FALSE; void gameStatsInitLog() { needToInit=TRUE; } void gameStatsInitForReal() { filehandle fh; FILE *fp; sdword i; GameStatsDebugHeader header; fileDelete(gamestatsfilename); fh = fileOpen(gamestatsfilename,FF_AppendMode); dbgAssert(!fileUsingBigfile(fh)); fp = fileStream(fh); header.numPlayers = universe.numPlayers; for(i=0;i 0) { pInfo=GetShipStaticInfoSafe(j,universe.players[i].race); if(pInfo != NULL) { universe.players[i].initialShipCost+=universe.gameStats.playerStats[i].totalForEachShip[j]* pInfo->buildCost; } } } } return; } // this function returns the actual ship class based on ship type, -1 otherwise sdword gameStatsGetShipClass(sdword nShipType) { switch(nShipType) { case Carrier: case JunkYardHQ: return(CLASS_Carrier); case HeavyCorvette: case LightCorvette: case MinelayerCorvette: case MultiGunCorvette: case RepairCorvette: case SalCapCorvette: case P1MissileCorvette: case P1StandardCorvette: case JunkYardDawg: return(CLASS_Corvette); case MissileDestroyer: case StandardDestroyer: case P3Destroyer: case MiningBase: return(CLASS_Destroyer); case AttackBomber: case CloakedFighter: case DefenseFighter: case HeavyDefender: case HeavyInterceptor: case LightDefender: case LightInterceptor: case Drone: case P1Fighter: case P2AdvanceSwarmer: case P2Swarmer: return(CLASS_Fighter); case AdvanceSupportFrigate: case DDDFrigate: case DFGFrigate: case IonCannonFrigate: case StandardFrigate: case P1IonArrayFrigate: case P2FuelPod: case P2MultiBeamFrigate: case P3Frigate: case Junk_LGun: case Junk_SGun: return(CLASS_Frigate); case HeavyCruiser: return(CLASS_HeavyCruiser); case Mothership: case HeadShotAsteroid: case P1Mothership: case P2Mothership: case P3Megaship: case FloatingCity: return(CLASS_Mothership); case CloakGenerator: case GravWellGenerator: case Probe: case ProximitySensor: case ResearchShip: case ResourceController: case SensorArray: case TargetDrone: case CryoTray: case CargoBarge: case ResearchStation: case ResearchStationBridge: case ResearchStationTower: case Ghostship: return(CLASS_NonCombat); case ResourceCollector: return(CLASS_Resource); default: return(-1); } } #define isPlayerIndexCmptPlayer(i) ((i) >= tpGameCreated.numPlayers) // this function checks the bounds for RUs bool verifyGameStatsResUnitsBounds(FILE *pStatsFile,sdword nPlayerNum,sdword nResourceUnits) { // check for single player game if(singlePlayerGame) return(TRUE); // check computer player flag if(isPlayerIndexCmptPlayer(nPlayerNum)) return(TRUE); if((nResourceUnits < 0) || (nResourceUnits >= 100000)) { // write warning to stats file fprintf(pStatsFile,"\t%s",strGetString(strStatsBadResUnitsBounds)); return(FALSE); } return(TRUE); } // this function checks the totals for RUs bool verifyGameStatsResUnitsTotals(FILE *pStatsFile,sdword nPlayerNum) { sdword nStartingResources=0; // check for single player game if(singlePlayerGame) return(TRUE); // check computer player flag if(isPlayerIndexCmptPlayer(nPlayerNum)) return(TRUE); switch(tpGameCreated.startingResources) { case MG_Small : nStartingResources=resourceStartSmall; break; case MG_Medium : nStartingResources=resourceStartMedium; break; case MG_Large : nStartingResources=resourceStartLarge; break; } if(universe.gameStats.playerStats[nPlayerNum].totalResourceUnitsSpent > ( universe.gameStats.playerStats[nPlayerNum].totalInjectedResources+ universe.gameStats.playerStats[nPlayerNum].totalRegeneratedResourceUnits+ universe.gameStats.playerStats[nPlayerNum].totalResourceUnitsCollected+ universe.gameStats.playerStats[nPlayerNum].totalResourceUnitsGiven+ universe.gameStats.playerStats[nPlayerNum].totalResourceUnitsRecieved+ universe.gameStats.playerStats[nPlayerNum].totalResourceUnitsViaBounties+ nStartingResources )) { // write warning to stats file fprintf(pStatsFile,"\t%s",strGetString(strStatsBadResUnitTotals)); return(FALSE); } return(TRUE); } // this function checks the bounds for the number of ships (based on the number of players) bool verifyGameStatsShipsBounds(FILE *pStatsFile,sdword nPlayerNum,sdword nNumShips,sdword nNumPlayers) { // check for single player game if(singlePlayerGame) return(TRUE); // check computer player flag if(isPlayerIndexCmptPlayer(nPlayerNum)) return(TRUE); if((nNumShips < 0) || (nNumShips >= 1000*nNumPlayers)) { // write warning to stats file fprintf(pStatsFile,"\t%s",strGetString(strStatsBadShipBounds)); return(FALSE); } return(TRUE); } // this function checks the ship cost totals bool verifyGameStatsShipCostTotals(FILE *pStatsFile,sdword nPlayerNum) { ShipStaticInfo *pInfo; sdword n,nShipTotal,nStartingResources=0; // check for single player game if(singlePlayerGame) return(TRUE); // check computer player flag if(isPlayerIndexCmptPlayer(nPlayerNum)) return(TRUE); switch(tpGameCreated.startingResources) { case MG_Small : nStartingResources=resourceStartSmall; break; case MG_Medium : nStartingResources=resourceStartMedium; break; case MG_Large : nStartingResources=resourceStartLarge; break; } // reset total nShipTotal=-universe.players[nPlayerNum].initialShipCost; // calculate total for(n=0;n 0) { pInfo=GetShipStaticInfoSafe(n,universe.players[nPlayerNum].race); if(pInfo != NULL) { nShipTotal+=universe.gameStats.playerStats[nPlayerNum].totalForEachShip[n]* pInfo->buildCost; } } } // compare totals if(((nShipTotal - nShipTotal/50 ) > ( universe.gameStats.playerStats[nPlayerNum].totalInjectedResources+ universe.gameStats.playerStats[nPlayerNum].totalRegeneratedResourceUnits+ universe.gameStats.playerStats[nPlayerNum].totalResourceUnitsCollected+ universe.gameStats.playerStats[nPlayerNum].totalResourceUnitsGiven+ universe.gameStats.playerStats[nPlayerNum].totalResourceUnitsRecieved+ universe.gameStats.playerStats[nPlayerNum].totalResourceUnitsViaBounties+ nStartingResources )) || ((nShipTotal - nShipTotal/50 ) > universe.gameStats.playerStats[nPlayerNum].totalResourceUnitsSpent)) { // write warning to stats file fprintf(pStatsFile,"\t%s",strGetString(strStatsBadShipCostTotals)); return(FALSE); } return(TRUE); } // this function checks the total number of ships acquired bool verifyGameStatsShipsAcquiredTotals(FILE *pStatsFile,sdword nPlayerNum) { sdword n,nShipTotal,nClassTotal; // check for single player game if(singlePlayerGame) return(TRUE); // check computer player flag if(isPlayerIndexCmptPlayer(nPlayerNum)) return(TRUE); // reset total nShipTotal=0; // calculate total for(n=0;n 0) { nShipTotal+=universe.gameStats.playerStats[nPlayerNum].totalForEachShip[n]; } } // reset total nClassTotal=0; // calculate total for(n=0;n 0) { nClassTotal+=universe.gameStats.playerStats[nPlayerNum].totalForEachClass[n]; } } // compare total if((universe.gameStats.playerStats[nPlayerNum].totalShips != nShipTotal) || (universe.gameStats.playerStats[nPlayerNum].totalShips != nClassTotal)) { // write warning to stats file fprintf(pStatsFile,"\t%s",strGetString(strStatsBadShipsAcquiredTotals)); return(FALSE); } return(TRUE); } // this function checks the total number of ships killed bool verifyGameStatsShipsKilledTotals(FILE *pStatsFile,sdword nPlayerNum) { sdword n,nShipTotal,nClassTotal; // check for single player game if(singlePlayerGame) return(TRUE); // check computer player flag if(isPlayerIndexCmptPlayer(nPlayerNum)) return(TRUE); // reset total nShipTotal=0; // calculate total for(n=0;n 0) { nShipTotal+=universe.gameStats.playerStats[nPlayerNum].totalKillsForEachShip[n]; } } // reset total nClassTotal=0; // calculate total for(n=0;n 0) { nClassTotal+=universe.gameStats.playerStats[nPlayerNum].totalKillsForEachClass[n]; } } // compare total if((universe.gameStats.playerStats[nPlayerNum].totalKills != nShipTotal) || (universe.gameStats.playerStats[nPlayerNum].totalKills != nClassTotal)) { // write warning to stats file fprintf(pStatsFile,"\t%s",strGetString(strStatsBadShipsKilledTotals)); return(FALSE); } return(TRUE); } // this function checks the total number of ships lost bool verifyGameStatsShipsLostTotals(FILE *pStatsFile,sdword nPlayerNum) { sdword n,nShipTotal,nClassTotal; // check for single player game if(singlePlayerGame) return(TRUE); // check computer player flag if(isPlayerIndexCmptPlayer(nPlayerNum)) return(TRUE); // reset total nShipTotal=0; // calculate total for(n=0;n 0) { nShipTotal+=universe.gameStats.playerStats[nPlayerNum].totalLossesForEachShip[n]; } } // reset total nClassTotal=0; // calculate total for(n=0;n 0) { nClassTotal+=universe.gameStats.playerStats[nPlayerNum].totalLossesForEachClass[n]; } } // compare total if((universe.gameStats.playerStats[nPlayerNum].totalLosses != nShipTotal) || (universe.gameStats.playerStats[nPlayerNum].totalLosses != nClassTotal)) { // write warning to stats file fprintf(pStatsFile,"\t%s",strGetString(strStatsBadShipsLostTotals)); return(FALSE); } return(TRUE); } // this function checks the number of ships acquired per class bool verifyGameStatsShipsAcquiredClassTotals(FILE *pStatsFile,sdword nPlayerNum,sdword nShipClass) { sdword n,nShipTotal,nActualClass; // check for single player game if(singlePlayerGame) return(TRUE); // check computer player flag if(isPlayerIndexCmptPlayer(nPlayerNum)) return(TRUE); // reset total nShipTotal=0; // calculate total for(n=0;n 0) { // get actual ship class nActualClass=gameStatsGetShipClass(n); if((nActualClass >= 0) && (nActualClass == nShipClass)) { nShipTotal+=universe.gameStats.playerStats[nPlayerNum].totalForEachShip[n]; } } } // compare totals if(nShipTotal != universe.gameStats.playerStats[nPlayerNum].totalForEachClass[nShipClass]) { // write warning to stats file fprintf(pStatsFile,"\t%s",strGetString(strStatsBadShipsAcquiredClassTotals)); return(FALSE); } return(TRUE); } // this function checks the number of ships killed per class bool verifyGameStatsShipsKilledClassTotals(FILE *pStatsFile,sdword nPlayerNum,sdword nShipClass) { sdword n,nShipTotal,nActualClass; // check for single player game if(singlePlayerGame) return(TRUE); // check computer player flag if(isPlayerIndexCmptPlayer(nPlayerNum)) return(TRUE); // reset total nShipTotal=0; // calculate total for(n=0;n 0) { // get actual ship class nActualClass=gameStatsGetShipClass(n); if((nActualClass >= 0) && (nActualClass == nShipClass)) { nShipTotal+=universe.gameStats.playerStats[nPlayerNum].totalKillsForEachShip[n]; } } } // compare totals if(nShipTotal != universe.gameStats.playerStats[nPlayerNum].totalKillsForEachClass[nShipClass]) { // write warning to stats file fprintf(pStatsFile,"\t%s",strGetString(strStatsBadShipsKilledClassTotals)); return(FALSE); } return(TRUE); } // this function checks the number of ships lost per class bool verifyGameStatsShipsLostClassTotals(FILE *pStatsFile,sdword nPlayerNum,sdword nShipClass) { sdword n,nShipTotal,nActualClass; // check for single player game if(singlePlayerGame) return(TRUE); // check computer player flag if(isPlayerIndexCmptPlayer(nPlayerNum)) return(TRUE); // reset total nShipTotal=0; // calculate total for(n=0;n 0) { // get actual ship class nActualClass=gameStatsGetShipClass(n); if((nActualClass >= 0) && (nActualClass == nShipClass)) { nShipTotal+=universe.gameStats.playerStats[nPlayerNum].totalLossesForEachShip[n]; } } } // compare totals if(nShipTotal != universe.gameStats.playerStats[nPlayerNum].totalLossesForEachClass[nShipClass]) { // write warning to stats file fprintf(pStatsFile,"\t%s",strGetString(strStatsBadShipsLostClassTotals)); return(FALSE); } return(TRUE); } // why are there no comments below? void writeGameStatsToFile(char *filename) { sdword i,j,startingresources=0; filehandle statsFH; FILE *statsFile = NULL; if (singlePlayerGame) { return; } statsFH = fileOpen(filename, FF_WriteMode | FF_TextMode | FF_ReturnNULLOnFail); if (!statsFH) { return; } dbgAssert(!fileUsingBigfile(statsFH)); statsFile = fileStream(statsFH); if (statsFile) { if (randSyncErr) { fprintf(statsFile,"\nRAND SYNC ERR: Frame %d",randSyncErrFrame); } if (univSyncErr) { fprintf(statsFile,"\nUNIV SYNC ERR: Frame %d",univSyncErrFrame); } if (multiPlayerGame) // only print cheat detect in multiplayer game { if (blobSyncErr) { fprintf(statsFile,"\n"); fprintf(statsFile,strGetString(strCheatDetect),blobSyncErrFrame); } } if (pktSyncErr) { fprintf(statsFile,"\nPKT SYNC ERR"); } for(i=0;i 0) { fprintf(statsFile,"\n%-40s:%d",ShipTypeToNiceStr(j),universe.gameStats.playerStats[i].totalForEachShip[j]); // check stats verifyGameStatsShipsBounds(statsFile,i,universe.gameStats.playerStats[i].totalForEachShip[j],1); } } fprintf(statsFile,"\n___________________\n\n\n"); fprintf(statsFile,strGetString(strStatsTotalAcqShipsByClass)); for(j=0;j 0) { fprintf(statsFile,"\n%-40s:%d",ShipClassToNiceStr(j),universe.gameStats.playerStats[i].totalForEachClass[j]); // check stats if(verifyGameStatsShipsBounds(statsFile,i,universe.gameStats.playerStats[i].totalForEachClass[j],1) == TRUE) verifyGameStatsShipsAcquiredClassTotals(statsFile,i,j); } } fprintf(statsFile,"\n___________________\n\n"); fprintf(statsFile,strGetString(strStatsTotalKills),universe.gameStats.playerStats[i].totalKills); // check stats if(verifyGameStatsShipsBounds(statsFile,i,universe.gameStats.playerStats[i].totalKills,universe.numPlayers) == TRUE) verifyGameStatsShipsKilledTotals(statsFile,i); for(j=0;j 0) { fprintf(statsFile,"\n%s %s\t\t%d",ShipTypeToNiceStr(j),strGetString(strStatsKilled),universe.gameStats.playerStats[i].totalKillsForEachShip[j]); // check stats verifyGameStatsShipsBounds(statsFile,i,universe.gameStats.playerStats[i].totalKillsForEachShip[j],universe.numPlayers); } } for(j=0;j 0) { fprintf(statsFile,"\n%s %s\t\t%d",ShipClassToNiceStr(j),strGetString(strStatsKilled),universe.gameStats.playerStats[i].totalKillsForEachClass[j]); // check stats if(verifyGameStatsShipsBounds(statsFile,i,universe.gameStats.playerStats[i].totalKillsForEachClass[j],universe.numPlayers) == TRUE) verifyGameStatsShipsKilledClassTotals(statsFile,i,j); } } fprintf(statsFile,"\n___________________\n\n"); fprintf(statsFile,strGetString(strStatsTotalLosses),universe.gameStats.playerStats[i].totalLosses); // check stats if(verifyGameStatsShipsBounds(statsFile,i,universe.gameStats.playerStats[i].totalLosses,universe.numPlayers) == TRUE) verifyGameStatsShipsLostTotals(statsFile,i); for(j=0;j 0) { fprintf(statsFile,"\n%s %s\t\t %d",ShipTypeToNiceStr(j),strGetString(strStatsLost),universe.gameStats.playerStats[i].totalLossesForEachShip[j]); // check stats verifyGameStatsShipsBounds(statsFile,i,universe.gameStats.playerStats[i].totalLossesForEachShip[j],universe.numPlayers); } } for(j=0;j 0) { fprintf(statsFile,"\n%s %s\t\t %d",ShipClassToNiceStr(j),strGetString(strStatsLost),universe.gameStats.playerStats[i].totalLossesForEachClass[j]); // check stats if(verifyGameStatsShipsBounds(statsFile,i,universe.gameStats.playerStats[i].totalLossesForEachClass[j],universe.numPlayers) == TRUE) verifyGameStatsShipsLostClassTotals(statsFile,i,j); } } fprintf(statsFile,"\n___________________\n"); fprintf(statsFile,"\n___________________\n"); } } fileClose(statsFH); }