From 6e163d900348ac3bfac64754b3b7a316023aeeae Mon Sep 17 00:00:00 2001 From: Per Inge Mathisen Date: Sat, 10 Nov 2007 20:28:28 +0000 Subject: [PATCH] Extend new savegame code to save game objects. Droids saved fully, while structures and features still have a way to go. git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@2786 4a71c877-e1ca-e34f-864e-861f7616d084 --- data/testdata/tagfile_map.def | 66 +++++++++++- src/map.c | 187 +++++++++++++++++++++++++++++++++- 2 files changed, 250 insertions(+), 3 deletions(-) diff --git a/data/testdata/tagfile_map.def b/data/testdata/tagfile_map.def index d1099eb65..0c74a4349 100644 --- a/data/testdata/tagfile_map.def +++ b/data/testdata/tagfile_map.def @@ -1,6 +1,7 @@ # # FORMAT: tag enum, value representation (VR), value multiplicity (VM), default value -# VR: ST for text, US for unsigned, SI for signed, FP for floating point, GR for group, EN for group end +# VR: ST for text, US for unsigned, SI for signed, FP for floating point, GR for group, +# EN for group end, BO for boolean # VM: Must be no longer than the size given here; set to 00 for repeating groups # default value cannot be set for VM > 1, ST, GR or EN # @@ -64,3 +65,66 @@ FF EN 00 - FF EN 00 - FF EN 00 - +0f GR 00 - # OBJECT GROUP + 01 GR 00 - # BASE OBJECT GROUP + 01 US 01 - # Object type (always type droid) + 02 US 01 - # Unique object id + 03 US 03 - # (x, y, z) position coordinates + 04 FP 01 - # Direction + 05 SI 01 - # Pitch + 06 SI 01 - # Roll + 07 US 01 - # Player + 08 US 01 - # Selection group + 09 US 01 - # Selected + 0a US 01 - # Cluster + 0b US 08 - # Visibility per player + 0c US 01 - # Died (in game time) + 0d US 01 - # Last smoke emission (in game time) + 0e BO 01 - # On fire? + 0f US 01 - # Burn start (in game time) + 10 US 01 - # Total accumulated burn damage + FF EN 00 - + 02 GR 00 - # SENSOR GROUP + 01 US 01 0 # Sensor range + 02 US 01 0 # Sensor power + 03 US 01 0 # ECM range + 04 US 01 0 # ECM power + FF EN 00 - + 03 GR 00 - # OBJECT STAT GROUP + 01 US 01 - # Original body points + 02 US 01 2 # Number of weapon classes + 03 GR 00 - # ARMOUR GROUP (for each defined side) + 01 US 01 0 # Armour vs kinetic weapons + 02 US 02 0 # Armour vs heat weapons + FF EN 00 - + 04 US 01 - # Resistance (used in electronic warfare) + FF EN 00 - + 04 GR 00 - # WEAPON GROUP + 01 US 01 - # Weapon type + 02 US 01 0 # Weapon rotation + 03 US 01 0 # Weapon pitch + 04 US 01 0 # hitPoints (EXPLAIN ME) + 05 US 01 0 # Ammo + 06 US 01 0 # Time frame it was last fired + 07 US 01 0 # recoilValue (EXPLAIN ME) + FF EN 00 - + 0a GR 00 - # DROID GROUP + 01 US 01 - # Droid type + 02 US 0a - # Components + 03 BO 01 0 # Transport on mission? + 07 US 01 - # Weight + 08 US 01 - # Base speed + 09 ST 60 - # Droid name (typically template name) + 0a US 01 - # Current body points + 0b US 01 - # Number of kills + 0c US 01 - # Name version (EXPLAIN ME) + 0d US 01 - # currRayAng (EXPLAIN ME) + FF EN 00 - + 0b GR 00 - # STRUCTURE GROUP + 01 SI 01 0 # currentBuildPts + 02 SI 01 0 # currentPowerAccrued + FF EN 00 - + 0c GR 00 - # FEATURE GROUP + 01 US 01 0 # Time frame it was created + FF EN 00 - + FF EN 00 - diff --git a/src/map.c b/src/map.c index ad8776576..95d2e63d4 100644 --- a/src/map.c +++ b/src/map.c @@ -44,6 +44,7 @@ #include "environ.h" #include "advvis.h" #include "research.h" +#include "mission.h" #include "gateway.h" #include "wrappers.h" @@ -499,13 +500,165 @@ BOOL mapLoad(char *pFileData, UDWORD fileSize) return TRUE; } +// Object macro group +static void objectSaveTagged(BASE_OBJECT *psObj) +{ + uint16_t v[MAX_PLAYERS], i; + + // not written: sDisplay + + tagWriteEnter(0x01, 1); + tagWrite(0x01, psObj->type); + tagWrite(0x02, psObj->id); + v[0] = psObj->x; + v[1] = psObj->y; + v[2] = psObj->z; + tagWrite16v(0x03, 3, v); + tagWritef(0x04, psObj->direction); + tagWrites(0x05, psObj->pitch); + tagWrites(0x06, psObj->roll); + tagWrite(0x07, psObj->player); + tagWrite(0x08, psObj->group); + tagWrite(0x09, psObj->selected); + tagWrite(0x0a, psObj->cluster); + for (i = 0; i < MAX_PLAYERS; i++) + { + v[i] = psObj->visible[i]; + } + tagWrite16v(0x0b, MAX_PLAYERS, v); + tagWrite(0x0c, psObj->died); + tagWrite(0x0d, psObj->lastEmission); + tagWriteBool(0x0e, psObj->inFire); + tagWrite(0x0f, psObj->burnStart); + tagWrite(0x10, psObj->burnDamage); + tagWriteLeave(0x01); +} + +static void objectSensorTagged(int sensorRange, int sensorPower, int ecmRange, int ecmPower) +{ + tagWriteEnter(0x02, 1); + tagWrite(0x01, sensorRange); + tagWrite(0x02, sensorPower); + tagWrite(0x03, ecmRange); + tagWrite(0x04, ecmPower); + tagWriteLeave(0x02); +} + +static void objectStatTagged(BASE_OBJECT *psObj, int body, int resistance) +{ + int i; + + tagWriteEnter(0x03, 1); + tagWrite(0x01, body); + tagWrite(0x02, NUM_WEAPON_CLASS); + tagWriteEnter(0x03, NUM_HIT_SIDES); + for (i = 0; i < NUM_HIT_SIDES; i++) + { + tagWrite(0x01, psObj->armour[i][WC_KINETIC]); + tagWrite(0x02, psObj->armour[i][WC_HEAT]); + tagWriteSeparator(); + } + tagWriteLeave(0x03); + tagWrite(0x04, resistance); + tagWriteLeave(0x03); +} + +static void objectWeaponTagged(int num, UWORD *rotation, UWORD *pitch, WEAPON *asWeaps) +{ + int i; + + tagWriteEnter(0x04, num); + for (i = 0; i < num; i++) + { + tagWrite(0x01, asWeaps[i].nStat); + tagWrite(0x02, rotation[i]); + tagWrite(0x03, pitch[i]); + tagWrite(0x04, asWeaps[i].hitPoints); + tagWrite(0x04, asWeaps[i].ammo); + tagWrite(0x04, asWeaps[i].lastFired); + tagWrite(0x04, asWeaps[i].recoilValue); + tagWriteSeparator(); + } + tagWriteLeave(0x04); +} + +static void droidSaveTagged(DROID *psDroid) +{ + int plr = psDroid->player; + uint16_t v[DROID_MAXCOMP], i; + + /* common groups */ + + objectSaveTagged((BASE_OBJECT *)psDroid); /* 0x01 */ + objectSensorTagged(psDroid->sensorRange, psDroid->sensorPower, 0, psDroid->ECMMod); /* 0x02 */ + objectStatTagged((BASE_OBJECT *)psDroid, psDroid->originalBody, psDroid->resistance); /* 0x03 */ + objectWeaponTagged(psDroid->numWeaps, psDroid->turretRotation, psDroid->turretPitch, psDroid->asWeaps); + + /* DROID GROUP */ + + tagWriteEnter(0x0a, 1); + tagWrite(0x01, psDroid->droidType); + for (i = 0; i < DROID_MAXCOMP; i++) + { + v[i] = psDroid->asBits[i].nStat; + } + tagWrite16v(0x02, DROID_MAXCOMP, v); + // transporter droid in the mission list + if (psDroid->droidType == DROID_TRANSPORTER && apsDroidLists[plr] == mission.apsDroidLists[plr]) + { + tagWriteBool(0x03, true); + } + tagWrite(0x07, psDroid->weight); + tagWrite(0x08, psDroid->baseSpeed); + tagWriteString(0x09, psDroid->aName); + tagWrite(0x0a, psDroid->body); + tagWrite(0x0b, psDroid->numKills); + tagWrite(0x0c, psDroid->NameVersion); + tagWrite(0x0d, psDroid->currRayAng); + tagWriteLeave(0x0a); +} + +static void structureSaveTagged(STRUCTURE *psStruct) +{ + /* common groups */ + + objectSaveTagged((BASE_OBJECT *)psStruct); /* 0x01 */ + objectSensorTagged(psStruct->sensorRange, psStruct->sensorPower, 0, psStruct->ecmPower); /* 0x02 */ + objectStatTagged((BASE_OBJECT *)psStruct, psStruct->pStructureType->bodyPoints, psStruct->resistance); /* 0x03 */ + objectWeaponTagged(psStruct->numWeaps, psStruct->turretRotation, psStruct->turretPitch, psStruct->asWeaps); + + /* STRUCTURE GROUP */ + + tagWriteEnter(0x0b, 1); + tagWrites(0x01, psStruct->currentBuildPts); + tagWrites(0x02, psStruct->currentPowerAccrued); + tagWriteLeave(0x0b); +} + +static void featureSaveTagged(FEATURE *psFeat) +{ + /* common groups */ + + objectSaveTagged((BASE_OBJECT *)psFeat); /* 0x01 */ + objectStatTagged((BASE_OBJECT *)psFeat, psFeat->psStats->body, 0); /* 0x03 */ + + /* FEATURE GROUP */ + + tagWriteEnter(0x0c, 1); + tagWrite(0x01, psFeat->startTime); + tagWriteLeave(0x0c); +} + BOOL mapSaveTagged(char *pFileName) { MAPTILE *psTile; GATEWAY *psCurrGate; - int numGateways = 0, i = 0, x = 0, y = 0, plr; + int numGateways = 0, i = 0, x = 0, y = 0, plr, droids, structures, features; float cam[3]; const char *definition = "testdata/tagfile_map.def"; + DROID *psDroid; + FEATURE *psFeat; + STRUCTURE *psStruct; // find the number of non water gateways for (psCurrGate = gwGetGateways(); psCurrGate; psCurrGate = psCurrGate->psNext) @@ -608,7 +761,6 @@ BOOL mapSaveTagged(char *pFileName) RESEARCH *psResearch = asResearch; STRUCTURE_STATS *psStructStats = asStructureStats; FLAG_POSITION *psFlag; - STRUCTURE *psStruct; FLAG_POSITION *flagList[NUM_FLAG_TYPES * MAX_FACTORY]; tagWriteEnter(0x01, numResearch); // research group @@ -719,6 +871,37 @@ BOOL mapSaveTagged(char *pFileName) } tagWriteLeave(0x0e); + objCount(&droids, &structures, &features); + tagWriteEnter(0x0f, droids + structures + features); // object group + for (plr = 0; plr < MAX_PLAYERS; plr++) + { + for (psDroid = apsDroidLists[plr]; psDroid != NULL; psDroid = psDroid->psNext) + { + droidSaveTagged(psDroid); + tagWriteSeparator(); + if (psDroid->droidType == DROID_TRANSPORTER) + { + DROID *psTrans = psDroid->psGroup->psList; + for(psTrans = psTrans->psGrpNext; psTrans != NULL; psTrans = psTrans->psGrpNext) + { + droidSaveTagged(psTrans); + tagWriteSeparator(); + } + } + } + for (psStruct = apsStructLists[plr]; psStruct; psStruct = psStruct->psNext) + { + structureSaveTagged(psStruct); + tagWriteSeparator(); + } + } + for (psFeat = apsFeatureLists[0]; psFeat; psFeat = psFeat->psNext) + { + featureSaveTagged(psFeat); + tagWriteSeparator(); + } + tagWriteLeave(0x0f); + tagClose(); return TRUE; }