Created
February 1, 2020 05:34
-
-
Save SnowyMouse/4860792940132174ad4a8d6801182498 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
custom-colors-unfuckerupper - Fixes change colors on object tags when | |
improperly extracted using older versions of Invader or the current stable | |
version of Refinery. | |
Copyright (c) Kavawuvi | |
This tool is licensed strictly under the GNU General Public License version | |
3. Read https://www.gnu.org/licenses/gpl-3.0.en.html for more information. | |
*/ | |
#include <invader/tag/parser/parser.hpp> | |
#include <invader/file/file.hpp> | |
#include <invader/tag/hek/header.hpp> | |
#include <invader/printf.hpp> | |
template<typename T> T fix_meme_shit(const std::byte *what, std::size_t size, bool &necessary) { | |
auto x = T::parse_hek_tag_file(what, size); | |
necessary = false; | |
for(Invader::Parser::ObjectChangeColors &c : x.change_colors) { | |
// Obviously this only affects tags with multiple permutations | |
if(c.permutations.size() <= 1) { | |
continue; | |
} | |
float current_weight = 0.0F; | |
// See if we can detect it (each iteration is greater than or equal to the last, and it ends at 1.0) | |
// NOTE: This CAN detect tags that are specifically set like this, but it is unlikely and never occurs on Bungie tags, at least | |
for(auto &ccp : c.permutations) { | |
if(ccp.weight <= current_weight) { | |
current_weight = 0.0F; | |
break; | |
} | |
current_weight = ccp.weight; | |
} | |
if(current_weight != 1.0F) { | |
continue; | |
} | |
necessary = true; | |
// Fix it | |
double progress = 0.0; | |
for(auto &p : c.permutations) { | |
double difference = p.weight - progress; | |
progress = p.weight; | |
p.weight = static_cast<float>(difference); | |
} | |
} | |
return x; | |
} | |
int main(int argc, char **argv) { | |
if(argc != 3) { | |
NOPE: | |
eprintf("Usage: %s <r|w> <tag>\n", argv[0]); | |
return 1; | |
} | |
bool read_only; | |
switch(argv[1][0]) { | |
case 'r': | |
read_only = true; | |
break; | |
case 'w': | |
read_only = false; | |
break; | |
default: | |
goto NOPE; | |
} | |
try { | |
auto file = Invader::File::open_file(argv[2]).value(); | |
auto *header = reinterpret_cast<Invader::HEK::TagFileHeader *>(file.data()); | |
Invader::HEK::TagFileHeader::validate_header(header, file.size()); | |
std::vector<std::byte> final_result; | |
bool necessary; | |
#define FIX_MEME_SHIT(classname, class_int) case Invader::HEK::TagClassInt::class_int: { \ | |
final_result = fix_meme_shit<Invader::Parser::classname>(file.data(), file.size(), necessary).generate_hek_tag_data(Invader::HEK::TagClassInt::class_int); \ | |
break; \ | |
} | |
switch(header->tag_class_int) { | |
FIX_MEME_SHIT(Biped, TAG_CLASS_BIPED) | |
FIX_MEME_SHIT(DeviceControl, TAG_CLASS_DEVICE_CONTROL) | |
FIX_MEME_SHIT(Device, TAG_CLASS_DEVICE) | |
FIX_MEME_SHIT(Equipment, TAG_CLASS_EQUIPMENT) | |
FIX_MEME_SHIT(Garbage, TAG_CLASS_GARBAGE) | |
FIX_MEME_SHIT(Item, TAG_CLASS_ITEM) | |
FIX_MEME_SHIT(DeviceLightFixture, TAG_CLASS_DEVICE_LIGHT_FIXTURE) | |
FIX_MEME_SHIT(DeviceMachine, TAG_CLASS_DEVICE_MACHINE) | |
FIX_MEME_SHIT(Object, TAG_CLASS_OBJECT) | |
FIX_MEME_SHIT(Scenery, TAG_CLASS_SCENERY) | |
FIX_MEME_SHIT(Placeholder, TAG_CLASS_PLACEHOLDER) | |
FIX_MEME_SHIT(Unit, TAG_CLASS_UNIT) | |
FIX_MEME_SHIT(Vehicle, TAG_CLASS_VEHICLE) | |
FIX_MEME_SHIT(Weapon, TAG_CLASS_WEAPON) | |
FIX_MEME_SHIT(SoundScenery, TAG_CLASS_SOUND_SCENERY) | |
default: | |
return 2; | |
} | |
if(!necessary) { | |
return 3; | |
} | |
oprintf("%s\n", argv[2]); | |
if(!read_only) { | |
if(!Invader::File::save_file(argv[2], final_result)) { | |
eprintf_error("Failed to write %s\n", argv[2]); | |
} | |
} | |
return 0; | |
} | |
catch(std::exception &e) { | |
eprintf_error("Failed to fix %s: %s", argv[2], e.what()); | |
return 1; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment