commit
cf5aa2ac65
@ -1,11 +1,71 @@
|
|||||||
init()
|
main()
|
||||||
{
|
{
|
||||||
// define the auto balance string in the game array (referenced in gsc dump, but not defined past IW6?)
|
|
||||||
precachestring(&"MP_AUTOBALANCE_NOW");
|
precachestring(&"MP_AUTOBALANCE_NOW");
|
||||||
game["strings"]["autobalance"] = &"MP_AUTOBALANCE_NOW";
|
|
||||||
|
|
||||||
// define onteamselection callback function used in balanceteams()
|
// use player's score to balance instead player's time on team
|
||||||
level.onteamselection = ::set_team;
|
replacefunc(maps\mp\gametypes\_teams::balanceteams, ::balance_teams_stub);
|
||||||
|
}
|
||||||
|
|
||||||
|
balance_teams_stub()
|
||||||
|
{
|
||||||
|
iprintlnbold(&"MP_AUTOBALANCE_NOW");
|
||||||
|
|
||||||
|
allied_players = get_valid_team_array("allies");
|
||||||
|
axis_players = get_valid_team_array("axis");
|
||||||
|
while (is_team_bigger_than(allied_players, axis_players) || is_team_bigger_than(axis_players, allied_players))
|
||||||
|
{
|
||||||
|
if (is_team_bigger_than(allied_players, axis_players))
|
||||||
|
{
|
||||||
|
handle_lowest_score_player(allied_players, "axis");
|
||||||
|
}
|
||||||
|
else if (is_team_bigger_than(axis_players, allied_players))
|
||||||
|
{
|
||||||
|
handle_lowest_score_player(axis_players, "allies");
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh array for loop
|
||||||
|
allied_players = get_valid_team_array("allies");
|
||||||
|
axis_players = get_valid_team_array("axis");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get_valid_team_array(team)
|
||||||
|
{
|
||||||
|
team_array = [];
|
||||||
|
players = level.players;
|
||||||
|
for (i = 0; i < players.size; i++)
|
||||||
|
{
|
||||||
|
if (!isdefined(players[i].pers["score"])) // was teamTime
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (isdefined(players[i].pers["team"]) && players[i].pers["team"] == team)
|
||||||
|
team_array[team_array.size] = players[i];
|
||||||
|
}
|
||||||
|
return team_array;
|
||||||
|
}
|
||||||
|
|
||||||
|
is_team_bigger_than(team_one, team_two)
|
||||||
|
{
|
||||||
|
return (team_one.size > (team_two.size + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_lowest_score_player(team, new_team)
|
||||||
|
{
|
||||||
|
lowest_score_player = undefined;
|
||||||
|
|
||||||
|
// move the player that has the lowest score (highest teamTime value)
|
||||||
|
for (i = 0; i < team.size; i++)
|
||||||
|
{
|
||||||
|
if (isdefined(team[i].dont_auto_balance))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!isdefined(lowest_score_player))
|
||||||
|
lowest_score_player = team[i];
|
||||||
|
else if (team[i].pers["score"] < lowest_score_player.pers["score"])
|
||||||
|
lowest_score_player = team[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
lowest_score_player set_team(new_team);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_team(team)
|
set_team(team)
|
||||||
@ -22,6 +82,6 @@ set_team(team)
|
|||||||
self suicide();
|
self suicide();
|
||||||
}
|
}
|
||||||
|
|
||||||
maps\mp\gametypes\_menus::addtoteam(team);
|
self maps\mp\gametypes\_menus::addtoteam(team);
|
||||||
maps\mp\gametypes\_menus::endrespawnnotify();
|
self maps\mp\gametypes\_menus::endrespawnnotify();
|
||||||
}
|
}
|
||||||
|
@ -61,11 +61,6 @@ namespace branding
|
|||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void post_start() override
|
|
||||||
{
|
|
||||||
scheduler::loop(draw_branding, scheduler::pipeline::renderer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
if (game::environment::is_dedi())
|
if (game::environment::is_dedi())
|
||||||
@ -73,6 +68,8 @@ namespace branding
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scheduler::loop(draw_branding, scheduler::pipeline::renderer);
|
||||||
|
|
||||||
ui_get_formatted_build_number_hook.create(
|
ui_get_formatted_build_number_hook.create(
|
||||||
SELECT_VALUE(0x406EC0_b, 0x1DF300_b), ui_get_formatted_build_number_stub);
|
SELECT_VALUE(0x406EC0_b, 0x1DF300_b), ui_get_formatted_build_number_stub);
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ namespace fastfiles
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
utils::hook::detour db_init_load_x_file_hook;
|
||||||
utils::hook::detour db_try_load_x_file_internal_hook;
|
utils::hook::detour db_try_load_x_file_internal_hook;
|
||||||
utils::hook::detour db_find_xasset_header_hook;
|
utils::hook::detour db_find_xasset_header_hook;
|
||||||
|
|
||||||
@ -31,9 +32,14 @@ namespace fastfiles
|
|||||||
utils::concurrency::container<std::vector<HANDLE>> fastfile_handles;
|
utils::concurrency::container<std::vector<HANDLE>> fastfile_handles;
|
||||||
bool is_mod_pre_gfx = false;
|
bool is_mod_pre_gfx = false;
|
||||||
|
|
||||||
|
void db_init_load_x_file_stub(game::DBFile* file, std::uint64_t offset)
|
||||||
|
{
|
||||||
|
console::info("Loading fastfile %s\n", file->name);
|
||||||
|
return db_init_load_x_file_hook.invoke<void>(file, offset);
|
||||||
|
}
|
||||||
|
|
||||||
void db_try_load_x_file_internal(const char* zone_name, const int flags)
|
void db_try_load_x_file_internal(const char* zone_name, const int flags)
|
||||||
{
|
{
|
||||||
console::info("Loading fastfile %s\n", zone_name);
|
|
||||||
is_mod_pre_gfx = zone_name == "mod_pre_gfx"s;
|
is_mod_pre_gfx = zone_name == "mod_pre_gfx"s;
|
||||||
current_fastfile.access([&](std::string& fastfile)
|
current_fastfile.access([&](std::string& fastfile)
|
||||||
{
|
{
|
||||||
@ -74,30 +80,32 @@ namespace fastfiles
|
|||||||
dump_gsc_script(name, result);
|
dump_gsc_script(name, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string override_asset_name = "override/"s + name;
|
|
||||||
|
|
||||||
if (type == game::XAssetType::ASSET_TYPE_RAWFILE)
|
|
||||||
{
|
{
|
||||||
if (result.rawfile)
|
const std::string override_asset_name = "override/"s + name;
|
||||||
|
|
||||||
|
if (type == game::XAssetType::ASSET_TYPE_RAWFILE)
|
||||||
{
|
{
|
||||||
const auto override_rawfile = db_find_xasset_header_hook.invoke<game::XAssetHeader>(type, override_asset_name.data(), 0);
|
if (result.rawfile)
|
||||||
if (override_rawfile.rawfile)
|
|
||||||
{
|
{
|
||||||
result.rawfile = override_rawfile.rawfile;
|
const auto override_rawfile = db_find_xasset_header_hook.invoke<game::XAssetHeader>(type, override_asset_name.data(), 0);
|
||||||
console::debug("using override asset for rawfile: \"%s\"\n", name);
|
if (override_rawfile.rawfile)
|
||||||
|
{
|
||||||
|
result.rawfile = override_rawfile.rawfile;
|
||||||
|
console::debug("using override asset for rawfile: \"%s\"\n", name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (type == game::XAssetType::ASSET_TYPE_STRINGTABLE)
|
if (type == game::XAssetType::ASSET_TYPE_STRINGTABLE)
|
||||||
{
|
|
||||||
if (result.stringTable)
|
|
||||||
{
|
{
|
||||||
const auto override_stringtable = db_find_xasset_header_hook.invoke<game::XAssetHeader>(type, override_asset_name.data(), 0);
|
if (result.stringTable)
|
||||||
if (override_stringtable.stringTable)
|
|
||||||
{
|
{
|
||||||
result.stringTable = override_stringtable.stringTable;
|
const auto override_stringtable = db_find_xasset_header_hook.invoke<game::XAssetHeader>(type, override_asset_name.data(), 0);
|
||||||
console::debug("using override asset for stringtable: \"%s\"\n", name);
|
if (override_stringtable.stringTable)
|
||||||
|
{
|
||||||
|
result.stringTable = override_stringtable.stringTable;
|
||||||
|
console::debug("using override asset for stringtable: \"%s\"\n", name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1193,8 +1201,8 @@ namespace fastfiles
|
|||||||
public:
|
public:
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
db_try_load_x_file_internal_hook.create(
|
db_try_load_x_file_internal_hook.create(SELECT_VALUE(0x1F5700_b, 0x39A620_b), db_try_load_x_file_internal);
|
||||||
SELECT_VALUE(0x1F5700_b, 0x39A620_b), &db_try_load_x_file_internal);
|
db_init_load_x_file_hook.create(SELECT_VALUE(0x1C46E0_b, 0x3681E0_b), db_init_load_x_file_stub);
|
||||||
db_find_xasset_header_hook.create(game::DB_FindXAssetHeader, db_find_xasset_header_stub);
|
db_find_xasset_header_hook.create(game::DB_FindXAssetHeader, db_find_xasset_header_stub);
|
||||||
|
|
||||||
db_unload_x_zones_hook.create(SELECT_VALUE(0x1F6040_b,
|
db_unload_x_zones_hook.create(SELECT_VALUE(0x1F6040_b,
|
||||||
|
@ -35,7 +35,7 @@ namespace gsc
|
|||||||
std::unordered_map<std::string, std::uint32_t> init_handles;
|
std::unordered_map<std::string, std::uint32_t> init_handles;
|
||||||
|
|
||||||
utils::memory::allocator scriptfile_allocator;
|
utils::memory::allocator scriptfile_allocator;
|
||||||
std::unordered_map<const char*, game::ScriptFile*> loaded_scripts;
|
std::unordered_map<std::string, game::ScriptFile*> loaded_scripts;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -136,8 +136,10 @@ namespace imagefiles
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* pakfile_open_stub(void* /*handles*/, unsigned int count, int is_imagefile,
|
void* pakfile_open_stub(void* /*handles*/, unsigned int count, int is_imagefile,
|
||||||
unsigned int index, int is_localized)
|
unsigned int index, short is_localized)
|
||||||
{
|
{
|
||||||
|
console::debug("Opening %s%d.pak (localized:%d)\n", is_imagefile ? "imagefile" : "soundfile", index, is_localized);
|
||||||
|
|
||||||
if (index != CUSTOM_IMAGE_FILE_INDEX)
|
if (index != CUSTOM_IMAGE_FILE_INDEX)
|
||||||
{
|
{
|
||||||
return utils::hook::invoke<void*>(
|
return utils::hook::invoke<void*>(
|
||||||
|
@ -46,6 +46,11 @@ namespace lui
|
|||||||
public:
|
public:
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
{
|
{
|
||||||
|
if (game::environment::is_dedi())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (game::environment::is_mp())
|
if (game::environment::is_mp())
|
||||||
{
|
{
|
||||||
// Patch game message overflow
|
// Patch game message overflow
|
||||||
|
@ -1144,9 +1144,15 @@ namespace party
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
server_connection_state.base_url = info.get("sv_wwwBaseUrl");
|
||||||
|
|
||||||
|
if (download_files(target, info, false))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
server_connection_state.motd = info.get("sv_motd");
|
server_connection_state.motd = info.get("sv_motd");
|
||||||
server_connection_state.max_clients = std::stoi(info.get("sv_maxclients"));
|
server_connection_state.max_clients = std::stoi(info.get("sv_maxclients"));
|
||||||
server_connection_state.base_url = info.get("sv_wwwBaseUrl");
|
|
||||||
|
|
||||||
discord_information discord_info{};
|
discord_information discord_info{};
|
||||||
discord_info.image = info.get("sv_discordImageUrl");
|
discord_info.image = info.get("sv_discordImageUrl");
|
||||||
@ -1156,11 +1162,6 @@ namespace party
|
|||||||
server_discord_info.emplace(discord_info);
|
server_discord_info.emplace(discord_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (download_files(target, info, false))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect_to_party(target, mapname, gametype);
|
connect_to_party(target, mapname, gametype);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2418,6 +2418,12 @@ namespace game
|
|||||||
DB_AuthSignature signature;
|
DB_AuthSignature signature;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DBFile
|
||||||
|
{
|
||||||
|
char __pad0[32];
|
||||||
|
char name[64];
|
||||||
|
};
|
||||||
|
|
||||||
namespace hks
|
namespace hks
|
||||||
{
|
{
|
||||||
struct lua_State;
|
struct lua_State;
|
||||||
|
@ -158,7 +158,6 @@ FARPROC load_binary(const launcher::mode mode, uint64_t* base_address)
|
|||||||
void remove_crash_file()
|
void remove_crash_file()
|
||||||
{
|
{
|
||||||
utils::io::remove_file("__h1Exe");
|
utils::io::remove_file("__h1Exe");
|
||||||
utils::io::remove_file("h1-mod\\h1_mp64_ship.exe"); // remove this at some point
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void enable_dpi_awareness()
|
void enable_dpi_awareness()
|
||||||
|
Loading…
Reference in New Issue
Block a user