]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/mutators/mutator/buffs/buffs.qc
Merge branch 'master' into Mario/killother
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / buffs / buffs.qc
index dbddbfc840bf918e20d8ff294c492adf5cbee0bb..921cd03cd39dadbcf043cdfbcb8a203644f1ea02 100644 (file)
@@ -88,35 +88,35 @@ REGISTER_MUTATOR(buffs, cvar("g_buffs"))
 {
        MUTATOR_ONADD
        {
-               InitializeEntity(world, buffs_DelayedInit, INITPRIO_FINDTARGET);
+               InitializeEntity(NULL, buffs_DelayedInit, INITPRIO_FINDTARGET);
        }
 }
 
-bool buffs_BuffModel_Customize(entity this)
+bool buffs_BuffModel_Customize(entity this, entity client)
 {
        entity player, myowner;
        bool same_team;
 
-       player = WaypointSprite_getviewentity(other);
-       myowner = self.owner;
+       player = WaypointSprite_getviewentity(client);
+       myowner = this.owner;
        same_team = (SAME_TEAM(player, myowner) || SAME_TEAM(player, myowner));
 
        if(myowner.alpha <= 0.5 && !same_team && myowner.alpha != 0)
                return false;
 
-       if(MUTATOR_CALLHOOK(BuffModel_Customize, self, player))
+       if(MUTATOR_CALLHOOK(BuffModel_Customize, this, player))
                return false;
 
-       if(player == myowner || (IS_SPEC(other) && other.enemy == myowner))
+       if(player == myowner || (IS_SPEC(client) && client.enemy == myowner))
        {
                // somewhat hide the model, but keep the glow
-               self.effects = 0;
-               self.alpha = -1;
+               this.effects = 0;
+               this.alpha = -1;
        }
        else
        {
-               self.effects = EF_FULLBRIGHT | EF_LOWPRECISION;
-               self.alpha = 1;
+               this.effects = EF_FULLBRIGHT | EF_LOWPRECISION;
+               this.alpha = 1;
        }
        return true;
 }
@@ -169,7 +169,7 @@ bool buff_Waypoint_visible_for_player(entity this, entity player, entity view)
 void buff_Waypoint_Spawn(entity e)
 {
        entity buff = buff_FirstFromFlags(e.buffs);
-       entity wp = WaypointSprite_Spawn(WP_Buff, 0, autocvar_g_buffs_waypoint_distance, e, '0 0 1' * e.maxs.z, world, e.team, e, buff_waypoint, true, RADARICON_Buff);
+       entity wp = WaypointSprite_Spawn(WP_Buff, 0, autocvar_g_buffs_waypoint_distance, e, '0 0 1' * e.maxs.z, NULL, e.team, e, buff_waypoint, true, RADARICON_Buff);
        wp.wp_extra = buff.m_id;
        WaypointSprite_UpdateTeamRadar(e.buff_waypoint, RADARICON_Buff, e.glowmod);
        e.buff_waypoint.waypointsprite_visible_for_player = buff_Waypoint_visible_for_player;
@@ -222,56 +222,57 @@ void buff_Respawn(entity this)
        sound(this, CH_TRIGGER, SND_KA_RESPAWN, VOL_BASE, ATTEN_NONE); // ATTEN_NONE (it's a sound intended to be heard anywhere)
 }
 
