mirror of
https://github.com/nzp-team/quakec.git
synced 2025-02-14 16:01:52 +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 achievement_pages;
|
||||
|
||||
float sniper_hold_breath;
|
||||
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -609,22 +609,102 @@ float(float a) angledelta =
|
|||
}
|
||||
|
||||
//MOVEME
|
||||
float delta_pitch, delta_yaw;
|
||||
vector current_sway;
|
||||
float current_intensity;
|
||||
float target_intensity;
|
||||
vector sniper_sway;
|
||||
// Sways the camera while scoped in.
|
||||
void() Camera_SniperSway =
|
||||
float sniper_breath_starttime;
|
||||
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)) {
|
||||
sniper_sway = '0 0 0';
|
||||
return;
|
||||
}
|
||||
|
||||
delta_pitch = (cos(cltime/0.7) + cos(cltime) + sin(cltime/1.1)) * 0.5;
|
||||
delta_yaw = (sin(cltime/0.4) + cos(cltime/0.56) + sin(cltime)) * 0.5;
|
||||
|
||||
sniper_sway[0] = angledelta(delta_pitch);
|
||||
sniper_sway[1] = angledelta(delta_yaw);
|
||||
if (inhale) {
|
||||
if (sniper_hold_breath == true)
|
||||
return;
|
||||
sniper_breath_starttime = time;
|
||||
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;
|
||||
|
||||
// CALLED EVERY CLIENT RENDER FRAME
|
||||
|
@ -782,6 +862,13 @@ void(float scanx, float setval) Input_Movecheck =
|
|||
tokenize(findkeysforcommand("+back"));
|
||||
if (scanx == stof(argv(0)))
|
||||
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 =
|
||||
|
|
Loading…
Reference in a new issue