summaryrefslogtreecommitdiffstats
path: root/src/hl2h.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/hl2h.cpp74
1 files changed, 69 insertions, 5 deletions
diff --git a/src/hl2h.cpp b/src/hl2h.cpp
index 0261ff2..a4a1a88 100644
--- a/src/hl2h.cpp
+++ b/src/hl2h.cpp
@@ -117,9 +117,20 @@ static void *entitylist_get(int idx) {
117 117
118 118
119static void do_move(int seq) { 119static void do_move(int seq) {
120 static bool g_echo_sent = false;
120 if (!g_input || !g_net.ok()) 121 if (!g_input || !g_net.ok())
121 return; 122 return;
122 123
124 if (!g_echo_sent) {
125 g_echo_sent = true;
126 if (g_conmsg) {
127 g_conmsg("[hl2hake] succesfully loaded\n");
128 logf("console echo sent (first CreateMove)");
129 } else {
130 logf("g_conmsg is NULL — in-game console output unavailable");
131 }
132 }
133
123 int localIdx = engine_get_local_player(); 134 int localIdx = engine_get_local_player();
124 if (localIdx <= 0 || localIdx > 64) 135 if (localIdx <= 0 || localIdx > 64)
125 return; 136 return;
@@ -137,17 +148,16 @@ static void do_move(int seq) {
137 return; 148 return;
138 149
139 uintptr_t e = (uintptr_t)ent; 150 uintptr_t e = (uintptr_t)ent;
140 uint8_t movetype = *(uint8_t *)(e + g_net.movetype);
141 int flags = *(int *)(e + g_net.flags); 151 int flags = *(int *)(e + g_net.flags);
142 bool onground = (flags & FL_ONGROUND) != 0; 152 bool onground = (flags & FL_ONGROUND) != 0;
143 bool inwater = (flags & FL_INWATER) != 0; 153 bool inwater = (flags & FL_INWATER) != 0;
144 154
145 if (movetype == MOVETYPE_NOCLIP || movetype == MOVETYPE_LADDER) 155 bool climb_on = feature_active(FEAT_CLIMB); // bind held (or middle mouse when unbound)
146 return; 156 bool bhop_on = feature_active(FEAT_BHOP);
147 157
148 static bool lastground = false; 158 static bool lastground = false;
149 159
150 if (middle_mouse_down()) { 160 if (climb_on) {
151 if (cmd->command_number % 2) { 161 if (cmd->command_number % 2) {
152 cmd->buttons &= ~IN_JUMP; 162 cmd->buttons &= ~IN_JUMP;
153 cmd->buttons |= IN_USE; 163 cmd->buttons |= IN_USE;
@@ -156,7 +166,7 @@ static void do_move(int seq) {
156 cmd->buttons |= IN_JUMP; 166 cmd->buttons |= IN_JUMP;
157 } 167 }
158 note_modified(cmd, flags, (float *)(e + g_net.velocity)); 168 note_modified(cmd, flags, (float *)(e + g_net.velocity));
159 } else if (cmd->buttons & IN_JUMP) { 169 } else if (bhop_on && (cmd->buttons & IN_JUMP)) {
160 if (inwater && (cmd->buttons & IN_DUCK)) { 170 if (inwater && (cmd->buttons & IN_DUCK)) {
161 lastground = onground; 171 lastground = onground;
162 return; 172 return;
@@ -193,9 +203,63 @@ static void do_move(int seq) {
193using CreateMoveFn = bool (*)(void *, int, float, bool); 203using CreateMoveFn = bool (*)(void *, int, float, bool);
194static CreateMoveFn oCreateMove = nullptr; 204static CreateMoveFn oCreateMove = nullptr;
195 205
206using DrawPrintTextFn = void (*)(void *self, const wchar_t *text, int len, int drawType);
207static DrawPrintTextFn oDrawPrintText = nullptr;
208using PaintTraverseExFn = void (*)(void *, long, bool);
209static PaintTraverseExFn oPaintTraverseEx = nullptr;
210static bool g_in_draw = false;
211
212// Hooked ISurface slot 22. The game calls this from a valid paint context;
213// our overlay draws are submitted through outer_draw() (menu.cpp), which
214// wraps them in PushMakeCurrent/PopMakeCurrent with the embedded panel.
215static void hkdDrawPrintText(void *self, const wchar_t *text, int len, int drawType) {
216 if (g_in_draw) {
217 oDrawPrintText(self, text, len, drawType);
218 return;
219 }
220 g_in_draw = true;
221 oDrawPrintText(self, text, len, drawType);
222 // fallback trigger: fires when the game draws text (menus). Primary draw
223 // path is the PaintTraverseEx hook (slot 114), which fires every frame.
224 outer_draw();
225 g_in_draw = false;
226}
227
228// PaintTraverseEx (slot 114, verified: IsVisible check + popups loop + "Too many
229// popups" assert). Fires every frame for the root panel — unlike DrawPrintText
230// (slot 22) which only fires when text is drawn, so it never fires in-world.
231static void hkdPaintTraverseEx(void *self, long panel, bool paintPopups) {
232 using Fn = void (*)(void *, long, bool);
233 ((Fn)oPaintTraverseEx)(self, panel, paintPopups);
234 if (!g_in_draw) {
235 g_in_draw = true;
236 outer_draw();
237 g_in_draw = false;
238 }
239}
240
196static bool hkdCreateMove(void *self, int seq, float frametime, bool active) { 241static bool hkdCreateMove(void *self, int seq, float frametime, bool active) {
197 bool ret = oCreateMove(self, seq, frametime, active); 242 bool ret = oCreateMove(self, seq, frametime, active);
198 do_move(seq); 243 do_move(seq);
244
245 // Hook ISurface once: PaintTraverseEx (slot 114) fires every frame; keep
246 // DrawPrintText (slot 22) hooked as a fallback text-draw trigger.
247 static int isurface_hooked = 0;
248 if (!isurface_hooked && g_surface) {
249 void **svt = VTABLE(g_surface);
250 constexpr size_t VT_SIZE = 256;
251 void **newsvt = new void *[VT_SIZE];
252 memcpy(newsvt, svt, VT_SIZE * sizeof(void *));
253 oDrawPrintText = (DrawPrintTextFn)svt[22];
254 newsvt[22] = (void *)&hkdDrawPrintText;
255 oPaintTraverseEx = (PaintTraverseExFn)svt[114];
256 newsvt[114] = (void *)&hkdPaintTraverseEx;
257 VTABLE(g_surface) = newsvt;
258 isurface_hooked = 1;
259 logf("ISurface hooked: DrawPrintText slot 22 orig=%p, PaintTraverseEx slot 114 orig=%p",
260 (void *)oDrawPrintText, (void *)oPaintTraverseEx);
261 }
262
199 return ret; 263 return ret;
200} 264}
201 265