void buff_Respawn(entity this)
{
- if(gameover) { return; }
+ if(game_stopped) return;
vector oldbufforigin = this.origin;
this.velocity = '0 0 200';
void buff_Touch(entity this, entity toucher)
{
- if(gameover) { return; }
+ if(game_stopped) return;
if(ITEM_TOUCH_NEEDKILL())
{
if((this.team && DIFF_TEAM(toucher, this))
|| (STAT(FROZEN, toucher))
|| (toucher.vehicle)
+ || (time < toucher.buff_shield)
|| (!this.buff_active)
)
{
.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)
this.oldbuffs = this.buffs;
}
- if(!gameover)
+ if(!game_stopped)
if((round_handler_IsActive() && !round_handler_IsRoundStarted()) || time >= game_starttime)
if(!this.buff_activetime_updated)
{
}
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.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);
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);
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);
//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;
player.buffs = 0;
player.buff_time = 0;
+ 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;
-
- if(player.buffs & BUFF_FLIGHT.m_itemid)
- if(!IS_JUMP_HELD(player) && PHYS_INPUT_BUTTON_CROUCH(player))
- player.gravity *= -1;
+ STAT(MOVEVARS_JUMPVELOCITY, player) = autocvar_g_buffs_jump_height;
}
MUTATOR_HOOKFUNCTION(buffs, MonsterMove)
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);
Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid);
player.buffs = 0;
- player.buff_time = 0; // already notified
+ 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;
}
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)
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)
else
Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid);
player.buffs = 0;
+ player.buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); // always put in a delay, even if small
}
}
}
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)
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)
{
}
else
{
- delete(player.buff_model);
+ if(player.buff_model)
+ delete(player.buff_model);
player.buff_model = NULL;
player.effects &= ~(EF_NOSHADOW);
entity client = M_ARGV(1, entity);
client.buffs = spectatee.buffs;
+ client.buff_time = spectatee.buff_time;
}
MUTATOR_HOOKFUNCTION(buffs, VehicleEnter)