#pragma once #include #include #include #include #include struct GcUvCell { uint16_t x = 0; uint16_t y = 0; uint16_t width = 0; uint16_t height = 0; }; struct GcEffectSprite { uint16_t uvRecord = 0; int frame = 0; glm::vec3 offsetPixels{0.0f}; glm::vec4 color{1.0f}; glm::vec2 scale{1.0f}; float rotationDegrees = 0.0f; }; // Interpreter for the sprite subset of the original common effect format. // It follows game471 FUN_005f2030/FUN_005f2250/FUN_005f23f0 and is enough to // reproduce control-helper effects 61..69, including parent rotation nodes. class GcTargetEffectBank { public: bool load(const std::string& efcPath, const std::string& uvPath, std::string* error = nullptr); int lifetime(int effectId) const; std::vector evaluate(int effectId, float tick, int uvRecordBase = 0) const; const GcUvCell* uvCell(uint16_t record, int frame) const; int uvTexture(uint16_t record) const; private: struct Key { uint16_t time = 0; uint8_t interpolation = 0; std::vector values; }; struct Track { uint16_t loopStart = 0; uint16_t loopEnd = 0; std::vector keys; }; struct Child { uint8_t type = 0; uint16_t reference = 0xffff; bool inheritParent = false; std::array tracks; }; struct Effect { uint16_t lifetime = 0; std::vector children; }; struct UvRecord { int16_t textureIndex = -1; std::vector cells; }; static std::vector sampleTrack(const Track& track, float tick, bool* started); std::vector effects_; std::vector uvRecords_; };