]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Bring back old powerups temporarily for tourney
authorMario <zacjardine@y7mail.com>
Mon, 23 Mar 2015 00:31:38 +0000 (11:31 +1100)
committerMario <zacjardine@y7mail.com>
Mon, 23 Mar 2015 00:31:38 +0000 (11:31 +1100)
23 files changed:
qcsrc/client/autocvars.qh
qcsrc/client/hud.qc
qcsrc/client/hud_config.qc
qcsrc/client/view.qc
qcsrc/client/waypointsprites.qc
qcsrc/common/notifications.qh
qcsrc/common/weapons/w_porto.qc
qcsrc/common/weapons/w_shockwave.qc
qcsrc/common/weapons/w_shotgun.qc
qcsrc/server/autocvars.qh
qcsrc/server/cheats.qc
qcsrc/server/cl_client.qc
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/mutators/mutator_buffs.qc
qcsrc/server/mutators/mutator_instagib.qc
qcsrc/server/mutators/mutator_nix.qc
qcsrc/server/mutators/mutator_superspec.qc
qcsrc/server/t_items.qc
qcsrc/server/weapons/common.qc
qcsrc/server/weapons/common.qh
qcsrc/server/weapons/tracing.qc

index a721dc87a51476d7ab7a8f56cd99cdded4e138e6..9f6cac59187d9ccb1fda70745a3dc21e46c1f809 100644 (file)
@@ -307,6 +307,8 @@ int autocvar_hud_panel_powerups_iconalign;
 bool autocvar_hud_panel_powerups_progressbar;
 bool autocvar_hud_panel_buffs = 1;
 //float autocvar_hud_panel_buffs_iconalign;
+string autocvar_hud_panel_powerups_progressbar_shield;
+string autocvar_hud_panel_powerups_progressbar_strength;
 string autocvar_hud_panel_powerups_progressbar_superweapons;
 bool autocvar_hud_panel_powerups_text;
 int autocvar_hud_panel_pressedkeys;
@@ -369,7 +371,9 @@ vector autocvar_hud_progressbar_armor_color;
 vector autocvar_hud_progressbar_fuel_color;
 vector autocvar_hud_progressbar_health_color;
 vector autocvar_hud_progressbar_nexball_color;
+vector autocvar_hud_progressbar_shield_color;
 vector autocvar_hud_progressbar_speed_color;
+vector autocvar_hud_progressbar_strength_color;
 vector autocvar_hud_progressbar_superweapons_color;
 bool autocvar_hud_showbinds;
 bool autocvar_hud_showbinds_limit;
