summaryrefslogtreecommitdiff
path: root/ZAPD/ZActorList.cpp
diff options
context:
space:
mode:
authorlouist103 <louist103@gmail.com>2022-10-25 10:47:22 -0400
committerlouist103 <louist103@gmail.com>2022-10-25 10:47:22 -0400
commit0293bafafe118dde1a238ea2546940302eb1baa9 (patch)
treeb862a47fde8857bc0460daa349b2775368d86d72 /ZAPD/ZActorList.cpp
parent78fdac56498f674eba2692e075d415a12cb4a31f (diff)
ActorList file node.
Diffstat (limited to 'ZAPD/ZActorList.cpp')
-rw-r--r--ZAPD/ZActorList.cpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/ZAPD/ZActorList.cpp b/ZAPD/ZActorList.cpp
new file mode 100644
index 0000000..ee5cb4d
--- /dev/null
+++ b/ZAPD/ZActorList.cpp
@@ -0,0 +1,194 @@
+#include "ZActorList.h"
+
+#include "Globals.h"
+#include "Utils/BitConverter.h"
+#include "WarningHandler.h"
+#include "ZFile.h"
+#include "ZRoom/ZNames.h"
+
+REGISTER_ZFILENODE(ActorList, ZActorList);
+
+ZActorList::ZActorList(ZFile* nParent) : ZResource(nParent)
+{
+ RegisterRequiredAttribute("Count");
+}
+
+void ZActorList::ExtractFromBinary(uint32_t nRawDataIndex, uint8_t nNumActors)
+{
+ rawDataIndex = nRawDataIndex;
+ numActors = nNumActors;
+
+ // Don't parse raw data of external files
+ if (parent->GetMode() == ZFileMode::ExternalFile)
+ return;
+
+ ParseRawData();
+}
+
+void ZActorList::ParseXML(tinyxml2::XMLElement* reader)
+{
+ ZResource::ParseXML(reader);
+
+ numActors = StringHelper::StrToL(registeredAttributes.at("Count").value);
+
+ if (numActors < 1)
+ {
+ HANDLE_ERROR_RESOURCE(
+ WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
+ StringHelper::Sprintf("invalid value '%d' found for 'NumPaths' attribute", numActors),
+ "Should be at least '1'");
+ }
+}
+
+void ZActorList::ParseRawData()
+{
+ ZResource::ParseRawData();
+
+ offset_t currentPtr = rawDataIndex;
+ size_t largestlength = 0;
+
+ for (size_t i = 0; i < numActors; i++)
+ {
+ ActorSpawnEntry entry(parent->GetRawData(), currentPtr);
+
+ currentPtr += entry.GetRawDataSize();
+ actors.push_back(entry);
+
+ size_t actorNameLength = ZNames::GetActorName(entry.GetActorId()).size();
+ if (actorNameLength > largestlength)
+ largestlength = actorNameLength;
+ }
+
+ for (auto& entry : actors)
+ {
+ entry.SetLargestActorName(largestlength);
+ }
+}
+
+Declaration* ZActorList::DeclareVar(const std::string& prefix, const std::string& bodyStr)
+{
+ std::string auxName = name;
+
+ if (name == "")
+ auxName = GetDefaultName(prefix);
+
+ Declaration* decl =
+ parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(),
+ GetSourceTypeName(), name, GetActorListArraySize(), bodyStr);
+ decl->staticConf = staticConf;
+
+ return decl;
+}
+
+std::string ZActorList::GetBodySourceCode() const
+{
+ std::string declaration;
+
+ size_t index = 0;
+ for (auto& entry : actors)
+ {
+ declaration += StringHelper::Sprintf("\t{ %s },", entry.GetBodySourceCode().c_str());
+
+ if (index < actors.size() - 1)
+ declaration += "\n";
+
+ index++;
+ }
+
+ return declaration;
+}
+
+std::string ZActorList::GetSourceTypeName() const
+{
+ return actors.front().GetSourceTypeName();
+}
+
+ZResourceType ZActorList::GetResourceType() const
+{
+ return ZResourceType::ActorList;
+}
+
+size_t ZActorList::GetRawDataSize() const
+{
+ return actors.size() * actors.front().GetRawDataSize();
+}
+
+size_t ZActorList::GetActorListArraySize() const
+{
+ size_t actorCount = 0;
+
+ // Doing an else-if here so we only do the loop when the game is SW97.
+ // Actor 0x22 is removed from SW97, so we need to ensure that we don't increment the actor count
+ // for it.
+ if (Globals::Instance->game == ZGame::OOT_SW97)
+ {
+ actorCount = 0;
+
+ for (const auto& entry : actors)
+ if (entry.GetActorId() != 0x22)
+ actorCount++;
+ }
+ else
+ {
+ actorCount = actors.size();
+ }
+
+ return actorCount;
+}
+
+/* ActorSpawnEntry */
+
+ActorSpawnEntry::ActorSpawnEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
+{
+ actorNum = BitConverter::ToInt16BE(rawData, rawDataIndex + 0);
+ posX = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
+ posY = BitConverter::ToInt16BE(rawData, rawDataIndex + 4);
+ posZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 6);
+ rotX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 8);
+ rotY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 10);
+ rotZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 12);
+ params = BitConverter::ToInt16BE(rawData, rawDataIndex + 14);
+}
+
+std::string ActorSpawnEntry::GetBodySourceCode() const
+{
+ std::string body;
+
+ std::string actorNameFmt = StringHelper::Sprintf("%%-%zus ", largestActorName + 1);
+ body =
+ StringHelper::Sprintf(actorNameFmt.c_str(), (ZNames::GetActorName(actorNum) + ",").c_str());
+
+ body += StringHelper::Sprintf("{ %6i, %6i, %6i }, ", posX, posY, posZ);
+ if (Globals::Instance->game == ZGame::MM_RETAIL)
+ body += StringHelper::Sprintf("{ SPAWN_ROT_FLAGS(%#5hX, 0x%04X)"
+ ", SPAWN_ROT_FLAGS(%#5hX, 0x%04X)"
+ ", SPAWN_ROT_FLAGS(%#5hX, 0x%04X) }, ",
+ (rotX >> 7) & 0b111111111, rotX & 0b1111111,
+ (rotY >> 7) & 0b111111111, rotY & 0b1111111,
+ (rotZ >> 7) & 0b111111111, rotZ & 0b1111111);
+ else
+ body += StringHelper::Sprintf("{ %#6hX, %#6hX, %#6hX }, ", rotX, rotY, rotZ);
+ body += StringHelper::Sprintf("0x%04X", params);
+
+ return body;
+}
+
+std::string ActorSpawnEntry::GetSourceTypeName() const
+{
+ return "ActorEntry";
+}
+
+size_t ActorSpawnEntry::GetRawDataSize() const
+{
+ return 16;
+}
+
+uint16_t ActorSpawnEntry::GetActorId() const
+{
+ return actorNum;
+}
+
+void ActorSpawnEntry::SetLargestActorName(size_t nameSize)
+{
+ largestActorName = nameSize;
+}