-void buff_Touch(entity this)
+void buff_Touch(entity this, entity toucher)
 {
        if(gameover) { return; }
 
        if(ITEM_TOUCH_NEEDKILL())
        {
-               buff_Respawn(self);
+               buff_Respawn(this);
                return;
        }
 
-       if((self.team && DIFF_TEAM(other, self))
-       || (STAT(FROZEN, other))
-       || (other.vehicle)
-       || (!self.buff_active)
+       if((this.team && DIFF_TEAM(toucher, this))
+       || (STAT(FROZEN, toucher))
+       || (toucher.vehicle)
+       || (!this.buff_active)
        )
        {
                // can't touch this
                return;
        }
 
-       if(MUTATOR_CALLHOOK(BuffTouch, self, other))
+       if(MUTATOR_CALLHOOK(BuffTouch, this, toucher))
                return;
+       toucher = M_ARGV(1, entity);
 
-       if(!IS_PLAYER(other))
-               return; // incase mutator changed other
+       if(!IS_PLAYER(toucher))
+               return; // incase mutator changed toucher
 
-       if (other.buffs)
+       if (toucher.buffs)
        {
-               if (other.cvar_cl_buffs_autoreplace && other.buffs != self.buffs)
+               if (toucher.cvar_cl_buffs_autoreplace && toucher.buffs != this.buffs)
                {
-                       int buffid = buff_FirstFromFlags(other.buffs).m_id;
-                       //Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_DROP, other.buffs);
-                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_ITEM_BUFF_LOST, other.netname, buffid);
+                       int buffid = buff_FirstFromFlags(toucher.buffs).m_id;
+                       //Send_Notification(NOTIF_ONE, toucher, MSG_MULTI, ITEM_BUFF_DROP, toucher.buffs);
+                       Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_ITEM_BUFF_LOST, toucher.netname, buffid);
 
-                       other.buffs = 0;
-                       //sound(other, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
+                       toucher.buffs = 0;
+                       //sound(toucher, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
                }
                else { return; } // do nothing
        }
 
-       self.owner = other;
-       self.buff_active = false;
-       self.lifetime = 0;
-       int buffid = buff_FirstFromFlags(self.buffs).m_id;
-       Send_Notification(NOTIF_ONE, other, MSG_MULTI, ITEM_BUFF_GOT, buffid);
-       Send_Notification(NOTIF_ALL_EXCEPT, other, MSG_INFO, INFO_ITEM_BUFF, other.netname, buffid);
+       this.owner = toucher;
+       this.buff_active = false;
+       this.lifetime = 0;
+       int buffid = buff_FirstFromFlags(this.buffs).m_id;
+       Send_Notification(NOTIF_ONE, toucher, MSG_MULTI, ITEM_BUFF_GOT, buffid);
+       Send_Notification(NOTIF_ALL_EXCEPT, toucher, MSG_INFO, INFO_ITEM_BUFF, toucher.netname, buffid);
 
-       Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(self), '0 0 0', 1);
-       sound(other, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTN_NORM);
-       other.buffs |= (self.buffs);
+       Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
+       sound(toucher, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTN_NORM);
+       toucher.buffs |= (this.buffs);
 }
 
 float buff_Available(entity buff)
@@ -293,7 +294,7 @@ void buff_NewType(entity ent, float cb)
        FOREACH(Buffs, buff_Available(it), LAMBDA(
                it.buff_seencount += 1;
                // if it's already been chosen, give it a lower priority
-               RandomSelection_Add(world, it.m_itemid, string_null, 1, max(0.2, 1 / it.buff_seencount));
+               RandomSelection_Add(NULL, it.m_itemid, string_null, 1, max(0.2, 1 / it.buff_seencount));
        ));
        ent.buffs = RandomSelection_chosen_float;
 }
