- if(time < player.buff_disability_time)
- if(time >= player.buff_disability_effect_time)
- {
- Send_Effect(EFFECT_SMOKING, player.origin + ((player.mins + player.maxs) * 0.5), '0 0 0', 1);
- player.buff_disability_effect_time = time + 0.5;
- }
-
- // handle buff lost status
- // 1: notify everyone else
- // 2: notify carrier as well
- int buff_lost = 0;
-
- if(STAT(BUFF_TIME, player) && STAT(BUFFS, player))
- if(time >= STAT(BUFF_TIME, player))
- {
- STAT(BUFF_TIME, player) = 0;
- buff_lost = 2;
- }
-
- if(STAT(FROZEN, player)) { buff_lost = 1; }
-
- if(buff_lost)
- {
- if(STAT(BUFFS, player))
- {
- int buffid = buff_FirstFromFlags(STAT(BUFFS, player)).m_id;
- if(buff_lost == 2)
- {
- Send_Notification(NOTIF_ONE, player, MSG_MULTI, ITEM_BUFF_DROP, buffid); // TODO: special timeout message?
- sound(player, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
- }
- else if(!IS_INDEPENDENT_PLAYER(player))
- Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid);
- STAT(BUFFS, player) = 0;
- PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); // always put in a delay, even if small
- }
- }
-
- if(STAT(BUFFS, player) & BUFF_MAGNET.m_itemid)
- {
- vector pickup_size;
- IL_EACH(g_items, it.itemdef,
- {
- if(STAT(BUFFS, it))
- pickup_size = '1 1 1' * autocvar_g_buffs_magnet_range_buff;
- else
- pickup_size = '1 1 1' * autocvar_g_buffs_magnet_range_item;
-
- if(boxesoverlap(player.absmin - pickup_size, player.absmax + pickup_size, it.absmin, it.absmax))
- {
- if(gettouch(it))
- gettouch(it)(it, player);
- }
- });
- }
-
- if(STAT(BUFFS, player) & BUFF_AMMO.m_itemid)
- {
- 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((STAT(BUFFS, player) & BUFF_INVISIBLE.m_itemid) && (player.oldbuffs & BUFF_INVISIBLE.m_itemid))
- player.alpha = ((autocvar_g_buffs_invisible_alpha) ? autocvar_g_buffs_invisible_alpha : -1); // powerups reset alpha, so we must enforce this (TODO)
-
-#define BUFF_ONADD(b) if ( (STAT(BUFFS, player) & (b).m_itemid) && !(player.oldbuffs & (b).m_itemid))
-#define BUFF_ONREM(b) if (!(STAT(BUFFS, player) & (b).m_itemid) && (player.oldbuffs & (b).m_itemid))
-
- if(STAT(BUFFS, player) != player.oldbuffs)
- {
- entity buff = buff_FirstFromFlags(STAT(BUFFS, player));
- float bufftime = buff != BUFF_Null ? buff.m_time(buff) : 0;
- if(STAT(BUFF_TIME, player) <= time) // if the player still has a buff countdown, don't reset it!
- STAT(BUFF_TIME, player) = (bufftime) ? time + bufftime : 0;
-
- BUFF_ONADD(BUFF_AMMO)
- {
- player.buff_ammo_prev_infitems = (player.items & IT_UNLIMITED_AMMO);
- player.items |= IT_UNLIMITED_AMMO;
-
- if(STAT(BUFFS, player) & 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)
- {
- if(player.buff_ammo_prev_infitems)
- player.items |= IT_UNLIMITED_AMMO;
- else
- player.items &= ~IT_UNLIMITED_AMMO;
-
- if(STAT(BUFFS, player) & 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 < STAT(STRENGTH_FINISHED, player) && MUTATOR_IS_ENABLED(mutator_instagib))
- 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.buff_invisible_prev_alpha = player.alpha;
- player.alpha = autocvar_g_buffs_invisible_alpha;
- }
-
- BUFF_ONREM(BUFF_INVISIBLE)
- {
- if(time < STAT(STRENGTH_FINISHED, player) && MUTATOR_IS_ENABLED(mutator_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 = STAT(BUFFS, player);
- if(STAT(BUFFS, player))
- {
- if(!player.buff_model)
- buffs_BuffModel_Spawn(player);
-
- player.buff_model.color = buff.m_color;
- player.buff_model.glowmod = buff_GlowColor(player.buff_model);
- player.buff_model.skin = buff.m_skin;
-
- player.effects |= EF_NOSHADOW;
- }
- else
- {
- buffs_BuffModel_Remove(player);
-
- player.effects &= ~(EF_NOSHADOW);
- }
- }
-
- if(player.buff_model)
- {
- player.buff_model.effects = player.effects;
- player.buff_model.effects |= EF_LOWPRECISION;
- player.buff_model.effects = player.buff_model.effects & EFMASK_CHEAP; // eat performance
-
- player.buff_model.alpha = player.alpha;
- }
-
-#undef BUFF_ONADD
-#undef BUFF_ONREM
-}
-
-MUTATOR_HOOKFUNCTION(buffs, SpectateCopy)
-{
- entity spectatee = M_ARGV(0, entity);
- entity client = M_ARGV(1, entity);
-
- STAT(BUFFS, client) = STAT(BUFFS, spectatee);
- STAT(BUFF_TIME, client) = STAT(BUFF_TIME, spectatee);