]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/mutators/mutator/powerups/sv_powerups.qc
Improved powerups_dropondeath setting
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / powerups / sv_powerups.qc
index c4b79eb9c2a09ac5617367cb56efa03883965f78..7491d853efb5ba5c30be35d9e6de06272ced00f6 100644 (file)
@@ -77,21 +77,60 @@ MUTATOR_HOOKFUNCTION(powerups, MonsterValidTarget)
        return StatusEffects_active(STATUSEFFECT_Invisibility, targ);
 }
 
-MUTATOR_HOOKFUNCTION(powerups, PlayerPhysics_UpdateStats)
+void powerups_DropItem(entity this, StatusEffects effect)
 {
-       entity player = M_ARGV(0, entity);
-       // these automatically reset, no need to worry
+       entity item = Item_DefinitionFromInternalName(effect.netname);
+       float t = StatusEffects_gettime(effect, this);
+       float timeleft = t - time;
 
-       if(StatusEffects_active(STATUSEFFECT_Speed, player))
-               STAT(MOVEVARS_HIGHSPEED, player) *= autocvar_g_balance_powerup_speed_highspeed;
+       if(timeleft <= 1 || !item)
+               return;
+       entity e = spawn();
+
+       // If we want the timer to keep running, we enable expiring then use the exact time the powerup will finish at.
+       // If we want the timer to freeze, we disable expiring and we just use the time left of the powerup.
+       // See Item_SetExpiring() below.
+       float finished_time = (autocvar_g_powerups_dropondeath == 2 ? timeleft : t);
+
+       // If the timer is frozen, the item will stay on the floor for 60 secs (TODO hardcoded for now),
+       // otherwise it'll disappear after the timer runs out.
+       float time_to_live = (autocvar_g_powerups_dropondeath == 2 ? 60 : timeleft);
+
+       // TODO: items cannot hold their "item field" yet, so we need to list all the powerups here!
+       switch(item)
+       {
+               case ITEM_Strength: e.strength_finished = finished_time; break;
+               case ITEM_Shield: e.invincible_finished = finished_time; break;
+               case ITEM_Invisibility: e.invisibility_finished = finished_time; break;
+               case ITEM_Speed: e.speed_finished = finished_time; break;
+       }
+       Item_InitializeLoot(e, item.m_canonical_spawnfunc, this.origin + '0 0 32', randomvec() * 175 + '0 0 175', time_to_live);
+
+       if(autocvar_g_powerups_dropondeath != 2)
+               Item_SetExpiring(e, true);
 }
 
-MUTATOR_HOOKFUNCTION(powerups, WeaponSpeedFactor)
+MUTATOR_HOOKFUNCTION(powerups, PlayerDies)
 {
-       entity player = M_ARGV(1, entity);
+       if(!autocvar_g_powerups_dropondeath)
+               return;
+
+       entity frag_target = M_ARGV(2, entity);
+
+       FOREACH(StatusEffect, it.instanceOfPowerups,
+       {
+               if(StatusEffects_active(it, frag_target))
+                       powerups_DropItem(frag_target, it);
+       });
+}
+
+MUTATOR_HOOKFUNCTION(powerups, PlayerPhysics_UpdateStats)
+{
+       entity player = M_ARGV(0, entity);
+       // these automatically reset, no need to worry
 
        if(StatusEffects_active(STATUSEFFECT_Speed, player))
-               M_ARGV(0, float) *= autocvar_g_balance_powerup_speed_weaponspeed;
+               STAT(MOVEVARS_HIGHSPEED, player) *= autocvar_g_balance_powerup_speed_highspeed;
 }
 
 MUTATOR_HOOKFUNCTION(powerups, WeaponRateFactor)