X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Fmutators%2Fmutator%2Fbuffs%2Fsv_buffs.qc;h=fdc555dd2a90ede54ae5bfe332cce78a9108b833;hp=4bc977d2ba945615872227ac0db9747a0f9b8580;hb=29ba411594428929a9e9a0e0baa620210213bec7;hpb=f7b69c7bd1d05162b3c532422e3ce3013dc0f5f2;ds=sidebyside diff --git a/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc b/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc index 4bc977d2b..fdc555dd2 100644 --- a/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc +++ b/qcsrc/common/mutators/mutator/buffs/sv_buffs.qc @@ -6,11 +6,14 @@ .float buff_time = _STAT(BUFF_TIME); void buffs_DelayedInit(entity this); -REGISTER_MUTATOR(buffs, cvar("g_buffs")) +AUTOCVAR(g_buffs, int, -1, "Enable buffs, -1: enabled but no auto location or replacing powerups, 1: enabled and can replace them"); + +REGISTER_MUTATOR(buffs, autocvar_g_buffs) { MUTATOR_ONADD { - InitializeEntity(NULL, buffs_DelayedInit, INITPRIO_FINDTARGET); + if(autocvar_g_buffs > 0) + InitializeEntity(NULL, buffs_DelayedInit, INITPRIO_FINDTARGET); } } @@ -111,7 +114,7 @@ void buff_SetCooldown(entity this, float cd) void buff_Respawn(entity this) { - if(gameover) { return; } + if(game_stopped) return; vector oldbufforigin = this.origin; this.velocity = '0 0 200'; @@ -146,7 +149,7 @@ void buff_Respawn(entity this) void buff_Touch(entity this, entity toucher) { - if(gameover) { return; } + if(game_stopped) return; if(ITEM_TOUCH_NEEDKILL()) { @@ -154,15 +157,8 @@ void buff_Touch(entity this, entity toucher) return; } - if((this.team && DIFF_TEAM(toucher, this)) - || (STAT(FROZEN, toucher)) - || (toucher.vehicle) - || (!this.buff_active) - ) - { - // can't touch this + if(!this.buff_active) return; - } if(MUTATOR_CALLHOOK(BuffTouch, this, toucher)) return; @@ -171,6 +167,16 @@ void buff_Touch(entity this, entity toucher) if(!IS_PLAYER(toucher)) return; // incase mutator changed toucher + if((this.team && DIFF_TEAM(toucher, this)) + || (STAT(FROZEN, toucher)) + || (toucher.vehicle) + || (time < PS(toucher).buff_shield) + ) + { + // can't touch this + return; + } + if (toucher.buffs) { if (toucher.cvar_cl_buffs_autoreplace && toucher.buffs != this.buffs) @@ -210,15 +216,17 @@ float buff_Available(entity buff) .int buff_seencount; -void buff_NewType(entity ent, float cb) +void buff_NewType(entity ent) { RandomSelection_Init(); - FOREACH(Buffs, buff_Available(it), LAMBDA( - it.buff_seencount += 1; + FOREACH(Buffs, buff_Available(it), + { // if it's already been chosen, give it a lower priority - RandomSelection_AddFloat(it.m_itemid, 1, max(0.2, 1 / it.buff_seencount)); - )); - ent.buffs = RandomSelection_chosen_float; + RandomSelection_AddEnt(it, max(0.2, 1 / it.buff_seencount), 1); + }); + entity newbuff = RandomSelection_chosen_ent; + newbuff.buff_seencount += 1; // lower chances of seeing this buff again soon + ent.buffs = newbuff.m_itemid; } void buff_Think(entity this) @@ -245,7 +253,7 @@ void buff_Think(entity this) this.oldbuffs = this.buffs; } - if(!gameover) + if(!game_stopped) if((round_handler_IsActive() && !round_handler_IsRoundStarted()) || time >= game_starttime) if(!this.buff_activetime_updated) { @@ -254,19 +262,19 @@ void buff_Think(entity this) } if(!this.buff_active && !this.buff_activetime) - if(!this.owner || STAT(FROZEN, this.owner) || IS_DEAD(this.owner) || !this.owner.iscreature || !(this.owner.buffs & this.buffs)) + if(!this.owner || STAT(FROZEN, this.owner) || IS_DEAD(this.owner) || !this.owner.iscreature || this.owner.vehicle || !(this.owner.buffs & this.buffs) || this.pickup_anyway > 0 || (this.pickup_anyway >= 0 && autocvar_g_buffs_pickup_anyway)) { buff_SetCooldown(this, autocvar_g_buffs_cooldown_respawn + frametime); this.owner = NULL; if(autocvar_g_buffs_randomize) - buff_NewType(this, this.buffs); + buff_NewType(this); if(autocvar_g_buffs_random_location || (this.spawnflags & 64)) buff_Respawn(this); } if(this.buff_activetime) - if(!gameover) + if(!game_stopped) if((round_handler_IsActive() && !round_handler_IsRoundStarted()) || time >= game_starttime) { this.buff_activetime = max(0, this.buff_activetime - frametime); @@ -303,7 +311,7 @@ void buff_Waypoint_Reset(entity this) void buff_Reset(entity this) { if(autocvar_g_buffs_randomize) - buff_NewType(this, this.buffs); + buff_NewType(this); this.owner = NULL; buff_SetCooldown(this, autocvar_g_buffs_cooldown_activate); buff_Waypoint_Reset(this); @@ -340,14 +348,14 @@ void buff_Init(entity this) entity buff = buff_FirstFromFlags(this.buffs); - if(!this.buffs || buff_Available(buff)) - buff_NewType(this, 0); + if(!this.buffs || !buff_Available(buff)) + buff_NewType(this); this.classname = "item_buff"; this.solid = SOLID_TRIGGER; this.flags = FL_ITEM; this.bot_pickup = true; - this.bot_pickupevalfunc = commodity_pickupevalfunc; + this.bot_pickupevalfunc = generic_pickupevalfunc; this.bot_pickupbasevalue = 1000; IL_PUSH(g_items, this); setthink(this, buff_Think); @@ -364,7 +372,7 @@ void buff_Init(entity this) //this.gravity = 100; this.color = buff.m_color; this.glowmod = buff_GlowColor(this); - buff_SetCooldown(this, autocvar_g_buffs_cooldown_activate + game_starttime); + buff_SetCooldown(this, autocvar_g_buffs_cooldown_activate + max(0, game_starttime - time)); this.buff_active = !this.buff_activetime; this.pflags = PFLAGS_FULLDYNAMIC; @@ -431,22 +439,6 @@ float buff_Inferno_CalculateTime(float damg, float offset_x, float offset_y, flo } // mutator hooks -MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_SplitHealthArmor) -{ - entity frag_target = M_ARGV(2, entity); - float frag_deathtype = M_ARGV(6, float); - float frag_damage = M_ARGV(7, float); - - if(frag_deathtype == DEATH_BUFF.m_id) { return; } - - if(frag_target.buffs & BUFF_RESISTANCE.m_itemid) - { - vector v = healtharmor_applydamage(50, autocvar_g_buffs_resistance_blockpercent, frag_deathtype, frag_damage); - M_ARGV(4, float) = v.x; // take - M_ARGV(5, float) = v.y; // save - } -} - MUTATOR_HOOKFUNCTION(buffs, Damage_Calculate) { entity frag_attacker = M_ARGV(1, entity); @@ -457,6 +449,12 @@ MUTATOR_HOOKFUNCTION(buffs, Damage_Calculate) if(frag_deathtype == DEATH_BUFF.m_id) { return; } + if(frag_target.buffs & BUFF_RESISTANCE.m_itemid) + { + float reduced = frag_damage * autocvar_g_buffs_resistance_blockpercent; + frag_damage = bound(0, frag_damage - reduced, frag_damage); + } + if(frag_target.buffs & BUFF_SPEED.m_itemid) if(frag_target != frag_attacker) frag_damage *= autocvar_g_buffs_speed_damage_take; @@ -554,44 +552,31 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerSpawn) player.buffs = 0; player.buff_time = 0; + PS(player).buff_shield = time + 0.5; // prevent picking up buffs immediately // reset timers here to prevent them continuing after re-spawn player.buff_disability_time = 0; player.buff_disability_effect_time = 0; } -.float stat_sv_maxspeed; -.float stat_sv_airspeedlimit_nonqw; -.float stat_sv_jumpvelocity; - -MUTATOR_HOOKFUNCTION(buffs, PlayerPhysics) +MUTATOR_HOOKFUNCTION(buffs, PlayerPhysics_UpdateStats) { entity player = M_ARGV(0, entity); + // these automatically reset, no need to worry if(player.buffs & BUFF_SPEED.m_itemid) - { - player.stat_sv_maxspeed *= autocvar_g_buffs_speed_speed; - player.stat_sv_airspeedlimit_nonqw *= autocvar_g_buffs_speed_speed; - } + STAT(MOVEVARS_HIGHSPEED, player) *= autocvar_g_buffs_speed_speed; if(time < player.buff_disability_time) - { - player.stat_sv_maxspeed *= autocvar_g_buffs_disability_speed; - player.stat_sv_airspeedlimit_nonqw *= autocvar_g_buffs_disability_speed; - } - - if(player.buffs & BUFF_JUMP.m_itemid) - { - // automatically reset, no need to worry - player.stat_sv_jumpvelocity = autocvar_g_buffs_jump_height; - } + STAT(MOVEVARS_HIGHSPEED, player) *= autocvar_g_buffs_disability_speed; } -MUTATOR_HOOKFUNCTION(buffs, PlayerJump) +MUTATOR_HOOKFUNCTION(buffs, PlayerPhysics) { entity player = M_ARGV(0, entity); + // these automatically reset, no need to worry if(player.buffs & BUFF_JUMP.m_itemid) - M_ARGV(1, float) = autocvar_g_buffs_jump_height; + STAT(MOVEVARS_JUMPVELOCITY, player) = autocvar_g_buffs_jump_height; } MUTATOR_HOOKFUNCTION(buffs, MonsterMove) @@ -625,7 +610,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerDies) MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST) { - if(MUTATOR_RETURNVALUE || gameover) { return; } + if(MUTATOR_RETURNVALUE || game_stopped || !autocvar_g_buffs_drop) return; entity player = M_ARGV(0, entity); @@ -636,7 +621,8 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST) Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid); player.buffs = 0; - player.buff_time = 0; // already notified + PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); + //player.buff_time = 0; // already notified sound(player, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM); return true; } @@ -644,7 +630,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST) MUTATOR_HOOKFUNCTION(buffs, ForbidThrowCurrentWeapon) { - if(MUTATOR_RETURNVALUE || gameover) { return; } + if(MUTATOR_RETURNVALUE || game_stopped) return; entity player = M_ARGV(0, entity); if(player.buffs & BUFF_SWAPPER.m_itemid) @@ -744,6 +730,9 @@ MUTATOR_HOOKFUNCTION(buffs, CustomizeWaypoint) MUTATOR_HOOKFUNCTION(buffs, OnEntityPreSpawn, CBC_ORDER_LAST) { + if(autocvar_g_buffs < 0) + return; // no auto replacing of entities in this mode + entity ent = M_ARGV(0, entity); if(autocvar_g_buffs_replace_powerups) @@ -781,11 +770,24 @@ MUTATOR_HOOKFUNCTION(buffs, WeaponSpeedFactor) M_ARGV(0, float) *= autocvar_g_buffs_disability_weaponspeed; } +.bool buff_flight_crouchheld; + MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) { entity player = M_ARGV(0, entity); - if(gameover || IS_DEAD(player)) { return; } + if(game_stopped || IS_DEAD(player) || frametime || !IS_PLAYER(player)) return; + + if(player.buffs & BUFF_FLIGHT.m_itemid) + { + if(!PHYS_INPUT_BUTTON_CROUCH(player)) + player.buff_flight_crouchheld = false; + else if(!player.buff_flight_crouchheld) + { + player.buff_flight_crouchheld = true; + player.gravity *= -1; + } + } if(time < player.buff_disability_time) if(time >= player.buff_disability_effect_time) @@ -821,6 +823,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) else Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid); player.buffs = 0; + PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); // always put in a delay, even if small } } @@ -843,12 +846,17 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) } if(player.buffs & BUFF_AMMO.m_itemid) - if(player.clip_size) - player.clip_load = player.(weapon_load[PS(player).m_switchweapon.m_id]) = player.clip_size; + { + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(player.(weaponentity).clip_size) + player.(weaponentity).clip_load = player.(weaponentity).(weapon_load[player.(weaponentity).m_switchweapon.m_id]) = player.(weaponentity).clip_size; + } + } if((player.buffs & BUFF_INVISIBLE.m_itemid) && (player.oldbuffs & BUFF_INVISIBLE.m_itemid)) - if(player.alpha != autocvar_g_buffs_invisible_alpha) - player.alpha = autocvar_g_buffs_invisible_alpha; // powerups reset alpha, so we must enforce this (TODO) + player.alpha = ((autocvar_g_buffs_invisible_alpha) ? autocvar_g_buffs_invisible_alpha : -1); // powerups reset alpha, so we must enforce this (TODO) if(player.buffs & BUFF_MEDIC.m_itemid) if(time >= player.buff_medic_healtime) @@ -871,9 +879,17 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) player.buff_ammo_prev_infitems = (player.items & IT_UNLIMITED_WEAPON_AMMO); player.items |= IT_UNLIMITED_WEAPON_AMMO; - if(player.clip_load) - player.buff_ammo_prev_clipload = player.clip_load; - player.clip_load = player.(weapon_load[PS(player).m_switchweapon.m_id]) = player.clip_size; + if(player.buffs & BUFF_AMMO.m_itemid) + { + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(player.(weaponentity).clip_load) + player.(weaponentity).buff_ammo_prev_clipload = player.(weaponentity).clip_load; + if(player.(weaponentity).clip_size) + player.(weaponentity).clip_load = player.(weaponentity).(weapon_load[player.(weaponentity).m_switchweapon.m_id]) = player.(weaponentity).clip_size; + } + } } BUFF_ONREM(BUFF_AMMO) @@ -883,21 +899,43 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) else player.items &= ~IT_UNLIMITED_WEAPON_AMMO; - if(player.buff_ammo_prev_clipload) - player.clip_load = player.buff_ammo_prev_clipload; + if(player.buffs & BUFF_AMMO.m_itemid) + { + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(player.(weaponentity).buff_ammo_prev_clipload) + player.(weaponentity).clip_load = player.(weaponentity).buff_ammo_prev_clipload; + } + } } BUFF_ONADD(BUFF_INVISIBLE) { if(time < player.strength_finished && g_instagib) - player.alpha = autocvar_g_instagib_invis_alpha; + player.buff_invisible_prev_alpha = default_player_alpha; // we don't want to save the powerup's alpha, as player may lose the powerup while holding the buff else - player.alpha = player.buff_invisible_prev_alpha; + player.buff_invisible_prev_alpha = player.alpha; player.alpha = autocvar_g_buffs_invisible_alpha; } BUFF_ONREM(BUFF_INVISIBLE) - player.alpha = player.buff_invisible_prev_alpha; + { + if(time < player.strength_finished && g_instagib) + player.alpha = autocvar_g_instagib_invis_alpha; + else + player.alpha = player.buff_invisible_prev_alpha; + } + + BUFF_ONADD(BUFF_FLIGHT) + { + player.buff_flight_oldgravity = player.gravity; + if(!player.gravity) + player.gravity = 1; + } + + BUFF_ONREM(BUFF_FLIGHT) + player.gravity = ((player.trigger_gravity_check) ? player.trigger_gravity_check.enemy.gravity : player.buff_flight_oldgravity); player.oldbuffs = player.buffs; if(player.buffs) @@ -913,7 +951,8 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink) } else { - delete(player.buff_model); + if(player.buff_model) + delete(player.buff_model); player.buff_model = NULL; player.effects &= ~(EF_NOSHADOW); @@ -939,28 +978,7 @@ MUTATOR_HOOKFUNCTION(buffs, SpectateCopy) entity client = M_ARGV(1, entity); client.buffs = spectatee.buffs; -} - -MUTATOR_HOOKFUNCTION(buffs, VehicleEnter) -{ - entity player = M_ARGV(0, entity); - entity veh = M_ARGV(1, entity); - - veh.buffs = player.buffs; - player.buffs = 0; - veh.buff_time = max(0, player.buff_time - time); - player.buff_time = 0; -} - -MUTATOR_HOOKFUNCTION(buffs, VehicleExit) -{ - entity player = M_ARGV(0, entity); - entity veh = M_ARGV(1, entity); - - player.buffs = player.oldbuffs = veh.buffs; - veh.buffs = 0; - player.buff_time = time + veh.buff_time; - veh.buff_time = 0; + client.buff_time = spectatee.buff_time; } MUTATOR_HOOKFUNCTION(buffs, PlayerRegen) @@ -982,12 +1000,14 @@ REPLICATE(cvar_cl_buffs_autoreplace, bool, "cl_buffs_autoreplace"); MUTATOR_HOOKFUNCTION(buffs, BuildMutatorsString) { - M_ARGV(0, string) = strcat(M_ARGV(0, string), ":Buffs"); + if(autocvar_g_buffs > 0) // only report as a mutator if they're enabled + M_ARGV(0, string) = strcat(M_ARGV(0, string), ":Buffs"); } MUTATOR_HOOKFUNCTION(buffs, BuildMutatorsPrettyString) { - M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Buffs"); + if(autocvar_g_buffs > 0) + M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Buffs"); } void buffs_DelayedInit(entity this)