[Paintball]: Added module
This commit is contained in:
parent
9ae08588fa
commit
81f6cfa9a6
@ -64,6 +64,7 @@ namespace Components
|
||||
Register(new GUI());
|
||||
Register(new Markdown());
|
||||
Register(new Changelog());
|
||||
Register(new Paintball());
|
||||
|
||||
Pregame = false;
|
||||
// Make sure preDestroy is called when the game shuts down
|
||||
|
@ -82,3 +82,4 @@ namespace Components
|
||||
#include "Modules/GUI/GUI.hpp"
|
||||
#include "Modules/GUI/Markdown.hpp"
|
||||
#include "Modules/Changelog.hpp"
|
||||
#include "Modules/Paintball.hpp"
|
||||
|
@ -34,6 +34,7 @@ namespace Dvars
|
||||
// Player settings dvars
|
||||
Game::dvar_s* p_allowFire = nullptr;
|
||||
Game::dvar_s* player_sprintUnlimited = nullptr;
|
||||
Game::dvar_s* paintball_mode = nullptr;
|
||||
|
||||
Game::dvar_s* external_console = nullptr;
|
||||
|
||||
|
@ -34,6 +34,7 @@ namespace Dvars
|
||||
// Player settings dvars
|
||||
extern Game::dvar_s* p_allowFire;
|
||||
extern Game::dvar_s* player_sprintUnlimited;
|
||||
extern Game::dvar_s* paintball_mode;
|
||||
|
||||
extern Game::dvar_s* external_console;
|
||||
|
||||
|
@ -6,6 +6,8 @@ namespace Components
|
||||
Utils::ConcurrentList::Container<Events::Callback> Events::ShutdownSystemTasks_;
|
||||
Utils::ConcurrentList::Container<Events::ScriptShutdownCallback> Events::ScriptsShutdownTasks_;
|
||||
Utils::ConcurrentList::Container<Events::Callback> Events::OnMapLoadTasks_;
|
||||
Utils::ConcurrentList::Container<Events::Callback> Events::RegisterGraphic_;
|
||||
Utils::ConcurrentList::Container<Events::Callback> Events::RegisterSound_;
|
||||
|
||||
void Events::OnDvarInit(const std::function<void()>& callback)
|
||||
{
|
||||
@ -39,6 +41,22 @@ namespace Components
|
||||
});
|
||||
}
|
||||
|
||||
void Events::RegisterGraphic(const std::function<void()>& callback)
|
||||
{
|
||||
RegisterGraphic_.access([&callback](Callback& tasks)
|
||||
{
|
||||
tasks.emplace_back(callback);
|
||||
});
|
||||
}
|
||||
|
||||
void Events::RegisterSound(const std::function<void()>& callback)
|
||||
{
|
||||
RegisterSound_.access([&callback](Callback& tasks)
|
||||
{
|
||||
tasks.emplace_back(callback);
|
||||
});
|
||||
}
|
||||
|
||||
void Events::Com_InitDvars_stub()
|
||||
{
|
||||
DvarInitTasks_.access([](Callback& tasks)
|
||||
@ -107,6 +125,32 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
void Events::CG_InitStub(const char* mapname)
|
||||
{
|
||||
RegisterGraphic_.access([](Callback& tasks)
|
||||
{
|
||||
for (const auto& func : tasks)
|
||||
{
|
||||
func();
|
||||
}
|
||||
});
|
||||
|
||||
Utils::Hook::Call<void(const char*)>(0x41FE10)(mapname); // CG_RegisterGraphics
|
||||
}
|
||||
|
||||
void Events::SV_SpawnServerStub()
|
||||
{
|
||||
RegisterSound_.access([](Callback& tasks)
|
||||
{
|
||||
for (const auto& func : tasks)
|
||||
{
|
||||
func();
|
||||
}
|
||||
});
|
||||
|
||||
Utils::Hook::Call<void()>(0x41F8F0)(); //CG_RegisterSounds
|
||||
}
|
||||
|
||||
Events::Events()
|
||||
{
|
||||
Utils::Hook(0x534B15, Com_InitDvars_stub, HOOK_CALL).install()->quick();
|
||||
@ -118,6 +162,10 @@ namespace Components
|
||||
Utils::Hook(0x5C657C, SV_ShutdownGameVM_Hk, HOOK_CALL).install()->quick();
|
||||
|
||||
Utils::Hook(0x5C7748, Scr_OnMapLoadStub, HOOK_CALL).install()->quick();
|
||||
|
||||
// For custom object 'cgMediaMod'
|
||||
Utils::Hook(0x421011, CG_InitStub, HOOK_CALL).install()->quick();
|
||||
Utils::Hook(0x5C7638, SV_SpawnServerStub, HOOK_CALL).install()->quick();
|
||||
}
|
||||
|
||||
Events::~Events()
|
||||
|
@ -15,13 +15,19 @@ namespace Components
|
||||
static void OnScriptsShutdown(const std::function<void(int clearScripts)>& callback);
|
||||
static void OnVMShutdown(const std::function<void()>& callback);
|
||||
static void OnMapLoad(const std::function<void()>& callback);
|
||||
static void RegisterGraphic(const std::function<void()>& callback);
|
||||
static void RegisterSound(const std::function<void()>& callback);
|
||||
private:
|
||||
static Utils::ConcurrentList::Container<Callback> DvarInitTasks_;
|
||||
static Utils::ConcurrentList::Container<ScriptShutdownCallback> ScriptsShutdownTasks_;
|
||||
static Utils::ConcurrentList::Container<Callback> ShutdownSystemTasks_;
|
||||
static Utils::ConcurrentList::Container<Callback> OnMapLoadTasks_;
|
||||
static Utils::ConcurrentList::Container<Callback> RegisterGraphic_;
|
||||
static Utils::ConcurrentList::Container<Callback> RegisterSound_;
|
||||
|
||||
static void Com_InitDvars_stub();
|
||||
static void CG_InitStub(const char* mapname);
|
||||
static void SV_SpawnServerStub();
|
||||
static void Scr_OnMapLoadStub(int channel, const char* message, const char* format);
|
||||
static void Scr_ShutdownSystem_Hk(unsigned char sys);
|
||||
static void SV_ShutdownGameVM_Hk();
|
||||
|
217
src/Components/Modules/Paintball.cpp
Normal file
217
src/Components/Modules/Paintball.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
#include "STDInc.hpp"
|
||||
#include <random>
|
||||
namespace Components
|
||||
{
|
||||
bool Paintball::PB_Enabled()
|
||||
{
|
||||
return !Game::HasLoadedMod() && Dvars::paintball_mode->current.enabled;
|
||||
}
|
||||
|
||||
const Game::FxEffectDef* Paintball::GetEffect()
|
||||
{
|
||||
const std::vector<const Game::FxEffectDef*> effects = {
|
||||
Game::cgMediaMod.fxPaintBallGreen,
|
||||
Game::cgMediaMod.fxPaintBallOrange,
|
||||
Game::cgMediaMod.fxPaintBallBlue,
|
||||
Game::cgMediaMod.fxPaintBallRed,
|
||||
Game::cgMediaMod.fxPaintBallYellow
|
||||
};
|
||||
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<> distr(0, effects.size() - 1);
|
||||
|
||||
int randomIndex = distr(gen);
|
||||
|
||||
return effects[randomIndex];
|
||||
}
|
||||
|
||||
const Game::FxEffectDef* Paintball::GetExplosiveEffect()
|
||||
{
|
||||
const std::vector<const Game::FxEffectDef*> effects = {
|
||||
Game::cgMediaMod.fxPaintBallExpGreen,
|
||||
Game::cgMediaMod.fxPaintBallExpOrange
|
||||
};
|
||||
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<> distr(0, effects.size() - 1);
|
||||
|
||||
int randomIndex = distr(gen);
|
||||
|
||||
return effects[randomIndex];
|
||||
}
|
||||
|
||||
void Paintball::FireSound(Game::snd_alias_list_t* aliasList/*eax*/, int localClientNum, float* origin)
|
||||
{
|
||||
Game::snd_alias_list_t* soundAlias;
|
||||
if (PB_Enabled())
|
||||
{
|
||||
std::string soundAliasName = aliasList->aliasName;
|
||||
if (soundAliasName.ends_with("_plr"))
|
||||
soundAlias = Game::cgMediaMod.paintBallFirePlayer;
|
||||
else
|
||||
soundAlias = Game::cgMediaMod.paintBallFireNPC;
|
||||
}
|
||||
else
|
||||
soundAlias = aliasList;
|
||||
|
||||
Game::CG_PlayClientSoundAlias(soundAlias, localClientNum, origin);
|
||||
}
|
||||
|
||||
void Paintball::ImpactSound(Game::snd_alias_list_t* aliasList/*eax*/, int localClientNum, float* origin)
|
||||
{
|
||||
Game::snd_alias_list_t* soundAlias;
|
||||
if (PB_Enabled())
|
||||
{
|
||||
// Apply effect for bullets only!
|
||||
std::string soundAliasName = aliasList->aliasName;
|
||||
if (soundAliasName.starts_with("bullet_"))
|
||||
soundAlias = Game::cgMediaMod.paintBallImpact;
|
||||
else
|
||||
soundAlias = aliasList;
|
||||
}
|
||||
else
|
||||
soundAlias = aliasList;
|
||||
|
||||
Game::CG_PlayClientSoundAlias(soundAlias, localClientNum, origin);
|
||||
}
|
||||
|
||||
void Paintball::ImpactEffect(const Game::FxEffectDef* fxDef)
|
||||
{
|
||||
const Game::FxEffectDef* effect = PB_Enabled() ? GetEffect() : fxDef;
|
||||
unsigned int weaponIndex = Game::ps->weapon;
|
||||
Game::CG_PlayBoltedEffect(Game::cgs->localClientNum,
|
||||
Game::scr_const->tag_knife_fx,
|
||||
weaponIndex + 2176,
|
||||
effect);
|
||||
}
|
||||
|
||||
void Paintball::ImpactMark(int axis/*edx*/, int markEntnum/*ecx*/, const Game::FxEffectDef* fxDef, int msecBegin, const float* origin)
|
||||
{
|
||||
const Game::FxEffectDef* effect = PB_Enabled() ? GetEffect() : fxDef;
|
||||
Game::FX_SpawnOrientedEffect(axis, markEntnum, effect, msecBegin, origin);
|
||||
}
|
||||
|
||||
void Paintball::ImpactExplosion(const float* origin/*edx*/, int axis/*ecx*/, const Game::FxEffectDef* fxDef, int time)
|
||||
{
|
||||
const Game::FxEffectDef* effectExplosive = PB_Enabled() ? GetExplosiveEffect() : fxDef;
|
||||
Game::DynEntCl_PlayEventFx(origin, axis, effectExplosive, time);
|
||||
}
|
||||
|
||||
void __declspec(naked) Paintball::CG_PlayClientSoundAliasStub1()
|
||||
{
|
||||
const static uint32_t retn_addr = 0x434776;
|
||||
__asm
|
||||
{
|
||||
push eax;
|
||||
call FireSound;
|
||||
add esp, 4;
|
||||
jmp retn_addr;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) Paintball::CG_PlayClientSoundAliasStub2()
|
||||
{
|
||||
const static uint32_t retn_addr = 0x43536B;
|
||||
__asm
|
||||
{
|
||||
push eax;
|
||||
call ImpactSound;
|
||||
add esp, 4;
|
||||
jmp retn_addr;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) Paintball::CG_PlayBoltedEffectStub()
|
||||
{
|
||||
const static uint32_t retn_addr = 0x435510;
|
||||
__asm
|
||||
{
|
||||
call ImpactEffect
|
||||
jmp retn_addr;
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) Paintball::FX_CreateImpactMarkStub()
|
||||
{
|
||||
const static uint32_t retn_addr = 0x435404;
|
||||
__asm
|
||||
{
|
||||
//mov ecx, [esp + 4Ch];
|
||||
push ecx;
|
||||
|
||||
//lea edx, [esp + 20h];
|
||||
push edx;
|
||||
|
||||
call ImpactMark
|
||||
add esp, 0x8;
|
||||
jmp retn_addr;
|
||||
}
|
||||
}
|
||||
|
||||
//void DynEntCl_PlayEventFx(const float* origin/*edx*/, int axis/*ecx*/, const Game::FxEffectDef* def, int time)
|
||||
void __declspec(naked) Paintball::DynEntCl_PlayEventFxStub()
|
||||
{
|
||||
const static uint32_t retn_addr = 0x419A0F;
|
||||
__asm
|
||||
{
|
||||
push ecx;
|
||||
push edx;
|
||||
call ImpactExplosion;
|
||||
add esp, 0x8;
|
||||
jmp retn_addr;
|
||||
}
|
||||
}
|
||||
|
||||
Paintball::Paintball()
|
||||
{
|
||||
Events::OnDvarInit([]
|
||||
{
|
||||
Dvars::paintball_mode = Dvars::Register::Dvar_RegisterBool("paintball_mode", "Enable/Disable the paintball cheat", false, Game::saved_flag);
|
||||
});
|
||||
|
||||
Events::RegisterGraphic([]
|
||||
{
|
||||
if(Game::HasLoadedMod())
|
||||
return;
|
||||
// Bullets
|
||||
Game::cgMediaMod.fxPaintBallGreen = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_FX, "impacts/flesh_hit_pball_green").fx;
|
||||
Game::cgMediaMod.fxPaintBallOrange = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_FX, "impacts/flesh_hit_pball_orange").fx;
|
||||
Game::cgMediaMod.fxPaintBallBlue = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_FX, "impacts/flesh_hit_pball_blue").fx;
|
||||
Game::cgMediaMod.fxPaintBallRed = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_FX, "impacts/flesh_hit_pball_red").fx;
|
||||
Game::cgMediaMod.fxPaintBallYellow = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_FX, "impacts/flesh_hit_pball_yellow").fx;
|
||||
// Explosion
|
||||
Game::cgMediaMod.fxPaintBallExpGreen = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_FX, "explosions/exp_paintball_green").fx;
|
||||
Game::cgMediaMod.fxPaintBallExpOrange = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_FX, "explosions/exp_paintball_orange").fx;
|
||||
});
|
||||
|
||||
Events::RegisterSound([]
|
||||
{
|
||||
if(Game::HasLoadedMod())
|
||||
return;
|
||||
Game::cgMediaMod.paintBallFirePlayer = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_SOUND, "paintball_fire_plr").sound;
|
||||
Game::cgMediaMod.paintBallFireNPC = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_SOUND, "paintball_fire_npc").sound;
|
||||
Game::cgMediaMod.paintBallImpact = Game::DB_FindXAssetHeader(Game::ASSET_TYPE_SOUND, "paintball_impact").sound;
|
||||
});
|
||||
|
||||
// Hook the soundalias in 'CG_FireWeapon'
|
||||
Utils::Hook(0x434771, CG_PlayClientSoundAliasStub1, HOOK_JUMP).install()->quick();
|
||||
|
||||
// Hook the impact sound effect in 'CG_BulletHitEvent_Internal'
|
||||
Utils::Hook(0x435366, CG_PlayClientSoundAliasStub2, HOOK_JUMP).install()->quick();
|
||||
|
||||
// Hook the impact in 'CG_EntityEvent'
|
||||
Utils::Hook(0x43550B, CG_PlayBoltedEffectStub, HOOK_JUMP).install()->quick();
|
||||
|
||||
// Hook the impact in 'FX_SpawnOrientedEffect'
|
||||
Utils::Hook(0x4353FF, FX_CreateImpactMarkStub, HOOK_JUMP).install()->quick();
|
||||
|
||||
// Hook the explosion impact for grenade launchers, grenades, c4 and claymore in 'CG_EntityEvent'
|
||||
Utils::Hook(0x419A0A, DynEntCl_PlayEventFxStub, HOOK_JUMP).install()->quick();
|
||||
}
|
||||
|
||||
Paintball::~Paintball()
|
||||
{
|
||||
}
|
||||
}
|
26
src/Components/Modules/Paintball.hpp
Normal file
26
src/Components/Modules/Paintball.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class Paintball : public Component
|
||||
{
|
||||
public:
|
||||
Paintball();
|
||||
~Paintball();
|
||||
private:
|
||||
static bool PB_Enabled();
|
||||
static const Game::FxEffectDef* GetEffect();
|
||||
static const Game::FxEffectDef* GetExplosiveEffect();
|
||||
static void FireSound(Game::snd_alias_list_t* aliasList/*eax*/, int localClientNum, float* origin);
|
||||
static void ImpactSound(Game::snd_alias_list_t* aliasList/*eax*/, int localClientNum, float* origin);
|
||||
static void ImpactEffect(const Game::FxEffectDef* fxDef);
|
||||
static void ImpactMark(int axis/*edx*/, int markEntnum/*ecx*/, const Game::FxEffectDef* fxDef, int msecBegin, const float* origin);
|
||||
static void ImpactExplosion(const float* origin/*edx*/, int axis/*ecx*/, const Game::FxEffectDef* fxDef, int time);
|
||||
|
||||
static void CG_PlayClientSoundAliasStub1();
|
||||
static void CG_PlayClientSoundAliasStub2();
|
||||
static void CG_PlayBoltedEffectStub();
|
||||
static void FX_CreateImpactMarkStub();
|
||||
static void DynEntCl_PlayEventFxStub();
|
||||
};
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Game
|
||||
{
|
||||
Game::cgMedia_t_mod cgMediaMod = {};
|
||||
Game::gui_t gui = {};
|
||||
|
||||
bool HasLoadedMod()
|
||||
|
@ -9,6 +9,23 @@
|
||||
|
||||
namespace Game
|
||||
{
|
||||
// IW3SP-MOD cgMedia
|
||||
struct cgMedia_t_mod
|
||||
{
|
||||
// Paintball assets
|
||||
const FxEffectDef* fxPaintBallGreen;
|
||||
const FxEffectDef* fxPaintBallOrange;
|
||||
const FxEffectDef* fxPaintBallBlue;
|
||||
const FxEffectDef* fxPaintBallRed;
|
||||
const FxEffectDef* fxPaintBallYellow;
|
||||
const FxEffectDef* fxPaintBallExpGreen;
|
||||
const FxEffectDef* fxPaintBallExpOrange;
|
||||
snd_alias_list_t* paintBallFirePlayer;
|
||||
snd_alias_list_t* paintBallFireNPC;
|
||||
snd_alias_list_t* paintBallImpact;
|
||||
};
|
||||
|
||||
extern Game::cgMedia_t_mod cgMediaMod;
|
||||
extern Game::gui_t gui;
|
||||
|
||||
bool HasLoadedMod();
|
||||
|
Loading…
x
Reference in New Issue
Block a user