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
master
Per Inge Mathisen 2007-11-10 20:28:28 +00:00
parent f50b4d11dd
commit 6e163d9003
2 changed files with 250 additions and 3 deletions

View File

@ -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 -

187
src/map.c
View File

@ -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;
}