Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,19 +64,36 @@ GSC Entity fields:
- `self.noclip = <bool>` - toggles noclip
- `self.ufo = <bool>` - toggles ufomode
- `self.entityflags = <int>` - gentity flags e.g. `1` is godmode
- `self.forwardmove <int>` - **Read-Only** Player's forward/backward movement input (-127 = full backward, 127 = full forward, 0 = no input)
- `self.rightmove <int>` - **Read-Only** Player's left/right movement input (-127 = full left, 127 = full right, 0 = no input)

GSC Functions:

- `exec` Executes the given command on server as console command e.g. `exec("fast_restart");`

GSC Methods:

- `HoldBreathButtonPressed`
- `JumpButtonPressed`
- `NightVisionButtonPressed`
- `SetVelocity` - Changes current player velocity. `self setVelocity((0, 0, 300)); // Go up.`
- `CloneBrushModelToScriptModel`
- **HOST ONLY** `ButtonPressed` e.g. `self ButtonPressed("DPAD_DOWN")` - See **keynames** below for valid button identifiers.
- `ButtonPressed` - **HOST ONLY** - Check if a specific button is pressed.
- Usage: `self ButtonPressed("DPAD_DOWN")`
- See **keynames** below for valid button identifiers.
- `SprintBreathButtonPressed` - Check if the sprint button is pressed.
- `LeanLeftButtonPressed` - Check if the lean left button is pressed.
- `LeanRightButtonPressed` - Check if the lean right button is pressed.
- `JumpButtonPressed` - Check if the jump button is pressed.
- `HoldBreathButtonPressed` - Check if the hold breath button is pressed.
- `NightVisionButtonPressed` - Check if the night vision button is pressed.
- `ForwardButtonPressed` - Check if the player is moving forward (left stick up).
- `BackButtonPressed` - Check if the player is moving backward (left stick down).
- `LeftButtonPressed` - Check if the player is moving left (left stick left).
- `RightButtonPressed` - Check if the player is moving right (left stick right).
- `SetVelocity` - Changes current player velocity.

- Usage: `self setVelocity((0, 0, 300)); // Go up.`

- `CloneBrushModelToScriptModel` - Clones a brush model's geometry to a script model entity.
- Usage: `scriptModel CloneBrushModelToScriptModel(brushEntity);`
- `SetBrushModel` - Sets an entity's brush model by index.
- Usage: `entity SetBrushModel(index);`

<details>
<summary>keynames</summary>
Expand Down
6 changes: 4 additions & 2 deletions codxe.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@
<ClCompile Include="src\game\iw3\mp\components\cj_tas.cpp" />
<ClCompile Include="src\game\iw3\mp\components\clipmap.cpp" />
<ClCompile Include="src\game\iw3\mp\components\cmds.cpp" />
<ClCompile Include="src\game\iw3\mp\components\g_client_fields.cpp" />
<ClCompile Include="src\game\iw3\mp\components\g_scr_main.cpp" />
<ClCompile Include="src\game\iw3\mp\components\gsc_client_fields.cpp" />
<ClCompile Include="src\game\iw3\mp\components\gsc_methods.cpp" />
<ClCompile Include="src\game\iw3\mp\components\pm.cpp" />
<ClCompile Include="src\game\iw3\mp\components\mpsp.cpp" />
<ClCompile Include="src\game\iw3\mp\components\scr_parser.cpp" />
Expand Down Expand Up @@ -189,8 +190,9 @@
<ClInclude Include="src\game\iw3\mp\components\cj_tas.h" />
<ClInclude Include="src\game\iw3\mp\components\cmds.h" />
<ClInclude Include="src\game\iw3\mp\components\clipmap.h" />
<ClInclude Include="src\game\iw3\mp\components\g_client_fields.h" />
<ClInclude Include="src\game\iw3\mp\components\g_scr_main.h" />
<ClInclude Include="src\game\iw3\mp\components\gsc_client_fields.h" />
<ClInclude Include="src\game\iw3\mp\components\gsc_methods.h" />
<ClInclude Include="src\game\iw3\mp\components\pm.h" />
<ClInclude Include="src\game\iw3\mp\components\scr_parser.h" />
<ClInclude Include="src\game\iw3\mp\components\scr_vm_functions.h" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "pch.h"
#include "g_client_fields.h"
#include "gsc_client_fields.h"