index 54971ff36cf0ebf73dac5d087d3269b302c733a4..1e45bfc469c7073ea790a6b0d0ea98d2725835f4 100644 (file)
@@ -1292,14 +1292,16 @@ void DrawNumIcon(vector myPos, vector mySize, float x, string icon, float vertic
 //
 void HUD_Powerups(void)
 {
-       float superweapons_time;
+       float strength_time, shield_time, superweapons_time;
        if(!autocvar__hud_configure)
        {
                if(!autocvar_hud_panel_powerups) return;
                if(spectatee_status == -1) return;
-               if(!(getstati(STAT_ITEMS, 0, 24) & IT_SUPERWEAPON)) return;
+               if(!(getstati(STAT_ITEMS, 0, 24) & (IT_STRENGTH | IT_INVINCIBLE | IT_SUPERWEAPON))) return;
                if (getstati(STAT_HEALTH) <= 0) return;
 
+               strength_time = bound(0, getstatf(STAT_STRENGTH_FINISHED) - time, 99);
+               shield_time = bound(0, getstatf(STAT_INVINCIBLE_FINISHED) - time, 99);
                superweapons_time = bound(0, getstatf(STAT_SUPERWEAPONS_FINISHED) - time, 99);
 
                if (getstati(STAT_ITEMS, 0, 24) & IT_UNLIMITED_SUPERWEAPONS)
@@ -1311,6 +1313,8 @@ void HUD_Powerups(void)
        }
        else
        {
+               strength_time = 15;
+               shield_time = 27;
                superweapons_time = 13;
        }
 
@@ -1322,7 +1326,7 @@ void HUD_Powerups(void)
        pos = panel_pos;
        mySize = panel_size;
 
-       HUD_Panel_DrawBg(bound(0, superweapons_time, 1));
+       HUD_Panel_DrawBg(bound(0, max(strength_time, shield_time, superweapons_time), 1));
        if(panel_bg_padding)
        {
                pos += '1 1 0' * panel_bg_padding;
@@ -1331,29 +1335,139 @@ void HUD_Powerups(void)
 
        float panel_ar = mySize.x/mySize.y;
        float is_vertical = (panel_ar < 1);
-       vector superweapons_offset = '0 0 0';
+       vector shield_offset = '0 0 0', strength_offset = '0 0 0', superweapons_offset = '0 0 0';
 
        float superweapons_is = -1;
 
-       if(superweapons_time) { superweapons_is = 2; }
+       if(superweapons_time)
+       {
+               if(strength_time)
+               {
+                       if(shield_time)
+                               superweapons_is = 0;
+                       else
+                               superweapons_is = 2;
+               }
+               else
+               {
+                       if(shield_time)
+                               superweapons_is = 1;
+                       else
+                               superweapons_is = 2;
+               }
+       }
 
-       float superweapons_baralign;
-       float superweapons_iconalign;
+       // FIXME handle superweapons here
+       if(superweapons_is == 0)
+       {
+               if (panel_ar >= 4 || (panel_ar >= 1/4 && panel_ar < 1))
+               {
+                       mySize.x *= (1.0 / 3.0);
+                       superweapons_offset.x = mySize.x;
+                       if (autocvar_hud_panel_powerups_flip)
+                               shield_offset.x = 2*mySize.x;
+                       else
+                               strength_offset.x = 2*mySize.x;
+               }
+               else
+               {
+                       mySize.y *= (1.0 / 3.0);
+                       superweapons_offset.y = mySize.y;
+                       if (autocvar_hud_panel_powerups_flip)
+                               shield_offset.y = 2*mySize.y;
+                       else
+                               strength_offset.y = 2*mySize.y;
+               }
+       }
+       else
+       {
+               if (panel_ar >= 4 || (panel_ar >= 1/4 && panel_ar < 1))
+               {
+                       mySize.x *= 0.5;
+                       if (autocvar_hud_panel_powerups_flip)
+                               shield_offset.x = mySize.x;
+                       else
+                               strength_offset.x = mySize.x;
+               }
+               else
+               {
+                       mySize.y *= 0.5;
+                       if (autocvar_hud_panel_powerups_flip)
+                               shield_offset.y = mySize.y;
+                       else
+                               strength_offset.y = mySize.y;
+               }
+       }
+
+       float shield_baralign, strength_baralign, superweapons_baralign;
+       float shield_iconalign, strength_iconalign, superweapons_iconalign;
 
        if (autocvar_hud_panel_powerups_flip)
        {
-               superweapons_baralign = (autocvar_hud_panel_powerups_baralign == 3 || autocvar_hud_panel_powerups_baralign == 1);
-               superweapons_iconalign = (autocvar_hud_panel_powerups_iconalign == 3 || autocvar_hud_panel_powerups_iconalign == 1);
+               strength_baralign = (autocvar_hud_panel_powerups_baralign == 2 || autocvar_hud_panel_powerups_baralign == 1);
+               shield_baralign = (autocvar_hud_panel_powerups_baralign == 3 || autocvar_hud_panel_powerups_baralign == 1);
+               strength_iconalign = (autocvar_hud_panel_powerups_iconalign == 2 || autocvar_hud_panel_powerups_iconalign == 1);
+               shield_iconalign = (autocvar_hud_panel_powerups_iconalign == 3 || autocvar_hud_panel_powerups_iconalign == 1);
        }
        else
        {
-               superweapons_baralign = (autocvar_hud_panel_powerups_baralign == 2 || autocvar_hud_panel_powerups_baralign == 1);
-               superweapons_iconalign = (autocvar_hud_panel_powerups_iconalign == 2 || autocvar_hud_panel_powerups_iconalign == 1);
+               shield_baralign = (autocvar_hud_panel_powerups_baralign == 2 || autocvar_hud_panel_powerups_baralign == 1);
+               strength_baralign = (autocvar_hud_panel_powerups_baralign == 3 || autocvar_hud_panel_powerups_baralign == 1);
+               shield_iconalign = (autocvar_hud_panel_powerups_iconalign == 2 || autocvar_hud_panel_powerups_iconalign == 1);
+               strength_iconalign = (autocvar_hud_panel_powerups_iconalign == 3 || autocvar_hud_panel_powerups_iconalign == 1);
+       }
+
+       if(superweapons_is == 0)
+       {
+               superweapons_iconalign = strength_iconalign;
+               superweapons_baralign = 2;
+       }
+       else if(superweapons_is == 1)
+       {
+               superweapons_offset = strength_offset;
+               superweapons_iconalign = strength_iconalign;
+               superweapons_baralign = strength_baralign;
+       }
+       else // if(superweapons_is == 2)
+       {
+               superweapons_offset = shield_offset;
+               superweapons_iconalign = shield_iconalign;
+               superweapons_baralign = shield_baralign;
+       }
+
+       if(shield_time)
+       {
+               const float maxshield = 30;
+               float shield = ceil(shield_time);
+               if(autocvar_hud_panel_powerups_progressbar)
+                       HUD_Panel_DrawProgressBar(pos + shield_offset, mySize, autocvar_hud_panel_powerups_progressbar_shield, shield/maxshield, is_vertical, shield_baralign, autocvar_hud_progressbar_shield_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
+               if(autocvar_hud_panel_powerups_text)
+               {
+                       if(shield > 1)
+                               DrawNumIcon(pos + shield_offset, mySize, shield, "shield", is_vertical, shield_iconalign, '1 1 1', 1);
+                       if(shield <= 5)
+                               DrawNumIcon_expanding(pos + shield_offset, mySize, shield, "shield", is_vertical, shield_iconalign, '1 1 1', 1, bound(0, (shield - shield_time) / 0.5, 1));
+               }
+       }
+
+       if(strength_time)
+       {
+               const float maxstrength = 30;
+               float strength = ceil(strength_time);
+               if(autocvar_hud_panel_powerups_progressbar)
+                       HUD_Panel_DrawProgressBar(pos + strength_offset, mySize, autocvar_hud_panel_powerups_progressbar_strength, strength/maxstrength, is_vertical, strength_baralign, autocvar_hud_progressbar_strength_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
+               if(autocvar_hud_panel_powerups_text)
+               {
+                       if(strength > 1)
+                               DrawNumIcon(pos + strength_offset, mySize, strength, "strength", is_vertical, strength_iconalign, '1 1 1', 1);
+                       if(strength <= 5)
+                               DrawNumIcon_expanding(pos + strength_offset, mySize, strength, "strength", is_vertical, strength_iconalign, '1 1 1', 1, bound(0, (strength - strength_time) / 0.5, 1));
+               }
        }
 
        if(superweapons_time)
        {
-               float maxsuperweapons = 30;
+               const float maxsuperweapons = 30;
                float superweapons = ceil(superweapons_time);
                if(autocvar_hud_panel_powerups_progressbar)
                        HUD_Panel_DrawProgressBar(pos + superweapons_offset, mySize, autocvar_hud_panel_powerups_progressbar_superweapons, superweapons/maxsuperweapons, is_vertical, superweapons_baralign, autocvar_hud_progressbar_superweapons_color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
index d5b3f0546ed49158971dd03c0a85a94051363c92..1b453e6284be37e440985391fcf0800d62bd2b07 100644 (file)
@@ -41,6 +41,8 @@ void HUD_Panel_ExportCfg(string cfgname)
                HUD_Write("\n");
 
                HUD_Write_Cvar_q("hud_progressbar_alpha");
+               HUD_Write_Cvar_q("hud_progressbar_strength_color");
+               HUD_Write_Cvar_q("hud_progressbar_shield_color");
                HUD_Write_Cvar_q("hud_progressbar_health_color");
                HUD_Write_Cvar_q("hud_progressbar_armor_color");
                HUD_Write_Cvar_q("hud_progressbar_fuel_color");
@@ -112,6 +114,8 @@ void HUD_Panel_ExportCfg(string cfgname)
                                        HUD_Write_PanelCvar_q("_iconalign");
                                        HUD_Write_PanelCvar_q("_baralign");
                                        HUD_Write_PanelCvar_q("_progressbar");
+                                       HUD_Write_PanelCvar_q("_progressbar_strength");
+                                       HUD_Write_PanelCvar_q("_progressbar_shield");
                                        HUD_Write_PanelCvar_q("_text");
                                        break;
                                case HUD_PANEL_HEALTHARMOR:
index d1a8839fbd567e4e9ecc675170a927198460a89f..63a5809d9ec8c94f3fffdbc8846375443e1564c9 100644 (file)
@@ -1852,11 +1852,9 @@ void CSQC_UpdateView(float w, float h)
                }
 
                // edge detection postprocess handling done second (used by hud_powerup)
-               float sharpen_intensity = 0, buffs = getstati(STAT_BUFFS, 0, 24);
-               entity e;
-               for(e = Buff_Type_first; e; e = e.enemy)
-               if(buffs & e.items)
-                       ++sharpen_intensity;
+               float sharpen_intensity = 0, strength_finished = getstatf(STAT_STRENGTH_FINISHED), invincible_finished = getstatf(STAT_INVINCIBLE_FINISHED);
+               if (strength_finished - time > 0) { sharpen_intensity += (strength_finished - time); }
+               if (invincible_finished - time > 0) { sharpen_intensity += (invincible_finished - time); }
 
                sharpen_intensity = bound(0, ((getstati(STAT_HEALTH) > 0) ? sharpen_intensity : 0), 5); // Check to see if player is alive (if not, set 0) - also bound to fade out starting at 5 seconds.
 
index 973a9b5ef1ae96dab19b9cf2dc276af8a9be09dd..aca18c17c9e5fa57917b392b6f5fd56f8497088b 100644 (file)
@@ -157,6 +157,8 @@ float spritelookupblinkvalue(string s)
                case "item-invis":       return 2;
                case "item-extralife":   return 2;
                case "item-speed":       return 2;
+               case "item-strength":    return 2;
+               case "item-shield":      return 2;
                case "item-fuelregen":   return 2;
                case "item-jetpack":     return 2;
                case "tagged-target":    return 2;
@@ -226,6 +228,8 @@ string spritelookuptext(string s)
                case "item-invis": return _("Invisibility");
                case "item-extralife": return _("Extra life");
                case "item-speed": return _("Speed");
+               case "item-strength": return _("Strength");
+               case "item-shield": return _("Shield");
                case "item-fuelregen": return _("Fuel regen");
                case "item-jetpack": return _("Jet Pack");
                case "frozen": return _("Frozen!");
index 9298d6e3a85e2fe9bc278ec41dbebf605bd0d003..0de2de45170bf9d41842976d0deba2b15d501615 100644 (file)
@@ -531,6 +531,10 @@ void Send_Notification_WOCOVA(
     MULTITEAM_INFO(1, INFO_ONSLAUGHT_CPDESTROYED_, 4,      2, 0, "s1 s2", "",                       "",                     _("^TC^TT^BG team %s^BG control point has been destroyed by %s"), "") \
     MULTITEAM_INFO(1, INFO_ONSLAUGHT_GENDESTROYED_, 4,     0, 0, "", "",                            "",                     _("^TC^TT^BG generator has been destroyed"), "") \
     MULTITEAM_INFO(1, INFO_ONSLAUGHT_GENDESTROYED_OVERTIME_, 4,  0, 0, "", "",                      "",                     _("^TC^TT^BG generator spontaneously combusted due to overtime!"), "") \
+    MSG_INFO_NOTIF(1, INFO_POWERUP_INVISIBILITY,           1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up Invisibility"), "") \
+    MSG_INFO_NOTIF(1, INFO_POWERUP_SHIELD,                 1, 0, "s1", "s1",                        "shield",               _("^BG%s^K1 picked up Shield"), "") \
+    MSG_INFO_NOTIF(1, INFO_POWERUP_SPEED,                  1, 0, "s1", "s1",                        "shield",               _("^BG%s^K1 picked up Speed"), "") \
+    MSG_INFO_NOTIF(1, INFO_POWERUP_STRENGTH,               1, 0, "s1", "s1",                        "strength",             _("^BG%s^K1 picked up Strength"), "") \
     MSG_INFO_NOTIF(2, INFO_QUIT_DISCONNECT,                1, 0, "s1", "",                          "",                     _("^BG%s^F3 disconnected"), "") \
     MSG_INFO_NOTIF(2, INFO_QUIT_KICK_IDLING,               1, 0, "s1", "",                          "",                     _("^BG%s^F3 was kicked for idling"), "") \
     MSG_INFO_NOTIF(1, INFO_QUIT_KICK_SPECTATING,           0, 0, "", "",                            "",                     _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment."), "") \
@@ -824,6 +828,14 @@ void Send_Notification_WOCOVA(
     MSG_CENTER_NOTIF(1, CENTER_PORTO_FAILED,                0, 0, "",              NO_CPID,               "0 0", _("^K1Portal deployment failed.\n\n^F2Catch it to try again!"), "") \
     MSG_CENTER_NOTIF(1, CENTER_PORTO_CREATED_IN,            0, 0, "",              NO_CPID,               "0 0", _("^K1In^BG-portal created"), "") \
     MSG_CENTER_NOTIF(1, CENTER_PORTO_CREATED_OUT,           0, 0, "",              NO_CPID,               "0 0", _("^F3Out^BG-portal created"), "") \
+    MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_INVISIBILITY,      0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Invisibility has worn off"), "") \
+    MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_SHIELD,            0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Shield has worn off"), "") \
+    MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_SPEED,             0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Speed has worn off"), "") \
+    MSG_CENTER_NOTIF(1, CENTER_POWERDOWN_STRENGTH,          0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Strength has worn off"), "") \
+    MSG_CENTER_NOTIF(1, CENTER_POWERUP_INVISIBILITY,        0, 0, "",              CPID_POWERUP,          "0 0", _("^F2You are invisible"), "") \
+    MSG_CENTER_NOTIF(1, CENTER_POWERUP_SHIELD,              0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Shield surrounds you"), "") \
+    MSG_CENTER_NOTIF(1, CENTER_POWERUP_SPEED,               0, 0, "",              CPID_POWERUP,          "0 0", _("^F2You are on speed"), "") \
+    MSG_CENTER_NOTIF(1, CENTER_POWERUP_STRENGTH,            0, 0, "",              CPID_POWERUP,          "0 0", _("^F2Strength infuses your weapons with devastating power"), "") \
     MSG_CENTER_NOTIF(1, CENTER_RACE_FINISHLAP,              0, 0, "",              CPID_RACE_FINISHLAP,   "0 0", _("^F2The race is over, finish your lap!"), "") \
     MSG_CENTER_NOTIF(1, CENTER_SECONDARY_NODAMAGE,          0, 0, "",              NO_CPID,               "0 0", _("^BGSecondary fire inflicts no damage!"), "") \
     MSG_CENTER_NOTIF(1, CENTER_SEQUENCE_COMPLETED,          0, 0, "",              NO_CPID,               "0 0", _("^BGSequence completed!"), "") \
index 6f49dbffd141360196368d3a8a2459f40c191832..87b5af045995e9c8f20be9a317d9d8073b0eef27 100644 (file)
@@ -260,7 +260,10 @@ void W_Porto_Attack(float type)
        gren.think = W_Porto_Think;
        gren.touch = W_Porto_Touch;
 
-       W_SetupProjVelocity_Basic(gren, WEP_CVAR_BOTH(porto, (type <= 0), speed), 0);
+       if(self.items & IT_STRENGTH)
+               W_SetupProjVelocity_Basic(gren, WEP_CVAR_BOTH(porto, (type <= 0), speed) * autocvar_g_balance_powerup_strength_force, 0);
+       else
+               W_SetupProjVelocity_Basic(gren, WEP_CVAR_BOTH(porto, (type <= 0), speed), 0);
 
        gren.angles = vectoangles(gren.velocity);
        gren.flags = FL_PROJECTILE;
index c69e2f976525a25b2ba0395482373a14887b1886..9d8a73c4346ce148c599b9ecda4aae3694d10120 100644 (file)
@@ -123,7 +123,8 @@ void W_Shockwave_Melee_Think(void)
        // set start time of melee
        if(!self.cnt)
        {
-               self.cnt = time; 
+               self.cnt = time;
+               W_PlayStrengthSound(self.realowner);
        }
 
        // update values for v_* vectors
index d88a15159adbba8beb3f8355f6cc72d1efbcb1dc..994ba9278148e6b61e0aeb4177366428f270b58b 100644 (file)
@@ -94,6 +94,7 @@ void W_Shotgun_Melee_Think(void)
        if(!self.cnt) // set start time of melee
        {
                self.cnt = time;
+               W_PlayStrengthSound(self.realowner);
        }
 
        makevectors(self.realowner.v_angle); // update values for v_* vectors
index c8f2a35fac752b9c5dc5479875c9dab2a2ac05be..8ceff9aeb7ac6075e6014830c76b441abe07f1bf 100644 (file)
@@ -160,6 +160,13 @@ float autocvar_g_balance_pause_health_rot;
 float autocvar_g_balance_pause_health_rot_spawn;
 float autocvar_g_balance_portal_health;
 float autocvar_g_balance_portal_lifetime;
+float autocvar_g_balance_powerup_invincible_takedamage;
+float autocvar_g_balance_powerup_invincible_time;
+float autocvar_g_balance_powerup_strength_damage;
+float autocvar_g_balance_powerup_strength_force;
+float autocvar_g_balance_powerup_strength_selfdamage;
+float autocvar_g_balance_powerup_strength_selfforce;
+float autocvar_g_balance_powerup_strength_time;
 float autocvar_g_balance_superweapons_time;
 float autocvar_g_balance_selfdamagepercent;
 float autocvar_g_balance_teams;
@@ -215,6 +222,7 @@ float autocvar_g_ctf_throw_angle_min;
 float autocvar_g_ctf_throw_punish_count;
 float autocvar_g_ctf_throw_punish_delay;
 float autocvar_g_ctf_throw_punish_time;
+float autocvar_g_ctf_throw_strengthmultiplier;
 float autocvar_g_ctf_throw_velocity_forward;
 float autocvar_g_ctf_throw_velocity_up;
 float autocvar_g_ctf_drop_velocity_up;
@@ -452,6 +460,8 @@ float autocvar_g_instagib_use_normal_ammo;
 float autocvar_g_instagib_ammo_drop;
 float autocvar_g_instagib_ammo_rockets;
 float autocvar_g_instagib_extralives;
+float autocvar_g_instagib_speed_highspeed;
+float autocvar_g_instagib_invis_alpha;
 float autocvar_g_instagib_damagedbycontents;
 float autocvar_g_instagib_blaster_keepdamage;
 float autocvar_g_instagib_blaster_keepforce;
@@ -486,6 +496,7 @@ float autocvar_g_nick_flood_penalty_yellow;
 //float autocvar_g_nick_flood_timeout;
 float autocvar_g_nix_with_healtharmor;
 float autocvar_g_nix_with_blaster;
+float autocvar_g_nix_with_powerups;
 float autocvar_g_nodepthtestitems;
 float autocvar_g_nodepthtestplayers;
 float autocvar_g_norecoil;
@@ -499,6 +510,7 @@ float autocvar_g_pickup_shells_max;
 float autocvar_g_player_alpha;
 float autocvar_g_player_brightness;
 float autocvar_g_playerclip_collisions;
+float autocvar_g_powerups;
 float autocvar_g_projectiles_damage;
 float autocvar_g_projectiles_keep_owner;
 float autocvar_g_projectiles_newton_style;
@@ -667,6 +679,8 @@ float autocvar_sv_spectate;
 float autocvar_sv_spectator_speed_multiplier;
 float autocvar_sv_status_privacy;
 float autocvar_sv_stepheight;
+float autocvar_sv_strengthsound_antispam_refire_threshold;
+float autocvar_sv_strengthsound_antispam_time;
 float autocvar_sv_teamnagger;
 float autocvar_sv_timeout;
 float autocvar_sv_timeout_leadtime;
index 9bc06ea88ac5b48ec7973193658897d4587042d4..6b331cd80562c3f9c6643388e8e3b77527987048 100644 (file)
@@ -177,6 +177,8 @@ float CheatImpulse(float i)
                        self.personal.pauserothealth_finished = self.pauserothealth_finished;
                        self.personal.pauserotfuel_finished = self.pauserotfuel_finished;
                        self.personal.pauseregen_finished = self.pauseregen_finished;
+                       self.personal.strength_finished = self.strength_finished;
+                       self.personal.invincible_finished = self.invincible_finished;
                        self.personal.teleport_time = time;
                        break; // this part itself doesn't cheat, so let's not count this
                case CHIMPULSE_CLONE_MOVING:
@@ -234,6 +236,8 @@ float CheatImpulse(float i)
                                self.pauserothealth_finished = time + self.personal.pauserothealth_finished - self.personal.teleport_time;
                                self.pauserotfuel_finished = time + self.personal.pauserotfuel_finished - self.personal.teleport_time;
                                self.pauseregen_finished = time + self.personal.pauseregen_finished - self.personal.teleport_time;
+                               self.strength_finished = time + self.personal.strength_finished - self.personal.teleport_time;
+                               self.invincible_finished = time + self.personal.invincible_finished - self.personal.teleport_time;
 
                                DID_CHEAT();
                                break;
index 5b2b7043ad08d049cfc771eb505c7ccdf299b72e..a26de6e020d31e5e1f263083554afe363eb1ad63 100644 (file)
@@ -304,6 +304,8 @@ void PutObserverInServer (void)
        self.fade_time = 0;
        self.pain_frame = 0;
        self.pain_finished = 0;
+       self.strength_finished = 0;
+       self.invincible_finished = 0;
        self.superweapons_finished = 0;
        self.pushltime = 0;
        self.istypefrag = 0;
@@ -676,6 +678,8 @@ void PutClientInServer (void)
                self.fade_time = 0;
                self.pain_frame = 0;
                self.pain_finished = 0;
+               self.strength_finished = 0;
+               self.invincible_finished = 0;
                self.pushltime = 0;
                // players have no think function
                self.think = func_null;
@@ -1646,6 +1650,46 @@ void player_powerups (void)
 
        if (!g_instagib)
        {
+               if (self.items & IT_STRENGTH)
+               {
+                       play_countdown(self.strength_finished, "misc/poweroff.wav");
+                       self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
+                       if (time > self.strength_finished)
+                       {
+                               self.items = self.items - (self.items & IT_STRENGTH);
+                               //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_STRENGTH, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_STRENGTH);
+                       }
+               }
+               else
+               {
+                       if (time < self.strength_finished)
+                       {
+                               self.items = self.items | IT_STRENGTH;
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_STRENGTH, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_STRENGTH);
+                       }
+               }
+               if (self.items & IT_INVINCIBLE)
+               {
+                       play_countdown(self.invincible_finished, "misc/poweroff.wav");
+                       self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
+                       if (time > self.invincible_finished)
+                       {
+                               self.items = self.items - (self.items & IT_INVINCIBLE);
+                               //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_SHIELD, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SHIELD);
+                       }
+               }
+               else
+               {
+                       if (time < self.invincible_finished)
+                       {
+                               self.items = self.items | IT_INVINCIBLE;
+                               Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SHIELD, self.netname);
+                               Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SHIELD);
+                       }
+               }
                if (self.items & IT_SUPERWEAPON)
                {
                        if (!(self.weapons & WEPSET_SUPERWEAPONS))
@@ -1894,6 +1938,8 @@ void SpectateCopy(entity spectatee) {
        self.last_pickup = spectatee.last_pickup;
        self.hit_time = spectatee.hit_time;
        self.metertime = spectatee.metertime;
+       self.strength_finished = spectatee.strength_finished;
+       self.invincible_finished = spectatee.invincible_finished;
        self.pressedkeys = spectatee.pressedkeys;
        self.weapons = spectatee.weapons;
        self.switchweapon = spectatee.switchweapon;
index ec3b00021bb753fff6a85fadb285f96f69ab827c..0be21680072443a530eff6d2fddc8c518f2c23df 100644 (file)
@@ -192,6 +192,10 @@ string AppendItemcodes(string s, entity player)
        if(w == 0)
                w = player.cnt; // previous weapon!
        s = strcat(s, ftos(w));
+       if(time < player.strength_finished)
+               s = strcat(s, "S");
+       if(time < player.invincible_finished)
+               s = strcat(s, "I");
        if(player.flagcarried != world)
                s = strcat(s, "F");
        if(player.BUTTON_CHAT)
@@ -837,6 +841,28 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                        self = oldself;
                }
 
+               if(!g_instagib)
+               {
+                       // apply strength multiplier
+                       if (attacker.items & IT_STRENGTH)
+                       {
+                               if(targ == attacker)
+                               {
+                                       damage = damage * autocvar_g_balance_powerup_strength_selfdamage;
+                                       force = force * autocvar_g_balance_powerup_strength_selfforce;
+                               }
+                               else
+                               {
+                                       damage = damage * autocvar_g_balance_powerup_strength_damage;
+                                       force = force * autocvar_g_balance_powerup_strength_force;
+                               }
+                       }
+
+                       // apply invincibility multiplier
+                       if (targ.items & IT_INVINCIBLE)
+                               damage = damage * autocvar_g_balance_powerup_invincible_takedamage;
+               }
+
                if (targ == attacker)
                        damage = damage * autocvar_g_balance_selfdamagepercent; // Partial damage if the attacker hits himself
 
index 60de30e0df404addf5aa1ab7fb105da9a3769478..6d424816c298c74a0e8ade836ab91c4a43b49a21 100644 (file)
@@ -743,6 +743,12 @@ void spawnfunc_worldspawn (void)
                if(autocvar_g_norecoil)
                        s = strcat(s, ":norecoil");
 
+               // TODO to mutator system
+               if(autocvar_g_powerups == 0)
+                       s = strcat(s, ":no_powerups");
+               if(autocvar_g_powerups > 0)
+                       s = strcat(s, ":powerups");
+
                GameLogEcho(s);
                GameLogEcho(":gameinfo:end");
        }
@@ -807,6 +813,8 @@ void spawnfunc_worldspawn (void)
        addstat(STAT_ALLOW_OLDVORTEXBEAM, AS_INT, stat_allow_oldvortexbeam);
        Nagger_Init();
 
+       addstat(STAT_STRENGTH_FINISHED, AS_FLOAT, strength_finished);
+       addstat(STAT_INVINCIBLE_FINISHED, AS_FLOAT, invincible_finished);
        addstat(STAT_SUPERWEAPONS_FINISHED, AS_FLOAT, superweapons_finished);
        addstat(STAT_PRESSED_KEYS, AS_FLOAT, pressedkeys);
        addstat(STAT_FUEL, AS_INT, ammo_fuel);
index 7e956569813541a5f06acbef11621e8062b20f79..cc05b729e195ebe2f9c4fcbeac01ddc33baaf234 100644 (file)
@@ -377,7 +377,7 @@ void ctf_Handle_Throw(entity player, entity receiver, float droptype)
                {
                        makevectors((player.v_angle.y * '0 1 0') + (bound(autocvar_g_ctf_throw_angle_min, player.v_angle.x, autocvar_g_ctf_throw_angle_max) * '1 0 0'));
 
-                       flag_velocity = (('0 0 1' * autocvar_g_ctf_throw_velocity_up) + ((v_forward * autocvar_g_ctf_throw_velocity_forward)));
+                       flag_velocity = (('0 0 1' * autocvar_g_ctf_throw_velocity_up) + ((v_forward * autocvar_g_ctf_throw_velocity_forward) * ((player.items & IT_STRENGTH) ? autocvar_g_ctf_throw_strengthmultiplier : 1)));
                        flag.velocity = W_CalculateProjectileVelocity(player.velocity, flag_velocity, false);
                        ctf_Handle_Drop(flag, player, droptype);
                        break;
index f710e89c562967b363659ce61e0fb480cdec45bc..b039e95f74d9077b2baa6cbc591ef5d193dcc1e5 100644 (file)
@@ -751,11 +751,17 @@ MUTATOR_HOOKFUNCTION(buffs_PlayerThink)
 
                if(self.oldbuffs & BUFF_INVISIBLE)
                {
-                       self.alpha = self.buff_invisible_prev_alpha;
+                       if(time < self.strength_finished && g_instagib)
+                               self.alpha = autocvar_g_instagib_invis_alpha;
+                       else
+                               self.alpha = self.buff_invisible_prev_alpha;
                }
                else if(self.buffs & BUFF_INVISIBLE)
                {
-                       self.buff_invisible_prev_alpha = self.alpha;
+                       if(time < self.strength_finished && g_instagib)
+                               self.buff_invisible_prev_alpha = default_player_alpha;
+                       else
+                               self.buff_invisible_prev_alpha = self.alpha;
                        self.alpha = autocvar_g_buffs_invisible_alpha;
                }
 
index c6db80991a95643aea31fffd88b7c6410e095693..951f99bda1474766e9cb8db1da0c57914a6f84f1 100644 (file)
@@ -158,6 +158,14 @@ MUTATOR_HOOKFUNCTION(instagib_MonsterSpawn)
        return false;
 }
 
+MUTATOR_HOOKFUNCTION(instagib_BotShouldAttack)
+{
+       if(other.items & IT_STRENGTH)
+               return true;
+
+       return false;
+}
+
 MUTATOR_HOOKFUNCTION(instagib_MakePlayerObserver)
 {
        instagib_stop_countdown(self);
@@ -186,6 +194,56 @@ MUTATOR_HOOKFUNCTION(instagib_PlayerPowerups)
 {
        if (!(self.effects & EF_FULLBRIGHT))
                self.effects |= EF_FULLBRIGHT;
+
+       if (self.items & IT_STRENGTH)
+       {
+               play_countdown(self.strength_finished, "misc/poweroff.wav");
+               if (time > self.strength_finished)
+               {
+                       self.alpha = default_player_alpha;
+                       self.exteriorweaponentity.alpha = default_weapon_alpha;
+                       self.items &= ~IT_STRENGTH;
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY);
+               }
+       }
+       else
+       {
+               if (time < self.strength_finished)
+               {
+                       self.alpha = autocvar_g_instagib_invis_alpha;
+                       self.exteriorweaponentity.alpha = autocvar_g_instagib_invis_alpha;
+                       self.items |= IT_STRENGTH;
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname);
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY);
+               }
+       }
+
+       if (self.items & IT_INVINCIBLE)
+       {
+               play_countdown(self.invincible_finished, "misc/poweroff.wav");
+               if (time > self.invincible_finished)
+               {
+                       self.items &= ~IT_INVINCIBLE;
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED);
+               }
+       }
+       else
+       {
+               if (time < self.invincible_finished)
+               {
+                       self.items |= IT_INVINCIBLE;
+                       Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname);
+                       Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED);
+               }
+       }
+       return false;
+}
+
+MUTATOR_HOOKFUNCTION(instagib_PlayerPhysics)
+{
+       if(self.items & IT_INVINCIBLE)
+               self.stat_sv_maxspeed = self.stat_sv_maxspeed * autocvar_g_instagib_speed_highspeed;
+
        return false;
 }
 
