]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into Mario/killsound
authorMario <mario@smbclan.net>
Sat, 24 Dec 2016 08:46:10 +0000 (18:46 +1000)
committerMario <mario@smbclan.net>
Sat, 24 Dec 2016 08:46:10 +0000 (18:46 +1000)
75 files changed:
_hud_common.cfg
balance-mario.cfg
balance-nexuiz25.cfg
balance-overkill.cfg
balance-samual.cfg
balance-xdf.cfg
balance-xonotic.cfg
balance-xpm.cfg
mutators.cfg
notifications.cfg
qcsrc/client/defs.qh
qcsrc/client/hud/panel/infomessages.qc
qcsrc/client/hud/panel/modicons.qc
qcsrc/client/hud/panel/powerups.qc
qcsrc/client/hud/panel/radar.qc
qcsrc/client/hud/panel/timer.qc
qcsrc/client/miscfunctions.qh
qcsrc/client/mutators/events.qh
qcsrc/client/teamradar.qc
qcsrc/client/view.qc
qcsrc/common/items/all.qc
qcsrc/common/items/item/armor.qh
qcsrc/common/items/item/health.qh
qcsrc/common/items/item/powerup.qh
qcsrc/common/monsters/monster/mage.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/mutators/mutator/instagib/items.qh
qcsrc/common/mutators/mutator/itemstime/itemstime.qc
qcsrc/common/mutators/mutator/nix/sv_nix.qc
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/mutators/mutator/waypoints/all.inc
qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc
qcsrc/common/notifications/all.inc
qcsrc/common/physics/player.qc
qcsrc/common/sounds/all.inc
qcsrc/common/stats.qh
qcsrc/common/t_items.qc
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/vehicles/vehicle/bumblebee.qc
qcsrc/common/vehicles/vehicle/racer.qc
qcsrc/common/vehicles/vehicle/raptor.qc
qcsrc/common/vehicles/vehicle/spiderbot.qc
qcsrc/lib/vector.qh
qcsrc/menu/xonotic/dialog_hudpanel_itemstime.qc
qcsrc/server/bot/api.qh
qcsrc/server/bot/default/bot.qc
qcsrc/server/bot/default/bot.qh
qcsrc/server/bot/default/havocbot/havocbot.qc
qcsrc/server/bot/default/navigation.qc
qcsrc/server/bot/default/scripting.qc
qcsrc/server/bot/default/waypoints.qc
qcsrc/server/client.qc
qcsrc/server/command/getreplies.qc
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/defs.qh
qcsrc/server/g_hook.qc
qcsrc/server/g_world.qc
qcsrc/server/mapvoting.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/mutators/events.qh
qcsrc/server/mutators/mutator/gamemode_assault.qc
qcsrc/server/mutators/mutator/gamemode_ca.qc
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/mutators/mutator/gamemode_ctf.qh
qcsrc/server/mutators/mutator/gamemode_keyhunt.qc
qcsrc/server/mutators/mutator/gamemode_lms.qc
qcsrc/server/player.qc
qcsrc/server/race.qc
qcsrc/server/round_handler.qc
qcsrc/server/t_quake.qc
qcsrc/server/t_quake3.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/weaponsystem.qc

index 2e8d64da5ae99f8ed274600eda2f73520151fa44..6e88873e960eca4ad0429d1f8dd9141e4e84f8a6 100644 (file)
@@ -97,7 +97,7 @@ seta hud_panel_physics_speed_unit "1" "speed unit (1 = qu/s, 2 = m/s, 3 = km/h,
 
 seta hud_panel_itemstime_progressbar_maxtime "30" "when left time is at least this amount, the status bar is full"
 seta hud_panel_itemstime_hidespawned "1" "if 1 hide an item from the panel when all the occurrences of it are available again; if 2 hide it when at least one occurrence is available again"
-seta hud_panel_itemstime_hidelarge "0" "if 1 hide large armor and health from the panel"
+seta hud_panel_itemstime_hidebig "0" "if 1 hide big armor and health from the panel"
 
 seta hud_panel_quickmenu_file "" "load the quick menu from this file (empty or 0 to disable)"
 seta hud_panel_quickmenu_translatecommands 0 "when the game is translated, translate strings inside commands too (useful for chat commands)"
index 022d62eaa0ff475cb8ec1d6d73f3c5734fe8d749..d290be01265d0280de9b1f06955478a641911aa5 100644 (file)
@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 1
 set g_pickup_armorbig 50
 set g_pickup_armorbig_max 200
 set g_pickup_armorbig_anyway 1
-set g_pickup_armorlarge 100
-set g_pickup_armorlarge_max 200
-set g_pickup_armorlarge_anyway 1
+set g_pickup_armormega 100
+set g_pickup_armormega_max 200
+set g_pickup_armormega_anyway 1
 set g_pickup_healthsmall 5
 set g_pickup_healthsmall_max 200
 set g_pickup_healthsmall_anyway 1
 set g_pickup_healthmedium 25
 set g_pickup_healthmedium_max 200
 set g_pickup_healthmedium_anyway 1
-set g_pickup_healthlarge 50
-set g_pickup_healthlarge_max 200
-set g_pickup_healthlarge_anyway 1
+set g_pickup_healthbig 50
+set g_pickup_healthbig_max 200
+set g_pickup_healthbig_anyway 1
 set g_pickup_healthmega 100
 set g_pickup_healthmega_max 200
 set g_pickup_healthmega_anyway 1
index ebce2fabe7978327e5c6388dc4c570a304dec8b5..39405f399881c31eecdc243527b81eec5e3628f5 100644 (file)
@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 0
 set g_pickup_armorbig 50
 set g_pickup_armorbig_max 999
 set g_pickup_armorbig_anyway 0
-set g_pickup_armorlarge 100
-set g_pickup_armorlarge_max 999
-set g_pickup_armorlarge_anyway 0
+set g_pickup_armormega 100
+set g_pickup_armormega_max 999
+set g_pickup_armormega_anyway 0
 set g_pickup_healthsmall 5
 set g_pickup_healthsmall_max 999
 set g_pickup_healthsmall_anyway 0
 set g_pickup_healthmedium 25
 set g_pickup_healthmedium_max 999
 set g_pickup_healthmedium_anyway 0
-set g_pickup_healthlarge 50
-set g_pickup_healthlarge_max 999
-set g_pickup_healthlarge_anyway 0
+set g_pickup_healthbig 50
+set g_pickup_healthbig_max 999
+set g_pickup_healthbig_anyway 0
 set g_pickup_healthmega 100
 set g_pickup_healthmega_max 999
 set g_pickup_healthmega_anyway 0
index c55241962ba5817ff3d0e4df00fb09a3d023ece6..da17e0afeb099d8cdd3664890f6cca351d208e43 100644 (file)
@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 1
 set g_pickup_armorbig 50
 set g_pickup_armorbig_max 100
 set g_pickup_armorbig_anyway 1
-set g_pickup_armorlarge 100
-set g_pickup_armorlarge_max 100
-set g_pickup_armorlarge_anyway 1
+set g_pickup_armormega 100
+set g_pickup_armormega_max 100
+set g_pickup_armormega_anyway 1
 set g_pickup_healthsmall 5
 set g_pickup_healthsmall_max 200
 set g_pickup_healthsmall_anyway 1
 set g_pickup_healthmedium 25
 set g_pickup_healthmedium_max 200
 set g_pickup_healthmedium_anyway 1
-set g_pickup_healthlarge 50
-set g_pickup_healthlarge_max 200
-set g_pickup_healthlarge_anyway 1
+set g_pickup_healthbig 50
+set g_pickup_healthbig_max 200
+set g_pickup_healthbig_anyway 1
 set g_pickup_healthmega 100
 set g_pickup_healthmega_max 200
 set g_pickup_healthmega_anyway 0
index 58a0f37584392c4ba613e3fa07b1575938adf645..ad7192227eb4abcf842a2b02f57b1025de46ff27 100644 (file)
@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 1
 set g_pickup_armorbig 50
 set g_pickup_armorbig_max 200
 set g_pickup_armorbig_anyway 1
-set g_pickup_armorlarge 100
-set g_pickup_armorlarge_max 200
-set g_pickup_armorlarge_anyway 1
+set g_pickup_armormega 100
+set g_pickup_armormega_max 200
+set g_pickup_armormega_anyway 1
 set g_pickup_healthsmall 5
 set g_pickup_healthsmall_max 200
 set g_pickup_healthsmall_anyway 1
 set g_pickup_healthmedium 25
 set g_pickup_healthmedium_max 200
 set g_pickup_healthmedium_anyway 1
-set g_pickup_healthlarge 50
-set g_pickup_healthlarge_max 200
-set g_pickup_healthlarge_anyway 1
+set g_pickup_healthbig 50
+set g_pickup_healthbig_max 200
+set g_pickup_healthbig_anyway 1
 set g_pickup_healthmega 100
 set g_pickup_healthmega_max 200
 set g_pickup_healthmega_anyway 1
index ff2ec1871639c7c7917496de6f7bfdd0cd0d70b8..79344fda96b597a1ac1b034e3a2755c08bc598d0 100644 (file)
@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 1
 set g_pickup_armorbig 50
 set g_pickup_armorbig_max 200
 set g_pickup_armorbig_anyway 1
-set g_pickup_armorlarge 100
-set g_pickup_armorlarge_max 200
-set g_pickup_armorlarge_anyway 1
+set g_pickup_armormega 100
+set g_pickup_armormega_max 200
+set g_pickup_armormega_anyway 1
 set g_pickup_healthsmall 5
 set g_pickup_healthsmall_max 200
 set g_pickup_healthsmall_anyway 1
 set g_pickup_healthmedium 25
 set g_pickup_healthmedium_max 200
 set g_pickup_healthmedium_anyway 1
-set g_pickup_healthlarge 50
-set g_pickup_healthlarge_max 200
-set g_pickup_healthlarge_anyway 1
+set g_pickup_healthbig 50
+set g_pickup_healthbig_max 200
+set g_pickup_healthbig_anyway 1
 set g_pickup_healthmega 100
 set g_pickup_healthmega_max 200
 set g_pickup_healthmega_anyway 1
index e9fb9994dd6a317a6b3bc58e081ab3e50af03003..f317d2e6b422d1225078fe3fa4d58de4ee128ce4 100644 (file)
@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 1
 set g_pickup_armorbig 50
 set g_pickup_armorbig_max 200
 set g_pickup_armorbig_anyway 1
-set g_pickup_armorlarge 100
-set g_pickup_armorlarge_max 200
-set g_pickup_armorlarge_anyway 1
+set g_pickup_armormega 100
+set g_pickup_armormega_max 200
+set g_pickup_armormega_anyway 1
 set g_pickup_healthsmall 5
 set g_pickup_healthsmall_max 200
 set g_pickup_healthsmall_anyway 1
 set g_pickup_healthmedium 25
 set g_pickup_healthmedium_max 200
 set g_pickup_healthmedium_anyway 1
-set g_pickup_healthlarge 50
-set g_pickup_healthlarge_max 200
-set g_pickup_healthlarge_anyway 1
+set g_pickup_healthbig 50
+set g_pickup_healthbig_max 200
+set g_pickup_healthbig_anyway 1
 set g_pickup_healthmega 100
 set g_pickup_healthmega_max 200
 set g_pickup_healthmega_anyway 1
index 0c24cf206753edc261a1c16727e9f0165556c1eb..f5ec29240e97d8b8646c7ba8aabb535037049acd 100644 (file)
@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 0
 set g_pickup_armorbig 50
 set g_pickup_armorbig_max 100
 set g_pickup_armorbig_anyway 0
-set g_pickup_armorlarge 100
-set g_pickup_armorlarge_max 200
-set g_pickup_armorlarge_anyway 0
+set g_pickup_armormega 100
+set g_pickup_armormega_max 200
+set g_pickup_armormega_anyway 0
 set g_pickup_healthsmall 5
 set g_pickup_healthsmall_max 200
 set g_pickup_healthsmall_anyway 0
 set g_pickup_healthmedium 25
 set g_pickup_healthmedium_max 100
 set g_pickup_healthmedium_anyway 0
-set g_pickup_healthlarge 50
-set g_pickup_healthlarge_max 100
-set g_pickup_healthlarge_anyway 0
+set g_pickup_healthbig 50
+set g_pickup_healthbig_max 100
+set g_pickup_healthbig_anyway 0
 set g_pickup_healthmega 100
 set g_pickup_healthmega_max 200
 set g_pickup_healthmega_anyway 0
index 0031904599c7997f7e4b6340719254ea3e5e7993..781377637e076515e4fc0474340d4357e4460079 100644 (file)
@@ -53,7 +53,7 @@ set g_overkill_powerups_replace 1
 set g_overkill_filter_healthmega 0
 set g_overkill_filter_armormedium 0
 set g_overkill_filter_armorbig 0
-set g_overkill_filter_armorlarge 0
+set g_overkill_filter_armormega 0
 
 set g_overkill_ammo_charge 0
 set g_overkill_ammo_charge_notice 1
index 8583592b9acb74d11d24b8125b9b9caac23f0177..8ca401bb423f43be3e960a9b23cd2215f889ed9a 100644 (file)
@@ -424,10 +424,11 @@ seta notification_INFO_WEAPON_TUBA_SUICIDE "1" "0 = off, 1 = print to console, 2
 seta notification_INFO_WEAPON_VAPORIZER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
 seta notification_INFO_WEAPON_VORTEX_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
 
-// MSG_CENTER notifications (count = 230):
+// MSG_CENTER notifications (count = 231):
 seta notification_CENTER_ALONE "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ASSAULT_ATTACKING "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_ASSAULT_DEFENDING "1" "0 = off, 1 = centerprint"
+seta notification_CENTER_ASSAULT_OBJ_DESTROYED "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_CAMPCHECK "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_COINTOSS "1" "0 = off, 1 = centerprint"
 seta notification_CENTER_COUNTDOWN_BEGIN "1" "0 = off, 1 = centerprint"
@@ -886,4 +887,4 @@ seta notification_show_sprees_info "3" "Show spree information in MSG_INFO messa
 seta notification_show_sprees_info_newline "1" "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself"
 seta notification_show_sprees_info_specialonly "1" "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement"
 
-// Notification counts (total = 820): MSG_ANNCE = 89, MSG_INFO = 320, MSG_CENTER = 230, MSG_MULTI = 153, MSG_CHOICE = 28
+// Notification counts (total = 821): MSG_ANNCE = 89, MSG_INFO = 320, MSG_CENTER = 231, MSG_MULTI = 153, MSG_CHOICE = 28
index 437e1dd75bab5538dc80c311102adcb7719a8ebd..309ed1d81572998098dcc40fdaad24ae72df6ba1 100644 (file)
@@ -120,7 +120,7 @@ int serverflags;
 
 float uid2name_dialog;
 
-float gameover_time;
+float intermission_time;
 
 .bool csqcmodel_isdead; // used by shownames and miscfunctions (entcs_IsDead) to know when a player is dead
 
index db102e60e8b6fb7fb17d6223a8268fbb20025fc5..2d6c952fc0f3764cfced6e99448be1a14628dd47 100644 (file)
@@ -114,6 +114,8 @@ void HUD_InfoMessages()
                                InfoMessage(s);
                        }
 
+                       MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize);
+
                        if(!warmup_stage && gametype == MAPINFO_TYPE_LMS)
                        {
                                entity sk;
index c3310b25a13b8189711c8ccecf7e3957b4b17c5c..bf302fdfa3f3cff6f2fcc701e269821a4a8b1f7f 100644 (file)
@@ -283,8 +283,9 @@ void HUD_Mod_KH(vector pos, vector mySize)
        mod_active = 1; // keyhunt should never hide the mod icons panel
 
        // Read current state
-
        int state = STAT(KH_KEYS);
+       if(!state) return;
+
        int i, key_state;
        int all_keys, team1_keys, team2_keys, team3_keys, team4_keys, dropped_keys, carrying_keys;
        all_keys = team1_keys = team2_keys = team3_keys = team4_keys = dropped_keys = carrying_keys = 0;
@@ -315,9 +316,7 @@ void HUD_Mod_KH(vector pos, vector mySize)
        }
 
        // Calculate slot measurements
