<commit_before>#include "stdafx.h"

#ifdef _DEBUG
	#include <vector>

	#include "d3d8types.hpp"
	#include <SADXModLoader/SADXFunctions.h>
#else
	#include <ModLoader/MemAccess.h>
#endif

#include <ninja.h>
#include "FixCharacterMaterials.h"

static HMODULE chrmodels_handle = nullptr;

inline int get_handle()
{
	if (chrmodels_handle != nullptr)
	{
		return (int)chrmodels_handle;
	}

	chrmodels_handle = GetModuleHandle(L"CHRMODELS_orig");
	if (chrmodels_handle == nullptr)
	{
		throw;
	}

	return (int)chrmodels_handle;
}

#ifdef _DEBUG
static std::vector<NJS_MATERIAL*> materials;

template<typename T = Uint32, size_t N>
static void models(NJS_MODEL_SADX* model, const T(&ids)[N])
{
	if (!model)
	{
		return;
	}

	if (model->nbMat != N)
	{
		return;
	}

	const auto& mats = model->mats;

	if (!mats)
	{
		return;
	}

	auto it = std::find(materials.begin(), materials.end(), mats);

	if (it != materials.end())
	{
		return;
	}

	for (int i = 0; i < N; i++)
	{
		if (mats[i].attr_texId != ids[i])
			return;
	}

	materials.push_back(mats);
	PrintDebug("HIT: 0x%08X\n", (int)mats - (int)chrmodels_handle);
}
template<typename T = Uint32, size_t N>
static void models(const std::string& id, int length, const T(&ids)[N])
{
	auto handle = (NJS_MODEL_SADX**)GetProcAddress(chrmodels_handle, ("___" + id + "_MODELS").c_str());
	if (!handle)
	{
		return;
	}

	for (int i = 0; i < length; i++)
	{
		models(handle[i], ids);
	}
}

template<typename T = Uint32, size_t N>
static void objects(NJS_OBJECT* object, const T(&ids)[N])
{
	if (!object)
	{
		return;
	}

	auto model = object->getbasicdxmodel();

	if (model)
	{
		models(model, ids);
	}

	if (object->child)
	{
		objects(object->child, ids);
	}

	if (object->sibling)
	{
		objects(object->sibling, ids);
	}
}
template<typename T = Uint32, size_t N>
static void objects(const std::string& id, int length, const T(&ids)[N])
{
	auto handle = (NJS_OBJECT**)GetProcAddress(chrmodels_handle, ("___" + id + "_OBJECTS").c_str());
	if (!handle)
	{
		return;
	}

	for (int i = 0; i < length; i++)
	{
		objects(handle[i], ids);
	}
}

template<typename T = Uint32, size_t N>
static void actions(NJS_ACTION* action, const T(&ids)[N])
{
	if (!action)
	{
		return;
	}

	auto object = action->object;
	objects(object, ids);
}
template<typename T = Uint32, size_t N>
static void actions(const std::string& id, int length, const T(&ids)[N])
{
	auto handle = (NJS_ACTION**)GetProcAddress(chrmodels_handle, ("___" + id + "_ACTIONS").c_str());
	if (!handle)
	{
		return;
	}

	for (int i = 0; i < length; i++)
	{
		actions(handle[i], ids);
	}
}
#endif

