summaryrefslogtreecommitdiffstats
path: root/src/hl2h.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/hl2h.cpp')
-rw-r--r--src/hl2h.cpp96
1 files changed, 94 insertions, 2 deletions
diff --git a/src/hl2h.cpp b/src/hl2h.cpp
index 8ab1a3e..74a8c6c 100644
--- a/src/hl2h.cpp
+++ b/src/hl2h.cpp
@@ -503,7 +503,7 @@ static void hkdSrvRandomSeed(int seed) {
503 (uintptr_t)self == g_local_server_player; 503 (uintptr_t)self == g_local_server_player;
504 504
505 if (local && g_server.contains(ret) && feature_active(FEAT_SPREAD) && 505 if (local && g_server.contains(ret) && feature_active(FEAT_SPREAD) &&
506 spread_no_spread_enabled()) { 506 spread_no_spread_enabled() && spread_engine_enabled()) {
507 g_spread_rand_left = 8; 507 g_spread_rand_left = 8;
508 int pellets = g_spread_pellets; 508 int pellets = g_spread_pellets;
509 if (pellets < 1) 509 if (pellets < 1)
@@ -599,7 +599,7 @@ static bool g_uniform_hook_installed = false;
599 599
600static float hkdUniformRandomFloat(void *self, float mn, float mx) { 600static float hkdUniformRandomFloat(void *self, float mn, float mx) {
601 bool enabled = g_local_server_player && feature_active(FEAT_SPREAD) && 601 bool enabled = g_local_server_player && feature_active(FEAT_SPREAD) &&
602 spread_no_spread_enabled(); 602 spread_no_spread_enabled() && spread_engine_enabled();
603 bool hit = false; 603 bool hit = false;
604 void *who = nullptr; 604 void *who = nullptr;
605 if (enabled) { 605 if (enabled) {
@@ -654,6 +654,90 @@ static void install_uniform_random_hook() {
654 (void *)g_orig_uniform_float, (void *)&hkdUniformRandomFloat); 654 (void *)g_orig_uniform_float, (void *)&hkdUniformRandomFloat);
655} 655}
656 656
657// ---------------------------------------------------------------------------
658// camera / viewmodel FOV and gamma
659// ---------------------------------------------------------------------------
660//
661// The rendered camera FOV is derived from C_BasePlayer::m_iDefaultFOV every
662// frame (CViewRender::OnRenderStart copies it into default_fov), so writing
663// the client netvar is enough and needs no server command. The viewmodel FOV
664// and monitor gamma are plain client cvars.
665
666static void view_settings_apply(void *ent) {
667 if (g_net.default_fov >= 0 && ent) {
668 static int last = -2;
669 int want = g_fov_camera > 0 ? g_fov_camera : 0;
670 if (want != last || g_fov_camera > 0) {
671 *(int *)((uintptr_t)ent + g_net.default_fov) = want;
672 last = want;
673 }
674 }
675 // 0 means "leave the game's value alone": only send a command once the
676 // slider is non-zero, then restore the stock value when it returns to 0.
677 static int last_vm = 0;
678 if (g_fov_viewmodel > 0 && g_fov_viewmodel != last_vm) {
679 char cmd[48];
680 snprintf(cmd, sizeof(cmd), "viewmodel_fov %d", g_fov_viewmodel);
681 console_cmd(cmd);
682 last_vm = g_fov_viewmodel;
683 } else if (g_fov_viewmodel == 0 && last_vm > 0) {
684 console_cmd("viewmodel_fov 54");
685 last_vm = 0;
686 }
687 static int last_gamma = 22;
688 if (g_gamma != last_gamma) {
689 char cmd[48];
690 snprintf(cmd, sizeof(cmd), "mat_monitorgamma %d.%d", g_gamma / 10,
691 g_gamma % 10);
692 console_cmd(cmd);
693 last_gamma = g_gamma;
694 }
695}
696
697// ---------------------------------------------------------------------------
698// jump assist: crouch-jump and edge jump
699// ---------------------------------------------------------------------------
700
701static bool g_cj_added = false;
702
703static bool crouch_jump_apply(CUserCmd *cmd, int flags, const float *vel) {
704 bool user_duck = (cmd->buttons & IN_DUCK) != 0;
705 bool onground = (flags & FL_ONGROUND) != 0;
706 bool want = g_auto_crouchjump && !onground && !user_duck &&
707 (cmd->buttons & IN_JUMP) && vel[2] > 20.0f;
708 int old = cmd->buttons;
709 if (want) {
710 cmd->buttons |= IN_DUCK;
711 g_cj_added = true;
712 } else if (g_cj_added && !user_duck) {
713 cmd->buttons &= ~IN_DUCK;
714 g_cj_added = false;
715 }
716 return cmd->buttons != old;
717}
718
719static bool edge_jump_apply(CUserCmd *cmd, void *ent, int flags,
720 const float *vel) {
721 if (!g_edge_jump || g_net.origin < 0 || !(flags & FL_ONGROUND) ||
722 (flags & FL_INWATER))
723 return false;
724 if (cmd->buttons & (IN_JUMP | IN_DUCK))
725 return false;
726 float speed2d = sqrtf(vel[0] * vel[0] + vel[1] * vel[1]);
727 if (speed2d < 120.0f)
728 return false;
729 uintptr_t e = (uintptr_t)ent;
730 Vector origin{*(float *)(e + g_net.origin), *(float *)(e + g_net.origin + 4),
731 *(float *)(e + g_net.origin + 8)};
732 // Probe the ground a fraction of a second ahead. No hit within 64 units
733 // means a real ledge; slopes and stairs still find a floor and are skipped.
734 Vector ahead{origin.x + vel[0] * 0.12f, origin.y + vel[1] * 0.12f, origin.z};
735 if (!g_iface.enginetrace || point_ground(ahead, ent))
736 return false;
737 cmd->buttons |= IN_JUMP;
738 return true;
739}
740
657static void do_move(int seq, float frametime) { 741static void do_move(int seq, float frametime) {
658 install_seed_hook(); 742 install_seed_hook();
659 install_uniform_random_hook(); 743 install_uniform_random_hook();
@@ -683,6 +767,8 @@ static void do_move(int seq, float frametime) {
683 if (!ent) 767 if (!ent)
684 return; 768 return;
685 769
770 view_settings_apply(ent);
771
686 // New map / respawn: drop stale bone caches and target locks. 772 // New map / respawn: drop stale bone caches and target locks.
687 static void *last_local_ent = nullptr; 773 static void *last_local_ent = nullptr;
688 if (ent != last_local_ent) { 774 if (ent != last_local_ent) {
@@ -803,6 +889,12 @@ static void do_move(int seq, float frametime) {
803 } 889 }
804 } 890 }
805 891
892 bool jump_assist = crouch_jump_apply(cmd, flags, vel);
893 if (edge_jump_apply(cmd, ent, flags, vel))
894 jump_assist = true;
895 if (jump_assist)
896 note_modified(cmd, flags, vel);
897
806 if (jumpbug_apply(cmd, localIdx, ent, flags, vel, frametime)) 898 if (jumpbug_apply(cmd, localIdx, ent, flags, vel, frametime))
807 note_modified(cmd, flags, vel); 899 note_modified(cmd, flags, vel);
808 900