-
        vector slot_size;
-
        if(all_keys == 4 && mySize.x * 0.5 < mySize.y && mySize.y * 0.5 < mySize.x)
        {
                // Quadratic arrangement
@@ -347,11 +346,10 @@ void HUD_Mod_KH(vector pos, vector mySize)
 
        // Make icons blink in case of RUN HERE
 
-       float blink = 0.6 + sin(2*M_PI*time) / 2.5; // Oscillate between 0.2 and 1
-       float alpha;
-       alpha = 1;
-
+       float alpha = 1;
        if(carrying_keys)
+       {
+               float blink = 0.6 + sin(2 * M_PI * time) * 0.4; // Oscillate between 0.2 and 1
                switch(myteam)
                {
                        case NUM_TEAM_1: if(team1_keys == all_keys) alpha = blink; break;
@@ -359,6 +357,7 @@ void HUD_Mod_KH(vector pos, vector mySize)
                        case NUM_TEAM_3: if(team3_keys == all_keys) alpha = blink; break;
                        case NUM_TEAM_4: if(team4_keys == all_keys) alpha = blink; break;
                }
+       }
 
        // Draw icons
 
index 7c454f9f9001ff695115234408f7c571f8d93a25..076ce918f14723dcde2e755308a3f4379fb885e0 100644 (file)
@@ -63,7 +63,7 @@ void HUD_Powerups()
 {
        int allItems = STAT(ITEMS);
        int allBuffs = STAT(BUFFS);
-       int strengthTime, shieldTime, superTime;
+       float strengthTime, shieldTime, superTime;
 
        // Initialize items
        if(!autocvar__hud_configure)
@@ -72,7 +72,7 @@ void HUD_Powerups()
                        return;
                if(STAT(HEALTH) <= 0 && autocvar_hud_panel_powerups_hide_ondeath)
                        return;
-               if(!(allItems & (ITEM_Strength.m_itemid | ITEM_Shield.m_itemid | IT_SUPERWEAPON)) && !allBuffs) return;
+               //if(!(allItems & (ITEM_Strength.m_itemid | ITEM_Shield.m_itemid | IT_SUPERWEAPON)) && !allBuffs) return;
 
                strengthTime = bound(0, STAT(STRENGTH_FINISHED) - time, 99);
                shieldTime = bound(0, STAT(INVINCIBLE_FINISHED) - time, 99);
index 269d870718e42663a431a3445c984876ff74b4c5..3bc537c8f8b5e42760e5ca614ac4e02dadc4ce08 100644 (file)
@@ -312,10 +312,10 @@ void HUD_Radar()
        else
        {
                vector c0, c1, c2, c3, span;
-               c0 = rotate(mi_min, teamradar_angle * DEG2RAD);
-               c1 = rotate(mi_max, teamradar_angle * DEG2RAD);
-               c2 = rotate('1 0 0' * mi_min.x + '0 1 0' * mi_max.y, teamradar_angle * DEG2RAD);
-               c3 = rotate('1 0 0' * mi_max.x + '0 1 0' * mi_min.y, teamradar_angle * DEG2RAD);
+               c0 = Rotate(mi_min, teamradar_angle * DEG2RAD);
+               c1 = Rotate(mi_max, teamradar_angle * DEG2RAD);
+               c2 = Rotate('1 0 0' * mi_min.x + '0 1 0' * mi_max.y, teamradar_angle * DEG2RAD);
+               c3 = Rotate('1 0 0' * mi_max.x + '0 1 0' * mi_min.y, teamradar_angle * DEG2RAD);
                span = '0 0 0';
                span.x = max(c0_x, c1_x, c2_x, c3_x) - min(c0_x, c1_x, c2_x, c3_x);
                span.y = max(c0_y, c1_y, c2_y, c3_y) - min(c0_y, c1_y, c2_y, c3_y);
index fab0392dc08938d19dd27046faf608e9f1241931..45f46b4087ad35da1c4cff70aabe9799a40463f6 100644 (file)
@@ -50,15 +50,15 @@ void HUD_Timer()
        }
 
        vector timer_color;
-       if(gameover_time || minutesLeft >= 5 || warmup_stage || timelimit == 0)
+       if(intermission_time || minutesLeft >= 5 || warmup_stage || timelimit == 0)
                timer_color = '1 1 1'; //white
        else if(minutesLeft >= 1)
                timer_color = '1 1 0'; //yellow
        else
                timer_color = '1 0 0'; //red
 
-       if (gameover_time) {
-               timer = seconds_tostring(max(0, floor(gameover_time - STAT(GAMESTARTTIME))));
+       if (intermission_time) {
+               timer = seconds_tostring(max(0, floor(intermission_time - STAT(GAMESTARTTIME))));
        } else if (autocvar_hud_panel_timer_increment || (!warmup_stage && timelimit == 0) || (warmup_stage && warmup_timeleft <= 0)) {
                if (time < STAT(GAMESTARTTIME))
                        timer = seconds_tostring(0); //while restart is still active, show 00:00
index 9d792f60cd62ad3335e5531e8c48c483a16dc199..62de4565e53bff2549a9b361f063ab0791c7004b 100644 (file)
@@ -31,7 +31,7 @@ vector HUD_GetFontsize(string cvarname);
 
 float PreviewExists(string name);
 
-vector rotate(vector v, float a);
+vector Rotate(vector v, float a);
 
 
 #define IS_DEAD(s) (((s).classname == "csqcmodel") ? (s).csqcmodel_isdead : ((s).health <= 0))
index 74090e14d6992749c8b747c04894a20279c8d7bf..edd178199d5c17b0d3eafb191748afc890cb600f 100644 (file)
@@ -157,3 +157,10 @@ MUTATOR_HOOKABLE(DrawCrosshair, EV_NO_ARGS);
 
 /** Return true to not draw scoreboard */
 MUTATOR_HOOKABLE(DrawScoreboard, EV_NO_ARGS);
+
+/** Called when drawing info messages, allows adding new info messages */
+#define EV_DrawInfoMessages(i, o) \
+       /** pos */                          i(vector, MUTATOR_ARGV_0_vector) \
+       /** mySize */                   i(vector, MUTATOR_ARGV_1_vector) \
+       /**/
+MUTATOR_HOOKABLE(DrawInfoMessages, EV_DrawInfoMessages);
index abd700e613e38895b44ceeba7acbe86498895b42..782776eb7866757ebc7ff8ad24076b4923e57859 100644 (file)
@@ -20,7 +20,7 @@ vector teamradar_texcoord_to_2dcoord(vector in)
        vector out;
        in -= teamradar_origin3d_in_texcoord;
 
-       out = rotate(in, teamradar_angle * DEG2RAD);
+       out = Rotate(in, teamradar_angle * DEG2RAD);
        out.y = - out.y; // screen space is reversed
 
        out = out * teamradar_size;
@@ -42,7 +42,7 @@ vector teamradar_2dcoord_to_texcoord(vector in)
        out = out / teamradar_size;
 
        out_y = - out_y; // screen space is reversed
-       out = rotate(out, -teamradar_angle * DEG2RAD);
+       out = Rotate(out, -teamradar_angle * DEG2RAD);
 
        out += teamradar_origin3d_in_texcoord;
 
index 95e3a7b7dcf96aeb29d9a3d65e7e80670f2a6b05..4165da32ad5ebaa3359c2c0b62d0b2baadd0928c 100644 (file)
@@ -747,7 +747,7 @@ bool WantEventchase(entity this)
 {
        if(autocvar_cl_orthoview)
                return false;
-       if(intermission)
+       if(STAT(GAMEOVER) || intermission)
                return true;
        if(this.viewloc)
                return true;
@@ -948,7 +948,7 @@ void HUD_Crosshair(entity this)
 {
        float f, i, j;
        vector v;
-       if(!scoreboard_active && !camera_active && intermission != 2 &&
+       if(!scoreboard_active && !camera_active && intermission != 2 && !STAT(GAMEOVER) &&
                spectatee_status != -1 && !csqcplayer.viewloc && !MUTATOR_CALLHOOK(DrawCrosshair) &&
                !HUD_MinigameMenu_IsOpened() )
        {
@@ -1756,8 +1756,8 @@ void CSQC_UpdateView(entity this, float w, float h)
        if(!postinit)
                PostInit();
 
-       if(intermission && !gameover_time)
-               gameover_time = time;
+       if(intermission && !intermission_time)
+               intermission_time = time;
 
        if(intermission && !isdemo() && !(calledhooks & HOOK_END))
        {
index 7782cda0d6d1518c47de858484a6123974dcde45..0a26a75b5a7fd33aeee0f0b35a3dfd4b8ec92b8b 100644 (file)
@@ -14,3 +14,14 @@ string Item_Model(string item_mdl)
 #endif
     return output;
 }
+
+string Item_Sound(string it_snd)
+{
+       string output = strcat("misc/", it_snd);
+#ifdef SVQC
+               MUTATOR_CALLHOOK(ItemSound, it_snd, output);
+               return M_ARGV(1, string);
+#else
+               return output;
+#endif
+}
index 0a527548517a2337dc2c673d13419d491fec2a02..b222ca62894465b23364409bb9d369fe478d53c3 100644 (file)
@@ -15,7 +15,7 @@ ENDCLASS(Armor)
 
 #ifdef GAMEQC
 MODEL(ArmorSmall_ITEM, Item_Model("item_armor_small.md3"));
-SOUND(ArmorSmall, "misc/armor1");
+SOUND(ArmorSmall, Item_Sound("armor1"));
 #endif
 
 REGISTER_ITEM(ArmorSmall, Armor) {
@@ -35,7 +35,7 @@ REGISTER_ITEM(ArmorSmall, Armor) {
 
 #ifdef GAMEQC
 MODEL(ArmorMedium_ITEM, Item_Model("item_armor_medium.md3"));
-SOUND(ArmorMedium, "misc/armor10");
+SOUND(ArmorMedium, Item_Sound("armor10"));
 #endif
 
 REGISTER_ITEM(ArmorMedium, Armor) {
@@ -54,19 +54,19 @@ REGISTER_ITEM(ArmorMedium, Armor) {
 }
 
 #ifdef GAMEQC
-MODEL(ArmorLarge_ITEM, Item_Model("item_armor_big.md3"));
-SOUND(ArmorLarge, "misc/armor17_5");
+MODEL(ArmorBig_ITEM, Item_Model("item_armor_big.md3"));
+SOUND(ArmorBig, Item_Sound("armor17_5"));
 #endif
 
-REGISTER_ITEM(ArmorLarge, Armor) {
+REGISTER_ITEM(ArmorBig, Armor) {
 #ifdef GAMEQC
-    this.m_model                =   MDL_ArmorLarge_ITEM;
-    this.m_sound                =   SND_ArmorLarge;
+    this.m_model                =   MDL_ArmorBig_ITEM;
+    this.m_sound                =   SND_ArmorBig;
 #endif
     this.m_name                 =   "50 Armor";
     this.m_icon                 =   "armor";
     this.m_color                =   '0 1 0';
-    this.m_waypoint             =   _("Large armor");
+    this.m_waypoint             =   _("Big armor");
 #ifdef SVQC
     this.m_botvalue             =   20000; // FIXME: higher than BOT_PICKUP_RATING_HIGH?
     this.m_itemid               =   IT_ARMOR;
@@ -77,7 +77,7 @@ REGISTER_ITEM(ArmorLarge, Armor) {
 
 #ifdef GAMEQC
 MODEL(ArmorMega_ITEM, Item_Model("item_armor_large.md3"));
-SOUND(ArmorMega, "misc/armor25");
+SOUND(ArmorMega, Item_Sound("armor25"));
 #endif
 
 REGISTER_ITEM(ArmorMega, Armor) {
index 3717bf5be411ff52263a96a6ff88581938d5bf3c..f7915987e3b01a55fcc864ce3517e7590372acfa 100644 (file)
@@ -15,7 +15,7 @@ ENDCLASS(Health)
 
 #ifdef GAMEQC
 MODEL(HealthSmall_ITEM, Item_Model("g_h1.md3"));
-SOUND(HealthSmall, "misc/minihealth");
+SOUND(HealthSmall, Item_Sound("minihealth"));
 #endif
 
 REGISTER_ITEM(HealthSmall, Health) {
@@ -35,7 +35,7 @@ REGISTER_ITEM(HealthSmall, Health) {
 
 #ifdef GAMEQC
 MODEL(HealthMedium_ITEM, Item_Model("g_h25.md3"));
-SOUND(HealthMedium, "misc/mediumhealth");
+SOUND(HealthMedium, Item_Sound("mediumhealth"));
 #endif
 
 REGISTER_ITEM(HealthMedium, Health) {
@@ -54,19 +54,19 @@ REGISTER_ITEM(HealthMedium, Health) {
 }
 
 #ifdef GAMEQC
-MODEL(HealthLarge_ITEM, Item_Model("g_h50.md3"));
-SOUND(HealthLarge, "misc/mediumhealth");
+MODEL(HealthBig_ITEM, Item_Model("g_h50.md3"));
+SOUND(HealthBig, Item_Sound("mediumhealth"));
 #endif
 
-REGISTER_ITEM(HealthLarge, Health) {
+REGISTER_ITEM(HealthBig, Health) {
 #ifdef GAMEQC
-    this.m_model                =   MDL_HealthLarge_ITEM;
-    this.m_sound                =   SND_HealthLarge;
+    this.m_model                =   MDL_HealthBig_ITEM;
+    this.m_sound                =   SND_HealthBig;
 #endif
     this.m_name                 =   "50 Health";
     this.m_icon                 =   "health";
     this.m_color                =   '1 0 0';
-    this.m_waypoint             =   _("Large health");
+    this.m_waypoint             =   _("Big health");
 #ifdef SVQC
     this.m_botvalue             =   BOT_PICKUP_RATING_MID;
     this.m_itemid               =   IT_25HP;
@@ -77,7 +77,7 @@ REGISTER_ITEM(HealthLarge, Health) {
 
 #ifdef GAMEQC
 MODEL(HealthMega_ITEM, Item_Model("g_h100.md3"));
-SOUND(HealthMega, "misc/megahealth");
+SOUND(HealthMega, Item_Sound("megahealth"));
 #endif
 
 REGISTER_ITEM(HealthMega, Health) {
index df9315e2c838e72d7153fbcc9e81450c16d8bd91..80b1e6affc0a12747c9d2fd0b14c4ef25659da32 100644 (file)
@@ -19,7 +19,7 @@ ENDCLASS(Powerup)
 
 #ifdef GAMEQC
 MODEL(Strength_ITEM, Item_Model("g_strength.md3"));
-SOUND(Strength, "misc/powerup");
+SOUND(Strength, Item_Sound("powerup"));
 #endif
 
 REGISTER_ITEM(Strength, Powerup) {
@@ -39,7 +39,7 @@ REGISTER_ITEM(Strength, Powerup) {
 
 #ifdef GAMEQC
 MODEL(Shield_ITEM, Item_Model("g_invincible.md3"));
-SOUND(Shield, "misc/powerup_shield");
+SOUND(Shield, Item_Sound("powerup_shield"));
 #endif
 
 REGISTER_ITEM(Shield, Powerup) {
index 71bca32c64033b0fed60e56bbae2055c7c44dee6..748f9a9bd639130f695a0d5f936c93492f016d32 100644 (file)
@@ -451,7 +451,7 @@ METHOD(Mage, mr_anim, bool(Mage this, entity actor))
 #endif
 #ifdef SVQC
 .float speed;
-spawnfunc(item_health_large);
+spawnfunc(item_health_big);
 METHOD(Mage, mr_setup, bool(Mage this, entity actor))
 {
     TC(Mage, this);
@@ -461,7 +461,7 @@ METHOD(Mage, mr_setup, bool(Mage this, entity actor))
     if(!actor.stopspeed) { actor.stopspeed = (autocvar_g_monster_mage_speed_stop); }
     if(!actor.damageforcescale) { actor.damageforcescale = (autocvar_g_monster_mage_damageforcescale); }
 
-    actor.monster_loot = spawnfunc_item_health_large;
+    actor.monster_loot = spawnfunc_item_health_big;
     actor.monster_attackfunc = M_Mage_Attack;
 
     return true;
index b8c3bab21e77240e82dcef113826ab1b5b96c751..f0f789af3762ffcf1a9ebdf8e1b2697c945b9599 100644 (file)
@@ -34,7 +34,7 @@ void monster_dropitem(entity this, entity attacker)
        if(!this.candrop || !this.monster_loot)
                return;
 
-       vector org = this.origin + ((this.mins + this.maxs) * 0.5);
+       vector org = CENTER_OR_VIEWOFS(this);
        entity e = new(droppedweapon); // use weapon handling to remove it on touch
        e.spawnfunc_checked = true;
 
@@ -80,7 +80,7 @@ bool Monster_ValidTarget(entity this, entity targ)
 
        if((targ == this)
        || (autocvar_g_monsters_lineofsight && !checkpvs(this.origin + this.view_ofs, targ)) // enemy cannot be seen
-       || (IS_VEHICLE(targ) && !((get_monsterinfo(this.monsterid)).spawnflags & MON_FLAG_RANGED)) // melee vs vehicle is useless
+       || (IS_VEHICLE(targ) && !((Monsters_from(this.monsterid)).spawnflags & MON_FLAG_RANGED)) // melee vs vehicle is useless
        || (time < game_starttime) // monsters do nothing before match has started
        || (targ.takedamage == DAMAGE_NO)
        || (targ.items & IT_INVISIBILITY)
@@ -107,10 +107,8 @@ bool Monster_ValidTarget(entity this, entity targ)
        if(autocvar_g_monsters_target_infront || (this.spawnflags & MONSTERFLAG_INFRONT))
        if(this.enemy != targ)
        {
-               float dot;
-
                makevectors (this.angles);
-               dot = normalize (targ.origin - this.origin) * v_forward;
+               float dot = normalize (targ.origin - this.origin) * v_forward;
 
                if(dot <= autocvar_g_monsters_target_infront_range) { return false; }
        }
@@ -118,25 +116,25 @@ bool Monster_ValidTarget(entity this, entity targ)
        return true; // this target is valid!
 }
 
-entity Monster_FindTarget(entity mon)
+entity Monster_FindTarget(entity this)
 {
-       if(MUTATOR_CALLHOOK(MonsterFindTarget)) { return mon.enemy; } // Handled by a mutator
+       if(MUTATOR_CALLHOOK(MonsterFindTarget)) { return this.enemy; } // Handled by a mutator
 
        entity closest_target = NULL;
+       vector my_center = CENTER_OR_VIEWOFS(this);
 
        // find the closest acceptable target to pass to
-       FOREACH_ENTITY_RADIUS(mon.origin, mon.target_range, it.monster_attack,
+       FOREACH_ENTITY_RADIUS(this.origin, this.target_range, it.monster_attack,
        {
-               if(Monster_ValidTarget(mon, it))
+               if(Monster_ValidTarget(this, it))
                {
                        // if it's a player, use the view origin as reference (stolen from RadiusDamage functions in g_damage.qc)
-                       vector head_center = CENTER_OR_VIEWOFS(it);
-                       vector ent_center = CENTER_OR_VIEWOFS(mon);
+                       vector targ_center = CENTER_OR_VIEWOFS(it);
 
                        if(closest_target)
                        {
                                vector closest_target_center = CENTER_OR_VIEWOFS(closest_target);
-                               if(vlen2(ent_center - head_center) < vlen2(ent_center - closest_target_center))
+                               if(vlen2(my_center - targ_center) < vlen2(my_center - closest_target_center))
                                        { closest_target = it; }
                        }
                        else { closest_target = it; }
@@ -146,43 +144,43 @@ entity Monster_FindTarget(entity mon)
        return closest_target;
 }
 
-void monster_setupcolors(entity mon)
+void monster_setupcolors(entity this)
 {
-       if(IS_PLAYER(mon.realowner))
-               mon.colormap = mon.realowner.colormap;
-       else if(teamplay && mon.team)
-               mon.colormap = 1024 + (mon.team - 1) * 17;
+       if(IS_PLAYER(this.realowner))
+               this.colormap = this.realowner.colormap;
+       else if(teamplay && this.team)
+               this.colormap = 1024 + (this.team - 1) * 17;
        else
        {
-               if(mon.monster_skill <= MONSTER_SKILL_EASY)
-                       mon.colormap = 1029;
-               else if(mon.monster_skill <= MONSTER_SKILL_MEDIUM)
-                       mon.colormap = 1027;
-               else if(mon.monster_skill <= MONSTER_SKILL_HARD)
-                       mon.colormap = 1038;
-               else if(mon.monster_skill <= MONSTER_SKILL_INSANE)
-                       mon.colormap = 1028;
-               else if(mon.monster_skill <= MONSTER_SKILL_NIGHTMARE)
-                       mon.colormap = 1032;
+               if(this.monster_skill <= MONSTER_SKILL_EASY)
+                       this.colormap = 1029;
+               else if(this.monster_skill <= MONSTER_SKILL_MEDIUM)
+                       this.colormap = 1027;
+               else if(this.monster_skill <= MONSTER_SKILL_HARD)
+                       this.colormap = 1038;
+               else if(this.monster_skill <= MONSTER_SKILL_INSANE)
+                       this.colormap = 1028;
+               else if(this.monster_skill <= MONSTER_SKILL_NIGHTMARE)
+                       this.colormap = 1032;
                else
-                       mon.colormap = 1024;
+                       this.colormap = 1024;
        }
 }
 
-void monster_changeteam(entity ent, float newteam)
+void monster_changeteam(entity this, int newteam)
 {
        if(!teamplay) { return; }
 
-       ent.team = newteam;
-       ent.monster_attack = true; // new team, activate attacking
-       monster_setupcolors(ent);
+       this.team = newteam;
+       this.monster_attack = true; // new team, activate attacking
+       monster_setupcolors(this);
 
-       if(ent.sprite)
+       if(this.sprite)
        {
-               WaypointSprite_UpdateTeamRadar(ent.sprite, RADARICON_DANGER, ((newteam) ? Team_ColorRGB(newteam) : '1 0 0'));
+               WaypointSprite_UpdateTeamRadar(this.sprite, RADARICON_DANGER, ((newteam) ? Team_ColorRGB(newteam) : '1 0 0'));
 
-               ent.sprite.team = newteam;
-               ent.sprite.SendFlags |= 1;
+               this.sprite.team = newteam;
+               this.sprite.SendFlags |= 1;
        }
 }
 
@@ -295,10 +293,9 @@ void Monster_Sounds_Clear(entity this)
 
 bool Monster_Sounds_Load(entity this, string f, int first)
 {
-       float fh;
        string s;
        var .string field;
-       fh = fopen(f, FILE_READ);
+       float fh = fopen(f, FILE_READ);
        if(fh < 0)
        {
                LOG_TRACE("Monster sound file not found: ", f);
@@ -330,7 +327,7 @@ void Monster_Sounds_Update(entity this)
                Monster_Sounds_Load(this, get_monster_model_datafilename(this.model, 0, "sounds"), 0);
 }
 
-void Monster_Sound(entity this, .string samplefield, float sound_delay, float delaytoo, float chan)
+void Monster_Sound(entity this, .string samplefield, float sound_delay, bool delaytoo, float chan)
 {
        if(!autocvar_g_monsters_sounds) { return; }
 
@@ -384,7 +381,7 @@ bool Monster_Attack_Leap_Check(entity this, vector vel)
        this.velocity = vel;
        tracetoss(this, this);
        this.velocity = old;
-       if (trace_ent != this.enemy)
+       if(trace_ent != this.enemy)
                return false;
 
        return true;
@@ -397,12 +394,12 @@ bool Monster_Attack_Leap(entity this, vector anm, void(entity this, entity touch
 
        setanim(this, anm, false, true, false);
 
-       if(this.animstate_endtime > time && (this.flags & FL_MONSTER))
+       if(this.animstate_endtime > time && IS_MONSTER(this))
                this.attack_finished_single[0] = this.anim_finished = this.animstate_endtime;
        else
                this.attack_finished_single[0] = this.anim_finished = time + animtime;
 
-       if(this.flags & FL_MONSTER)
+       if(IS_MONSTER(this))
                this.state = MONSTER_ATTACK_RANGED;
        settouch(this, touchfunc);
        this.origin_z += 1;
@@ -414,14 +411,14 @@ bool Monster_Attack_Leap(entity this, vector anm, void(entity this, entity touch
 
 void Monster_Attack_Check(entity this, entity targ)
 {
-       if((this == NULL || targ == NULL)
+       if((!this || !targ)
        || (!this.monster_attackfunc)
        || (time < this.attack_finished_single[0])
        ) { return; }
 
        if(vdist(targ.origin - this.origin, <=, this.attack_range))
        {
-               bool attack_success = this.monster_attackfunc(MONSTER_ATTACK_MELEE, this, targ);
+               int attack_success = this.monster_attackfunc(MONSTER_ATTACK_MELEE, this, targ);
                if(attack_success == 1)
                        Monster_Sound(this, monstersound_melee, 0, false, CH_VOICE);
                else if(attack_success > 0)
@@ -430,7 +427,7 @@ void Monster_Attack_Check(entity this, entity targ)
 
        if(vdist(targ.origin - this.origin, >, this.attack_range))
        {
-               float attack_success = this.monster_attackfunc(MONSTER_ATTACK_RANGED, this, targ);
+               int attack_success = this.monster_attackfunc(MONSTER_ATTACK_RANGED, this, targ);
                if(attack_success == 1)
                        Monster_Sound(this, monstersound_melee, 0, false, CH_VOICE);
                else if(attack_success > 0)
@@ -458,7 +455,7 @@ void Monster_UpdateModel(entity this)
        this.anim_die2   = animfixfps(this, '9 1 0.01', '0 0 0');*/
 
        // then get the real values
-       Monster mon = get_monsterinfo(this.monsterid);
+       Monster mon = Monsters_from(this.monsterid);
        mon.mr_anim(mon, this);
 }
 
@@ -554,7 +551,8 @@ vector Monster_Move_Target(entity this, entity targ)
                targ_origin = WarpZone_RefSys_TransformOrigin(this.enemy, this, targ_origin); // origin of target as seen by the monster (us)
                WarpZone_TraceLine(this.origin, targ_origin, MOVE_NOMONSTERS, this);
 
-               if((this.enemy == NULL)
+               // cases where the enemy may have changed their state (don't need to check everything here)
+               if((!this.enemy)
                        || (IS_DEAD(this.enemy) || this.enemy.health < 1)
                        || (STAT(FROZEN, this.enemy))
                        || (this.enemy.flags & FL_NOTARGET)
@@ -695,8 +693,6 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed)
        // update goal entity if lost
        if(this.target2 && this.goalentity.targetname != this.target2) { this.goalentity = find(NULL, targetname, this.target2); }
 
-       entity targ;
-
        if(STAT(FROZEN, this) == 2)
        {
                this.revive_progress = bound(0, this.revive_progress + this.ticrate * this.revive_speed, 1);
@@ -781,7 +777,7 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed)
                }
        }
 
-       targ = this.goalentity;
+       entity targ = this.goalentity;
 
        if (MUTATOR_CALLHOOK(MonsterMove, this, runspeed, walkspeed, targ)
                || gameover
@@ -802,8 +798,7 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed)
        runspeed = bound(0, M_ARGV(1, float) * MONSTER_SKILLMOD(this), runspeed * 2.5); // limit maxspeed to prevent craziness
        walkspeed = bound(0, M_ARGV(2, float) * MONSTER_SKILLMOD(this), walkspeed * 2.5); // limit maxspeed to prevent craziness
 
-       if(teamplay)
-       if(autocvar_g_monsters_teams)
+       if(teamplay && autocvar_g_monsters_teams)
        if(DIFF_TEAM(this.monster_follow, this))
                this.monster_follow = NULL;
 
@@ -855,13 +850,12 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed)
 
        if(vdist(this.origin - this.moveto, >, 100))
        {
-               float do_run = (this.enemy || this.monster_moveto);
+               bool do_run = (this.enemy || this.monster_moveto);
                if(IS_ONGROUND(this) || ((this.flags & FL_FLY) || (this.flags & FL_SWIM)))
                        Monster_CalculateVelocity(this, this.moveto, this.origin, true, ((do_run) ? runspeed : walkspeed));
 
-               if(time > this.pain_finished) // TODO: use anim_finished instead!
+               if(time > this.pain_finished && time > this.anim_finished) // TODO: use anim_finished instead!?
                if(!this.state)
-               if(time > this.anim_finished)
                if(vdist(this.velocity, >, 10))
                        setanim(this, ((do_run) ? this.anim_run : this.anim_walk), true, false, false);
                else
@@ -876,8 +870,7 @@ void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed)
                        this.target2 = e.target;
 
                movelib_brake_simple(this, stpspeed);
-               if(time > this.anim_finished)
-               if(time > this.pain_finished)
+               if(time > this.anim_finished && time > this.pain_finished)
                if(!this.state)
                if(vdist(this.velocity, <=, 30))
                        setanim(this, this.anim_idle, true, false, false);
@@ -1032,7 +1025,7 @@ void Monster_Dead(entity this, entity attacker, float gibbed)
 
        CSQCModel_UnlinkEntity(this);
 
-       Monster mon = get_monsterinfo(this.monsterid);
+       Monster mon = Monsters_from(this.monsterid);
        mon.mr_death(mon, this);
 
        if(this.candrop && this.weapon)
@@ -1056,14 +1049,11 @@ void Monster_Damage(entity this, entity inflictor, entity attacker, float damage
        if(deathtype == DEATH_FALL.m_id && this.draggedby != NULL)
                return;
 
-       vector v;
-       float take, save;
-
-       v = healtharmor_applydamage(100, this.armorvalue / 100, deathtype, damage);
-       take = v_x;
-       save = v_y;
+       vector v = healtharmor_applydamage(100, this.armorvalue / 100, deathtype, damage);
+       float take = v.x;
+       //float save = v.y;
 
-       Monster mon = get_monsterinfo(this.monsterid);
+       Monster mon = Monsters_from(this.monsterid);
        take = mon.mr_pain(mon, this, take, attacker, deathtype);
 
        if(take)
@@ -1160,8 +1150,7 @@ void Monster_Move_2D(entity this, float mspeed, bool allow_jumpoff)
 
        movelib_move_simple_gravity(this, v_forward, mspeed, 1);
 
-       if(time > this.pain_finished)
-       if(time > this.attack_finished_single[0])
+       if(time > this.pain_finished && time > this.attack_finished_single[0])
        if(vdist(this.velocity, >, 10))
                setanim(this, this.anim_walk, true, false, false);
        else
@@ -1210,14 +1199,13 @@ void Monster_Think(entity this)
        setthink(this, Monster_Think);
        this.nextthink = time + this.ticrate;
 
-       if(this.monster_lifetime)
-       if(time >= this.monster_lifetime)
+       if(this.monster_lifetime && time >= this.monster_lifetime)
        {
                Damage(this, this, this, this.health + this.max_health, DEATH_KILL.m_id, this.origin, this.origin);
                return;
        }
 
-       Monster mon = get_monsterinfo(this.monsterid);
+       Monster mon = Monsters_from(this.monsterid);
        if(mon.mr_think(mon, this))
                Monster_Move(this, this.speed2, this.speed, this.stopspeed);
 
index 7736fa7b30a1dea2d07f6305a5f55db19ef90b88..1efa4cbdc1d221d0a19adc9c33cb6f048706bb7e 100644 (file)
@@ -11,7 +11,7 @@ GETTER(float, instagib_respawntimejitter_ammo)
 
 #ifdef GAMEQC
 MODEL(VaporizerCells_ITEM, Item_Model("a_cells.md3"));
-SOUND(VaporizerCells, "misc/itempickup");
+SOUND(VaporizerCells, Item_Sound("itempickup"));
 #endif
 
 REGISTER_ITEM(VaporizerCells, Ammo) {
@@ -31,7 +31,7 @@ REGISTER_ITEM(VaporizerCells, Ammo) {
 
 #ifdef GAMEQC
 MODEL(ExtraLife_ITEM, Item_Model("g_h100.md3"));
-SOUND(ExtraLife, "misc/megahealth");
+SOUND(ExtraLife, Item_Sound("megahealth"));
 #endif
 
 REGISTER_ITEM(ExtraLife, Powerup) {
@@ -49,7 +49,7 @@ REGISTER_ITEM(ExtraLife, Powerup) {
 
 #ifdef GAMEQC
 MODEL(Invisibility_ITEM, Item_Model("g_strength.md3"));
-SOUND(Invisibility, "misc/powerup");
+SOUND(Invisibility, Item_Sound("powerup"));
 #endif
 
 REGISTER_ITEM(Invisibility, Powerup) {
@@ -67,7 +67,7 @@ REGISTER_ITEM(Invisibility, Powerup) {
 
 #ifdef GAMEQC
 MODEL(Speed_ITEM, Item_Model("g_invincible.md3"));
-SOUND(Speed, "misc/powerup_shield");
+SOUND(Speed, Item_Sound("powerup_shield"));
 #endif
 
 REGISTER_ITEM(Speed, Powerup) {
index b76d22e95b51e5a1409a365159ab1e2261136c33..3db867a5b9418655c8a96b3be6e7119bd26227bf 100644 (file)
@@ -49,18 +49,18 @@ float autocvar_hud_panel_itemstime_progressbar_maxtime = 30;
 string autocvar_hud_panel_itemstime_progressbar_name = "progressbar";
 float autocvar_hud_panel_itemstime_progressbar_reduced;
 bool autocvar_hud_panel_itemstime_hidespawned = 1;
-bool autocvar_hud_panel_itemstime_hidelarge = false;
+bool autocvar_hud_panel_itemstime_hidebig = false;
 int autocvar_hud_panel_itemstime_text = 1;
-#define hud_panel_itemstime_hidelarge autocvar_hud_panel_itemstime_hidelarge
+#define hud_panel_itemstime_hidebig autocvar_hud_panel_itemstime_hidebig
 #else
-#define hud_panel_itemstime_hidelarge false
+#define hud_panel_itemstime_hidebig false
 #endif
 
 bool Item_ItemsTime_SpectatorOnly(GameItem it)
 {
     return (false
-    || it == ITEM_ArmorMega     || (it == ITEM_ArmorLarge && !hud_panel_itemstime_hidelarge)
-    || it == ITEM_HealthMega    || (it == ITEM_HealthLarge && !hud_panel_itemstime_hidelarge)
+    || it == ITEM_ArmorMega     || (it == ITEM_ArmorBig && !hud_panel_itemstime_hidebig)
+    || it == ITEM_HealthMega    || (it == ITEM_HealthBig && !hud_panel_itemstime_hidebig)
     );
 }
 
index 143b3c6edf63200089fd825c41508f636a18905a..76e735e5505b482a34df8cd32d09847a6a21b58b 100644 (file)
@@ -256,7 +256,7 @@ MUTATOR_HOOKFUNCTION(nix, PlayerPreThink)
 {
        entity player = M_ARGV(0, entity);
 
-       if(!intermission_running)
+       if(!gameover)
        if(!IS_DEAD(player))
        if(IS_PLAYER(player))
                NIX_GiveCurrentWeapon(player);
index 21a191a0e67c82b080d962ec034fa668fa997324..56bc8d14cce8d4fad53d010fd57ecea83fa17e1d 100644 (file)
@@ -11,7 +11,7 @@ float autocvar_g_overkill_ammo_charge_limit;
 bool autocvar_g_overkill_filter_healthmega;
 bool autocvar_g_overkill_filter_armormedium;
 bool autocvar_g_overkill_filter_armorbig;
-bool autocvar_g_overkill_filter_armorlarge;
+bool autocvar_g_overkill_filter_armormega;
 
 .float ok_lastwep;
 .float ok_item;
@@ -164,7 +164,7 @@ MUTATOR_HOOKFUNCTION(ok, ForbidThrowCurrentWeapon)
 
 MUTATOR_HOOKFUNCTION(ok, PlayerPreThink)
 {
-       if(intermission_running || gameover)
+       if(gameover)
                return;
 
        entity player = M_ARGV(0, entity);
@@ -312,10 +312,8 @@ MUTATOR_HOOKFUNCTION(ok, FilterItem)
        {
                case ITEM_HealthMega: return autocvar_g_overkill_filter_healthmega;
                case ITEM_ArmorMedium: return autocvar_g_overkill_filter_armormedium;
-               // WARNING: next two statements look wrong because of inconsistency between cvar names and code
-               // armor cvars need renaming to be consistent with their health counterparts
-               case ITEM_ArmorLarge: return autocvar_g_overkill_filter_armorbig;
-               case ITEM_ArmorMega: return autocvar_g_overkill_filter_armorlarge;
+               case ITEM_ArmorBig: return autocvar_g_overkill_filter_armorbig;
+               case ITEM_ArmorMega: return autocvar_g_overkill_filter_armormega;
        }
 
        return true;
index 0fb3d6139c64ff3f60750188f0a501a2c821f548..73f22b836ce6485c9a5e9164e96bf5238a14e95e 100644 (file)
@@ -14,7 +14,6 @@ REGISTER_WAYPOINT(RaceFinish, _("Finish"), '1 0.5 0', 1);
 REGISTER_WAYPOINT(RaceStart, _("Start"), '1 0.5 0', 1);
 REGISTER_WAYPOINT(RaceStartFinish, _("Start"), '1 0.5 0', 1);
 
-REGISTER_WAYPOINT(Assault, _("<placeholder>"), '1 0.5 0', 1);
 REGISTER_WAYPOINT(AssaultDefend, _("Defend"), '1 0.5 0', 1);
 REGISTER_WAYPOINT(AssaultDestroy, _("Destroy"), '1 0.5 0', 1);
 REGISTER_WAYPOINT(AssaultPush, _("Push"), '1 0.5 0', 1);
index a26441ee6e425118186595bf4fdcc3479a2dfa7a..bcb317b4abe305562183dfd2456c51e994d93acf 100644 (file)
@@ -282,10 +282,10 @@ void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, ve
 
     // rotate them, and make them absolute
     rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
-    v1 = rotate(v1, rot) + org;
-    v2 = rotate(v2, rot) + org;
-    v3 = rotate(v3, rot) + org;
-    v4 = rotate(v4, rot) + org;
+    v1 = Rotate(v1, rot) + org;
+    v2 = Rotate(v2, rot) + org;
+    v3 = Rotate(v3, rot) + org;
+    v4 = Rotate(v4, rot) + org;
 
     // draw them
     R_BeginPolygon(pic, f);
@@ -319,9 +319,9 @@ void drawhealthbar(vector org, float rot, float h, vector sz, vector hotspot, fl
     up = '0 1 0';
 
     rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
-    o = rotate(o, rot) + org;
-    ri = rotate(ri, rot);
-    up = rotate(up, rot);
+    o = Rotate(o, rot) + org;
+    ri = Rotate(ri, rot);
+    up = Rotate(up, rot);
 
     owidth = width + 2 * border;
     o = o - up * (margin + border + theheight) + ri * (sz.x - owidth) * 0.5;
@@ -348,19 +348,19 @@ vector drawspritearrow(vector o, float ang, vector rgb, float a, float t)
 
     R_BeginPolygon("", DRAWFLAG_NORMAL);
     R_PolygonVertex(o,                                  '0 0 0', '0 0 0', a);
-    R_PolygonVertex(o + rotate(arrowY  - borderX, ang), '0 0 0', '0 0 0', a);
-    R_PolygonVertex(o + rotate(borderY - borderX, ang), '0 0 0', '0 0 0', a);
-    R_PolygonVertex(o + rotate(borderY + borderX, ang), '0 0 0', '0 0 0', a);
-    R_PolygonVertex(o + rotate(arrowY  + borderX, ang), '0 0 0', '0 0 0', a);
+    R_PolygonVertex(o + Rotate(arrowY  - borderX, ang), '0 0 0', '0 0 0', a);
+    R_PolygonVertex(o + Rotate(borderY - borderX, ang), '0 0 0', '0 0 0', a);
+    R_PolygonVertex(o + Rotate(borderY + borderX, ang), '0 0 0', '0 0 0', a);
+    R_PolygonVertex(o + Rotate(arrowY  + borderX, ang), '0 0 0', '0 0 0', a);
     R_EndPolygon();
 
     R_BeginPolygon("", DRAWFLAG_ADDITIVE);
-    R_PolygonVertex(o + rotate(eY * borderDiag, ang), '0 0 0', rgb, a);
-    R_PolygonVertex(o + rotate(arrowY - arrowX, ang), '0 0 0', rgb, a);
-    R_PolygonVertex(o + rotate(arrowY + arrowX, ang), '0 0 0', rgb, a);
+    R_PolygonVertex(o + Rotate(eY * borderDiag, ang), '0 0 0', rgb, a);
+    R_PolygonVertex(o + Rotate(arrowY - arrowX, ang), '0 0 0', rgb, a);
+    R_PolygonVertex(o + Rotate(arrowY + arrowX, ang), '0 0 0', rgb, a);
     R_EndPolygon();
 
-    return o + rotate(eY * (borderDiag+size+margin), ang);
+    return o + Rotate(eY * (borderDiag+size+margin), ang);
 }
 
 // returns location of sprite healthbar
index a6431cf673810c1625552fc2418c644738c3e8ad..92fd5df1ac37330b1479044e7ef1cb61280d3930 100644 (file)
 
     MSG_CENTER_NOTIF(ASSAULT_ATTACKING,                 1,      0, 0, "",               CPID_ASSAULT_ROLE,      "0 0",  _("^BGYou are attacking!"), "")
     MSG_CENTER_NOTIF(ASSAULT_DEFENDING,                 1,      0, 0, "",               CPID_ASSAULT_ROLE,      "0 0",  _("^BGYou are defending!"), "")
+    MSG_CENTER_NOTIF(ASSAULT_OBJ_DESTROYED,             1,      0, 1, "f1time",         CPID_ASSAULT_ROLE,      "0 0",  _("^BGObjective destroyed in ^F4%s^BG!"), "")
 
     MSG_CENTER_NOTIF(COUNTDOWN_BEGIN,                   1,      0, 0, "",               CPID_ROUND,             "2 0",  _("^F4Begin!"), "")
     MSG_CENTER_NOTIF(COUNTDOWN_GAMESTART,               1,      0, 1, "",               CPID_ROUND,             "1 f1", _("^F4Game starts in ^COUNT"), "")
index 26454152270150477da3a12c6edb48c22d6be231..6e6dd9fb01b3e44530ca1bc58cdce987d979d426 100644 (file)
@@ -803,5 +803,10 @@ void CSQC_ClientMovement_PlayerMove_Frame(entity this)
 
 #ifdef SVQC
        this.pm_frametime = frametime;
+#elif defined(CSQC)
+       if((ITEMS_STAT(this) & IT_USING_JETPACK) && !IS_DEAD(this) && !intermission)
+               this.csqcmodel_modelflags |= MF_ROCKET;
+       else
+               this.csqcmodel_modelflags &= ~MF_ROCKET;
 #endif
 }
index 99e377e6464f2b91cb5e448e13849038ed1904fb..7462239f7701d88886e59387b5dec24d3721996b 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "../teams.qh"
 string W_Sound(string w_snd);
+string Item_Sound(string it_snd);
 
 SOUND(ARC_FIRE, W_Sound("arc_fire"));
 SOUND(ARC_LOOP, W_Sound("arc_loop"));
@@ -236,20 +237,20 @@ SOUND(NADE_BEEP, "overkill/grenadebip");
 
 SOUND(BUFF_LOST, "relics/relic_effect");
 
-SOUND(POWEROFF, "misc/poweroff");
-SOUND(POWERUP, "misc/powerup");
-SOUND(SHIELD_RESPAWN, "misc/shield_respawn");
-SOUND(STRENGTH_RESPAWN, "misc/strength_respawn");
+SOUND(POWEROFF, Item_Sound("poweroff"));
+SOUND(POWERUP, Item_Sound("powerup"));
+SOUND(SHIELD_RESPAWN, Item_Sound("shield_respawn"));
+SOUND(STRENGTH_RESPAWN, Item_Sound("strength_respawn"));
 
-SOUND(ARMOR25, "misc/armor25");
+SOUND(ARMOR25, Item_Sound("armor25"));
 SOUND(ARMORIMPACT, "misc/armorimpact");
 SOUND(BODYIMPACT1, "misc/bodyimpact1");
 SOUND(BODYIMPACT2, "misc/bodyimpact2");
 
-SOUND(ITEMPICKUP, "misc/itempickup");
-SOUND(ITEMRESPAWNCOUNTDOWN, "misc/itemrespawncountdown");
-SOUND(ITEMRESPAWN, "misc/itemrespawn");
-SOUND(MEGAHEALTH, "misc/megahealth");
+SOUND(ITEMPICKUP, Item_Sound("itempickup"));
+SOUND(ITEMRESPAWNCOUNTDOWN, Item_Sound("itemrespawncountdown"));
+SOUND(ITEMRESPAWN, Item_Sound("itemrespawn"));
+SOUND(MEGAHEALTH, Item_Sound("megahealth"));
 
 SOUND(LAVA, "player/lava");
 SOUND(SLIME, "player/slime");
index 5816d5ad198dfe27dcb6de687e32e1e30a9f76cc..edfa47fd417625ea24758a442ea44c720dbefe91 100644 (file)
@@ -44,14 +44,14 @@ const int MAX_CL_STATS = 256;
 REGISTER_STAT(WEAPONS, vectori)
 REGISTER_STAT(WEAPONSINMAP, vectori)
 
-REGISTER_STAT(PL_VIEW_OFS, vector, autocvar_sv_player_viewoffset)
-REGISTER_STAT(PL_CROUCH_VIEW_OFS, vector, autocvar_sv_player_crouch_viewoffset)
+REGISTER_STAT(PL_VIEW_OFS, vector)
+REGISTER_STAT(PL_CROUCH_VIEW_OFS, vector)
 
-REGISTER_STAT(PL_MIN, vector, autocvar_sv_player_mins)
-REGISTER_STAT(PL_CROUCH_MIN, vector, autocvar_sv_player_crouch_mins)
+REGISTER_STAT(PL_MIN, vector)
+REGISTER_STAT(PL_CROUCH_MIN, vector)
 
-REGISTER_STAT(PL_MAX, vector, autocvar_sv_player_maxs)
-REGISTER_STAT(PL_CROUCH_MAX, vector, autocvar_sv_player_crouch_maxs)
+REGISTER_STAT(PL_MAX, vector)
+REGISTER_STAT(PL_CROUCH_MAX, vector)
 
 REGISTER_STAT(KH_KEYS, int)
 
@@ -63,9 +63,10 @@ REGISTER_STAT(WEAPON_NEXTTHINK, float)
 #ifdef SVQC
 SPECTATE_COPYFIELD(_STAT(WEAPON_NEXTTHINK))
 float W_WeaponRateFactor(entity this);
+float gameover;
 #endif
 REGISTER_STAT(WEAPONRATEFACTOR, float, W_WeaponRateFactor(this))
-
+REGISTER_STAT(GAMEOVER, int, gameover)
 REGISTER_STAT(GAMESTARTTIME, float)
 REGISTER_STAT(STRENGTH_FINISHED, float)
 REGISTER_STAT(INVINCIBLE_FINISHED, float)
index 2f1a4c3aa6b7e4087a9de95a8136ade2204d54a5..19aa6ba54aa3136348469a5cf5912a0a077849a3 100644 (file)
@@ -1346,17 +1346,17 @@ spawnfunc(item_armor_big)
                this.max_armorvalue = g_pickup_armorbig_max;
        if(!this.pickup_anyway)
                this.pickup_anyway = g_pickup_armorbig_anyway;
-       StartItem(this, ITEM_ArmorLarge);
+       StartItem(this, ITEM_ArmorBig);
 }
 
-spawnfunc(item_armor_large)
+spawnfunc(item_armor_mega)
 {
        if(!this.armorvalue)
-               this.armorvalue = g_pickup_armorlarge;
+               this.armorvalue = g_pickup_armormega;
        if(!this.max_armorvalue)
-               this.max_armorvalue = g_pickup_armorlarge_max;
+               this.max_armorvalue = g_pickup_armormega_max;
        if(!this.pickup_anyway)
-               this.pickup_anyway = g_pickup_armorlarge_anyway;
+               this.pickup_anyway = g_pickup_armormega_anyway;
        StartItem(this, ITEM_ArmorMega);
 }
 
@@ -1382,15 +1382,15 @@ spawnfunc(item_health_medium)
     StartItem(this, ITEM_HealthMedium);
 }
 
-spawnfunc(item_health_large)
+spawnfunc(item_health_big)
 {
        if(!this.max_health)
-               this.max_health = g_pickup_healthlarge_max;
+               this.max_health = g_pickup_healthbig_max;
        if(!this.health)
-               this.health = g_pickup_healthlarge;
+               this.health = g_pickup_healthbig;
        if(!this.pickup_anyway)
-               this.pickup_anyway = g_pickup_healthlarge_anyway;
-       StartItem(this, ITEM_HealthLarge);
+               this.pickup_anyway = g_pickup_healthbig_anyway;
+       StartItem(this, ITEM_HealthBig);
 }
 
 spawnfunc(item_health_mega)
@@ -1406,9 +1406,11 @@ spawnfunc(item_health_mega)
 
 // support old misnamed entities
 spawnfunc(item_armor1) { spawnfunc_item_armor_small(this); }  // FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
-spawnfunc(item_armor25) { spawnfunc_item_armor_large(this); }
+spawnfunc(item_armor25) { spawnfunc_item_armor_mega(this); }
+spawnfunc(item_armor_large) { spawnfunc_item_armor_mega(this); }
 spawnfunc(item_health1) { spawnfunc_item_health_small(this); }
 spawnfunc(item_health25) { spawnfunc_item_health_medium(this); }
+spawnfunc(item_health_large) { spawnfunc_item_health_big(this); }
 spawnfunc(item_health100) { spawnfunc_item_health_mega(this); }
 
 spawnfunc(item_strength)
index 498f0ff2dbbffb885c36a546ff7f4faba2bac378..edbe9c580a28ec33d50314236a3346f58feed121 100644 (file)
@@ -130,23 +130,14 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
        return sdir * vs + '0 0 1' * vz;
 }
 
-void trigger_push_touch(entity this, entity toucher)
+bool jumppad_push(entity this, entity targ)
 {
-       if (this.active == ACTIVE_NOT)
-               return;
-
-       if (!isPushable(toucher))
-               return;
-
-       if(this.team)
-               if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, toucher)))
-                       return;
-
-       EXACTTRIGGER_TOUCH(this, toucher);
+       if (!isPushable(targ))
+               return false;
 
        if(this.enemy)
        {
-               toucher.velocity = trigger_push_calculatevelocity(toucher.origin, this.enemy, this.height);
+               targ.velocity = trigger_push_calculatevelocity(targ.origin, this.enemy, this.height);
        }
        else if(this.target && this.target != "")
        {
@@ -159,105 +150,117 @@ void trigger_push_touch(entity this, entity toucher)
                        else
                                RandomSelection_AddEnt(e, 1, 1);
                }
-               toucher.velocity = trigger_push_calculatevelocity(toucher.origin, RandomSelection_chosen_ent, this.height);
+               targ.velocity = trigger_push_calculatevelocity(targ.origin, RandomSelection_chosen_ent, this.height);
        }
        else
        {
-               toucher.velocity = this.movedir;
+               targ.velocity = this.movedir;
        }
 
-       UNSET_ONGROUND(toucher);
+       UNSET_ONGROUND(targ);
 
 #ifdef CSQC
-       if (toucher.flags & FL_PROJECTILE)
+       if (targ.flags & FL_PROJECTILE)
        {
-               toucher.angles = vectoangles (toucher.velocity);
-               switch(toucher.move_movetype)
+               targ.angles = vectoangles (targ.velocity);
+               switch(targ.move_movetype)
                {
                        case MOVETYPE_FLY:
-                               set_movetype(toucher, MOVETYPE_TOSS);
-                               toucher.gravity = 1;
+                               set_movetype(targ, MOVETYPE_TOSS);
+                               targ.gravity = 1;
                                break;
                        case MOVETYPE_BOUNCEMISSILE:
-                               set_movetype(toucher, MOVETYPE_BOUNCE);
-                               toucher.gravity = 1;
+                               set_movetype(targ, MOVETYPE_BOUNCE);
+                               targ.gravity = 1;
                                break;
                }
        }
 #endif
 
 #ifdef SVQC
-       if (IS_PLAYER(toucher))
+       if (IS_PLAYER(targ))
        {
                // reset tracking of oldvelocity for impact damage (sudden velocity changes)
-               toucher.oldvelocity = toucher.velocity;
+               targ.oldvelocity = targ.velocity;
 
                if(this.pushltime < time)  // prevent "snorring" sound when a player hits the jumppad more than once
                {
                        // flash when activated
-                       Send_Effect(EFFECT_JUMPPAD, toucher.origin, toucher.velocity, 1);
-                       _sound (toucher, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
+                       Send_Effect(EFFECT_JUMPPAD, targ.origin, targ.velocity, 1);
+                       _sound (targ, CH_TRIGGER, this.noise, VOL_BASE, ATTEN_NORM);
                        this.pushltime = time + 0.2;
                }
-               if(IS_REAL_CLIENT(toucher) || IS_BOT_CLIENT(toucher))
+               if(IS_REAL_CLIENT(targ) || IS_BOT_CLIENT(targ))
                {
                        bool found = false;
-                       for(int i = 0; i < toucher.jumppadcount && i < NUM_JUMPPADSUSED; ++i)
-                               if(toucher.(jumppadsused[i]) == this)
+                       for(int i = 0; i < targ.jumppadcount && i < NUM_JUMPPADSUSED; ++i)
+                               if(targ.(jumppadsused[i]) == this)
                                        found = true;
                        if(!found)
                        {
-                               toucher.(jumppadsused[toucher.jumppadcount % NUM_JUMPPADSUSED]) = this;
-                               toucher.jumppadcount = toucher.jumppadcount + 1;
+                               targ.(jumppadsused[targ.jumppadcount % NUM_JUMPPADSUSED]) = this;
+                               targ.jumppadcount = targ.jumppadcount + 1;
                        }
 
-                       if(IS_REAL_CLIENT(toucher))
+                       if(IS_REAL_CLIENT(targ))
                        {
                                if(this.message)
-                                       centerprint(toucher, this.message);
+                                       centerprint(targ, this.message);
                        }
                        else
-                               toucher.lastteleporttime = time;
+                               targ.lastteleporttime = time;
 
-                       if (!IS_DEAD(toucher))
-                               animdecide_setaction(toucher, ANIMACTION_JUMP, true);
+                       if (!IS_DEAD(targ))
+                               animdecide_setaction(targ, ANIMACTION_JUMP, true);
                }
                else
-                       toucher.jumppadcount = true;
+                       targ.jumppadcount = true;
 
                // reset tracking of who pushed you into a hazard (for kill credit)
-               toucher.pushltime = 0;
-               toucher.istypefrag = 0;
+               targ.pushltime = 0;
+               targ.istypefrag = 0;
        }
 
        if(this.enemy.target)
-               SUB_UseTargets(this.enemy, toucher, toucher); // TODO: do we need toucher as trigger too?
+               SUB_UseTargets(this.enemy, targ, targ); // TODO: do we need targ as trigger too?
 
-       if (toucher.flags & FL_PROJECTILE)
+       if (targ.flags & FL_PROJECTILE)
        {
-               toucher.angles = vectoangles (toucher.velocity);
-               toucher.com_phys_gravity_factor = 1;
-               switch(toucher.move_movetype)
+               targ.angles = vectoangles (targ.velocity);
+               targ.com_phys_gravity_factor = 1;
+               switch(targ.move_movetype)
                {
                        case MOVETYPE_FLY:
-                               set_movetype(toucher, MOVETYPE_TOSS);
-                               toucher.gravity = 1;
+                               set_movetype(targ, MOVETYPE_TOSS);
+                               targ.gravity = 1;
                                break;
                        case MOVETYPE_BOUNCEMISSILE:
-                               set_movetype(toucher, MOVETYPE_BOUNCE);
-                               toucher.gravity = 1;
+                               set_movetype(targ, MOVETYPE_BOUNCE);
+                               targ.gravity = 1;
                                break;
                }
-               UpdateCSQCProjectile(toucher);
+               UpdateCSQCProjectile(targ);
        }
+#endif
 
-       /*if (toucher.flags & FL_ITEM)
-       {
-               ItemUpdate(toucher);
-               toucher.SendFlags |= ISF_DROP;
-       }*/
+       return true;
+}
+
+void trigger_push_touch(entity this, entity toucher)
+{
+       if (this.active == ACTIVE_NOT)
+               return;
 
-       if (this.spawnflags & PUSH_ONCE)
+       if(this.team)
+               if(((this.spawnflags & 4) == 0) == (DIFF_TEAM(this, toucher)))
+                       return;
+
+       EXACTTRIGGER_TOUCH(this, toucher);
+
+       noref bool success = jumppad_push(this, toucher);
+
+#ifdef SVQC
+       if (success && (this.spawnflags & PUSH_ONCE))
        {
                settouch(this, func_null);
                setthink(this, SUB_Remove);
@@ -272,17 +275,14 @@ void trigger_push_updatelink(entity this);
 #endif
 void trigger_push_findtarget(entity this)
 {
-       entity t;
-       vector org;
-
        // first calculate a typical start point for the jump
-       org = (this.absmin + this.absmax) * 0.5;
+       vector org = (this.absmin + this.absmax) * 0.5;
        org_z = this.absmax.z - STAT(PL_MIN, NULL).z;
 
        if (this.target)
        {
-               float n = 0;
-               for(t = NULL; (t = find(t, targetname, this.target)); )
+               int n = 0;
+               for(entity t = NULL; (t = find(t, targetname, this.target)); )
                {
                        ++n;
 #ifdef SVQC
@@ -328,7 +328,6 @@ void trigger_push_findtarget(entity this)
                delete(e);
        }
 
-       trigger_push_link(this);
        defer(this, 0.1, trigger_push_updatelink);
 #endif
 }
@@ -393,6 +392,8 @@ spawnfunc(trigger_push)
                this.noise = "misc/jumppad.wav";
        precache_sound (this.noise);
 
+       trigger_push_link(this); // link it now
+
        // this must be called to spawn the teleport waypoints for bots
        InitializeEntity(this, trigger_push_findtarget, INITPRIO_FINDTARGET);
 }
@@ -415,6 +416,11 @@ bool target_push_send(entity this, entity to, float sf)
        return true;
 }
 
+void target_push_use(entity this, entity actor, entity trigger)
+{
+       jumppad_push(this, actor);
+}
+
 void target_push_link(entity this)
 {
        BITSET_ASSIGN(this.effects, EF_NODEPTHTEST);
@@ -429,7 +435,18 @@ void target_push_init(entity this)
        target_push_link(this);
 }
 
-spawnfunc(target_push) { target_push_init(this); }
+void target_push_init2(entity this)
+{
+       if(this.target && this.target != "") // we have an old style pusher!
+       {
+               InitializeEntity(this, trigger_push_findtarget, INITPRIO_FINDTARGET);
+               this.use = target_push_use;
+       }
+
+       target_push_init(this); // normal push target behaviour can be combined with a legacy pusher?
+}
+
+spawnfunc(target_push) { target_push_init2(this); }
 spawnfunc(info_notnull) { target_push_init(this); }
 spawnfunc(target_position) { target_push_init(this); }
 
index 3f5f40435819d6de9b7f748eeb7724af411623c6..95cc74802ceab386bc8611a277e9c9f3bd4eec04 100644 (file)
@@ -391,7 +391,7 @@ bool bumblebee_pilot_frame(entity this, float dt)
        entity vehic = this.vehicle;
        return = true;
 
-       if(intermission_running)
+       if(gameover)
        {
                vehic.solid = SOLID_NOT;
                vehic.takedamage = DAMAGE_NO;
index 0cdfc8cb870b52960254e754c07f38c5c0dfaa0a..80c28a8ab9ac7eab11f3f0fbd29053ad072864c3 100644 (file)
@@ -151,7 +151,7 @@ bool racer_frame(entity this, float dt)
        entity vehic = this.vehicle;
        return = true;
 
-       if(intermission_running)
+       if(gameover)
        {
                vehic.solid = SOLID_NOT;
                vehic.takedamage = DAMAGE_NO;
index 1068e7430dd47a8cc36b008575f2077b98071d9e..7c433f9c76f69dce59cbdba280418880c8210fe1 100644 (file)
@@ -133,7 +133,7 @@ bool raptor_frame(entity this, float dt)
        entity vehic = this.vehicle;
        return = true;
 
-       if(intermission_running)
+       if(gameover)
        {
                vehic.solid = SOLID_NOT;
                vehic.takedamage = DAMAGE_NO;
index d99335a51c3bcdde3497a9f6cd2866fdfa87d4da..6ad46946d70927728dd7447d96d8314a907cc5f9 100644 (file)
@@ -48,7 +48,7 @@ bool spiderbot_frame(entity this, float dt)
        entity vehic = this.vehicle;
        return = true;
 
-       if(intermission_running)
+       if(gameover)
        {
                vehic.solid = SOLID_NOT;
                vehic.takedamage = DAMAGE_NO;
index bb363c12ef26ba5b5dd765200ed08f28dc99519f..0a887cfebb03c4544df88a8d0316bd6f8aa4ab8d 100644 (file)
@@ -101,7 +101,7 @@ noref vector _vec2;
 noref vector _vec3;
 #define vec3(_x, _y, _z) (_vec3.x = (_x), _vec3.y = (_y), _vec3.z = (_z), _vec3)
 
-vector rotate(vector v, float a)
+vector Rotate(vector v, float a)
 {
        float a_sin = sin(a), a_cos = cos(a);
        vector r = '0 0 0';
index f06038377561bb5fea908ac39e0e8e6c12370c00..aeb8c8c774d639fa11a2073135e343e9d8c78f33 100644 (file)
@@ -34,7 +34,7 @@ void XonoticHUDItemsTimeDialog_fill(entity me)
        me.TR(me);
                me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_itemstime_hidespawned", _("Hide spawned items")));
        me.TR(me);
-               me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_itemstime_hidelarge", _("Hide large armor and health")));
+               me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_itemstime_hidebig", _("Hide big armor and health")));
        me.TR(me);
                me.TD(me, 1, 4, e = makeXonoticCheckBox(0, "hud_panel_itemstime_dynamicsize", _("Dynamic size")));
 }
index 64957b92e09c0b7ea7b26e8955cebcc3e784a60f..dbe3197a7c97c0a6cbbe2e7e108281a4444adb5f 100644 (file)
@@ -54,6 +54,7 @@ void bot_endgame();
 bool bot_fixcount();
 void bot_list_commands();
 void bot_queuecommand(entity bot, string cmdstring);
+void bot_clear(entity this);
 void bot_relinkplayerlist();
 void bot_resetqueues();
 void bot_serverframe();
@@ -84,3 +85,6 @@ void waypoint_spawnforitem_force(entity e, vector org);
 void waypoint_spawnforteleporter(entity e, vector destination, float timetaken);
 void waypoint_spawnforteleporter_v(entity e, vector org, vector destination, float timetaken);
 entity waypoint_spawn(vector m1, vector m2, float f);
+
+.entity goalcurrent;
+void navigation_clearroute(entity this);
index 9d612ea2edb2ba19b34d7368e53b5af044ff6b1b..ed9070f9cdd60821538da821afdceab6a2405cab 100644 (file)
@@ -340,9 +340,8 @@ void bot_custom_weapon_priority_setup()
 
 void bot_endgame()
 {
-       entity e;
-       //dprint("bot_endgame\n");
-       e = bot_list;
+       bot_relinkplayerlist();
+       entity e = bot_list;
        while (e)
        {
                setcolor(e, e.bot_preferredcolors);
@@ -399,7 +398,7 @@ void bot_clientdisconnect(entity this)
        this.playerskin_freeme = string_null;
        if(this.bot_cmd_current)
                delete(this.bot_cmd_current);
-       if(bot_waypoint_queue_owner==this)
+       if(bot_waypoint_queue_owner == this)
                bot_waypoint_queue_owner = NULL;
 }
 
@@ -632,9 +631,42 @@ float bot_fixcount()
        return true;
 }
 
+void bot_remove_from_bot_list(entity this)
+{
+       entity e = bot_list;
+       entity prev_bot = NULL;
+       while (e)
+       {
+               if(e == this)
+               {
+                       if(!prev_bot)
+                               bot_list = this.nextbot;
+                       else
+                               prev_bot.nextbot = this.nextbot;
+                       if(bot_strategytoken == this)
+                       {
+                               bot_strategytoken = this.nextbot;
+                               bot_strategytoken_taken = true;
+                       }
+                       this.nextbot = NULL;
+                       break;
+               }
+               prev_bot = e;
+               e = e.nextbot;
+       }
+}
+
+void bot_clear(entity this)
+{
+       bot_remove_from_bot_list(this);
+       if(bot_waypoint_queue_owner == this)
+               bot_waypoint_queue_owner = NULL;
+       this.aistatus &= ~AI_STATUS_STUCK; // otherwise bot_waypoint_queue_owner will be set again to this by navigation_unstuck
+}
+
 void bot_serverframe()
 {
-       if (intermission_running)
+       if (gameover)
                return;
 
        if (time < 2)
index 0959307608d3239bd7405bc809c2352467fd1c6c..05c6a5ed9a0643b4a1d8232c70a13d96262009b9 100644 (file)
@@ -89,6 +89,7 @@ void bot_setnameandstuff(entity this);
 void bot_custom_weapon_priority_setup();
 void bot_endgame();
 void bot_relinkplayerlist();
+void bot_clear(entity this);
 void bot_clientdisconnect(entity this);
 void bot_clientconnect(entity this);
 void bot_removefromlargestteam();
index e599bb8bd6f15bfcb0ee20b25ceb4878c485bb2a..b23c15bcafdeccbfb0b4874f0d8cfe77f18c5aaa 100644 (file)
@@ -29,9 +29,12 @@ void havocbot_ai(entity this)
        if(bot_execute_commands(this))
                return;
 
-       if(this.goalcurrent)
-       if(wasfreed(this.goalcurrent))
+       while(this.goalcurrent && wasfreed(this.goalcurrent))
+       {
                navigation_poproute(this);
+               if(!this.goalcurrent)
+                       this.bot_strategytime = 0;
+       }
 
        if (bot_strategytoken == this)
        if (!bot_strategytoken_taken)
@@ -134,7 +137,7 @@ void havocbot_ai(entity this)
                //heading = this.velocity;
                //dprint(this.goalstack01.classname,etos(this.goalstack01),"\n");
                if(
-                       this.goalstack01 != this && this.goalstack01 != NULL && ((this.aistatus & AI_STATUS_RUNNING) == 0) &&
+                       this.goalstack01 != this && this.goalstack01 && !wasfreed(this.goalstack01) && ((this.aistatus & AI_STATUS_RUNNING) == 0) &&
                        !(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
                )
                        next = ((this.goalstack01.absmin + this.goalstack01.absmax) * 0.5) - (this.origin + this.view_ofs);
@@ -325,7 +328,7 @@ void havocbot_bunnyhop(entity this, vector dir)
                                        if(this.goalcurrent.classname=="waypoint")
                                        if (!(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL))
                                        if(fabs(gco.z - this.origin.z) < this.maxs.z - this.mins.z)
-                                       if(this.goalstack01!=NULL)
+                                       if(this.goalstack01 && !wasfreed(this.goalstack01))
                                        {
                                                gno = (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5;
                                                deviation = vectoangles(gno - this.origin) - vectoangles(gco - this.origin);
index 5092a65c664c4adcebc4753c279d386c6426cb08..19c0ed8e600337c22590dfda6342fb7fd91e226f 100644 (file)
@@ -893,7 +893,7 @@ void navigation_poptouchedgoals(entity this)
        }
 
        // If for some reason the bot is closer to the next goal, pop the current one
-       if(this.goalstack01)
+       if(this.goalstack01 && !wasfreed(this.goalstack01))
        if(vlen2(this.goalcurrent.origin - this.origin) > vlen2(this.goalstack01.origin - this.origin))
        if(checkpvs(this.origin + this.view_ofs, this.goalstack01))
        if(tracewalk(this, this.origin, this.mins, this.maxs, (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5, bot_navigation_movemode))
index f96099087b7b345ec65aa6e14fe5fead95e5509f..0d34ae3c24bc973d285c3ab07a0ab7713afbdac5 100644 (file)
@@ -485,6 +485,7 @@ float bot_cmd_impulse(entity this)
 
 float bot_cmd_continue(entity this)
 {
+       bot_relinkplayerlist();
        this.bot_exec_status &= ~BOT_EXEC_STATUS_PAUSED;
        return CMD_STATUS_FINISHED;
 }
@@ -991,6 +992,7 @@ float bot_cmd_pause(entity this)
        this.movement = '0 0 0';
        this.bot_cmd_keys = BOT_CMD_KEY_NONE;
 
+       bot_clear(this);
        this.bot_exec_status |= BOT_EXEC_STATUS_PAUSED;
        return CMD_STATUS_FINISHED;
 }
index c83d0f63c58dc2c4e3ebae76e9c50593ce85bd8c..0f8999a8d17f7cbb5c58017a28096c31b4178b9a 100644 (file)
 #include <lib/warpzone/common.qh>
 #include <lib/warpzone/util_server.qh>
 
+void waypoint_setupmodel(entity wp)
+{
+       if (autocvar_g_waypointeditor)
+       {
+               // TODO: add some sort of visible box in edit mode for box waypoints
+               vector m1 = wp.mins;
+               vector m2 = wp.maxs;
+               setmodel(wp, MDL_WAYPOINT);
+               setsize(wp, m1, m2);
+               wp.effects = EF_LOWPRECISION;
+               if (wp.wpflags & WAYPOINTFLAG_ITEM)
+                       wp.colormod = '1 0 0';
+               else if (wp.wpflags & WAYPOINTFLAG_GENERATED)
+                       wp.colormod = '1 1 0';
+               else
+                       wp.colormod = '1 1 1';
+       }
+       else
+               wp.model = "";
+}
+
 // create a new spawnfunc_waypoint and automatically link it to other waypoints, and link
 // them back to it as well
 // (suitable for spawnfunc_waypoint editor)
@@ -64,21 +85,7 @@ entity waypoint_spawn(vector m1, vector m2, float f)
        waypoint_clearlinks(w);
        //waypoint_schedulerelink(w);
 
-       if (autocvar_g_waypointeditor)
-       {
-               m1 = w.mins;
-               m2 = w.maxs;
-               setmodel(w, MDL_WAYPOINT); w.effects = EF_LOWPRECISION;
-               setsize(w, m1, m2);
-               if (w.wpflags & WAYPOINTFLAG_ITEM)
-                       w.colormod = '1 0 0';
-               else if (w.wpflags & WAYPOINTFLAG_GENERATED)
-                       w.colormod = '1 1 0';
-               else
-                       w.colormod = '1 1 1';
-       }
-       else
-               w.model = "";
+       waypoint_setupmodel(w);
 
        return w;
 }
@@ -264,23 +271,8 @@ void waypoint_schedulerelink(entity wp)
 {
        if (wp == NULL)
                return;
-       // TODO: add some sort of visible box in edit mode for box waypoints
-       if (autocvar_g_waypointeditor)
-       {
-               vector m1, m2;
-               m1 = wp.mins;
-               m2 = wp.maxs;
-               setmodel(wp, MDL_WAYPOINT); wp.effects = EF_LOWPRECISION;
-               setsize(wp, m1, m2);
-               if (wp.wpflags & WAYPOINTFLAG_ITEM)
-                       wp.colormod = '1 0 0';
-               else if (wp.wpflags & WAYPOINTFLAG_GENERATED)
-                       wp.colormod = '1 1 0';
-               else
-                       wp.colormod = '1 1 1';
-       }
-       else
-               wp.model = "";
+
+       waypoint_setupmodel(wp);
        wp.wpisbox = vdist(wp.size, >, 0);
        wp.enemy = NULL;
        if (!(wp.wpflags & WAYPOINTFLAG_PERSONAL))
index 04c35a11761ffbb05b04cec53c55919c53b4a55c..9583118ceacae67335fc8ff8612e17d3b4bd97e5 100644 (file)
@@ -284,8 +284,8 @@ void PutObserverInServer(entity this)
        if (this.killcount != FRAGS_SPECTATOR)
        {
                Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_SPECTATE, this.netname);
-               if(!intermission_running)
-               if(autocvar_g_chat_nospectators == 1 || (!(warmup_stage || gameover) && autocvar_g_chat_nospectators == 2))
+               if(!gameover)
+               if(autocvar_g_chat_nospectators == 1 || (!warmup_stage && autocvar_g_chat_nospectators == 2))
                        Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CHAT_NOSPECTATORS);
 
                if(this.just_joined == false) {
@@ -2320,8 +2320,9 @@ void PlayerPreThink (entity this)
        if (IS_PLAYER(this)) {
                CheckRules_Player(this);
 
-               if (intermission_running) {
-                       IntermissionThink(this);
+               if (gameover || intermission_running) {
+                       if(intermission_running)
+                               IntermissionThink(this);
                        return;
                }
 
@@ -2472,8 +2473,9 @@ void PlayerPreThink (entity this)
 
                this.dmg_team = max(0, this.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
        }
-       else if (gameover) {
-               if (intermission_running) IntermissionThink(this);
+       else if (gameover || intermission_running) {
+               if(intermission_running)
+                       IntermissionThink(this);
                return;
        }
        else if (IS_OBSERVER(this)) {
@@ -2615,13 +2617,23 @@ void PlayerPostThink (entity this)
        CheatFrame(this);
 
        //CheckPlayerJump();
+       if (gameover)
+       {
+               this.solid = SOLID_NOT;
+               this.takedamage = DAMAGE_NO;
+               set_movetype(this, MOVETYPE_NONE);
+       }
 
        if (IS_PLAYER(this)) {
                DrownPlayer(this);
                CheckRules_Player(this);
                UpdateChatBubble(this);
                if (this.impulse) ImpulseCommands(this);
-               if (intermission_running) return; // intermission or finale
+               if (gameover)
+               {
+                       CSQCMODEL_AUTOUPDATE(this);
+                       return;
+               }
                GetPressedKeys(this);
        }
 
index 5017e81aba03014d4d325c3ddbb56fe0b9e36e2e..d01448aad81ca4d022f415c42d12759eebff606a 100644 (file)
@@ -242,16 +242,22 @@ string getmaplist()
        return sprintf("^7Maps in list: %s\n", maplist);
 }
 
-
+const int LSMAPS_MAX = 250;
 string getlsmaps()
 {
        string lsmaps = "", col;
-       float i, newmaps = 0;
+       bool newmaps = false;
+       int added = 0;
 
-       for (i = 0; i < MapInfo_count; ++i)
+       for (int i = 0; i < MapInfo_count; ++i)
        {
                if ((MapInfo_Get_ByID(i)) && !(MapInfo_Map_flags & MapInfo_ForbiddenFlags()))
                {
+                       ++added;
+
+                       if(added > LSMAPS_MAX)
+                               continue; // we still get the added count, but skip the actual processing
+
                        // todo: Check by play count of maps for other game types?
                        if (
                            (g_race && !stof(db_get(ServerProgsDB, strcat(MapInfo_Map_bspname, RACE_RECORD, "time"))))
@@ -271,19 +277,22 @@ string getlsmaps()
                }
        }
 
+       if(added > LSMAPS_MAX)
+               lsmaps = sprintf("%s^7(%d not listed)", lsmaps, added - LSMAPS_MAX);
+
        MapInfo_ClearTemps();
-       return sprintf("^7Maps available (%d)%s: %s\n", tokenize_console(lsmaps), (newmaps ? " (New maps have asterisks marked in blue)" : ""), lsmaps);
+       return sprintf("^7Maps available (%d)%s: %s\n", added, (newmaps ? " (New maps have asterisks marked in blue)" : ""), lsmaps);
 }
 
 string getmonsterlist()
 {
-       string monsterlist = "", col;
+       string monsterlist = "";
 
-       for (int i = MON_FIRST; i <= MON_LAST; ++i)
+       FOREACH(Monsters, it != MON_Null,
        {
-               if (i % 2) col = "^2"; else col = "^3";
-               monsterlist = sprintf("%s%s%s ", monsterlist, col, (get_monsterinfo(i)).netname);
-       }
+               string col = ((i % 2) ? "^2" : "^3");
+               monsterlist = sprintf("%s%s%s ", monsterlist, col, it.netname);
+       });
 
        return sprintf("^7Monsters available: %s\n", monsterlist);
 }
index 1e5fedbcb65b79d209fff4de1fd2e7b11045a861..76e913500db7b53fafe4df3ee69c8f6d35e4c06b 100644 (file)
@@ -383,10 +383,16 @@ void GameCommand_bot_cmd(float request, float argc, string command)
                                                }
                                                else
                                                {
-                                                       // let's start at token 2 so we can skip sv_cmd bot_cmd
-                                                       bot = find_bot_by_number(stof(argv(2)));
-                                                       if (bot == NULL) bot = find_bot_by_name(argv(2));
-                                                       if (bot) bot_queuecommand(bot, substring(s, argv_start_index(3), -1));
+                                                       if(argv(2) == "*" || argv(2) == "all")
+                                                               FOREACH_CLIENT(IS_BOT_CLIENT(it), {
+                                                                       bot_queuecommand(it, substring(s, argv_start_index(3), -1));
+                                                               });
+                                                       else
+                                                       {
+                                                               bot = find_bot_by_number(stof(argv(2)));
+                                                               if (bot == NULL) bot = find_bot_by_name(argv(2));
+                                                               if (bot) bot_queuecommand(bot, substring(s, argv_start_index(3), -1));
+                                                       }
                                                }
                                        }
                                        else
@@ -408,17 +414,31 @@ void GameCommand_bot_cmd(float request, float argc, string command)
                        }
                        else if (argc >= 3)  // this comes last
                        {
-                               bot = find_bot_by_number(stof(argv(1)));
-                               if (bot == NULL) bot = find_bot_by_name(argv(1));
-                               if (bot)
+                               if(argv(1) == "*" || argv(1) == "all")
                                {
-                                       LOG_INFO(strcat("Command '", substring(command, argv_start_index(2), -1), "' sent to bot ", bot.netname, "\n"));
-                                       bot_queuecommand(bot, substring(command, argv_start_index(2), -1));
+                                       int bot_num = 0;
+                                       FOREACH_CLIENT(IS_BOT_CLIENT(it), {
+                                               bot_queuecommand(it, substring(command, argv_start_index(2), -1));
+                                               bot_num++;
+                                       });
+                                       if(bot_num)
+                                               LOG_INFO(strcat("Command '", substring(command, argv_start_index(2), -1), "' sent to all bots (", ftos(bot_num), ")\n"));
                                        return;
                                }
                                else
                                {
-                                       LOG_INFO(strcat("Error: Can't find bot with the name or id '", argv(1), "' - Did you mistype the command?\n"));  // don't return so that usage is shown
+                                       bot = find_bot_by_number(stof(argv(1)));
+                                       if (bot == NULL) bot = find_bot_by_name(argv(1));
+                                       if (bot)
+                                       {
+                                               LOG_INFO(strcat("Command '", substring(command, argv_start_index(2), -1), "' sent to bot ", bot.netname, "\n"));
+                                               bot_queuecommand(bot, substring(command, argv_start_index(2), -1));
+                                               return;
+                                       }
+                                       else
+                                       {
+                                               LOG_INFO(strcat("Error: Can't find bot with the name or id '", argv(1), "' - Did you mistype the command?\n"));  // don't return so that usage is shown
+                                       }
                                }
                        }
                }
@@ -428,10 +448,12 @@ void GameCommand_bot_cmd(float request, float argc, string command)
                case CMD_REQUEST_USAGE:
                {
                        LOG_INFO("\nUsage:^3 sv_cmd bot_cmd client command [argument]\n");
-                       LOG_INFO("  'client' can be either the name or entity id of the bot\n");
+                       LOG_INFO("  'client' can be either the name of the bot or a progressive number (not the entity number!)\n");
+                       LOG_INFO("           can also be '*' or 'all' to allow sending the command to all the bots\n");
                        LOG_INFO("  For full list of commands, see bot_cmd help [command].\n");
-                       LOG_INFO("Examples: sv_cmd bot_cmd client cc \"say something\"\n");
-                       LOG_INFO("          sv_cmd bot_cmd client presskey jump\n");
+                       LOG_INFO("Examples: sv_cmd bot_cmd 1 cc \"say something\"\n");
+                       LOG_INFO("          sv_cmd bot_cmd 1 presskey jump\n");
+                       LOG_INFO("          sv_cmd bot_cmd * pause\n");
                        return;
                }
        }
index 85c5d18472f82b08f94ff695c220ae2181761662..b91a8f4df3e208633e21e0d7ee40ef12fcddffc1 100644 (file)
@@ -464,8 +464,7 @@ void ReadyRestart_force()
 
 void ReadyRestart()
 {
-       // no assault support yet...
-       if (g_assault | gameover | intermission_running | race_completing) localcmd("restart\n");
+       if (MUTATOR_CALLHOOK(ReadyRestart_Deny) || gameover || race_completing) localcmd("restart\n");
        else localcmd("\nsv_hook_gamerestart\n");
 
        // Reset ALL scores, but only do that at the beginning of the countdown if sv_ready_restart_after_countdown is off!
index 42cf15db4c57fdc13d64372daace3b49e8c49f8d..f719d60c253dae805b9981418346806d9317a118 100644 (file)
@@ -129,7 +129,6 @@ const int W_TICSPERFRAME = 2;
 
 void weapon_defaultspawnfunc(entity this, Weapon e);
 
-float gameover;
 float intermission_running;
 float intermission_exittime;
 float alreadychangedlevel;
index fd725ad35e8b128a3e78521e0d46913e64f6134e..cccba42bb42128fff96050498f317875c050c360 100644 (file)
@@ -144,7 +144,7 @@ void GrapplingHookThink(entity this)
                error("Owner lost the hook!\n");
                return;
        }
-       if(LostMovetypeFollow(this) || intermission_running || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade"))
+       if(LostMovetypeFollow(this) || gameover || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || ((this.aiment.flags & FL_PROJECTILE) && this.aiment.classname != "nade"))
        {
                RemoveGrapplingHook(this.realowner);
                return;
index c9d25353237bd89b854e6b6a5fa921000904a269..2acc67a6e947a655a23a6d64283fb7f5fb8c1b0f 100644 (file)
@@ -1308,7 +1308,6 @@ When the player presses attack or jump, change to the next level
 void IntermissionThink(entity this)
 {
        FixIntermissionClient(this);
-       CSQCMODEL_AUTOUPDATE(this); // PlayerPostThink returns before calling this during intermission, so run it here
 
        float server_screenshot = (autocvar_sv_autoscreenshot && this.cvar_cl_autoscreenshot);
        float client_screenshot = (this.cvar_cl_autoscreenshot == 2);
@@ -1496,9 +1495,6 @@ void FixIntermissionClient(entity e)
                e.autoscreenshot = time + 0.8;  // used for autoscreenshot
                e.health = -2342;
                // first intermission phase; voting phase has positive health (used to decide whether to send SVC_FINALE or not)
-               e.solid = SOLID_NOT;
-               set_movetype(e, MOVETYPE_NONE);
-               e.takedamage = DAMAGE_NO;
                for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                {
                    .entity weaponentity = weaponentities[slot];
@@ -1536,7 +1532,7 @@ void NextLevel()
 
        intermission_running = 1;
 
-// enforce a wait time before allowing changelevel
+       // enforce a wait time before allowing changelevel
        if(player_count > 0)
                intermission_exittime = time + autocvar_sv_mapchange_delay;
        else
@@ -1843,7 +1839,7 @@ void CheckRules_World()
 
        SetDefaultAlpha();
 
-       if (gameover)   // someone else quit the game already
+       if (intermission_running) // someone else quit the game already
        {
                if(player_count == 0) // Nobody there? Then let's go to the next map
                        MapVote_Start();
index 2ea425692c1d5ead09c22889c91237190e8f1321..b5a6014462ea141adf7379172adf8fb9a853cd2c 100644 (file)
@@ -270,14 +270,14 @@ void MapVote_SendPicture(entity to, int id)
 
 void MapVote_WriteMask()
 {
-       float i;
        if ( mapvote_count < 24 )
        {
-               float mask,power;
-               mask = 0;
-               for(i = 0, power = 1; i < mapvote_count; ++i, power *= 2)
-                       if(mapvote_maps_flags[i] & GTV_AVAILABLE )
-                               mask |= power;
+               int mask = 0;
+               for(int j = 0; j < mapvote_count; ++j)
+               {
+                       if(mapvote_maps_flags[j] & GTV_AVAILABLE)
+                               mask |= BIT(j);
+               }
 
                if(mapvote_count < 8)
                        WriteByte(MSG_ENTITY, mask);
@@ -288,8 +288,8 @@ void MapVote_WriteMask()
        }
        else
        {
-               for ( i = 0; i < mapvote_count; ++i )
-                       WriteByte(MSG_ENTITY, mapvote_maps_flags[i]);
+               for (int j = 0; j < mapvote_count; ++j)
+                       WriteByte(MSG_ENTITY, mapvote_maps_flags[j]);
        }
 }
 
index 7f4899f127faed3c1d53e77e9ad15a4d236f197b..d2aff2ae7bbc53d7378372b3aac05033ecb826a7 100644 (file)
@@ -461,7 +461,7 @@ void GetCvars(entity this, int f)
 string playername(entity p)
 {
     string t;
-    if (teamplay && !intermission_running && IS_PLAYER(p))
+    if (teamplay && !gameover && IS_PLAYER(p))
     {
         t = Team_ColorCode(p.team);
         return strcat(t, strdecolorize(p.netname));
index b6ddd3c6a17cfd76d37019e80330a51b93a6e16c..eb0f3a910a80cb568c57d52212460d37057f2637 100644 (file)
@@ -182,18 +182,18 @@ float g_pickup_armormedium_anyway;
 float g_pickup_armorbig;
 float g_pickup_armorbig_max;
 float g_pickup_armorbig_anyway;
-float g_pickup_armorlarge;
-float g_pickup_armorlarge_max;
-float g_pickup_armorlarge_anyway;
+float g_pickup_armormega;
+float g_pickup_armormega_max;
+float g_pickup_armormega_anyway;
 float g_pickup_healthsmall;
 float g_pickup_healthsmall_max;
 float g_pickup_healthsmall_anyway;
 float g_pickup_healthmedium;
 float g_pickup_healthmedium_max;
 float g_pickup_healthmedium_anyway;
-float g_pickup_healthlarge;
-float g_pickup_healthlarge_max;
-float g_pickup_healthlarge_anyway;
+float g_pickup_healthbig;
+float g_pickup_healthbig_max;
+float g_pickup_healthbig_anyway;
 float g_pickup_healthmega;
 float g_pickup_healthmega_max;
 float g_pickup_healthmega_anyway;
@@ -312,18 +312,18 @@ void readlevelcvars()
        g_pickup_armorbig = cvar("g_pickup_armorbig");
        g_pickup_armorbig_max = cvar("g_pickup_armorbig_max");
        g_pickup_armorbig_anyway = cvar("g_pickup_armorbig_anyway");
-       g_pickup_armorlarge = cvar("g_pickup_armorlarge");
-       g_pickup_armorlarge_max = cvar("g_pickup_armorlarge_max");
-       g_pickup_armorlarge_anyway = cvar("g_pickup_armorlarge_anyway");
+       g_pickup_armormega = cvar("g_pickup_armormega");
+       g_pickup_armormega_max = cvar("g_pickup_armormega_max");
+       g_pickup_armormega_anyway = cvar("g_pickup_armormega_anyway");
        g_pickup_healthsmall = cvar("g_pickup_healthsmall");
        g_pickup_healthsmall_max = cvar("g_pickup_healthsmall_max");
        g_pickup_healthsmall_anyway = cvar("g_pickup_healthsmall_anyway");
        g_pickup_healthmedium = cvar("g_pickup_healthmedium");
        g_pickup_healthmedium_max = cvar("g_pickup_healthmedium_max");
        g_pickup_healthmedium_anyway = cvar("g_pickup_healthmedium_anyway");
-       g_pickup_healthlarge = cvar("g_pickup_healthlarge");
-       g_pickup_healthlarge_max = cvar("g_pickup_healthlarge_max");
-       g_pickup_healthlarge_anyway = cvar("g_pickup_healthlarge_anyway");
+       g_pickup_healthbig = cvar("g_pickup_healthbig");
+       g_pickup_healthbig_max = cvar("g_pickup_healthbig_max");
+       g_pickup_healthbig_anyway = cvar("g_pickup_healthbig_anyway");
        g_pickup_healthmega = cvar("g_pickup_healthmega");
        g_pickup_healthmega_max = cvar("g_pickup_healthmega_max");
        g_pickup_healthmega_anyway = cvar("g_pickup_healthmega_anyway");
index cab67d0c659d80e4d549b08b90c071d75c5b2dba..09e1cf70bd212497b69907be4ec13c31e97d33ca 100644 (file)
@@ -96,6 +96,14 @@ MUTATOR_HOOKABLE(WeaponSound, EV_WeaponSound);
     /**/
 MUTATOR_HOOKABLE(ItemModel, EV_ItemModel);
 
+/** called when an item sound is about to be played, allows custom paths etc. */
+#define EV_ItemSound(i, o) \
+    /** sound       */ i(string, MUTATOR_ARGV_0_string) \
+    /** output      */ i(string, MUTATOR_ARGV_1_string) \
+    /**/               o(string, MUTATOR_ARGV_1_string) \
+    /**/
+MUTATOR_HOOKABLE(ItemSound, EV_ItemSound);
+
 /** called when someone was fragged by "self", and is expected to change frag_score to adjust scoring for the kill */
 #define EV_GiveFragsForKill(i, o) \
     /** attacker   */ i(entity, MUTATOR_ARGV_0_entity) \
@@ -906,3 +914,6 @@ MUTATOR_HOOKABLE(ChatMessage, EV_ChatMessage);
     /** sender */ i(entity, MUTATOR_ARGV_1_entity) \
     /**/
 MUTATOR_HOOKABLE(ChatMessageTo, EV_ChatMessageTo);
+
+/** return true to just restart the match, for modes that don't support readyrestart */
+MUTATOR_HOOKABLE(ReadyRestart_Deny, EV_NO_ARGS);
index 1a1d7959fd2799b4e3908d3e13736b314106aced..39987414348d0d3a37556741a320eb755e3a1cb3 100644 (file)
@@ -1,6 +1,7 @@
 #include "gamemode_assault.qh"
 
 .entity sprite;
+#define AS_ROUND_DELAY 5
 
 // random functions
 void assault_objective_use(entity this, entity actor, entity trigger)
@@ -105,7 +106,7 @@ void target_objective_decrease_activate(entity this)
                                it.sprite = NULL; // TODO: just unsetting it?!
                }
 
-               spr = WaypointSprite_SpawnFixed(WP_Assault, 0.5 * (it.absmin + it.absmax), it, assault_sprite, RADARICON_OBJECTIVE);
+               spr = WaypointSprite_SpawnFixed(WP_AssaultDefend, 0.5 * (it.absmin + it.absmax), it, assault_sprite, RADARICON_OBJECTIVE);
                spr.assault_decreaser = this;
                spr.waypointsprite_visible_for_player = assault_decreaser_sprite_visible;
                spr.classname = "sprite_waypoint";
@@ -202,14 +203,27 @@ void assault_new_round(entity this)
        });
 
        // reset the level with a countdown
-       cvar_set("timelimit", ftos(ceil(time - game_starttime) / 60));
+       cvar_set("timelimit", ftos(ceil(time - AS_ROUND_DELAY - game_starttime) / 60));
        ReadyRestart_force(); // sets game_starttime
 }
 
+entity as_round;
+.entity ent_winning;
+void as_round_think()
+{
+       gameover = false;
+       assault_new_round(as_round.ent_winning);
+       delete(as_round);
+       as_round = NULL;
+}
+
 // Assault winning condition: If the attackers triggered a round end (by fulfilling all objectives)
 // they win. Otherwise the defending team wins once the timelimit passes.
 int WinningCondition_Assault()
 {
+       if(as_round)
+               return WINNING_NO;
+
        WinningConditionHelper(NULL); // set worldstatus
 
        int status = WINNING_NO;
@@ -229,7 +243,7 @@ int WinningCondition_Assault()
        {
                if(ent.winning) // round end has been triggered by attacking team
                {
-                       bprint("ASSAULT: round completed...\n");
+                       bprint("Assault: round completed.\n");
                        SetWinners(team, assault_attacker_team);
 
                        TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 666 - TeamScore_AddToTeam(assault_attacker_team, ST_ASSAULT_OBJECTIVES, 0));
@@ -240,7 +254,17 @@ int WinningCondition_Assault()
                        }
                        else
                        {
-                               assault_new_round(ent);
+                               Send_Notification(NOTIF_ALL, NULL, MSG_CENTER, CENTER_ASSAULT_OBJ_DESTROYED, ceil(time - game_starttime));
+                               as_round = new(as_round);
+                               as_round.think = as_round_think;
+                               as_round.ent_winning = ent;
+                               as_round.nextthink = time + AS_ROUND_DELAY;
+                               gameover = true;
+
+                               // make sure timelimit isn't hit while the game is blocked
+                               if(autocvar_timelimit > 0)
+                               if(time + AS_ROUND_DELAY >= game_starttime + autocvar_timelimit * 60)
+                                       cvar_set("timelimit", ftos(autocvar_timelimit + AS_ROUND_DELAY / 60));
                        }
                }
        }
@@ -584,6 +608,12 @@ MUTATOR_HOOKFUNCTION(as, OnEntityPreSpawn)
        }
 }
 
+MUTATOR_HOOKFUNCTION(as, ReadyRestart_Deny)
+{
+       // readyrestart not supported (yet)
+       return true;
+}
+
 // scoreboard setup
 void assault_ScoreRules()
 {
index ebfcd9540282d99f853c94cbb6c0f5d94ca75d04..561a30d222a40b223d14d41a702403efba0f2a14 100644 (file)
@@ -209,6 +209,7 @@ MUTATOR_HOOKFUNCTION(ca, reset_map_players)
                        PutClientInServer(it);
                }
        });
+       bot_relinkplayerlist();
        return true;
 }
 
@@ -265,6 +266,8 @@ MUTATOR_HOOKFUNCTION(ca, PlayerDies)
                frag_target.respawn_flags =  RESPAWN_SILENT;
        if (!warmup_stage)
                eliminatedPlayers.SendFlags |= 1;
+       if(IS_BOT_CLIENT(frag_target))
+               bot_clear(frag_target);
        return true;
 }
 
index 8120e1cb348a77e35e545eaa2c78733f41a2ea02..27fd46b88524ebc6eecd712634b4ea8af0296f37 100644 (file)
@@ -155,6 +155,16 @@ void ctf_CaptureRecord(entity flag, entity player)
        }
 }
 
+bool ctf_Immediate_Return_Allowed(entity flag, entity toucher)
+{
+       int num_perteam = 0;
+       FOREACH_CLIENT(IS_PLAYER(it) && SAME_TEAM(toucher, it), { ++num_perteam; });
+
+       // automatically return if there's only 1 player on the team
+       return ((autocvar_g_ctf_flag_return || num_perteam <= 1 || (autocvar_g_ctf_flag_return_carrying && toucher.flagcarried))
+               && flag.team);
+}
+
 bool ctf_Return_Customize(entity this, entity client)
 {
        // only to the carrier
@@ -871,9 +881,7 @@ void ctf_FlagDamage(entity this, entity inflictor, entity attacker, float damage
        if(ITEM_DAMAGE_NEEDKILL(deathtype))
        {
                if(autocvar_g_ctf_flag_return_damage_delay)
-               {
-                       this.ctf_flagdamaged = true;
-               }
+                       this.ctf_flagdamaged_byworld = true;
                else
                {
                        this.health = 0;
@@ -906,17 +914,7 @@ void ctf_FlagThink(entity this)
                LOG_TRACE("wtf the flag got squashed?");
                tracebox(this.origin, CTF_FLAG.m_mins, CTF_FLAG.m_maxs, this.origin, MOVE_NOMONSTERS, this);
                if(!trace_startsolid || this.noalign) // can we resize it without getting stuck?
-                       setsize(this, CTF_FLAG.m_mins, CTF_FLAG.m_maxs); }
-
-       switch(this.ctf_status) // reset flag angles in case warpzones adjust it
-       {
-               case FLAG_DROPPED:
-               {
-                       this.angles = '0 0 0';
-                       break;
-               }
-
-               default: break;
+                       setsize(this, CTF_FLAG.m_mins, CTF_FLAG.m_maxs);
        }
 
        // main think method
@@ -937,6 +935,8 @@ void ctf_FlagThink(entity this)
 
                case FLAG_DROPPED:
                {
+                       this.angles = '0 0 0'; // reset flag angles in case warpzones adjust it
+
                        if(autocvar_g_ctf_flag_dropped_floatinwater)
                        {
                                vector midpoint = ((this.absmin + this.absmax) * 0.5);
@@ -960,7 +960,7 @@ void ctf_FlagThink(entity this)
                                        return;
                                }
                        }
-                       if(this.ctf_flagdamaged)
+                       if(this.ctf_flagdamaged_byworld)
                        {
                                this.health -= ((this.max_flag_health / autocvar_g_ctf_flag_return_damage_delay) * FLAG_THINKRATE);
                                ctf_CheckFlagReturn(this, RETURN_NEEDKILL);
@@ -1051,12 +1051,9 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
                        flag.health = 0;
                        ctf_CheckFlagReturn(flag, RETURN_NEEDKILL);
                }
-               if(!flag.ctf_flagdamaged) { return; }
+               if(!flag.ctf_flagdamaged_byworld) { return; }
        }
 
-       int num_perteam = 0;
-       FOREACH_CLIENT(IS_PLAYER(it) && SAME_TEAM(toucher, it), LAMBDA(++num_perteam));
-
        // special touch behaviors
        if(STAT(FROZEN, toucher)) { return; }
        else if(IS_VEHICLE(toucher))
@@ -1108,7 +1105,7 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
 
                case FLAG_DROPPED:
                {
-                       if(CTF_SAMETEAM(toucher, flag) && (autocvar_g_ctf_flag_return || num_perteam <= 1 || (autocvar_g_ctf_flag_return_carrying && toucher.flagcarried)) && flag.team) // automatically return if there's only 1 player on the team
+                       if(CTF_SAMETEAM(toucher, flag) && ctf_Immediate_Return_Allowed(flag, toucher))
                                ctf_Handle_Return(flag, toucher); // toucher just returned his own flag
                        else if(is_not_monster && (!toucher.flagcarried) && ((toucher != flag.ctf_dropper) || (time > flag.ctf_droptime + autocvar_g_ctf_flag_collect_delay)))
                                ctf_Handle_Pickup(flag, toucher, PICKUP_DROPPED); // toucher just picked up a dropped enemy flag
@@ -1126,7 +1123,12 @@ METHOD(Flag, giveTo, bool(Flag this, entity flag, entity toucher))
                        if((IS_PLAYER(toucher)) && !IS_DEAD(toucher) && (toucher != flag.pass_sender))
                        {
                                if(DIFF_TEAM(toucher, flag.pass_sender))
-                                       ctf_Handle_Return(flag, toucher);
+                               {
+                                       if(ctf_Immediate_Return_Allowed(flag, toucher))
+                                               ctf_Handle_Return(flag, toucher);
+                                       else if(is_not_monster && (!toucher.flagcarried))
+                                               ctf_Handle_Pickup(flag, toucher, PICKUP_DROPPED);
+                               }
                                else
                                        ctf_Handle_Retrieve(flag, toucher);
                        }
@@ -1183,7 +1185,7 @@ void ctf_RespawnFlag(entity flag)
        flag.ctf_dropper = NULL;
        flag.ctf_pickuptime = 0;
        flag.ctf_droptime = 0;
-       flag.ctf_flagdamaged = 0;
+       flag.ctf_flagdamaged_byworld = false;
 
        ctf_CheckStalemate();
 }
@@ -1823,6 +1825,11 @@ void havocbot_role_ctf_retriever(entity this)
        mf = havocbot_ctf_find_flag(this);
        if(mf.ctf_status==FLAG_BASE)
        {
+               if(this.goalcurrent == mf)
+               {
+                       navigation_clearroute(this);
+                       this.bot_strategytime = 0;
+               }
                havocbot_ctf_reset_role(this);
                return;
        }
index 65f2937fd978351104f35027d5d81cfd7eb38824..593b0bec34d0930c54b47f9a31cf350e5427495e 100644 (file)
@@ -107,7 +107,7 @@ float ctf_captimerecord; // record time for capturing the flag
 .entity ctf_dropper; // don't allow spam of dropping the flag
 .int max_flag_health;
 .float next_take_time;
-.bool ctf_flagdamaged;
+.bool ctf_flagdamaged_byworld;
 int ctf_teams;
 
 // passing/throwing properties
index 2954fd1d33a2507f0809bc8838e416f2b0299f3a..2aede9204052148d1dee08243f137e5379be642f 100644 (file)
@@ -155,7 +155,7 @@ void kh_Controller_SetThink(float t, kh_Think_t func)  // runs occasionaly
 void kh_WaitForPlayers();
 void kh_Controller_Think(entity this)  // called a lot
 {
-       if(intermission_running)
+       if(gameover)
                return;
        if(this.cnt > 0)
        {
@@ -175,7 +175,7 @@ void kh_Controller_Think(entity this)  // called a lot
 void kh_Scores_Event(entity player, entity key, string what, float frags_player, float frags_owner)  // update the score when a key is captured
 {
        string s;
-       if(intermission_running)
+       if(gameover)
                return;
 
        if(frags_player)
@@ -448,7 +448,7 @@ void kh_Key_Collect(entity key, entity player)  //a player picks up a dropped ke
 
 void kh_Key_Touch(entity this, entity toucher)  // runs many, many times when a key has been dropped and can be picked up
 {
-       if(intermission_running)
+       if(gameover)
                return;
 
        if(this.owner) // already carried
@@ -659,7 +659,7 @@ void kh_LoserTeam(int loser_team, entity lostkey)  // runs when a player pushes
 
 void kh_Key_Think(entity this)  // runs all the time
 {
-       if(intermission_running)
+       if(gameover)
                return;
 
        if(this.owner)
index c325a359500a955812465a4443a512420730be0a..25f6d3e0ab03ae441a08313a3606bf7869222b25 100644 (file)
@@ -176,6 +176,8 @@ void lms_RemovePlayer(entity player)
                FOREACH_CLIENT(IS_PLAYER(it), { pl_cnt++; });
                if (player.lms_spectate_warning != 2)
                {
+                       if(IS_BOT_CLIENT(player))
+                               bot_clear(player);
                        player.frags = FRAGS_LMS_LOSER;
                        PlayerScore_Add(player, SP_LMS_RANK, pl_cnt + 1);
                }
@@ -281,6 +283,8 @@ MUTATOR_HOOKFUNCTION(lms, GiveFragsForKill)
                {
                        int pl_cnt = 0;
                        FOREACH_CLIENT(IS_PLAYER(it), { pl_cnt++; });
+                       if(IS_BOT_CLIENT(frag_target))
+                               bot_clear(frag_target);
                        frag_target.frags = FRAGS_LMS_LOSER;
                        PlayerScore_Add(frag_target, SP_LMS_RANK, pl_cnt);
                }
index fea4b125abb0a6604fde98e6380efe6a32dcc2b3..9cccbe887a87790aa49ce0b8ac1b9a32e8304483 100644 (file)
@@ -699,7 +699,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc
                teamsay = false;
        }
 
-       if(intermission_running)
+       if(gameover)
                teamsay = false;
 
     if (!source) {
@@ -876,9 +876,9 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc
 
        if (!privatesay && source && !IS_PLAYER(source))
        {
-               if (!intermission_running)
-                       if(teamsay || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !(warmup_stage || gameover)))
-                               teamsay = -1; // spectators
+               if (!gameover)
+               if (teamsay || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !warmup_stage))
+                       teamsay = -1; // spectators
        }
 
        if(flood)
index 545fb2a85949a1317e8d8cac910101f79dd7f32c..87776d4794bca8099a766b92d709e3c51a7a5923 100644 (file)
@@ -953,20 +953,29 @@ spawnfunc(trigger_race_checkpoint)
 
 spawnfunc(target_checkpoint) // defrag entity
 {
-       vector o;
        if(!g_race && !g_cts) { delete(this); return; }
        defrag_ents = 1;
 
-       EXACTTRIGGER_INIT;
+       // if this is targeted, then it probably isn't a trigger
+       bool is_trigger = !boolean(!this.nottargeted && this.targetname != "");
+
+       if(is_trigger)
+               EXACTTRIGGER_INIT;
 
        this.use = checkpoint_use;
-       if (!(this.spawnflags & 1))
+       if (is_trigger && !(this.spawnflags & 1))
                settouch(this, checkpoint_touch);
 
-       o = (this.absmin + this.absmax) * 0.5;
-       tracebox(o, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), o - '0 0 1' * (o.z - this.absmin.z), MOVE_NORMAL, this);
-       waypoint_spawnforitem_force(this, trace_endpos);
-       this.nearestwaypointtimeout = time + 1000000000;
+       vector org = this.origin;
+
+       // bots should only pathfind to this if it is a valid touchable trigger
+       if(is_trigger)
+       {
+               org = (this.absmin + this.absmax) * 0.5;
+               tracebox(org, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), org - '0 0 1' * (org.z - this.absmin.z), MOVE_NORMAL, this);
+               waypoint_spawnforitem_force(this, trace_endpos);
+               this.nearestwaypointtimeout = time + 1000000000;
+       }
 
        if(this.message == "")
                this.message = "went backwards";
@@ -983,9 +992,9 @@ spawnfunc(target_checkpoint) // defrag entity
        race_timed_checkpoint = 1;
 
        if(this.race_checkpoint == 0)
-               WaypointSprite_SpawnFixed(WP_RaceStart, o, this, sprite, RADARICON_NONE);
+               WaypointSprite_SpawnFixed(WP_RaceStart, org, this, sprite, RADARICON_NONE);
        else
-               WaypointSprite_SpawnFixed(WP_RaceCheckpoint, o, this, sprite, RADARICON_NONE);
+               WaypointSprite_SpawnFixed(WP_RaceCheckpoint, org, this, sprite, RADARICON_NONE);
 
        this.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
 
index 8cc3295b9a5d4acfe8d59a7f77585e115a30ccf3..063c12abb0aa8f67dd25c600ab70512251194589 100644 (file)
@@ -13,6 +13,9 @@ void round_handler_Think(entity this)
        }
 
        if (gameover)
+               gameover = false;
+
+       if (intermission_running)
        {
                round_handler_Reset(0);
                round_handler_Remove();
@@ -56,6 +59,7 @@ void round_handler_Think(entity this)
                        // schedule a new round
                        this.wait = true;
                        this.nextthink = time + this.delay;
+                       gameover = true;
                }
                else
                {
index dac8f193001de334cd0e19e2838176a86f26721c..7a277df98bc93fbda506d4bba4d410d784b34d83 100644 (file)
@@ -6,8 +6,7 @@ spawnfunc(weapon_electro);
 spawnfunc(weapon_hagar);
 spawnfunc(weapon_machinegun);
 spawnfunc(item_bullets);
-spawnfunc(item_armor_large);
-spawnfunc(item_armor_large);
+spawnfunc(item_armor_mega);
 spawnfunc(item_health_mega);
 spawnfunc(item_health_medium);
 
@@ -20,8 +19,8 @@ spawnfunc(weapon_supershotgun) {spawnfunc_weapon_machinegun(this);}
 
 spawnfunc(item_spikes) {spawnfunc_item_bullets(this);}
 //spawnfunc(item_armor1) {spawnfunc_item_armor_medium(this);}  // FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
-spawnfunc(item_armor2) {spawnfunc_item_armor_large(this);}
-spawnfunc(item_armorInv) {spawnfunc_item_armor_large(this);} // TODO: make sure we actually want this
+spawnfunc(item_armor2) {spawnfunc_item_armor_mega(this);}
+spawnfunc(item_armorInv) {spawnfunc_item_armor_mega(this);} // TODO: make sure we actually want this
 spawnfunc(item_health) {if (this.spawnflags & 2) spawnfunc_item_health_mega(this);else spawnfunc_item_health_medium(this);}
 
 //spawnfunc_item_spikes
index 254130f88c443cd4105e65ed20210faa4bbbb849..85ec325bdf6ea5c7196acaa8073d3aaf4cc832d5 100644 (file)
@@ -18,7 +18,7 @@ spawnfunc(item_shells);
 spawnfunc(item_jetpack);
 
 spawnfunc(item_armor_big);
-spawnfunc(item_armor_large);
+spawnfunc(item_armor_mega);
 spawnfunc(item_armor_small);
 
 spawnfunc(item_health_medium);
@@ -59,7 +59,7 @@ spawnfunc(ammo_bfg)            { spawnfunc_item_cells(this);          }
 spawnfunc(ammo_rockets)        { spawnfunc_item_rockets(this);        }
 
 // Armor
-spawnfunc(item_armor_body)     { spawnfunc_item_armor_large(this);    }
+spawnfunc(item_armor_body)     { spawnfunc_item_armor_mega(this);    }
 spawnfunc(item_armor_combat)   { spawnfunc_item_armor_big(this);      }
 spawnfunc(item_armor_shard)    { spawnfunc_item_armor_small(this);    }
 spawnfunc(item_enviro)         { spawnfunc_item_invincible(this);     }
index 5df7accc0b93afc2c3066fd56b0c963fc6435063..cdb337d145bb948a877141cd610f4a0b74a58acc 100644 (file)
@@ -22,7 +22,7 @@ void Send_WeaponComplain(entity e, float wpn, float type)
 void Weapon_whereis(Weapon this, entity cl)
 {
        if (!autocvar_g_showweaponspawns) return;
-       IL_EACH(g_items, it.weapon == this.m_id && (it.ItemStatus & ITS_AVAILABLE),
+       IL_EACH(g_items, it.weapon == this.m_id && (!it.team || (it.ItemStatus & ITS_AVAILABLE)),
        {
                if (it.classname == "droppedweapon" && autocvar_g_showweaponspawns < 2)
                        continue;
index c0d302e2232123e9e3c049eed1965f27d750cf7b..7dbdae6838cb2d5adcd632b9f67404b1f9359021 100644 (file)
@@ -67,7 +67,7 @@ vector CL_Weapon_GetShotOrg(int wpn)
 void CL_Weaponentity_Think(entity this)
 {
        this.nextthink = time;
-       if (intermission_running) this.frame = this.anim_idle.x;
+       if (gameover) this.frame = this.anim_idle.x;
        .entity weaponentity = this.weaponentity_fld;
        if (this.owner.(weaponentity) != this)
        {