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)
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);
#include "powerups.qh"
int autocvar_g_powerups;
+bool autocvar_g_powerups_dropondeath;
bool autocvar_g_powerups_stack;
REGISTER_MUTATOR(powerups, true);
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);
/// 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.
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");
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"