@@ -333,7 +334,7 @@ void buff_Think(entity this)
        if(!this.owner || STAT(FROZEN, this.owner) || IS_DEAD(this.owner) || !this.owner.iscreature || !(this.owner.buffs & this.buffs))
        {
                buff_SetCooldown(this, autocvar_g_buffs_cooldown_respawn + frametime);
-               this.owner = world;
+               this.owner = NULL;
                if(autocvar_g_buffs_randomize)
                        buff_NewType(this, this.buffs);
 
@@ -380,7 +381,7 @@ void buff_Reset(entity this)
 {
        if(autocvar_g_buffs_randomize)
                buff_NewType(this, this.buffs);
-       this.owner = world;
+       this.owner = NULL;
        buff_SetCooldown(this, autocvar_g_buffs_cooldown_activate);
        buff_Waypoint_Reset(this);
        this.buff_activetime_updated = false;
@@ -389,9 +390,9 @@ void buff_Reset(entity this)
                buff_Respawn(this);
 }
 
-float buff_Customize(entity this)
+bool buff_Customize(entity this, entity client)
 {
-       entity player = WaypointSprite_getviewentity(other);
+       entity player = WaypointSprite_getviewentity(client);
        if(!this.buff_active || (this.team && DIFF_TEAM(player, this)))
        {
                this.alpha = 0.3;
@@ -509,7 +510,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_SplitHealthArmor)
        float frag_deathtype = M_ARGV(6, float);
        float frag_damage = M_ARGV(7, float);
 
-       if(frag_deathtype == DEATH_BUFF.m_id) { return false; }
+       if(frag_deathtype == DEATH_BUFF.m_id) { return; }
 
        if(frag_target.buffs & BUFF_RESISTANCE.m_itemid)
        {
@@ -517,8 +518,6 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_SplitHealthArmor)
                M_ARGV(4, float) = v.x; // take
                M_ARGV(5, float) = v.y; // save
        }
-
-       return false;
 }
 
 MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_Calculate)
@@ -529,7 +528,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_Calculate)
        float frag_damage = M_ARGV(4, float);
        vector frag_force = M_ARGV(6, vector);
 
-       if(frag_deathtype == DEATH_BUFF.m_id) { return false; }
+       if(frag_deathtype == DEATH_BUFF.m_id) { return; }
 
        if(frag_target.buffs & BUFF_SPEED.m_itemid)
        if(frag_target != frag_attacker)
@@ -620,8 +619,6 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerDamage_Calculate)
 
        M_ARGV(4, float) = frag_damage;
        M_ARGV(6, vector) = frag_force;
-
-       return false;
 }
 
 MUTATOR_HOOKFUNCTION(buffs, PlayerSpawn)
@@ -629,10 +626,10 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerSpawn)
        entity player = M_ARGV(0, entity);
 
        player.buffs = 0;
+       player.buff_time = 0;
        // reset timers here to prevent them continuing after re-spawn
        player.buff_disability_time = 0;
        player.buff_disability_effect_time = 0;
-       return false;
 }
 
 .float stat_sv_maxspeed;
@@ -694,10 +691,9 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerDies)
                if(frag_target.buff_model)
                {
                        remove(frag_target.buff_model);
-                       frag_target.buff_model = world;
+                       frag_target.buff_model = NULL;
                }
        }
-       return false;
 }
 
 MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST)
@@ -713,6 +709,7 @@ 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
                sound(player, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
                return true;
        }
@@ -720,13 +717,13 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST)
 
 MUTATOR_HOOKFUNCTION(buffs, ForbidThrowCurrentWeapon)
 {
-       if(MUTATOR_RETURNVALUE || gameover) { return false; }
+       if(MUTATOR_RETURNVALUE || gameover) { return; }
        entity player = M_ARGV(0, entity);
 
        if(player.buffs & BUFF_SWAPPER.m_itemid)
        {
                float best_distance = autocvar_g_buffs_swapper_range;
-               entity closest = world;
+               entity closest = NULL;
                FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
                        if(!IS_DEAD(it) && !STAT(FROZEN, it) && !it.vehicle)
                        if(DIFF_TEAM(it, player))
@@ -785,7 +782,6 @@ MUTATOR_HOOKFUNCTION(buffs, ForbidThrowCurrentWeapon)
                        return true;
                }
        }
-       return false;
 }
 
 bool buffs_RemovePlayer(entity player)
@@ -793,7 +789,7 @@ bool buffs_RemovePlayer(entity player)
        if(player.buff_model)
        {
                remove(player.buff_model);
-               player.buff_model = world;
+               player.buff_model = NULL;
        }
 
        // also reset timers here to prevent them continuing after spectating
@@ -817,8 +813,6 @@ MUTATOR_HOOKFUNCTION(buffs, CustomizeWaypoint)
        if((wp.owner.flags & FL_CLIENT) && (wp.owner.buffs & BUFF_INVISIBLE.m_itemid) && (e == player))
        if(DIFF_TEAM(wp.owner, e))
                return true;
