summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/bones.cpp39
-rw-r--r--src/esp.cpp16
-rw-r--r--src/hl2h.h2
3 files changed, 55 insertions, 2 deletions
diff --git a/src/bones.cpp b/src/bones.cpp
index 88aa429..a9c6887 100644
--- a/src/bones.cpp
+++ b/src/bones.cpp
@@ -182,6 +182,25 @@ static bool hitbox_world(const BoneEntry *e, const Hitbox &b, Vector &out) {
182 return true; 182 return true;
183} 183}
184 184
185// HL2 humanoids (combine, metrocop, citizen, zombie, ...) use the ValveBiped
186// skeleton. Draw only the core chain: pelvis/spine/neck/head, clavicle to
187// hand, thigh to foot. Fingers, toes and extra model bones (e.g. the headcrab
188// on a zombie) are skipped.
189static bool core_bone_name(const char *n) {
190 if (!n || strncasecmp(n, "ValveBiped.Bip01_", 17) != 0)
191 return false;
192 if (contains_ci(n, "Finger") || contains_ci(n, "Toe") ||
193 contains_ci(n, "Headcrab"))
194 return false;
195 static const char *tokens[] = {"Pelvis", "Spine", "Neck", "Head1",
196 "Clavicle", "UpperArm", "Forearm", "Hand",
197 "Thigh", "Calf", "Foot", nullptr};
198 for (int i = 0; tokens[i]; i++)
199 if (contains_ci(n, tokens[i]))
200 return true;
201 return false;
202}
203
185static void dump_hitboxes(const BoneEntry *e) { 204static void dump_hitboxes(const BoneEntry *e) {
186 const StudioHdr *h = e->hdr; 205 const StudioHdr *h = e->hdr;
187 logf("hitbox dump: idx=%d sets=%d setidx=%d", e->idx, h->numhitboxsets, 206 logf("hitbox dump: idx=%d sets=%d setidx=%d", e->idx, h->numhitboxsets,
@@ -312,6 +331,26 @@ int bone_parent(int idx, int bone) {
312 return bone_at(e->hdr, bone)->parent; 331 return bone_at(e->hdr, bone)->parent;
313} 332}
314 333
334bool bone_is_skeleton_core(int idx, int bone) {
335 BoneEntry *e = find_entry(idx);
336 if (!e || !e->valid || bone < 0 || bone >= e->count)
337 return false;
338 return core_bone_name(bone_name_raw(e->hdr, bone));
339}
340
341int bone_nearest_core_parent(int idx, int bone) {
342 BoneEntry *e = find_entry(idx);
343 if (!e || !e->valid || bone < 0 || bone >= e->count)
344 return -1;
345 int p = bone_at(e->hdr, bone)->parent;
346 for (int guard = 0; p >= 0 && p < e->count && guard < 64; guard++) {
347 if (core_bone_name(bone_name_raw(e->hdr, p)))
348 return p;
349 p = bone_at(e->hdr, p)->parent;
350 }
351 return -1;
352}
353
315bool bone_pos(int idx, int bone, Vector &out) { 354bool bone_pos(int idx, int bone, Vector &out) {
316 BoneEntry *e = find_entry(idx); 355 BoneEntry *e = find_entry(idx);
317 if (!e || !e->valid || bone < 0 || bone >= e->count) 356 if (!e || !e->valid || bone < 0 || bone >= e->count)
diff --git a/src/esp.cpp b/src/esp.cpp
index b75a7a9..b5cb9b0 100644
--- a/src/esp.cpp
+++ b/src/esp.cpp
@@ -285,11 +285,21 @@ static void draw_skeleton(const EspTarget &t) {
285 Vector wp[256]; 285 Vector wp[256];
286 float xs[256], ys[256]; 286 float xs[256], ys[256];
287 bool ok[256]; 287 bool ok[256];
288 int core_count = 0;
288 for (int i = 0; i < n; i++) { 289 for (int i = 0; i < n; i++) {
290 ok[i] = false;
291 if (!bone_is_skeleton_core(t.idx, i))
292 continue;
293 core_count++;
289 ok[i] = bone_pos(t.idx, i, wp[i]) && 294 ok[i] = bone_pos(t.idx, i, wp[i]) &&
290 world_to_screen(wp[i], xs[i], ys[i]) && std::isfinite(xs[i]) && 295 world_to_screen(wp[i], xs[i], ys[i]) && std::isfinite(xs[i]) &&
291 std::isfinite(ys[i]); 296 std::isfinite(ys[i]);
292 } 297 }
298 static int logged = 0;
299 if (core_count > 0 && logged < 4) {
300 logged++;
301 logf("skeleton: idx=%d bones=%d core=%d", t.idx, n, core_count);
302 }
293 if (t.friendly) 303 if (t.friendly)
294 surf_color(60, 255, 60, 255); 304 surf_color(60, 255, 60, 255);
295 else if (t.neutral) 305 else if (t.neutral)
@@ -297,8 +307,10 @@ static void draw_skeleton(const EspTarget &t) {
297 else 307 else
298 surf_color(255, 60, 60, 255); 308 surf_color(255, 60, 60, 255);
299 for (int i = 0; i < n; i++) { 309 for (int i = 0; i < n; i++) {
300 int p = bone_parent(t.idx, i); 310 if (!ok[i])
301 if (p >= 0 && p < n && ok[i] && ok[p]) 311 continue;
312 int p = bone_nearest_core_parent(t.idx, i);
313 if (p >= 0 && p < n && ok[p])
302 surf_line((int)xs[p], (int)ys[p], (int)xs[i], (int)ys[i]); 314 surf_line((int)xs[p], (int)ys[p], (int)xs[i], (int)ys[i]);
303 } 315 }
304} 316}
diff --git a/src/hl2h.h b/src/hl2h.h
index 1eaee10..c0d4cdd 100644
--- a/src/hl2h.h
+++ b/src/hl2h.h
@@ -175,6 +175,8 @@ int bones_count(int idx);
175int bone_find(int idx, const char *name); 175int bone_find(int idx, const char *name);
176int bone_parent(int idx, int bone); 176int bone_parent(int idx, int bone);
177bool bone_pos(int idx, int bone, Vector &out); 177bool bone_pos(int idx, int bone, Vector &out);
178bool bone_is_skeleton_core(int idx, int bone);
179int bone_nearest_core_parent(int idx, int bone);
178bool hitbox_center(int idx, const char *hitbox_name, Vector &out); 180bool hitbox_center(int idx, const char *hitbox_name, Vector &out);
179bool head_position(int idx, Vector &out); 181bool head_position(int idx, Vector &out);
180 182