diff --git a/include/ArmorAddonOverrideService.h b/include/ArmorAddonOverrideService.h index 64024f1..0557ded 100644 --- a/include/ArmorAddonOverrideService.h +++ b/include/ArmorAddonOverrideService.h @@ -40,7 +40,7 @@ class ArmorAddonOverrideService { public: typedef Outfit Outfit; static constexpr UInt32 signature = 'AAOS'; - enum { kSaveVersionV1 = 1, kSaveVersionV2 = 2 }; + enum { kSaveVersionV1 = 1, kSaveVersionV2 = 2, kSaveVersionV3 = 3 }; // static constexpr UInt32 ce_outfitNameMaxLength = 256; // SKSE caps serialized std::strings and const char*s to 256 bytes. // diff --git a/src/ArmorAddonOverrideService.cpp b/src/ArmorAddonOverrideService.cpp index 3e64501..1198054 100644 --- a/src/ArmorAddonOverrideService.cpp +++ b/src/ArmorAddonOverrideService.cpp @@ -278,6 +278,32 @@ void ArmorAddonOverrideService::load(SKSESerializationInterface* intfc, UInt32 v outfit.load(intfc, version); } this->setOutfit(selectedOutfitName.c_str()); + if (version >= ArmorAddonOverrideService::kSaveVersionV3) { + _assertWrite(ReadData(intfc, &this->locationBasedAutoSwitchEnabled), "Failed to read the autoswitch enable state."); + UInt32 autoswitchSize = this->locationOutfits.size(); + _assertRead(ReadData(intfc, &autoswitchSize), "Failed to read the number of autoswitch slots."); + for (UInt32 i = 0; i < autoswitchSize; i++) { + // get location outfit + // + // we can't call WriteData directly on this->currentOutfitName because it's + // a cobb::istring, and SKSE only templated WriteData for std::string in + // specific; other basic_string classes break it. + // + LocationType autoswitchSlot; + _assertRead(ReadData(intfc, &autoswitchSlot), "Failed to read the an autoswitch slot ID."); + UInt32 locationOutfitNameSize = 0; + char locationOutfitName[257]; + memset(locationOutfitName, '\0', sizeof(locationOutfitName)); + _assertRead(ReadData(intfc, &locationOutfitNameSize), "Failed to read the an autoswitch outfit name."); + _assertRead(locationOutfitNameSize < 257, "The autoswitch outfit name is too long."); + if (locationOutfitNameSize) { + _assertRead(intfc->ReadRecordData(locationOutfitName, locationOutfitNameSize), "Failed to read the selected outfit name."); + this->locationOutfits.emplace(autoswitchSlot, locationOutfitName); + } + } + } else { + this->locationOutfits = std::map(); + } } void ArmorAddonOverrideService::save(SKSESerializationInterface* intfc) { using namespace Serialization; @@ -303,6 +329,18 @@ void ArmorAddonOverrideService::save(SKSESerializationInterface* intfc) { auto& outfit = it->second; outfit.save(intfc); } + _assertWrite(WriteData(intfc, &this->locationBasedAutoSwitchEnabled), "Failed to write the autoswitch enable state."); + UInt32 autoswitchSize = this->locationOutfits.size(); + _assertWrite(WriteData(intfc, &autoswitchSize), "Failed to write the autoswitch count."); + for (auto it = this->locationOutfits.cbegin(); it != this->locationOutfits.cend(); ++it) { + auto& locationId = it->first; + _assertWrite(WriteData(intfc, &locationId), "Failed to write a location ID."); + // + UInt32 outfitNameSize = it->second.size(); + const char* outfitName = it->second.c_str(); + _assertWrite(WriteData(intfc, &outfitNameSize), "Failed to write autoswitch location outfit name."); + _assertWrite(intfc->WriteRecordData(outfitName, outfitNameSize), "Failed to write autoswitch location outfit name."); + } } // void ArmorAddonOverrideService::dump() const { diff --git a/src/OutfitSystem.cpp b/src/OutfitSystem.cpp index fe0b05c..704b906 100644 --- a/src/OutfitSystem.cpp +++ b/src/OutfitSystem.cpp @@ -615,9 +615,11 @@ type = LocationType::World; } + /* char message[100]; sprintf_s(message, "SOS: This location is a %s.", type_str.c_str()); RE::DebugNotification(message, nullptr, false); + */ auto& service = ArmorAddonOverrideService::GetInstance(); service.setOutfitUsingLocation(type); diff --git a/src/main.cpp b/src/main.cpp index 0f1b287..5882a84 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -147,7 +147,7 @@ void Callback_Messaging_SKSE(SKSEMessagingInterface::Message* message) { void Callback_Serialization_Save(SKSESerializationInterface* intfc) { _MESSAGE("Writing savedata..."); // - if (intfc->OpenRecord(ArmorAddonOverrideService::signature, ArmorAddonOverrideService::kSaveVersionV2)) { + if (intfc->OpenRecord(ArmorAddonOverrideService::signature, ArmorAddonOverrideService::kSaveVersionV3)) { try { auto& service = ArmorAddonOverrideService::GetInstance(); service.save(intfc);