@@ -277,7 +335,7 @@ MUTATOR_HOOKFUNCTION(instagib_PlayerDamage)
                frag_mirrordamage = 0;
        }
 
-       if(frag_target.buffs & BUFF_INVISIBLE)
+       if((frag_target.buffs & BUFF_INVISIBLE) || (frag_target.items & IT_STRENGTH))
                yoda = 1;
 
        return false;
@@ -349,11 +407,26 @@ MUTATOR_HOOKFUNCTION(instagib_FilterItem)
        return true;
 }
 
+MUTATOR_HOOKFUNCTION(instagib_CustomizeWaypoint)
+{
+       entity e = WaypointSprite_getviewentity(other);
+
+       // if you have the invisibility powerup, sprites ALWAYS are restricted to your team
+       // but only apply this to real players, not to spectators
+       if((self.owner.flags & FL_CLIENT) && (self.owner.items & IT_STRENGTH) && (e == other))
+       if(DIFF_TEAM(self.owner, e))
+               return true;
+
+       return false;
+}
+
 MUTATOR_HOOKFUNCTION(instagib_ItemCountdown)
 {
        switch(self.items)
        {
+               case IT_STRENGTH:   item_name = "item-invis"; item_color = '0 0 1'; break;
                case IT_NAILS:      item_name = "item-extralife"; item_color = '1 0 0'; break;
+               case IT_INVINCIBLE: item_name = "item-speed"; item_color = '1 0 1'; break;
        }
        return false;
 }