const unsigned int CLIENT_FIELD_MASK = 0xC000;

Expand All @@ -10,16 +10,28 @@ namespace mp

void ClientScr_SetEntityFlags(gclient_s *pSelf, const client_fields_s *pField)
{
gentity_s *ent = &g_entities[g_clients - pSelf];
gentity_s *ent = &g_entities[pSelf - g_clients];
ent->flags = Scr_GetInt(0);
}

void ClientScr_GetEntityFlags(gclient_s *pSelf, const client_fields_s *field)
{
const gentity_s *ent = &g_entities[g_clients - pSelf];
const gentity_s *ent = &g_entities[pSelf - g_clients];
Scr_AddInt(ent->flags);
}

void ClientScr_GetForwardMove(gclient_s *pSelf, const client_fields_s *field)
{
const client_t *cl = &svsHeader->clients[pSelf - g_clients];
Scr_AddInt(cl->lastUsercmd.rightmove);
}

void ClientScr_GetRightMove(gclient_s *pSelf, const client_fields_s *field)
{
const client_t *cl = &svsHeader->clients[pSelf - g_clients];
Scr_AddInt(cl->lastUsercmd.forwardmove);
}

client_fields_s client_fields_extended[] = {
// Original fields
{"name", 0, F_LSTRING, ClientScr_ReadOnly, ClientScr_GetName},
Expand All @@ -44,6 +56,8 @@ client_fields_s client_fields_extended[] = {
{"noclip", 12456, F_INT, nullptr, nullptr},
{"ufo", 12460, F_INT, nullptr, nullptr},
{"entityflags", NULL, F_INT, ClientScr_SetEntityFlags, ClientScr_GetEntityFlags},
{"forwardmove", NULL, F_INT, ClientScr_ReadOnly, ClientScr_GetForwardMove},
{"rightmove", NULL, F_INT, ClientScr_ReadOnly, ClientScr_GetRightMove},

{nullptr, 0, F_INT, nullptr, nullptr}};

Expand Down Expand Up @@ -133,7 +147,7 @@ void Scr_GetEntityField_Hook(int entnum, int offset)
}
}

g_client_fields::g_client_fields()
gsc_client_fields::gsc_client_fields()
{
GScr_AddFieldsForClient_Detour = Detour(GScr_AddFieldsForClient, GScr_AddFieldsForClient_Hook);
GScr_AddFieldsForClient_Detour.Install();
Expand All @@ -145,7 +159,7 @@ g_client_fields::g_client_fields()
Scr_SetEntityField_Detour.Install();
}

