diff --git a/xlive/Blam/Engine/Simulation/game_interface/simulation_game_objects.cpp b/xlive/Blam/Engine/Simulation/game_interface/simulation_game_objects.cpp index 73a79df83..f1951483e 100644 --- a/xlive/Blam/Engine/Simulation/game_interface/simulation_game_objects.cpp +++ b/xlive/Blam/Engine/Simulation/game_interface/simulation_game_objects.cpp @@ -95,6 +95,7 @@ bool __stdcall c_simulation_object_entity_definition__object_setup_placement_dat *flags &= ~FLAG(5); } + // Set variant of the object if (object_creation_data->model_variant_id != NONE && object_creation_data->object_definition_index != NONE) { object_definition* object_def = (object_definition*)tag_get_fast(object_creation_data->object_definition_index); @@ -103,7 +104,6 @@ bool __stdcall c_simulation_object_entity_definition__object_setup_placement_dat s_model_group_definition* model_def = (s_model_group_definition*)tag_get_fast(object_def->model.TagIndex); if (object_creation_data->model_variant_id < model_def->variants.size) { - LOG_INFO_FUNC("Model variant id: {}", object_creation_data->model_variant_id); placement_data->variant_name = model_def->variants[object_creation_data->model_variant_id]->name; } } @@ -133,15 +133,15 @@ datum __fastcall c_simulation_object_entity_definition__object_create_object(voi void simulation_game_objects_apply_patches(void) { DetourClassFunc(Memory::GetAddress(0x1F27D1, 0x1DD86A), (uint8*)c_simulation_object_entity_definition__object_creation_required_bits, 8); - DetourClassFunc(Memory::GetAddress(0x1F24ED, 0x1DD586), (uint8*)c_simulation_object_entity_definition__object_build_creation_data, 6); - DetourClassFunc(Memory::GetAddress(0x1F2704, 0x1DD79D), (uint8*)c_simulation_object_entity_definition__object_setup_placement_data, 20); + DetourClassFunc(Memory::GetAddress(0x1F24ED, 0x1DD586), (uint8*)c_simulation_object_entity_definition__object_build_creation_data, 9); + DetourClassFunc(Memory::GetAddress(0x1F2704, 0x1DD79D), (uint8*)c_simulation_object_entity_definition__object_setup_placement_data, 10); p_c_simulation_unit_entity_definition_encode = (c_simulation_unit_entity_definition_creation_encode_t)DetourClassFunc( Memory::GetAddress(0x1F3B11, 0x1DEBAA), (uint8*)c_simulation_object_entity_definition__object_creation_encode, - 20); + 8); p_c_simulation_unit_entity_definition_decode = (c_simulation_unit_entity_definition_creation_decode_t)DetourClassFunc( Memory::GetAddress(0x1F3BDD, 0x1DEC76), (uint8*)c_simulation_object_entity_definition__object_creation_decode, - 16); + 10); return; } \ No newline at end of file diff --git a/xlive/Blam/Engine/Simulation/game_interface/simulation_game_units.cpp b/xlive/Blam/Engine/Simulation/game_interface/simulation_game_units.cpp index 99bcf890a..13757926a 100644 --- a/xlive/Blam/Engine/Simulation/game_interface/simulation_game_units.cpp +++ b/xlive/Blam/Engine/Simulation/game_interface/simulation_game_units.cpp @@ -3,6 +3,7 @@ #include "simulation_game_objects.h" +#include "Blam/Engine/game/game_globals.h" #include "Blam/Engine/game/game_engine.h" #include "Blam/Engine/math/color_math.h" #include "Blam/Engine/units/units.h" @@ -16,13 +17,25 @@ datum __stdcall c_simulation_unit_entity_definition__create_object(void* _this, int32 internal_state_data_size, s_simulation_unit_state_data* initial_state_data) { - real_color_rgb change_colors[4]; // [esp+18h] [ebp-F8h] BYREF + real_color_rgb change_colors[4]; object_placement_data placement_data; object_placement_data_new(&placement_data, creation_data->object.object_definition_index, -1, 0); + + // Hacky hack for player variants + // TODO Remove this once we get tag injection working on servers + if (initial_state_data->controlling_player_index != NONE) + { + if (datum unit_rep_tag_index = game_globals_get_representation(creation_data->profile_traits.profile.player_character_type)->third_person_unit.TagIndex; + unit_rep_tag_index != NONE) + { + placement_data.tag_index = unit_rep_tag_index; + creation_data->object.object_definition_index = unit_rep_tag_index; + } + } c_simulation_object_entity_definition__object_setup_placement_data(_this, &creation_data->object, &initial_state_data->object_state_data, flags, &placement_data); - // Check if the unit is controlled by a player and change color is available before we override it + // Check if the unit is controlled by a player and override change color if (initial_state_data->controlling_player_index != NONE && game_engine_get_change_colors(&creation_data->profile_traits.profile, creation_data->team, change_colors)) { placement_data.active_change_colors_mask |= 15u; diff --git a/xlive/Blam/Engine/cseries/cseries_errors.cpp b/xlive/Blam/Engine/cseries/cseries_errors.cpp index 529bb8bfb..7c014db69 100644 --- a/xlive/Blam/Engine/cseries/cseries_errors.cpp +++ b/xlive/Blam/Engine/cseries/cseries_errors.cpp @@ -263,7 +263,7 @@ void setup_game_options_text(const wchar_t* reports_path) print_bool_to_file(file, game_options->scenario_custom); fwprintf(file, L"Game Tick Rate: "); - print_bool_to_file(file, game_options->game_tick_rate); + fwprintf(file, L"%d\n", game_options->game_tick_rate); fwprintf(file, L"Random Data: "); print_array_to_file(file, game_options->random_data, 8); diff --git a/xlive/Blam/Engine/game/game_globals.cpp b/xlive/Blam/Engine/game/game_globals.cpp index 9733a97c7..f6a237244 100644 --- a/xlive/Blam/Engine/game/game_globals.cpp +++ b/xlive/Blam/Engine/game/game_globals.cpp @@ -1,6 +1,49 @@ #include "stdafx.h" #include "game_globals.h" +#include "Blam/Cache/TagGroups/model_definition.hpp" +#include "Blam/Cache/TagGroups/unit_definition.hpp" + +#include "Blam/Engine/scenario/scenario.h" +#include "Blam/Engine/tag_files/global_string_ids.h" +#include "Blam/Engine/cache/cache_files.h" + +#include "H2MOD/Modules/Shell/Config.h" +#include "H2MOD/Modules/SpecialEvents/SpecialEvents.h" +#include "H2MOD/Tags/MetaExtender.h" +#include "H2MOD/Tags/MetaLoader/tag_loader.h" +#include "H2MOD/Tags/TagInterface.h" + +/** + * \brief Adds a new player representation to the globals tag block + * \param fp_hands the datum index of the first person hands render model + * \param fp_body the datum index of the first person body render model + * \param tp_biped the datum index of the third person biped + * \param variant the string_id of the variant + * \return returns a pointer to the new representation +*/ +s_game_globals_player_representation* add_representation(datum fp_hands, datum fp_body, datum tp_biped, string_id variant = NONE); + +/** + * \brief Clones an existing player_representation + * \param original_type: index of the representation to clone + * \return returns a pointer to the new representation + */ +s_game_globals_player_representation* clone_representation(e_character_type original_type); + +// Loops through every representation and makes sure the base bipeds aren't null. +// If it's the case then set it to masterchief_mp +// This is an issue on maps that use custom shared and leave these representations null +void game_globals_fixup_representation(void); + +void game_globals_add_skeleton_representation(scenario* scenario_definition); +void game_globals_add_flood_representation(scenario* scenario_definition); +void game_globals_add_lmao_representation(void); + +// Adds new representations to the globals tag +void game_globals_add_new_player_representations(void); + + s_game_globals* scenario_get_game_globals(void) { return *Memory::GetAddress(0x479E70, 0x4A642C); @@ -16,3 +59,221 @@ s_ui_levels_definition* game_globals_get_ui_levels(void) return NULL; } + +s_game_globals_player_representation* game_globals_get_representation(e_character_type type) +{ + return scenario_get_game_globals()->player_representation[type]; +} + + +s_game_globals_player_representation* add_representation(datum fp_hands, datum fp_body, datum tp_biped, string_id variant) +{ + s_game_globals* globals = scenario_get_game_globals(); + + auto new_rep = MetaExtender::add_tag_block2((unsigned long)std::addressof(globals->player_representation)); + if (fp_hands != NONE) + { + new_rep->first_person_hands.TagGroup = blam_tag::tag_group_type::rendermodel; + new_rep->first_person_hands.TagIndex = fp_hands; + } + else + { + new_rep->first_person_hands = globals->player_representation[_character_type_spartan]->first_person_hands; + } + + if (fp_body != NONE) + { + new_rep->first_person_body.TagGroup = blam_tag::tag_group_type::rendermodel; + new_rep->first_person_body.TagIndex = fp_body; + } + else + new_rep->first_person_body = globals->player_representation[_character_type_spartan]->first_person_body; + + if (tp_biped != NONE) + { + new_rep->third_person_unit.TagGroup = blam_tag::tag_group_type::biped; + new_rep->third_person_unit.TagIndex = tp_biped; + } + else + { + new_rep->third_person_unit = globals->player_representation[_character_type_spartan]->third_person_unit; + } + + if (variant != NONE) + { + new_rep->third_person_variant = variant; + } + + return new_rep; +} + +s_game_globals_player_representation* clone_representation(e_character_type original_type) +{ + s_game_globals* globals = scenario_get_game_globals(); + s_game_globals_player_representation* original_rep = globals->player_representation[original_type]; + s_game_globals_player_representation* new_rep = MetaExtender::add_tag_block2((unsigned long)std::addressof(globals->player_representation)); + new_rep->first_person_body = original_rep->first_person_body; + new_rep->first_person_hands = original_rep->first_person_hands; + new_rep->third_person_unit = original_rep->third_person_unit; + new_rep->third_person_variant = original_rep->third_person_variant; + return new_rep; +} + +void game_globals_fixup_representation(void) +{ + s_game_globals* globals = scenario_get_game_globals(); + + for (uint32 i = 0; i < globals->player_representation.size; ++i) + { + s_game_globals_player_representation* representation = globals->player_representation[i]; + if (representation->third_person_unit.TagIndex == NONE) + { + representation->third_person_unit = globals->player_representation[_character_type_spartan]->third_person_unit; + } + + if (representation->first_person_body.TagIndex == NONE) + { + representation->first_person_body = globals->player_representation[_character_type_spartan]->first_person_body; + } + + if (representation->first_person_hands.TagIndex == NONE) + { + representation->first_person_hands = globals->player_representation[_character_type_spartan]->first_person_hands; + } + } + return; +} + +void game_globals_add_skeleton_representation(scenario* scenario_definition) +{ + // Add skeleton + datum skele_datum = tag_loader::Get_tag_datum("objects\\characters\\masterchief_skeleton\\masterchief_skeleton", blam_tag::tag_group_type::biped, "carto_shared"); + datum skele_fp_datum = tag_loader::Get_tag_datum("objects\\characters\\masterchief_skeleton\\fp\\fp", blam_tag::tag_group_type::rendermodel, "carto_shared"); + datum skele_body_datum = tag_loader::Get_tag_datum("objects\\characters\\masterchief_skeleton\\fp_body\\fp_body", blam_tag::tag_group_type::rendermodel, "carto_shared"); + + if (skele_datum != NONE && skele_fp_datum != NONE && skele_body_datum != NONE && get_current_special_event() == _special_event_halloween && !H2Config_no_events) + { + tag_loader::Load_tag(skele_fp_datum, true, "carto_shared"); + tag_loader::Load_tag(skele_body_datum, true, "carto_shared"); + tag_loader::Load_tag(skele_datum, true, "carto_shared"); + tag_loader::Push_Back(); + datum skele_new_datum = tag_loader::ResolveNewDatum(skele_datum); + add_representation(tag_loader::ResolveNewDatum(skele_fp_datum), tag_loader::ResolveNewDatum(skele_body_datum), skele_new_datum, _character_type_skeleton); + s_scenario_simulation_definition_table_element* new_def = MetaExtender::add_tag_block2((unsigned long)std::addressof(scenario_definition->simulation_definition_table)); + new_def->tag_datum = skele_new_datum; + } + else + { + clone_representation(_character_type_spartan); + } + return; +} + +void game_globals_add_flood_representation(scenario* scenario_definition) +{ + datum flood_datum = tag_loader::Get_tag_datum("objects\\characters\\floodcombat_elite\\floodcombat_elite_mp", blam_tag::tag_group_type::biped, "carto_shared"); + datum flood_arms_datum = tag_loader::Get_tag_datum("objects\\characters\\flood_mp\\fp_arms\\fp_arms", blam_tag::tag_group_type::rendermodel, "carto_shared"); + datum flood_body_datum = tag_loader::Get_tag_datum("objects\\characters\\flood_mp\\fp_body\\fp_body", blam_tag::tag_group_type::rendermodel, "carto_shared"); + if (flood_datum != NONE && flood_arms_datum != NONE && flood_body_datum != NONE) + { + tag_loader::Load_tag(flood_datum, true, "carto_shared"); + tag_loader::Load_tag(flood_arms_datum, true, "carto_shared"); + tag_loader::Load_tag(flood_body_datum, true, "carto_shared"); + tag_loader::Push_Back(); + add_representation(tag_loader::ResolveNewDatum(flood_arms_datum), tag_loader::ResolveNewDatum(flood_body_datum), tag_loader::ResolveNewDatum(flood_datum), _character_type_flood); + s_scenario_simulation_definition_table_element* new_def = MetaExtender::add_tag_block2((unsigned long)std::addressof(scenario_definition->simulation_definition_table)); + new_def->tag_datum = tag_loader::ResolveNewDatum(flood_datum); + } + else + { + clone_representation(_character_type_masterchief); + } + return; +} + +void game_globals_add_lmao_representation(void) +{ + // Create copy of default variant for chief and add lmao object to head + s_unit_group_definition* mp_chief_unit = (s_unit_group_definition*)tag_get_fast(game_globals_get_representation(_character_type_spartan)->third_person_unit.TagIndex); + datum mode_chief_mp_datum = mp_chief_unit->objectTag.model.TagIndex; + if (mode_chief_mp_datum != NONE) + { + // Copy the variant + s_model_group_definition* mode_chief_mp = tags::get_tag(mode_chief_mp_datum); + auto base_variant = mode_chief_mp->variants[0]; + auto new_variant = MetaExtender::add_tag_block2((unsigned long)std::addressof(mode_chief_mp->variants)); + new_variant->name = 0xABABABA; + new_variant->dialogue.TagGroup = base_variant->dialogue.TagGroup; + new_variant->dialogue.TagIndex = base_variant->dialogue.TagIndex; + memcpy(new_variant->runtime_model_regions, base_variant->runtime_model_regions, sizeof(new_variant->runtime_model_regions)); + for (auto i = 0; i < base_variant->regions.size; i++) + { + auto region = base_variant->regions[i]; + auto new_region = MetaExtender::add_tag_block2((unsigned long)std::addressof(new_variant->regions)); + new_region->region_name = region->region_name; + new_region->runtime_model_region_index = region->runtime_model_region_index; + new_region->region_runtime_flags = region->region_runtime_flags; + new_region->parent_variant = region->parent_variant; + new_region->sort_order = region->sort_order; + for (auto k = 0; k < region->permutations.size; k++) + { + auto permutation = region->permutations[k]; + auto new_permutation = MetaExtender::add_tag_block2((unsigned long)std::addressof(new_region->permutations)); + new_permutation->permutation_name = permutation->permutation_name; + new_permutation->model_permutation_index = permutation->model_permutation_index; + new_permutation->flags = permutation->flags; + new_permutation->probability_0 = permutation->probability_0; + memcpy(new_permutation->runtime_permutations, permutation->runtime_permutations, sizeof(new_permutation->runtime_permutations)); + new_permutation->unk_1 = permutation->unk_1; + new_permutation->unk2 = permutation->unk2; + new_permutation->unk3 = permutation->unk3; + } + } + + // Add lmao head as an attachment on the new variant + datum lmao_datum = tag_loader::Get_tag_datum("scenarios\\objects\\multi\\carto_shared\\emoji_head\\emoji_head", blam_tag::tag_group_type::scenery, "carto_shared"); + if (lmao_datum != NONE) + { + tag_loader::Load_tag(lmao_datum, true, "carto_shared"); + tag_loader::Push_Back(); + + lmao_datum = tag_loader::ResolveNewDatum(lmao_datum); + if (lmao_datum != NONE) + { + auto new_object = MetaExtender::add_tag_block2((unsigned long)std::addressof(new_variant->objects)); + new_object->parent_marker = e_global_string_id::HS_HEAD; + new_object->child_object.TagGroup = blam_tag::tag_group_type::scenery; + new_object->child_object.TagIndex = lmao_datum; + } + } + add_representation(NONE, NONE, NONE, new_variant->name); + } + else + { + clone_representation(_character_type_masterchief); + } + + return; +} + +void game_globals_add_new_player_representations(void) +{ + scenario* scenario_definition = get_global_scenario(); + + game_globals_add_skeleton_representation(scenario_definition); + game_globals_add_flood_representation(scenario_definition); + game_globals_add_lmao_representation(); + return; +} + +void game_globals_apply_tag_patches(s_game_options* options) +{ + if (options->game_mode == _game_mode_multiplayer) + { + game_globals_add_new_player_representations(); + + // Fixup representations after we add our new ones at runtime + game_globals_fixup_representation(); + } + return; +} diff --git a/xlive/Blam/Engine/game/game_globals.h b/xlive/Blam/Engine/game/game_globals.h index c789178cc..ae9e03925 100644 --- a/xlive/Blam/Engine/game/game_globals.h +++ b/xlive/Blam/Engine/game/game_globals.h @@ -1,5 +1,6 @@ #pragma once #include "game_engine.h" +#include "game_options.h" #include "game_preferences.h" #include "materials.h" @@ -17,7 +18,6 @@ #define NUMBER_OF_GLOBAL_SOUNDS 2 #define k_unit_grenade_types_count 2 #define k_global_vertex_shader_count 32 -#define k_player_character_type_count 4 #define k_maximum_material_types 256 #define k_game_globals_maximum_multiplayer_colors 32 @@ -597,3 +597,6 @@ TAG_BLOCK_SIZE_ASSERT(s_game_globals, 644); s_game_globals* scenario_get_game_globals(void); s_ui_levels_definition* game_globals_get_ui_levels(void); +s_game_globals_player_representation* game_globals_get_representation(e_character_type type); + +void game_globals_apply_tag_patches(s_game_options* options); diff --git a/xlive/Blam/Engine/game/players.cpp b/xlive/Blam/Engine/game/players.cpp index 68dd867c0..75b60ab2b 100644 --- a/xlive/Blam/Engine/game/players.cpp +++ b/xlive/Blam/Engine/game/players.cpp @@ -9,6 +9,9 @@ #include "Blam/Engine/scenario/scenario.h" #include "H2MOD/Modules/Shell/Config.h" +#include "H2MOD/Modules/SpecialEvents/SpecialEvents.h" + +#include "Util/Hooks/Hook.h" /* - TO NOTE: @@ -186,33 +189,36 @@ void __cdecl player_validate_configuration(datum player_index, s_player_properti if (!found) { configuration_data->team_index = _game_team_player; - configuration_data->profile_traits.profile.player_character_type = character_type_masterchief; + configuration_data->profile_traits.profile.player_character_type = _character_type_masterchief; } } else { configuration_data->team_index = _game_team_player; - configuration_data->profile_traits.profile.player_character_type = character_type_masterchief; + configuration_data->profile_traits.profile.player_character_type = _character_type_masterchief; } } // Multiplayer verification else if (game_is_multiplayer()) { // Don't allow dervish since he's not loaded properly in shared - if (configuration_data->profile_traits.profile.player_character_type == character_type_dervish) + if (configuration_data->profile_traits.profile.player_character_type == _character_type_dervish) { - configuration_data->profile_traits.profile.player_character_type = character_type_elite; + configuration_data->profile_traits.profile.player_character_type = _character_type_elite; } - - if (H2Config_spooky_boy && !Memory::IsDedicatedServer()) + // Force skeletons in mp during the halloween event + if (e_character_type character = configuration_data->profile_traits.profile.player_character_type; + character != _character_type_flood && H2Config_spooky_boy && get_current_special_event() == _special_event_halloween) { - configuration_data->profile_traits.profile.player_character_type = character_type_skeleton; - for (uint32 i = 0; i < k_number_of_users; i++) + configuration_data->profile_traits.profile.player_character_type = _character_type_skeleton; + if (!Memory::IsDedicatedServer()) { - network_session_interface_set_local_user_character_type(i, character_type_skeleton); + for (uint32 i = 0; i < k_number_of_users; i++) + { + network_session_interface_set_local_user_character_type(i, _character_type_skeleton); + } } - *Memory::GetAddress(0x51A67C) = character_type_skeleton; } } @@ -220,7 +226,7 @@ void __cdecl player_validate_configuration(datum player_index, s_player_properti e_character_type character = configuration_data->profile_traits.profile.player_character_type; if (character != NONE) { - if (character >= character_type_masterchief) + if (character >= _character_type_masterchief) { s_game_globals* globals = scenario_get_game_globals(); if (character > (e_character_type)globals->player_representation.size - 1) @@ -230,7 +236,7 @@ void __cdecl player_validate_configuration(datum player_index, s_player_properti } else { - character = character_type_masterchief; + character = _character_type_masterchief; } configuration_data->profile_traits.profile.player_character_type = character; } @@ -288,3 +294,12 @@ void __cdecl player_validate_configuration(datum player_index, s_player_properti return; } + +void players_apply_patches(void) +{ + // Change the validation for player_appearance_valid to use the updated k_player_character_type_count constant + WriteValue(Memory::GetAddress(0x54fb3, 0x5D4AB), k_player_character_type_count); + + // Replace the player profile validation function with our own + PatchCall(Memory::GetAddress(0x5509E, 0x5D596), player_validate_configuration); +} diff --git a/xlive/Blam/Engine/game/players.h b/xlive/Blam/Engine/game/players.h index 6f7ba33f2..229a4d19e 100644 --- a/xlive/Blam/Engine/game/players.h +++ b/xlive/Blam/Engine/game/players.h @@ -31,18 +31,19 @@ enum e_player_color : byte enum e_character_type : int8 { - character_type_masterchief = 0, - character_type_dervish = 1, - character_type_spartan = 2, - character_type_elite = 3, + _character_type_masterchief = 0, + _character_type_dervish = 1, + _character_type_spartan = 2, + _character_type_elite = 3, // cartographer added characters - character_type_skeleton = 4, - character_type_flood = 5, - character_type_lmao = 6 + _character_type_skeleton = 4, + _character_type_flood = 5, + _character_type_lmao = 6, + k_player_character_type_count }; -enum e_handicap : uint8 +enum e_handicap : int8 { _handicap_none = 0, _handicap_minor = 1, @@ -252,3 +253,5 @@ uint32 player_appearance_required_bits(void); // Validate player configuration void __cdecl player_validate_configuration(datum player_index, s_player_properties* configuration_data); + +void players_apply_patches(void); diff --git a/xlive/Blam/Engine/objects/objects.cpp b/xlive/Blam/Engine/objects/objects.cpp index d6cb28278..2343c088b 100644 --- a/xlive/Blam/Engine/objects/objects.cpp +++ b/xlive/Blam/Engine/objects/objects.cpp @@ -10,7 +10,6 @@ #include "Blam/Engine/Simulation/game_interface/simulation_game_units.h" #include "Blam/Engine/units/bipeds.h" -#include "H2MOD/Modules/PlayerRepresentation/PlayerRepresentation.h" #include "Util/Hooks/Hook.h" void* object_header_block_get(const datum object_datum, const object_header_block_reference* reference) diff --git a/xlive/H2MOD.cpp b/xlive/H2MOD.cpp index 17e3f8d28..cfa45d351 100644 --- a/xlive/H2MOD.cpp +++ b/xlive/H2MOD.cpp @@ -5,6 +5,7 @@ #include "Blam/Engine/game/aim_assist.h" #include "Blam/Engine/game/cheats.h" #include "Blam/Engine/game/game.h" +#include "Blam/Engine/game/game_globals.h" #include "Blam/Engine/interface/hud.h" #include "Blam/Engine/interface/hud_messaging.h" #include "Blam/Engine/interface/motion_sensor.h" @@ -41,7 +42,6 @@ #include "H2MOD/Modules/MapManager/MapManager.h" #include "H2MOD/Modules/ObserverMode/ObserverMode.h" #include "H2MOD/Modules/OnScreenDebug/OnscreenDebug.h" -#include "H2MOD/Modules/PlayerRepresentation/PlayerRepresentation.h" #include "H2MOD/Modules/PlaylistLoader/PlaylistLoader.h" #include "H2MOD/Modules/RenderHooks/RenderHooks.h" #include "H2MOD/Modules/Shell/Config.h" @@ -486,7 +486,7 @@ bool __cdecl OnMapLoad(s_game_options* options) if (result == false) // verify if the game didn't fail to load the map return false; - PlayerRepresentation::OnMapLoad(options); + game_globals_apply_tag_patches(options); tags::run_callbacks(); H2Tweaks::SetScreenRefreshRate(); @@ -982,6 +982,7 @@ void H2MOD::ApplyHooks() { game_statborg_apply_patches(); simulation_game_objects_apply_patches(); simulation_game_units_apply_patches(); + players_apply_patches(); // server/client detours DETOUR_ATTACH(p_player_spawn, Memory::GetAddress(0x55952, 0x5DE4A), OnPlayerSpawn); @@ -1061,7 +1062,6 @@ void H2MOD::Initialize() LOG_INFO_GAME("H2MOD - Initializing {}", DLL_VERSION_STR); LOG_INFO_GAME("H2MOD - Image base address: 0x{:X}", Memory::baseAddress); - PlayerRepresentation::Initialize(); if (!Memory::IsDedicatedServer()) { MouseInput::Initialize(); diff --git a/xlive/H2MOD/GUI/imgui_integration/AdvancedSettings.cpp b/xlive/H2MOD/GUI/imgui_integration/AdvancedSettings.cpp index 169a9fc3e..753fb3ca3 100644 --- a/xlive/H2MOD/GUI/imgui_integration/AdvancedSettings.cpp +++ b/xlive/H2MOD/GUI/imgui_integration/AdvancedSettings.cpp @@ -839,7 +839,7 @@ namespace ImGuiHandler { if (ImGui::IsItemHovered()) ImGui::SetTooltip(GetString(no_events_tooltip)); - if (get_current_special_event() == e_special_event_type::_halloween) { + if (get_current_special_event() == _special_event_halloween) { TextVerticalPad(GetString(skeleton_biped)); ImGui::SameLine(ImGui::GetColumnWidth() - 35); ImGui::Checkbox("##spooky_scary", &H2Config_spooky_boy); @@ -1039,30 +1039,30 @@ namespace ImGuiHandler { static int event_type = H2Config_forced_event; if (ImGui::CollapsingHeader("Events")) { - if (ImGui::RadioButton("None", &event_type, e_special_event_type::_no_event)) + if (ImGui::RadioButton("None", &event_type, _special_event_none)) { - H2Config_forced_event = (int)e_special_event_type::_no_event; + H2Config_forced_event = _special_event_none; } ImGui::SameLine(); - if (ImGui::RadioButton("Christmas", &event_type, e_special_event_type::_christmas)) + if (ImGui::RadioButton("Christmas", &event_type, _special_event_christmas)) { - H2Config_forced_event = (int)e_special_event_type::_christmas; + H2Config_forced_event = _special_event_christmas; } ImGui::SameLine(); - if (ImGui::RadioButton("St Paddys", &event_type, e_special_event_type::_st_paddys)) + if (ImGui::RadioButton("St Paddys", &event_type, _special_event_st_paddys)) { - H2Config_forced_event = (int)e_special_event_type::_st_paddys; + H2Config_forced_event = _special_event_st_paddys; } ImGui::SameLine(); - if (ImGui::RadioButton("Mook Madness", &event_type, e_special_event_type::_mook_maddness)) + if (ImGui::RadioButton("Mook Madness", &event_type, _special_event_mook_maddness)) { - H2Config_forced_event = (int)e_special_event_type::_mook_maddness; + H2Config_forced_event = _special_event_mook_maddness; } - if (ImGui::RadioButton("Halloween", &event_type, e_special_event_type::_halloween)) + if (ImGui::RadioButton("Halloween", &event_type, _special_event_halloween)) { - H2Config_forced_event = (int)e_special_event_type::_halloween; + H2Config_forced_event = _special_event_halloween; }ImGui::SameLine(); - if (ImGui::RadioButton("Birthday", &event_type, e_special_event_type::_birthday)) + if (ImGui::RadioButton("Birthday", &event_type, _special_event_birthday)) { - H2Config_forced_event = (int)e_special_event_type::_birthday; + H2Config_forced_event = _special_event_birthday; } } diff --git a/xlive/H2MOD/Modules/PlayerRepresentation/PlayerRepresentation.cpp b/xlive/H2MOD/Modules/PlayerRepresentation/PlayerRepresentation.cpp deleted file mode 100644 index df4a2c498..000000000 --- a/xlive/H2MOD/Modules/PlayerRepresentation/PlayerRepresentation.cpp +++ /dev/null @@ -1,212 +0,0 @@ -#include "stdafx.h" -#include "PlayerRepresentation.h" - -#include "Blam/Cache/TagGroups/biped_definition.hpp" -#include "Blam/Cache/TagGroups/model_definition.hpp" -#include "Blam/Engine/game/game.h" -#include "Blam/Engine/game/game_engine.h" -#include "Blam/Engine/game/game_engine_util.h" -#include "Blam/Engine/game/players.h" -#include "Blam/Engine/Networking/Session/NetworkSession.h" -#include "Blam/Engine/scenario/scenario.h" -#include "Blam/Engine/tag_files/global_string_ids.h" - -#include "H2MOD/Modules/Shell/Config.h" -#include "H2MOD/Modules/SpecialEvents/SpecialEvents.h" -#include "H2MOD/Tags/MetaExtender.h" -#include "H2MOD/Tags/MetaLoader/tag_loader.h" -#include "H2MOD/Tags/TagInterface.h" - -#include "Util/Hooks/Hook.h" - -namespace PlayerRepresentation -{ - //Non-zero index based value for the count of valid representation types - std::map type_map - { - {character_type_masterchief, 0}, - {character_type_dervish, 1}, - {character_type_spartan, 2}, - {character_type_elite, 3}, - }; - - BYTE current_representation_count = 4; - s_game_globals_player_representation* add_representation(datum fp_hands, datum fp_body, datum tp_biped, e_character_type type, string_id variant) - { - s_game_globals* globals = scenario_get_game_globals(); - - auto new_rep = MetaExtender::add_tag_block2((unsigned long)std::addressof(globals->player_representation)); - if (!DATUM_IS_NONE(fp_hands)) - { - new_rep->first_person_hands.TagGroup = blam_tag::tag_group_type::rendermodel; - new_rep->first_person_hands.TagIndex = fp_hands; - } - else - new_rep->first_person_hands = globals->player_representation[2]->first_person_hands; - - if (!DATUM_IS_NONE(fp_body)) - { - new_rep->first_person_body.TagGroup = blam_tag::tag_group_type::rendermodel; - new_rep->first_person_body.TagIndex = fp_body; - } - else - new_rep->first_person_body = globals->player_representation[2]->first_person_body; - - if (!DATUM_IS_NONE(tp_biped)) - { - new_rep->third_person_unit.TagGroup = blam_tag::tag_group_type::biped; - new_rep->third_person_unit.TagIndex = tp_biped; - } - else - new_rep->third_person_unit = globals->player_representation[2]->third_person_unit; - - if (variant != -1) - new_rep->third_person_variant = variant; - type_map.emplace(type, current_representation_count); - ++current_representation_count; - return new_rep; - } - - - s_game_globals_player_representation* clone_representation(int index, e_character_type newType) - { - s_game_globals* globals = scenario_get_game_globals(); - auto new_rep = MetaExtender::add_tag_block2((unsigned long)std::addressof(globals->player_representation)); - new_rep->first_person_body = globals->player_representation[index]->first_person_body; - new_rep->first_person_hands = globals->player_representation[index]->first_person_hands; - new_rep->third_person_unit = globals->player_representation[index]->third_person_unit; - new_rep->third_person_variant = globals->player_representation[index]->third_person_variant; - type_map.emplace(newType, current_representation_count); - ++current_representation_count; - return new_rep; - } - - s_game_globals_player_representation* get_representation(int index) - { - return scenario_get_game_globals()->player_representation[index]; - } - - datum get_object_datum_from_representation(e_character_type representation_index) - { - s_game_globals* game_globals = scenario_get_game_globals(); - if (game_globals != nullptr) - { - if (type_map.find(representation_index) != type_map.end()) - return game_globals->player_representation[type_map[representation_index]]->third_person_unit.TagIndex; - } - return DATUM_INDEX_NONE; - } - - - - void OnMapLoad(s_game_options* options) - { - current_representation_count = 4; - - if (options->game_mode == _game_mode_multiplayer) - { - scenario* scenario_definition = get_global_scenario(); - datum skele_datum = tag_loader::Get_tag_datum("objects\\characters\\masterchief_skeleton\\masterchief_skeleton", blam_tag::tag_group_type::biped, "carto_shared"); - datum skele_fp_datum = tag_loader::Get_tag_datum("objects\\characters\\masterchief_skeleton\\fp\\fp", blam_tag::tag_group_type::rendermodel, "carto_shared"); - datum skele_body_datum = tag_loader::Get_tag_datum("objects\\characters\\masterchief_skeleton\\fp_body\\fp_body", blam_tag::tag_group_type::rendermodel, "carto_shared"); - - if (!DATUM_IS_NONE(skele_datum) && !DATUM_IS_NONE(skele_fp_datum) && !DATUM_IS_NONE(skele_body_datum) && get_current_special_event() == e_special_event_type::_halloween && !H2Config_no_events) - { - tag_loader::Load_tag(skele_fp_datum, true, "carto_shared"); - tag_loader::Load_tag(skele_body_datum, true, "carto_shared"); - tag_loader::Load_tag(skele_datum, true, "carto_shared"); - tag_loader::Push_Back(); - datum skele_new_datum = tag_loader::ResolveNewDatum(skele_datum); - add_representation(tag_loader::ResolveNewDatum(skele_fp_datum), tag_loader::ResolveNewDatum(skele_body_datum), skele_new_datum, character_type_skeleton); - s_scenario_simulation_definition_table_element* new_def = MetaExtender::add_tag_block2((unsigned long)std::addressof(scenario_definition->simulation_definition_table)); - new_def->tag_datum = skele_new_datum; - } - else - { - clone_representation(2, character_type_skeleton); - } - auto flood_datum = tag_loader::Get_tag_datum("objects\\characters\\floodcombat_elite\\floodcombat_elite_mp", blam_tag::tag_group_type::biped, "carto_shared"); - auto flood_arms_datum = tag_loader::Get_tag_datum("objects\\characters\\flood_mp\\fp_arms\\fp_arms", blam_tag::tag_group_type::rendermodel, "carto_shared"); - auto flood_body_datum = tag_loader::Get_tag_datum("objects\\characters\\flood_mp\\fp_body\\fp_body", blam_tag::tag_group_type::rendermodel, "carto_shared"); - if (!DATUM_IS_NONE(flood_datum) && !DATUM_IS_NONE(flood_arms_datum) && !DATUM_IS_NONE(flood_body_datum)) - { - tag_loader::Load_tag(flood_datum, true, "carto_shared"); - tag_loader::Load_tag(flood_arms_datum, true, "carto_shared"); - tag_loader::Load_tag(flood_body_datum, true, "carto_shared"); - tag_loader::Push_Back(); - add_representation(tag_loader::ResolveNewDatum(flood_arms_datum), tag_loader::ResolveNewDatum(flood_body_datum), tag_loader::ResolveNewDatum(flood_datum), character_type_flood); - s_scenario_simulation_definition_table_element* new_def = MetaExtender::add_tag_block2((unsigned long)std::addressof(scenario_definition->simulation_definition_table)); - new_def->tag_datum = tag_loader::ResolveNewDatum(flood_datum); - } - else - { - clone_representation(3, character_type_flood); - } - - // Create copy of default variant for chief and add lmao object to head - auto mode_chief_mp_datum = tags::find_tag(blam_tag::tag_group_type::model, "objects\\characters\\masterchief\\masterchief_mp"); - if (mode_chief_mp_datum != DATUM_INDEX_NONE) - { - auto mode_chief_mp = tags::get_tag(mode_chief_mp_datum); - auto base_variant = mode_chief_mp->variants[0]; - auto new_variant = MetaExtender::add_tag_block2((unsigned long)std::addressof(mode_chief_mp->variants)); - new_variant->name = 0xABABABA; - new_variant->dialogue.TagGroup = base_variant->dialogue.TagGroup; - new_variant->dialogue.TagIndex = base_variant->dialogue.TagIndex; - memcpy(new_variant->runtime_model_regions, base_variant->runtime_model_regions, sizeof(new_variant->runtime_model_regions)); - for (auto i = 0; i < base_variant->regions.size; i++) - { - auto region = base_variant->regions[i]; - auto new_region = MetaExtender::add_tag_block2((unsigned long)std::addressof(new_variant->regions)); - new_region->region_name = region->region_name; - new_region->runtime_model_region_index = region->runtime_model_region_index; - new_region->region_runtime_flags = region->region_runtime_flags; - new_region->parent_variant = region->parent_variant; - new_region->sort_order = region->sort_order; - for (auto k = 0; k < region->permutations.size; k++) - { - auto permutation = region->permutations[k]; - auto new_permutation = MetaExtender::add_tag_block2((unsigned long)std::addressof(new_region->permutations)); - new_permutation->permutation_name = permutation->permutation_name; - new_permutation->model_permutation_index = permutation->model_permutation_index; - new_permutation->flags = permutation->flags; - new_permutation->probability_0 = permutation->probability_0; - memcpy(new_permutation->runtime_permutations, permutation->runtime_permutations, sizeof(new_permutation->runtime_permutations)); - new_permutation->unk_1 = permutation->unk_1; - new_permutation->unk2 = permutation->unk2; - new_permutation->unk3 = permutation->unk3; - } - } - - datum lmao_datum = tag_loader::Get_tag_datum("scenarios\\objects\\multi\\carto_shared\\emoji_head\\emoji_head", blam_tag::tag_group_type::scenery, "carto_shared"); - if (!DATUM_IS_NONE(lmao_datum)) - { - tag_loader::Load_tag(lmao_datum, true, "carto_shared"); - tag_loader::Push_Back(); - - lmao_datum = tag_loader::ResolveNewDatum(lmao_datum); - if (!DATUM_IS_NONE(lmao_datum)) - { - auto new_object = MetaExtender::add_tag_block2((unsigned long)std::addressof(new_variant->objects)); - new_object->parent_marker = e_global_string_id::HS_HEAD; - new_object->child_object.TagGroup = blam_tag::tag_group_type::scenery; - new_object->child_object.TagIndex = lmao_datum; - } - } - add_representation(-1, -1, -1, character_type_lmao, new_variant->name); - } - } - } - void ApplyHooks() - { - PatchCall(Memory::GetAddress(0x5509E, 0x5D596), player_validate_configuration); - // Change the packet validation for player::properties::profile to just accept anything, we catch it later if it's outside of the acceptable range. - WriteValue(Memory::GetAddress(0x54fb3, 0x5D4AB), 25); - } - - void Initialize() - { - ApplyHooks(); - } - -} diff --git a/xlive/H2MOD/Modules/PlayerRepresentation/PlayerRepresentation.h b/xlive/H2MOD/Modules/PlayerRepresentation/PlayerRepresentation.h deleted file mode 100644 index a3870ce49..000000000 --- a/xlive/H2MOD/Modules/PlayerRepresentation/PlayerRepresentation.h +++ /dev/null @@ -1,29 +0,0 @@ -#include "Blam/Engine/game/game_globals.h" -#include "Blam/Engine/game/game_options.h" -#include "Blam/Engine/game/players.h" -#include "Blam/Engine/tag_files/string_id.h" - -namespace PlayerRepresentation -{ - /** - * \brief Adds a new player representation to the globals tag block - * \param fp_hands the datum index of the first person hands render model - * \param fp_body the datum index of the first person body render model - * \param tp_biped the datum index of the third person biped - * \param type the type of biped being added, will override an existing biped - * \param variant the string_id of the variant - * \return returns a pointer to the new representation - */ - s_game_globals_player_representation* add_representation(datum fp_hands, datum fp_body, datum tp_biped, e_character_type type, string_id variant = -1); - /** - * \brief Clones an existing player_representation - * \param index 0 based index of the representation to clone - * \param newType the new Player::Biped type to register this as, cannot be the same as an existing one. - * \return returns a pointer to the new representation - */ - s_game_globals_player_representation* clone_representation(int index, e_character_type newType); - - datum get_object_datum_from_representation(e_character_type representation_index); - void OnMapLoad(s_game_options* options); - void Initialize(); -} diff --git a/xlive/H2MOD/Modules/SpecialEvents/Events/Christmas.cpp b/xlive/H2MOD/Modules/SpecialEvents/Events/Christmas.cpp index 9f97f8517..4e1cea631 100644 --- a/xlive/H2MOD/Modules/SpecialEvents/Events/Christmas.cpp +++ b/xlive/H2MOD/Modules/SpecialEvents/Events/Christmas.cpp @@ -10,7 +10,6 @@ #include "Blam/Engine/game/game_globals.h" #include "Blam/Engine/scenario/scenario.h" -#include "H2MOD/Modules/PlayerRepresentation/PlayerRepresentation.h" #include "H2MOD/Tags/MetaExtender.h" #include "H2MOD/Tags/MetaLoader/tag_loader.h" @@ -60,8 +59,8 @@ void christmas_event_map_load() add_hat_and_beard_to_model(hlmt_elite_datum, santa_hat_datum, beard_datum, true); } - if (datum flood_datum = PlayerRepresentation::get_object_datum_from_representation(character_type_flood); - !DATUM_IS_NONE(flood_datum)) + if (datum flood_datum = game_globals_get_representation(_character_type_flood)->third_person_unit.TagIndex; + flood_datum != NONE) { auto flood_biped = tags::get_tag(flood_datum, true); add_hat_and_beard_to_model(flood_biped->unitTag.objectTag.model.TagIndex, santa_hat_datum, beard_datum, false); diff --git a/xlive/H2MOD/Modules/SpecialEvents/SpecialEvents.cpp b/xlive/H2MOD/Modules/SpecialEvents/SpecialEvents.cpp index 05901b229..e339711d5 100644 --- a/xlive/H2MOD/Modules/SpecialEvents/SpecialEvents.cpp +++ b/xlive/H2MOD/Modules/SpecialEvents/SpecialEvents.cpp @@ -73,30 +73,30 @@ bool check_special_event_date(std::wstring date) e_special_event_type get_current_special_event() { if (H2Config_no_events) - return _no_event; + return _special_event_none; #ifndef NDEBUG - if (H2Config_forced_event != _no_event) + if (H2Config_forced_event != _special_event_none) return (e_special_event_type)H2Config_forced_event; #endif if (check_special_event_week(L"3-17")) - return _st_paddys; + return _special_event_st_paddys; if (check_special_event_week(L"12-24") || check_special_event_week(L"12-30") || check_special_event_week(L"1-4")) - return _christmas; + return _special_event_christmas; // One time event /*if (CheckIfEventTime(L"4-12")) return _mook_maddness;*/ if (check_special_event_week(L"10-20") || check_special_event_week(L"10-27") || check_special_event_date(L"10-31")) - return _halloween; + return _special_event_halloween; if (check_special_event_date(L"11-08") || check_special_event_date(L"11-09") || check_special_event_date(L"11-10") || check_special_event_date(L"5-30") || check_special_event_date(L"5-31") || check_special_event_date(L"6-01")) - return _birthday; + return _special_event_birthday; - return _no_event; + return _special_event_none; } void load_special_event() @@ -106,19 +106,19 @@ void load_special_event() add_special_event_markers(); switch (get_current_special_event()) { - case _christmas: + case _special_event_christmas: christmas_event_map_load(); break; - case _st_paddys: + case _special_event_st_paddys: paddy_event_map_load(); break; - case _mook_maddness: + case _special_event_mook_maddness: mook_event_map_load(); break; - case _halloween: + case _special_event_halloween: halloween_event_map_load(); break; - case _birthday: + case _special_event_birthday: birthday_event_map_load(); break; default: diff --git a/xlive/H2MOD/Modules/SpecialEvents/SpecialEvents.h b/xlive/H2MOD/Modules/SpecialEvents/SpecialEvents.h index aec9690bc..030cd6caf 100644 --- a/xlive/H2MOD/Modules/SpecialEvents/SpecialEvents.h +++ b/xlive/H2MOD/Modules/SpecialEvents/SpecialEvents.h @@ -2,12 +2,13 @@ enum e_special_event_type { - _no_event, - _christmas, - _st_paddys, - _mook_maddness, - _halloween, - _birthday + _special_event_none = 0, + _special_event_christmas = 1, + _special_event_st_paddys = 2, + _special_event_mook_maddness = 3, + _special_event_halloween = 4, + _special_event_birthday = 5, + k_special_event_count }; e_special_event_type get_current_special_event(); void load_special_event(); diff --git a/xlive/H2MOD/Variants/GunGame/GunGame.cpp b/xlive/H2MOD/Variants/GunGame/GunGame.cpp index 0852fe651..d527db532 100644 --- a/xlive/H2MOD/Variants/GunGame/GunGame.cpp +++ b/xlive/H2MOD/Variants/GunGame/GunGame.cpp @@ -221,7 +221,7 @@ void GunGame::OnPlayerSpawn(ExecTime execTime, datum playerIdx) { // prespawn handler case ExecTime::_preEventExec: - s_player::SetUnitBipedType(absPlayerIdx, character_type_spartan); + s_player::SetUnitBipedType(absPlayerIdx, _character_type_spartan); break; // postspawn handler diff --git a/xlive/H2MOD/Variants/Infection/Infection.cpp b/xlive/H2MOD/Variants/Infection/Infection.cpp index 99bdfcf2c..990a03116 100644 --- a/xlive/H2MOD/Variants/Infection/Infection.cpp +++ b/xlive/H2MOD/Variants/Infection/Infection.cpp @@ -14,7 +14,6 @@ #include "H2MOD/Modules/Shell/Config.h" #include "H2MOD/Modules/CustomMenu/CustomLanguage.h" #include "H2MOD/Modules/EventHandler/EventHandler.hpp" -#include "H2MOD/Modules/PlayerRepresentation/PlayerRepresentation.h" #include "H2MOD/Tags/MetaLoader/tag_loader.h" #include "H2MOD/Tags/TagInterface.h" @@ -179,31 +178,31 @@ void Infection::preSpawnServerSetup() { LOG_TRACE_GAME(L"[h2mod-infection] Zombie pre spawn index={}, isZombie={}, playerIdentifier={}, playerName:{}", currentPlayerIndex, isZombie, playerIdentifier, s_player::GetName(currentPlayerIndex)); if (isZombie) { - s_player::SetUnitBipedType(currentPlayerIndex, character_type_flood); + s_player::SetUnitBipedType(currentPlayerIndex, _character_type_flood); if (s_player::GetTeam(currentPlayerIndex) != ZOMBIE_TEAM) { if (NetworkSession::LocalPeerIsSessionHost()) NetworkMessage::SendTeamChange(NetworkSession::GetPeerIndex(currentPlayerIndex), ZOMBIE_TEAM); // prevent *toxic* kids from switching to humans in the pre-game lobby after joining } } else { - if (get_current_special_event() == e_special_event_type::_halloween && H2Config_spooky_boy) - s_player::SetUnitBipedType(currentPlayerIndex, character_type_skeleton); + if (get_current_special_event() == _special_event_halloween && H2Config_spooky_boy) + s_player::SetUnitBipedType(currentPlayerIndex, _character_type_skeleton); else - s_player::SetUnitBipedType(currentPlayerIndex, character_type_spartan); + s_player::SetUnitBipedType(currentPlayerIndex, _character_type_spartan); } } } void Infection::setPlayerAsHuman(int playerIndex) { - if (get_current_special_event() == e_special_event_type::_halloween && H2Config_spooky_boy) - s_player::SetUnitBipedType(playerIndex, character_type_skeleton); + if (get_current_special_event() == _special_event_halloween && H2Config_spooky_boy) + s_player::SetUnitBipedType(playerIndex, _character_type_skeleton); else - s_player::SetUnitBipedType(playerIndex, character_type_spartan); + s_player::SetUnitBipedType(playerIndex, _character_type_spartan); s_player::SetBipedSpeed(playerIndex, 1.0f); } void Infection::setPlayerAsZombie(int playerIndex) { - s_player::SetUnitBipedType(playerIndex, character_type_flood); + s_player::SetUnitBipedType(playerIndex, _character_type_flood); s_player::SetBipedSpeed(playerIndex, 1.1f); call_give_player_weapon(playerIndex, e_weapons_datum_index::energy_blade, 1); @@ -370,7 +369,7 @@ void Infection::OnPlayerDeath(ExecTime execTime, datum playerIdx) if (playerIdentifier == s_player::GetId(DATUM_INDEX_TO_ABSOLUTE_INDEX(h2mod->get_player_datum_index_from_controller_index(0)))) { LOG_TRACE_GAME("[h2mod-infection] Setting player as zombie"); h2mod->set_local_team_index(0, ZOMBIE_TEAM); - s_player::SetUnitBipedType(absPlayerIdx, character_type_flood); + s_player::SetUnitBipedType(absPlayerIdx, _character_type_flood); } else { //if not, then this is a new zombie @@ -429,7 +428,7 @@ void Infection::OnPlayerSpawn(ExecTime execTime, datum playerIdx) if (h2mod->get_local_team_index() == ZOMBIE_TEAM) { LOG_TRACE_GAME("[h2mod-infection] Client is infected! switching bipeds: {}", absPlayerIdx); - s_player::SetUnitBipedType(absPlayerIdx, character_type_flood); + s_player::SetUnitBipedType(absPlayerIdx, _character_type_flood); } } } @@ -464,7 +463,7 @@ void Infection::OnPlayerSpawn(ExecTime execTime, datum playerIdx) } else if (h2mod->get_local_team_index() == ZOMBIE_TEAM) { - s_player::SetUnitBipedType(absPlayerIdx, character_type_flood); + s_player::SetUnitBipedType(absPlayerIdx, _character_type_flood); h2mod->disable_weapon_pickup(false); h2mod->team_player_indicator_visibility(true); } diff --git a/xlive/Project_Cartographer.vcxproj b/xlive/Project_Cartographer.vcxproj index 766ca7e78..0e6feaf2a 100644 --- a/xlive/Project_Cartographer.vcxproj +++ b/xlive/Project_Cartographer.vcxproj @@ -499,7 +499,6 @@ - @@ -846,7 +845,6 @@ - diff --git a/xlive/Util/Hooks/Hook.cpp b/xlive/Util/Hooks/Hook.cpp index 0580c540d..af0752bcc 100644 --- a/xlive/Util/Hooks/Hook.cpp +++ b/xlive/Util/Hooks/Hook.cpp @@ -17,13 +17,14 @@ void *DetourFunc(BYTE *src, const BYTE *dst, const unsigned int len) VirtualProtectAndExecutePatch(src, len, PAGE_READWRITE, // parameters - // code + // copy the overwritten bytes memcpy(jmp, src, len); jmp += len; jmp[0] = 0xE9; *(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5; + // detour source function call src[0] = 0xE9; *(DWORD*)(src + 1) = (DWORD)(dst - src) - 5; @@ -51,13 +52,15 @@ void *DetourClassFunc(BYTE *src, const BYTE *dst, const unsigned int len) VirtualProtectAndExecutePatch(src, len, PAGE_READWRITE, - memcpy(jmp + 3, src, len); - // calculate callback function call jmp[0] = 0x58; // pop eax jmp[1] = 0x59; // pop ecx jmp[2] = 0x50; // push eax - jmp[len + 3] = 0xE9; // jmp + + // copy the overwritten bytes + memcpy(jmp + 3, src, len); + + jmp[3 + len] = 0xE9; // jmp *(DWORD*)(jmp + len + 4) = (DWORD)((src + len) - (jmp + len + 3)) - 5; // detour source function call diff --git a/xlive/version.h b/xlive/version.h index cd413b4a6..d7b456611 100644 --- a/xlive/version.h +++ b/xlive/version.h @@ -4,7 +4,7 @@ #define DLL_VERSION_MAJOR 0 #define DLL_VERSION_MINOR 6 #define DLL_VERSION_REVISION 8 -#define DLL_VERSION_BUILD 2 +#define DLL_VERSION_BUILD 3 #define DLL_VERSION DLL_VERSION_MAJOR, DLL_VERSION_MINOR, DLL_VERSION_REVISION, DLL_VERSION_BUILD