]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Add g_powerups_dropondeath setting (off by default, whitelisted) 928/head
authorMario <mario.mario@y7mail.com>
Fri, 27 Aug 2021 06:14:56 +0000 (16:14 +1000)
committerMario <mario.mario@y7mail.com>
Fri, 27 Aug 2021 06:14:56 +0000 (16:14 +1000)
qcsrc/common/mutators/mutator/powerups/powerup/shield.qh
qcsrc/common/mutators/mutator/powerups/sv_powerups.qc
qcsrc/common/mutators/mutator/powerups/sv_powerups.qh
qcsrc/server/items/spawning.qc
qcsrc/server/items/spawning.qh
qcsrc/server/world.qc
xonotic-server.cfg

index 10900e86a89c7ec5f95dfb55693c24543b5cf6a6..508a39487ae84309a8bf106f052a586a03f1967a 100644 (file)
@@ -53,7 +53,7 @@ SPAWNFUNC_ITEM(item_shield, ITEM_Shield)
 SPAWNFUNC_ITEM(item_invincible, ITEM_Shield)
 
 CLASS(Shield, Powerups)
-    ATTRIB(Shield, netname, string, "shield");
+    ATTRIB(Shield, netname, string, "invincible"); // NOTE: referring to as invincible so that it matches the powerup item
     ATTRIB(Shield, m_name, string, _("Shield"));
     ATTRIB(Shield, m_icon, string, "shield");
 ENDCLASS(Shield)
index 2ac0bbccc930f46bf52fe3ff9cc472879cb92dd5..47ad0c5098eff2bce12f0511a4bcb94c10d49a9e 100644 (file)
@@ -77,6 +77,39 @@ MUTATOR_HOOKFUNCTION(powerups, MonsterValidTarget)
        return StatusEffects_active(STATUSEFFECT_Invisibility, targ);
 }
 
+void powerups_DropItem(entity this, StatusEffects effect)
+{
+       entity item = Item_DefinitionFromInternalName(effect.netname);
+       float timeleft = StatusEffects_gettime(effect, this);
+       if((timeleft - time) <= 0 || !item)
+               return;
+       entity e = spawn();
+       // 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 = timeleft; break;
+               case ITEM_Shield: e.invincible_finished = timeleft; break;
+               case ITEM_Invisibility: e.invisibility_finished = timeleft; break;
+               case ITEM_Speed: e.speed_finished = timeleft; break;
+       }
+       Item_InitializeLoot(e, item.m_canonical_spawnfunc, this.origin + '0 0 32', randomvec() * 175 + '0 0 175', min(timeleft - time, 10));
+       Item_SetExpiring(e, true);
+}
+
+MUTATOR_HOOKFUNCTION(powerups, PlayerDies)
+{
+       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);
index b514385381c8a8bfb38d274dcf1c6f9dc36596be..1d79396c8cbacbe271a4a8e94169778677abdca1 100644 (file)
@@ -5,6 +5,7 @@
 #include "powerups.qh"
 
 int autocvar_g_powerups;
+bool autocvar_g_powerups_dropondeath;
 bool autocvar_g_powerups_stack;
 
 REGISTER_MUTATOR(powerups, true);
index fc8338f38d1f67db11a986ca1aa4571ed31d726c..50ad6a1cef1ebcaff807976a6a06fb0044ccd9ca 100644 (file)
@@ -29,6 +29,19 @@ entity Item_FindDefinition(string class_name)
        return NULL;
 }
 
+entity Item_DefinitionFromInternalName(string item_name)
+{
+       FOREACH(Items, it.netname == item_name,
+       {
+               return it;
+       });
+       FOREACH(Weapons, it.netname == item_name,
+       {
+               return it.m_pickup;
+       });
+       return NULL;
+}
+
 bool Item_IsAllowed(string class_name)
 {
        entity definition = Item_FindDefinition(class_name);
index b52449e7158dffab62269d6b17d32a6a7cdcc439..f4bd32e7b87adda20e0c679c29430b719c87fa20 100644 (file)
@@ -12,6 +12,12 @@ bool startitem_failed;
 /// found.
 entity Item_FindDefinition(string class_name);
 
+/// \brief Returns the item definition corresponding to the given internal name.
+/// \param[in] item_name Internal netname to search for.
+/// \return Item definition corresponding to the given internal name or NULL is not
+/// found.
+entity Item_DefinitionFromInternalName(string item_name);
+
 /// \brief Checks whether the items with the specified class name are allowed to
 /// spawn.
 /// \param[in] class_name Item class name to check.
index 6c397d05353850515f0b2af7ce2870ef1a1875fb..ee8bdbddeb48e08a10da415965f8633415f46014 100644 (file)
@@ -461,6 +461,7 @@ void cvar_changes_init()
                BADCVAR("g_physics_clientselect");
                BADCVAR("g_pinata");
                BADCVAR("g_powerups");
+               BADCVAR("g_powerups_dropondeath");
                BADCVAR("g_player_brightness");
                BADCVAR("g_rocket_flying");
                BADCVAR("g_rocket_flying_disabledelays");
index 39323f0dc6fba66ed95c10acde291b1e4c40db1c..b1718900a83b70852cc3411787e44b0dc7390568 100644 (file)
@@ -198,6 +198,7 @@ set g_shootfromfixedorigin "" "if set to a string like 0 y z, the gun is moved t
 set g_weapon_stay 0 "1: ghost weapons can be picked up but give no ammo, thrown guns have ammo 2: ghost weapons can be picked up and refill ammo to one pickup size, thrown guns have no ammo (to prevent infinite ammo abuse)"
 set g_weapon_throwable 1 "if set to 1, weapons can be dropped"
 set g_powerups -1 "if set to 0 no powerups will spawn, if 1 they will spawn in all game modes, -1 is game mode default"
+set g_powerups_dropondeath 0 "whether or not held powerups should be droppd when the player dies"
 set g_powerups_stack 0 "enables stacking of powerup timers when picking up a powerup you already have; otherwise timer is reset to the time granted by the item, if greater than the time you currently have"
 set g_powerups_strength 1 "allow strength powerups to spawn"
 set g_powerups_shield 1 "allow shield powerups to spawn"