g_client_fields::~g_client_fields()
gsc_client_fields::~gsc_client_fields()
{
GScr_AddFieldsForClient_Detour.Remove();
Scr_GetEntityField_Detour.Remove();
Expand Down
21 changes: 21 additions & 0 deletions src/game/iw3/mp/components/gsc_client_fields.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include "pch.h"

namespace iw3
{
namespace mp
{
class gsc_client_fields : public Module
{
public:
gsc_client_fields();
~gsc_client_fields();

const char *get_name() override
{
return "gsc_client_fields";
};
};
} // namespace mp
} // namespace iw3
201 changes: 201 additions & 0 deletions src/game/iw3/mp/components/gsc_methods.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
// cod4x

#include "pch.h"
#include "g_scr_main.h"
#include "gsc_methods.h"

namespace iw3
{
namespace mp
{

// #define KEY_MASK_FIRE 1
#define KEY_MASK_SPRINT 2
// #define KEY_MASK_MELEE 4
// #define KEY_MASK_RELOAD 16
#define KEY_MASK_LEANLEFT 64
#define KEY_MASK_LEANRIGHT 128
// #define KEY_MASK_PRONE 256
// #define KEY_MASK_CROUCH 512
#define KEY_MASK_JUMP 1024
// #define KEY_MASK_ADS_MODE 2048
// #define KEY_MASK_TEMP_ACTION 4096
#define KEY_MASK_HOLDBREATH 8192
// #define KEY_MASK_FRAG 16384
// #define KEY_MASK_SMOKE 32768
#define KEY_MASK_NIGHTVISION 262144
// #define KEY_MASK_ADS 524288
// #define KEY_MASK_USE 8
// #define KEY_MASK_USERELOAD 0x20
// #define BUTTON_ATTACK KEY_MASK_FIRE

int CL_IsKeyPressed(const int localClientNum, const char *keyName)
{
const int keynum = Key_StringToKeynum(keyName);
if (keynum >= 0)
return playerKeys[0].keys[keynum].down;
else
return 0;
}

void PlayerCmd_ButtonPressed(scr_entref_t entref)
{
if (entref.classnum != 0)
Scr_ObjectError("not an entity");

char *button = Scr_GetString(0);
if (!button || !*button)
Scr_Error("usage: <client> buttonPressed(<button name>)");

// toupper
for (char *p = button; *p; p++)
if (*p >= 'a' && *p <= 'z')
*p -= 32;

const int keypressed = CL_IsKeyPressed(0, button);
return Scr_AddInt(keypressed);
}

void PlayerCmd_SprintButtonPressed(scr_entref_t entref)
{
const gentity_s *ent = GetPlayerEntity(entref);
Scr_AddInt(((ent->client->buttonsSinceLastFrame | ent->client->buttons) & KEY_MASK_SPRINT) != 0);
}

void PlayerCmd_LeanLeftButtonPressed(scr_entref_t entref)
{
const gentity_s *ent = GetPlayerEntity(entref);
Scr_AddInt(((ent->client->buttonsSinceLastFrame | ent->client->buttons) & KEY_MASK_LEANLEFT) != 0);
}

void PlayerCmd_LeanRightButtonPressed(scr_entref_t entref)
{
const gentity_s *ent = GetPlayerEntity(entref);
Scr_AddInt(((ent->client->buttonsSinceLastFrame | ent->client->buttons) & KEY_MASK_LEANRIGHT) != 0);
}

void PlayerCmd_JumpButtonPressed(scr_entref_t entref)
{
const gentity_s *ent = GetPlayerEntity(entref);
Scr_AddInt(((ent->client->buttonsSinceLastFrame | ent->client->buttons) & KEY_MASK_JUMP) != 0);
}

void PlayerCmd_HoldBreathButtonPressed(scr_entref_t entref)
{
const gentity_s *ent = GetPlayerEntity(entref);
Scr_AddInt(((ent->client->buttonsSinceLastFrame | ent->client->buttons) & KEY_MASK_HOLDBREATH) != 0);
}

void PlayerCmd_NightVisionButtonPressed(scr_entref_t entref)
{
const gentity_s *ent = GetPlayerEntity(entref);
Scr_AddInt(((ent->client->buttonsSinceLastFrame | ent->client->buttons) & KEY_MASK_NIGHTVISION) != 0);
}

void PlayerCmd_ForwardButtonPressed(scr_entref_t entref)
{
const gentity_s *ent = GetPlayerEntity(entref);
const client_t *cl = &svsHeader->clients[ent->s.number];

Scr_AddInt(cl->lastUsercmd.forwardmove > 0);
}

void PlayerCmd_BackButtonPressed(scr_entref_t entref)
{
const gentity_s *ent = GetPlayerEntity(entref);
const client_t *cl = &svsHeader->clients[ent->s.number];

Scr_AddInt(cl->lastUsercmd.forwardmove < 0);
}

void PlayerCmd_LeftButtonPressed(scr_entref_t entref)
{
const gentity_s *ent = GetPlayerEntity(entref);
const client_t *cl = &svsHeader->clients[ent->s.number];

Scr_AddInt(cl->lastUsercmd.rightmove < 0);
}

void PlayerCmd_RightButtonPressed(scr_entref_t entref)
{
const gentity_s *ent = GetPlayerEntity(entref);
const client_t *cl = &svsHeader->clients[ent->s.number];

Scr_AddInt(cl->lastUsercmd.rightmove > 0);
}

void PlayerCmd_SetVelocity(scr_entref_t entref)
{
gentity_s *ent = GetPlayerEntity(entref);

if (Scr_GetNumParam() != 1)
Scr_Error("Usage: <client> SetVelocity( vec3 )\n");

float velocity[3] = {0};

Scr_GetVector(0, velocity);

ent->client->ps.velocity[0] = velocity[0];
ent->client->ps.velocity[1] = velocity[1];
ent->client->ps.velocity[2] = velocity[2];
}

void GScr_CloneBrushModelToScriptModel(scr_entref_t entref)
{
gentity_s *scriptEnt = GetEntity(entref);
gentity_s *brushEnt = Scr_GetEntity(0);

SV_UnlinkEntity(scriptEnt);
scriptEnt->s.index = brushEnt->s.index;
int contents = scriptEnt->r.contents;
SV_SetBrushModel(scriptEnt);
scriptEnt->r.contents |= contents;
SV_LinkEntity(scriptEnt);
}

void GScr_SetBrushModel(scr_entref_t entref)
{
if (Scr_GetNumParam() != 1)
Scr_Error("usage: <entity> SetBrushModel( <index> )\n");

gentity_s *ent = GetEntity(entref);
const int index = Scr_GetInt(0);

if (index < 0 || (unsigned int)index >= cm->numSubModels)
{
Scr_ParamError(0, "brush model index out of range");
}

SV_UnlinkEntity(ent);
ent->s.index = index;

SV_SetBrushModel(ent);
SV_LinkEntity(ent);
}

gsc_methods::gsc_methods()
{
// Player entity methods
Scr_AddMethod("buttonpressed", PlayerCmd_ButtonPressed, 0); // Host-only
Scr_AddMethod("sprintbreathbuttonpressed", PlayerCmd_SprintButtonPressed, 0);
Scr_AddMethod("leanleftbuttonpressed", PlayerCmd_LeanLeftButtonPressed, 0);
Scr_AddMethod("leanrightbuttonpressed", PlayerCmd_LeanRightButtonPressed, 0);
Scr_AddMethod("jumpbuttonpressed", PlayerCmd_JumpButtonPressed, 0);
Scr_AddMethod("holdbreathbuttonpressed", PlayerCmd_HoldBreathButtonPressed, 0);
Scr_AddMethod("nightvisionbuttonpressed", PlayerCmd_NightVisionButtonPressed, 0);
Scr_AddMethod("forwardbuttonpressed", PlayerCmd_ForwardButtonPressed, 0);
Scr_AddMethod("backbuttonpressed", PlayerCmd_BackButtonPressed, 0);
Scr_AddMethod("leftbuttonpressed", PlayerCmd_LeftButtonPressed, 0);
Scr_AddMethod("rightbuttonpressed", PlayerCmd_RightButtonPressed, 0);
Scr_AddMethod("setvelocity", PlayerCmd_SetVelocity, 0);

// Script entity methods
Scr_AddMethod("clonebrushmodeltoscriptmodel", GScr_CloneBrushModelToScriptModel, 0);
Scr_AddMethod("setbrushmodel", GScr_SetBrushModel, 0);
}

gsc_methods::~gsc_methods()
{
}
} // namespace mp
} // namespace iw3
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ namespace iw3
{
namespace mp
{
class g_client_fields : public Module
class gsc_methods : public Module
{
public:
g_client_fields();
~g_client_fields();
gsc_methods();
~gsc_methods();

const char *get_name() override
{
return "g_client_fields";
return "gsc_methods";
};
};
} // namespace mp
Expand Down
Loading