@@ -407,7 +480,25 @@ MUTATOR_HOOKFUNCTION(instagib_OnEntityPreSpawn)
        if(random() <= 0.5)
                instagib_item_supercells();
 
-       return false;
+       if(!autocvar_g_powerups) { return false; }
+       if(!(self.classname == "item_strength" || self.classname == "item_invincible" || self.classname == "item_health_mega"))
+               return false;
+
+       entity e = spawn();
+
+       if(random() < 0.3)
+               e.think = spawnfunc_item_strength;
+       else if(random() < 0.6)
+               e.think = instagib_health_mega;
+       else
+               e.think = spawnfunc_item_invincible;
+
+       e.nextthink = time + 0.1;
+       e.spawnflags = self.spawnflags;
+       e.noalign = self.noalign;
+       setorigin(e, self.origin);
+
+       return true;
 }
 
 MUTATOR_HOOKFUNCTION(instagib_BuildMutatorsString)
@@ -433,12 +524,15 @@ MUTATOR_DEFINITION(mutator_instagib)
        MUTATOR_HOOK(MatchEnd, instagib_MatchEnd, CBC_ORDER_ANY);
        MUTATOR_HOOK(MonsterDropItem, instagib_MonsterLoot, CBC_ORDER_ANY);
        MUTATOR_HOOK(MonsterSpawn, instagib_MonsterSpawn, CBC_ORDER_ANY);
