mirror of
https://github.com/nzp-team/quakec.git
synced 2025-02-15 16:41:41 +00:00
CLIENT: Add Hold Breath to Steady Rifle
This commit is contained in:
parent
ee349fcc6c
commit
a9cc26679a
3 changed files with 141 additions and 9 deletions
|
@ -102,6 +102,8 @@ float active_achievement;
|
||||||
float current_achievement_page;
|
float current_achievement_page;
|
||||||
float achievement_pages;
|
float achievement_pages;
|
||||||
|
|
||||||
|
float sniper_hold_breath;
|
||||||
|
|
||||||
|
|
||||||
float K_LEFTDOWN, K_RIGHTDOWN, K_BACKDOWN, K_FORWARDDOWN;
|
float K_LEFTDOWN, K_RIGHTDOWN, K_BACKDOWN, K_FORWARDDOWN;
|
||||||
|
|
||||||
|
|
|
@ -1299,6 +1299,49 @@ void() Draw_Crosshair =
|
||||||
drawfill('0 0 0', [g_width/2 - g_height/2, g_height, 0], '0 0 0', 1, 0);
|
drawfill('0 0 0', [g_width/2 - g_height/2, g_height, 0], '0 0 0', 1, 0);
|
||||||
drawpic([(g_width/2 - g_height/2),0,0], "gfx/hud/scope_nb.tga", [g_height, g_height, 1], [1,1,1], 1);
|
drawpic([(g_width/2 - g_height/2),0,0], "gfx/hud/scope_nb.tga", [g_height, g_height, 1], [1,1,1], 1);
|
||||||
drawfill([(g_width/2 + g_height/2),0,0], [g_width, g_height, 0], '0 0 0', 1, 0);
|
drawfill([(g_width/2 + g_height/2),0,0], [g_width, g_height, 0], '0 0 0', 1, 0);
|
||||||
|
|
||||||
|
// Draw "Hold Breath" text if we aren't already doing so and we don't have Deadshot Daiquiri.
|
||||||
|
if (sniper_hold_breath != true && !(getstatf(STAT_PERKS) & P_DEAD)) {
|
||||||
|
// Grab the bind for Sprint/Hold Breath
|
||||||
|
string breath_button = "";
|
||||||
|
string space_width = "";
|
||||||
|
|
||||||
|
float argc = tokenize(findkeysforcommandex("impulse 23"));
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
breath_button = strtoupper(argv(i));
|
||||||
|
float bind_is_gamepad = Key_IsControllerGlyph(breath_button);
|
||||||
|
|
||||||
|
if (bind_is_gamepad && last_input_was_gamepad)
|
||||||
|
break;
|
||||||
|
else if (!bind_is_gamepad && !last_input_was_gamepad)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (breath_button == "")
|
||||||
|
breath_button = "UNBOUND";
|
||||||
|
|
||||||
|
string breath_button_string = " ";
|
||||||
|
|
||||||
|
// If this is a gamepad button, the space we want to reserve
|
||||||
|
// in the string should be a fixed width.
|
||||||
|
if (!Key_IsControllerGlyph(breath_button)) {
|
||||||
|
breath_button_string = breath_button;
|
||||||
|
}
|
||||||
|
|
||||||
|
string breath_string = strcat("Hold ", breath_button_string, " to steady");
|
||||||
|
float print_width = getTextWidth(breath_string, 12);
|
||||||
|
float x = (g_width - print_width)/2;
|
||||||
|
Draw_String([x, 65, 0], breath_string, [12, 12, 0], [1, 1, 1], 1, 0);
|
||||||
|
|
||||||
|
// Draw highlighted button
|
||||||
|
float button_width = x + getTextWidth("Hold ", 12);
|
||||||
|
|
||||||
|
if (Key_IsControllerGlyph(breath_button))
|
||||||
|
Key_DrawControllerGlyph([button_width - 5, 62], breath_button, [18, 18]);
|
||||||
|
else
|
||||||
|
Draw_String([button_width, 65, 0], breath_button, [12, 12, 0], [1, 1, 0], 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -609,22 +609,102 @@ float(float a) angledelta =
|
||||||
}
|
}
|
||||||
|
|
||||||
//MOVEME
|
//MOVEME
|
||||||
float delta_pitch, delta_yaw;
|
vector current_sway;
|
||||||
|
float current_intensity;
|
||||||
|
float target_intensity;
|
||||||
vector sniper_sway;
|
vector sniper_sway;
|
||||||
// Sways the camera while scoped in.
|
float sniper_breath_starttime;
|
||||||
void() Camera_SniperSway =
|
float sniper_breath_endtime;
|
||||||
|
float sniper_breath_counter;
|
||||||
|
float sniper_breath_exhaustion_starttime;
|
||||||
|
float sniper_breath_exhaustion_endtime;
|
||||||
|
float sniper_breath_delay;
|
||||||
|
float sniper_hold_breath;
|
||||||
|
|
||||||
|
#define SNIPER_SWAY_INTENSITY_FOCUSED 0.05
|
||||||
|
#define SNIPER_SWAY_INTENSITY_NORMAL 0.5
|
||||||
|
#define SNIPER_SWAY_INTENSITY_EXHAUSTION 2
|
||||||
|
|
||||||
|
void(float inhale) Sniper_HoldBreath =
|
||||||
{
|
{
|
||||||
|
if (sniper_breath_delay > time)
|
||||||
|
return;
|
||||||
|
|
||||||
if (getstatf(STAT_WEAPONZOOM) != 2 || (getstatf(STAT_PERKS) & P_DEAD)) {
|
if (getstatf(STAT_WEAPONZOOM) != 2 || (getstatf(STAT_PERKS) & P_DEAD)) {
|
||||||
sniper_sway = '0 0 0';
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
delta_pitch = (cos(cltime/0.7) + cos(cltime) + sin(cltime/1.1)) * 0.5;
|
if (inhale) {
|
||||||
delta_yaw = (sin(cltime/0.4) + cos(cltime/0.56) + sin(cltime)) * 0.5;
|
if (sniper_hold_breath == true)
|
||||||
|
return;
|
||||||
sniper_sway[0] = angledelta(delta_pitch);
|
sniper_breath_starttime = time;
|
||||||
sniper_sway[1] = angledelta(delta_yaw);
|
sniper_breath_endtime = time + 4;
|
||||||
|
sniper_hold_breath = true;
|
||||||
|
localsound("sounds/player/inhale.wav", 0, 1);
|
||||||
|
} else {
|
||||||
|
if (sniper_hold_breath == false)
|
||||||
|
return;
|
||||||
|
sniper_breath_endtime = sniper_breath_starttime = 0;
|
||||||
|
sniper_hold_breath = false;
|
||||||
|
sniper_breath_delay = time + 1;
|
||||||
|
localsound("sounds/player/exhale.wav", 0, 1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void() Camera_SniperSway =
|
||||||
|
{
|
||||||
|
// Determine target intensity based on state
|
||||||
|
target_intensity = SNIPER_SWAY_INTENSITY_NORMAL;
|
||||||
|
|
||||||
|
if (getstatf(STAT_WEAPONZOOM) != 2 || (getstatf(STAT_PERKS) & P_DEAD)) {
|
||||||
|
current_intensity = 0;
|
||||||
|
current_sway = '0 0 0';
|
||||||
|
target_intensity = 0;
|
||||||
|
sniper_breath_counter = 0;
|
||||||
|
} else {
|
||||||
|
// We are focused.
|
||||||
|
if (sniper_breath_endtime > time) {
|
||||||
|
target_intensity = SNIPER_SWAY_INTENSITY_FOCUSED;
|
||||||
|
|
||||||
|
float breath_duration = floor(time - sniper_breath_starttime);
|
||||||
|
|
||||||
|
// Play heartbeat sfx at every second interval.
|
||||||
|
if (breath_duration != sniper_breath_counter) {
|
||||||
|
sniper_breath_counter = breath_duration;
|
||||||
|
localsound("sounds/player/heart.wav", 0, 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Time has expired and we're out of breath, begin exhaustion.
|
||||||
|
else if (sniper_breath_endtime < time && sniper_hold_breath == true) {
|
||||||
|
Sniper_HoldBreath(false);
|
||||||
|
sniper_breath_exhaustion_starttime = time;
|
||||||
|
sniper_breath_exhaustion_endtime = time + 4;
|
||||||
|
sniper_breath_delay = time + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slowly decrease in intensity from fully exhausted to normal.
|
||||||
|
if (sniper_breath_exhaustion_endtime > time) {
|
||||||
|
float progress = (time - sniper_breath_exhaustion_starttime) / (sniper_breath_exhaustion_endtime - sniper_breath_exhaustion_starttime);
|
||||||
|
target_intensity = SNIPER_SWAY_INTENSITY_EXHAUSTION + progress * (SNIPER_SWAY_INTENSITY_NORMAL - SNIPER_SWAY_INTENSITY_EXHAUSTION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Smoothly interpolate intensity towards target
|
||||||
|
current_intensity += (target_intensity - current_intensity) * (clframetime * 5); // Adjust 0.1 for smoother/faster transitions
|
||||||
|
|
||||||
|
// Calculate sway deltas based on cltime and intensity
|
||||||
|
float sway_pitch = (cos(cltime / 0.7) + cos(cltime) + sin(cltime / 1.1));
|
||||||
|
float sway_yaw = (sin(cltime / 0.4) + cos(cltime / 0.56) + sin(cltime));
|
||||||
|
|
||||||
|
// Update current sway using the smoothly interpolated intensity
|
||||||
|
current_sway[0] = sway_pitch * current_intensity;
|
||||||
|
current_sway[1] = sway_yaw * current_intensity;
|
||||||
|
|
||||||
|
// Apply the smooth sway to sniper_sway
|
||||||
|
sniper_sway[0] = angledelta(current_sway[0]);
|
||||||
|
sniper_sway[1] = angledelta(current_sway[1]);
|
||||||
|
};
|
||||||
|
|
||||||
float gamepad_enabled;
|
float gamepad_enabled;
|
||||||
|
|
||||||
// CALLED EVERY CLIENT RENDER FRAME
|
// CALLED EVERY CLIENT RENDER FRAME
|
||||||
|
@ -782,6 +862,13 @@ void(float scanx, float setval) Input_Movecheck =
|
||||||
tokenize(findkeysforcommand("+back"));
|
tokenize(findkeysforcommand("+back"));
|
||||||
if (scanx == stof(argv(0)))
|
if (scanx == stof(argv(0)))
|
||||||
K_BACKDOWN = setval;
|
K_BACKDOWN = setval;
|
||||||
|
|
||||||
|
float argc = tokenize(findkeysforcommand("impulse 23"));
|
||||||
|
for (int i = 0; i < argc; i++) {
|
||||||
|
if (scanx == stof(argv(i))) {
|
||||||
|
Sniper_HoldBreath(setval);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
noref float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent =
|
noref float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent =
|
||||||
|
|
Loading…
Reference in a new issue