diff --git a/Ja2/SaveLoadGame.cpp b/Ja2/SaveLoadGame.cpp index 503fb74e..05e840b9 100644 --- a/Ja2/SaveLoadGame.cpp +++ b/Ja2/SaveLoadGame.cpp @@ -3028,15 +3028,24 @@ BOOLEAN StackedObjectData::Load( INT8** hBuffer, float dMajorMapVersion, UINT8 u { int size; - if (dMajorMapVersion >= 7 && ubMinorMapVersion >= MINOR_MAP_VERSION) + if (dMajorMapVersion >= 8 && ubMinorMapVersion >= MINOR_MAP_VERSION) + { + // Deal with Increased Team Sizes data + LOADDATA(&(this->data), *hBuffer, sizeof(ObjectData) ); + } + else if (dMajorMapVersion >= 7 && ubMinorMapVersion >= MINOR_MAP_VERSION) { // Flugente: changed this, otherwise game would crash when reading WF maps if class ObjectData was different. this is a rough fix and by no means perfect - LOADDATA(&(this->data), *hBuffer, sizeof(ObjectData) ); + ObjectData_PRE_ITS oldData{}; + LOADDATA(&(oldData), *hBuffer, sizeof(ObjectData_PRE_ITS)); + this->data = oldData; } else if (dMajorMapVersion >= 7 && ubMinorMapVersion >= MINOR_MAP_REPAIR_SYSTEM) { // sObjectFlag' size changed - LOADDATA(&(this->data), *hBuffer, sizeof(ObjectData) - sizeof(this->data.sObjectFlag) ); + ObjectData_PRE_ITS oldData; + LOADDATA(&(oldData), *hBuffer, sizeof(ObjectData_PRE_ITS) - sizeof(oldData.sObjectFlag)); + this->data = oldData; } // When saving maps with the new map editor that has weapon overheated feature included! else if (dMajorMapVersion >= 7 && ubMinorMapVersion >= MINOR_MAP_OVERHEATING) @@ -3047,14 +3056,18 @@ BOOLEAN StackedObjectData::Load( INT8** hBuffer, float dMajorMapVersion, UINT8 u // But of course, we now 'read' the values for sRepairThreshold, but there weren't any in older map versions, resulting in garbage values - we therefore set that manually to 100 // Of course, once the ObjectData-Class is altered, this has to be altered as well! //dnl ch74 241013 We cannot change past so hardcode 32 simply because that was sizeof(ObjectData) before current and all future changes ;-) - LOADDATA(&(this->data), *hBuffer, /*sizeof(ObjectData) - (sizeof(this->data.bDirtLevel) + sizeof(this->data.sObjectFlag) )*/32); + ObjectData_PRE_ITS oldData{}; + LOADDATA(&(oldData), *hBuffer, 32); + this->data = oldData; this->data.sRepairThreshold = 100; } else { // WF Maps have old format // +1 because we have to account for endOfPOD itself - LOADDATA(&(this->data), *hBuffer, SIZEOF_OBJECTDATA_POD+1 ); + ObjectData_PRE_ITS oldData{}; + LOADDATA(&(oldData), *hBuffer, SIZEOF_OBJECTDATA_POD_PRE_ITS + 1); + this->data = oldData; } LOADDATA(&size, *hBuffer, sizeof(int) ); diff --git a/Tactical/Item Types.cpp b/Tactical/Item Types.cpp index 218cfe91..30302d46 100644 --- a/Tactical/Item Types.cpp +++ b/Tactical/Item Types.cpp @@ -1179,6 +1179,34 @@ ObjectData& ObjectData::operator =(const ObjectData& src) return *this; } +ObjectData& ObjectData::operator =(const ObjectData_PRE_ITS& src) +{ + if ((void*)this != (void*)&src) + { + //copy over the data + this->bTrap = src.bTrap; + this->fUsed = src.fUsed; + this->ubImprintID = src.ubImprintID; + + this->bTemperature = src.bTemperature; + this->ubDirection = src.ubDirection; + this->ubWireNetworkFlag = src.ubWireNetworkFlag; + this->bDefuseFrequency = src.bDefuseFrequency; + this->sRepairThreshold = src.sRepairThreshold; + this->sObjectFlag = src.sObjectFlag; + + //copy over the union + this->misc.bBombStatus = src.misc.bBombStatus; + this->misc.bDetonatorType = src.misc.bDetonatorType; + this->misc.usBombItem = src.misc.usBombItem; + this->misc.bDelay = src.misc.bDelay; + this->misc.ubBombOwner = static_cast(src.misc.ubBombOwner); + this->misc.bActionValue = src.misc.bActionValue; + this->misc.ubTolerance = src.misc.ubTolerance; + } + return *this; +} + ObjectData::~ObjectData() { DeleteLBE(); diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index 34799f74..20b29a5f 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -390,6 +390,7 @@ public: UINT8 fUsed; // flags for whether the item is used or not }; + namespace ObjectDataStructs { struct OBJECT_GUN { @@ -439,8 +440,57 @@ namespace ObjectDataStructs { INT8 bLBE; // Marks item as LBENODE int uniqueID; // how the LBENODE is accessed }; + + // Used to maintain compatibility with major map versions older than 8.0 + struct OBJECT_BOMBS_AND_OTHER_PRE_ITS + { + INT16 bBombStatus; + INT8 bDetonatorType; + UINT16 usBombItem; + union + { + INT8 bDelay; + INT8 bFrequency; + }; + UINT8 ubBombOwner; //<-- Data size changed + UINT8 bActionValue; + union + { + UINT8 ubTolerance; + UINT8 ubLocationID; + }; + }; }; + +struct ObjectData_PRE_ITS +{ + union { + INT16 objectStatus;//holds the same value as bStatus[0] + UINT16 ubShotsLeft;//holds the same value as ubShotsLeft[0] + ObjectDataStructs::OBJECT_GUN gun; + ObjectDataStructs::OBJECT_MONEY money; + ObjectDataStructs::OBJECT_BOMBS_AND_OTHER_PRE_ITS misc; + ObjectDataStructs::OBJECT_KEY key; + ObjectDataStructs::OBJECT_OWNER owner; + ObjectDataStructs::OBJECT_LBE lbe; + }; + INT8 bTrap; // 1-10 exp_lvl to detect + UINT8 fUsed; // flags for whether the item is used or not + UINT8 ubImprintID; // ID of merc that item is imprinted on + char endOfPOD; // For WF maps + FLOAT bTemperature; // Flugente FTW 1.2: temperature of gun + UINT8 ubDirection; // direction the bomb faces (for directional explosives) + UINT32 ubWireNetworkFlag; // flags for the tripwire network + INT8 bDefuseFrequency; // frequency for defusing, >=0 values used only + INT16 sRepairThreshold; // repair only possible up to this value + FLOAT bFiller; // unused for now + UINT64 sObjectFlag; // used to notify of various states that apply to this object, but not the item in general +}; +// Flugente: needed for reading WF maps +#define SIZEOF_OBJECTDATA_POD_PRE_ITS (offsetof(ObjectData_PRE_ITS, endOfPOD)) + + class ObjectData { public: @@ -451,6 +501,8 @@ public: ObjectData(const ObjectData&); // Assignment operator ObjectData& operator=(const ObjectData&); + // Conversion operator + ObjectData& operator=(const ObjectData_PRE_ITS&); void initialize() {memset(this, 0, sizeof(ObjectData));}; @@ -474,7 +526,7 @@ public: UINT8 fUsed; // flags for whether the item is used or not UINT8 ubImprintID; // ID of merc that item is imprinted on - // Flugente: due do inconsistencies with WF maps, where data from a map is laoded differently, I had to add this marker. + // Flugente: due do inconsistencies with WF maps, where data from a map is loaded differently, I had to add this marker. // New values, like bTemperature, have to come after this. And please, don't destroy ObjectData's POD-ness. char endOfPOD;