43 Commits

Author SHA1 Message Date
Wizzard
c7ee48dfa6 Added game by game detection to help fix certain issues with specific games 2023-09-19 13:16:13 -04:00
Wizzard
a7b30ca7f8 Note about watermark 2023-09-19 11:54:58 -04:00
Wizzard
1f3e531610 Revert "Fix cvars not showing up"
This reverts commit 0e7f955c7d.
2023-09-19 10:55:51 -04:00
Wizzard
0e7f955c7d Fix cvars not showing up 2023-09-19 10:54:04 -04:00
Wizzard
f0485a3f36 Change cvar from 'cv_' to 'dz_' 2023-09-19 10:45:57 -04:00
Wizzard
02888c1158 Fix links 2023-09-19 10:42:56 -04:00
Wizzard
b9851de177 Fix readme 2023-09-19 10:40:05 -04:00
Wizzard
56f8ae79d7 Added cv_watermark 2023-09-19 10:38:01 -04:00
8dcc
f9db9ff1b6 Change value of cl_forwardspeed 2023-08-05 00:50:28 +02:00
8dcc
29a40f63da Add missing unload to include 2023-08-01 19:53:43 +02:00
8dcc
b7c6e74dd4 README - Add supported games 2023-08-01 13:35:36 +02:00
8dcc
510243c46d Add can_shoot to aimbot 2023-07-31 20:57:25 +02:00
8dcc
fb6ed02dd4 Add clip check to can_shoot 2023-07-31 20:10:45 +02:00
8dcc
42a7961142 Store clip from HUD_PostRunCmd 2023-07-31 20:10:27 +02:00
8dcc
da6cf86910 README - Add autoshoot to features 2023-07-31 18:06:21 +02:00
8dcc
3414d131f4 Add autoshoot
If this cvar is enabled (1), and the aimbot is enabled (fov>0), it will
stop attacking if there is no visible target.
2023-07-31 18:03:26 +02:00
8dcc
83278b9983 Change head offset if crouched 2023-07-31 18:03:14 +02:00
8dcc
4bb21a4ca6 Fix fov calculations, fix aimbot head offset 2023-07-31 17:40:01 +02:00
8dcc
51c302f492 Add alive check to localplayer 2023-07-31 16:10:47 +02:00
8dcc
865a02a8cd README - Add tracers feature 2023-07-31 15:57:23 +02:00
8dcc
d09fdf66b5 Add bullet tracers 2023-07-31 15:55:01 +02:00
8dcc
87e6b34eee Add cv_tracers cvar 2023-07-31 15:54:47 +02:00
8dcc
cd3fde56a3 Hook HUD_PostRunCmd and store NextAttacks 2023-07-31 15:36:41 +02:00
8dcc
3d3ebd7c5a Add can_shoot and draw_tracer to util.c 2023-07-31 15:36:09 +02:00
8dcc
7cf0b30495 Add g_flNextAttack and g_flNextPrimaryAttack 2023-07-31 15:35:44 +02:00
8dcc
70a69c1fc8 Add is_visible check to aimbot 2023-07-30 23:53:39 +02:00
8dcc
e26d5639c2 Add aim punch compensation to aimbot 2023-07-30 20:05:33 +02:00
8dcc
0625638e31 Hook CalcRefdef, store punchAngles 2023-07-30 20:05:22 +02:00
8dcc
56fa55a751 Add g_punchAngles 2023-07-30 20:05:12 +02:00
8dcc
bb6c9efc50 Modify vec_copy so it supports float[] 2023-07-30 20:04:28 +02:00
8dcc
04720aa4a3 README - Add aimbot cvar to features, fix typo 2023-07-30 15:09:49 +02:00
8dcc
d5cfc33837 Change remainder func in vec_norm
remainderf -> remainder
2023-07-30 15:07:40 +02:00
8dcc
77e8b04214 Fix aimbot
cv_aimbot now indicates the aimbot fov
2023-07-30 15:07:10 +02:00
8dcc
772f4a1d7a Remove unnecessary check
Already checked in get_player()
2023-07-29 18:58:43 +02:00
8dcc
e43eeb2d3b Add the worst aimbot ever known to man 2023-07-29 17:35:45 +02:00
8dcc
762368d75f Optimize some vector functions, replace vec_copy with macro 2023-07-29 17:34:18 +02:00
8dcc
67f4c5ed88 Change REGISTER_CVAR macro
Remove manual initialization, remove string arguments to macro (convert
to str inside it with #name)
2023-07-29 16:27:01 +02:00
8dcc
e83dad0409 Add aimbot cvar 2023-07-29 16:24:59 +02:00
8dcc
e9f3031ca1 Add vec_sub, vec_norm, vec_to_ang and RAD2DEG to util 2023-07-29 16:23:26 +02:00
8dcc
9f64f544de Add event_api_s include to sdk.h 2023-07-29 16:23:11 +02:00
8dcc
3a514789a7 Add matrix_3x4 and bone_matrix to sdk.h 2023-07-28 23:12:20 +02:00
8dcc
8d735ece89 Add vec_copy and matrix_3x4_origin to util.c 2023-07-28 23:10:54 +02:00
8dcc
2a57c69444 Replace vector indexing with members
Use .x instead of [0]
Also add vec_add() to util.c
2023-07-28 22:15:25 +02:00
22 changed files with 495 additions and 74 deletions

View File

@@ -5,7 +5,7 @@ INCLUDES=-Isrc/include/sdk/common -Isrc/include/sdk/public -Isrc/include/sdk/pm_
CFLAGS=-Wall -Wextra -Wno-write-strings -m32 -fPIC $(INCLUDES) CFLAGS=-Wall -Wextra -Wno-write-strings -m32 -fPIC $(INCLUDES)
LDFLAGS=-lm LDFLAGS=-lm
OBJS=obj/main.c.o obj/globals.c.o obj/cvars.c.o obj/hooks.c.o obj/detour.c.o obj/util.c.o obj/features/movement.c.o obj/features/esp.c.o obj/features/chams.c.o obj/features/misc.c.o OBJS=obj/main.c.o obj/globals.c.o obj/cvars.c.o obj/hooks.c.o obj/detour.c.o obj/util.c.o obj/features/movement.c.o obj/features/esp.c.o obj/features/chams.c.o obj/features/aim.c.o obj/features/misc.c.o obj/game_detection.c.o
BIN=libhlcheat.so BIN=libhlcheat.so
.PHONY: clean all inject .PHONY: clean all inject

View File

@@ -1,14 +1,20 @@
#+title: Half-Life cheat #+title: Half-Life cheat
#+options: toc:nil #+options: toc:nil
#+startup: showeverything #+startup: showeverything
#+author: 8dcc #+author: Wizzard (Original arthur: [[https://github.com/8dcc/][8dcc]])
*Linux cheat for Half-Life 1 (and goldsrc).* *Linux cheat for goldsrc games.*
#+TOC: headlines 2 #+TOC: headlines 2
* Description * Description
Simple linux cheat for Half-Life 1 (and most /goldsrc/ games) made in C. Simple linux cheat for most goldsrc games, made in C.
Supported games:
- [[https://store.steampowered.com/app/70/HalfLife/][Half-Life 1]]
- [[https://store.steampowered.com/app/10/CounterStrike/][Counter-Strike 1.6]]
- [[https://store.steampowered.com/app/20/Team_Fortress_Classic/][Team Fortress Classic]]
- [[https://store.steampowered.com/app/30/Day_of_Defeat/][Day of Defeat]]
This project was heavily inspired by [[https://github.com/UnkwUsr/hlhax][UnkwUsr/hlhax]], and would not have been This project was heavily inspired by [[https://github.com/UnkwUsr/hlhax][UnkwUsr/hlhax]], and would not have been
possible without his help. Make sure to check out his repo too. possible without his help. Make sure to check out his repo too.
@@ -19,22 +25,44 @@ Also make sure to check out [[https://github.com/deboogerxyz/ahc][deboogerxyz/ah
| Feature | Command | Values (0..n) | | Feature | Command | Values (0..n) |
|------------+---------------+------------------------| |------------+---------------+------------------------|
| Bhop | =cv_bhop= | off/on | | Bhop | =dz_bhop= | off/on |
| ESP | =cv_esp= | off/3d-box/name/all | | Autostrafe | =dz_autostrafe= | off/rage/legit |
| Autostrafe | =sv_autostrafe= | off/rage/legit | | Aimbot | =dz_aimbot= | off/fov* |
| Chams | =cv_chams= | off/players/hands/all* | | Autoshoot | =dz_autoshoot= | off/on* |
| Crosshair | =cv_crosshair= | off/length | | ESP | =dz_esp= | off/3d-box/name/all |
| Chams | =dz_chams= | off/players/hands/all* |
| Crosshair | =dz_crosshair= | off/length |
| Tracers | =dz_tracers= | off/on* |
#+begin_quote
*Note:* Aimbot FOV goes from 0 (off) to 180 (all enemies)
#+end_quote
#+begin_quote
*Note:* If =dz_autoshoot= is enabled, and =dz_aimbot= is enabled, it will stop
attacking if there is no visible target.
#+end_quote
#+begin_quote #+begin_quote
*Note:* Chams color can be changed from the =h_glColor4f()= function inside *Note:* Chams color can be changed from the =h_glColor4f()= function inside
[[https://github.com/8dcc/hl-cheat/blob/main/src/hooks.c][src/hooks.c]]. Since this cheat is not hard to compile, I rather have less [[https://git.deadzone.lol/Wizzard/goldsource-cheat/src/branch/main/src/hooks.c][src/hooks.c]]. Since this cheat is not hard to compile, I rather have less
console variables than more customization at runtime. console variables than more customization at runtime.
#+end_quote #+end_quote
#+begin_quote
*Note:* Bullet tracer color, width and time can be changed at the bottom of the
=bullet_tracers()= function inside [[https://git.deadzone.lol/Wizzard/goldsource-cheat/src/branch/main/src/features/misc.c][src/features/misc.c]]. See previous chams note.
#+end_quote
#+begin_quote
*Note:* You can disable the watermark with dz_watermark 0
#+end_quote
* Building * Building
#+begin_src console #+begin_src console
$ git clone --recurse-submodules https://github.com/8dcc/hl-cheat $ git clone --recurse-submodules https://git.deadzone.lol/Wizzard/goldsource-cheat
$ cd hl-cheat $ cd goldsource-cheat
$ make $ make
... ...
#+end_src #+end_src
@@ -43,7 +71,7 @@ Note that you will need to clone with =--recurse-submodules= for the sdk. If you
have already cloned it, you can just: have already cloned it, you can just:
#+begin_src console #+begin_src console
$ cd hl-cheat $ cd goldsource-cheat
$ git submodule update --init --recursive $ git submodule update --init --recursive
#+end_src #+end_src
@@ -56,5 +84,5 @@ $ ./injector.sh
... ...
hl-cheat loaded! goldsource-cheat loaded!
#+end_src #+end_src

View File

@@ -30,7 +30,7 @@ if [ "$1" == "unload" ]; then
fi fi
if grep -q "$libpath" "/proc/$pid/maps"; then if grep -q "$libpath" "/proc/$pid/maps"; then
echo -e "hl-cheat already loaded. Reloading...\n"; echo -e "goldsource-cheat already loaded. Reloading...\n";
# 0x2 -> RTLD_NOW # 0x2 -> RTLD_NOW
# 0x6 -> RTLD_LAZY | RTLD_NOLOAD # 0x6 -> RTLD_LAZY | RTLD_NOLOAD

View File

@@ -5,18 +5,26 @@
DECL_CVAR(bhop); DECL_CVAR(bhop);
DECL_CVAR(autostrafe); DECL_CVAR(autostrafe);
DECL_CVAR(aimbot);
DECL_CVAR(autoshoot);
DECL_CVAR(esp); DECL_CVAR(esp);
DECL_CVAR(chams); DECL_CVAR(chams);
DECL_CVAR(crosshair); DECL_CVAR(crosshair);
DECL_CVAR(tracers);
DECL_CVAR(clmove); DECL_CVAR(clmove);
DECL_CVAR(watermark);
bool cvars_init(void) { bool cvars_init(void) {
cv_bhop = REGISTER_CVAR("bhop", "1"); REGISTER_CVAR(bhop, 1);
cv_autostrafe = REGISTER_CVAR("autostrafe", "0"); REGISTER_CVAR(autostrafe, 1);
cv_esp = REGISTER_CVAR("esp", "3"); REGISTER_CVAR(aimbot, 0);
cv_chams = REGISTER_CVAR("chams", "1"); REGISTER_CVAR(autoshoot, 0); /* Only works with aimbot enabled */
cv_crosshair = REGISTER_CVAR("crosshair", "0"); REGISTER_CVAR(esp, 3);
cv_clmove = REGISTER_CVAR("clmove", "0"); REGISTER_CVAR(chams, 1);
REGISTER_CVAR(crosshair, 0);
REGISTER_CVAR(tracers, 1);
REGISTER_CVAR(clmove, 0);
REGISTER_CVAR(watermark, 1);
return true; return true;
} }

106
src/features/aim.c Normal file
View File

@@ -0,0 +1,106 @@
#include <math.h>
#include "features.h"
#include "../include/sdk.h"
#include "../include/cvars.h"
#include "../include/util.h"
/* Game units to add to the entity origin to get the head */
#define HEAD_OFFSET 25.f
/* Scale factor for aim punch */
#define AIM_PUNCH_MULT 2
static bool is_visible(vec3_t start, vec3_t end) {
/* Syntax: PM_TraceLine(start, end, flags, usehulll, ignore_pe); */
pmtrace_t* tr =
i_engine->PM_TraceLine(start, end, PM_TRACELINE_PHYSENTSONLY, 2, -1);
/* We didn't hit a valid entity */
if (tr->ent <= 0)
return false;
/* Get entity index from physents, check if we can't get a valid player */
const int ent_idx = i_pmove->physents[tr->ent].info;
if (!get_player(ent_idx))
return false;
/* We hit a valid player */
return true;
}
static vec3_t get_closest_delta(vec3_t viewangles) {
/* Compensate aim punch. We get g_punchAngles from CalcRefdef hook */
viewangles.x += g_punchAngles.x * AIM_PUNCH_MULT;
viewangles.y += g_punchAngles.y * AIM_PUNCH_MULT;
viewangles.z += g_punchAngles.z * AIM_PUNCH_MULT;
vec3_t view_height;
i_engine->pEventAPI->EV_LocalPlayerViewheight(view_height);
vec3_t local_eyes = vec_add(localplayer->origin, view_height);
/* These 2 vars are used to store the best target across iterations.
* NOTE: The default value of best_fov will be the aimbot fov */
float best_fov = dz_aimbot->value;
vec3_t best_delta = { 0, 0, 0 };
for (int i = 1; i <= i_engine->GetMaxClients(); i++) {
cl_entity_t* ent = get_player(i);
if (!is_alive(ent) || is_friend(ent))
continue;
/* TODO: Get bones origin instead of calculating from ent origin */
vec3_t head_pos = ent->origin;
if (ent->curstate.usehull != 1) /* Get head if not crouched */
head_pos.z += HEAD_OFFSET;
if (!is_visible(local_eyes, head_pos)) /* We can't see player */
continue;
const vec3_t enemy_angle = vec_to_ang(vec_sub(head_pos, local_eyes));
const vec3_t delta = vec_sub(enemy_angle, viewangles);
vec_norm(delta);
float fov = hypotf(delta.x, delta.y);
if (fov > 360.0f)
fov = remainderf(fov, 360.0f);
if (fov > 180.0f)
fov = 360.0f - fov;
if (fov < best_fov) {
best_fov = fov;
vec_copy(best_delta, delta);
}
}
return best_delta;
}
void aimbot(usercmd_t* cmd) {
if (!CVAR_ON(aimbot) || !(cmd->buttons & IN_ATTACK) || !can_shoot())
return;
/* Calculate delta with the engine viewangles, not with the cmd ones */
vec3_t engine_viewangles;
i_engine->GetViewAngles(engine_viewangles);
/* TODO: Add setting for lowest health */
vec3_t best_delta = get_closest_delta(engine_viewangles);
if (!vec_is_zero(best_delta)) {
/* NOTE: We can divide the best delta here to add smoothing */
engine_viewangles.x += best_delta.x;
engine_viewangles.y += best_delta.y;
engine_viewangles.z += best_delta.z;
} else if (CVAR_ON(autoshoot)) {
/* No valid target and we have autoshoot, don't shoot */
cmd->buttons &= ~IN_ATTACK;
}
vec_copy(cmd->viewangles, engine_viewangles);
/* NOTE: Uncomment to disable silent aim */
/* i_engine->SetViewAngles(engine_viewangles); */
}

View File

@@ -15,7 +15,7 @@ enum chams_settings {
visible_flags visible_mode; visible_flags visible_mode;
bool chams(void* this_ptr) { bool chams(void* this_ptr) {
const int setting = cv_chams->value == 5.0f ? 7 : cv_chams->value; const int setting = dz_chams->value == 5.0f ? 7 : dz_chams->value;
if (setting == DISABLED) if (setting == DISABLED)
return false; return false;

View File

@@ -5,7 +5,7 @@
#include "../include/cvars.h" #include "../include/cvars.h"
#include "../include/util.h" #include "../include/util.h"
/* For cv_esp */ /* For dz_esp */
enum esp_values { enum esp_values {
ESP_OFF = 0, ESP_OFF = 0,
ESP_BOX = 1, ESP_BOX = 1,
@@ -36,14 +36,14 @@ bool gl_draw3dbox(vec3_t o, int bh, int bw, int lw) {
* |/ O|/ z(-) * |/ O|/ z(-)
* 7---8 * 7---8
*/ */
vec3_t p1 = vec3(o[0] - bw / 2, o[1] + bw / 2, o[2] + bh / 2); vec3_t p1 = vec3(o.x - bw / 2, o.y + bw / 2, o.z + bh / 2);
vec3_t p2 = vec3(o[0] + bw / 2, o[1] + bw / 2, o[2] + bh / 2); vec3_t p2 = vec3(o.x + bw / 2, o.y + bw / 2, o.z + bh / 2);
vec3_t p3 = vec3(o[0] - bw / 2, o[1] - bw / 2, o[2] + bh / 2); vec3_t p3 = vec3(o.x - bw / 2, o.y - bw / 2, o.z + bh / 2);
vec3_t p4 = vec3(o[0] + bw / 2, o[1] - bw / 2, o[2] + bh / 2); vec3_t p4 = vec3(o.x + bw / 2, o.y - bw / 2, o.z + bh / 2);
vec3_t p5 = vec3(o[0] - bw / 2, o[1] + bw / 2, o[2] - bh / 2); vec3_t p5 = vec3(o.x - bw / 2, o.y + bw / 2, o.z - bh / 2);
vec3_t p6 = vec3(o[0] + bw / 2, o[1] + bw / 2, o[2] - bh / 2); vec3_t p6 = vec3(o.x + bw / 2, o.y + bw / 2, o.z - bh / 2);
vec3_t p7 = vec3(o[0] - bw / 2, o[1] - bw / 2, o[2] - bh / 2); vec3_t p7 = vec3(o.x - bw / 2, o.y - bw / 2, o.z - bh / 2);
vec3_t p8 = vec3(o[0] + bw / 2, o[1] - bw / 2, o[2] - bh / 2); vec3_t p8 = vec3(o.x + bw / 2, o.y - bw / 2, o.z - bh / 2);
vec2_t s1, s2, s3, s4, s5, s6, s7, s8; vec2_t s1, s2, s3, s4, s5, s6, s7, s8;
if (!world_to_screen(p1, s1) || !world_to_screen(p2, s2) || if (!world_to_screen(p1, s1) || !world_to_screen(p2, s2) ||
@@ -78,8 +78,8 @@ static bool gl_draw2dbox(vec3_t o, int bh) {
const rgb_t out_col = { 0, 0, 0 }; /* Outline */ const rgb_t out_col = { 0, 0, 0 }; /* Outline */
/* Get top and bottom of player from origin with box height */ /* Get top and bottom of player from origin with box height */
const vec3_t bot = vec3(o[0], o[1], o[2] - bh / 2); const vec3_t bot = vec3(o.x, o.y, o.z - bh / 2);
const vec3_t top = vec3(o[0], o[1], o[2] + bh / 2); const vec3_t top = vec3(o.x, o.y, o.z + bh / 2);
vec2_t s_bot, s_top; vec2_t s_bot, s_top;
if (!world_to_screen(bot, s_bot) || !world_to_screen(top, s_top)) if (!world_to_screen(bot, s_bot) || !world_to_screen(top, s_top))
@@ -98,7 +98,7 @@ static bool gl_draw2dbox(vec3_t o, int bh) {
} }
void esp(void) { void esp(void) {
const int setting = (int)cv_esp->value; const int setting = (int)dz_esp->value;
if (setting == ESP_OFF) if (setting == ESP_OFF)
return; return;
@@ -121,7 +121,7 @@ void esp(void) {
continue; continue;
/* Draw name on top of the player. */ /* Draw name on top of the player. */
vec3_t top = vec3(ent->origin[0], ent->origin[1], ent->origin[2] + bh); vec3_t top = vec3(ent->origin.x, ent->origin.y, ent->origin.z + bh);
vec2_t s_top; vec2_t s_top;
if (!world_to_screen(top, s_top)) if (!world_to_screen(top, s_top))

View File

@@ -26,7 +26,11 @@ void correct_movement(usercmd_t* cmd, vec3_t old_angles);
extern visible_flags visible_mode; extern visible_flags visible_mode;
bool chams(void* this_ptr); bool chams(void* this_ptr);
/* src/features/aim.c */
void aimbot(usercmd_t* cmd);
/* src/features/misc.c */ /* src/features/misc.c */
void custom_crosshair(void); void custom_crosshair(void);
void bullet_tracers(usercmd_t* cmd);
#endif /* FEATURES_H_ */ #endif /* FEATURES_H_ */

View File

@@ -14,7 +14,7 @@ void custom_crosshair(void) {
int my = game_info->m_height / 2; int my = game_info->m_height / 2;
/* The real length is sqrt(2 * (len^2)) */ /* The real length is sqrt(2 * (len^2)) */
const int len = cv_crosshair->value; const int len = dz_crosshair->value;
const int gap = 1; const int gap = 1;
const float w = 1; const float w = 1;
const rgb_t col = { 255, 255, 255 }; const rgb_t col = { 255, 255, 255 };
@@ -29,3 +29,30 @@ void custom_crosshair(void) {
gl_drawline(mx - gap, my + gap, mx - gap - len, my + gap + len, w, col); gl_drawline(mx - gap, my + gap, mx - gap - len, my + gap + len, w, col);
gl_drawline(mx + gap, my + gap, mx + gap + len, my + gap + len, w, col); gl_drawline(mx + gap, my + gap, mx + gap + len, my + gap + len, w, col);
} }
void bullet_tracers(usercmd_t* cmd) {
/* Only draw if we are holding attack and we can shoot */
if (!CVAR_ON(tracers) || !(cmd->buttons & IN_ATTACK) || !can_shoot() ||
!is_alive(localplayer))
return;
/* Get player eye pos, start of tracer */
vec3_t view_height;
i_engine->pEventAPI->EV_LocalPlayerViewheight(view_height);
vec3_t local_eyes = vec_add(localplayer->origin, view_height);
/* Get forward vector from viewangles */
vec3_t fwd;
i_engine->pfnAngleVectors(cmd->viewangles, fwd, NULL, NULL);
const int tracer_len = 3000;
vec3_t end;
end.x = local_eyes.x + fwd.x * tracer_len;
end.y = local_eyes.y + fwd.y * tracer_len;
end.z = local_eyes.z + fwd.z * tracer_len;
/* NOTE: Change tracer settings here */
const float w = 0.8;
const float time = 2;
draw_tracer(local_eyes, end, (rgb_t){ 66, 165, 245 }, 1, w, time);
}

View File

@@ -31,7 +31,7 @@ static void autostrafe_rage(usercmd_t* cmd) {
/* TODO: Get at runtime */ /* TODO: Get at runtime */
const float sv_airaccelerate = 10.0f; const float sv_airaccelerate = 10.0f;
const float sv_maxspeed = 320.0f; const float sv_maxspeed = 320.0f;
const float cl_forwardspeed = 400.0f; const float cl_forwardspeed = 425.0f;
const float cl_sidespeed = 400.0f; const float cl_sidespeed = 400.0f;
float speed = vec_len2d(i_pmove->velocity); float speed = vec_len2d(i_pmove->velocity);
@@ -53,8 +53,8 @@ static void autostrafe_rage(usercmd_t* cmd) {
i_engine->GetViewAngles(viewangles); i_engine->GetViewAngles(viewangles);
/* Get our desired angles and delta */ /* Get our desired angles and delta */
float yaw = DEG2RAD(viewangles[1]); float yaw = DEG2RAD(viewangles.y);
float vel_dir = atan2f(i_pmove->velocity[1], i_pmove->velocity[0]) - yaw; float vel_dir = atan2f(i_pmove->velocity.y, i_pmove->velocity.x) - yaw;
float target_ang = atan2f(-cmd->sidemove, cmd->forwardmove); float target_ang = atan2f(-cmd->sidemove, cmd->forwardmove);
float delta = angle_delta_rad(vel_dir, target_ang); float delta = angle_delta_rad(vel_dir, target_ang);
@@ -82,7 +82,7 @@ void bhop(usercmd_t* cmd) {
/* Autostrafe if enabled. Check if we are in the air and holding space. */ /* Autostrafe if enabled. Check if we are in the air and holding space. */
if (is_jumping) { if (is_jumping) {
switch ((int)cv_autostrafe->value) { switch ((int)dz_autostrafe->value) {
case 1: case 1:
autostrafe_rage(cmd); autostrafe_rage(cmd);
break; break;
@@ -101,8 +101,8 @@ void bhop(usercmd_t* cmd) {
* https://github.com/deboogerxyz/ahc/blob/0492646e28dd7234a8cd431d37b152dc18a21b04/ahc.c#L377 * https://github.com/deboogerxyz/ahc/blob/0492646e28dd7234a8cd431d37b152dc18a21b04/ahc.c#L377
*/ */
void correct_movement(usercmd_t* cmd, vec3_t old_angles) { void correct_movement(usercmd_t* cmd, vec3_t old_angles) {
float old_y = old_angles[1] + (old_angles[1] < 0 ? 360 : 0); float old_y = old_angles.y + (old_angles.y < 0 ? 360 : 0);
float new_y = cmd->viewangles[1] + (cmd->viewangles[1] < 0 ? 360 : 0); float new_y = cmd->viewangles.y + (cmd->viewangles.y < 0 ? 360 : 0);
float delta = (new_y < old_y) ? fabsf(new_y - old_y) float delta = (new_y < old_y) ? fabsf(new_y - old_y)
: 360 - fabsf(new_y - old_y); : 360 - fabsf(new_y - old_y);

68
src/game_detection.c Normal file
View File

@@ -0,0 +1,68 @@
#include "include/game_detection.h"
#include <string.h>
#include <stdio.h>
static GameType current_game = GAME_UNKNOWN;
GameType get_current_game(void) {
if (current_game != GAME_UNKNOWN) {
return current_game;
}
FILE *fp = fopen("/proc/self/cmdline", "r");
if (fp) {
char buf[1024];
size_t size = fread(buf, sizeof(char), sizeof(buf) - 1, fp);
fclose(fp);
if (size > 0) {
buf[size] = '\0';
char *gameTypeToken = NULL;
char *steamToken = NULL;
int tokensFound = 0;
for (char *token = buf; token < buf + size; token += strlen(token) + 1) {
tokensFound++;
if (strcmp(token, "-game") == 0) {
gameTypeToken = token + strlen(token) + 1;
} else if (strcmp(token, "-steam") == 0) {
steamToken = token;
}
}
if (gameTypeToken) {
if (strcmp(gameTypeToken, "cstrike") == 0) {
current_game = GAME_CS16;
} else if (strcmp(gameTypeToken, "dod") == 0) {
current_game = GAME_DAY_OF_DEFEAT;
} else if (strcmp(gameTypeToken, "tfc") == 0) {
current_game = GAME_TFC;
}
} else if (steamToken && tokensFound == 2) {
// If only `-steam` is found and no `-game`, with only two tokens, assume it's Half-Life 1
current_game = GAME_HALFLIFE;
}
}
}
return current_game;
}
int IsCS16(void) {
return get_current_game() == GAME_CS16;
}
int IsHalfLife(void) {
return get_current_game() == GAME_HALFLIFE;
}
int IsDayOfDefeat(void) {
return get_current_game() == GAME_DAY_OF_DEFEAT;
}
int IsTFC(void) {
return get_current_game() == GAME_TFC;
}

View File

@@ -8,7 +8,12 @@
#include "include/sdk.h" #include "include/sdk.h"
#include "include/util.h" #include "include/util.h"
enum game_id this_game_id = HL; game_id this_game_id = HL;
vec3_t g_punchAngles = { 0, 0, 0 };
/* Weapon info */
float g_flNextAttack = 0.f, g_flNextPrimaryAttack = 0.f;
int g_iClip = 0;
void* hw; void* hw;
void** h_client; void** h_client;
@@ -37,13 +42,13 @@ bool globals_init(void) {
*/ */
hw = dlopen("hw.so", RTLD_LAZY | RTLD_NOLOAD); hw = dlopen("hw.so", RTLD_LAZY | RTLD_NOLOAD);
if (!hw) { if (!hw) {
printf("hl-cheat: globals_init: can't open hw.so\n"); printf("goldsource-cheat: globals_init: can't open hw.so\n");
return false; return false;
} }
h_client = (void**)dlsym(hw, "hClientDLL"); h_client = (void**)dlsym(hw, "hClientDLL");
if (!h_client) { if (!h_client) {
printf("hl-cheat: globals_init: can't find hClientDLL\n"); printf("goldsource-cheat: globals_init: can't find hClientDLL\n");
return false; return false;
} }
@@ -62,12 +67,12 @@ bool globals_init(void) {
if (!i_engine || !i_client || !i_pmove || !i_enginestudio || if (!i_engine || !i_client || !i_pmove || !i_enginestudio ||
!i_studiomodelrenderer || !game_info) { !i_studiomodelrenderer || !game_info) {
printf("hl-cheat: globals_init: couldn't load some symbols\n"); printf("goldsource-cheat: globals_init: couldn't load some symbols\n");
return false; return false;
} }
if (!protect_addr(i_studiomodelrenderer, PROT_READ | PROT_WRITE)) { if (!protect_addr(i_studiomodelrenderer, PROT_READ | PROT_WRITE)) {
printf("hl-cheat: globals_init: couldn't unprotect address of SMR\n"); printf("goldsource-cheat: globals_init: couldn't unprotect address of SMR\n");
return false; return false;
} }

View File

@@ -11,6 +11,8 @@
DECL_HOOK(CL_CreateMove); DECL_HOOK(CL_CreateMove);
DECL_HOOK(HUD_Redraw); DECL_HOOK(HUD_Redraw);
DECL_HOOK(StudioRenderModel); DECL_HOOK(StudioRenderModel);
DECL_HOOK(CalcRefdef);
DECL_HOOK(HUD_PostRunCmd);
/* OpenGL hooks */ /* OpenGL hooks */
DECL_HOOK(glColor4f); DECL_HOOK(glColor4f);
@@ -27,6 +29,8 @@ bool hooks_init(void) {
HOOK(i_client, CL_CreateMove); HOOK(i_client, CL_CreateMove);
HOOK(i_client, HUD_Redraw); HOOK(i_client, HUD_Redraw);
HOOK(i_studiomodelrenderer, StudioRenderModel); HOOK(i_studiomodelrenderer, StudioRenderModel);
HOOK(i_client, CalcRefdef);
HOOK(i_client, HUD_PostRunCmd);
/* OpenGL hooks */ /* OpenGL hooks */
GL_HOOK(glColor4f); GL_HOOK(glColor4f);
@@ -58,6 +62,8 @@ void h_CL_CreateMove(float frametime, usercmd_t* cmd, int active) {
localplayer = i_engine->GetLocalPlayer(); localplayer = i_engine->GetLocalPlayer();
bhop(cmd); bhop(cmd);
aimbot(cmd);
bullet_tracers(cmd);
correct_movement(cmd, old_angles); correct_movement(cmd, old_angles);
vec_clamp(cmd->viewangles); vec_clamp(cmd->viewangles);
@@ -68,8 +74,10 @@ void h_CL_CreateMove(float frametime, usercmd_t* cmd, int active) {
int h_HUD_Redraw(float time, int intermission) { int h_HUD_Redraw(float time, int intermission) {
int ret = ORIGINAL(HUD_Redraw, time, intermission); int ret = ORIGINAL(HUD_Redraw, time, intermission);
/* Watermark */ if (dz_watermark->value) {
engine_draw_text(5, 5, "8dcc/hl-cheat", (rgb_t){ 255, 255, 255 }); /* Watermark */
engine_draw_text(5, 5, "https://git.deadzone.lol/Wizzard/goldsource-cheat", (rgb_t){ 0, 255, 255 });
}
esp(); esp();
custom_crosshair(); custom_crosshair();
@@ -86,6 +94,31 @@ void h_StudioRenderModel(void* this_ptr) {
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void h_CalcRefdef(ref_params_t* params) {
/* Store punch angles for CreateMove */
vec_copy(g_punchAngles, params->punchangle);
ORIGINAL(CalcRefdef, params);
}
/*----------------------------------------------------------------------------*/
void h_HUD_PostRunCmd(struct local_state_s* from, struct local_state_s* to,
struct usercmd_s* cmd, int runfuncs, double time,
unsigned int random_seed) {
ORIGINAL(HUD_PostRunCmd, from, to, cmd, runfuncs, time, random_seed);
/* Store attack information to check if we can shoot */
if (runfuncs) {
g_flNextAttack = to->client.m_flNextAttack;
g_flNextPrimaryAttack =
to->weapondata[to->client.m_iId].m_flNextPrimaryAttack;
g_iClip = to->weapondata[to->client.m_iId].m_iClip;
}
}
/*----------------------------------------------------------------------------*/
void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
/* This visible_mode variable is changed inside the chams() function, which /* This visible_mode variable is changed inside the chams() function, which
* is called from the StudioRenderModel hook. * is called from the StudioRenderModel hook.
@@ -131,8 +164,8 @@ void h_glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
void h_CL_Move() { void h_CL_Move() {
if (cv_clmove->value != 0) { if (dz_clmove->value != 0) {
for (int i = 0; i < (int)cv_clmove->value; i++) for (int i = 0; i < (int)dz_clmove->value; i++)
CALL_ORIGINAL(detour_data_clmove, clmove_type); CALL_ORIGINAL(detour_data_clmove, clmove_type);
} }

View File

@@ -5,7 +5,7 @@
#include "sdk.h" #include "sdk.h"
#include "globals.h" #include "globals.h"
#define CVAR_PREFIX "cv_" #define CVAR_PREFIX "dz_"
#define CVAR_HACK_ID 0x4000 /* (1<<14) One that is not in use by the game */ #define CVAR_HACK_ID 0x4000 /* (1<<14) One that is not in use by the game */
/* /*
@@ -16,25 +16,30 @@
* *
* prefix | meaning * prefix | meaning
* -------+------------------------------- * -------+-------------------------------
* cv_* | cvar variable * dz_* | cvar variable
*/ */
#define DECL_CVAR(name) cvar_t* cv_##name = NULL; #define DECL_CVAR(name) cvar_t* dz_##name = NULL;
#define DECL_CVAR_EXTERN(name) extern cvar_t* cv_##name; #define DECL_CVAR_EXTERN(name) extern cvar_t* dz_##name;
#define REGISTER_CVAR(name, value) \ #define REGISTER_CVAR(name, value) \
i_engine->pfnRegisterVariable(CVAR_PREFIX name, value, CVAR_HACK_ID); dz_##name = \
i_engine->pfnRegisterVariable(CVAR_PREFIX #name, #value, CVAR_HACK_ID);
#define CVAR_ON(name) (cv_##name->value != 0.0f) #define CVAR_ON(name) (dz_##name->value != 0.0f)
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
DECL_CVAR_EXTERN(bhop); DECL_CVAR_EXTERN(bhop);
DECL_CVAR_EXTERN(autostrafe); DECL_CVAR_EXTERN(autostrafe);
DECL_CVAR_EXTERN(aimbot);
DECL_CVAR_EXTERN(autoshoot);
DECL_CVAR_EXTERN(esp); DECL_CVAR_EXTERN(esp);
DECL_CVAR_EXTERN(chams); DECL_CVAR_EXTERN(chams);
DECL_CVAR_EXTERN(crosshair); DECL_CVAR_EXTERN(crosshair);
DECL_CVAR_EXTERN(tracers);
DECL_CVAR_EXTERN(clmove); DECL_CVAR_EXTERN(clmove);
DECL_CVAR_EXTERN(watermark);
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/

View File

@@ -0,0 +1,17 @@
#ifndef _GAME_DETECT_H_
#define _GAME_DETECT_H_
typedef enum {
GAME_UNKNOWN = 0,
GAME_HALFLIFE,
GAME_CS16,
GAME_TFC,
GAME_DAY_OF_DEFEAT
} GameType;
GameType get_current_game(void);
int IsCS16(void);
int IsHalfLife(void);
int IsDayOfDefeat(void);
#endif

View File

@@ -34,6 +34,9 @@ enum game_id {
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
extern game_id this_game_id; extern game_id this_game_id;
extern vec3_t g_punchAngles;
extern float g_flNextAttack, g_flNextPrimaryAttack;
extern int g_iClip;
extern void* hw; extern void* hw;
extern void** h_client; /* hClientDLL hander */ extern void** h_client; /* hClientDLL hander */

View File

@@ -95,6 +95,10 @@ void hooks_restore(void);
DECL_HOOK_EXTERN(void, CL_CreateMove, float, usercmd_t*, int); DECL_HOOK_EXTERN(void, CL_CreateMove, float, usercmd_t*, int);
DECL_HOOK_EXTERN(int, HUD_Redraw, float, int); DECL_HOOK_EXTERN(int, HUD_Redraw, float, int);
DECL_HOOK_EXTERN(void, StudioRenderModel, void*); DECL_HOOK_EXTERN(void, StudioRenderModel, void*);
DECL_HOOK_EXTERN(void, CalcRefdef, ref_params_t*);
DECL_HOOK_EXTERN(void, HUD_PostRunCmd, struct local_state_s*,
struct local_state_s*, struct usercmd_s*, int, double,
unsigned int);
/* OpenGL hooks */ /* OpenGL hooks */
DECL_HOOK_EXTERN(void, glColor4f, GLfloat, GLfloat, GLfloat, GLfloat); DECL_HOOK_EXTERN(void, glColor4f, GLfloat, GLfloat, GLfloat, GLfloat);

View File

@@ -3,6 +3,7 @@
#define MAIN_H_ #define MAIN_H_
void load(void); void load(void);
void unload(void);
void self_unload(void); void self_unload(void);
#endif /* MAIN_H_ */ #endif /* MAIN_H_ */

View File

@@ -11,6 +11,9 @@
#include "sdk/cl_dll/wrect.h" #include "sdk/cl_dll/wrect.h"
#include "sdk/cl_dll/cl_dll.h" #include "sdk/cl_dll/cl_dll.h"
/* event_api_s */
#include "sdk/common/event_api.h"
/* usercmd_t */ /* usercmd_t */
#include "sdk/common/usercmd.h" #include "sdk/common/usercmd.h"
@@ -32,6 +35,9 @@
/* engine_studio_api_t */ /* engine_studio_api_t */
#include "sdk/common/r_studioint.h" #include "sdk/common/r_studioint.h"
typedef float matrix_3x4[3][4];
typedef matrix_3x4 bone_matrix[128];
/* /*
* Credits: * Credits:
* https://github.com/UnkwUsr/hlhax/blob/26491984996c8389efec977ed940c5a67a0ecca4/src/sdk.h#L45 * https://github.com/UnkwUsr/hlhax/blob/26491984996c8389efec977ed940c5a67a0ecca4/src/sdk.h#L45
@@ -56,7 +62,7 @@ typedef struct cl_clientfuncs_s {
void (*CL_CameraOffset)(float* ofs); void (*CL_CameraOffset)(float* ofs);
struct kbutton_s* (*KB_Find)(const char* name); struct kbutton_s* (*KB_Find)(const char* name);
void (*CAM_Think)(void); void (*CAM_Think)(void);
void (*V_CalcRefdef)(struct ref_params_s* pparams); void (*CalcRefdef)(struct ref_params_s* pparams);
int (*HUD_AddEntity)(int type, struct cl_entity_s* ent, int (*HUD_AddEntity)(int type, struct cl_entity_s* ent,
const char* modelname); const char* modelname);

View File

@@ -14,28 +14,42 @@ typedef struct {
uint8_t r, g, b; uint8_t r, g, b;
} rgb_t; } rgb_t;
#define DEG2RAD(n) ((n)*M_PI / 180.0) #define DEG2RAD(n) ((n)*M_PI / 180.0f)
#define RAD2DEG(n) ((n)*180.0f / M_PI)
#define CLAMP(val, min, max) \ #define CLAMP(val, min, max) \
(((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val))) (((val) > (max)) ? (max) : (((val) < (min)) ? (min) : (val)))
#define gl_drawline_points(p0, p1, w, col) \ #define gl_drawline_points(p0, p1, w, col) \
gl_drawline(p0[0], p0[1], p1[0], p1[1], w, col); gl_drawline(p0[0], p0[1], p1[0], p1[1], w, col);
/* Use indexes so it works for float[] as well as vec3_t */
#define vec_copy(dst, src) \
dst[0] = src[0]; \
dst[1] = src[1]; \
dst[2] = src[2];
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
cl_entity_t* get_player(int ent_idx); cl_entity_t* get_player(int ent_idx);
bool is_alive(cl_entity_t* ent); bool is_alive(cl_entity_t* ent);
bool valid_player(cl_entity_t* ent); bool valid_player(cl_entity_t* ent);
bool is_friend(cl_entity_t* ent); bool is_friend(cl_entity_t* ent);
bool can_shoot(void);
char* get_name(int ent_idx); char* get_name(int ent_idx);
game_id get_cur_game(void); game_id get_cur_game(void);
vec3_t vec3(float x, float y, float z); vec3_t vec3(float x, float y, float z);
vec3_t vec_add(vec3_t a, vec3_t b);
vec3_t vec_sub(vec3_t a, vec3_t b);
bool vec_is_zero(vec3_t v); bool vec_is_zero(vec3_t v);
float vec_len2d(vec3_t v); float vec_len2d(vec3_t v);
void vec_clamp(vec3_t v); void vec_clamp(vec3_t v);
void vec_norm(vec3_t v);
float angle_delta_rad(float a, float b); float angle_delta_rad(float a, float b);
vec3_t vec_to_ang(vec3_t v);
vec3_t matrix_3x4_origin(matrix_3x4 m);
bool world_to_screen(vec3_t vec, vec2_t screen); bool world_to_screen(vec3_t vec, vec2_t screen);
void engine_draw_text(int x, int y, char* s, rgb_t c); void engine_draw_text(int x, int y, char* s, rgb_t c);
void draw_tracer(vec3_t start, vec3_t end, rgb_t c, float a, float w, float t);
void gl_drawbox(int x, int y, int w, int h, rgb_t c); void gl_drawbox(int x, int y, int w, int h, rgb_t c);
void gl_drawline(int x0, int y0, int x1, int y1, float w, rgb_t col); void gl_drawline(int x0, int y0, int x1, int y1, float w, rgb_t col);
bool protect_addr(void* ptr, int new_flags); bool protect_addr(void* ptr, int new_flags);

View File

@@ -8,30 +8,31 @@
#include "include/cvars.h" #include "include/cvars.h"
#include "include/hooks.h" #include "include/hooks.h"
#include "include/util.h" #include "include/util.h"
#include "include/game_detection.h"
static bool loaded = false; static bool loaded = false;
__attribute__((constructor)) /* Entry point when injected */ __attribute__((constructor)) /* Entry point when injected */
void load(void) { void load(void) {
printf("hl-cheat injected!\n"); printf("goldsource-cheat injected!\n");
/* Initialize globals/interfaces */ /* Initialize globals/interfaces */
if (!globals_init()) { if (!globals_init()) {
fprintf(stderr, "hl-cheat: load: error loading globals, aborting\n"); fprintf(stderr, "goldsource-cheat: load: error loading globals, aborting\n");
self_unload(); self_unload();
return; return;
} }
/* Create cvars for settings */ /* Create cvars for settings */
if (!cvars_init()) { if (!cvars_init()) {
fprintf(stderr, "hl-cheat: load: error creating cvars, aborting\n"); fprintf(stderr, "goldsource-cheat: load: error creating cvars, aborting\n");
self_unload(); self_unload();
return; return;
} }
/* Hook functions */ /* Hook functions */
if (!hooks_init()) { if (!hooks_init()) {
fprintf(stderr, "hl-cheat: load: error hooking functions, aborting\n"); fprintf(stderr, "goldsource-cheat: load: error hooking functions, aborting\n");
self_unload(); self_unload();
return; return;
} }
@@ -39,13 +40,40 @@ void load(void) {
/* Get game version after injecting */ /* Get game version after injecting */
this_game_id = get_cur_game(); this_game_id = get_cur_game();
i_engine->pfnClientCmd("echo \"hl-cheat loaded successfully!\""); i_engine->pfnClientCmd("echo \"goldsource-cheat loaded successfully!\"");
i_engine->pfnClientCmd("echo \"Deadzone rulez!\"");
i_engine->pfnClientCmd("echo \"https://git.deadzone.lol/Wizzard/goldsource-cheat\"");
GameType game = get_current_game();
switch(game) {
case GAME_HALFLIFE:
i_engine->pfnClientCmd("echo \"Detected Game: Half-Life 1\"");
break;
case GAME_CS16:
i_engine->pfnClientCmd("echo \"Detected Game: Counter-Strike 1.6\"");
break;
case GAME_DAY_OF_DEFEAT:
i_engine->pfnClientCmd("echo \"Detected Game: Day of Defeat\"");
break;
case GAME_TFC:
i_engine->pfnClientCmd("echo \"Detected Game: Team Fortress Classic\"");
break;
default:
i_engine->pfnClientCmd("echo \"Detected Game: Unknown Game\"");
break;
}
return;
loaded = true; loaded = true;
} }
__attribute__((destructor)) /* Entry point when unloaded */ __attribute__((destructor)) /* Entry point when unloaded */
void unload() { void unload(void) {
if (loaded) { if (loaded) {
/* TODO: Remove our cvars */ /* TODO: Remove our cvars */
@@ -55,7 +83,7 @@ void unload() {
GL_UNHOOK(glColor4f); /* Manually restore OpenGL hooks here */ GL_UNHOOK(glColor4f); /* Manually restore OpenGL hooks here */
} }
printf("hl-cheat unloaded.\n\n"); printf("goldsource-cheat unloaded.\n\n");
} }
void self_unload(void) { void self_unload(void) {

View File

@@ -63,6 +63,11 @@ bool is_friend(cl_entity_t* ent) {
} }
} }
bool can_shoot(void) {
return g_iClip > 0 && g_flNextAttack <= 0.0f &&
g_flNextPrimaryAttack <= 0.0f;
}
char* get_name(int ent_idx) { char* get_name(int ent_idx) {
hud_player_info_t info; hud_player_info_t info;
i_engine->pfnGetPlayerInfo(ent_idx, &info); i_engine->pfnGetPlayerInfo(ent_idx, &info);
@@ -93,15 +98,35 @@ game_id get_cur_game(void) {
vec3_t vec3(float x, float y, float z) { vec3_t vec3(float x, float y, float z) {
vec3_t ret; vec3_t ret;
ret[0] = x; ret.x = x;
ret[1] = y; ret.y = y;
ret[2] = z; ret.z = z;
return ret;
}
vec3_t vec_add(vec3_t a, vec3_t b) {
vec3_t ret;
ret.x = a.x + b.x;
ret.y = a.y + b.y;
ret.z = a.z + b.z;
return ret;
}
vec3_t vec_sub(vec3_t a, vec3_t b) {
vec3_t ret;
ret.x = a.x - b.x;
ret.y = a.y - b.y;
ret.z = a.z - b.z;
return ret; return ret;
} }
bool vec_is_zero(vec3_t v) { bool vec_is_zero(vec3_t v) {
return v[0] == 0.0f && v[1] == 0.0f && v[2] == 0.0f; return v.x == 0.0f && v.y == 0.0f && v.z == 0.0f;
} }
float vec_len2d(vec3_t v) { float vec_len2d(vec3_t v) {
@@ -109,9 +134,15 @@ float vec_len2d(vec3_t v) {
} }
void vec_clamp(vec3_t v) { void vec_clamp(vec3_t v) {
v[0] = CLAMP(v[0], -89.0f, 89.0f); v.x = CLAMP(v.x, -89.0f, 89.0f);
v[1] = CLAMP(remainderf(v[1], 360.0f), -180.0f, 180.0f); /* v.y % 360 */ v.y = CLAMP(remainderf(v.y, 360.0f), -180.0f, 180.0f); /* v.y % 360 */
v[2] = CLAMP(v[2], -50.0f, 50.0f); v.z = CLAMP(v.z, -50.0f, 50.0f);
}
void vec_norm(vec3_t v) {
v.x = isfinite(v.x) ? remainder(v.x, 360) : 0;
v.y = isfinite(v.y) ? remainder(v.y, 360) : 0;
v.z = 0.0f;
} }
float angle_delta_rad(float a, float b) { float angle_delta_rad(float a, float b) {
@@ -125,6 +156,26 @@ float angle_delta_rad(float a, float b) {
return delta; return delta;
} }
vec3_t vec_to_ang(vec3_t v) {
vec3_t ret;
ret.x = RAD2DEG(atan2(-v.z, hypot(v.x, v.y)));
ret.y = RAD2DEG(atan2(v.y, v.x));
ret.z = 0.0f;
return ret;
}
vec3_t matrix_3x4_origin(matrix_3x4 m) {
vec3_t ret;
ret.x = m[0][3];
ret.y = m[1][3];
ret.z = m[2][3];
return ret;
}
bool world_to_screen(vec3_t vec, vec2_t screen) { bool world_to_screen(vec3_t vec, vec2_t screen) {
if (vec_is_zero(vec)) if (vec_is_zero(vec))
return false; return false;
@@ -158,6 +209,19 @@ void engine_draw_text(int x, int y, char* s, rgb_t c) {
i_engine->pfnDrawConsoleString(x, y, s); i_engine->pfnDrawConsoleString(x, y, s);
} }
void draw_tracer(vec3_t start, vec3_t end, rgb_t c, float a, float w,
float time) {
static const char* MDL_STR = "sprites/laserbeam.spr";
static int beam_idx = i_engine->pEventAPI->EV_FindModelIndex(MDL_STR);
float r = c.r / 255.f;
float g = c.g / 255.f;
float b = c.b / 255.f;
i_engine->pEfxAPI->R_BeamPoints(start, end, beam_idx, time, w, 0, a, 0, 0,
0, r, g, b);
}
void gl_drawbox(int x, int y, int w, int h, rgb_t c) { void gl_drawbox(int x, int y, int w, int h, rgb_t c) {
/* Line width */ /* Line width */
const int lw = 1; const int lw = 1;
@@ -207,7 +271,7 @@ bool protect_addr(void* ptr, int new_flags) {
int pgsz = getpagesize(); int pgsz = getpagesize();
if (mprotect(p, pgsz, new_flags) == -1) { if (mprotect(p, pgsz, new_flags) == -1) {
printf("hl-cheat: error protecting %p\n", ptr); printf("goldsource-cheat: error protecting %p\n", ptr);
return false; return false;
} }