-
-       return false;
 }
 
 MUTATOR_HOOKFUNCTION(buffs, OnEntityPreSpawn, CBC_ORDER_LAST)
@@ -836,7 +830,6 @@ MUTATOR_HOOKFUNCTION(buffs, OnEntityPreSpawn, CBC_ORDER_LAST)
                        return true;
                }
        }
-       return false;
 }
 
 MUTATOR_HOOKFUNCTION(buffs, WeaponRateFactor)
@@ -865,7 +858,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
 {
        entity player = M_ARGV(0, entity);
 
-       if(gameover || IS_DEAD(player)) { return false; }
+       if(gameover || IS_DEAD(player)) { return; }
 
        if(time < player.buff_disability_time)
        if(time >= player.buff_disability_effect_time)
@@ -879,9 +872,12 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
        // 2: notify carrier as well
        int buff_lost = 0;
 
-       if(player.buff_time)
+       if(player.buff_time && player.buffs)
        if(time >= player.buff_time)
+       {
+               player.buff_time = 0;
                buff_lost = 2;
+       }
 
        if(STAT(FROZEN, player)) { buff_lost = 1; }
 
@@ -890,12 +886,13 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
                if(player.buffs)
                {
                        int buffid = buff_FirstFromFlags(player.buffs).m_id;
-                       Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid);
-                       if(buff_lost >= 2)
+                       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
+                               Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid);
                        player.buffs = 0;
                }
        }
@@ -913,12 +910,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
                        if(boxesoverlap(player.absmin - pickup_size, player.absmax + pickup_size, it.absmin, it.absmax))
                        {
                                if(gettouch(it))
-                               {
-                                       entity oldother = other;
-                                       other = player;
-                                       WITHSELF(it, gettouch(it)(it));
-                                       other = oldother;
-                               }
+                                       gettouch(it)(it, player);
                        }
                });
        }
@@ -995,7 +987,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
                else
                {
                        remove(player.buff_model);
-                       player.buff_model = world;
+                       player.buff_model = NULL;
 
                        player.effects &= ~(EF_NOSHADOW);
                }
@@ -1045,18 +1037,18 @@ MUTATOR_HOOKFUNCTION(buffs, VehicleExit)
 }
 
 MUTATOR_HOOKFUNCTION(buffs, PlayerRegen)
-{SELFPARAM();
-       if(self.buffs & BUFF_MEDIC.m_itemid)
+{
+       entity player = M_ARGV(0, entity);
+
+       if(player.buffs & BUFF_MEDIC.m_itemid)
        {
-               regen_mod_rot = autocvar_g_buffs_medic_rot;
-               regen_mod_limit = regen_mod_max = autocvar_g_buffs_medic_max;
-               regen_mod_regen = autocvar_g_buffs_medic_regen;
+               M_ARGV(2, float) = autocvar_g_buffs_medic_rot; // rot_mod
+               M_ARGV(4, float) = M_ARGV(1, float) = autocvar_g_buffs_medic_max; // limit_mod = max_mod
+               M_ARGV(2, float) = autocvar_g_buffs_medic_regen; // regen_mod
        }
 
-       if(self.buffs & BUFF_SPEED.m_itemid)
-               regen_mod_regen = autocvar_g_buffs_speed_regen;
-
-       return false;
+       if(player.buffs & BUFF_SPEED.m_itemid)
+               M_ARGV(2, float) = autocvar_g_buffs_speed_regen; // regen_mod
 }
 
 REPLICATE(cvar_cl_buffs_autoreplace, bool, "cl_buffs_autoreplace");
@@ -1074,7 +1066,7 @@ MUTATOR_HOOKFUNCTION(buffs, BuildMutatorsPrettyString)
 void buffs_DelayedInit(entity this)
 {
        if(autocvar_g_buffs_spawn_count > 0)
-       if(find(world, classname, "item_buff") == world)
+       if(find(NULL, classname, "item_buff") == NULL)
        {
                float i;
                for(i = 0; i < autocvar_g_buffs_spawn_count; ++i)