From c3c746501a5c1f7f216d7a21fd403a00ba93d7d9 Mon Sep 17 00:00:00 2001 From: div0 Date: Mon, 30 Mar 2009 08:39:32 +0000 Subject: [PATCH] jetpack: add a "fuel" ammo type, and use that - and let it have regeneration git-svn-id: svn://svn.icculus.org/nexuiz/trunk@6359 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/defaultNexuiz.cfg | 10 ++- data/qcsrc/client/sbar.qc | 138 +++++++++++++---------------- data/qcsrc/common/constants.qh | 1 + data/qcsrc/common/items.qh | 7 +- data/qcsrc/server/cl_client.qc | 32 ++++++- data/qcsrc/server/cl_physics.qc | 20 ++--- data/qcsrc/server/defs.qh | 3 + data/qcsrc/server/g_hook.qc | 2 +- data/qcsrc/server/miscfunctions.qc | 7 +- data/qcsrc/server/w_hook.qc | 6 +- 10 files changed, 127 insertions(+), 99 deletions(-) diff --git a/data/defaultNexuiz.cfg b/data/defaultNexuiz.cfg index 0ace65184..15509b307 100644 --- a/data/defaultNexuiz.cfg +++ b/data/defaultNexuiz.cfg @@ -1423,7 +1423,15 @@ set g_jetpack_acceleration_side 1200 "acceleration of the jetpack in xy directio set g_jetpack_acceleration_up 600 "acceleration of the jetpack in z direction (note: you have to factor in gravity here, if antigravity is not 1)" set g_jetpack_maxspeed_side 1500 "max speed of the jetpack in xy direction" set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction" -set g_jetpack_ammo 3 "cells per second for jetpack" +set g_jetpack_fuel 3 "fuel per second for jetpack" + +set g_balance_fuel_regen 0.1 "fuel regeneration (only applies if the player owns IT_FUEL_REGEN)" +set g_balance_fuel_rot 0.1 +set g_balance_fuel_regenlinear 0 +set g_balance_fuel_rotlinear 0 +set g_balance_fuel_stable 100 +set g_balance_fuel_limit 999 +set g_balance_fuel_start 100 set cl_effects_lightningarc_simple 0 set cl_effects_lightningarc_segmentlength 64 diff --git a/data/qcsrc/client/sbar.qc b/data/qcsrc/client/sbar.qc index 6eb4e958e..4f15c5724 100644 --- a/data/qcsrc/client/sbar.qc +++ b/data/qcsrc/client/sbar.qc @@ -1722,12 +1722,52 @@ void Sbar_DrawPressedKeys(void) drawpic(pos + ' 65 32 0', "gfx/keys/key_right.tga", ' 32 32 0', '1 1 1', .5 * ((pressedkeys & KEY_RIGHT) + 1), DRAWFLAG_NORMAL); } +float GetAmmoStat(float i) +{ + switch(i) + { + case 0: return STAT_SHELLS; + case 1: return STAT_NAILS; + case 2: return STAT_ROCKETS; + case 3: return STAT_CELLS; + case 4: return STAT_FUEL; + default: return -1; + } +} + +float GetAmmoItemCode(float i) +{ + switch(i) + { + case 0: return IT_SHELLS; + case 1: return IT_NAILS; + case 2: return IT_ROCKETS; + case 3: return IT_CELLS; + case 4: return IT_FUEL; + default: return -1; + } +} + +string GetAmmoPicture(float i) +{ + switch(i) + { + case 0: return "gfx/sb_shells"; + case 1: return "gfx/sb_bullets"; + case 2: return "gfx/sb_rockets"; + case 3: return "gfx/sb_cells"; + case 4: return "gfx/sb_fuel"; + default: return ""; + } +} + void Sbar_Draw (void) { float i; float x, fade; float stat_items, stat_weapons; vector o; o = '1 0 0' * vid_conwidth; + vector v; string s; sbar_fontsize = Sbar_GetFontsize("sbar_fontsize"); @@ -1967,43 +2007,17 @@ void Sbar_Draw (void) } // ammo - if (stat_items & IT_SHELLS) - x = getstati(STAT_SHELLS); - else if (stat_items & IT_NAILS) - x = getstati(STAT_NAILS); - else if (stat_items & IT_ROCKETS) - x = getstati(STAT_ROCKETS); - else if (stat_items & IT_CELLS) - x = getstati(STAT_CELLS); - else - x = 0; - if ((stat_items & IT_AMMO) || x != 0) - { - if (stat_items & IT_SHELLS) - drawpic(sbar + '296 0 0', "gfx/sb_shells", '24 24 0', '1 1 1', sbar_alpha_fg, 0); - else if (stat_items & IT_NAILS) - drawpic(sbar + '296 0 0', "gfx/sb_bullets", '24 24 0', '1 1 1', sbar_alpha_fg, 0); - else if (stat_items & IT_ROCKETS) - drawpic(sbar + '296 0 0', "gfx/sb_rocket", '24 24 0', '1 1 1', sbar_alpha_fg, 0); - else if (stat_items & IT_CELLS) - drawpic(sbar + '296 0 0', "gfx/sb_cells", '24 24 0', '1 1 1', sbar_alpha_fg, 0); - if(x > 10) - Sbar_DrawXNum('224 0 0', x, 3, 24, '0.6 0.7 0.8', 1, 0); - else - Sbar_DrawXNum('224 0 0', x, 3, 24, '0.7 0 0', 1, 0); - } - - // jetpack cells - if(stat_items & IT_USING_JETPACK) - if not(stat_items & IT_CELLS) - { - x = getstati(STAT_CELLS); - drawpic(sbar + '296 -30 0', "gfx/sb_cells", '24 24 0', '1 1 1', sbar_alpha_fg, 0); - if(x > 10) - Sbar_DrawXNum('224 -30 0', x, 3, 24, '0.6 0.7 0.8', 1, 0); - else - Sbar_DrawXNum('224 -30 0', x, 3, 24, '0.7 0 0', 1, 0); - } + for(i = 0, v = '0 0 0'; (x = GetAmmoStat(i)) >= 0; ++i) + if(stat_items & GetAmmoItemCode(i)) + { + x = getstati(x); + drawpic(sbar + '296 0 0' + v, GetAmmoPicture(i), '24 24 0', '1 1 1', sbar_alpha_fg, 0); + if(x > 10) + Sbar_DrawXNum('224 0 0' + v, x, 3, 24, '0.6 0.7 0.8', 1, 0); + else + Sbar_DrawXNum('224 0 0' + v, x, 3, 24, '0.7 0 0', 1, 0); + v_y -= 30; + } if (sbar_x + 320 + 160 <= vid_conwidth) Sbar_MiniDeathmatchOverlay(sbar + '320 0 0'); @@ -2055,44 +2069,18 @@ void Sbar_Draw (void) else Sbar_DrawXNum('81 12 0', x, 3, 24, '0.6 0.7 0.8', 1, 0); - if (stat_items & IT_SHELLS) - x = getstati(STAT_SHELLS); - else if (stat_items & IT_NAILS) - x = getstati(STAT_NAILS); - else if (stat_items & IT_ROCKETS) - x = getstati(STAT_ROCKETS); - else if (stat_items & IT_CELLS) - x = getstati(STAT_CELLS); - else - x = 0; - if ((stat_items & IT_AMMO) || x != 0) - { - // (519-3*24) = 447 - if (stat_items & IT_SHELLS) - drawpic(sbar + '519 0 0', "gfx/sb_shells", '0 0 0', '1 1 1', sbar_alpha_fg, 0); - else if (stat_items & IT_NAILS) - drawpic(sbar + '519 0 0', "gfx/sb_bullets", '0 0 0', '1 1 1', sbar_alpha_fg, 0); - else if (stat_items & IT_ROCKETS) - drawpic(sbar + '519 0 0', "gfx/sb_rocket", '0 0 0', '1 1 1', sbar_alpha_fg, 0); - else if (stat_items & IT_CELLS) - drawpic(sbar + '519 0 0', "gfx/sb_cells", '0 0 0', '1 1 1', sbar_alpha_fg, 0); - if(x > 10) - Sbar_DrawXNum('447 12 0', x, 3, 24, '0.6 0.7 0.8', 1, 0); - else - Sbar_DrawXNum('447 12 0', x, 3, 24, '0.7 0 0', 1, 0); - } - - // jetpack cells - if(stat_items & IT_USING_JETPACK) - if not(stat_items & IT_CELLS) - { - x = getstati(STAT_CELLS); - drawpic(sbar + '519 -40 0', "gfx/sb_cells", '0 0 0', '1 1 1', sbar_alpha_fg, 0); - if(x > 10) - Sbar_DrawXNum('447 -28 0', x, 3, 24, '0.6 0.7 0.8', 1, 0); - else - Sbar_DrawXNum('447 -28 0', x, 3, 24, '0.7 0 0', 1, 0); - } + // ammo + for(i = 0, v = '0 0 0'; (x = GetAmmoStat(i)) >= 0; ++i) + if(stat_items & GetAmmoItemCode(i)) + { + x = getstati(x); + drawpic(sbar + '519 0 0' + v, GetAmmoPicture(i), '24 24 0', '1 1 1', sbar_alpha_fg, 0); + if(x > 10) + Sbar_DrawXNum('447 12 0' + v, x, 3, 24, '0.6 0.7 0.8', 1, 0); + else + Sbar_DrawXNum('447 12 0' + v, x, 3, 24, '0.7 0 0', 1, 0); + v_y -= 40; + } if (sb_lines > 24) drawpic(sbar, "gfx/sbar_overlay", '0 0 0', '1 1 1', 1, DRAWFLAG_MODULATE); diff --git a/data/qcsrc/common/constants.qh b/data/qcsrc/common/constants.qh index b34a93681..97f756a3a 100644 --- a/data/qcsrc/common/constants.qh +++ b/data/qcsrc/common/constants.qh @@ -246,6 +246,7 @@ const float STAT_STRENGTH_FINISHED = 38; const float STAT_INVINCIBLE_FINISHED = 39; const float STAT_PRESSED_KEYS = 42; const float STAT_ALLOW_OLDNEXBEAM = 43; // this stat could later contain some other bits of info, like, more server-side particle config +const float STAT_FUEL = 44; const float CTF_STATE_ATTACK = 1; const float CTF_STATE_DEFEND = 2; const float CTF_STATE_COMMANDER = 3; diff --git a/data/qcsrc/common/items.qh b/data/qcsrc/common/items.qh index 2caf7713c..2caa0f937 100644 --- a/data/qcsrc/common/items.qh +++ b/data/qcsrc/common/items.qh @@ -31,13 +31,16 @@ float IT_UNLIMITED_AMMO = 3; // both of these combined float IT_CTF_SHIELDED = 4; // set for the flag shield // using jetpack -float IT_USING_JETPACK = 8; +float IT_USING_JETPACK = 8; // confirmation that button is pressed +float IT_JETPACK = 16; // actual item +float IT_FUEL_REGEN = 32; // fuel regeneration trigger float IT_SHELLS = 256; float IT_NAILS = 512; float IT_ROCKETS = 1024; float IT_CELLS = 2048; float IT_SUPERWEAPON = 4096; -float IT_AMMO = 7936; +float IT_FUEL = 128; +float IT_AMMO = 8064; float IT_STRENGTH = 8192; float IT_INVINCIBLE = 16384; float IT_HEALTH = 32768; diff --git a/data/qcsrc/server/cl_client.qc b/data/qcsrc/server/cl_client.qc index 52a3ac4a9..b61815041 100644 --- a/data/qcsrc/server/cl_client.qc +++ b/data/qcsrc/server/cl_client.qc @@ -1700,11 +1700,13 @@ float CalcRegen(float current, float stable, float regenfactor) void player_regen (void) { - float maxh, maxa, limith, limita, max_mod, regen_mod, rot_mod, limit_mod; + float maxh, maxa, maxf, limith, limita, limitf, max_mod, regen_mod, rot_mod, limit_mod; maxh = cvar("g_balance_health_stable"); maxa = cvar("g_balance_armor_stable"); + maxf = cvar("g_balance_fuel_stable"); limith = cvar("g_balance_health_limit"); limita = cvar("g_balance_armor_limit"); + limitf = cvar("g_balance_fuel_limit"); if (g_minstagib || (g_lms && !cvar("g_lms_regenerate"))) return; @@ -1739,8 +1741,10 @@ void player_regen (void) } maxh = maxh * max_mod; //maxa = maxa * max_mod; + //maxf = maxf * max_mod; limith = limith * limit_mod; limita = limita * limit_mod; + //limitf = limitf * limit_mod; if (self.armorvalue > maxa) { @@ -1774,11 +1778,32 @@ void player_regen (void) self.health = min(maxh, self.health + regen_mod*cvar("g_balance_health_regenlinear") * frametime); } } + if (self.ammo_fuel > maxf) + { + if (time > self.pauserotfuel_finished) + { + self.ammo_fuel = max(maxf, self.ammo_fuel + (maxf - self.ammo_fuel) * rot_mod*cvar("g_balance_fuel_rot") * frametime); + self.ammo_fuel = max(maxf, self.ammo_fuel - rot_mod*cvar("g_balance_fuel_rotlinear") * frametime); + } + } + else if (self.ammo_fuel < maxf) + { + if(self.items & IT_FUEL_REGEN) + { + if (time > self.pauseregen_finished) + { + self.ammo_fuel = CalcRegen(self.ammo_fuel, maxf, regen_mod * cvar("g_balance_fuel_regen")); + self.ammo_fuel = min(maxf, self.ammo_fuel + regen_mod*cvar("g_balance_fuel_regenlinear") * frametime); + } + } + } if (self.health > limith) self.health = limith; if (self.armorvalue > limita) self.armorvalue = limita; + if (self.ammo_fuel > limitf) + self.ammo_fuel = limitf; // if player rotted to death... die! if(self.health < 1) @@ -1848,6 +1873,7 @@ void SpectateCopy(entity spectatee) { self.ammo_shells = spectatee.ammo_shells; self.ammo_nails = spectatee.ammo_nails; self.ammo_rockets = spectatee.ammo_rockets; + self.ammo_fuel = spectatee.ammo_fuel; self.effects = spectatee.effects & EFMASK_CHEAP; // eat performance self.health = spectatee.health; self.impulse = 0; @@ -2337,7 +2363,11 @@ void PlayerPreThink (void) GrapplingHookFrame(); if(frametime) + { W_WeaponFrame(); + if(self.items & IT_JETPACK) + self.items |= IT_FUEL; + } player_regen(); if(frametime) diff --git a/data/qcsrc/server/cl_physics.qc b/data/qcsrc/server/cl_physics.qc index 931b0375e..494304fd3 100644 --- a/data/qcsrc/server/cl_physics.qc +++ b/data/qcsrc/server/cl_physics.qc @@ -638,7 +638,7 @@ void SV_PlayerPhysics() self.velocity = self.velocity + wishdir * min(f, sv_accelerate*maxspd_mod * frametime * wishspeed); } } - else if (g_jetpack && self.BUTTON_HOOK && (!cvar("g_jetpack_ammo") || self.ammo_cells >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO)) + else if ((self.items & IT_JETPACK) && self.BUTTON_HOOK && (!cvar("g_jetpack_fuel") || self.ammo_fuel >= 0.01 || self.items & IT_UNLIMITED_WEAPON_AMMO)) { //makevectors(self.v_angle_y * '0 1 0'); makevectors(self.v_angle); @@ -670,13 +670,8 @@ void SV_PlayerPhysics() wishvel_z = (wishvel_z - sv_gravity) * fz + sv_gravity; fvel = min(1, vlen(wishvel) / fvel); - if(cvar("g_jetpack_ammo") && !(self.items & IT_UNLIMITED_WEAPON_AMMO)) - { - if(self.ammo_cells < 0.01) - f = 0; - else - f = min(1, self.ammo_cells / (cvar("g_jetpack_ammo") * frametime * fvel)); - } + if(cvar("g_jetpack_fuel") && !(self.items & IT_UNLIMITED_WEAPON_AMMO)) + f = min(1, self.ammo_fuel / (cvar("g_jetpack_fuel") * frametime * fvel)); else f = 1; @@ -684,15 +679,18 @@ void SV_PlayerPhysics() { self.velocity = self.velocity + wishvel * f * frametime; if not(self.items & IT_UNLIMITED_WEAPON_AMMO) - self.ammo_cells -= cvar("g_jetpack_ammo") * frametime * fvel * f; + self.ammo_fuel -= cvar("g_jetpack_fuel") * frametime * fvel * f; self.flags &~= FL_ONGROUND; self.items |= IT_USING_JETPACK; + + // jetpack also inhibits health regeneration! + self.pauseregen_finished = max(self.pauseregen_finished, time + cvar("g_balance_pause_health_regen")); } } else if (self.flags & FL_ONGROUND) { // we get here if we ran out of ammo - if(g_jetpack && self.BUTTON_HOOK && !(buttons_prev & 32)) + if((self.items & IT_JETPACK) && self.BUTTON_HOOK && !(buttons_prev & 32)) sprint(self, "You don't have any fuel for the ^2Jetpack\n"); // walking @@ -742,7 +740,7 @@ void SV_PlayerPhysics() else { // we get here if we ran out of ammo - if(g_jetpack && self.BUTTON_HOOK && !(buttons_prev & 32)) + if((self.items & IT_JETPACK) && self.BUTTON_HOOK && !(buttons_prev & 32)) sprint(self, "You don't have any fuel for the ^2Jetpack\n"); if(maxspd_mod < 1) diff --git a/data/qcsrc/server/defs.qh b/data/qcsrc/server/defs.qh index 819e331ad..4b1172053 100644 --- a/data/qcsrc/server/defs.qh +++ b/data/qcsrc/server/defs.qh @@ -190,6 +190,7 @@ void setanim(entity e, vector anim, float looping, float override, float restart .float pauseregen_finished; .float pauserothealth_finished; .float pauserotarmor_finished; +.float pauserotfuel_finished; .string item_pickupsound; // definitions for weaponsystem @@ -557,3 +558,5 @@ float servertime, serverprevtime, serverframetime; void Drag_MoveDrag(entity from, entity to); .entity soundentity; + +.float ammo_fuel; diff --git a/data/qcsrc/server/g_hook.qc b/data/qcsrc/server/g_hook.qc index 7ae9d5ce6..f49c6cf5e 100644 --- a/data/qcsrc/server/g_hook.qc +++ b/data/qcsrc/server/g_hook.qc @@ -408,7 +408,7 @@ void GrapplingHookFrame() //self.hook_state &~= HOOK_RELEASING; } } - else if(!g_jetpack && !g_grappling_hook && self.switchweapon != WEP_HOOK) + else if(!(self.items & IT_JETPACK) && !g_grappling_hook && self.switchweapon != WEP_HOOK) { if(self.BUTTON_HOOK && !self.hook_switchweapon) W_SwitchWeapon(WEP_HOOK); diff --git a/data/qcsrc/server/miscfunctions.qc b/data/qcsrc/server/miscfunctions.qc index c4b659b61..57d08c1c7 100644 --- a/data/qcsrc/server/miscfunctions.qc +++ b/data/qcsrc/server/miscfunctions.qc @@ -949,12 +949,9 @@ void readplayerstartcvars() if(g_jetpack) { - if(!start_ammo_cells) - start_ammo_cells = g_pickup_cells; - if(!warmup_start_ammo_cells) - warmup_start_ammo_cells = g_pickup_cells; - g_grappling_hook = 0; // these two can't coexist, as they use the same button + start_items |= IT_JETPACK; + start_items |= IT_FUEL_REGEN; } if(g_weapon_stay == 2) diff --git a/data/qcsrc/server/w_hook.qc b/data/qcsrc/server/w_hook.qc index 0f5af5b11..03f918182 100644 --- a/data/qcsrc/server/w_hook.qc +++ b/data/qcsrc/server/w_hook.qc @@ -111,7 +111,7 @@ float w_hook(float req) } else if (req == WR_THINK) { - if (self.BUTTON_ATCK || (!g_jetpack && self.BUTTON_HOOK)) + if (self.BUTTON_ATCK || (!(self.items & IT_JETPACK) && self.BUTTON_HOOK)) { if(!self.hook) if not(self.hook_state & HOOK_WAITING_FOR_RELEASE) @@ -179,7 +179,7 @@ float w_hook(float req) if (self.BUTTON_CROUCH) { self.hook_state &~= HOOK_PULLING; - if (self.BUTTON_ATCK || (!g_jetpack && self.BUTTON_HOOK)) + if (self.BUTTON_ATCK || (!(self.items & IT_JETPACK) && self.BUTTON_HOOK)) self.hook_state &~= HOOK_RELEASING; else self.hook_state |= HOOK_RELEASING; @@ -189,7 +189,7 @@ float w_hook(float req) self.hook_state |= HOOK_PULLING; self.hook_state &~= HOOK_RELEASING; - if (self.BUTTON_ATCK || (!g_jetpack && self.BUTTON_HOOK)) + if (self.BUTTON_ATCK || (!(self.items & IT_JETPACK) && self.BUTTON_HOOK)) { // already fired if(self.hook) -- 2.39.2