+       MUTATOR_HOOK(BotShouldAttack, instagib_BotShouldAttack, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerPhysics, instagib_PlayerPhysics, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerSpawn, instagib_PlayerSpawn, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerDamage_Calculate, instagib_PlayerDamage, CBC_ORDER_ANY);
        MUTATOR_HOOK(MakePlayerObserver, instagib_MakePlayerObserver, CBC_ORDER_ANY);
        MUTATOR_HOOK(SetStartItems, instagib_SetStartItems, CBC_ORDER_ANY);
        MUTATOR_HOOK(ItemTouch, instagib_ItemTouch, CBC_ORDER_ANY);
        MUTATOR_HOOK(FilterItem, instagib_FilterItem, CBC_ORDER_ANY);
+       MUTATOR_HOOK(CustomizeWaypoint, instagib_CustomizeWaypoint, CBC_ORDER_ANY);
        MUTATOR_HOOK(Item_RespawnCountdown, instagib_ItemCountdown, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerDies, instagib_PlayerDies, CBC_ORDER_ANY);
        MUTATOR_HOOK(PlayerDamage_SplitHealthArmor, instagib_SplitHealthArmor, CBC_ORDER_ANY);
index 56b3d5261743b982a232b8e62e80a70b8fbbddc6..a0ec6adaa020ca3d2273ee988886fe1e642d14d0 100644 (file)
@@ -184,6 +184,11 @@ MUTATOR_HOOKFUNCTION(nix_FilterItem)
                        if (autocvar_g_nix_with_healtharmor)
                                return 0;
                        break;
