From e64aad11146faae067bccb49ae8bcc712163cc83 Mon Sep 17 00:00:00 2001 From: z411 Date: Sat, 27 Nov 2021 17:11:52 -0300 Subject: [PATCH] Experimental powerup throwing --- .../mutators/mutator/powerups/sv_powerups.qc | 35 +++++++++++++++---- .../mutators/mutator/powerups/sv_powerups.qh | 1 + xonotic-server.cfg | 1 + 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/qcsrc/common/mutators/mutator/powerups/sv_powerups.qc b/qcsrc/common/mutators/mutator/powerups/sv_powerups.qc index 3356fe49e..68e2c8c72 100644 --- a/qcsrc/common/mutators/mutator/powerups/sv_powerups.qc +++ b/qcsrc/common/mutators/mutator/powerups/sv_powerups.qc @@ -88,13 +88,13 @@ void powerups_DropItem_Think(entity this) } // Only needed to update if the timer of the powerup is running - if(autocvar_g_powerups_dropondeath == 1) + if(!GetResource(this, RES_ARMOR)) WaypointSprite_UpdateHealth(this.waypointsprite_attached, GetResource(this, RES_HEALTH)); this.nextthink = time + 1; } -void powerups_DropItem(entity this, StatusEffects effect) +void powerups_DropItem(entity this, StatusEffects effect, bool freezeTimer) { entity item = Item_DefinitionFromInternalName(effect.netname); float t = StatusEffects_gettime(effect, this); @@ -108,11 +108,11 @@ void powerups_DropItem(entity this, StatusEffects effect) // 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 = (autocvar_g_powerups_dropondeath == 2 ? timeleft : t); + float finished = (freezeTimer ? timeleft : t); // If the timer is frozen, the item will stay on the floor for 20 secs (same as weapons), // otherwise it'll disappear after the timer runs out. - float time_to_live = (autocvar_g_powerups_dropondeath == 2 ? autocvar_g_powerups_dropondeath_ttl : timeleft); + float time_to_live = (freezeTimer ? autocvar_g_powerups_dropondeath_ttl : timeleft); // TODO: items cannot hold their "item field" yet, so we need to list all the powerups here! switch(item) @@ -122,14 +122,18 @@ void powerups_DropItem(entity this, StatusEffects effect) case ITEM_Invisibility: e.invisibility_finished = finished; maxtime = autocvar_g_balance_powerup_invincible_time; break; case ITEM_Speed: e.speed_finished = finished; maxtime = autocvar_g_balance_powerup_speed_time; break; } - Item_InitializeLoot(e, item.m_canonical_spawnfunc, this.origin + '0 0 32', randomvec() * 175 + '0 0 175', time_to_live); + Item_InitializeLoot(e, item.m_canonical_spawnfunc, this.origin + '0 100 132', randomvec() * 175 + '0 0 175', time_to_live); - if(autocvar_g_powerups_dropondeath != 2) + if(!freezeTimer) Item_SetExpiring(e, true); // Use health as time left to live SetResourceExplicit(e, RES_HEALTH, time_to_live); + // Use armor as timer freezer + if(freezeTimer) + SetResourceExplicit(e, RES_ARMOR, 1); + // Create waypoint displaying time left of the powerup entity wp = WaypointSprite_Spawn(WP_Item, 0, 0, e, '0 0 1' * e.maxs.z, NULL, 0, e, waypointsprite_attached, true, RADARICON_Item); wp.wp_extra = item.m_id; @@ -158,7 +162,24 @@ MUTATOR_HOOKFUNCTION(powerups, PlayerDies) FOREACH(StatusEffect, it.instanceOfPowerups, { if(StatusEffects_active(it, frag_target)) - powerups_DropItem(frag_target, it); + powerups_DropItem(frag_target, it, autocvar_g_powerups_dropondeath == 2); + }); +} + +MUTATOR_HOOKFUNCTION(powerups, PlayerUseKey, CBC_ORDER_FIRST) +{ + if(!autocvar_g_powerups_drop) + return; + + entity player = M_ARGV(0, entity); + + FOREACH(StatusEffect, it.instanceOfPowerups, + { + if(StatusEffects_active(it, player)) { + powerups_DropItem(player, it, autocvar_g_powerups_drop == 2); + StatusEffects_remove(it, player, STATUSEFFECT_REMOVE_NORMAL); + return true; + } }); } diff --git a/qcsrc/common/mutators/mutator/powerups/sv_powerups.qh b/qcsrc/common/mutators/mutator/powerups/sv_powerups.qh index eab884e57..6342037c2 100644 --- a/qcsrc/common/mutators/mutator/powerups/sv_powerups.qh +++ b/qcsrc/common/mutators/mutator/powerups/sv_powerups.qh @@ -5,6 +5,7 @@ #include "powerups.qh" int autocvar_g_powerups; +int autocvar_g_powerups_drop; int autocvar_g_powerups_dropondeath; int autocvar_g_powerups_dropondeath_ttl; bool autocvar_g_powerups_stack; diff --git a/xonotic-server.cfg b/xonotic-server.cfg index 250086222..00cda685a 100644 --- a/xonotic-server.cfg +++ b/xonotic-server.cfg @@ -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_drop 0 "allow dropping powerups (1 = timer continues, 2 = timer freezes untip icked up)" set g_powerups_dropondeath 0 "players will drop their powerups on death (1 = timer continues, 2 = timer freezes until picked up)" set g_powerups_dropondeath_ttl 20 "seconds before a dropped powerup disappears if dropondeath is set to 2" 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" -- 2.39.2