feat: noclip/ufo methods

This commit is contained in:
Diavolo 2023-04-05 13:07:13 +02:00
parent ed838b3212
commit 5d5eb00bb8
No known key found for this signature in database
GPG Key ID: FA77F074E98D98A5
3 changed files with 82 additions and 37 deletions

View File

@ -5,24 +5,16 @@
#include "command.hpp" #include "command.hpp"
#include "scheduler.hpp" #include "scheduler.hpp"
#include "gsc/script_error.hpp"
#include <utils/hook.hpp>
#include <utils/string.hpp> #include <utils/string.hpp>
static const game::native::dvar_t* g_cheats; namespace
class client_command final : public module
{ {
public: const game::native::dvar_t* g_cheats;
void post_load() override
{
if (game::is_mp())
{
g_cheats = game::native::Dvar_RegisterBool("sv_cheats", true, game::native::DVAR_CODINFO, "Enable cheats");
add_mp_client_commands();
}
}
private: bool cheats_ok(game::native::gentity_s* ent)
static bool cheats_ok(game::native::gentity_s* ent)
{ {
if (!g_cheats->current.enabled) if (!g_cheats->current.enabled)
{ {
@ -41,7 +33,7 @@ private:
return true; return true;
} }
static bool cheats_ok_internal(game::native::sp::gentity_s* ent) bool cheats_ok_internal(game::native::sp::gentity_s* ent)
{ {
if (ent->health < 1) if (ent->health < 1)
{ {
@ -52,29 +44,61 @@ private:
return true; return true;
} }
void cmd_noclip_f(game::native::gentity_s* ent, [[maybe_unused]] const command::params_sv& params)
{
if (!cheats_ok(ent))
return;
ent->client->flags ^= 1;
game::native::mp::SV_GameSendServerCommand(ent->s.number, game::native::SV_CMD_CAN_IGNORE,
utils::string::va("%c \"%s\"", 0x65, (ent->client->flags & 1) ? "GAME_NOCLIPON" : "GAME_NOCLIPOFF"));
}
void cmd_ufo_f(game::native::gentity_s* ent, [[maybe_unused]] const command::params_sv& params)
{
if (!cheats_ok(ent))
return;
ent->client->flags ^= 2;
game::native::mp::SV_GameSendServerCommand(ent->s.number, game::native::SV_CMD_CAN_IGNORE,
utils::string::va("%c \"%s\"", 0x65, (ent->client->flags & 2) ? "GAME_UFOON" : "GAME_UFOOFF"));
}
void player_cmd_noclip(game::native::scr_entref_t entref)
{
auto* ent = gsc::get_player_entity(entref);
cmd_noclip_f(ent, command::params_sv{});
}
void player_cmd_ufo(game::native::scr_entref_t entref)
{
auto* ent = gsc::get_player_entity(entref);
cmd_ufo_f(ent, command::params_sv{});
}
}
class client_command final : public module
{
public:
void post_load() override
{
if (game::is_mp())
{
g_cheats = game::native::Dvar_RegisterBool("sv_cheats", true, game::native::DVAR_CODINFO, "Enable cheats");
add_mp_client_commands();
utils::hook::set<game::native::BuiltinMethod>(0x7FDBC8, player_cmd_noclip);
utils::hook::set<game::native::BuiltinMethod>(0x7FDBD4, player_cmd_ufo);
}
}
private:
static void add_mp_client_commands() static void add_mp_client_commands()
{ {
command::add_sv("noclip", [](game::native::gentity_s* ent, [[maybe_unused]] const command::params_sv& params) command::add_sv("noclip", cmd_noclip_f);
{ command::add_sv("ufo", cmd_ufo_f);
if (!cheats_ok(ent))
return;
ent->client->flags ^= 1;
game::native::mp::SV_GameSendServerCommand(ent->s.number, game::native::SV_CMD_CAN_IGNORE,
utils::string::va("%c \"%s\"", 0x65, (ent->client->flags & 1) ? "GAME_NOCLIPON" : "GAME_NOCLIPOFF"));
});
command::add_sv("ufo", [](game::native::gentity_s* ent, [[maybe_unused]] const command::params_sv& params)
{
if (!cheats_ok(ent))
return;
ent->client->flags ^= 2;
game::native::mp::SV_GameSendServerCommand(ent->s.number, game::native::SV_CMD_CAN_IGNORE,
utils::string::va("%c \"%s\"", 0x65, (ent->client->flags & 2) ? "GAME_UFOON" : "GAME_UFOOFF"));
});
command::add_sv("god", [](game::native::gentity_s* ent, [[maybe_unused]] const command::params_sv& params) command::add_sv("god", [](game::native::gentity_s* ent, [[maybe_unused]] const command::params_sv& params)
{ {

View File

@ -447,15 +447,35 @@ namespace gsc
game::native::gentity_s* get_entity(game::native::scr_entref_t entref) game::native::gentity_s* get_entity(game::native::scr_entref_t entref)
{ {
if (entref.classnum != 0) if (entref.classnum)
{ {
scr_error("not an entity"); scr_error("not an entity");
return nullptr; return nullptr;
} }
assert(entref.entnum < game::native::MAX_GENTITIES);
return &game::native::g_entities[entref.entnum]; return &game::native::g_entities[entref.entnum];
} }
game::native::gentity_s* get_player_entity(game::native::scr_entref_t entref)
{
if (entref.classnum)
{
scr_error("not an entity");
return nullptr;
}
assert(entref.entnum < game::native::MAX_GENTITIES);
auto* ent = &game::native::g_entities[entref.entnum];
if (!ent->client)
{
scr_error(va("entity %i is not a player", entref.entnum));
return nullptr;
}
return ent;
}
class error final : public module class error final : public module
{ {
public: public:

View File

@ -17,6 +17,7 @@ namespace gsc
const char* scr_get_type_name(unsigned int index); const char* scr_get_type_name(unsigned int index);
game::native::gentity_s* get_entity(game::native::scr_entref_t entref); game::native::gentity_s* get_entity(game::native::scr_entref_t entref);
game::native::gentity_s* get_player_entity(game::native::scr_entref_t entref);
void scr_error(const char* error); void scr_error(const char* error);
} }