+               case IT_STRENGTH:
+               case IT_INVINCIBLE:
+                       if (autocvar_g_nix_with_powerups)
+                               return 0;
+                       break;
        }
 
        return 1; // delete all other items
index 9a8ff07c4c1d350c7eb1bf9356236331c3195d1d..da9e36a61d24e1cdb3bed232d9efffbb3d9698e5 100644 (file)
@@ -3,6 +3,8 @@
 #define _SSMAGIX "SUPERSPEC_OPTIONSFILE_V1"
 #define _ISLOCAL ((edict_num(1) == self) ? true : false)
 
+const float ASF_STRENGTH               = 1;
+const float ASF_SHIELD                         = 2;
 const float ASF_MEGA_AR                = 4;
 const float ASF_MEGA_HP                = 8;
 const float ASF_FLAG_GRAB              = 16;
@@ -117,7 +119,9 @@ MUTATOR_HOOKFUNCTION(superspec_ItemTouch)
                                }
                        }
 
-               if(             (self.autospec_flags & ASF_MEGA_AR && _item.classname == "item_armor_large") ||
+               if((self.autospec_flags & ASF_SHIELD && _item.invincible_finished) ||
+                               (self.autospec_flags & ASF_STRENGTH && _item.strength_finished) ||
+                               (self.autospec_flags & ASF_MEGA_AR && _item.classname == "item_armor_large") ||
                                (self.autospec_flags & ASF_MEGA_HP && _item.classname == "item_health_mega") ||
                                (self.autospec_flags & ASF_FLAG_GRAB && _item.classname == "item_flag_team"))
                {
@@ -270,6 +274,8 @@ MUTATOR_HOOKFUNCTION(superspec_SV_ParseClientCommand)
                        if(argv(1) == "help")
                        {
                                _aspeco = "use cmd autospec [option] [on|off] to set options\n\n";
+                               _aspeco = strcat(_aspeco, "^3 strength ^7(short^5 st^7) for automatic spectate on strength powerup\n");
+                               _aspeco = strcat(_aspeco, "^3 shield ^7(short^5 sh^7) for automatic spectate on shield powerup\n");
                                _aspeco = strcat(_aspeco, "^3 mega_health ^7(short^5 mh^7) for automatic spectate on mega health\n");
                                _aspeco = strcat(_aspeco, "^3 mega_armor ^7(short^5 ma^7) for automatic spectate on mega armor\n");
                                _aspeco = strcat(_aspeco, "^3 flag_grab ^7(short^5 fg^7) for automatic spectate on CTF flag grab\n");
@@ -305,6 +311,8 @@ MUTATOR_HOOKFUNCTION(superspec_SV_ParseClientCommand)
                                }
                                else
                                {
+                                       if((argv(i) == "strength") || (argv(i) == "st")) _bits |= ASF_STRENGTH;
+                                       if((argv(i) == "shield") || (argv(i) == "sh")) _bits |= ASF_SHIELD;
                                        if((argv(i) == "mega_health") || (argv(i) == "mh")) _bits |= ASF_MEGA_HP;
                                        if((argv(i) == "mega_armor") || (argv(i) == "ma")) _bits |= ASF_MEGA_AR;
                                        if((argv(i) == "flag_grab") || (argv(i) == "fg")) _bits |= ASF_FLAG_GRAB;
@@ -318,6 +326,8 @@ MUTATOR_HOOKFUNCTION(superspec_SV_ParseClientCommand)
                }
 
                _aspeco = "";
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_STRENGTH, "Strength", "strength", "st");
+               OPTIONINFO(self.autospec_flags, _aspeco, ASF_SHIELD, "Shield", "shield", "sh");
                OPTIONINFO(self.autospec_flags, _aspeco, ASF_MEGA_HP, "Mega Health", "mega_health", "mh");
                OPTIONINFO(self.autospec_flags, _aspeco, ASF_MEGA_AR, "Mega Armor", "mega_armor", "ma");
                OPTIONINFO(self.autospec_flags, _aspeco, ASF_FLAG_GRAB, "Flag grab", "flag_grab","fg");
@@ -335,7 +345,7 @@ MUTATOR_HOOKFUNCTION(superspec_SV_ParseClientCommand)
                entity _player;
                FOR_EACH_PLAYER(_player)
                {
-                       if(_player.buffs)
+                       if(_player.strength_finished > time || _player.invincible_finished > time)
                                return _spectate(_player);
                }
 
@@ -343,6 +353,32 @@ MUTATOR_HOOKFUNCTION(superspec_SV_ParseClientCommand)
                return true;
        }
 
