diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/esp.cpp | 46 | ||||
| -rw-r--r-- | src/gui.cpp | 7 | ||||
| -rw-r--r-- | src/hl2h.cpp | 29 | ||||
| -rw-r--r-- | src/hl2h.h | 2 |
4 files changed, 73 insertions, 11 deletions
diff --git a/src/esp.cpp b/src/esp.cpp index bda6232..ca7bae0 100644 --- a/src/esp.cpp +++ b/src/esp.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #include "hl2h.h" | 2 | #include "hl2h.h" |
| 3 | #include <cmath> | 3 | #include <cmath> |
| 4 | #include <cstring> | 4 | #include <cstring> |
| 5 | #include <strings.h> | ||
| 5 | #include <cstddef> | 6 | #include <cstddef> |
| 6 | #include <cstdlib> | 7 | #include <cstdlib> |
| 7 | #include <ctime> | 8 | #include <ctime> |
| @@ -1131,18 +1132,49 @@ static void spread_compute() { | |||
| 1131 | g_spread_ready = true; | 1132 | g_spread_ready = true; |
| 1132 | } | 1133 | } |
| 1133 | 1134 | ||
| 1135 | static bool icontains(const char *hay, const char *needle) { | ||
| 1136 | if (!hay || !needle || !*needle) | ||
| 1137 | return false; | ||
| 1138 | size_t n = strlen(needle); | ||
| 1139 | for (const char *p = hay; *p; p++) | ||
| 1140 | if (strncasecmp(p, needle, n) == 0) | ||
| 1141 | return true; | ||
| 1142 | return false; | ||
| 1143 | } | ||
| 1144 | |||
| 1134 | bool entity_is_physics_prop(int idx) { | 1145 | bool entity_is_physics_prop(int idx) { |
| 1135 | if (idx <= 0 || idx > 4096) | 1146 | if (idx <= 0 || idx > 4096) |
| 1136 | return false; | 1147 | return false; |
| 1148 | void *ent = entitylist_get(idx); | ||
| 1149 | if (!ent) | ||
| 1150 | return false; | ||
| 1151 | int mt = -1; | ||
| 1152 | // The reliable signal: physics objects use MOVETYPE_VPHYSICS. The client | ||
| 1153 | // class is CPhysicsProp / CPhysBox, not the server's prop_physics name. | ||
| 1154 | if (g_net.movetype >= 0) { | ||
| 1155 | mt = *(int *)((uintptr_t)ent + g_net.movetype); | ||
| 1156 | if (mt == MOVETYPE_VPHYSICS) | ||
| 1157 | return true; | ||
| 1158 | } | ||
| 1137 | void *net = entity_networkable(idx); | 1159 | void *net = entity_networkable(idx); |
| 1138 | const char *cls = net ? entity_class_name(net, nullptr) : nullptr; | 1160 | const char *cls = net ? entity_class_name(net, nullptr) : nullptr; |
| 1139 | void *ent = entitylist_get(idx); | 1161 | const char *model = entity_model_name(ent); |
| 1140 | const char *model = ent ? entity_model_name(ent) : nullptr; | 1162 | bool is_prop = icontains(cls, "physicsprop") || icontains(cls, "physbox") || |
| 1141 | if (cls && (strstr(cls, "prop_physics") || strstr(cls, "physbox"))) | 1163 | icontains(cls, "prop_physics") || |
| 1142 | return true; | 1164 | icontains(model, "props_junk") || |
| 1143 | if (model && (strstr(model, "props_junk") || strstr(model, "props_physics"))) | 1165 | icontains(model, "props_physics") || |
| 1144 | return true; | 1166 | icontains(model, "props_c17") || |
| 1145 | return false; | 1167 | icontains(model, "props_interiors") || |
| 1168 | icontains(model, "props_lab"); | ||
| 1169 | if (!is_prop) { | ||
| 1170 | static int miss_logs = 0; | ||
| 1171 | if (miss_logs < 6) { | ||
| 1172 | miss_logs++; | ||
| 1173 | logf("stucklaunch prop? idx=%d movetype=%d cls=%s model=%s", idx, mt, | ||
| 1174 | cls ? cls : "?", model ? model : "?"); | ||
| 1175 | } | ||
| 1176 | } | ||
| 1177 | return is_prop; | ||
| 1146 | } | 1178 | } |
| 1147 | 1179 | ||
| 1148 | bool active_weapon_is_gravity_gun(void *local_ent) { | 1180 | bool active_weapon_is_gravity_gun(void *local_ent) { |
diff --git a/src/gui.cpp b/src/gui.cpp index 9af8003..156e496 100644 --- a/src/gui.cpp +++ b/src/gui.cpp | |||
| @@ -879,6 +879,8 @@ static void handle_capture(const unsigned char *keys) { | |||
| 879 | config_save(); | 879 | config_save(); |
| 880 | toastf(TOAST_INFO, "%s bound to %s", card.title, | 880 | toastf(TOAST_INFO, "%s bound to %s", card.title, |
| 881 | scancode_name(card.feat->bind)); | 881 | scancode_name(card.feat->bind)); |
| 882 | if (!card.feat->active) | ||
| 883 | toastf(TOAST_WARN, "%s is not Active yet", card.title); | ||
| 882 | return; | 884 | return; |
| 883 | } | 885 | } |
| 884 | for (int k = 0; k < 512; k++) { | 886 | for (int k = 0; k < 512; k++) { |
| @@ -890,9 +892,12 @@ static void handle_capture(const unsigned char *keys) { | |||
| 890 | card.feat->bind = k; | 892 | card.feat->bind = k; |
| 891 | g_capture_card = -1; | 893 | g_capture_card = -1; |
| 892 | config_save(); | 894 | config_save(); |
| 893 | if (card.feat) | 895 | if (card.feat) { |
| 894 | toastf(TOAST_INFO, "%s bound to %s", card.title, | 896 | toastf(TOAST_INFO, "%s bound to %s", card.title, |
| 895 | scancode_name(card.feat->bind)); | 897 | scancode_name(card.feat->bind)); |
| 898 | if (!card.feat->active) | ||
| 899 | toastf(TOAST_WARN, "%s is not Active yet", card.title); | ||
| 900 | } | ||
| 896 | return; | 901 | return; |
| 897 | } | 902 | } |
| 898 | } | 903 | } |
diff --git a/src/hl2h.cpp b/src/hl2h.cpp index 84de815..defdd27 100644 --- a/src/hl2h.cpp +++ b/src/hl2h.cpp | |||
| @@ -172,8 +172,14 @@ static void apply_autostrafe(CUserCmd *cmd, const float *vel) { | |||
| 172 | // True while the player stands on (or just left) a physics prop. m_hGroundEntity | 172 | // True while the player stands on (or just left) a physics prop. m_hGroundEntity |
| 173 | // is latched briefly because it clears during each hop. | 173 | // is latched briefly because it clears during each hop. |
| 174 | static bool stucklaunch_prop_ok(void *ent, int tick) { | 174 | static bool stucklaunch_prop_ok(void *ent, int tick) { |
| 175 | if (g_net.groundentity < 0) | 175 | if (g_net.groundentity < 0) { |
| 176 | static bool logged = false; | ||
| 177 | if (!logged) { | ||
| 178 | logged = true; | ||
| 179 | logf("stucklaunch: m_hGroundEntity unavailable; prop detection off"); | ||
| 180 | } | ||
| 176 | return true; // no netvar: the bind is the only safeguard | 181 | return true; // no netvar: the bind is the only safeguard |
| 182 | } | ||
| 177 | static int last_prop_tick = -100000; | 183 | static int last_prop_tick = -100000; |
| 178 | uint32_t h = *(uint32_t *)((uintptr_t)ent + g_net.groundentity); | 184 | uint32_t h = *(uint32_t *)((uintptr_t)ent + g_net.groundentity); |
| 179 | int gi = (h == 0xFFFFFFFFu) ? 0 : (int)(h & 0xFFFF); | 185 | int gi = (h == 0xFFFFFFFFu) ? 0 : (int)(h & 0xFFFF); |
| @@ -182,9 +188,15 @@ static bool stucklaunch_prop_ok(void *ent, int tick) { | |||
| 182 | static int prop_logs = 0; | 188 | static int prop_logs = 0; |
| 183 | if (prop_logs < 4) { | 189 | if (prop_logs < 4) { |
| 184 | prop_logs++; | 190 | prop_logs++; |
| 185 | logf("stucklaunch: prop idx=%d", gi); | 191 | logf("stucklaunch: prop idx=%d engaged", gi); |
| 186 | } | 192 | } |
| 187 | last_prop_tick = tick; | 193 | last_prop_tick = tick; |
| 194 | } else { | ||
| 195 | static int miss_logs = 0; | ||
| 196 | if (miss_logs < 4) { | ||
| 197 | miss_logs++; | ||
| 198 | logf("stucklaunch: ground h=%#x idx=%d is not a physics prop", h, gi); | ||
| 199 | } | ||
| 188 | } | 200 | } |
| 189 | return tick - last_prop_tick < 32; // ~0.5 s at 66 tick | 201 | return tick - last_prop_tick < 32; // ~0.5 s at 66 tick |
| 190 | } | 202 | } |
| @@ -194,6 +206,11 @@ static bool stucklaunch_prop_ok(void *ent, int tick) { | |||
| 194 | // gun's +attack) to keep regrabbing the prop, and air-strafes the hops. | 206 | // gun's +attack) to keep regrabbing the prop, and air-strafes the hops. |
| 195 | static void stucklaunch_apply(CUserCmd *cmd, void *local_ent, bool onground, | 207 | static void stucklaunch_apply(CUserCmd *cmd, void *local_ent, bool onground, |
| 196 | const float *vel) { | 208 | const float *vel) { |
| 209 | static bool engaged_logged = false; | ||
| 210 | if (!engaged_logged) { | ||
| 211 | engaged_logged = true; | ||
| 212 | logf("stucklaunch: applying jump/spam (onground=%d)", (int)onground); | ||
| 213 | } | ||
| 197 | cmd->buttons |= IN_JUMP; | 214 | cmd->buttons |= IN_JUMP; |
| 198 | int period = stucklaunch_spam_ticks(); | 215 | int period = stucklaunch_spam_ticks(); |
| 199 | if (period < 1) | 216 | if (period < 1) |
| @@ -629,6 +646,14 @@ static void do_move(int seq, float frametime) { | |||
| 629 | } | 646 | } |
| 630 | 647 | ||
| 631 | bool stuck_on = feature_active(FEAT_STUCKLAUNCH); | 648 | bool stuck_on = feature_active(FEAT_STUCKLAUNCH); |
| 649 | if (g_stucklaunch.active) { | ||
| 650 | static bool state_logged = false; | ||
| 651 | if (!state_logged) { | ||
| 652 | state_logged = true; | ||
| 653 | logf("stucklaunch: active=1 run=%d bind=%d groundoff=%d", | ||
| 654 | (int)stuck_on, g_stucklaunch.bind, g_net.groundentity); | ||
| 655 | } | ||
| 656 | } | ||
| 632 | bool stuck_engaged = stuck_on && stucklaunch_prop_ok(ent, cmd->tick_count); | 657 | bool stuck_engaged = stuck_on && stucklaunch_prop_ok(ent, cmd->tick_count); |
| 633 | if (stuck_engaged) { | 658 | if (stuck_engaged) { |
| 634 | stucklaunch_apply(cmd, ent, onground, vel); | 659 | stucklaunch_apply(cmd, ent, onground, vel); |
| @@ -141,7 +141,7 @@ struct CUserCmd { | |||
| 141 | 141 | ||
| 142 | enum { IN_ATTACK = 1 << 0, IN_JUMP = 1 << 1, IN_DUCK = 1 << 2, IN_USE = 1 << 5, IN_ATTACK2 = 1 << 11, IN_SPEED = 1 << 17 }; | 142 | enum { IN_ATTACK = 1 << 0, IN_JUMP = 1 << 1, IN_DUCK = 1 << 2, IN_USE = 1 << 5, IN_ATTACK2 = 1 << 11, IN_SPEED = 1 << 17 }; |
| 143 | enum { FL_ONGROUND = 1 << 0, FL_DUCKING = 1 << 1, FL_INWATER = 1 << 9 }; | 143 | enum { FL_ONGROUND = 1 << 0, FL_DUCKING = 1 << 1, FL_INWATER = 1 << 9 }; |
| 144 | enum { MOVETYPE_WALK = 2, MOVETYPE_NOCLIP = 8, MOVETYPE_LADDER = 9 }; | 144 | enum { MOVETYPE_WALK = 2, MOVETYPE_VPHYSICS = 6, MOVETYPE_NOCLIP = 8, MOVETYPE_LADDER = 9 }; |
| 145 | 145 | ||
| 146 | // --------------------------------------------------------------------------- | 146 | // --------------------------------------------------------------------------- |
| 147 | // vector math | 147 | // vector math |