void FixCharacterMaterials()
{
	auto handle = get_handle();

#if _DEBUG
	int ids[] = { 2, 8, 8, 6, 1, 0 };
	actions("SONIC", 149, ids);
	objects("SONIC", 79, ids);
	models ("SONIC", 11, ids);
	materials.clear();
#endif
	
	// Sonic's nose
	DataArray_(NJS_MATERIAL, matlist_00565C68, (0x00565C68 + handle), 3);
	DataArray_(NJS_MATERIAL, matlist_0057636C, (0x0057636C + handle), 3);
	DataArray_(NJS_MATERIAL, matlist_0057D7BC, (0x0057D7BC + handle), 3);

	matlist_00565C68[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;
	matlist_0057636C[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;
	matlist_0057D7BC[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;

	// Super Sonic's jump ball
	DataArray_(NJS_MATERIAL, matlist_0062DEBC, (0x0062DEBC + handle), 1);
	matlist_0062DEBC[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;

	// Sonic's eyes (cutscenes)
	DataArray_(NJS_MATERIAL, matlist_0057BC78, (0x0057BC78 + handle), 6);
	matlist_0057BC78[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;

	// Sonic's jump ball
	DataArray_(NJS_MATERIAL, matlist_00579C94, (0x00579C94 + handle), 1);
	matlist_00579C94[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR; // object_0057BC44 Sonic's jump ball

	// Sonic's Crystal Ring
	DataArray_(NJS_MATERIAL, matlist_00582CF4, (0x00582CF4 + handle), 2);
	matlist_00582CF4[1].attrflags |= NJD_FLAG_IGNORE_LIGHT;    // object_00583284 Sonic's Crystal Ring
	
	// Tails' shoes (8 duplicates? Are you kidding me?):
	DataArray_(NJS_MATERIAL, matlist_00420290, (0x00420290 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_004208B8, (0x004208B8 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_004219F0, (0x004219F0 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_00422018, (0x00422018 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_0042D180, (0x0042D180 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_0042D7A8, (0x0042D7A8 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_0042E8E0, (0x0042E8E0 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_0042EF08, (0x0042EF08 + handle), 2);

	matlist_00420290[0].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_00420290[1].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_004208B8[0].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_004208B8[1].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_004219F0[0].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_004219F0[1].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_00422018[0].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;<commit_msg>Fixed Metal Sonic's jump ball.<commit_after>#include "stdafx.h"

#ifdef _DEBUG
	#include <vector>

	#include "d3d8types.hpp"
	#include <SADXModLoader/SADXFunctions.h>
#else
	#include <ModLoader/MemAccess.h>
#endif

#include <ninja.h>
#include "FixCharacterMaterials.h"

static HMODULE chrmodels_handle = nullptr;

inline int get_handle()
{
	if (chrmodels_handle != nullptr)
	{
		return (int)chrmodels_handle;
	}

	chrmodels_handle = GetModuleHandle(L"CHRMODELS_orig");
	if (chrmodels_handle == nullptr)
	{
		throw;
	}

	return (int)chrmodels_handle;
}

#ifdef _DEBUG
static std::vector<NJS_MATERIAL*> materials;

template<typename T = Uint32, size_t N>
static void models(NJS_MODEL_SADX* model, const T(&ids)[N])
{
	if (!model)
	{
		return;
	}

	if (model->nbMat != N)
	{
		return;
	}

	const auto& mats = model->mats;

	if (!mats)
	{
		return;
	}

	auto it = std::find(materials.begin(), materials.end(), mats);

	if (it != materials.end())
	{
		return;
	}

	for (int i = 0; i < N; i++)
	{
		if (mats[i].attr_texId != ids[i])
			return;
	}

	materials.push_back(mats);
	PrintDebug("HIT: 0x%08X\n", (int)mats - (int)chrmodels_handle);
}
template<typename T = Uint32, size_t N>
static void models(const std::string& id, int length, const T(&ids)[N])
{
	auto handle = (NJS_MODEL_SADX**)GetProcAddress(chrmodels_handle, ("___" + id + "_MODELS").c_str());
	if (!handle)
	{
		return;
	}

	for (int i = 0; i < length; i++)
	{
		models(handle[i], ids);
	}
}

template<typename T = Uint32, size_t N>
static void objects(NJS_OBJECT* object, const T(&ids)[N])
{
	if (!object)
	{
		return;
	}

	auto model = object->getbasicdxmodel();

	if (model)
	{
		models(model, ids);
	}

	if (object->child)
	{
		objects(object->child, ids);
	}

	if (object->sibling)
	{
		objects(object->sibling, ids);
	}
}
template<typename T = Uint32, size_t N>
static void objects(const std::string& id, int length, const T(&ids)[N])
{
	auto handle = (NJS_OBJECT**)GetProcAddress(chrmodels_handle, ("___" + id + "_OBJECTS").c_str());
	if (!handle)
	{
		return;
	}

	for (int i = 0; i < length; i++)
	{
		objects(handle[i], ids);
	}
}

template<typename T = Uint32, size_t N>
static void actions(NJS_ACTION* action, const T(&ids)[N])
{
	if (!action)
	{
		return;
	}

	auto object = action->object;
	objects(object, ids);
}
template<typename T = Uint32, size_t N>
static void actions(const std::string& id, int length, const T(&ids)[N])
{
	auto handle = (NJS_ACTION**)GetProcAddress(chrmodels_handle, ("___" + id + "_ACTIONS").c_str());
	if (!handle)
	{
		return;
	}

	for (int i = 0; i < length; i++)
	{
		actions(handle[i], ids);
	}
}
#endif

void FixCharacterMaterials()
{
	auto handle = get_handle();

#if _DEBUG
	int ids[] = { 2, 8, 8, 6, 1, 0 };
	actions("SONIC", 149, ids);
	objects("SONIC", 79, ids);
	models ("SONIC", 11, ids);
	materials.clear();
#endif
	
	// Sonic's nose
	DataArray_(NJS_MATERIAL, matlist_00565C68, (0x00565C68 + handle), 3);
	DataArray_(NJS_MATERIAL, matlist_0057636C, (0x0057636C + handle), 3);
	DataArray_(NJS_MATERIAL, matlist_0057D7BC, (0x0057D7BC + handle), 3);

	matlist_00565C68[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;
	matlist_0057636C[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;
	matlist_0057D7BC[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;

	// Sonic's eyes (cutscenes)
	DataArray_(NJS_MATERIAL, matlist_0057BC78, (0x0057BC78 + handle), 6);
	matlist_0057BC78[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;

	// Sonic's jump ball
	DataArray_(NJS_MATERIAL, matlist_00579C94, (0x00579C94 + handle), 1);
	matlist_00579C94[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR; // object_0057BC44 Sonic's jump ball

	// Sonic's Crystal Ring
	DataArray_(NJS_MATERIAL, matlist_00582CF4, (0x00582CF4 + handle), 2);
	matlist_00582CF4[1].attrflags |= NJD_FLAG_IGNORE_LIGHT;    // object_00583284 Sonic's Crystal Ring

	// Super Sonic's jump ball
	DataArray_(NJS_MATERIAL, matlist_0062DEBC, (0x0062DEBC + handle), 1);
	matlist_0062DEBC[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;

	// Metal Sonic's jump ball
	DataArray_(NJS_MATERIAL, matlist_0059C268, (0x0059C268 + handle), 1);
	matlist_0059C268[0].attrflags |= NJD_FLAG_IGNORE_SPECULAR;
	
	// Tails' shoes (8 duplicates? Are you kidding me?):
	DataArray_(NJS_MATERIAL, matlist_00420290, (0x00420290 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_004208B8, (0x004208B8 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_004219F0, (0x004219F0 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_00422018, (0x00422018 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_0042D180, (0x0042D180 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_0042D7A8, (0x0042D7A8 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_0042E8E0, (0x0042E8E0 + handle), 2);
	DataArray_(NJS_MATERIAL, matlist_0042EF08, (0x0042EF08 + handle), 2);

	matlist_00420290[0].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_00420290[1].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_004208B8[0].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_004208B8[1].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_004219F0[0].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_004219F0[1].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
	matlist_00422018[0].attrflags &= ~NJD_FLAG_IGNORE_SPECULAR;
{'fraction_non_alphanumeric': 0.1492360768851651, 'fraction_numerical': 0.07747658945293248, 'mean_word_length': 5.450095359186268, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3942776', 'n_tokens_mistral': 4849, 'n_tokens_neox': 4226, 'n_words': 806}