+       if(cmd_name == "followstrength")
+       {
+               entity _player;
+               FOR_EACH_PLAYER(_player)
+               {
+                       if(_player.strength_finished > time)
+                               return _spectate(_player);
+               }
+
+               superspec_msg("", "", self, "No active Strength\n", 1);
+               return true;
+       }
+
+       if(cmd_name == "followshield")
+       {
+               entity _player;
+               FOR_EACH_PLAYER(_player)
+               {
+                       if(_player.invincible_finished > time)
+                               return _spectate(_player);
+               }
+
+               superspec_msg("", "", self, "No active Shield\n", 1);
+               return true;
+       }
+
        if(cmd_name == "followfc")
        {
                if(!g_ctf)
index 31799ac164d4fff7e6140deab34076fe5481cd50..e96af453e89a3c8a57864c20c0766293f63ff815 100644 (file)
@@ -286,15 +286,25 @@ void ItemUpdate(entity item)
        item.SendFlags |= ISF_LOCATION;
 }
 
-bool have_pickup_item(void)
+float have_pickup_item(void)
 {
-       if(autocvar_g_pickup_items > 0)
-               return true;
-       if(autocvar_g_pickup_items == 0)
-               return false;
-       if(g_weaponarena)
-       if(self.weapons || (self.items & IT_AMMO))
-               return false;
+       if(self.flags & FL_POWERUP)
+       {
+               if(autocvar_g_powerups > 0)
+                       return true;
+               if(autocvar_g_powerups == 0)
+                       return false;
+       }
+       else
+       {
+               if(autocvar_g_pickup_items > 0)
+                       return true;
+               if(autocvar_g_pickup_items == 0)
+                       return false;
+               if(g_weaponarena)
+                       if(self.weapons || (self.items & IT_AMMO)) // no item or ammo pickups in weaponarena
+                               return false;
+       }
        return true;
 }
 
@@ -364,6 +374,9 @@ void Item_Show (entity e, float mode)
                e.ItemStatus &= ~ITS_AVAILABLE;
        }
 
+       if (e.items & IT_STRENGTH || e.items & IT_INVINCIBLE)
+           e.ItemStatus |= ITS_POWERUP;
+
        if (autocvar_g_nodepthtestitems)
                e.effects |= EF_NODEPTHTEST;
 
@@ -392,7 +405,13 @@ void Item_Think()
 void Item_Respawn (void)
 {
        Item_Show(self, 1);
-       sound (self, CH_TRIGGER, "misc/itemrespawn.wav", VOL_BASE, ATTEN_NORM); // play respawn sound
+       // this is ugly...
+       if(self.items == IT_STRENGTH)
+               sound (self, CH_TRIGGER, "misc/strength_respawn.wav", VOL_BASE, ATTEN_NORM);    // play respawn sound
+       else if(self.items == IT_INVINCIBLE)
+               sound (self, CH_TRIGGER, "misc/shield_respawn.wav", VOL_BASE, ATTEN_NORM);      // play respawn sound
+       else
+               sound (self, CH_TRIGGER, "misc/itemrespawn.wav", VOL_BASE, ATTEN_NORM); // play respawn sound
        setorigin (self, self.origin);
 
        self.think = Item_Think;
@@ -422,6 +441,8 @@ void Item_RespawnCountdown (void)
                        {
                                case IT_FUEL_REGEN: name = "item-fuelregen"; rgb = '1 0.5 0'; break;
                                case IT_JETPACK:    name = "item-jetpack"; rgb = '0.5 0.5 0.5'; break;
+                               case IT_STRENGTH:   name = "item-strength"; rgb = '0 0 1'; break;
+                               case IT_INVINCIBLE: name = "item-shield"; rgb = '1 0 1'; break;
                        }
                        item_name = name;
                        item_color = rgb;
@@ -602,6 +623,16 @@ float Item_GiveTo(entity item, entity player)
                Send_Notification(NOTIF_ONE, player, MSG_INFO, INFO_ITEM_WEAPON_GOT, item.netname);
        }
 
+       if (item.strength_finished)
+       {
+               pickedup = true;
+               player.strength_finished = max(player.strength_finished, time) + item.strength_finished;
+       }
+       if (item.invincible_finished)
+       {
+               pickedup = true;
+               player.invincible_finished = max(player.invincible_finished, time) + item.invincible_finished;
+       }
        if (item.superweapons_finished)
        {
                pickedup = true;
@@ -661,13 +692,19 @@ void Item_Touch (void)
        }
 
        if (self.classname == "droppedweapon")
+       {
+               self.strength_finished = max(0, self.strength_finished - time);
+               self.invincible_finished = max(0, self.invincible_finished - time);
                self.superweapons_finished = max(0, self.superweapons_finished - time);
+       }
 
        if(!Item_GiveTo(self, other))
        {
                if (self.classname == "droppedweapon")
                {
                        // undo what we did above
+                       self.strength_finished += time;
+                       self.invincible_finished += time;
                        self.superweapons_finished += time;
                }
                return;
@@ -949,10 +986,21 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                self.takedamage = DAMAGE_YES;
                self.event_damage = Item_Damage;
 
-               if(self.superweapons_finished)
+               if(self.strength_finished || self.invincible_finished || self.superweapons_finished)
+               /*
+               if(self.items == 0)
+               if(!(self.weapons & ~WEPSET_SUPERWEAPONS)) // only superweapons
+               if(self.ammo_nails == 0)
+               if(self.ammo_cells == 0)
+               if(self.ammo_rockets == 0)
+               if(self.ammo_shells == 0)
+               if(self.ammo_fuel == 0)
+               if(self.health == 0)
+               if(self.armorvalue == 0)
+               */
                {
                        // if item is worthless after a timer, have it expire then
-                       self.nextthink = self.superweapons_finished;
+                       self.nextthink = max(self.strength_finished, self.invincible_finished, self.superweapons_finished);
                }
 
                // don't drop if in a NODROP zone (such as lava)
@@ -1036,7 +1084,12 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                precache_sound (self.item_pickupsound);
 
                precache_sound ("misc/itemrespawncountdown.wav");
-               precache_sound ("misc/itemrespawn.wav");
+               if(itemid == IT_STRENGTH)
+                       precache_sound ("misc/strength_respawn.wav");
+               else if(itemid == IT_INVINCIBLE)
+                       precache_sound ("misc/shield_respawn.wav");
+               else
+                       precache_sound ("misc/itemrespawn.wav");
 
                if((itemflags & (FL_POWERUP | FL_WEAPON)) || (itemid & (IT_HEALTH | IT_ARMOR | IT_KEY1 | IT_KEY2)))
                        self.target = "###item###"; // for finding the nearest item using find()
@@ -1273,9 +1326,18 @@ void spawnfunc_item_health1() { spawnfunc_item_health_small(); }
 void spawnfunc_item_health25() { spawnfunc_item_health_medium(); }
 void spawnfunc_item_health100() { spawnfunc_item_health_mega(); }
 
-// mutator hookable items
-void spawnfunc_item_strength() { /* dummy item */ }
-void spawnfunc_item_invincible() { /* dummy item */ }
+void spawnfunc_item_strength (void) {
+               precache_sound("weapons/strength_fire.wav");
+               if(!self.strength_finished)
+                       self.strength_finished = autocvar_g_balance_powerup_strength_time;
+               StartItem ("models/items/g_strength.md3", "misc/powerup.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup, "Strength Powerup", IT_STRENGTH, 0, FL_POWERUP, generic_pickupevalfunc, 100000);
+}
+
+void spawnfunc_item_invincible (void) {
+               if(!self.invincible_finished)
+                       self.invincible_finished = autocvar_g_balance_powerup_invincible_time;
+               StartItem ("models/items/g_invincible.md3", "misc/powerup_shield.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup, "Shield", IT_INVINCIBLE, 0, FL_POWERUP, generic_pickupevalfunc, 100000);
+}
 
 // compatibility:
 void spawnfunc_item_quad (void) {self.classname = "item_strength";spawnfunc_item_strength();}
@@ -1311,6 +1373,10 @@ void spawnfunc_target_items (void)
        string s;
 
        self.use = target_items_use;
+       if(!self.strength_finished)
+               self.strength_finished = autocvar_g_balance_powerup_strength_time;
+       if(!self.invincible_finished)
+               self.invincible_finished = autocvar_g_balance_powerup_invincible_time;
        if(!self.superweapons_finished)
                self.superweapons_finished = autocvar_g_balance_superweapons_time;
 
@@ -1333,6 +1399,8 @@ void spawnfunc_target_items (void)
                        if     (argv(i) == "unlimited_ammo")         self.items |= IT_UNLIMITED_AMMO;
                        else if(argv(i) == "unlimited_weapon_ammo")  self.items |= IT_UNLIMITED_WEAPON_AMMO;
                        else if(argv(i) == "unlimited_superweapons") self.items |= IT_UNLIMITED_SUPERWEAPONS;
+                       else if(argv(i) == "strength")               self.items |= IT_STRENGTH;
+                       else if(argv(i) == "invincible")             self.items |= IT_INVINCIBLE;
                        else if(argv(i) == "superweapons")           self.items |= IT_SUPERWEAPON;
                        else if(argv(i) == "jetpack")                self.items |= IT_JETPACK;
                        else if(argv(i) == "fuel_regen")             self.items |= IT_FUEL_REGEN;
@@ -1385,6 +1453,8 @@ void spawnfunc_target_items (void)
                self.netname = "";
                self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & IT_UNLIMITED_WEAPON_AMMO), "unlimited_weapon_ammo");
                self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & IT_UNLIMITED_SUPERWEAPONS), "unlimited_superweapons");
+               self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.strength_finished * !!(self.items & IT_STRENGTH), "strength");
+               self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.invincible_finished * !!(self.items & IT_INVINCIBLE), "invincible");
                self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.superweapons_finished * !!(self.items & IT_SUPERWEAPON), "superweapons");
                self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & IT_JETPACK), "jetpack");
                self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & IT_FUEL_REGEN), "fuel_regen");
@@ -1579,10 +1649,14 @@ float GiveItems(entity e, float beginarg, float endarg)
                if (e.switchweapon == w_getbestweapon(e))
                        _switchweapon = true;
 
+       e.strength_finished = max(0, e.strength_finished - time);
+       e.invincible_finished = max(0, e.invincible_finished - time);
        e.superweapons_finished = max(0, e.superweapons_finished - time);
 
        PREGIVE(e, items);
        PREGIVE_WEAPONS(e);
+       PREGIVE(e, strength_finished);
+       PREGIVE(e, invincible_finished);
        PREGIVE(e, superweapons_finished);
        PREGIVE(e, ammo_nails);
        PREGIVE(e, ammo_cells);
@@ -1623,6 +1697,8 @@ float GiveItems(entity e, float beginarg, float endarg)
                                continue;
                        case "ALL":
                                got += GiveBit(e, items, IT_FUEL_REGEN, op, val);
+                               got += GiveValue(e, strength_finished, op, val);
+                               got += GiveValue(e, invincible_finished, op, val);
                                got += GiveValue(e, superweapons_finished, op, val);
                                got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
                        case "all":
@@ -1661,6 +1737,12 @@ float GiveItems(entity e, float beginarg, float endarg)
                        case "fuel_regen":
                                got += GiveBit(e, items, IT_FUEL_REGEN, op, val);
                                break;
+                       case "strength":
+                               got += GiveValue(e, strength_finished, op, val);
+                               break;
+                       case "invincible":
+                               got += GiveValue(e, invincible_finished, op, val);
+                               break;
                        case "superweapons":
                                got += GiveValue(e, superweapons_finished, op, val);
                                break;
@@ -1725,6 +1807,8 @@ float GiveItems(entity e, float beginarg, float endarg)
                                        WEP_ACTION(wi.weapon, WR_INIT);
                }
        }
+       POSTGIVE_VALUE(e, strength_finished, 1, "misc/powerup.wav", "misc/poweroff.wav");
+       POSTGIVE_VALUE(e, invincible_finished, 1, "misc/powerup_shield.wav", "misc/poweroff.wav");
        POSTGIVE_VALUE(e, ammo_nails, 0, "misc/itempickup.wav", string_null);
        POSTGIVE_VALUE(e, ammo_cells, 0, "misc/itempickup.wav", string_null);
        POSTGIVE_VALUE(e, ammo_plasma, 0, "misc/itempickup.wav", string_null);
@@ -1739,6 +1823,14 @@ float GiveItems(entity e, float beginarg, float endarg)
                if(self.weapons & WEPSET_SUPERWEAPONS)
                        e.superweapons_finished = autocvar_g_balance_superweapons_time;
 
+       if(e.strength_finished <= 0)
+               e.strength_finished = 0;
+       else
+               e.strength_finished += time;
+       if(e.invincible_finished <= 0)
+               e.invincible_finished = 0;
+       else
+               e.invincible_finished += time;
        if(e.superweapons_finished <= 0)
                e.superweapons_finished = 0;
        else
index dfb2323884bd7946b6cc1980eae2b61ce59e651e..44276506321fcf16616f9872e18a97bcbb2ded21 100644 (file)
@@ -31,6 +31,18 @@ void W_GiveWeapon (entity e, float wep)
        self = oldself;
 }
 
+void W_PlayStrengthSound(entity player) // void W_PlayStrengthSound
+{
+       if((player.items & IT_STRENGTH)
+               && ((time > player.prevstrengthsound + autocvar_sv_strengthsound_antispam_time) // prevent insane sound spam
+               || (time > player.prevstrengthsoundattempt + autocvar_sv_strengthsound_antispam_refire_threshold)))
+               {
+                       sound(player, CH_TRIGGER, "weapons/strength_fire.wav", VOL_BASE, ATTEN_NORM);
+                       player.prevstrengthsound = time;
+               }
+               player.prevstrengthsoundattempt = time;
+}
+
 float W_CheckProjectileDamage(entity inflictor, entity projowner, float deathtype, float exception)
 {
        float is_from_contents = (deathtype == DEATH_SLIME || deathtype == DEATH_LAVA);
index a0f99999de7650f2b81c836da72f1d9740f39b7e..eeb197f37e1905802af34010959849ca9dc40da7 100644 (file)
@@ -2,6 +2,9 @@
 #define WEAPONS_COMMON_H
 
 void W_GiveWeapon (entity e, float wep);
+.float prevstrengthsound;
+.float prevstrengthsoundattempt;
+void W_PlayStrengthSound(entity player);
 float W_CheckProjectileDamage(entity inflictor, entity projowner, float deathtype, float exception);
 void W_PrepareExplosionByDamage(entity attacker, void() explode);
 
index 302152e858919cc889a8501cb5700b9f589e684d..169e711877b768d727884bf829e891809737cf1a 100644 (file)
@@ -131,6 +131,7 @@ void W_SetupShot_Dir_ProjectileSize_Range(entity ent, vector s_forward, vector m
        if (snd != "")
        {
                sound (ent, chan, snd, VOL_BASE, ATTN_NORM);
+               W_PlayStrengthSound(ent);
        }
 
        // nudge w_shotend so a trace to w_shotend hits