]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into terencehill/CA_forbidspawn
authorterencehill <piuntn@gmail.com>
Wed, 31 Aug 2016 12:15:20 +0000 (14:15 +0200)
committerterencehill <piuntn@gmail.com>
Wed, 31 Aug 2016 12:15:20 +0000 (14:15 +0200)
151 files changed:
.gitlab-ci.yml
defaultXonotic.cfg
gamemodes.cfg
models/player/megaerebus.iqm_0.txt
models/player/pyria.iqm_0.skin
models/player/pyria_lod1.iqm_0.skin
models/player/pyria_lod2.iqm_0.skin
models/player/seraphinamasked.iqm_0.skin
models/player/seraphinamasked_lod1.iqm_0.skin
models/player/seraphinamasked_lod2.iqm_0.skin
monsters.cfg
qcsrc/client/hud/hud_config.qc
qcsrc/client/hud/panel/quickmenu.qc
qcsrc/client/hud/panel/radar.qc
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/client/hud/panel/weapons.qc
qcsrc/client/main.qc
qcsrc/client/mapvoting.qc
qcsrc/client/miscfunctions.qc
qcsrc/client/miscfunctions.qh
qcsrc/client/view.qc
qcsrc/common/_all.inc
qcsrc/common/animdecide.qc
qcsrc/common/constants.qh
qcsrc/common/effects/qc/rubble.qh
qcsrc/common/ent_cs.qc
qcsrc/common/gamemodes/gamemode/nexball/nexball.qc
qcsrc/common/gamemodes/gamemode/onslaught/cl_controlpoint.qc
qcsrc/common/gamemodes/gamemode/onslaught/cl_generator.qc
qcsrc/common/gamemodes/gamemode/onslaught/onslaught.qh
qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qc
qcsrc/common/gamemodes/gamemode/onslaught/sv_onslaught.qh
qcsrc/common/mapinfo.qc
qcsrc/common/mapinfo.qh
qcsrc/common/minigames/cl_minigames_hud.qc
qcsrc/common/monsters/_all.inc [deleted file]
qcsrc/common/monsters/_all.qh [deleted file]
qcsrc/common/monsters/_mod.inc
qcsrc/common/monsters/_mod.qh
qcsrc/common/monsters/all.qc
qcsrc/common/monsters/all.qh
qcsrc/common/monsters/monster.qh
qcsrc/common/monsters/monster/mage.qc
qcsrc/common/monsters/monster/mage.qh
qcsrc/common/monsters/monster/shambler.qc
qcsrc/common/monsters/monster/shambler.qh
qcsrc/common/monsters/monster/spider.qc
qcsrc/common/monsters/monster/spider.qh
qcsrc/common/monsters/monster/wyvern.qc
qcsrc/common/monsters/monster/wyvern.qh
qcsrc/common/monsters/monster/zombie.qc
qcsrc/common/monsters/monster/zombie.qh
qcsrc/common/monsters/spawn.qc [deleted file]
qcsrc/common/monsters/spawn.qh [deleted file]
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/monsters/sv_spawn.qc [new file with mode: 0644]
qcsrc/common/monsters/sv_spawn.qh [new file with mode: 0644]
qcsrc/common/mutators/mutator/buffs/sv_buffs.qc
qcsrc/common/mutators/mutator/itemstime/itemstime.qc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/mutators/mutator/overkill/rpc.qc
qcsrc/common/mutators/mutator/sandbox/sv_sandbox.qc
qcsrc/common/mutators/mutator/sandbox/sv_sandbox.qh
qcsrc/common/notifications/all.qc
qcsrc/common/notifications/all.qh
qcsrc/common/physics/player.qc
qcsrc/common/t_items.qc
qcsrc/common/triggers/func/breakable.qc
qcsrc/common/triggers/func/conveyor.qc
qcsrc/common/triggers/func/conveyor.qh
qcsrc/common/triggers/func/door_secret.qc
qcsrc/common/triggers/target/music.qc
qcsrc/common/triggers/teleporters.qc
qcsrc/common/triggers/teleporters.qh
qcsrc/common/triggers/trigger/teleport.qc
qcsrc/common/turrets/sv_turrets.qc
qcsrc/common/turrets/targettrigger.qc
qcsrc/common/turrets/turret/phaser_weapon.qc
qcsrc/common/turrets/turret/walker.qc
qcsrc/common/util.qc
qcsrc/common/util.qh
qcsrc/common/vehicles/sv_vehicles.qc
qcsrc/common/vehicles/sv_vehicles.qh
qcsrc/common/vehicles/vehicle/raptor_weapons.qc
qcsrc/common/vehicles/vehicle/spiderbot.qc
qcsrc/common/vehicles/vehicle/spiderbot_weapons.qc
qcsrc/common/weapons/all.qc
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/blaster.qc
qcsrc/common/weapons/weapon/crylink.qc
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/fireball.qc
qcsrc/common/weapons/weapon/hagar.qc
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/hook.qc
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/mortar.qc
qcsrc/common/weapons/weapon/porto.qc
qcsrc/common/weapons/weapon/seeker.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/lib/net.qh
qcsrc/menu/xonotic/keybinder.qc
qcsrc/menu/xonotic/playermodel.qc
qcsrc/server/autocvars.qh
qcsrc/server/bot/api.qh
qcsrc/server/bot/default/bot.qc
qcsrc/server/bot/default/havocbot/havocbot.qc
qcsrc/server/bot/default/havocbot/roles.qc
qcsrc/server/bot/default/havocbot/roles.qh
qcsrc/server/bot/default/navigation.qc
qcsrc/server/bot/default/scripting.qc
qcsrc/server/bot/default/waypoints.qc
qcsrc/server/bot/null/bot_null.qc
qcsrc/server/cheats.qc
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/command/cmd.qc
qcsrc/server/command/common.qc
qcsrc/server/command/common.qh
qcsrc/server/command/getreplies.qc
qcsrc/server/command/radarmap.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_hook.qc
qcsrc/server/g_world.qc
qcsrc/server/impulse.qc
qcsrc/server/item_key.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/gamemode.qh
qcsrc/server/mutators/mutator.qh
qcsrc/server/mutators/mutator/gamemode_assault.qc
qcsrc/server/mutators/mutator/gamemode_ctf.qc
qcsrc/server/mutators/mutator/gamemode_cts.qc
qcsrc/server/mutators/mutator/gamemode_domination.qc
qcsrc/server/mutators/mutator/gamemode_domination.qh
qcsrc/server/mutators/mutator/gamemode_freezetag.qc
qcsrc/server/mutators/mutator/gamemode_invasion.qc
qcsrc/server/mutators/mutator/gamemode_keepaway.qc
qcsrc/server/mutators/mutator/gamemode_keyhunt.qc
qcsrc/server/mutators/mutator/gamemode_race.qc
qcsrc/server/player.qc
qcsrc/server/race.qc
qcsrc/server/race.qh
qcsrc/server/spawnpoints.qc
qcsrc/server/steerlib.qc
qcsrc/server/sv_main.qc
qcsrc/server/t_quake3.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/spawning.qc
qcsrc/server/weapons/weaponsystem.qc

index 8838f39c9734b2fbb015b615c68e645cb487dd22..afd12e592f5e3a5de8dbc67cce4461b2d8efe74b 100644 (file)
@@ -30,7 +30,7 @@ test_sv_game:
     - wget -O data/maps/g-23.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.cache
     - wget -O data/maps/g-23.waypoints.hardwired https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.hardwired
     - make
-    - EXPECT=74f3802009cec230bdaa3b87235368ca
+    - EXPECT=b46b7dcf27e864c2842b7436e32e24fe
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index d2731c0732e2623c2dda636e5d367622546a1a26..538e3549fc5cc41ca4d8bebb03226129243a0f4a 100644 (file)
@@ -1024,13 +1024,13 @@ sv_allowdownloads 0 // download protocol is evil
 
 set g_jump_grunt 0     "Do you make a grunting noise every time you jump? Is it the same grunting noise every time?"
 
-seta cl_weaponpriority "vaporizer vortex fireball mortar machinegun hagar rifle arc electro devastator crylink minelayer shotgun shockwave hlac tuba blaster porto seeker hook" "weapon priority list"
+seta cl_weaponpriority "vaporizer hmg rpc vortex fireball mortar machinegun hagar rifle arc electro devastator crylink minelayer shotgun shockwave hlac tuba blaster porto seeker hook" "weapon priority list"
 seta cl_weaponpriority_useforcycling 0 "when set, weapon cycling by the mouse wheel makes use of the weapon priority list (the special value 2 uses the weapon ID list for cycling)"
-seta cl_weaponpriority0 "devastator mortar hagar seeker fireball"                       "use weapon_priority_0_prev for prev gun from this list, weapon_priority_0_best for best gun, weapon_priority_0_next for next gun.  Default value: explosives"
+seta cl_weaponpriority0 "rpc devastator mortar hagar seeker fireball"                   "use weapon_priority_0_prev for prev gun from this list, weapon_priority_0_best for best gun, weapon_priority_0_next for next gun.  Default value: explosives"
 seta cl_weaponpriority1 "vaporizer vortex crylink hlac arc electro blaster shockwave"   "use weapon_priority_1_prev for prev gun from this list, weapon_priority_1_best for best gun, weapon_priority_1_next for next gun.  Default value: energy"
 seta cl_weaponpriority2 "vaporizer vortex rifle"                                        "use weapon_priority_2_prev for prev gun from this list, weapon_priority_2_best for best gun, weapon_priority_2_next for next gun.  Default value: hitscan exact"
-seta cl_weaponpriority3 "vaporizer vortex rifle machinegun shotgun shockwave"                     "use weapon_priority_3_prev for prev gun from this list, weapon_priority_3_best for best gun, weapon_priority_3_next for next gun.  Default value: hitscan all"
-seta cl_weaponpriority4 "mortar minelayer hlac hagar crylink seeker shotgun shockwave"            "use weapon_priority_4_prev for prev gun from this list, weapon_priority_4_best for best gun, weapon_priority_4_next for next gun.  Default value: spam weapons"
+seta cl_weaponpriority3 "vaporizer hmg vortex rifle machinegun shotgun shockwave"       "use weapon_priority_3_prev for prev gun from this list, weapon_priority_3_best for best gun, weapon_priority_3_next for next gun.  Default value: hitscan all"
+seta cl_weaponpriority4 "mortar minelayer hlac hagar crylink seeker shotgun shockwave"  "use weapon_priority_4_prev for prev gun from this list, weapon_priority_4_best for best gun, weapon_priority_4_next for next gun.  Default value: spam weapons"
 seta cl_weaponpriority5 "blaster shockwave hook porto"                                  "use weapon_priority_5_prev for prev gun from this list, weapon_priority_5_best for best gun, weapon_priority_5_next for next gun.  Default value: weapons for moving"
 seta cl_weaponpriority6 ""                                                              "use weapon_priority_6_prev for prev gun from this list, weapon_priority_6_best for best gun, weapon_priority_6_next for next gun"
 seta cl_weaponpriority7 ""                                                              "use weapon_priority_7_prev for prev gun from this list, weapon_priority_7_best for best gun, weapon_priority_7_next for next gun"
index 4cf77d52e39bd0373c320cf4231372f5864f633f..add2332726f51f1eb52df2f2e495a9be791f0693 100644 (file)
@@ -391,7 +391,7 @@ set g_freezetag_teams 0
 // ==========
 //  keepaway
 // ==========
-set g_keepaway 0 "game mode which focuses around a ball, look at g_keepaway_win_mode for further details"
+set g_keepaway 0 "game mode which focuses around a ball"
 set g_keepaway_score_bckill 1 "enable scoring points (y/n) for ball carrier kills (value is how many points to award)"
 set g_keepaway_score_killac 1 "amount of points to give when you kill someone while you have the ball"
 set g_keepaway_score_timeinterval 1 "amount of time it takes between intervals for timepoints to be added to the score"
index f75a15fb8ef55b3cf7b06abeaec7ba451ae9ab9f..f4b62dea70bce940d29eb41f959c5e349580dd6f 100644 (file)
@@ -11,3 +11,4 @@ bone_aim2 0.2 upperarm_L
 bone_aim3 0.35 bip01 r hand
 bone_weapon bip01 r hand
 fixbone 1
+hidden 1
index 1932354e8078c3f24947504da7bbb93390c5a51a..7533a4c53adab086fe9866c766df919d631666f7 100644 (file)
@@ -1,2 +1,2 @@
 pyria_obj.001,pyriahair
-pyria_obj,pyriafullbright
+pyria_obj,pyria
index 1932354e8078c3f24947504da7bbb93390c5a51a..7533a4c53adab086fe9866c766df919d631666f7 100644 (file)
@@ -1,2 +1,2 @@
 pyria_obj.001,pyriahair
-pyria_obj,pyriafullbright
+pyria_obj,pyria
index 1932354e8078c3f24947504da7bbb93390c5a51a..7533a4c53adab086fe9866c766df919d631666f7 100644 (file)
@@ -1,2 +1,2 @@
 pyria_obj.001,pyriahair
-pyria_obj,pyriafullbright
+pyria_obj,pyria
index 7b94ebe4a4e61e1d7e0803fb86a91a60fb3ecf4e..7138ad587e31e81451b941144041fa5ffec81ec0 100644 (file)
@@ -1,2 +1,2 @@
-ignis42,ignisfullbright
+ignis42,ignis
 ignis42.002,ignishead
index 7b94ebe4a4e61e1d7e0803fb86a91a60fb3ecf4e..7138ad587e31e81451b941144041fa5ffec81ec0 100644 (file)
@@ -1,2 +1,2 @@
-ignis42,ignisfullbright
+ignis42,ignis
 ignis42.002,ignishead
index 7b94ebe4a4e61e1d7e0803fb86a91a60fb3ecf4e..7138ad587e31e81451b941144041fa5ffec81ec0 100644 (file)
@@ -1,2 +1,2 @@
-ignis42,ignisfullbright
+ignis42,ignis
 ignis42.002,ignishead
index f6eca00d004e4196ffff60499b30a5ab44bed257..b5a97f87a52db532a16eea6cc85d5ac5d54eca34 100644 (file)
@@ -93,6 +93,8 @@ set g_monsters_skill 1 "Monster skill (affecting some of their attributes). 1 -
 set g_monsters_miniboss_chance 5
 set g_monsters_miniboss_healthboost 100
 set g_monsters_drop_time 10
+set g_monsters_ignoretraces 1
+set g_monsters_lineofsight 1
 set g_monsters_owners 1
 set g_monsters_teams 1
 set g_monsters_score_kill 0
index 4f116d724fb35a8203132f7ff43cec23504ab142..f2b23e39256217b9f33019b51c2e94bdd1e8b59a 100644 (file)
@@ -1111,12 +1111,7 @@ void HUD_Panel_Mouse()
                return;
 
        if (!autocvar_hud_cursormode)
-       {
-               mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
-
-               mousepos.x = bound(0, mousepos.x, vid_conwidth);
-               mousepos.y = bound(0, mousepos.y, vid_conheight);
-       }
+               update_mousepos();
 
        if(mouseClicked)
        {
index 65997f46ebb0a9199ff8dde59756e88663b6d593..e242ae895881a89d05baf81eb6da4c3197fdf4e7 100644 (file)
@@ -496,14 +496,10 @@ void QuickMenu_Mouse()
                return;
        }
 
-       if(!autocvar_hud_cursormode)
-       {
-               mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
-
-               mousepos.x = bound(0, mousepos.x, vid_conwidth);
-               mousepos.y = bound(0, mousepos.y, vid_conheight);
-       }
+       if (!autocvar_hud_cursormode)
+               update_mousepos();
 
+       panel = HUD_PANEL(QUICKMENU);
        HUD_Panel_LoadCvars();
 
        if(panel_bg_padding)
index 9f967aae0587b35bd3bbdad2528e20d0f26d056d..269d870718e42663a431a3445c984876ff74b4c5 100644 (file)
@@ -137,14 +137,10 @@ void HUD_Radar_Mouse()
                return;
        }
 
-       if(!autocvar_hud_cursormode)
-       {
-               mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
-
-               mousepos_x = bound(0, mousepos_x, vid_conwidth);
-               mousepos_y = bound(0, mousepos_y, vid_conheight);
-       }
+       if (!autocvar_hud_cursormode)
+               update_mousepos();
 
+       panel = HUD_PANEL(RADAR);
        HUD_Panel_LoadCvars();
 
 
index c283be1c42e17b68da31a5ab9ba20ece71eedfdf..acbc2e45caadd4dcb2c2f11c0a3c30edca48a0d2 100644 (file)
@@ -10,6 +10,9 @@
 
 // Scoreboard (#24)
 
+string autocvar_hud_fontsize;
+string hud_fontsize_str;
+
 float sbt_bg_alpha;
 float sbt_fg_alpha;
 float sbt_fg_alpha_self;
@@ -656,19 +659,8 @@ string Scoreboard_GetField(entity pl, PlayerScoreField field)
                        }
                }
 
-               case SP_DMG:
-                       num = pl.(scores(SP_DMG));
-                       denom = 1000;
-
-                       str = sprintf("%.1f k", num/denom);
-                       return str;
-
-               case SP_DMGTAKEN:
-                       num = pl.(scores(SP_DMGTAKEN));
-                       denom = 1000;
-
-                       str = sprintf("%.1f k", num/denom);
-                       return str;
+               case SP_DMG: case SP_DMGTAKEN:
+                       return sprintf("%.1f k", pl.(scores(field)) / 1000);
 
                default:
                        tmp = pl.(scores(field));
@@ -693,7 +685,6 @@ string Scoreboard_FixColumnWidth(int i, string str)
     TC(int, i);
        float f;
        vector sz;
-       PlayerScoreField field = sbt_field[i];
 
        sbt_fixcolumnwidth_iconlen = 0;
 
@@ -728,7 +719,7 @@ string Scoreboard_FixColumnWidth(int i, string str)
        else
                sbt_fixcolumnwidth_marginlen = 0;
 
-       if(field == SP_NAME) // name gets all remaining space
+       if(sbt_field[i] == SP_NAME) // name gets all remaining space
        {
                int j;
                float namesize;
@@ -754,6 +745,12 @@ string Scoreboard_FixColumnWidth(int i, string str)
        return str;
 }
 
+void Scoreboard_initFieldSizes()
+{
+       for(int i = 0; i < sbt_num_fields; ++i)
+               sbt_field_size[i] = stringwidth(sbt_field_title[i], false, hud_fontsize);
+}
+
 vector Scoreboard_DrawHeader(vector pos, vector rgb)
 {
        int i;
@@ -1007,23 +1004,30 @@ vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size)
        WepSet weapons_stat = WepSet_GetFromStat();
        WepSet weapons_inmap = WepSet_GetFromStat_InMap();
        int disownedcnt = 0;
+       int nHidden = 0;
        FOREACH(Weapons, it != WEP_Null, {
                int weapon_stats = weapon_accuracy[i - WEP_FIRST];
 
                WepSet set = it.m_wepset;
-               if (weapon_stats < 0 && !(weapons_stat & set || weapons_inmap & set))
-                       ++disownedcnt;
+               if (weapon_stats < 0)
+               {
+                       if (!(weapons_stat & set) && (it.spawnflags & WEP_FLAG_HIDDEN || it.spawnflags & WEP_FLAG_MUTATORBLOCKED))
+                               nHidden += 1;
+                       else if (!(weapons_stat & set || weapons_inmap & set))
+                               ++disownedcnt;
+               }
        });
 
-       int weapon_cnt = (Weapons_COUNT - 1) - disownedcnt;
+       int weapon_cnt = (Weapons_COUNT - 1) - disownedcnt - nHidden;
        if (weapon_cnt <= 0) return pos;
 
        int rows = 1;
-       if (autocvar_hud_panel_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - 1) * 0.5))
+       if (autocvar_hud_panel_scoreboard_accuracy_doublerows && weapon_cnt >= floor((Weapons_COUNT - nHidden - 1) * 0.5))
                rows = 2;
        int columnns = ceil(weapon_cnt / rows);
 
-       float height = 40;
+       float weapon_height = 29;
+       float height = hud_fontsize.y + weapon_height;
 
        drawstring(pos + eX * panel_bg_padding, sprintf(_("Accuracy stats (average %d%%)"), average_accuracy), hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
        pos.y += 1.25 * hud_fontsize.y;
@@ -1048,8 +1052,6 @@ vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size)
        pos = panel_pos;
        vector tmp = panel_size;
 
-       float fontsize = height * 1/3;
-       float weapon_height = height * 2/3;
        float weapon_width = tmp.x / columnns / rows;
 
        if (sbt_bg_alpha)
@@ -1064,7 +1066,7 @@ vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size)
 
                // row highlighting
                for (int i = 0; i < rows; ++i)
-                       drawfill(pos + eY * weapon_height + eY * height * i, eX * tmp.x + eY * fontsize, rgb, sbt_highlight_alpha, DRAWFLAG_NORMAL);
+                       drawfill(pos + eY * weapon_height + eY * height * i, eX * tmp.x + eY * hud_fontsize.y, rgb, sbt_highlight_alpha, DRAWFLAG_NORMAL);
        }
 
        average_accuracy = 0;
@@ -1105,12 +1107,12 @@ vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size)
                        s = sprintf("%d%%", weapon_stats * 100);
 
                        float padding;
-                       padding = (weapon_width - stringwidth(s, false, eX * fontsize)) / 2; // center the accuracy value
+                       padding = (weapon_width - stringwidth(s, false, hud_fontsize)) / 2; // center the accuracy value
 
                        if(!autocvar_hud_panel_scoreboard_accuracy_nocolors)
                                rgb = Accuracy_GetColor(weapon_stats);
 
-                       drawstring(tmpos + eX * padding + eY * weapon_height, s, '1 1 0' * fontsize, rgb, sbt_fg_alpha, DRAWFLAG_NORMAL);
+                       drawstring(tmpos + eX * padding + eY * weapon_height, s, hud_fontsize, rgb, sbt_fg_alpha, DRAWFLAG_NORMAL);
                }
                tmpos.x += weapon_width * rows;
                pos.x += weapon_width * rows;
@@ -1290,6 +1292,14 @@ void Scoreboard_Draw()
                                scoreboard_fade_alpha = min(1, scoreboard_fade_alpha + frametime * scoreboard_fadeinspeed);
                        else
                                scoreboard_fade_alpha = 1;
+                       if(hud_fontsize_str != autocvar_hud_fontsize)
+                       {
+                               hud_fontsize = HUD_GetFontsize("hud_fontsize");
+                               Scoreboard_initFieldSizes();
+                               if(hud_fontsize_str)
+                                       strunzone(hud_fontsize_str);
+                               hud_fontsize_str = strzone(autocvar_hud_fontsize);
+                       }
                }
                else {
                        float scoreboard_fadeoutspeed = autocvar_hud_panel_scoreboard_fadeoutspeed;
index 206bebc2f0cec146c9d0425112dfdea995a1729b..db25d532a016f938e31a04045ac54e1886f03617 100644 (file)
@@ -25,7 +25,7 @@ int weaponorder_cmp(int i, int j, entity pass)
        int nHidden = 0; \
        FOREACH(Weapons, it != WEP_Null, { \
                if (weapons_stat & WepSet_FromWeapon(it)) continue; \
-               if (it.spawnflags & WEP_FLAG_MUTATORBLOCKED) nHidden += 1; \
+               if (it.spawnflags & WEP_FLAG_HIDDEN || it.spawnflags & WEP_FLAG_MUTATORBLOCKED) nHidden += 1; \
        }); \
        vector table_size = HUD_GetTableSize_BestItemAR((Weapons_COUNT - 1) - nHidden, panel_size, aspect); \
        columns = table_size.x; \
index 7de2946819ceeabef3852073e8ed6ea7a3e66efb..9bcfd4e7a9c58571bbafdba76dfb5b247a1ba230 100644 (file)
@@ -944,6 +944,7 @@ NET_HANDLE(ENT_CLIENT_SCORES_INFO, bool isnew)
 {
        make_pure(this);
        gametype = ReadRegistered(Gametypes);
+       teamplay = _MapInfo_GetTeamPlayBool(gametype);
        HUD_ModIcons_SetFunc();
        FOREACH(Scores, true, {
                if (scores_label(it)) strunzone(scores_label(it));
index 72b60b5bd378097c74ed43b3b754328dc0b7d435..b497b56bc6e2d6730f4e1079b9537b870250914c 100644 (file)
@@ -24,7 +24,6 @@ float mv_timeout;
 float mv_top2_time;
 float mv_top2_alpha;
 
-vector mv_mousepos;
 int mv_selection;
 int mv_columns;
 int mv_mouse_selection;
@@ -297,10 +296,10 @@ float MapVote_Selection(vector topleft, vector cellsize, float rows, float colum
        for (r = 0; r < rows; ++r)
                for (c = 0; c < columns; ++c)
                {
-                       if (mv_mousepos.x >= topleft.x + cellsize.x *  c &&
-                               mv_mousepos.x <= topleft.x + cellsize.x * (c + 1) &&
-                               mv_mousepos.y >= topleft.y + cellsize.y *  r &&
-                               mv_mousepos.y <= topleft.y + cellsize.y * (r + 1))
+                       if (mousepos.x >= topleft.x + cellsize.x *  c &&
+                               mousepos.x <= topleft.x + cellsize.x * (c + 1) &&
+                               mousepos.y >= topleft.y + cellsize.y *  r &&
+                               mousepos.y <= topleft.y + cellsize.y * (r + 1))
                        {
                                mv_mouse_selection = r * columns + c;
                                break;
@@ -338,13 +337,10 @@ void MapVote_Draw()
 
        if (!autocvar_hud_cursormode)
        {
-               vector mpos = mv_mousepos + getmousepos();
-               mpos.x = bound(0, mpos.x, vid_conwidth);
-               mpos.y = bound(0, mpos.y, vid_conheight);
-
-               if ( mpos.x != mv_mousepos.x || mpos.y != mv_mousepos.y )
+               vector mpos = mousepos;
+               update_mousepos();
+               if (mpos.x != mousepos.x || mpos.y != mousepos.y)
                        mv_selection_keyboard = 0;
-               mv_mousepos = mpos;
        }
 
        center = (vid_conwidth - 1)/2;
@@ -488,7 +484,7 @@ void MapVote_Draw()
                MapVote_DrawAbstain(pos, dist.x, xmax - xmin, tmp, i);
        }
 
-       draw_cursor_normal(mv_mousepos, '1 1 1', panel_fg_alpha);
+       draw_cursor_normal(mousepos, '1 1 1', panel_fg_alpha);
 }
 
 void Cmd_MapVote_MapDownload(int argc)
@@ -638,8 +634,8 @@ void GameTypeVote_ReadOption(int i)
 void MapVote_Init()
 {
        mv_active = 1;
-       if(autocvar_hud_cursormode) { setcursormode(1); }
-       else { mv_mousepos = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight; }
+       if(autocvar_hud_cursormode) setcursormode(1);
+       else mousepos = '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;
        mv_selection = -1;
        mv_selection_keyboard = 0;
 
@@ -775,8 +771,8 @@ float MapVote_InputEvent(int bInputType, float nPrimary, float nSecondary)
 
        if(bInputType == 3)
        {
-               mv_mousepos.x = nPrimary;
-               mv_mousepos.y = nSecondary;
+               mousepos.x = nPrimary;
+               mousepos.y = nSecondary;
                mv_selection_keyboard = 0;
                return true;
        }
index 33fd015cce8f8724a5403d6024b3ea7f79a1f379..0e88cd5a51043107b2d2246e79351151dccc538e 100644 (file)
@@ -350,6 +350,13 @@ void drawcolorcodedstring_aspect_expanding(vector pos, string text, vector sz, f
        drawcolorcodedstring_expanding(pos, text, '1 1 0' * sz.y, theAlpha, drawflag, fadelerp);
 }
 
+void update_mousepos()
+{
+       mousepos += getmousepos() * autocvar_menu_mouse_speed;
+       mousepos.x = bound(0, mousepos.x, vid_conwidth);
+       mousepos.y = bound(0, mousepos.y, vid_conheight);
+}
+
 // this draws the triangles of a model DIRECTLY. Don't expect high performance, really...
 float PolyDrawModelSurface(entity e, float i_s)
 {
index 1f8790481f1a8d88a0193d9971d8b65b2dcbad4b..9d792f60cd62ad3335e5531e8c48c483a16dc199 100644 (file)
@@ -187,6 +187,8 @@ void drawcolorcodedstring_expanding(vector position, string text, vector theScal
 
 void drawcolorcodedstring_aspect_expanding(vector pos, string text, vector sz, float theAlpha, float drawflag, float fadelerp);
 
+void update_mousepos();
+
 // this draws the triangles of a model DIRECTLY. Don't expect high performance, really...
 float PolyDrawModelSurface(entity e, float i_s);
 void PolyDrawModel(entity e);
index b013a8e179909cdb6589402c8929b2b793e23f37..cd156e65ec7b3989e0afc6ce1d8a08faa4c4aa12 100644 (file)
@@ -980,7 +980,7 @@ void HUD_Crosshair(entity this)
                                v = wcross_origin - wcross_oldorigin;
                                v.x /= vid_conwidth;
                                v.y /= vid_conheight;
-                               if(vlen(v) > 0.01)
+                               if(vdist(v, >, 0.01))
                                        shottype = SHOTTYPE_HITOBSTRUCTION;
                        }
                        if(!autocvar_crosshair_hittest_showimpact)
@@ -1507,9 +1507,10 @@ void CSQC_UpdateView(entity this, float w, float h)
                        }
                }
 
-               if(ons_roundlost)
+               if(ons_roundlost) // TODO: move this junk to a client mutator for onslaught (possible using the WantEventchase hook)
                {
-                       FOREACH_ENTITY_CLASS("onslaught_generator", it.health <= 0, {
+                       IL_EACH(g_onsgenerators, it.health <= 0,
+                       {
                                gen = it;
                                break;
                        });
@@ -1784,13 +1785,6 @@ void CSQC_UpdateView(entity this, float w, float h)
 
        switchweapon = Weapons_from(STAT(SWITCHWEAPON));
 
-       f = (serverflags & SERVERFLAG_TEAMPLAY);
-       if(f != teamplay)
-       {
-               teamplay = f;
-               Scoreboard_InitScores();
-       }
-
        if(last_switchweapon != switchweapon)
        {
                weapontime = time;
index f528eee6db46aab5a426d78d60739db50ae83f7d..5177c9dfd17320b7a3bc4dfa577639a608637ba8 100644 (file)
@@ -43,7 +43,7 @@ float autocvar_net_connecttimeout = 30;
 
 #include "items/_mod.inc"
     #include "weapons/_all.inc"
-        #include "monsters/all.qc"
+        #include "monsters/_mod.inc"
         #include "turrets/all.qc"
         #include "vehicles/all.qc"
 
index ab389278d16fcd696d850af106c59947b4108da6..b53a9ba0e9cbf6123d7438736785e8206200358a 100644 (file)
@@ -1,6 +1,6 @@
 #include "animdecide.qh"
 
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
 
 #if defined(SVQC)
     #include "util.qh"
index 80a3f5edddf0edc00831f13e54e22271a3a97bb2..181511cc1a1cb819e4ddf94ea691038647bdfd2f 100644 (file)
@@ -154,10 +154,9 @@ USING(PlayerScoreField, entity);
 REGISTER_SP(END);
 
 REGISTER_SP(PING);
+REGISTER_SP(PL);
 REGISTER_SP(NAME);
 REGISTER_SP(KDRATIO);
-REGISTER_SP(CLRATIO);
-REGISTER_SP(PL);
 REGISTER_SP(SUM);
 
 REGISTER_SP(SEPARATOR);
index 83a6941213d627dbeca64e0174cc9e662696310e..dd3785b68ea2cf65af3fb5ecc5c77f86c0b102e0 100644 (file)
@@ -5,7 +5,10 @@
 entityclass(Rubble);
 class(Rubble).float creationtime;
 
-void RubbleLimit(string cname, float limit, void(entity) deleteproc)
+IntrusiveList g_rubble;
+STATIC_INIT(g_rubble) { g_rubble = IL_NEW(); }
+
+void RubbleLimit(string cname, int limit, void(entity) deleteproc)
 {
        // remove rubble of the same type if it's at the limit
        // remove multiple rubble if the limit has been decreased
@@ -17,7 +20,7 @@ void RubbleLimit(string cname, float limit, void(entity) deleteproc)
                entity oldest = NULL;
                float oldesttime = 0;
                // compare to all other matching entities
-               FOREACH_ENTITY_CLASS(cname, true,
+               IL_EACH(g_rubble, it.classname == cname,
                {
                        ++c;
                        if(!oldest || oldesttime > it.creationtime)
@@ -41,6 +44,7 @@ entity RubbleNew(string cname)
        entity e = spawn();
        e.classname = cname;
        e.creationtime = time;
+       IL_PUSH(g_rubble, e);
        return e;
 }
 
index 41183d85b21d5c505b4becc57bba4f1df396971c..17ee08e7cf14937037696112f4a7edf941c2ab4e 100644 (file)
@@ -1,45 +1,51 @@
 #include "ent_cs.qh"
 
-// #define PROP(public, fld, sv, cl)
-#define ENTCS_NETPROPS(PROP) \
-       PROP(true, sv_entnum, \
-       { WriteByte(chan, etof(player) - 1); }, \
-       { this.sv_entnum = ReadByte(); }) \
-    \
-       PROP(false, origin, \
+#define ENTCS_SET_NORMAL(var, x) MACRO_BEGIN \
+       var = x; \
+MACRO_END
+
+/** the engine player name strings are mutable! */
+#define ENTCS_SET_MUTABLE_STRING(var, x) MACRO_BEGIN \
+       if (var) strunzone(var); \
+       var = strzone(x); \
+MACRO_END
+
+// #define PROP(public, fld, set, sv, cl)
+#define ENTCS_NETPROPS(PROP) PROP(false, sv_entnum, ENTCS_SET_NORMAL, {}, {}) /* sentinel */ \
+       PROP(false, origin, ENTCS_SET_NORMAL, \
        { WriteShort(chan, this.origin.x);  WriteShort(chan, this.origin.y); \
          WriteShort(chan, this.origin.z); }, \
        { this.has_sv_origin = true; vector v; v.x = ReadShort(); v.y = ReadShort(); v.z = ReadShort(); setorigin(this, v); }) \
     \
-       PROP(false, angles_y, \
+       PROP(false, angles_y, ENTCS_SET_NORMAL, \
        { WriteByte(chan, this.angles.y / 360 * 256); }, \
        { vector v = '0 0 0'; v.y = ReadByte() / 256 * 360; this.angles = v; }) \
     \
-       PROP(false, health, \
+       PROP(false, health, ENTCS_SET_NORMAL, \
        { WriteByte(chan, bound(0, this.health / 10, 255));  /* FIXME: use a better scale? */ }, \
        { this.healthvalue = ReadByte() * 10; }) \
     \
-       PROP(false, armorvalue, \
+       PROP(false, armorvalue, ENTCS_SET_NORMAL, \
        { WriteByte(chan, bound(0, this.armorvalue / 10, 255));  /* FIXME: use a better scale? */ }, \
        { this.armorvalue = ReadByte() * 10; }) \
     \
-       PROP(true, netname, \
+       PROP(true, netname, ENTCS_SET_MUTABLE_STRING, \
        { WriteString(chan, this.netname); }, \
        { if (this.netname) strunzone(this.netname); this.netname = strzone(ReadString()); }) \
     \
-       PROP(true, model, \
+       PROP(true, model, ENTCS_SET_NORMAL, \
        { WriteString(chan, this.model); }, \
        { if (this.model) strunzone(this.model); this.model = strzone(ReadString()); }) \
     \
-       PROP(true, skin, \
+       PROP(true, skin, ENTCS_SET_NORMAL, \
        { WriteByte(chan, this.skin); }, \
        { this.skin = ReadByte(); }) \
     \
-    PROP(true, clientcolors, \
+    PROP(true, clientcolors, ENTCS_SET_NORMAL, \
        { WriteByte(chan, this.clientcolors); }, \
        { this.colormap = ReadByte(); }) \
     \
-    PROP(true, frags, \
+    PROP(true, frags, ENTCS_SET_NORMAL, \
        { WriteShort(chan, this.frags); }, \
        { this.frags = ReadShort(); }) \
     \
        int ENTCS_PUBLICMASK = 0;
        STATIC_INIT(ENTCS_PUBLICMASK)
        {
-               int i = 1;
-               #define X(public, fld, sv, cl) { if (public) ENTCS_PUBLICMASK |= BIT(i); } i += 1;
+               int i = 0;
+               #define X(public, fld, set, sv, cl) { \
+                       if (public) { \
+                               ENTCS_PUBLICMASK |= BIT(i); \
+                       } \
+                       i += 1; \
+               }
                ENTCS_NETPROPS(X);
        #undef X
                if (i >= BITS(16 - 1)) LOG_FATAL("Exceeded ENTCS_NETPROPS limit");
        bool _entcs_send(entity this, entity to, int sf, int chan)
        {
                entity player = this.owner;
-               sf |= BIT(0) | BIT(1);
-               if (IS_PLAYER(to) || to.caplayer)                                  // unless spectating,
-               {
-                       bool same_team = (to == player) || (teamplay && player.team == to.team);
-                       if (!same_team && !radar_showennemies) sf &= ENTCS_PUBLICMASK; // no private updates
-               }
+               sf |= BIT(0); // assume private
+               do {
+                       if (radar_showennemies) break;
+                       if (SAME_TEAM(to, player)) break;
+                       if (!(IS_PLAYER(to) || to.caplayer) && time > game_starttime) break;
+                       sf &= ENTCS_PUBLICMASK; // no private updates
+               } while (0);
                sf |= this.m_forceupdate;
                this.m_forceupdate = 0;
-               bool valid =
-                       time > game_starttime
-                   && (IS_PLAYER(player)          // player must be active
-                   || player == to)               // player is self
-               ;
-               if (!valid) sf = 0;
                if (chan == MSG_ENTITY)
                        WriteHeader(chan, ENT_CLIENT_ENTCS);
                else
                        WriteHeader(chan, CLIENT_ENTCS);
                WriteByte(chan, etof(player) - 1);
                WriteShort(chan, sf);
-               int i = 1;
-               #define X(public, fld, sv, cl) { if (sf & BIT(i)) sv; } i += 1;
+               int i = 0;
+               #define X(public, fld, set, sv, cl) { \
+                       if (sf & BIT(i)) { \
+                               sv; \
+                       } \
+                       i += 1; \
+               }
                ENTCS_NETPROPS(X);
        #undef X
                return true;
        {
                this.nextthink = time + 0.033333333333;  // TODO: increase this to like 0.15 once the client can do smoothing
                entity o = this.owner;
-               int i = 1;
-               #define X(public, fld, sv, cl) \
-                       if (o.fld != this.fld) \
-                       { \
-                               this.fld = o.fld; \
+               int i = 0;
+               #define X(public, fld, set, sv, cl) { \
+                       if (o.fld != this.fld) { \
+                               set(this.fld, o.fld); \
                                this.SendFlags |= BIT(i); \
                        } \
-                       i += 1;
+                       i += 1; \
+               }
                ENTCS_NETPROPS(X);
        #undef X
            setorigin(this, this.origin);  // relink
        {
                int n = ReadByte();
                entity e = entcs_receiver(n);
+               #define X(e) { \
+                       setthink(e, entcs_think); \
+                       entcs_receiver(n, e); \
+               }
                if (e == NULL)
                {
-                       if (this)
+                       if (!this)
                        {
-                               e = this;
+                               // initial = temp
+                               e = new_pure(entcs_receiver);
+                               X(e);
                        }
                        else
                        {
-                               e = new(entcs_receiver);
-                               make_pure(e);
+                               // initial = linked
+                               e = this;
+                               X(e);
                        }
-                       e.sv_entnum = n;
-                       setthink(e, entcs_think);
-                       entcs_receiver(n, e);
                }
-               else if (this && e != this)
+               else if (e != this && this)
                {
-                       this.classname = "entcs_gc";
-                       this.sv_entnum = n;
+                       // upgrade to linked
+                       delete(e);
+                       e = this;
+                       X(e);
                }
-               this = e;
-               InterpolateOrigin_Undo(this);
-               this.sv_entnum = n;
+               #undef X
+               InterpolateOrigin_Undo(e);
+               e.sv_entnum = n;
                int sf = ReadShort();
-               this.has_sv_origin = false;
-               this.m_entcs_private = boolean(sf & BIT(0));
-               int i = 1;
-               #define X(public, fld, sv, cl) { if (sf & BIT(i)) cl; } i += 1;
+               e.has_sv_origin = false;
+               e.m_entcs_private = boolean(sf & BIT(0));
+               int i = 0;
+               #define X(public, fld, set, sv, cl) { \
+                       if (sf & BIT(i)) { \
+                               cl; \
+                       } \
+                       i += 1; \
+               }
                ENTCS_NETPROPS(X);
        #undef X
-               this.iflags |= IFLAG_ORIGIN;
-               InterpolateOrigin_Note(this);
-               getthink(this)(this);
+               e.iflags |= IFLAG_ORIGIN;
+               InterpolateOrigin_Note(e);
+               getthink(e)(e);
                return true;
        }
 
index 9c6c9f0803941379bb39e765980cd4bc6361b133..0054fd63607b1523c5b729382e1fe52c593da6d9 100644 (file)
@@ -835,6 +835,7 @@ void W_Nexball_Attack2(entity actor, .entity weaponentity)
        missile.effects = EF_BRIGHTFIELD | EF_LOWPRECISION;
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
 
        CSQCProjectile(missile, true, PROJECTILE_ELECTRO, true);
 }
index fb8cb71719a2e4acea5a10718a737eb4f54d50bb..ee348fdbc6244707f53e7b6202aae30cd6392ea7 100644 (file)
@@ -104,7 +104,7 @@ void cpicon_damage(entity this, float hp)
        setsize(this, CPICON_MIN, CPICON_MAX);
 }
 
-void cpicon_construct(entity this)
+void cpicon_construct(entity this, bool isnew)
 {
        this.netname = "Control Point Icon";
 
@@ -133,6 +133,9 @@ void cpicon_construct(entity this)
        this.cp_origin          = this.origin;
        this.cp_bob_origin      = '0 0 0.1';
        this.cp_bob_spd         = 0;
+
+       if(isnew)
+               IL_PUSH(g_drawables, this);
 }
 
 .vector glowmod;
@@ -174,7 +177,7 @@ NET_HANDLE(ENT_CLIENT_CONTROLPOINT_ICON, bool isnew)
                        this.count = (this.health - this.max_health) * frametime;
 
                cpicon_changeteam(this);
-               cpicon_construct(this);
+               cpicon_construct(this, isnew);
        }
 
        if(sf & CPSF_STATUS)
index 2b9470f7750ab2b9fecac82a5abe51590811e6bb..cbba9a9aaa87bc23d183b18b224f9fd508d91080 100644 (file)
@@ -143,11 +143,14 @@ void generator_damage(entity this, float hp)
        setsize(this, GENERATOR_MIN, GENERATOR_MAX);
 }
 
-void generator_construct(entity this)
+void generator_construct(entity this, bool isnew)
 {
        this.netname = "Generator";
        this.classname = "onslaught_generator";
 
+       if(isnew)
+               IL_PUSH(g_onsgenerators, this);
+
        setorigin(this, this.origin);
        setmodel(this, MDL_ONS_GEN);
        setsize(this, GENERATOR_MIN, GENERATOR_MAX);
@@ -199,7 +202,7 @@ NET_HANDLE(ENT_CLIENT_GENERATOR, bool isnew)
                        this.count = 40;
 
                generator_changeteam(this);
-               generator_construct(this);
+               generator_construct(this, isnew);
        }
 
        if(sf & GSF_STATUS)
index be9b8203c61e60db594ea0579506e2c4ad9ca5f5..c863e2f71fb264d25ba52809ad1f2edaa87d59ad 100644 (file)
@@ -2,3 +2,13 @@
 
 REGISTER_NET_LINKED(ENT_CLIENT_GENERATOR)
 REGISTER_NET_LINKED(ENT_CLIENT_CONTROLPOINT_ICON)
+
+#ifdef SVQC
+IntrusiveList g_onsshields;
+STATIC_INIT(g_onsshields) { g_onsshields = IL_NEW(); }
+#endif
+
+#ifdef CSQC
+IntrusiveList g_onsgenerators;
+STATIC_INIT(g_onsgenerators) { g_onsgenerators = IL_NEW(); }
+#endif
index 570bc3645fdbbe1104e201b0a2a94fce3a410e44..8e60bc30897a4ac897ea19c594630b68987989a3 100644 (file)
@@ -74,6 +74,7 @@ void ons_CaptureShield_Reset(entity this)
 void ons_CaptureShield_Spawn(entity generator, bool is_generator)
 {
        entity shield = new(ons_captureshield);
+       IL_PUSH(g_onsshields, shield);
 
        shield.enemy = generator;
        shield.team = generator.team;
@@ -195,12 +196,16 @@ void onslaught_updatelinks()
                {
                        LOG_DEBUG(etos(l), " (generator) is shielded");
                        l.takedamage = DAMAGE_NO;
+                       if(l.bot_attack)
+                               IL_REMOVE(g_bot_targets, l);
                        l.bot_attack = false;
                }
                else
                {
                        LOG_DEBUG(etos(l), " (generator) is not shielded");
                        l.takedamage = DAMAGE_AIM;
+                       if(!l.bot_attack)
+                               IL_PUSH(g_bot_targets, l);
                        l.bot_attack = true;
                }
 
@@ -215,6 +220,8 @@ void onslaught_updatelinks()
                        if (l.goalentity)
                        {
                                l.goalentity.takedamage = DAMAGE_NO;
+                               if(l.goalentity.bot_attack)
+                                       IL_REMOVE(g_bot_targets, l.goalentity);
                                l.goalentity.bot_attack = false;
                        }
                }
@@ -224,12 +231,14 @@ void onslaught_updatelinks()
                        if (l.goalentity)
                        {
                                l.goalentity.takedamage = DAMAGE_AIM;
+                               if(!l.goalentity.bot_attack)
+                                       IL_PUSH(g_bot_targets, l.goalentity);
                                l.goalentity.bot_attack = true;
                        }
                }
                ons_ControlPoint_UpdateSprite(l);
        }
-       FOREACH_ENTITY_CLASS("ons_captureshield", true,
+       IL_EACH(g_onsshields, true,
        {
                it.team = it.enemy.team;
                it.colormap = it.enemy.colormap;
@@ -565,6 +574,7 @@ void ons_ControlPoint_Icon_Spawn(entity cp, entity player)
        e.solid = SOLID_NOT;
        e.takedamage = DAMAGE_AIM;
        e.bot_attack = true;
+       IL_PUSH(g_bot_targets, e);
        e.event_damage = ons_ControlPoint_Icon_Damage;
        e.team = player.team;
        e.colormap = 1024 + (e.team - 1) * 17;
@@ -916,6 +926,7 @@ void ons_GeneratorReset(entity this)
        this.lasthealth = this.max_health = this.health = autocvar_g_onslaught_gen_health;
        this.takedamage = DAMAGE_AIM;
        this.bot_attack = true;
+       IL_PUSH(g_bot_targets, this);
        this.iscaptured = true;
        this.islinked = true;
        this.isshielded = true;
@@ -978,6 +989,7 @@ void ons_GeneratorSetup(entity gen) // called when spawning a generator entity o
        gen.lasthealth = gen.max_health = gen.health = autocvar_g_onslaught_gen_health;
        gen.takedamage = DAMAGE_AIM;
        gen.bot_attack = true;
+       IL_PUSH(g_bot_targets, gen);
        gen.event_damage = ons_GeneratorDamage;
        gen.reset = ons_GeneratorReset;
        setthink(gen, ons_GeneratorThink);
@@ -1182,7 +1194,7 @@ void havocbot_goalrating_ons_offenseitems(entity this, float ratingscale, vector
        LOG_DEBUG(this.netname, " needs armor ", ftos(needarmor));
 
        // See what is around
-       FOREACH_ENTITY_FLOAT(bot_pickup, true,
+       IL_EACH(g_items, it.bot_pickup,
        {
                // gather health and armor only
                if (it.solid)
@@ -1463,21 +1475,21 @@ void havocbot_ons_reset_role(entity this)
 entity ons_Nearest_ControlPoint(entity this, vector pos, float max_dist)
 {
        entity closest_target = NULL;
-       FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
+       for(entity cp = ons_worldcplist; cp; cp = cp.ons_worldcpnext)
        {
-               if(SAME_TEAM(it, this))
-               if(it.iscaptured)
-               if(max_dist <= 0 || vdist(it.origin - pos, <=, max_dist))
-               if(vlen2(it.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
-                       closest_target = it;
-       });
-       FOREACH_ENTITY_CLASS("onslaught_generator", true,
+               if(SAME_TEAM(cp, this))
+               if(cp.iscaptured)
+               if(max_dist <= 0 || vdist(cp.origin - pos, <=, max_dist))
+               if(vlen2(cp.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
+                       closest_target = cp;
+       }
+       for(entity gen = ons_worldgeneratorlist; gen; gen = gen.ons_worldgeneratornext)
        {
-               if(SAME_TEAM(it, this))
-               if(max_dist <= 0 || vdist(it.origin - pos, <, max_dist))
-               if(vlen2(it.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
-                       closest_target = it;
-       });
+               if(SAME_TEAM(gen, this))
+               if(max_dist <= 0 || vdist(gen.origin - pos, <, max_dist))
+               if(vlen2(gen.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
+                       closest_target = gen;
+       }
 
        return closest_target;
 }
@@ -1493,35 +1505,35 @@ entity ons_Nearest_ControlPoint_2D(entity this, vector pos, float max_dist)
        vector delta;
        float smallest_distance = 0, distance;
 
-       FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
+       for(entity cp = ons_worldcplist; cp; cp = cp.ons_worldcpnext)
        {
-               delta = it.origin - pos;
+               delta = cp.origin - pos;
                delta_z = 0;
                distance = vlen(delta);
 
-               if(SAME_TEAM(it, this))
-               if(it.iscaptured)
+               if(SAME_TEAM(cp, this))
+               if(cp.iscaptured)
                if(max_dist <= 0 || distance <= max_dist)
                if(closest_target == NULL || distance <= smallest_distance )
                {
-                       closest_target = it;
+                       closest_target = cp;
                        smallest_distance = distance;
                }
-       });
-       FOREACH_ENTITY_CLASS("onslaught_generator", true,
+       }
+       for(entity gen = ons_worldgeneratorlist; gen; gen = gen.ons_worldgeneratornext)
        {
-               delta = it.origin - pos;
+               delta = gen.origin - pos;
                delta_z = 0;
                distance = vlen(delta);
 
-               if(SAME_TEAM(it, this))
+               if(SAME_TEAM(gen, this))
                if(max_dist <= 0 || distance <= max_dist)
                if(closest_target == NULL || distance <= smallest_distance )
                {
-                       closest_target = it;
+                       closest_target = gen;
                        smallest_distance = distance;
                }
-       });
+       }
 
        return closest_target;
 }
@@ -1531,17 +1543,17 @@ entity ons_Nearest_ControlPoint_2D(entity this, vector pos, float max_dist)
 int ons_Count_SelfControlPoints(entity this)
 {
        int n = 0;
-       FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
+       for(entity cp = ons_worldcplist; cp; cp = cp.ons_worldcpnext)
        {
-               if(SAME_TEAM(it, this))
-               if(it.iscaptured)
+               if(SAME_TEAM(cp, this))
+               if(cp.iscaptured)
                        n++;
-       });
-       FOREACH_ENTITY_CLASS("onslaught_generator", true,
+       }
+       for(entity gen = ons_worldgeneratorlist; gen; gen = gen.ons_worldgeneratornext)
        {
-               if(SAME_TEAM(it, this))
+               if(SAME_TEAM(gen, this))
                        n++;
-       });
+       }
        return n;
 }
 
index 70a5c8b6ba999078cb459c8933e2c11f7ab660e8..750ade34b412ece9a6b8a868c4cc747367407ae1 100644 (file)
@@ -44,7 +44,6 @@ const vector CPICON_OFFSET = ('0 0 96');
 // list of generators on the map
 entity ons_worldgeneratorlist;
 .entity ons_worldgeneratornext;
-.entity ons_stalegeneratornext;
 
 // list of control points on the map
 entity ons_worldcplist;
index f3213527ba48167611a8f842e45af3738e9dad85..7120c61eda932fa46b9cc2313dc26c8854549293 100644 (file)
@@ -6,7 +6,7 @@
 #elif defined(MENUQC)
 #elif defined(SVQC)
     #include "util.qh"
-    #include <common/monsters/all.qh>
+    #include <common/monsters/_mod.qh>
 #endif
 
 // generic string stuff
@@ -376,7 +376,7 @@ float _MapInfo_Generate(string pFilename) // 0: failure, 1: ok ent, 2: ok bsp
        }
        if(inWorldspawn)
        {
-               LOG_MAPWARN(fn, " ended still in worldspawn, BUG\n");
+               LOG_WARN(fn, " ended still in worldspawn, BUG");
                return 0;
        }
        diameter = vlen(mapMaxs - mapMins);
@@ -547,7 +547,7 @@ void _MapInfo_Map_ApplyGametypeEx(string s, Gametype pWantedType, Gametype pThis
                if (sa == "") continue;
                int p = strstrofs(sa, "=", 0);
                if (p < 0) {
-                       LOG_MAPWARNF("Invalid gametype setting in mapinfo for gametype %s: %s\n", MapInfo_Type_ToString(pWantedType), sa);
+                       LOG_WARNF("Invalid gametype setting in mapinfo for gametype %s: %s", MapInfo_Type_ToString(pWantedType), sa);
                        continue;
                }
                string k = substring(sa, 0, p);
@@ -587,7 +587,7 @@ void _MapInfo_Map_ApplyGametypeEx(string s, Gametype pWantedType, Gametype pThis
                }
                FOREACH(Gametypes, true, handled |= it.m_parse_mapinfo(k, v));
                if (!handled)
-            LOG_MAPWARNF("Invalid gametype setting in mapinfo for gametype %s: %s\n", MapInfo_Type_ToString(pWantedType), sa);
+            LOG_WARNF("Invalid gametype setting in mapinfo for gametype %s: %s", MapInfo_Type_ToString(pWantedType), sa);
        }
 
        if (pWantedType == MAPINFO_TYPE_RACE && cvar("g_race_teams") >= 2)
@@ -607,7 +607,7 @@ Gametype MapInfo_Type_FromString(string t)
 #define deprecate(from, to) MACRO_BEGIN { \
        if (t == #from) { \
                string replacement = #to; \
-               LOG_MAPWARNF("MapInfo_Type_FromString (probably %s): using deprecated name '%s'. Should use '%s'.\n", MapInfo_Map_bspname, t, replacement); \
+               LOG_WARNF("MapInfo_Type_FromString (probably %s): using deprecated name '%s'. Should use '%s'.", MapInfo_Map_bspname, t, replacement); \
                t = replacement; \
        } \
 } MACRO_END
@@ -677,7 +677,7 @@ void _MapInfo_Parse_Settemp(string pFilename, string acl, float type, string s,
                {
                        fh = fopen(s, FILE_READ);
                        if(fh < 0)
-                               LOG_MAPWARN("Map ", pFilename, " references not existing config file ", s, "\n");
+                               LOG_WARN("Map ", pFilename, " references not existing config file ", s);
                        else
                        {
                                for (;;)
@@ -706,18 +706,18 @@ void _MapInfo_Parse_Settemp(string pFilename, string acl, float type, string s,
                        }
                }
                else
-                       LOG_MAPWARN("Map ", pFilename, " uses too many levels of inclusion\n");
+                       LOG_WARN("Map ", pFilename, " uses too many levels of inclusion");
        }
        else if(t == "")
-               LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+               LOG_WARN("Map ", pFilename, " contains a potentially harmful setting, ignored");
        else if (!cvar_value_issafe(t))
-               LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+               LOG_WARN("Map ", pFilename, " contains a potentially harmful setting, ignored");
        else if (!cvar_value_issafe(s))
-               LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+               LOG_WARN("Map ", pFilename, " contains a potentially harmful setting, ignored");
        else if(matchacl(MAPINFO_SETTEMP_ACL_SYSTEM, t) <= 0)
-               LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful setting, ignored\n");
+               LOG_WARN("Map ", pFilename, " contains a potentially harmful setting, ignored");
        else if(matchacl(acl, t) <= 0)
-               LOG_MAPWARN("Map ", pFilename, " contains a denied setting, ignored\n");
+               LOG_WARN("Map ", pFilename, " contains a denied setting, ignored");
        else
        {
                if(type == 0) // server set
@@ -777,7 +777,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
 
        if(strstrofs(pFilename, "/", 0) >= 0)
        {
-               LOG_MAPWARN("Invalid character in map name, ignored\n");
+               LOG_WARN("Invalid character in map name, ignored");
                return 0;
        }
 
@@ -867,7 +867,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
                                error("... but I just wrote it!");
                }
 
-               LOG_MAPWARN("autogenerated mapinfo file ", fn, " has been loaded; please edit that file and move it to maps/", pFilename, ".mapinfo\n");
+               LOG_WARN("autogenerated mapinfo file ", fn, " has been loaded; please edit that file and move it to maps/", pFilename, ".mapinfo");
        }
 
        _MapInfo_Map_Reset();
@@ -906,7 +906,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
                        else if(t == "monsters") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_MONSTERS;
                        else if(t == "new_toys") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_WEAPONS;
                        else
-                               LOG_MAPWARN("Map ", pFilename, " supports unknown feature ", t, ", ignored\n");
+                               LOG_WARN("Map ", pFilename, " supports unknown feature ", t, ", ignored");
                }
                else if(t == "hidden")
                {
@@ -933,11 +933,11 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
                {
                        t = car(s); s = cdr(s);
                        Gametype f = MapInfo_Type_FromString(t);
-                       LOG_MAPWARN("Map ", pFilename, " contains the legacy 'type' keyword which is deprecated and will be removed in the future. Please migrate the mapinfo file to 'gametype'.\n");
+                       LOG_WARN("Map ", pFilename, " contains the legacy 'type' keyword which is deprecated and will be removed in the future. Please migrate the mapinfo file to 'gametype'.");
                        if(f)
                                _MapInfo_Map_ApplyGametype (s, pGametypeToSet, f, true);
                        else
-                               LOG_MAPWARN("Map ", pFilename, " supports unknown game type ", t, ", ignored\n");
+                               LOG_WARN("Map ", pFilename, " supports unknown game type ", t, ", ignored");
                }
                else if(t == "gametype")
                {
@@ -946,7 +946,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
                        if(f)
                                _MapInfo_Map_ApplyGametypeEx (s, pGametypeToSet, f);
                        else
-                               LOG_MAPWARN("Map ", pFilename, " supports unknown game type ", t, ", ignored\n");
+                               LOG_WARN("Map ", pFilename, " supports unknown game type ", t, ", ignored");
                }
                else if(t == "size")
                {
@@ -957,16 +957,16 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
                        t = car(s); s = cdr(s); d = stof(t);
                        t = car(s); s = cdr(s); e = stof(t);
                        if(s == "")
-                               LOG_MAPWARN("Map ", pFilename, " contains an incorrect size line (not enough params), syntax: size mins_x mins_y mins_z maxs_x maxs_y maxs_z\n");
+                               LOG_WARN("Map ", pFilename, " contains an incorrect size line (not enough params), syntax: size mins_x mins_y mins_z maxs_x maxs_y maxs_z");
                        else
                        {
                                t = car(s); s = cdr(s); f = stof(t);
                                if(s != "")
-                                       LOG_MAPWARN("Map ", pFilename, " contains an incorrect size line (too many params), syntax: size mins_x mins_y mins_z maxs_x maxs_y maxs_z\n");
+                                       LOG_WARN("Map ", pFilename, " contains an incorrect size line (too many params), syntax: size mins_x mins_y mins_z maxs_x maxs_y maxs_z");
                                else
                                {
                                        if(a >= d || b >= e || c >= f)
-                                               LOG_MAPWARN("Map ", pFilename, " contains an incorrect size line, mins have to be < maxs\n");
+                                               LOG_WARN("Map ", pFilename, " contains an incorrect size line, mins have to be < maxs");
                                        else
                                        {
                                                MapInfo_Map_mins.x = a;
@@ -982,39 +982,41 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
                else if(t == "settemp_for_type")
                {
                        t = car(s); s = cdr(s);
-                       Gametype f;
-                       if((f = MapInfo_Type_FromString(t)))
+                       bool all = t == "all";
+                       Gametype f = NULL;
+                       if(all || (f = MapInfo_Type_FromString(t)))
                        {
-                               if(f.m_flags & pGametypeToSet.m_flags)
+                               if((all ? MAPINFO_TYPE_ALL : f.m_flags) & pGametypeToSet.m_flags)
                                {
                                        _MapInfo_Parse_Settemp(pFilename, acl, 0, s, 1);
                                }
                        }
                        else
                        {
-                               LOG_MAPWARN("Map ", pFilename, " has a setting for unknown game type ", t, ", ignored\n");
+                               LOG_WARN("Map ", pFilename, " has a setting for unknown game type ", t, ", ignored");
                        }
                }
                else if(t == "clientsettemp_for_type")
                {
                        t = car(s); s = cdr(s);
-                       Gametype f;
-                       if((f = MapInfo_Type_FromString(t)))
+                       bool all = t == "all";
+                       Gametype f = NULL;
+                       if(all || (f = MapInfo_Type_FromString(t)))
                        {
-                               if(f.m_flags & pGametypeToSet.m_flags)
+                               if((all ? MAPINFO_TYPE_ALL : f.m_flags) & pGametypeToSet.m_flags)
                                {
                                        _MapInfo_Parse_Settemp(pFilename, acl, 1, s, 1);
                                }
                        }
                        else
                        {
-                               LOG_MAPWARN("Map ", pFilename, " has a client setting for unknown game type ", t, ", ignored\n");
+                               LOG_WARN("Map ", pFilename, " has a client setting for unknown game type ", t, ", ignored");
                        }
                }
                else if(t == "fog")
                {
                        if (!cvar_value_issafe(s))
-                               LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful fog setting, ignored\n");
+                               LOG_WARN("Map ", pFilename, " contains a potentially harmful fog setting, ignored");
                        else
                                MapInfo_Map_fog = s;
                }
@@ -1030,7 +1032,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
                        if(pGametypeToSet)
                        {
                                if (!cvar_value_issafe(t))
-                                       LOG_MAPWARN("Map ", pFilename, " contains a potentially harmful cdtrack, ignored\n");
+                                       LOG_WARN("Map ", pFilename, " contains a potentially harmful cdtrack, ignored");
                                else
                                        MapInfo_Map_clientstuff = strcat(
                                                MapInfo_Map_clientstuff, "cd loop \"", t, "\"\n"
@@ -1038,7 +1040,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
                        }
                }
                else
-                       LOG_MAPWARN("Map ", pFilename, " provides unknown info item ", t, ", ignored\n");
+                       LOG_WARN("Map ", pFilename, " provides unknown info item ", t, ", ignored");
        }
        fclose(fh);
 
@@ -1052,7 +1054,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, int pAllowGenerate, Gamet
        MapInfo_Cache_Store();
        if(MapInfo_Map_supportedGametypes != 0)
                return r;
-       LOG_MAPWARN("Map ", pFilename, " supports no game types, ignored\n");
+       LOG_WARN("Map ", pFilename, " supports no game types, ignored");
        return 0;
 }
 int MapInfo_Get_ByName(string pFilename, float pAllowGenerate, Gametype pGametypeToSet)
@@ -1259,10 +1261,11 @@ void MapInfo_LoadMapSettings(string s) // to be called from worldspawn
                        _t <<= 1;
                        MapInfo_Map_supportedGametypes = floor(MapInfo_Map_supportedGametypes >> 1);
                }
+               Gametype t_prev = t;
                FOREACH(Gametypes, it.m_flags == _t, { t = it; break; });
 
                // t is now a supported mode!
-               LOG_WARN("can't play the selected map in the given game mode. Falling back to a supported mode.");
+               LOG_WARNF("can't play the selected map in the given game mode (%s). Falling back to a supported mode (%s).", t_prev.mdl, t.mdl);
                MapInfo_LoadMapSettings_SaveGameType(t);
        }
        MapInfo_Get_ByName(s, 1, t);
index f37e2db060881e23088652e012926e668b731216..a3e000d33351fde6a8f9edb97808375d434670cd 100644 (file)
@@ -1,10 +1,5 @@
 #pragma once
 
-bool autocvar_developer_mapper;
-
-#define LOG_MAPWARN(...) MACRO_BEGIN { if (autocvar_developer_mapper) LOG_WARN(__VA_ARGS__); } MACRO_END
-#define LOG_MAPWARNF(...) MACRO_BEGIN { if (autocvar_developer_mapper) LOG_WARNF(__VA_ARGS__); } MACRO_END
-
 #include "util.qh"
 
 // info about a map that MapInfo loads
@@ -448,7 +443,7 @@ void HUD_Mod_Keepaway(vector pos, vector mySize);
 CLASS(Keepaway, Gametype)
     INIT(Keepaway)
     {
-        this.gametype_init(this, _("Keepaway"),"ka","g_keepaway",true,"","timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
+        this.gametype_init(this, _("Keepaway"),"ka","g_keepaway",false,"","timelimit=20 pointlimit=30",_("Hold the ball to get points for kills"));
     }
     METHOD(Keepaway, m_isAlwaysSupported, bool(Gametype this, int spawnpoints, float diameter))
     {
index 12d2f06d18caecf4bbf6f07d8f803e5ef5073544..a359831dfdd3cb74535c790c34f71b5ba9723721 100644 (file)
@@ -682,13 +682,8 @@ void HUD_Minigame_Mouse()
        if( !HUD_MinigameMenu_IsOpened() || autocvar__hud_configure || mv_active )
                return;
 
-       if(!autocvar_hud_cursormode)
-       {
-               mousepos = mousepos + getmousepos() * autocvar_menu_mouse_speed;
-
-               mousepos_x = bound(0, mousepos_x, vid_conwidth);
-               mousepos_y = bound(0, mousepos_y, vid_conheight);
-       }
+       if (!autocvar_hud_cursormode)
+               update_mousepos();
 
        if ( HUD_MinigameMenu_IsOpened() && HUD_mouse_over(HUD_PANEL(MINIGAME_MENU)) )
                HUD_MinigameMenu_MouseInput();
diff --git a/qcsrc/common/monsters/_all.inc b/qcsrc/common/monsters/_all.inc
deleted file mode 100644 (file)
index 8bc63f7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_all.qh"
-#include "_mod.inc"
diff --git a/qcsrc/common/monsters/_all.qh b/qcsrc/common/monsters/_all.qh
deleted file mode 100644 (file)
index 947026d..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-#pragma once
-#include "_mod.qh"
index 0478f09eec10f3bfcddac8995a4b3b14f9be81e9..be50e5503f70f2d660263fd15f68c98aa991bd40 100644 (file)
@@ -1,6 +1,10 @@
 // generated file; do not modify
 #include <common/monsters/all.qc>
-#include <common/monsters/spawn.qc>
 #ifdef SVQC
     #include <common/monsters/sv_monsters.qc>
 #endif
+#ifdef SVQC
+    #include <common/monsters/sv_spawn.qc>
+#endif
+
+#include <common/monsters/monster/_mod.inc>
index 39d594e4c5c99c40e70dc7d70eb3243dbaf9cfce..55204bd1a770ec46b66e48222b6d0ae3fcbf62e7 100644 (file)
@@ -1,6 +1,10 @@
 // generated file; do not modify
 #include <common/monsters/all.qh>
-#include <common/monsters/spawn.qh>
 #ifdef SVQC
     #include <common/monsters/sv_monsters.qh>
 #endif
+#ifdef SVQC
+    #include <common/monsters/sv_spawn.qh>
+#endif
+
+#include <common/monsters/monster/_mod.qh>
index a262a234505008acf2d80c49b0617bd947695ce2..9dc09ca394b47166bc4d717901d0aa17f6465664 100644 (file)
@@ -1,6 +1,4 @@
 #include "all.qh"
-#ifndef MONSTERS_ALL_C
-#define MONSTERS_ALL_C
 
 string M_Model(string m_mdl)
 {
@@ -12,16 +10,3 @@ string M_Model(string m_mdl)
        return output;
 #endif
 }
-
-#include "all.qh"
-
-#define IMPLEMENTATION
-#include "monster/_mod.inc"
-#undef IMPLEMENTATION
-
-#ifdef SVQC
-#include "spawn.qc"
-#include "sv_monsters.qc"
-#endif
-
-#endif
index 84f7a0d78f6d19d4121334681655c170e19f2569..c9e5ad37ba6448ed85374378affde2e871a6197c 100644 (file)
@@ -1,7 +1,5 @@
 #pragma once
 
-#include "monster.qh"
-
 string M_Model(string m_mdl);
 
 REGISTRY(Monsters, BITS(5))
@@ -13,7 +11,6 @@ const int MON_FIRST = 1;
 #define MON_LAST (Monsters_COUNT - 1)
 #define REGISTER_MONSTER(id, inst) REGISTER(Monsters, MON, id, monsterid, inst)
 
-REGISTER_MONSTER(Null, NEW(Monster));
-
+#include "monster.qh"
 
-#include "monster/_mod.inc"
+REGISTER_MONSTER(Null, NEW(Monster));
index 341b92e7b53849b86b5a3b830c7d4173ec7062c5..babf6e4faf19a2f1e1879afd774693a05514c762 100644 (file)
@@ -1,22 +1,5 @@
 #pragma once
 
-#ifdef SVQC
-#include "sv_monsters.qh"
-#include <server/g_damage.qh>
-#include <server/bot/api.qh>
-#include <server/weapons/common.qh>
-#include <server/weapons/tracing.qh>
-#include <server/weapons/weaponsystem.qh>
-#include <common/mutators/mutator/waypoints/waypointsprites.qh>
-#include <lib/warpzone/server.qh>
-#endif
-
-#ifdef GAMEQC
-#include "../animdecide.qh"
-#include "../anim.qh"
-vector animfixfps(entity e, vector a, vector b);
-#endif
-
 // special spawn flags
 const int MONSTER_RESPAWN_DEATHPOINT = 16; // re-spawn where we died
 const int MONSTER_TYPE_FLY = 32;
@@ -73,3 +56,21 @@ CLASS(Monster, Object)
     METHOD(Monster, mr_anim, bool(Monster this, entity actor)) { TC(Monster, this); return false; }
 
 ENDCLASS(Monster)
+
+
+#ifdef SVQC
+#include "sv_monsters.qh"
+#include <server/g_damage.qh>
+#include <server/bot/api.qh>
+#include <server/weapons/common.qh>
+#include <server/weapons/tracing.qh>
+#include <server/weapons/weaponsystem.qh>
+#include <common/mutators/mutator/waypoints/waypointsprites.qh>
+#include <lib/warpzone/server.qh>
+#endif
+
+#ifdef GAMEQC
+#include "../animdecide.qh"
+#include "../anim.qh"
+vector animfixfps(entity e, vector a, vector b);
+#endif
index 650999de1eaf4c7c63e7b295d6b5a6143ed94fb7..30d09807f2f9faf9c4462c30b07c36bb117983e9 100644 (file)
@@ -1,7 +1,5 @@
 #include "mage.qh"
 
-#ifdef IMPLEMENTATION
-
 #ifdef SVQC
 
 SOUND(MageSpike_FIRE, W_Sound("electro_fire"));
@@ -201,6 +199,7 @@ void M_Mage_Attack_Spike(entity this, vector dir)
        set_movetype(missile, MOVETYPE_FLYMISSILE);
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        setorigin(missile, this.origin + v_forward * 14 + '0 0 30' + v_right * -14);
        setsize(missile, '0 0 0', '0 0 0');
        missile.velocity = dir * 400;
@@ -382,10 +381,9 @@ METHOD(Mage, mr_think, bool(Mage thismon, entity actor))
     TC(Mage, thismon);
     bool need_help = false;
 
-    FOREACH_ENTITY_FLOAT(iscreature, true,
+    FOREACH_CLIENT(IS_PLAYER(it) && it != actor,
     {
-        if(it != actor)
-        if(vdist(it.origin - actor.origin, <=, autocvar_g_monster_mage_heal_range))
+       if(vdist(it.origin - actor.origin, <=, autocvar_g_monster_mage_heal_range))
         if(M_Mage_Defend_Heal_Check(actor, it))
         {
             need_help = true;
@@ -393,6 +391,19 @@ METHOD(Mage, mr_think, bool(Mage thismon, entity actor))
         }
     });
 
+    if(!need_help)
+    {
+       IL_EACH(g_monsters, it != actor,
+       {
+               if(vdist(it.origin - actor.origin, <=, autocvar_g_monster_mage_heal_range))
+               if(M_Mage_Defend_Heal_Check(actor, it))
+               {
+                   need_help = true;
+                   break;
+               }
+       });
+    }
+
     if(actor.health < (autocvar_g_monster_mage_heal_minhealth) || need_help)
     if(time >= actor.attack_finished_single[0])
     if(random() < 0.5)
@@ -462,5 +473,3 @@ METHOD(Mage, mr_precache, bool(Mage this))
     return true;
 }
 #endif
-
-#endif
index 04826b39b543da893bb376ab0eefdbb7e9a87400..d78ee5ecf6b7f4bc8f8577a5d68ca93898da3550 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../all.qh"
+
 #ifdef GAMEQC
 MODEL(MON_MAGE, M_Model("mage.dpm"));
 #endif
index 3ba01fe21f226005c15b0bc04d59084e0b923938..8f84bdce31d70778f2989c696a14198f7aa29ac5 100644 (file)
@@ -1,7 +1,5 @@
 #include "shambler.qh"
 
-#ifdef IMPLEMENTATION
-
 #ifdef SVQC
 float autocvar_g_monster_shambler_health;
 float autocvar_g_monster_shambler_damageforcescale = 0.1;
@@ -150,6 +148,7 @@ void M_Shambler_Attack_Lightning(entity this)
        gren.angles = vectoangles (gren.velocity);
        gren.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, gren);
+       IL_PUSH(g_bot_dodge, gren);
 
        CSQCProjectile(gren, true, PROJECTILE_SHAMBLER_LIGHTNING, true);
 }
@@ -273,5 +272,3 @@ METHOD(Shambler, mr_precache, bool(Shambler this))
     return true;
 }
 #endif
-
-#endif
index 0824b55879aaec0745f98f3524df919c77843a3b..f7a3ce3a94f7ad7ee847c2f6ba269bc2e683d9c6 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../all.qh"
+
 #ifdef GAMEQC
 MODEL(MON_SHAMBLER, M_Model("shambler.mdl"));
 #endif
index 43a07e650c419a08f7675279f79df203f0ca517c..d2cb8313e3f022402353736f94ac839da415114b 100644 (file)
@@ -1,7 +1,5 @@
 #include "spider.qh"
 
-#ifdef IMPLEMENTATION
-
 #ifdef SVQC
 
 .float spider_slowness; // effect time of slowness inflicted by spiders
@@ -161,6 +159,7 @@ void M_Spider_Attack_Web(entity this)
        proj.event_damage = func_null;
        proj.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, proj);
+       IL_PUSH(g_bot_dodge, proj);
        proj.damagedbycontents = true;
 
        proj.bouncefactor = 0.3;
@@ -251,5 +250,3 @@ METHOD(Spider, mr_precache, bool(Spider this))
     return true;
 }
 #endif
-
-#endif
index 1da750d4ce74a3dc3eb1bcaefb581eb17fa59e1f..c54eb3a7a8c7a3e9c7cef14d562f8bcfa22eda70 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../all.qh"
+
 #ifdef GAMEQC
 MODEL(MON_SPIDER, M_Model("spider.dpm"));
 #endif
index 48e7ad61dce690da511c00b1cc5191bd3e0f0d2c..3fd7ec967679e05b750349427f0b2b68d6bf1a32 100644 (file)
@@ -1,7 +1,5 @@
 #include "wyvern.qh"
 
-#ifdef IMPLEMENTATION
-
 #ifdef SVQC
 
 float autocvar_g_monster_wyvern_attack_fireball_damage;
@@ -36,6 +34,7 @@ METHOD(WyvernAttack, wr_think, void(WyvernAttack thiswep, entity actor, .entity
                setorigin(missile, actor.origin + actor.view_ofs + v_forward * 14);
                missile.flags = FL_PROJECTILE;
         IL_PUSH(g_projectiles, missile);
+        IL_PUSH(g_bot_dodge, missile);
                missile.velocity = w_shotdir * (autocvar_g_monster_wyvern_attack_fireball_speed);
                missile.avelocity = '300 300 300';
                missile.nextthink = time + 5;
@@ -74,10 +73,9 @@ void M_Wyvern_Attack_Fireball_Explode(entity this)
 
        RadiusDamage(this, own, autocvar_g_monster_wyvern_attack_fireball_damage, autocvar_g_monster_wyvern_attack_fireball_edgedamage, autocvar_g_monster_wyvern_attack_fireball_force, NULL, NULL, autocvar_g_monster_wyvern_attack_fireball_radius, this.projectiledeathtype, NULL);
 
-       FOREACH_ENTITY_FLOAT(takedamage, DAMAGE_AIM,
+       FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_monster_wyvern_attack_fireball_radius, it.takedamage == DAMAGE_AIM,
        {
-               if(vdist(it.origin - this.origin, <=, autocvar_g_monster_wyvern_attack_fireball_radius))
-                       Fire_AddDamage(it, own, 5 * MONSTER_SKILLMOD(own), autocvar_g_monster_wyvern_attack_fireball_damagetime, this.projectiledeathtype);
+               Fire_AddDamage(it, own, 5 * MONSTER_SKILLMOD(own), autocvar_g_monster_wyvern_attack_fireball_damagetime, this.projectiledeathtype);
        });
 
        delete(this);
@@ -173,5 +171,3 @@ METHOD(Wyvern, mr_precache, bool(Wyvern this))
     return true;
 }
 #endif
-
-#endif
index 0982eb176b4090f876d9c644fed2a03dc24369c8..0af84c1301e26e042930bd26519e6fec3dfb93e1 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../all.qh"
+
 #ifdef GAMEQC
 MODEL(MON_WYVERN, M_Model("wizard.mdl"));
 #endif
index 3f43ea0f092a5376494d891b0770bcc04886337a..c48c2108fa2299b80eee1aebdccf5a7da5f4d21b 100644 (file)
@@ -1,7 +1,5 @@
 #include "zombie.qh"
 
-#ifdef IMPLEMENTATION
-
 #ifdef SVQC
 float autocvar_g_monster_zombie_health;
 float autocvar_g_monster_zombie_damageforcescale = 0.55;
@@ -210,5 +208,3 @@ METHOD(Zombie, mr_precache, bool(Zombie this))
     return true;
 }
 #endif
-
-#endif
index c5e243c754a86cbd0189223df03957555268ee83..b52056e71d9d0b58fd394f4bac976dd5f45c4fec 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+#include "../all.qh"
+
 #ifdef GAMEQC
 MODEL(MON_ZOMBIE, M_Model("zombie.dpm"));
 #endif
diff --git a/qcsrc/common/monsters/spawn.qc b/qcsrc/common/monsters/spawn.qc
deleted file mode 100644 (file)
index 6c72ada..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "spawn.qh"
-#if defined(CSQC)
-#elif defined(MENUQC)
-#elif defined(SVQC)
-    #include "../util.qh"
-    #include "all.qh"
-    #include "sv_monsters.qh"
-    #include "spawn.qh"
-    #include <server/autocvars.qh>
-    #include <server/defs.qh>
-#endif
-entity spawnmonster (string monster, float monster_id, entity spawnedby, entity own, vector orig, float respwn, float invincible, float moveflag)
-{
-       float i;
-       entity e = spawn();
-
-       e.spawnflags = MONSTERFLAG_SPAWNED;
-
-       if(!respwn) { e.spawnflags |= MONSTERFLAG_NORESPAWN; }
-       if(invincible) { e.spawnflags |= MONSTERFLAG_INVINCIBLE; }
-
-       setorigin(e, orig);
-
-       if(monster == "random")
-       {
-               RandomSelection_Init();
-               for(i = MON_FIRST; i <= MON_LAST; ++i)
-                       RandomSelection_Add(NULL, i, string_null, 1, 1);
-
-           monster_id = RandomSelection_chosen_float;
-       }
-       else if(monster != "")
-       {
-               float found = 0;
-               entity mon;
-               for(i = MON_FIRST; i <= MON_LAST; ++i)
-               {
-                       mon = get_monsterinfo(i);
-                       if(mon.netname == monster)
-                       {
-                               found = true;
-                               monster_id = mon.monsterid; // we have the monster, old monster id is no longer required
-                               break;
-                       }
-               }
-               if(!found)
-                       monster_id = ((monster_id > 0) ? monster_id : MON_FIRST);
-       }
-
-       e.realowner = spawnedby;
-
-       if(moveflag)
-               e.monster_moveflags = moveflag;
-
-       if(IS_PLAYER(spawnedby))
-       {
-               if(teamplay && autocvar_g_monsters_teams)
-                       e.team = spawnedby.team; // colors handled in spawn code
-
-               if(autocvar_g_monsters_owners)
-                       e.monster_follow = own; // using .owner makes the monster non-solid for its master
-
-               e.angles_y = spawnedby.angles_y;
-       }
-
-       // Monster_Spawn checks if monster is valid
-       Monster_Spawn(e, monster_id);
-
-       return e;
-}
diff --git a/qcsrc/common/monsters/spawn.qh b/qcsrc/common/monsters/spawn.qh
deleted file mode 100644 (file)
index 0aba5c1..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#pragma once
-
-entity spawnmonster (string monster, float monster_id, entity spawnedby, entity own, vector orig, float respwn, float invincible, float moveflag);
index a4f7e6acaace738772fd366d81f499b57a4cdf7c..9ac1f4e14084f0adaa1ec8f40f2047ac14dd2ef9 100644 (file)
@@ -99,10 +99,10 @@ bool Monster_ValidTarget(entity this, entity targ)
                return false;
        }
 
-       traceline(this.origin + this.view_ofs, targ.origin, 0, this);
+       traceline(this.origin + this.view_ofs, targ.origin, MOVE_NOMONSTERS, this);
 
-       if((trace_fraction < 1) && (trace_ent != targ))
-               return false;
+       if(trace_fraction < 1)
+               return false; // solid
 
        if(autocvar_g_monsters_target_infront || (this.spawnflags & MONSTERFLAG_INFRONT))
        if(this.enemy != targ)
@@ -1324,6 +1324,7 @@ bool Monster_Spawn(entity this, int mon_id)
        this.classname                  = "monster";
        this.takedamage                 = DAMAGE_AIM;
        this.bot_attack                 = true;
+       IL_PUSH(g_bot_targets, this);
        this.iscreature                 = true;
        this.teleportable               = true;
        this.damagedbycontents  = true;
diff --git a/qcsrc/common/monsters/sv_spawn.qc b/qcsrc/common/monsters/sv_spawn.qc
new file mode 100644 (file)
index 0000000..50373cc
--- /dev/null
@@ -0,0 +1,69 @@
+#include "sv_spawn.qh"
+#if defined(CSQC)
+#elif defined(MENUQC)
+#elif defined(SVQC)
+    #include "../util.qh"
+    #include "all.qh"
+    #include "sv_monsters.qh"
+    #include <server/autocvars.qh>
+    #include <server/defs.qh>
+#endif
+entity spawnmonster (string monster, float monster_id, entity spawnedby, entity own, vector orig, float respwn, float invincible, float moveflag)
+{
+       float i;
+       entity e = spawn();
+
+       e.spawnflags = MONSTERFLAG_SPAWNED;
+
+       if(!respwn) { e.spawnflags |= MONSTERFLAG_NORESPAWN; }
+       if(invincible) { e.spawnflags |= MONSTERFLAG_INVINCIBLE; }
+
+       setorigin(e, orig);
+
+       if(monster == "random")
+       {
+               RandomSelection_Init();
+               for(i = MON_FIRST; i <= MON_LAST; ++i)
+                       RandomSelection_Add(NULL, i, string_null, 1, 1);
+
+           monster_id = RandomSelection_chosen_float;
+       }
+       else if(monster != "")
+       {
+               float found = 0;
+               entity mon;
+               for(i = MON_FIRST; i <= MON_LAST; ++i)
+               {
+                       mon = get_monsterinfo(i);
+                       if(mon.netname == monster)
+                       {
+                               found = true;
+                               monster_id = mon.monsterid; // we have the monster, old monster id is no longer required
+                               break;
+                       }
+               }
+               if(!found)
+                       monster_id = ((monster_id > 0) ? monster_id : MON_FIRST);
+       }
+
+       e.realowner = spawnedby;
+
+       if(moveflag)
+               e.monster_moveflags = moveflag;
+
+       if(IS_PLAYER(spawnedby))
+       {
+               if(teamplay && autocvar_g_monsters_teams)
+                       e.team = spawnedby.team; // colors handled in spawn code
+
+               if(autocvar_g_monsters_owners)
+                       e.monster_follow = own; // using .owner makes the monster non-solid for its master
+
+               e.angles_y = spawnedby.angles_y;
+       }
+
+       // Monster_Spawn checks if monster is valid
+       Monster_Spawn(e, monster_id);
+
+       return e;
+}
diff --git a/qcsrc/common/monsters/sv_spawn.qh b/qcsrc/common/monsters/sv_spawn.qh
new file mode 100644 (file)
index 0000000..0aba5c1
--- /dev/null
@@ -0,0 +1,3 @@
+#pragma once
+
+entity spawnmonster (string monster, float monster_id, entity spawnedby, entity own, vector orig, float respwn, float invincible, float moveflag);
index d9223b302a13b771f34e11b55c8bb7077e08f01c..82fa2d33cb8bd0e0a649619e7836f95eefdfd9d6 100644 (file)
@@ -345,6 +345,10 @@ void buff_Init(entity this)
        this.classname = "item_buff";
        this.solid = SOLID_TRIGGER;
        this.flags = FL_ITEM;
+       this.bot_pickup = true;
+       this.bot_pickupevalfunc = commodity_pickupevalfunc;
+       this.bot_pickupbasevalue = 1000;
+       IL_PUSH(g_items, this);
        setthink(this, buff_Think);
        settouch(this, buff_Touch);
        this.reset = buff_Reset;
@@ -822,7 +826,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
        if(player.buffs & BUFF_MAGNET.m_itemid)
        {
                vector pickup_size;
-               FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
+               IL_EACH(g_items, it.classname != "item_flag_team" && it.classname != "item_kh_key",
                {
                        if(it.buffs)
                                pickup_size = '1 1 1' * autocvar_g_buffs_magnet_range_buff;
index 1252c34ed75c3fab38ab84286146186c99931bf7..b76d22e95b51e5a1409a365159ab1e2261136c33 100644 (file)
@@ -137,11 +137,10 @@ void Item_ItemsTime_SetTimesForAllPlayers()
 float Item_ItemsTime_UpdateTime(entity e, float t)
 {
     bool isavailable = (t == 0);
-    FOREACH_ENTITY_FLOAT(pure_data, false,
+    IL_EACH(g_items, it != e,
     {
-        if(!(it.itemdef == e.itemdef || ((e.weapons & WEPSET_SUPERWEAPONS) && (it.weapons & WEPSET_SUPERWEAPONS) && clienttype(it) == CLIENTTYPE_NOTACLIENT)))
+        if(!(it.itemdef == e.itemdef || ((e.weapons & WEPSET_SUPERWEAPONS) && (it.weapons & WEPSET_SUPERWEAPONS))))
             continue;
-        if (e == it) continue;
         if (it.scheduledrespawntime <= time)
             isavailable = true;
         else if (t == 0 || it.scheduledrespawntime < t)
@@ -157,11 +156,9 @@ MUTATOR_HOOKFUNCTION(itemstime, reset_map_global)
     Item_ItemsTime_ResetTimes();
     // ALL the times need to be reset before .reset()ing each item
     // since Item_Reset schedules respawn of superweapons and powerups
-    FOREACH_ENTITY_FLOAT(pure_data, false,
+    IL_EACH(g_items, it.reset,
     {
-        if(IS_CLIENT(it))
-            continue;
-        if (it.reset) Item_ItemsTime_SetTime(it, 0);
+        Item_ItemsTime_SetTime(it, 0);
     });
     Item_ItemsTime_SetTimesForAllPlayers();
 }
index d15353745e694868381c0aaf589e015c697c78ad..c4e73d286d13946e64024fc976ae1d5987e3347a 100644 (file)
@@ -146,7 +146,7 @@ void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expan
 #ifdef SVQC
 
 #include <common/gamemodes/_mod.qh>
-#include <common/monsters/spawn.qh>
+#include <common/monsters/sv_spawn.qh>
 #include <common/monsters/sv_monsters.qh>
 #include <server/g_subs.qh>
 
@@ -293,6 +293,7 @@ void nade_napalm_ball(entity this)
        proj.angles = vectoangles(proj.velocity);
        proj.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, proj);
+       IL_PUSH(g_bot_dodge, proj);
        proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
 
        //CSQCProjectile(proj, true, PROJECTILE_NAPALM_FIRE, true);
@@ -349,6 +350,9 @@ void nade_napalm_boom(entity this)
        fountain.owner = this.owner;
        fountain.realowner = this.realowner;
        fountain.origin = this.origin;
+       fountain.flags = FL_PROJECTILE;
+       IL_PUSH(g_projectiles, fountain);
+       IL_PUSH(g_bot_dodge, fountain);
        setorigin(fountain, fountain.origin);
        setthink(fountain, napalm_fountain_think);
        fountain.nextthink = time;
@@ -730,10 +734,9 @@ void nade_boom(entity this)
                case NADE_TYPE_ENTRAP: nade_entrap_boom(this); break;
        }
 
-       FOREACH_ENTITY_ENT(aiment, this,
+       IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
        {
-               if(it.classname == "grapplinghook")
-                       RemoveGrapplingHook(it.realowner);
+               RemoveGrapplingHook(it.realowner);
        });
 
        delete(this);
@@ -780,10 +783,9 @@ void nade_touch(entity this, entity toucher)
                is_weapclip = 1;*/
        if(ITEM_TOUCH_NEEDKILL()) // || is_weapclip)
        {
-               FOREACH_ENTITY_ENT(aiment, this,
+               IL_EACH(g_projectiles, it.classname == "grapplinghook" && it.aiment == this,
                {
-                       if(it.classname == "grapplinghook")
-                               RemoveGrapplingHook(it.realowner);
+                       RemoveGrapplingHook(it.realowner);
                });
                delete(this);
                return;
@@ -942,6 +944,7 @@ void toss_nade(entity e, bool set_owner, vector _velocity, float _time)
        _nade.angles = vectoangles(_nade.velocity);
        _nade.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, _nade);
+       IL_PUSH(g_bot_dodge, _nade);
        _nade.projectiledeathtype = DEATH_NADE.m_id;
        _nade.toss_time = time;
        _nade.solid = SOLID_CORPSE; //((_nade.nade_type == NADE_TYPE_TRANSLOCATE) ? SOLID_CORPSE : SOLID_BBOX);
index 4540a26f2e626ccc4761536b0b0cabc0d95e474d..122bdfc12c49bb43c89c6bb522352d18e1382b2e 100644 (file)
@@ -97,6 +97,7 @@ void W_RocketPropelledChainsaw_Attack (Weapon thiswep, entity actor, .entity wea
        missile.nextthink = time;
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
 
        CSQCProjectile(missile, true, PROJECTILE_RPC, false);
 
index d0739c2e4443a4e2e1820079bb7a6a7eb581dbb1..a2211fe75a2af294e229af70cafa403837c4a9df 100644 (file)
@@ -143,12 +143,9 @@ void sandbox_ObjectAttach_Remove(entity e)
 {
        // detaches any object attached to e
 
-       FOREACH_ENTITY_ENT(owner, e,
+       IL_EACH(g_sandbox_objects, it.owner == e,
        {
-               if(it.classname != "object") continue;
-
-               vector org;
-               org = gettaginfo(it, 0);
+               vector org = gettaginfo(it, 0);
                setattachment(it, NULL, "");
                it.owner = NULL;
 
@@ -167,6 +164,7 @@ entity sandbox_ObjectSpawn(entity this, float database)
        // spawn a new object with default properties
 
        entity e = new(object);
+       IL_PUSH(g_sandbox_objects, e);
        e.takedamage = DAMAGE_AIM;
        e.damageforcescale = 1;
        e.solid = SOLID_BBOX; // SOLID_BSP would be best, but can lag the server badly
@@ -226,30 +224,28 @@ void sandbox_ObjectRemove(entity e)
 
 string port_string[MAX_STORAGE_ATTACHMENTS]; // fteqcc crashes if this isn't defined as a global
 
-string sandbox_ObjectPort_Save(entity e, float database)
+string sandbox_ObjectPort_Save(entity e, bool database)
 {
        // save object properties, and return them as a string
-       float i = 0;
-       string s;
-       entity head;
+       int o = 0;
 
-       for(head = NULL; (head = find(head, classname, "object")); )
-       {
+       // order doesn't really matter, as we're writing the file fresh
+       IL_EACH(g_sandbox_objects, it == e || it.owner == e, LAMBDA(
                // the main object needs to be first in the array [0] with attached objects following
-               float slot, physics, solidity;
-               if(head == e) // this is the main object, place it first
+               int slot, physics, solidity;
+               if(it == e) // this is the main object, place it first
                {
                        slot = 0;
-                       solidity = head.solid; // applied solidity is normal solidity for children
-                       physics = head.move_movetype; // applied physics are normal physics for parents
+                       solidity = it.solid; // applied solidity is normal solidity for children
+                       physics = it.move_movetype; // applied physics are normal physics for parents
                }
-               else if(head.owner == e) // child object, list them in order
+               else if(it.owner == e) // child object, list them in order
                {
-                       i += 1; // children start from 1
-                       slot = i;
-                       solidity = head.old_solid; // persisted solidity is normal solidity for children
-                       physics = head.old_movetype; // persisted physics are normal physics for children
-                       gettaginfo(head.owner, head.tag_index); // get the name of the tag our object is attached to, used further below
+                       o += 1; // children start from 1
+                       slot = o;
+                       solidity = it.old_solid; // persisted solidity is normal solidity for children
+                       physics = it.old_movetype; // persisted physics are normal physics for children
+                       gettaginfo(it.owner, it.tag_index); // get the name of the tag our object is attached to, used further below
                }
                else
                        continue;
@@ -258,46 +254,55 @@ string sandbox_ObjectPort_Save(entity e, float database)
                if(slot)
                {
                        // properties stored only for child objects
-                       if(gettaginfo_name)     port_string[slot] = strcat(port_string[slot], "\"", gettaginfo_name, "\" ");    else    port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+                       if(gettaginfo_name)
+                               port_string[slot] = strcat(port_string[slot], "\"", gettaginfo_name, "\" ");
+                       else
+                               port_string[slot] = strcat(port_string[slot], "\"\" "); // none
                }
                else
                {
                        // properties stored only for parent objects
                        if(database)
                        {
-                               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.origin), " ");
-                               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.angles), " ");
+                               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.origin), " ");
+                               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.angles), " ");
                        }
                }
                // properties stored for all objects
-               port_string[slot] = strcat(port_string[slot], "\"", head.model, "\" ");
-               port_string[slot] = strcat(port_string[slot], ftos(head.skin), " ");
-               port_string[slot] = strcat(port_string[slot], ftos(head.alpha), " ");
-               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.colormod), " ");
-               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", head.glowmod), " ");
-               port_string[slot] = strcat(port_string[slot], ftos(head.frame), " ");
-               port_string[slot] = strcat(port_string[slot], ftos(head.scale), " ");
+               port_string[slot] = strcat(port_string[slot], "\"", it.model, "\" ");
+               port_string[slot] = strcat(port_string[slot], ftos(it.skin), " ");
+               port_string[slot] = strcat(port_string[slot], ftos(it.alpha), " ");
+               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.colormod), " ");
+               port_string[slot] = strcat(port_string[slot], sprintf("\"%.9v\"", it.glowmod), " ");
+               port_string[slot] = strcat(port_string[slot], ftos(it.frame), " ");
+               port_string[slot] = strcat(port_string[slot], ftos(it.scale), " ");
                port_string[slot] = strcat(port_string[slot], ftos(solidity), " ");
                port_string[slot] = strcat(port_string[slot], ftos(physics), " ");
-               port_string[slot] = strcat(port_string[slot], ftos(head.damageforcescale), " ");
-               if(head.material)       port_string[slot] = strcat(port_string[slot], "\"", head.material, "\" ");      else    port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+               port_string[slot] = strcat(port_string[slot], ftos(it.damageforcescale), " ");
+               if(it.material)
+                       port_string[slot] = strcat(port_string[slot], "\"", it.material, "\" ");
+               else
+                       port_string[slot] = strcat(port_string[slot], "\"\" "); // none
                if(database)
                {
                        // properties stored only for the database
-                       if(head.crypto_idfp)    port_string[slot] = strcat(port_string[slot], "\"", head.crypto_idfp, "\" ");   else    port_string[slot] = strcat(port_string[slot], "\"\" "); // none
+                       if(it.crypto_idfp)
+                               port_string[slot] = strcat(port_string[slot], "\"", it.crypto_idfp, "\" ");
+                       else
+                               port_string[slot] = strcat(port_string[slot], "\"\" "); // none
                        port_string[slot] = strcat(port_string[slot], "\"", e.netname, "\" ");
                        port_string[slot] = strcat(port_string[slot], "\"", e.message, "\" ");
                        port_string[slot] = strcat(port_string[slot], "\"", e.message2, "\" ");
                }
-       }
+       ));
 
        // now apply the array to a simple string, with the ; symbol separating objects
-       s = "";
-       for(i = 0; i <= MAX_STORAGE_ATTACHMENTS; ++i)
+       string s = "";
+       for(int j = 0; j <= MAX_STORAGE_ATTACHMENTS; ++j)
        {
-               if(port_string[i])
-                       s = strcat(s, port_string[i], "; ");
-               port_string[i] = string_null; // fully clear the string
+               if(port_string[j])
+                       s = strcat(s, port_string[j], "; ");
+               port_string[j] = string_null; // fully clear the string
        }
 
        return s;
@@ -375,7 +380,6 @@ entity sandbox_ObjectPort_Load(entity this, string s, float database)
 void sandbox_Database_Save()
 {
        // saves all objects to the database file
-       entity head;
        string file_name;
        float file_get;
 
@@ -384,15 +388,11 @@ void sandbox_Database_Save()
        fputs(file_get, strcat("// sandbox storage \"", autocvar_g_sandbox_storage_name, "\" for map \"", GetMapname(), "\" last updated ", strftime(true, "%d-%m-%Y %H:%M:%S")));
        fputs(file_get, strcat(" containing ", ftos(object_count), " objects\n"));
 
-       for(head = NULL; (head = find(head, classname, "object")); )
+       IL_EACH(g_sandbox_objects, !it.owner, // attached objects are persisted separately, ignore them here
        {
-               // attached objects are persisted separately, ignore them here
-               if(head.owner != NULL)
-                       continue;
-
                // use a line of text for each object, listing all properties
-               fputs(file_get, strcat(sandbox_ObjectPort_Save(head, true), "\n"));
-       }
+               fputs(file_get, strcat(sandbox_ObjectPort_Save(it, true), "\n"));
+       });
        fclose(file_get);
 }
 
@@ -784,10 +784,8 @@ MUTATOR_HOOKFUNCTION(sandbox, SV_ParseClientCommand)
                                                        // this should show the same info as 'mesh' but for attachments
                                                        s = "";
                                                        j = 0;
-                                                       FOREACH_ENTITY_ENT(owner, e,
+                                                       IL_EACH(g_sandbox_objects, it.owner == e,
                                                        {
-                                                               if(it.classname != "object") continue;
-
                                                                ++j; // start from 1
                                                                gettaginfo(e, it.tag_index);
                                                                s = strcat(s, "^1attachment ", ftos(j), "^7 has mesh \"^3", it.model, "^7\" at animation frame ^3", ftos(it.frame));
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..f6a0afdf404c1fdb173299f20d86dee76a25e65c 100644 (file)
@@ -1 +1,4 @@
 #pragma once
+
+IntrusiveList g_sandbox_objects;
+STATIC_INIT(g_sandbox_objects) { g_sandbox_objects = IL_NEW(); }
index acd570d0b67aeb7318267717b08ca924e1b7c949..dd5f3a164b58502f1b9bdacab31c4f1789145bbf 100644 (file)
@@ -1532,8 +1532,8 @@ void Kill_Notification(
        net_notif.nent_net_name = ORDINAL(net_cpid);
        Net_LinkEntity(net_notif, false, autocvar_notification_lifetime_runtime, Net_Write_Notification);
 
-       FOREACH_ENTITY_CLASS(
-               "net_notification",
+       IL_EACH(
+               g_notifications,
                (it.owner.nent_type == net_type || net_type == MSG_Null) && (it.owner.nent_cpid == net_cpid || net_cpid == CPID_Null),
                {
                        it.nent_net_name = -1;
@@ -1682,6 +1682,7 @@ void Send_Notification(
        else
        {
                entity net_notif = new_pure(net_notification);
+               IL_PUSH(g_notifications, net_notif);
                net_notif.owner = notif;
                net_notif.nent_broadcast = broadcast;
                net_notif.nent_client = client;
index 2715925944b6d16ae1701c4a3f0b5ba70db7c815..ccdcc690a8148cbc5308221823587225311af3c8 100644 (file)
@@ -225,6 +225,11 @@ string prev_soundfile;
 float prev_soundtime;
 #endif
 
+#ifdef SVQC
+IntrusiveList g_notifications;
+STATIC_INIT(g_notifications) { g_notifications = IL_NEW(); }
+#endif
+
 #ifdef SVQC
 ENUMCLASS(NOTIF)
        /** send to one client and their spectators */
index 4fe8c88f516bc9425abc6b3ac0a2e5dd7c2a597d..f5c0e0316e3340bb995e04577ad9719375c063b8 100644 (file)
@@ -80,44 +80,6 @@ float GeomLerp(float a, float _lerp, float b)
                : a * pow(fabs(b / a), _lerp);
 }
 
-#define unstick_offsets(X) \
-/* 1 no nudge (just return the original if this test passes) */ \
-       X(' 0.000  0.000  0.000') \
-/* 6 simple nudges */ \
-       X(' 0.000  0.000  0.125') X('0.000  0.000 -0.125') \
-       X('-0.125  0.000  0.000') X('0.125  0.000  0.000') \
-       X(' 0.000 -0.125  0.000') X('0.000  0.125  0.000') \
-/* 4 diagonal flat nudges */ \
-       X('-0.125 -0.125  0.000') X('0.125 -0.125  0.000') \
-       X('-0.125  0.125  0.000') X('0.125  0.125  0.000') \
-/* 8 diagonal upward nudges */ \
-       X('-0.125  0.000  0.125') X('0.125  0.000  0.125') \
-       X(' 0.000 -0.125  0.125') X('0.000  0.125  0.125') \
-       X('-0.125 -0.125  0.125') X('0.125 -0.125  0.125') \
-       X('-0.125  0.125  0.125') X('0.125  0.125  0.125') \
-/* 8 diagonal downward nudges */ \
-       X('-0.125  0.000 -0.125') X('0.125  0.000 -0.125') \
-       X(' 0.000 -0.125 -0.125') X('0.000  0.125 -0.125') \
-       X('-0.125 -0.125 -0.125') X('0.125 -0.125 -0.125') \
-       X('-0.125  0.125 -0.125') X('0.125  0.125 -0.125') \
-/**/
-
-void PM_ClientMovement_Unstick(entity this)
-{
-       #define X(unstick_offset) \
-       { \
-               vector neworigin = unstick_offset + this.origin; \
-               tracebox(neworigin, STAT(PL_CROUCH_MIN, NULL), STAT(PL_CROUCH_MAX, NULL), neworigin, MOVE_NORMAL, this); \
-               if (!trace_startsolid) \
-               { \
-                       setorigin(this, neworigin); \
-                       return; \
-               } \
-       }
-       unstick_offsets(X);
-       #undef X
-}
-
 void PM_ClientMovement_UpdateStatus(entity this)
 {
 #ifdef CSQC
index ebc971141447e77c2a5a72ad18f11e05746b392b..f9f89a73fa6ec8a5da6bf70d62227079c8569d5d 100644 (file)
@@ -18,7 +18,7 @@
        #include "triggers/subs.qh"
     #include "util.qh"
 
-    #include <common/monsters/all.qh>
+    #include <common/monsters/_mod.qh>
 
     #include <common/weapons/_all.qh>
 
@@ -835,10 +835,9 @@ LABEL(pickup)
                if(this.team)
                {
                        RandomSelection_Init();
-                       FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
+                       IL_EACH(g_items, it.team == this.team,
                        {
-                               if(it.team == this.team)
-                               if(it.classname != "item_flag_team" && it.classname != "item_key_team")
+                               if(it.classname != "item_flag_team" && it.classname != "item_kh_key")
                                {
                                        Item_Show(it, -1);
                                        RandomSelection_Add(it, 0, string_null, it.cnt, 0);
@@ -880,10 +879,9 @@ void Item_FindTeam(entity this)
                // marker for item team search
                LOG_TRACE("Initializing item team ", ftos(this.team));
                RandomSelection_Init();
-               FOREACH_ENTITY_FLOAT(team, this.team,
+               IL_EACH(g_items, it.team == this.team,
                {
-                       if(it.flags & FL_ITEM)
-                       if(it.classname != "item_flag_team" && it.classname != "item_key_team")
+                       if(it.classname != "item_flag_team" && it.classname != "item_kh_key")
                                RandomSelection_Add(it, 0, string_null, it.cnt, 0);
                });
 
@@ -891,10 +889,9 @@ void Item_FindTeam(entity this)
                e.state = 0;
                Item_Show(e, 1);
 
-               FOREACH_ENTITY_FLOAT(team, this.team,
+               IL_EACH(g_items, it.team == this.team,
                {
-                       if(it.flags & FL_ITEM)
-                       if(it.classname != "item_flag_team" && it.classname != "item_key_team")
+                       if(it.classname != "item_flag_team" && it.classname != "item_kh_key")
                        {
                                if(it != e)
                                {
@@ -1076,6 +1073,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
                this.weapons = WepSet_FromWeapon(Weapons_from(weaponid));
 
        this.flags = FL_ITEM | itemflags;
+       IL_PUSH(g_items, this);
 
        if(MUTATOR_CALLHOOK(FilterItem, this)) // error means we do not want the item
        {
@@ -1447,10 +1445,9 @@ void target_items_use(entity this, entity actor, entity trigger)
                EXACTTRIGGER_TOUCH(this, trigger);
        }
 
-       FOREACH_ENTITY_ENT(enemy, actor,
+       IL_EACH(g_items, it.enemy == actor && it.classname == "droppedweapon",
        {
-               if(it.classname == "droppedweapon")
-                       delete(it);
+               delete(it);
        });
 
        if(GiveItems(actor, 0, tokenize_console(this.netname)))
index 2b7a1155f483b101c8b122a5986df60f8d270219..13094e790aa527db25853d5a7f72944490c2b57b 100644 (file)
@@ -134,6 +134,8 @@ void func_breakable_behave_destroyed(entity this)
 {
        this.health = this.max_health;
        this.takedamage = DAMAGE_NO;
+       if(this.bot_attack)
+               IL_REMOVE(g_bot_targets, this);
        this.bot_attack = false;
        this.event_damage = func_null;
        this.state = 1;
@@ -155,6 +157,8 @@ void func_breakable_behave_restore(entity this)
        if(!(this.spawnflags & 4))
        {
                this.takedamage = DAMAGE_AIM;
+               if(!this.bot_attack)
+                       IL_PUSH(g_bot_targets, this);
                this.bot_attack = true;
                this.event_damage = func_breakable_damage;
        }
@@ -351,7 +355,7 @@ spawnfunc(func_breakable)
        this.reset = func_breakable_reset;
        this.reset(this);
 
-       this.init_for_player_needed = 1;
+       IL_PUSH(g_initforplayer, this);
        this.init_for_player = func_breakable_init_for_player;
 
        CSQCMODEL_AUTOINIT(this);
index 4902deea5c27307dac17b4e673db17a76da8a400..90328da23002dd61a1a8cc37fb9b6c93705fb7d9 100644 (file)
@@ -11,9 +11,10 @@ void conveyor_think(entity this)
 #endif
 
        // set mythis as current conveyor where possible
-       FOREACH_ENTITY_ENT(conveyor, this,
+       IL_EACH(g_conveyed, it.conveyor == this,
        {
                it.conveyor = NULL;
+               IL_REMOVE(g_conveyed, it);
        });
 
        if(this.state)
@@ -29,10 +30,14 @@ void conveyor_think(entity this)
                        }
                        if(boxesoverlap(emin, emax, this.absmin, this.absmax)) // quick
                                if(WarpZoneLib_BoxTouchesBrush(emin, emax, this, it)) // accurate
+                               {
+                                       if(!it.conveyor)
+                                               IL_PUSH(g_conveyed, it);
                                        it.conveyor = this;
+                               }
                });
 
-               FOREACH_ENTITY_ENT(conveyor, this,
+               IL_EACH(g_conveyed, it.conveyor == this,
                {
                        if(IS_CLIENT(it)) // doing it via velocity has quite some advantages
                                continue; // done in SV_PlayerPhysics   continue;
index 6f70f09beec2219624baeca92e2cd7deaa104fb4..c12b52d2dd19118e4d0a7209329796446922cbeb 100644 (file)
@@ -1 +1,4 @@
 #pragma once
+
+IntrusiveList g_conveyed;
+STATIC_INIT(g_conveyed) { g_conveyed = IL_NEW(); }
index efe997c855350d402a9e4a9a0221eb0099e79862..0b8930aec5a494aca16a3a889a5b02fdb2df8bf9 100644 (file)
@@ -20,6 +20,8 @@ void fd_secret_use(entity this, entity actor, entity trigger)
        string message_save;
 
        this.health = 10000;
+       if(!this.bot_attack)
+               IL_PUSH(g_bot_targets, this);
        this.bot_attack = true;
 
        // exit if still moving around...
index c8e3539283d76652c719e3ce0f82c9c5669f441d..0fde9e043904d00f4093fe74bcc45a9ce0a74b52 100644 (file)
@@ -12,6 +12,9 @@ REGISTER_NET_LINKED(ENT_CLIENT_TRIGGER_MUSIC)
 
 #ifdef SVQC
 
+IntrusiveList g_targetmusic_list;
+STATIC_INIT(g_targetmusic_list) { g_targetmusic_list = IL_NEW(); }
+
 // values:
 //   volume
 //   noise
@@ -37,7 +40,8 @@ void target_music_reset(entity this)
 }
 void target_music_kill()
 {
-       FOREACH_ENTITY_CLASS("target_music", true, {
+       IL_EACH(g_targetmusic_list, true,
+       {
                it.volume = 0;
         if (it.targetname == "")
             target_music_sendto(it, MSG_ALL, 1);
@@ -65,6 +69,7 @@ spawnfunc(target_music)
        this.reset = target_music_reset;
        if(!this.volume)
                this.volume = 1;
+       IL_PUSH(g_targetmusic_list, this);
        if(this.targetname == "")
                target_music_sendto(this, MSG_INIT, 1);
        else
@@ -72,7 +77,7 @@ spawnfunc(target_music)
 }
 void TargetMusic_RestoreGame()
 {
-       FOREACH_ENTITY_CLASS("target_music", true,
+       IL_EACH(g_targetmusic_list, true,
        {
                if(it.targetname == "")
                        target_music_sendto(it, MSG_INIT, 1);
index a1a38d39e1a95e24459d2a2c4c1a5bb857c7de27..b5e97b1fc7516f1a082a82d69c354a85f4b8594e 100644 (file)
@@ -267,10 +267,10 @@ void teleport_findtarget(entity this)
 
 entity Teleport_Find(vector mi, vector ma)
 {
-       entity e;
-       for(e = NULL; (e = find(e, classname, "trigger_teleport")); )
-               if(WarpZoneLib_BoxTouchesBrush(mi, ma, e, NULL))
-                       return e;
+       IL_EACH(g_teleporters, WarpZoneLib_BoxTouchesBrush(mi, ma, it, NULL),
+       {
+               return it;
+       });
        return NULL;
 }
 
index 513ed3e26928460e636b36940fa0d009c5213241..6f5f8cb76e21bec6f941b85e2aebccd767b5ba21 100644 (file)
@@ -1,5 +1,8 @@
 #pragma once
 
+IntrusiveList g_teleporters;
+STATIC_INIT(g_teleporters) { g_teleporters = IL_NEW(); }
+
 .entity pusher;
 const float TELEPORT_FLAG_SOUND = 1;
 const float TELEPORT_FLAG_PARTICLES = 2;
index 05bb13c710e7ed4c4289f92acbd137c82da3505c..c3de654609ff5e0db36ad1bf01e4b314b3283023 100644 (file)
@@ -99,6 +99,8 @@ spawnfunc(trigger_teleport)
                return;
        }
 
+       IL_PUSH(g_teleporters, this);
+
        this.teleport_next = teleport_first;
        teleport_first = this;
 }
@@ -106,6 +108,8 @@ spawnfunc(trigger_teleport)
 NET_HANDLE(ENT_CLIENT_TRIGGER_TELEPORT, bool isnew)
 {
        this.classname = "trigger_teleport";
+       if(isnew)
+               IL_PUSH(g_teleporters, this);
        int mytm = ReadByte(); if(mytm) { this.team = mytm - 1; }
        this.spawnflags = ReadInt24_t();
        this.active = ReadByte();
index dabb7ee35dfcdbcb8845f4014355be79168ae8de..c90eaff1fe98fdb22bc7918fefedd1f28c703738 100644 (file)
@@ -479,6 +479,7 @@ entity turret_projectile(entity actor, Sound _snd, float _size, float _health, f
        proj.velocity           = normalize(actor.tur_shotdir_updated + randomvec() * actor.shot_spread) * actor.shot_speed;
        proj.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, proj);
+       IL_PUSH(g_bot_dodge, proj);
        proj.enemy                = actor.enemy;
        proj.totalfrags  = _death;
        PROJECTILE_MAKETRIGGER(proj);
@@ -1252,6 +1253,7 @@ bool turret_initialize(entity this, Turret tur)
        if(!this.tur_head) {
                tur.tr_precache(tur);
                IL_PUSH(g_turrets, this);
+               IL_PUSH(g_bot_targets, this);
        }
 
        entity e = find(NULL, classname, "turret_manager");
index f2a97d4a12529e6fd576819d7509b5bd55597937..152a7d6a2715e362fde40fca3be8f20497ccc511 100644 (file)
@@ -5,7 +5,8 @@ void turret_targettrigger_touch(entity this, entity toucher);
 void turret_targettrigger_touch(entity this, entity toucher)
 {
     if (this.cnt > time) return;
-    FOREACH_ENTITY_STRING_ORDERED(targetname, this.target, {
+    IL_EACH(g_turrets, it.targetname == this.target,
+    {
         if (!(it.turret_flags & TUR_FLAG_RECIEVETARGETS)) continue;
         if (!it.turret_addtarget) continue;
         it.turret_addtarget(it, toucher, this);
index 2e08f5eb3d723cedefe9d790dbea66ee1c572f4e..bf901d886a77e407292d8d208d20f37819f5b8cc 100644 (file)
@@ -36,6 +36,7 @@ METHOD(PhaserTurretAttack, wr_think, void(entity thiswep, entity actor, .entity
         set_movetype(beam, MOVETYPE_NONE);
         beam.enemy = actor.enemy;
         beam.bot_dodge = true;
+        IL_PUSH(g_bot_dodge, beam);
         beam.bot_dodgerating = beam.shot_dmg;
         sound (beam, CH_SHOTS_SINGLE, SND_TUR_PHASER, VOL_BASE, ATTEN_NORM);
         actor.fireflag = 1;
index 94ecdd332a0a264625d7ac7be3727564b60bf8c3..ffba71439ab995198c760c69843a7bfbe1b3e3d7 100644 (file)
@@ -241,6 +241,7 @@ void walker_fire_rocket(entity this, vector org)
     settouch(rocket, walker_rocket_touch);
     rocket.flags = FL_PROJECTILE;
     IL_PUSH(g_projectiles, rocket);
+    IL_PUSH(g_bot_dodge, rocket);
     rocket.solid                         = SOLID_BBOX;
     rocket.max_health           = time + 9;
     rocket.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_GUIDED_HEAT;
index 716abaf9880f183d47d9a82cd8c3af52e9b0eeb4..962c5807067b28dd622a2f83bd78a3ba79c7f014 100644 (file)
@@ -397,6 +397,9 @@ string fixPriorityList(string order, float from, float to, float subtract, float
                n = tokenize_console(neworder);
                for(w = to; w >= from; --w)
                {
+                       int wflags = Weapons_from(w).spawnflags;
+                       if((wflags & WEP_FLAG_HIDDEN) && (wflags & WEP_FLAG_MUTATORBLOCKED) && !(wflags & WEP_FLAG_NORMAL))
+                               continue;
                        for(i = 0; i < n; ++i)
                                if(stof(argv(i)) == w)
                                        break;
@@ -600,7 +603,7 @@ float cvar_settemp(string tmp_cvar, string tmp_value)
                return 0;
        }
 
-       FOREACH_ENTITY_CLASS("saved_cvar_value", it.netname == tmp_cvar,
+       IL_EACH(g_saved_cvars, it.netname == tmp_cvar,
        {
                created_saved_value = -1; // skip creation
                break; // no need to continue
@@ -610,6 +613,7 @@ float cvar_settemp(string tmp_cvar, string tmp_value)
        {
                // creating a new entity to keep track of this cvar
                entity e = new_pure(saved_cvar_value);
+               IL_PUSH(g_saved_cvars, e);
                e.netname = strzone(tmp_cvar);
                e.message = strzone(cvar_string(tmp_cvar));
                created_saved_value = 1;
@@ -1225,6 +1229,7 @@ float get_model_parameters(string m, float sk)
                get_model_parameters_bone_aimweight[i] = 0;
        }
        get_model_parameters_fixbone = 0;
+       get_model_parameters_hidden = false;
 
 #ifdef GAMEQC
        MUTATOR_CALLHOOK(ClearModelParams);
@@ -1302,6 +1307,8 @@ float get_model_parameters(string m, float sk)
                        }
                if(c == "fixbone")
                        get_model_parameters_fixbone = stof(s);
+               if(c == "hidden")
+                       get_model_parameters_hidden = stob(s);
        }
 
        while((s = fgets(fh)))
index 9e1d5a75be3f94cf418fca7aecb9e4459d28aa44..57f9a2217c42d5a502e8268c139bd8f082094d29 100644 (file)
@@ -5,6 +5,9 @@
 vector real_origin(entity ent);
 #endif
 
+IntrusiveList g_saved_cvars;
+STATIC_INIT(g_saved_cvars) { g_saved_cvars = IL_NEW(); }
+
 // this returns a tempstring containing a copy of s with additional \n newlines added, it also replaces \n in the text with a real newline
 // NOTE: s IS allowed to be a tempstring
 string wordwrap(string s, float l);
@@ -178,6 +181,7 @@ float get_model_parameters_species;
 string get_model_parameters_sex;
 float get_model_parameters_weight;
 float get_model_parameters_age;
+bool get_model_parameters_hidden;
 string get_model_parameters_description;
 string get_model_parameters_bone_upperbody;
 string get_model_parameters_bone_weapon;
index 39f959d14b9f03f851f6b8edebf6d3efd90008e3..60a8ee07760fbe897e58cd58fab2e22904337728 100644 (file)
@@ -249,6 +249,7 @@ entity vehicles_projectile(entity this, string _mzlfx, Sound _mzlsound,
        set_movetype(proj, MOVETYPE_FLYMISSILE);
        proj.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, proj);
+       IL_PUSH(g_bot_dodge, proj);
        proj.bot_dodge          = true;
        proj.bot_dodgerating  = _dmg;
        proj.velocity            = _vel;
@@ -433,17 +434,15 @@ void vehicles_reset_colors(entity this)
 void vehicles_clearreturn(entity veh)
 {
        // Remove "return helper" entities, if any.
-       FOREACH_ENTITY_ENT(wp00, veh,
+       IL_EACH(g_vehicle_returners, it.wp00 == veh,
        {
-               if(it.classname == "vehicle_return")
-               {
-                       it.classname = "";
-                       setthink(it, SUB_Remove);
-                       it.nextthink = time + 0.1;
+               it.classname = "";
+               setthink(it, SUB_Remove);
+               it.nextthink = time + 0.1;
+               IL_REMOVE(g_vehicle_returners, it);
 
-                       if(it.waypointsprite_attached)
-                               WaypointSprite_Kill(it.waypointsprite_attached);
-               }
+               if(it.waypointsprite_attached)
+                       WaypointSprite_Kill(it.waypointsprite_attached);
        });
 }
 
@@ -513,6 +512,7 @@ void vehicles_setreturn(entity veh)
        vehicles_clearreturn(veh);
 
        entity ret = new(vehicle_return);
+       IL_PUSH(g_vehicle_returners, ret);
        ret.wp00           = veh;
        ret.team                = veh.team;
        setthink(ret, vehicles_showwp);
@@ -1076,6 +1076,8 @@ void vehicles_spawn(entity this)
        this.solid                              = SOLID_SLIDEBOX;
        this.takedamage                 = DAMAGE_AIM;
        this.deadflag                   = DEAD_NO;
+       if(!this.bot_attack)
+               IL_PUSH(g_bot_targets, this);
        this.bot_attack                 = true;
        this.flags                              = FL_NOTARGET;
        this.avelocity                  = '0 0 0';
@@ -1161,6 +1163,7 @@ bool vehicle_initialize(entity this, Vehicle info, bool nodrop)
        this.tur_head.owner                     = this;
        this.takedamage                         = DAMAGE_NO;
        this.bot_attack                         = true;
+       IL_PUSH(g_bot_targets, this);
        this.iscreature                         = true;
        this.teleportable                       = false; // no teleporting for vehicles, too buggy
        this.damagedbycontents          = true;
index 158191f654eed354806d07cf2140d7a6db1176b4..948427db33e0923c8c28af0ddbf61845a2369e32 100644 (file)
@@ -108,4 +108,7 @@ bool vehicle_impulse(entity this, int imp);
 bool vehicles_crushable(entity e);
 float vehicle_altitude(entity this, float amax);
 
+IntrusiveList g_vehicle_returners;
+STATIC_INIT(g_vehicle_returners) { g_vehicle_returners = IL_NEW(); }
+
 #endif
index 502ef80e2cd88af31f94979549c4b6820cb11d0b..4e16efbcc903df3227c1dc30ae419ef7e4f45731 100644 (file)
@@ -201,9 +201,8 @@ void raptor_flare_damage(entity this, entity inflictor, entity attacker, float d
 void raptor_flare_think(entity this)
 {
     this.nextthink = time + 0.1;
-    FOREACH_ENTITY_ENT(enemy, this.owner,
+    IL_EACH(g_projectiles, it.enemy == this.owner,
     {
-        if(it.flags & FL_PROJECTILE)
         if(vdist(this.origin - it.origin, <, autocvar_g_vehicle_raptor_flare_range))
         if(random() > autocvar_g_vehicle_raptor_flare_chase)
             it.enemy = this;
index fc8a4f190b1be8b6feb8a6f6872e4487aebc7dd0..ec06104824e1c555bc7792f0929787344625c1d2 100644 (file)
@@ -314,9 +314,8 @@ void spiderbot_exit(entity this, int eject)
 {
        vector spot;
 
-       FOREACH_ENTITY_ENT(owner, this.owner,
+       IL_EACH(g_projectiles, it.owner == this.owner && it.classname == "spiderbot_rocket",
        {
-               if(it.classname != "spiderbot_rocket") continue;
                it.realowner = this.owner;
                it.owner = NULL;
        });
index dc1f6ba60a29e16190c54d930e285af683b314d0..5f7a2c31c8a928cbbc5efec1d99e869a0c01a6fc 100644 (file)
@@ -48,16 +48,17 @@ void spiderbot_rocket_guided(entity this)
 
 void spiderbot_guide_release(entity this)
 {
-    FOREACH_ENTITY_ENT(realowner, this.owner,
+    bool donetrace = false;
+    IL_EACH(g_projectiles, it.realowner == this.owner && getthink(it) == spiderbot_rocket_guided,
     {
-        if(i == 0) // something exists, let's trace!
-            crosshair_trace(this.owner);
-
-        if(getthink(it) == spiderbot_rocket_guided)
+        if(!donetrace) // something exists, let's trace!
         {
-            it.pos1 = trace_endpos;
-            setthink(it, spiderbot_rocket_unguided);
+            donetrace = true;
+            crosshair_trace(this.owner);
         }
+
+        it.pos1 = trace_endpos;
+        setthink(it, spiderbot_rocket_unguided);
     });
 }
 
index dfdbd765665a1b09322afd0b28b62f4d6dcd8998..cf55aa65214b7a84673da155f3ffb0eece56eb36 100644 (file)
@@ -27,7 +27,7 @@
     #include "../stats.qh"
     #include "../teams.qh"
     #include "../util.qh"
-    #include "../monsters/all.qh"
+    #include "../monsters/_mod.qh"
     #include "config.qh"
     #include <server/weapons/csqcprojectile.qh>
     #include <server/weapons/tracing.qh>
index 1f8b8e7f085e7d6e6484095e3cb4a6cb279dcea5..a61dc0f031d3e9ed4da12e1be93b8e69c703b9fc 100644 (file)
@@ -282,6 +282,7 @@ void W_Arc_Attack_Bolt(Weapon thiswep, entity actor, .entity weaponentity)
        missile = new(missile);
        missile.owner = missile.realowner = actor;
        missile.bot_dodge = true;
+       IL_PUSH(g_bot_dodge, missile);
        missile.bot_dodgerating = WEP_CVAR(arc, bolt_damage);
 
        missile.takedamage = DAMAGE_YES;
@@ -691,6 +692,7 @@ void W_Arc_Beam(float burst, entity actor, .entity weaponentity)
        beam.owner = actor;
        set_movetype(beam, MOVETYPE_NONE);
        beam.bot_dodge = true;
+       IL_PUSH(g_bot_dodge, beam);
        beam.bot_dodgerating = WEP_CVAR(arc, beam_damage);
        beam.beam_bursting = burst;
        Net_LinkEntity(beam, false, 0, W_Arc_Beam_Send);
index 2f24e9e254bcb495b4c53782f4434771ed1269b8..2eb8f00b4179c72cd91727168bbee9f7719c93d4 100644 (file)
@@ -140,6 +140,7 @@ void W_Blaster_Attack(
        settouch(missile, W_Blaster_Touch);
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        missile.missile_flags = MIF_SPLASH;
        missile.projectiledeathtype = atk_deathtype;
        setthink(missile, W_Blaster_Think);
index be5b2ec28f2d96c9cfb8a4270315dda36d1e9306..58214bf390feed3d2f41e1ec5ec24c847b02c10f 100644 (file)
@@ -441,6 +441,7 @@ void W_Crylink_Attack(Weapon thiswep, entity actor, .entity weaponentity)
 
                proj.flags = FL_PROJECTILE;
                IL_PUSH(g_projectiles, proj);
+               IL_PUSH(g_bot_dodge, proj);
                proj.missile_flags = MIF_SPLASH;
 
                CSQCProjectile(proj, true, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), true);
@@ -557,6 +558,7 @@ void W_Crylink_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
 
                proj.flags = FL_PROJECTILE;
                IL_PUSH(g_projectiles, proj);
+               IL_PUSH(g_bot_dodge, proj);
         proj.missile_flags = MIF_SPLASH;
 
                CSQCProjectile(proj, true, (proj.cnt ? PROJECTILE_CRYLINK_BOUNCING : PROJECTILE_CRYLINK), true);
index 5ffe08bad9613ee7303ab9c256d8726e97b13f52..1fdb8d6ad6773a78cba7a24b428b15c389193357 100644 (file)
@@ -400,6 +400,7 @@ void W_Devastator_Attack(Weapon thiswep, entity actor, .entity weaponentity)
        missile.cnt = time + WEP_CVAR(devastator, lifetime);
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        missile.missile_flags = MIF_SPLASH;
 
        CSQCProjectile(missile, WEP_CVAR(devastator, guiderate) == 0 && WEP_CVAR(devastator, speedaccel) == 0, PROJECTILE_ROCKET, false); // because of fly sound
@@ -415,35 +416,6 @@ void W_Devastator_Attack(Weapon thiswep, entity actor, .entity weaponentity)
        MUTATOR_CALLHOOK(EditProjectile, actor, missile);
 }
 
-#if 0
-METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
-{
-    entity this = actor;
-    // aim and decide to fire if appropriate
-    PHYS_INPUT_BUTTON_ATCK(actor) = bot_aim(actor, WEP_CVAR(devastator, speed), 0, WEP_CVAR(devastator, lifetime), false);
-    if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
-    {
-        // decide whether to detonate rockets
-        entity missile, targetlist, targ;
-        targetlist = findchainfloat(bot_attack, true);
-        for(missile = NULL; (missile = find(missile, classname, "rocket")); ) if(missile.realowner == actor)
-        {
-            targ = targetlist;
-            while(targ)
-            {
-                if(targ != missile.realowner && vlen(targ.origin - missile.origin) < WEP_CVAR(devastator, radius))
-                {
-                    PHYS_INPUT_BUTTON_ATCK2(actor) = true;
-                    break;
-                }
-                targ = targ.chain;
-            }
-        }
-
-        if(PHYS_INPUT_BUTTON_ATCK2(actor)) PHYS_INPUT_BUTTON_ATCK(actor) = false;
-    }
-}
-#else
 METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
 {
     // aim and decide to fire if appropriate
@@ -460,12 +432,10 @@ METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
         selfdamage = 0;
         teamdamage = 0;
         enemydamage = 0;
-        FOREACH_ENTITY_ENT(realowner, actor,
+        IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket",
         {
-            if(it.classname != "rocket") continue;
-
             entity rocket = it;
-            FOREACH_ENTITY_FLOAT(bot_attack, true,
+            IL_EACH(g_bot_targets, it.bot_attack,
             {
                float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - rocket.origin);
                d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
@@ -486,14 +456,12 @@ METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
             desirabledamage = desirabledamage - teamdamage;
 
         makevectors(actor.v_angle);
-        FOREACH_ENTITY_ENT(realowner, actor,
+        IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket",
         {
-            if(it.classname != "rocket") continue;
-
             if(skill > 9) // normal players only do this for the target they are tracking
             {
                    entity rocket = it;
-                   FOREACH_ENTITY_FLOAT(bot_attack, true,
+                   IL_EACH(g_bot_targets, it.bot_attack,
                    {
                        if((v_forward * normalize(rocket.origin - it.origin) < 0.1)
                            && desirabledamage > 0.1 * coredamage
@@ -526,7 +494,7 @@ METHOD(Devastator, wr_aim, void(entity thiswep, entity actor))
         if(PHYS_INPUT_BUTTON_ATCK2(actor)) PHYS_INPUT_BUTTON_ATCK(actor) = false;
     }
 }
-#endif
+
 METHOD(Devastator, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
 {
     if(WEP_CVAR(devastator, reload_ammo) && actor.clip_load < WEP_CVAR(devastator, ammo)) { // forced reload
@@ -549,16 +517,15 @@ METHOD(Devastator, wr_think, void(entity thiswep, entity actor, .entity weaponen
         if(fire & 2)
         if(PS(actor).m_switchweapon == WEP_DEVASTATOR)
         {
-            entity rock;
             bool rockfound = false;
-            for(rock = NULL; (rock = find(rock, classname, "rocket")); ) if(rock.realowner == actor)
+            IL_EACH(g_projectiles, it.realowner == actor && it.classname == "rocket",
             {
-                if(!rock.rl_detonate_later)
+                if(!it.rl_detonate_later)
                 {
-                    rock.rl_detonate_later = true;
+                    it.rl_detonate_later = true;
                     rockfound = true;
                 }
-            }
+            });
             if(rockfound)
                 sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM);
         }
index bd6fb89694bda3bb0d4a265cc3d525c66218822d..7e05241a490873f200bbd1ecbeb5cbd8ec43e0ab 100644 (file)
@@ -301,6 +301,7 @@ void W_Electro_Attack_Bolt(Weapon thiswep, entity actor, .entity weaponentity)
        setsize(proj, '0 0 -3', '0 0 -3');
        proj.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, proj);
+       IL_PUSH(g_bot_dodge, proj);
        proj.missile_flags = MIF_SPLASH;
 
        CSQCProjectile(proj, true, PROJECTILE_ELECTRO_BEAM, true);
@@ -340,6 +341,8 @@ void W_Electro_Orb_Stick(entity this, entity to)
        newproj.nextthink = this.nextthink;
        newproj.use = this.use;
        newproj.flags = this.flags;
+       IL_PUSH(g_projectiles, newproj);
+       IL_PUSH(g_bot_dodge, newproj);
 
        delete(this);
 
@@ -448,6 +451,7 @@ void W_Electro_Attack_Orb(Weapon thiswep, entity actor, .entity weaponentity)
        proj.event_damage = W_Electro_Orb_Damage;
        proj.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, proj);
+       IL_PUSH(g_bot_dodge, proj);
        proj.damagedbycontents = (WEP_CVAR_SEC(electro, damagedbycontents));
 
        proj.bouncefactor = WEP_CVAR_SEC(electro, bouncefactor);
index db87ee445f8b9a379f267017ca4eaa072d7dc5e2..c2b93747c8c4c14d7d9437f6c50e2cc2934b8d89 100644 (file)
@@ -224,6 +224,7 @@ void W_Fireball_Attack1(entity actor, .entity weaponentity)
        setsize(proj, '-16 -16 -16', '16 16 16');
        proj.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, proj);
+       IL_PUSH(g_bot_dodge, proj);
     proj.missile_flags = MIF_SPLASH | MIF_PROXY;
 
        CSQCProjectile(proj, true, PROJECTILE_FIREBALL, true);
@@ -355,6 +356,7 @@ void W_Fireball_Attack2(entity actor, .entity weaponentity)
        proj.angles = vectoangles(proj.velocity);
        proj.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, proj);
+       IL_PUSH(g_bot_dodge, proj);
     proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;
 
        CSQCProjectile(proj, true, PROJECTILE_FIREMINE, true);
index ece4b358950281f125ab71561799b9afb9142e4b..9a178c03bbc0a47dd6fd8af8bdeb8be1ebdd96f4 100644 (file)
@@ -171,6 +171,7 @@ void W_Hagar_Attack(Weapon thiswep, entity actor, .entity weaponentity)
        missile.angles = vectoangles(missile.velocity);
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        missile.missile_flags = MIF_SPLASH;
 
        CSQCProjectile(missile, true, PROJECTILE_HAGAR, true);
@@ -215,6 +216,7 @@ void W_Hagar_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
        missile.angles = vectoangles(missile.velocity);
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        missile.missile_flags = MIF_SPLASH;
 
        CSQCProjectile(missile, true, PROJECTILE_HAGAR_BOUNCING, true);
@@ -292,6 +294,7 @@ void W_Hagar_Attack2_Load_Release(entity actor, .entity weaponentity)
                missile.angles = vectoangles(missile.velocity);
                missile.flags = FL_PROJECTILE;
                IL_PUSH(g_projectiles, missile);
+               IL_PUSH(g_bot_dodge, missile);
 
                CSQCProjectile(missile, true, PROJECTILE_HAGAR, true);
 
index c77ccc98e4d12377da82b75aff8ffefb1ba46f1c..79bf08193ec05b9b38e3fa1ac1be46ca102043f3 100644 (file)
@@ -112,6 +112,7 @@ void W_HLAC_Attack(Weapon thiswep, entity actor, .entity weaponentity)
 
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        missile.projectiledeathtype = WEP_HLAC.m_id;
 
        CSQCProjectile(missile, true, PROJECTILE_HLAC, true);
@@ -155,6 +156,7 @@ void W_HLAC_Attack2(entity actor, .entity weaponentity)
 
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        missile.missile_flags = MIF_SPLASH;
        missile.projectiledeathtype = WEP_HLAC.m_id | HITTYPE_SECONDARY;
 
index b2c317459935f818088d5d9feaa7773232257b3a..23e7c23ae5b2b16ccdd9b918e03ea378cfef60e4 100644 (file)
@@ -181,6 +181,7 @@ void W_Hook_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
        gren.angles = '0 0 0';
        gren.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, gren);
+       IL_PUSH(g_bot_dodge, gren);
 
        CSQCProjectile(gren, true, PROJECTILE_HOOKBOMB, true);
 
index a3b356954af68f47a0b07d76ac61aa5d81e4f204..5f5898aa41b78953872242278cfb5e3067a1cf54 100644 (file)
@@ -104,6 +104,7 @@ void W_MineLayer_Stick(entity this, entity to)
        newmine.cnt = this.cnt;
        newmine.flags = this.flags;
        IL_PUSH(g_projectiles, newmine);
+       IL_PUSH(g_bot_dodge, newmine);
 
        delete(this);
 
@@ -373,6 +374,7 @@ void W_MineLayer_Attack(Weapon thiswep, entity actor, .entity weaponentity)
        mine.cnt = (WEP_CVAR(minelayer, lifetime) - WEP_CVAR(minelayer, lifetime_countdown));
        mine.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, mine);
+       IL_PUSH(g_bot_dodge, mine);
        mine.missile_flags = MIF_SPLASH | MIF_ARC | MIF_PROXY;
 
        if(mine.cnt > 0) { mine.cnt += time; }
@@ -436,7 +438,7 @@ METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor))
         IL_EACH(g_mines, it.realowner == actor,
         {
                entity mine = it;
-               FOREACH_ENTITY_FLOAT(bot_attack, true,
+               IL_EACH(g_bot_targets, it.bot_attack,
                {
                        float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - mine.origin);
                        d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
@@ -463,7 +465,7 @@ METHOD(MineLayer, wr_aim, void(entity thiswep, entity actor))
             if(skill > 9) // normal players only do this for the target they are tracking
             {
                    entity mine = it;
-                   FOREACH_ENTITY_FLOAT(bot_attack, true,
+                   IL_EACH(g_bot_targets, it.bot_attack,
                    {
                        if((v_forward * normalize(mine.origin - it.origin) < 0.1)
                            && desirabledamage > 0.1 * coredamage
index 81be156541cb7f31c40d9dd5081ad76c3b41677d..1428cc4fa9d8395b74522f6fc69f2e616d3f90ea 100644 (file)
@@ -248,6 +248,7 @@ void W_Mortar_Attack(Weapon thiswep, entity actor, .entity weaponentity)
        gren.angles = vectoangles(gren.velocity);
        gren.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, gren);
+       IL_PUSH(g_bot_dodge, gren);
 
        if(WEP_CVAR_PRI(mortar, type) == 0 || WEP_CVAR_PRI(mortar, type) == 2)
                CSQCProjectile(gren, true, PROJECTILE_GRENADE, true);
@@ -296,6 +297,7 @@ void W_Mortar_Attack2(Weapon thiswep, entity actor, .entity weaponentity)
        gren.angles = vectoangles(gren.velocity);
        gren.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, gren);
+       IL_PUSH(g_bot_dodge, gren);
 
        if(WEP_CVAR_SEC(mortar, type) == 0 || WEP_CVAR_SEC(mortar, type) == 2)
                CSQCProjectile(gren, true, PROJECTILE_GRENADE, true);
@@ -361,15 +363,14 @@ METHOD(Mortar, wr_think, void(entity thiswep, entity actor, .entity weaponentity
         if(WEP_CVAR_SEC(mortar, remote_detonateprimary))
         {
             bool nadefound = false;
-            entity nade;
-            for(nade = NULL; (nade = find(nade, classname, "grenade")); ) if(nade.realowner == actor)
+            IL_EACH(g_projectiles, it.realowner == actor && it.classname == "grenade",
             {
-                if(!nade.gl_detonate_later)
+                if(!it.gl_detonate_later)
                 {
-                    nade.gl_detonate_later = true;
+                    it.gl_detonate_later = true;
                     nadefound = true;
                 }
-            }
+            });
             if(nadefound)
                 sound(actor, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM);
         }
index 8a689e05109086704ecf726a751aafea27463aee..3e4654fcbbcc41171454192188a8e1ef9f72f393 100644 (file)
@@ -90,6 +90,7 @@ void W_Porto_Fail(entity this, float failhard)
                if(move_out_of_solid(this))
                {
                        this.flags = FL_ITEM;
+                       IL_PUSH(g_items, this);
                        this.velocity = trigger_push_calculatevelocity(this.origin, this.realowner, 128);
                        tracetoss(this, this);
                        if(vdist(trace_endpos - this.realowner.origin, <, 128))
@@ -277,6 +278,7 @@ void W_Porto_Attack(entity actor, .entity weaponentity, float type)
        gren.angles = vectoangles(gren.velocity);
        gren.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, gren);
+       IL_PUSH(g_bot_dodge, gren);
 
        gren.portal_id = time;
        actor.porto_current = gren;
index 850659069a30cd71a6c259aa3c4c49775787515a..268e1916edc91d0c9e3468c229946ff6ad7ff166 100644 (file)
@@ -295,6 +295,7 @@ void W_Seeker_Fire_Missile(Weapon thiswep, entity actor, .entity weaponentity, v
        set_movetype(missile, MOVETYPE_FLYMISSILE);
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        missile.missile_flags = MIF_SPLASH | MIF_GUIDED_TAG;
 
        W_SetupProjVelocity_UP_PRE(missile, seeker, missile_);
@@ -372,6 +373,7 @@ void W_Seeker_Fire_Flac(Weapon thiswep, entity actor, .entity weaponentity)
        missile.projectiledeathtype = WEP_SEEKER.m_id | HITTYPE_SECONDARY;
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        missile.missile_flags       = MIF_SPLASH;
 
        // csqc projectiles
@@ -594,6 +596,7 @@ void W_Seeker_Fire_Tag(Weapon thiswep, entity actor, .entity weaponentity)
 
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
        //missile.missile_flags = MIF_..?;
 
        set_movetype(missile, MOVETYPE_FLY);
index d9c215e24b9d0ca5541875eee81f3fb99331c5c2..e11e4d8d5211aacc6e6d6e483afd0fe0ac45ea88 100644 (file)
@@ -289,6 +289,7 @@ void W_RocketMinsta_Attack2(entity actor, .entity weaponentity)
         setsize(proj, '0 0 -3', '0 0 -3');
         proj.flags = FL_PROJECTILE;
         IL_PUSH(g_projectiles, proj);
+        IL_PUSH(g_bot_dodge, proj);
         proj.missile_flags = MIF_SPLASH;
 
         CSQCProjectile(proj, true, PROJECTILE_ROCKETMINSTA_LASER, true);
@@ -340,6 +341,7 @@ void W_RocketMinsta_Attack3 (entity actor, .entity weaponentity)
         setsize(proj, '0 0 -3', '0 0 -3');
         proj.flags = FL_PROJECTILE;
         IL_PUSH(g_projectiles, proj);
+        IL_PUSH(g_bot_dodge, proj);
         proj.missile_flags = MIF_SPLASH;
 
         CSQCProjectile(proj, true, PROJECTILE_ROCKETMINSTA_LASER, true);
index 86c15ec473e1bcdee8ad4a29891b5f8462ea9194..30ab014ec988f1a2fae062bbe36115b003257872 100644 (file)
@@ -98,6 +98,9 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); }
        .int Version;  // deprecated, use SendFlags
        .int SendFlags;
 
+       IntrusiveList g_uncustomizables;
+       STATIC_INIT(g_uncustomizables) { g_uncustomizables = IL_NEW(); }
+
        void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
        {
                if (e.classname == "") e.classname = "net_linked";
@@ -135,11 +138,13 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); }
                setcefc(e, customizer);
                e.uncustomizeentityforclient = uncustomizer;
                e.uncustomizeentityforclient_set = !!uncustomizer;
+               if(uncustomizer)
+                       IL_PUSH(g_uncustomizables, e);
        }
 
        void UncustomizeEntitiesRun()
        {
-               FOREACH_ENTITY_FLOAT(uncustomizeentityforclient_set, true, it.uncustomizeentityforclient(it));
+               IL_EACH(g_uncustomizables, it.uncustomizeentityforclient_set, it.uncustomizeentityforclient(it));
        }
 
        STRING_ITERATOR(g_buf, string_null, 0);
index 2d093a2ed5fe23078604a10fdfdbe5606d9a2966..4546a62b109503192359c91904ac49bae9b4053c 100644 (file)
@@ -40,12 +40,13 @@ void Xonotic_KeyBinds_Read()
        KEYBIND_DEF("+fire"                                 , _("primary fire"));
        KEYBIND_DEF("+fire2"                                , _("secondary fire"));
        KEYBIND_DEF(""                                      , "");
-       KEYBIND_DEF(""                                      , _("Weapon switching"));
+       KEYBIND_DEF(""                                      , _("Weapons"));
        KEYBIND_DEF("weapprev"                              , CTX(_("WEAPON^previous")));
        KEYBIND_DEF("weapnext"                              , CTX(_("WEAPON^next")));
        KEYBIND_DEF("weaplast"                              , CTX(_("WEAPON^previously used")));
        KEYBIND_DEF("weapbest"                              , CTX(_("WEAPON^best")));
        KEYBIND_DEF("reload"                                , _("reload"));
+       KEYBIND_DEF("dropweapon"                            , _("drop weapon / throw nade"));
 
        int i;
 
@@ -59,9 +60,9 @@ void Xonotic_KeyBinds_Read()
        for(int imp = 1; imp <= 9; ++imp)
        {
         string w_list = "";
-               ADD_TO_W_LIST(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && !(it.spawnflags & WEP_TYPE_OTHER) && !(it.spawnflags & WEP_FLAG_HIDDEN) && !(it.spawnflags & WEP_FLAG_SUPERWEAPON));
-               ADD_TO_W_LIST((it.spawnflags & WEP_FLAG_SUPERWEAPON) && !(it.spawnflags & WEP_TYPE_OTHER) && !(it.spawnflags & WEP_FLAG_HIDDEN));
-               ADD_TO_W_LIST((it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && !(it.spawnflags & WEP_TYPE_OTHER) && !(it.spawnflags & WEP_FLAG_HIDDEN));
+               ADD_TO_W_LIST(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && !(it.spawnflags & WEP_FLAG_HIDDEN) && !(it.spawnflags & WEP_FLAG_SUPERWEAPON));
+               ADD_TO_W_LIST((it.spawnflags & WEP_FLAG_SUPERWEAPON) && !(it.spawnflags & WEP_FLAG_HIDDEN));
+               ADD_TO_W_LIST((it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && !(it.spawnflags & WEP_FLAG_HIDDEN));
                if(w_list)
                        KEYBIND_DEF(strcat("weapon_group_", itos(imp)), substring(w_list, 0, -4));
                if(imp == 0)
@@ -78,6 +79,8 @@ void Xonotic_KeyBinds_Read()
        KEYBIND_DEF("+showscores"                           , _("show scores"));
        KEYBIND_DEF("screenshot"                            , _("screen shot"));
        KEYBIND_DEF("+hud_panel_radar_maximized"            , _("maximize radar"));
+       KEYBIND_DEF("toggle chase_active"                   , _("3rd person view"));
+       KEYBIND_DEF("spec"                                  , _("enter spectator mode"));
        KEYBIND_DEF(""                                      , "");
        KEYBIND_DEF(""                                      , _("Communicate"));
        KEYBIND_DEF("messagemode"                           , _("public chat"));
@@ -97,12 +100,12 @@ void Xonotic_KeyBinds_Read()
        KEYBIND_DEF("messagemode2"                          , _("team chat"));
        KEYBIND_DEF("team_auto"                             , _("auto-join team"));
        KEYBIND_DEF("menu_showteamselect"                   , _("team menu"));
-       KEYBIND_DEF("menu_showsandboxtools"                 , _("sandbox menu"));
-       KEYBIND_DEF("spec"                                  , _("enter spectator mode"));
-       KEYBIND_DEF("dropweapon"                            , _("drop weapon"));
        KEYBIND_DEF("+use"                                  , _("drop key / drop flag"));
+       KEYBIND_DEF(""                                      , "");
+       KEYBIND_DEF(""                                      , _("Misc"));
+       KEYBIND_DEF("quickmenu"                             , _("quick menu"));
+       KEYBIND_DEF("menu_showsandboxtools"                 , _("sandbox menu"));
        KEYBIND_DEF("+button8"                              , _("drag object"));
-       KEYBIND_DEF("toggle chase_active"                   , _("3rd person view"));
        KEYBIND_DEF(""                                      , "");
        KEYBIND_DEF(""                                      , _("User defined"));
 
index 1a90fa737827bc8e2afaa6b074306d815439d046..c679d4449d7177598dc649228f7e4cc96b11be76 100644 (file)
@@ -38,6 +38,8 @@ void XonoticPlayerModelSelector_loadModels(entity me)
                fn = search_getfilename(glob, i);
                if(!get_model_parameters(fn, -1))
                        continue;
+               if(get_model_parameters_hidden)
+                       continue;
                bufstr_add(sortbuf, sprintf("%-128s%s", get_model_parameters_name, fn), 1);
        }
        search_end(glob);
@@ -49,6 +51,8 @@ void XonoticPlayerModelSelector_loadModels(entity me)
                fn = substring(bufstr_get(sortbuf, i), 128, -1);
                if(!get_model_parameters(fn, -1))
                        error("But it JUST worked!");
+               if(get_model_parameters_hidden)
+                       continue;
                bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_TITLE, get_model_parameters_name);
                bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_IMAGE, strcat("/", substring(get_model_datafilename(get_model_parameters_modelname, get_model_parameters_modelskin, "tga"), 0, -5)));
                bufstr_set(me.bufModels, BUFMODELS_COUNT*i+BUFMODELS_MODEL, get_model_parameters_modelname);
index a8d45bd5221ce1cde56fa0e9c8d3dd98fc639898..a1bb5fb958d5da0cdf69d86759fc9b48bfe7de82 100644 (file)
@@ -405,7 +405,8 @@ float autocvar_g_monsters_respawn_delay;
 bool autocvar_g_monsters_respawn;
 float autocvar_g_monsters_armor_blockpercent;
 float autocvar_g_monsters_healthbars;
-float autocvar_g_monsters_lineofsight;
+bool autocvar_g_monsters_lineofsight = true;
+//bool autocvar_g_monsters_ignoretraces = true;
 #define autocvar_g_bloodloss cvar("g_bloodloss")
 bool autocvar_g_nades;
 bool autocvar_g_nades_override_dropweapon = true;
index 59af78cb086c2181d662cf68c060a2cced87b5c3..64957b92e09c0b7ea7b26e8955cebcc3e784a60f 100644 (file)
@@ -63,7 +63,6 @@ void bot_think(entity this);
 entity find_bot_by_name(string name);
 entity find_bot_by_number(float number);
 
-void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius);
 void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius);
 void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius);
 
index 502e2532c6924add3d39208cbf90298d6781f450..ca12d0d651cf53e9caa39a6afa01bd3528a466f8 100644 (file)
@@ -436,7 +436,7 @@ void bot_removefromlargestteam()
        int bestcount = 0;
 
        int bcount = 0;
-       FOREACH_ENTITY_FLOAT(isbot, true,
+       FOREACH_CLIENT(it.isbot,
        {
                ++bcount;
 
@@ -486,7 +486,7 @@ void bot_removenewest()
        entity best = NULL;
        int bcount = 0;
 
-       FOREACH_ENTITY_FLOAT(isbot, true,
+       FOREACH_CLIENT(it.isbot,
        {
                ++bcount;
 
index d23c29675a70fa7bc5d2944922f143ee6a7c9a28..45051b6c270f1e738aa05786b3fbc9f54f1ecc34 100644 (file)
@@ -13,6 +13,7 @@
 #include <common/state.qh>
 #include <common/items/_mod.qh>
 
+#include <common/triggers/teleporters.qh>
 #include <common/triggers/trigger/jumppads.qh>
 
 #include <lib/warpzone/common.qh>
@@ -836,6 +837,26 @@ void havocbot_movetogoal(entity this)
        if (((dodge * v_up) < 0) && random()*frametime >= 0.5*bound(0,(10-skill-this.bot_dodgeskill)*0.1,1)) this.havocbot_ducktime=time+0.3/bound(0.1,skill+this.bot_dodgeskill,10);
 }
 
+entity havocbot_gettarget(entity this, bool secondary)
+{
+       entity best = NULL;
+       vector eye = CENTER_OR_VIEWOFS(this);
+       IL_EACH(g_bot_targets, boolean((secondary) ? it.classname == "misc_breakablemodel" : it.classname != "misc_breakablemodel"),
+       {
+               vector v = CENTER_OR_VIEWOFS(it);
+               if(vdist(v - eye, <, autocvar_bot_ai_enemydetectionradius))
+               if(!best || vlen2(CENTER_OR_VIEWOFS(best) - eye) > vlen2(v - eye))
+               if(bot_shouldattack(this, it))
+               {
+                       traceline(eye, v, true, this);
+                       if (trace_ent == it || trace_fraction >= 1)
+                               best = it;
+               }
+       });
+
+       return best;
+}
+
 void havocbot_chooseenemy(entity this)
 {
        entity head, best, head2;
@@ -1214,7 +1235,7 @@ float havocbot_moveto(entity this, vector pos)
        this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_LINKING;
 
        // if pos is inside a teleport, then let's mark it as teleport waypoint
-       FOREACH_ENTITY_CLASS("trigger_teleport", WarpZoneLib_BoxTouchesBrush(pos, pos, it, NULL),
+       IL_EACH(g_teleporters, WarpZoneLib_BoxTouchesBrush(pos, pos, it, NULL),
        {
                wp.wpflags |= WAYPOINTFLAG_TELEPORT;
                this.lastteleporttime = 0;
index 771ab282ddd49039f36fcfbed52a8cb24ccb18c1..dcf18ef19b1f3622a1eb12590ec66d937d51add9 100644 (file)
@@ -19,7 +19,7 @@ void havocbot_goalrating_items(entity this, float ratingscale, vector org, float
        vector o;
        ratingscale = ratingscale * 0.0001; // items are rated around 10000 already
 
-       FOREACH_ENTITY_FLOAT(bot_pickup, true,
+       IL_EACH(g_items, it.bot_pickup,
        {
                o = (it.absmin + it.absmax) * 0.5;
                friend_distance = 10000; enemy_distance = 10000;
@@ -118,19 +118,6 @@ void havocbot_goalrating_items(entity this, float ratingscale, vector org, float
        });
 }
 
-void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius)
-{
-       FOREACH_ENTITY_CLASS("dom_controlpoint", vdist((((it.absmin + it.absmax) * 0.5) - org), <, sradius),
-       {
-               if(it.cnt > -1) // this is just being fought
-                       navigation_routerating(this, it, ratingscale, 5000);
-               else if(it.goalentity.cnt == 0) // unclaimed
-                       navigation_routerating(this, it, ratingscale * 0.5, 5000);
-               else if(it.goalentity.team != this.team) // other team's point
-                       navigation_routerating(this, it, ratingscale * 0.2, 5000);
-       });
-}
-
 void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius)
 {
        if (autocvar_bot_nofire)
index 5b1f2b530de231e60d79dd03f76ea8d758e66809..6f70f09beec2219624baeca92e2cd7deaa104fb4 100644 (file)
@@ -1,2 +1 @@
 #pragma once
-void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius);
index 51325f4f966c10349070f2ac7b9bbb898eb2dc8c..0c563d1ff9e2f1953775caa14b437171fe74c480 100644 (file)
@@ -1000,7 +1000,7 @@ void botframe_updatedangerousobjects(float maxupdate)
                danger = 0;
                m1 = it.mins;
                m2 = it.maxs;
-               FOREACH_ENTITY_FLOAT(bot_dodge, true,
+               IL_EACH(g_bot_dodge, it.bot_dodge,
                {
                        v = it.origin;
                        v.x = bound(m1_x, v.x, m2_x);
index e111b2ab4f043f5174b270b5090f6190a3dfb5c1..fa273410ea6882bd012daff70dffe93c67c17743 100644 (file)
@@ -230,17 +230,10 @@ void bot_commands_init()
 // Returns first bot with matching name
 entity find_bot_by_name(string name)
 {
-       entity bot;
-
-       bot = findchainflags(flags, FL_CLIENT);
-       while (bot)
+       FOREACH_CLIENT(IS_BOT_CLIENT(it) && it.netname == name,
        {
-               if(IS_BOT_CLIENT(bot))
-               if(bot.netname==name)
-                       return bot;
-
-               bot = bot.chain;
-       }
+               return it;
+       });
 
        return NULL;
 }
index 8475640ac7086462ab73f087d6b8fc9603f285c5..5fb923799acfa41f863414a7ed96d33253874acd 100644 (file)
@@ -34,7 +34,7 @@ entity waypoint_spawn(vector m1, vector m2, float f)
        w.solid = SOLID_TRIGGER;
        setorigin(w, (m1 + m2) * 0.5);
        setsize(w, m1 - w.origin, m2 - w.origin);
-       if (vlen(w.size) > 0)
+       if (w.size)
                w.wpisbox = true;
 
        if(!w.wpisbox)
@@ -280,7 +280,7 @@ void waypoint_schedulerelink(entity wp)
        }
        else
                wp.model = "";
-       wp.wpisbox = vlen(wp.size) > 0;
+       wp.wpisbox = vdist(wp.size, >, 0);
        wp.enemy = NULL;
        if (!(wp.wpflags & WAYPOINTFLAG_PERSONAL))
                wp.owner = NULL;
@@ -1012,7 +1012,7 @@ void botframe_autowaypoints_fix(entity p, float walkfromwp, .entity fld)
 
 void botframe_deleteuselesswaypoints()
 {
-       FOREACH_ENTITY_FLOAT(bot_pickup, true,
+       IL_EACH(g_items, it.bot_pickup,
        {
                // NOTE: this protects waypoints if they're the ONLY nearest
                // waypoint. That's the intention.
index 271252dee96b47c028839ce4967289e97372e690..b4102cb6c09a20178f8549f1051da6afa71f5f45 100644 (file)
@@ -18,7 +18,6 @@ void bot_think(entity this) { }
 entity find_bot_by_name(string name) { return NULL; }
 entity find_bot_by_number(float number) { return NULL; }
 
-void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius) { }
 void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius) { }
 void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius) { }
 
index 71e0cd2e861805db6342b4203e39066b85ac39bc..9f763a886d73217cd4490aa05fba9f75a2add448 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <common/physics/player.qh>
 
-#include "../common/monsters/all.qh"
+#include "../common/monsters/_mod.qh"
 
 #include <common/weapons/_all.qh>
 
@@ -913,7 +913,7 @@ void Drag_Finish(entity dragger)
                        break;
        }
 
-       if((draggee.flags & FL_ITEM) && (vlen(draggee.velocity) < 32))
+       if((draggee.flags & FL_ITEM) && (vdist(draggee.velocity, <, 32)))
        {
                draggee.velocity = '0 0 0';
                SET_ONGROUND(draggee); // floating items are FUN
index d0449418383128bfc92d1a639abda7d01d449ba4..cb50d7cdaa9e207d9377ebb9694d2fe658db19a1 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <common/effects/qc/globalsound.qh>
 
+#include "../common/triggers/func/conveyor.qh"
 #include "../common/triggers/teleporters.qh"
 
 #include "../common/vehicles/all.qh"
@@ -295,6 +296,8 @@ void PutObserverInServer(entity this)
        accuracy_resend(this);
 
        this.spectatortime = time;
+       if(this.bot_attack)
+               IL_REMOVE(g_bot_targets, this);
        this.bot_attack = false;
     this.hud = HUD_NORMAL;
        TRANSMUTE(Observer, this);
@@ -631,11 +634,15 @@ void PutClientInServer(entity this)
                this.oldorigin = this.origin;
                this.prevorigin = this.origin;
                this.lastteleporttime = time; // prevent insane speeds due to changing origin
+               if(this.conveyor)
+                       IL_REMOVE(g_conveyed, this);
                this.conveyor = NULL; // prevent conveyors at the previous location from moving a freshly spawned player
                this.hud = HUD_NORMAL;
 
                this.event_damage = PlayerDamage;
 
+               if(!this.bot_attack)
+                       IL_PUSH(g_bot_targets, this);
                this.bot_attack = true;
                this.monster_attack = true;
 
@@ -938,10 +945,8 @@ void ClientKill_TeamChange (entity this, float targetteam) // 0 = don't change,
                        this.killindicator.count = bound(0, ceil(killtime), 10);
                        //sprint(this, strcat("^1You'll be dead in ", ftos(this.killindicator.cnt), " seconds\n"));
 
-                       FOREACH_ENTITY_ENT(enemy, this,
+                       IL_EACH(g_clones, it.enemy == this && !(it.effects & CSQCMODEL_EF_RESPAWNGHOST),
                        {
-                               if(it.classname != "body")
-                                       continue;
                                it.killindicator = spawn();
                                it.killindicator.owner = it;
                                it.killindicator.scale = 0.5;
@@ -1200,7 +1205,7 @@ void ClientConnect(entity this)
        if (IS_REAL_CLIENT(this))
                sv_notice_join(this);
 
-       FOREACH_ENTITY_FLOAT(init_for_player_needed, true, {
+       IL_EACH(g_initforplayer, it.init_for_player, {
                it.init_for_player(it, this);
        });
 
index 35ff6e961c61808a8f5f3cdd0f87e288653bd4f5..c2317aff0280b46179c7bc52d3d79f95913eba7f 100644 (file)
@@ -2,6 +2,9 @@
 
 void ClientState_attach(entity this);
 
+IntrusiveList g_players;
+STATIC_INIT(g_players) { g_players = IL_NEW(); }
+
 CLASS(Client, Object)
     /** Client name */
     ATTRIB(Client, netname, string, this.netname);
@@ -71,8 +74,11 @@ ENDCLASS(Spectator)
 CLASS(Player, Client)
     INIT(Player) {
         this.classname = STR_PLAYER;
+        IL_PUSH(g_players, this);
+    }
+    DESTRUCTOR(Player) {
+        IL_REMOVE(g_players, this);
     }
-    DESTRUCTOR(Player) { }
 ENDCLASS(Player)
 
 METHOD(Client, m_unwind, bool(Client this))
index 5d6ad3adab263edf38a8c51bec8febbab19528d8..e613599119a967fe7762d39f78dbf02150a3fc8e 100644 (file)
@@ -30,8 +30,8 @@
 
 #include <common/minigames/sv_minigames.qh>
 
-#include <common/monsters/all.qc>
-#include <common/monsters/spawn.qh>
+#include <common/monsters/_mod.qh>
+#include <common/monsters/sv_spawn.qh>
 #include <common/monsters/sv_monsters.qh>
 
 #include <lib/warpzone/common.qh>
index 357a33eba2d5d1cb398a138883ccd83b606fcca5..35418a02f07d420a9e0805f341a73cbaa6632ca5 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "../scores.qh"
 
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
 #include <common/notifications/all.qh>
 #include <lib/warpzone/common.qh>
 
index 7fbbddf7d799f5c7e7d100537dba926956c84a38..978a92b14f0c1fd4f6d5224f4a3610cf9caf67d9 100644 (file)
@@ -19,7 +19,7 @@ STATIC_INIT(COMMON_COMMANDS_aliases) {
 }
 
 #include "vote.qh"
-#include <common/monsters/spawn.qh>
+#include <common/monsters/sv_spawn.qh>
 
 #include <common/command/_mod.qh>
 
index 2598724717a72b3b3bdf5d22fd3168895cb55fe1..9380fc4cde280f0cd9fda57a24cd6bddbd41da56 100644 (file)
@@ -8,7 +8,7 @@
 #include <common/mapinfo.qh>
 #include <common/util.qh>
 
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
 
 // =========================================================
 //  Reply messages for common commands, re-worked by Samual
index acf2d40aee5233935b6569cb445a0c52c4d1ca88..a5e4a7547a51289d1d670dca53676910de761daa 100644 (file)
@@ -26,7 +26,7 @@ float FullTraceFraction(vector a, vector mi, vector ma, vector b)
        float n, m;
        n = m = 0;
 
-       while (vlen(c - b) > 1)
+       while (vdist(c - b, >, 1))
        {
                ++m;
 
index a6bd1552d2250d7c0a2ee1895173586b4f9ab81f..b034968901e741e40d348952fdf7ef40ab16f9d9 100644 (file)
@@ -426,7 +426,6 @@ const int MIF_GUIDED_CONFUSABLE = MIF_GUIDED_HEAT | MIF_GUIDED_AI;
 
 .string cvar_cl_physics;
 
-.bool init_for_player_needed;
 .void(entity this, entity player) init_for_player;
 
 IntrusiveList g_monsters;
@@ -446,3 +445,30 @@ STATIC_INIT(g_mines) { g_mines = IL_NEW(); }
 
 IntrusiveList g_projectiles;
 STATIC_INIT(g_projectiles) { g_projectiles = IL_NEW(); }
+
+IntrusiveList g_items;
+STATIC_INIT(g_items) { g_items = IL_NEW(); }
+
+IntrusiveList g_initforplayer;
+STATIC_INIT(g_initforplayer) { g_initforplayer = IL_NEW(); }
+
+IntrusiveList g_clones;
+STATIC_INIT(g_clones) { g_clones = IL_NEW(); }
+
+IntrusiveList g_assault_destructibles;
+STATIC_INIT(g_assault_destructibles) { g_assault_destructibles = IL_NEW(); }
+
+IntrusiveList g_assault_objectivedecreasers;
+STATIC_INIT(g_assault_objectivedecreasers) { g_assault_objectivedecreasers = IL_NEW(); }
+
+IntrusiveList g_assault_objectives;
+STATIC_INIT(g_assault_objectives) { g_assault_objectives = IL_NEW(); }
+
+IntrusiveList g_spawnpoints;
+STATIC_INIT(g_spawnpoints) { g_spawnpoints = IL_NEW(); }
+
+IntrusiveList g_bot_targets;
+STATIC_INIT(g_bot_targets) { g_bot_targets = IL_NEW(); }
+
+IntrusiveList g_bot_dodge;
+STATIC_INIT(g_bot_dodge) { g_bot_dodge = IL_NEW(); }
index e3cada6c84b0acc6332325b7cc9f71ddce10797a..3e448363655f6ce712a84efb3af74f3202a68db1 100644 (file)
@@ -526,6 +526,8 @@ void Freeze (entity targ, float freeze_time, float frozen_type, float show_waypo
        targ.revive_progress = ((frozen_type == 3) ? 1 : 0);
        targ.health = ((frozen_type == 3) ? targ_maxhealth : 1);
        targ.revive_speed = freeze_time;
+       if(targ.bot_attack)
+               IL_REMOVE(g_bot_targets, targ);
        targ.bot_attack = false;
 
        entity ice = new(ice);
@@ -563,6 +565,8 @@ void Unfreeze (entity targ)
        STAT(FROZEN, targ) = 0;
        targ.revive_progress = 0;
        targ.revival_time = time;
+       if(!targ.bot_attack)
+               IL_PUSH(g_bot_targets, targ);
        targ.bot_attack = true;
 
        WaypointSprite_Kill(targ.waypointsprite_attached);
@@ -835,7 +839,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
 
        // apply push
        if (targ.damageforcescale)
-       if (vlen(force))
+       if (force)
        if (!IS_PLAYER(targ) || time >= targ.spawnshieldtime || targ == attacker)
        {
                vector farce = damage_explosion_calcpush(targ.damageforcescale * force, targ.velocity, autocvar_g_balance_damagepush_speedfactor);
@@ -859,7 +863,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, int d
                UpdateCSQCProjectile(targ);
        }
        // apply damage
-       if (damage != 0 || (targ.damageforcescale && vlen(force)))
+       if (damage != 0 || (targ.damageforcescale && force))
        if (targ.event_damage)
                targ.event_damage (targ, inflictor, attacker, damage, deathtype, hitloc, force);
 
@@ -1034,7 +1038,7 @@ float RadiusDamageForSource (entity inflictor, vector inflictororigin, vector in
                                        //      print(" finaldmg ", ftos(finaldmg), " force ", vtos(force));
                                        //      print(" (", ftos(a), ")\n");
                                        //}
-                                       if(finaldmg || vlen(force))
+                                       if(finaldmg || force)
                                        {
                                                if(targ.iscreature)
                                                {
index 46508a9191162f34554428248f7d6118a221d41f..90266189b83c1adf5f4ea6f7db111c9780e3c24c 100644 (file)
@@ -371,6 +371,7 @@ void FireGrapplingHook(entity actor)
        missile.classname = "grapplinghook";
        missile.flags = FL_PROJECTILE;
        IL_PUSH(g_projectiles, missile);
+       IL_PUSH(g_bot_dodge, missile);
 
        set_movetype(missile, ((autocvar_g_balance_grapplehook_gravity) ? MOVETYPE_TOSS : MOVETYPE_FLY));
        PROJECTILE_MAKETRIGGER(missile);
index 0f18ad06e85cef6452e3c8eb9bcbc748f7754a36..e3bc706979607a7aa99c1e7a6203027cd67dd417 100644 (file)
@@ -21,7 +21,7 @@
 #include "../common/constants.qh"
 #include "../common/deathtypes/all.qh"
 #include "../common/mapinfo.qh"
-#include "../common/monsters/all.qh"
+#include "../common/monsters/_mod.qh"
 #include "../common/monsters/sv_monsters.qh"
 #include "../common/vehicles/all.qh"
 #include "../common/notifications/all.qh"
@@ -555,6 +555,8 @@ spawnfunc(__init_dedicated_server)
        static_init_late();
        static_init_precache();
 
+       IL_PUSH(g_spawnpoints, e); // just incase
+
        MapInfo_Enumerate();
        MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
 }
@@ -1332,32 +1334,32 @@ entity FindIntermission()
        local   float cyc;
 
 // look for info_intermission first
-       spot = find (NULL, classname, "info_intermission");
+       spot = find(NULL, classname, "info_intermission");
        if (spot)
        {       // pick a random one
                cyc = random() * 4;
                while (cyc > 1)
                {
-                       spot = find (spot, classname, "info_intermission");
+                       spot = find(spot, classname, "info_intermission");
                        if (!spot)
-                               spot = find (spot, classname, "info_intermission");
+                               spot = find(spot, classname, "info_intermission");
                        cyc = cyc - 1;
                }
                return spot;
        }
 
 // then look for the start position
-       spot = find (NULL, classname, "info_player_start");
+       spot = find(NULL, classname, "info_player_start");
        if (spot)
                return spot;
 
 // testinfo_player_start is only found in regioned levels
-       spot = find (NULL, classname, "testplayerstart");
+       spot = find(NULL, classname, "testplayerstart");
        if (spot)
                return spot;
 
 // then look for the start position
-       spot = find (NULL, classname, "info_player_deathmatch");
+       spot = find(NULL, classname, "info_player_deathmatch");
        if (spot)
                return spot;
 
@@ -1768,7 +1770,8 @@ float WinningCondition_RanOutOfSpawns()
                }
        ));
 
-       FOREACH_ENTITY_CLASS("info_player_deathmatch", true, LAMBDA(
+       IL_EACH(g_spawnpoints, true,
+       {
                switch(it.team)
                {
                        case NUM_TEAM_1: team1_score = 1; break;
@@ -1776,7 +1779,7 @@ float WinningCondition_RanOutOfSpawns()
                        case NUM_TEAM_3: team3_score = 1; break;
                        case NUM_TEAM_4: team4_score = 1; break;
                }
-       ));
+       });
 
        ClearWinners();
        if(team1_score + team2_score + team3_score + team4_score == 0)
index 4660a433ba543fee479e6c053a4d629d3a926ad5..8a10a6d7525f5c973367b7adef18c16546cfd8a6 100644 (file)
@@ -551,7 +551,7 @@ IMPULSE(navwaypoint_unreachable)
        if (m) LOG_INFOF("%d waypoints have been marked total\n", m);
 
        j = 0;
-       FOREACH_ENTITY_CLASS("info_player_deathmatch", true,
+       IL_EACH(g_spawnpoints, true,
        {
                vector org = it.origin;
                tracebox(it.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - '0 0 512', MOVE_NOMONSTERS, NULL);
@@ -578,12 +578,12 @@ IMPULSE(navwaypoint_unreachable)
        if (j) LOG_INFOF("%d spawnpoints have no nearest waypoint (marked by player model)\n", j);
 
        j = 0;
-       FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
+       IL_EACH(g_items, true,
        {
                it.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
                it.colormod = '0.5 0.5 0.5';
        });
-       FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
+       IL_EACH(g_items, true,
        {
                if (navigation_findnearestwaypoint(it, false)) continue;
                LOG_INFO("item without waypoint: ", etos(it), " ", vtos(it.origin), "\n");
@@ -594,7 +594,7 @@ IMPULSE(navwaypoint_unreachable)
        if (j) LOG_INFOF("%d items have no nearest waypoint and cannot be walked away from (marked with red light)\n", j);
 
        j = 0;
-       FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
+       IL_EACH(g_items, true,
        {
                if (navigation_findnearestwaypoint(it, true)) continue;
                LOG_INFO("item without waypoint: ", etos(it), " ", vtos(it.origin), "\n");
index 05172241c3e320630e3e4fc02321de3ab370c86f..d33fe87c2e1a477189000119b501b52c6f69c88e 100644 (file)
@@ -1,7 +1,7 @@
 #include "item_key.qh"
 
 #include "../common/triggers/subs.qh"
-#include "../common/monsters/all.qh"
+#include "../common/monsters/_mod.qh"
 #include "../common/notifications/all.qh"
 #include "../common/util.qh"
 #include "../lib/warpzone/util_server.qh"
index 58cd949297acefe1af5e3e48d65f8f098f6c58b4..4b3d404bf316907a579f6d246330d9f591b257c8 100644 (file)
@@ -1144,7 +1144,6 @@ float MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundma
 {
     float m, i;
     vector start, org, delta, end, enddown, mstart;
-    entity sp;
 
     m = e.dphitcontentsmask;
     e.dphitcontentsmask = goodcontents | badcontents;
@@ -1200,16 +1199,26 @@ float MoveToRandomLocationWithinBounds(entity e, vector boundmin, vector boundma
             continue;
 
        // rule 4: we must "see" some spawnpoint or item
-       for(sp = NULL; (sp = find(sp, classname, "info_player_deathmatch")); )
-               if(checkpvs(mstart, sp))
-                       if((traceline(mstart, sp.origin, MOVE_NORMAL, e), trace_fraction) >= 1)
-                               break;
+    entity sp = NULL;
+    IL_EACH(g_spawnpoints, checkpvs(mstart, it),
+    {
+       if((traceline(mstart, it.origin, MOVE_NORMAL, e), trace_fraction) >= 1)
+       {
+               sp = it;
+               break;
+       }
+    });
        if(!sp)
        {
-               for(sp = NULL; (sp = findflags(sp, flags, FL_ITEM)); )
-                       if(checkpvs(mstart, sp))
-                               if((traceline(mstart, sp.origin + (sp.mins + sp.maxs) * 0.5, MOVE_NORMAL, e), trace_fraction) >= 1)
-                                       break;
+               IL_EACH(g_items, checkpvs(mstart, it),
+               {
+                       if((traceline(mstart, it.origin + (it.mins + it.maxs) * 0.5, MOVE_NORMAL, e), trace_fraction) >= 1)
+                       {
+                               sp = it;
+                               break;
+                       }
+               });
+
                if(!sp)
                        continue;
        }
index ba3e48f17c1d5bba002d5c0f30e0d835ee405955..9a473affdf8bc1f8105cdbc9cef20fca5d8a1cea 100644 (file)
@@ -21,9 +21,9 @@
 #include <common/command/_mod.qh>
 #include <common/net_notice.qh>
 #include <common/animdecide.qh>
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
 #include <common/monsters/sv_monsters.qh>
-#include <common/monsters/spawn.qh>
+#include <common/monsters/sv_spawn.qh>
 #include <common/weapons/config.qh>
 #include <common/weapons/_all.qh>
 #include <server/weapons/accuracy.qh>
@@ -81,7 +81,7 @@
 
 #include <server/command/_mod.qh>
 
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
 
 #include <server/weapons/tracing.qh>
 #include <server/weapons/weaponsystem.qh>
index 9c13e1bb63e7393269853cafafb431d41f2ee8e4..e051cd6978dc6da2619fccfa06efc6e1ef2d61be 100644 (file)
@@ -27,7 +27,7 @@
 #include <common/stats.qh>
 #include <common/teams.qh>
 
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
 
 #include <lib/warpzone/anglestransform.qh>
 #include <lib/warpzone/server.qh>
index 5814e7cb744e2c56ea3a6b257fa2adc76410c117..f4566a9ca667b305a759e05fcf96edf9dc7c6e4c 100644 (file)
@@ -10,13 +10,10 @@ void assault_objective_use(entity this, entity actor, entity trigger)
        //print("^2Activated objective ", this.targetname, "=", etos(this), "\n");
        //print("Activator is ", actor.classname, "\n");
 
-       for (entity e = NULL; (e = find(e, target, this.targetname)); )
+       IL_EACH(g_assault_objectivedecreasers, it.target == this.targetname,
        {
-               if (e.classname == "target_objective_decrease")
-               {
-                       target_objective_decrease_activate(e);
-               }
-       }
+               target_objective_decrease_activate(it);
+       });
 }
 
 vector target_objective_spawn_evalfunc(entity this, entity player, entity spot, vector current)
@@ -74,16 +71,13 @@ void assault_objective_decrease_use(entity this, entity actor, entity trigger)
 
 void assault_setenemytoobjective(entity this)
 {
-       FOREACH_ENTITY_STRING(targetname, this.target,
+       IL_EACH(g_assault_objectives, it.targetname == this.target,
        {
-               if(it.classname == "target_objective")
-               {
-                       if(this.enemy == NULL)
-                               this.enemy = it;
-                       else
-                               objerror(this, "more than one objective as target - fix the map!");
-                       break;
-               }
+               if(this.enemy == NULL)
+                       this.enemy = it;
+               else
+                       objerror(this, "more than one objective as target - fix the map!");
+               break;
        });
 
        if(this.enemy == NULL)
@@ -150,7 +144,8 @@ void assault_roundstart_use(entity this, entity actor, entity trigger)
        SUB_UseTargets(this, this, trigger);
 
        //(Re)spawn all turrets
-       FOREACH_ENTITY_CLASS("turret_main", true, LAMBDA(
+       IL_EACH(g_turrets, true,
+       {
                // Swap turret teams
                if(it.team == NUM_TEAM_1)
                        it.team = NUM_TEAM_2;
@@ -159,7 +154,7 @@ void assault_roundstart_use(entity this, entity actor, entity trigger)
 
                // Doubles as teamchange
                turret_respawn(it);
-       ));
+       });
 }
 void assault_roundstart_use_this(entity this)
 {
@@ -286,6 +281,7 @@ spawnfunc(target_objective)
        if (!g_assault) { delete(this); return; }
 
        this.classname = "target_objective";
+       IL_PUSH(g_assault_objectives, this);
        this.use = assault_objective_use;
        this.reset = assault_objective_reset;
        this.reset(this);
@@ -297,6 +293,7 @@ spawnfunc(target_objective_decrease)
        if (!g_assault) { delete(this); return; }
 
        this.classname = "target_objective_decrease";
+       IL_PUSH(g_assault_objectivedecreasers, this);
 
        if(!this.dmg)
                this.dmg = 101;
@@ -317,6 +314,7 @@ spawnfunc(func_assault_destructible)
 
        this.spawnflags = 3;
        this.classname = "func_assault_destructible";
+       IL_PUSH(g_assault_destructibles, this);
 
        if(assault_attacker_team == NUM_TEAM_1)
                this.team = NUM_TEAM_2;
@@ -364,17 +362,15 @@ spawnfunc(target_assault_roundstart)
 // legacy bot code
 void havocbot_goalrating_ast_targets(entity this, float ratingscale)
 {
-       FOREACH_ENTITY_CLASS("func_assault_destructible", it.bot_attack,
+       IL_EACH(g_assault_destructibles, it.bot_attack,
        {
                if (it.target == "")
                        continue;
 
                bool found = false;
-               FOREACH_ENTITY_STRING(targetname, it.target,
+               entity destr = it;
+               IL_EACH(g_assault_objectivedecreasers, it.targetname == destr.target,
                {
-                       if(it.classname != "target_objective_decrease")
-                               continue;
-
                        if(it.enemy.health > 0 && it.enemy.health < ASSAULT_VALUE_INACTIVE)
                        {
                                found = true;
index 017fb265b9adc89fcb7aa5d63ab61d8c66e8dff6..79ac9994625de1b4a1f05da3ad540dee3d75d876 100644 (file)
@@ -1234,6 +1234,7 @@ void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag e
        flag.classname = "item_flag_team";
        flag.target = "###item###"; // wut?
        flag.flags = FL_ITEM | FL_NOTARGET;
+       IL_PUSH(g_items, flag);
        flag.solid = SOLID_TRIGGER;
        flag.takedamage = DAMAGE_NO;
        flag.damageforcescale = autocvar_g_ctf_flag_damageforcescale;
@@ -1527,7 +1528,7 @@ void havocbot_goalrating_ctf_droppedflags(entity this, float ratingscale, vector
 
 void havocbot_goalrating_ctf_carrieritems(entity this, float ratingscale, vector org, float sradius)
 {
-       FOREACH_ENTITY_FLOAT(bot_pickup, true,
+       IL_EACH(g_items, it.bot_pickup,
        {
                // gather health and armor only
                if (it.solid)
index 33030f2f9cce0057f094d1b173f6959f63f74ffe..4cd8e8767e5f163b58efd886f7e320c8dd66cd71 100644 (file)
@@ -18,7 +18,7 @@ void havocbot_role_cts(entity this)
                this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
                navigation_goalrating_start(this);
 
-               FOREACH_ENTITY_CLASS("trigger_race_checkpoint", true,
+               IL_EACH(g_racecheckpoints, true,
                {
                        if(it.cnt == this.race_checkpoint)
                                navigation_routerating(this, it, 1000000, 5000);
index 6ad5d4849910f19f468c193dcd4c51707586cb28..abcae5ada5dffb2db2381386b8a9d0a23627d5b4 100644 (file)
@@ -99,7 +99,8 @@ void dompoint_captured(entity this)
        WaypointSprite_UpdateSprites(this.sprite, msg, WP_Null, WP_Null);
 
        total_pps = 0, pps_red = 0, pps_blue = 0, pps_yellow = 0, pps_pink = 0;
-       FOREACH_ENTITY_CLASS("dom_controlpoint", true, LAMBDA(
+       IL_EACH(g_dompoints, true,
+       {
                if (autocvar_g_domination_point_amt)
                        points = autocvar_g_domination_point_amt;
                else
@@ -116,7 +117,7 @@ void dompoint_captured(entity this)
                        case NUM_TEAM_4: pps_pink += points/wait_time; break;
                }
                total_pps += points/wait_time;
-       ));
+       });
 
        WaypointSprite_UpdateTeamRadar(this.sprite, RADARICON_DOMPOINT, colormapPaletteColor(this.goalentity.team - 1, 0));
        WaypointSprite_Ping(this.sprite);
@@ -283,6 +284,8 @@ void dom_controlpoint_setup(entity this)
        this.nextthink = time;
        settouch(this, dompointtouch);
        this.solid = SOLID_TRIGGER;
+       if(!this.flags & FL_ITEM)
+               IL_PUSH(g_items, this);
        this.flags = FL_ITEM;
        setsize(this, '-32 -32 -32', '32 32 32');
        setorigin(this, this.origin + '0 0 20');
@@ -296,7 +299,7 @@ float total_controlpoints;
 void Domination_count_controlpoints()
 {
        total_controlpoints = redowned = blueowned = yellowowned = pinkowned = 0;
-       FOREACH_ENTITY_CLASS("dom_controlpoint", true,
+       IL_EACH(g_dompoints, true,
        {
                ++total_controlpoints;
                redowned += (it.goalentity.team == NUM_TEAM_1);
@@ -378,6 +381,19 @@ void Domination_RoundStart()
 }
 
 //go to best items, or control points you don't own
+void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius)
+{
+       IL_EACH(g_dompoints, vdist((((it.absmin + it.absmax) * 0.5) - org), <, sradius),
+       {
+               if(it.cnt > -1) // this is just being fought
+                       navigation_routerating(this, it, ratingscale, 5000);
+               else if(it.goalentity.cnt == 0) // unclaimed
+                       navigation_routerating(this, it, ratingscale * 0.5, 5000);
+               else if(it.goalentity.team != this.team) // other team's point
+                       navigation_routerating(this, it, ratingscale * 0.2, 5000);
+       });
+}
+
 void havocbot_role_dom(entity this)
 {
        if(IS_DEAD(this))
@@ -482,6 +498,8 @@ spawnfunc(dom_controlpoint)
        this.effects = this.effects | EF_LOWPRECISION;
        if (autocvar_g_domination_point_fullbright)
                this.effects |= EF_FULLBRIGHT;
+
+       IL_PUSH(g_dompoints, this);
 }
 
 /*QUAKED spawnfunc_dom_team (0 .5 .8) (-32 -32 -24) (32 32 32)
index e9eb2c2d9da3e4ca46189662785cc13c62f08f2e..609fcfd0d9f01c91afbe25566948f75f96626219 100644 (file)
@@ -61,3 +61,6 @@ float domination_roundbased;
 float domination_teams;
 
 void AnimateDomPoint(entity this);
+
+IntrusiveList g_dompoints;
+STATIC_INIT(g_dompoints) { g_dompoints = IL_NEW(); }
index 602a55b6b5356023face33cdc71b65587c2046b6..cd7372699004bd93fe18e482e69d552e5b24f27d 100644 (file)
@@ -334,7 +334,7 @@ MUTATOR_HOOKFUNCTION(ft, PlayerDies)
 {
        entity frag_attacker = M_ARGV(1, entity);
        entity frag_target = M_ARGV(2, entity);
-       float frag_deathtype = M_ARGV(2, float);
+       float frag_deathtype = M_ARGV(3, float);
 
        if(round_handler_IsActive())
        if(round_handler_CountdownRunning())
index 1d9dc662017f7743f212588be4a96ba0c8a7f1c4..2a1b35956b0bce2b42d6b6156629acf93c751683 100644 (file)
@@ -1,10 +1,12 @@
 #include "gamemode_invasion.qh"
 
-#include <common/monsters/spawn.qh>
+#include <common/monsters/sv_spawn.qh>
 #include <common/monsters/sv_monsters.qh>
 
 #include <server/teamplay.qh>
 
+IntrusiveList g_invasion_spawns;
+STATIC_INIT(g_invasion_spawns) { g_invasion_spawns = IL_NEW(); }
 
 float autocvar_g_invasion_round_timelimit;
 float autocvar_g_invasion_spawnpoint_spawn_delay;
@@ -18,6 +20,7 @@ spawnfunc(invasion_spawnpoint)
        if(!g_invasion) { delete(this); return; }
 
        this.classname = "invasion_spawnpoint";
+       IL_PUSH(g_invasion_spawns, this);
 
        if(autocvar_g_invasion_zombies_only) // precache only if it hasn't been already
        if(this.monsterid) {
@@ -26,24 +29,19 @@ spawnfunc(invasion_spawnpoint)
        }
 }
 
-float invasion_PickMonster(float supermonster_count)
+int invasion_PickMonster(int supermonster_count)
 {
        if(autocvar_g_invasion_zombies_only)
                return MON_ZOMBIE.monsterid;
 
-       float i;
-       entity mon;
-
        RandomSelection_Init();
 
-       for(i = MON_FIRST; i <= MON_LAST; ++i)
+       FOREACH(Monsters, it != MON_Null,
        {
-               mon = get_monsterinfo(i);
-               if((mon.spawnflags & MONSTER_TYPE_FLY) || (mon.spawnflags & MONSTER_TYPE_SWIM) || ((mon.spawnflags & MON_FLAG_SUPERMONSTER) && supermonster_count >= 1))
-                       continue; // flying/swimming monsters not yet supported
-
-               RandomSelection_Add(NULL, i, string_null, 1, 1);
-       }
+               if((it.spawnflags & MONSTER_TYPE_FLY) || (it.spawnflags & MONSTER_TYPE_SWIM) || (it.spawnflags & MONSTER_SIZE_QUAKE) || ((it.spawnflags & MON_FLAG_SUPERMONSTER) && supermonster_count >= 1))
+                       continue;
+        RandomSelection_Add(NULL, it.monsterid, string_null, 1, 1);
+       });
 
        return RandomSelection_chosen_float;
 }
@@ -52,7 +50,7 @@ entity invasion_PickSpawn()
 {
        RandomSelection_Init();
 
-       FOREACH_ENTITY_CLASS("invasion_spawnpoint", true,
+       IL_EACH(g_invasion_spawns, true,
        {
                RandomSelection_Add(it, 0, string_null, 1, ((time >= it.spawnshieldtime) ? 0.2 : 1)); // give recently used spawnpoints a very low rating
                it.spawnshieldtime = time + autocvar_g_invasion_spawnpoint_spawn_delay;
@@ -120,14 +118,14 @@ void invasion_SpawnChosenMonster(float mon)
                monster.spawnflags |= MONSTERFLAG_MINIBOSS; // last round spawns minibosses
 }
 
-void invasion_SpawnMonsters(float supermonster_count)
+void invasion_SpawnMonsters(int supermonster_count)
 {
-       float chosen_monster = invasion_PickMonster(supermonster_count);
+       int chosen_monster = invasion_PickMonster(supermonster_count);
 
        invasion_SpawnChosenMonster(chosen_monster);
 }
 
-float Invasion_CheckWinner()
+bool Invasion_CheckWinner()
 {
        if(round_handler_GetEndTime() > 0 && round_handler_GetEndTime() - time <= 0)
        {
@@ -340,6 +338,8 @@ MUTATOR_HOOKFUNCTION(inv, PlayerSpawn)
 {
        entity player = M_ARGV(0, entity);
 
+       if(player.bot_attack)
+               IL_REMOVE(g_bot_targets, player);
        player.bot_attack = false;
 }
 
index a430ab5368b0fc92049d5b6e885ad7bee7d5402b..6fa76d6c5c1e140fb15382fffbd15118979f8b23 100644 (file)
@@ -451,6 +451,7 @@ void ka_SpawnBall() // loads various values for the ball, runs only once at star
        e.glow_color = autocvar_g_keepawayball_trail_color;
        e.glow_trail = true;
        e.flags = FL_ITEM;
+       IL_PUSH(g_items, e);
        e.pushable = true;
        e.reset = ka_Reset;
        settouch(e, ka_TouchEvent);
index 86d76e4312c87aff1aa80e8b3602fe020e84b18b..0e5d7bd02a6ca2f3e63ecce293067c6f59211da1 100644 (file)
@@ -244,6 +244,7 @@ void kh_Key_Attach(entity key)  // runs when a player picks up a key and several
        key.angles_y -= key.owner.angles.y;
 #endif
        key.flags = 0;
+       IL_REMOVE(g_items, key);
        key.solid = SOLID_NOT;
        set_movetype(key, MOVETYPE_NONE);
        key.team = key.owner.team;
@@ -283,6 +284,7 @@ void kh_Key_Detach(entity key) // runs every time a key is dropped or lost. Runs
        key.angles_y += key.owner.angles.y;
 #endif
        key.flags = FL_ITEM;
+       IL_PUSH(g_items, key);
        key.solid = SOLID_TRIGGER;
        set_movetype(key, MOVETYPE_TOSS);
        key.pain_finished = time + autocvar_g_balance_keyhunt_delay_return;
@@ -421,7 +423,7 @@ void kh_Key_Damage(entity this, entity inflictor, entity attacker, float damage,
                // immediately return is bad
                // maybe start a shorter countdown?
        }
-       if(vlen(force) <= 0)
+       if(force == '0 0 0')
                return;
        if(time > this.pushltime)
                if(IS_PLAYER(attacker))
@@ -525,8 +527,8 @@ void kh_WinnerTeam(float teem)  // runs when a team wins // Samual: Teem?.... TE
        float first;
        entity key;
        float score;
-       score = (kh_teams - 1) * autocvar_g_balance_keyhunt_score_capture;
-       DistributeEvenly_Init(score, kh_teams);
+       score = (NumTeams(kh_teams) - 1) * autocvar_g_balance_keyhunt_score_capture;
+       DistributeEvenly_Init(score, NumTeams(kh_teams));
        // twice the score for 3 team games, three times the score for 4 team games!
        // note: for a win by destroying the key, this should NOT be applied
        FOR_EACH_KH_KEY(key)
@@ -570,11 +572,11 @@ void kh_WinnerTeam(float teem)  // runs when a team wins // Samual: Teem?.... TE
                        firstorigin = thisorigin;
                first = false;
        }
-       if(kh_teams > 2)
+       if(NumTeams(kh_teams) > 2)
        {
                te_lightning2(NULL, lastorigin, firstorigin);
        }
-       midpoint = midpoint * (1 / kh_teams);
+       midpoint = midpoint * (1 / NumTeams(kh_teams));
        te_customflash(midpoint, 1000, 1, Team_ColorRGB(teem) * 0.5 + '0.5 0.5 0.5');  // make the color >=0.5 in each component
 
        play2all(SND(KH_CAPTURE));
@@ -635,8 +637,8 @@ void kh_LoserTeam(float teem, entity lostkey)  // runs when a player pushes a fl
                fragsleft = DistributeEvenly_Get(players);
 
                // Now distribute these among all other teams...
-               j = kh_teams - 1;
-               for(i = 0; i < kh_teams; ++i)
+               j = NumTeams(kh_teams) - 1;
+               for(i = 0; i < NumTeams(kh_teams); ++i)
                {
                        thisteam = kh_Team_ByID(i);
                        if(thisteam == teem) // bad boy, no cookie - this WILL happen
@@ -787,7 +789,7 @@ float kh_Key_AllOwnedByWhichTeam()  // constantly called. check to see if all th
        float keys;
 
        teem = -1;
-       keys = kh_teams;
+       keys = NumTeams(kh_teams);
        FOR_EACH_KH_KEY(key)
        {
                if(!key.owner)
@@ -855,7 +857,7 @@ void kh_Key_DropAll(entity player, float suicide) // runs whenever a player dies
 
 float kh_CheckPlayers(float num)
 {
-       if(num < kh_teams)
+       if(num < NumTeams(kh_teams))
        {
                float t_team = kh_Team_ByID(num);
                float players = 0;
@@ -869,8 +871,8 @@ float kh_CheckPlayers(float num)
        return 0;
 }
 
-#define KH_READY_TEAMS() (!p1 + !p2 + ((kh_teams >= 3) ? !p3 : p3) + ((kh_teams >= 4) ? !p4 : p4))
-#define KH_READY_TEAMS_OK() (KH_READY_TEAMS() == kh_teams)
+#define KH_READY_TEAMS() (!p1 + !p2 + ((NumTeams(kh_teams) >= 3) ? !p3 : p3) + ((NumTeams(kh_teams) >= 4) ? !p4 : p4))
+#define KH_READY_TEAMS_OK() (KH_READY_TEAMS() == NumTeams(kh_teams))
 void kh_WaitForPlayers()  // delay start of the round until enough players are present
 {
        if(time < game_starttime)
@@ -946,7 +948,7 @@ void kh_StartRound()  // runs at the start of each round
        Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_KEYHUNT);
        Kill_Notification(NOTIF_ALL, NULL, MSG_CENTER, CPID_KEYHUNT_OTHER);
 
-       for(i = 0; i < kh_teams; ++i)
+       for(i = 0; i < NumTeams(kh_teams); ++i)
        {
                teem = kh_Team_ByID(i);
                players = 0;
@@ -959,7 +961,7 @@ void kh_StartRound()  // runs at the start of each round
                                        my_player = it;
                        }
                ));
-               kh_Key_Spawn(my_player, 360 * i / kh_teams, i);
+               kh_Key_Spawn(my_player, 360 * i / NumTeams(kh_teams), i);
        }
 
        kh_tracking_enabled = false;
index 756d975b156ad197febcbe333455f85d9eaf246f..b791a69dce9830cc42b45743501dce63bbc80ff1 100644 (file)
@@ -14,23 +14,22 @@ void havocbot_role_race(entity this)
        if(IS_DEAD(this))
                return;
 
-       entity e;
        if (this.bot_strategytime < time)
        {
                this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
                navigation_goalrating_start(this);
 
-               for(e = NULL; (e = find(e, classname, "trigger_race_checkpoint")) != NULL; )
+               IL_EACH(g_racecheckpoints, true,
                {
-                       if(e.cnt == this.race_checkpoint)
+                       if(it.cnt == this.race_checkpoint)
                        {
-                               navigation_routerating(this, e, 1000000, 5000);
+                               navigation_routerating(this, it, 1000000, 5000);
                        }
                        else if(this.race_checkpoint == -1)
                        {
-                               navigation_routerating(this, e, 1000000, 5000);
+                               navigation_routerating(this, it, 1000000, 5000);
                        }
-               }
+               });
 
                navigation_goalrating_end(this);
        }
index f2ceecf9ee4596d1cc9125da2dc7513f69f13c25..e95ae98193281c9ea5a6b1226d22b7a52548b4db 100644 (file)
@@ -126,6 +126,8 @@ void CopyBody(entity this, float keepvelocity)
        animdecide_load_if_needed(clone);
        animdecide_setframes(clone, false, frame, frame1time, frame2, frame2time);
 
+       IL_PUSH(g_clones, clone);
+
        MUTATOR_CALLHOOK(CopyBody, this, clone, keepvelocity);
 }
 
index fc5ba4d61b6dc50866360fb4e3a6cadb05cfe35e..8fc38aa2c5e028ed1d44f8cd5f3b7128454ddda9 100644 (file)
@@ -832,15 +832,14 @@ void trigger_race_checkpoint_verify(entity this)
                                race_timed_checkpoint = 255;
                        }
                } else {
-                       for (entity cp = NULL; (cp = find(cp, classname, "trigger_race_checkpoint")); ) {
-                               if (cp.sprite) {
-                                       if (cp.race_checkpoint == 0) {
-                                               WaypointSprite_UpdateSprites(cp.sprite, WP_RaceStart, WP_Null, WP_Null);
-                    } else if (cp.race_checkpoint == race_timed_checkpoint) {
-                                               WaypointSprite_UpdateSprites(cp.sprite, WP_RaceFinish, WP_Null, WP_Null);
-                    }
+                       IL_EACH(g_racecheckpoints, it.sprite,
+                       {
+                               if (it.race_checkpoint == 0) {
+                                       WaypointSprite_UpdateSprites(it.sprite, WP_RaceStart, WP_Null, WP_Null);
+                } else if (it.race_checkpoint == race_timed_checkpoint) {
+                                       WaypointSprite_UpdateSprites(it.sprite, WP_RaceFinish, WP_Null, WP_Null);
                                }
-            }
+            });
                }
        }
 
@@ -946,6 +945,8 @@ spawnfunc(trigger_race_checkpoint)
        this.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
        this.spawn_evalfunc = trigger_race_checkpoint_spawn_evalfunc;
 
+       IL_PUSH(g_racecheckpoints, this);
+
        InitializeEntity(this, trigger_race_checkpoint_verify, INITPRIO_FINDTARGET);
 }
 
@@ -1142,7 +1143,7 @@ float race_GetFractionalLapCount(entity e)
 
        vector o0, o1;
        float bestfraction, fraction;
-       entity lastcp, cp0, cp1;
+       entity lastcp;
        float nextcpindex, lastcpindex;
 
        nextcpindex = max(e.race_checkpoint, 0);
@@ -1153,26 +1154,26 @@ float race_GetFractionalLapCount(entity e)
                return l; // finish
 
        bestfraction = 1;
-       for(cp0 = NULL; (cp0 = find(cp0, classname, "trigger_race_checkpoint")); )
+       IL_EACH(g_racecheckpoints, true,
        {
-               if(cp0.race_checkpoint != lastcpindex)
+               if(it.race_checkpoint != lastcpindex)
                        continue;
                if(lastcp)
-                       if(cp0 != lastcp)
+                       if(it != lastcp)
                                continue;
-               o0 = (cp0.absmin + cp0.absmax) * 0.5;
-               for(cp1 = NULL; (cp1 = find(cp1, classname, "trigger_race_checkpoint")); )
+               o0 = (it.absmin + it.absmax) * 0.5;
+               IL_EACH(g_racecheckpoints, true,
                {
-                       if(cp1.race_checkpoint != nextcpindex)
+                       if(it.race_checkpoint != nextcpindex)
                                continue;
-                       o1 = (cp1.absmin + cp1.absmax) * 0.5;
+                       o1 = (it.absmin + it.absmax) * 0.5;
                        if(o0 == o1)
                                continue;
                        fraction = bound(0.0001, vlen(e.origin - o1) / vlen(o0 - o1), 1);
                        if(fraction < bestfraction)
                                bestfraction = fraction;
-               }
-       }
+               });
+       });
 
        // we are at CP "nextcpindex - bestfraction"
        // race_timed_checkpoint == 4: then nextcp==4 means 0.9999x, nextcp==0 means 0.0000x
index 6360b0ae5aba535b3727c36110ac5a85e099cce1..6419afb737690604dace62c681cabe9da377f4e7 100644 (file)
@@ -29,6 +29,9 @@ float race_completing;
 .float race_respawn_checkpoint;
 .entity race_respawn_spotref; // try THIS spawn in case you respawn
 
+IntrusiveList g_racecheckpoints;
+STATIC_INIT(g_racecheckpoints) { g_racecheckpoints = IL_NEW(); }
+
 // definitions for functions used outside race.qc
 float race_PreviousCheckpoint(float f);
 float race_NextCheckpoint(float f);
index 567217933fb27f5e519326444d21eb14d7a8f864..59cc052af421942def992c27f5103fd3d08d00d8 100644 (file)
@@ -166,6 +166,7 @@ spawnfunc(info_player_start)
 spawnfunc(info_player_deathmatch)
 {
        this.classname = "info_player_deathmatch";
+       IL_PUSH(g_spawnpoints, this);
        relocate_spawnpoint(this);
 }
 
@@ -333,7 +334,7 @@ entity SelectSpawnPoint(entity this, bool anypoint)
        float teamcheck;
        entity spot, firstspot;
 
-       spot = find (NULL, classname, "testplayerstart");
+       spot = find(NULL, classname, "testplayerstart");
        if (spot)
                return spot;
 
index 5312eb8140b06d1002e3c6471ec98238d8112622..1544fa384a5cbbf16eb4cebf3bf89be17faf1c1f 100644 (file)
@@ -144,7 +144,7 @@ vector steerlib_wander(entity this, float range, float tresh, vector oldpoint)
     vector wander_point;
     wander_point = v_forward - oldpoint;
 
-    if (vlen(wander_point) > tresh)
+    if (vdist(wander_point, >, tresh))
         return oldpoint;
 
     range = bound(0,range,1);
index 1bb6974eb03ccf0460c46210dda635f8ec45a34f..ea11ea36a613f25ffb8c3f9915c8fa3dbf9c58f0 100644 (file)
@@ -159,8 +159,8 @@ void sys_phys_update(entity this, float dt);
 void StartFrame()
 {
     // TODO: if move is more than 50ms, split it into two moves (this matches QWSV behavior and the client prediction)
-    FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), sys_phys_update(it, frametime));
-    FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), PlayerPreThink(it));
+    IL_EACH(g_players, IS_FAKE_CLIENT(it), sys_phys_update(it, frametime));
+    IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPreThink(it));
 
        execute_next_frame();
        if (autocvar_sv_autopause && !server_is_dedicated) Pause_TryPause(true);
@@ -191,7 +191,7 @@ void StartFrame()
        }
 #endif
 
-       FOREACH_ENTITY_FLOAT(csqcprojectile_clientanimate, true, CSQCProjectile_Check(it));
+       IL_EACH(g_projectiles, it.csqcprojectile_clientanimate, CSQCProjectile_Check(it));
 
        if (RedirectionThink()) return;
 
@@ -229,7 +229,7 @@ void StartFrame()
        MUTATOR_CALLHOOK(SV_StartFrame);
 
     FOREACH_CLIENT(true, GlobalStats_update(it));
-    FOREACH_ENTITY_CLASS(STR_PLAYER, IS_FAKE_CLIENT(it), PlayerPostThink(it));
+    IL_EACH(g_players, IS_FAKE_CLIENT(it), PlayerPostThink(it));
 }
 
 .vector originjitter;
index 1e71d33445cb22026ab772cd914f3911a34f7c35..254130f88c443cd4105e65ed20210faa4bbbb849 100644 (file)
@@ -97,41 +97,41 @@ spawnfunc(target_init)
 // weapon give ent from defrag
 void target_give_init(entity this)
 {
-       entity targ;
-       for (targ = NULL; (targ = find(targ, targetname, this.target)); ) {
-               if (targ.classname == "weapon_rocketlauncher" || targ.classname == "weapon_devastator") {
-                       this.ammo_rockets += targ.count * WEP_CVAR(devastator, ammo);
+       IL_EACH(g_items, it.targetname == this.target,
+       {
+               if (it.classname == "weapon_rocketlauncher" || it.classname == "weapon_devastator") {
+                       this.ammo_rockets += it.count * WEP_CVAR(devastator, ammo);
                        this.netname = "devastator";
                }
-               else if (targ.classname == "weapon_plasmagun") {
-                       this.ammo_rockets += targ.count * WEP_CVAR_PRI(hagar, ammo); // WEAPONTODO
+               else if (it.classname == "weapon_plasmagun") {
+                       this.ammo_rockets += it.count * WEP_CVAR_PRI(hagar, ammo); // WEAPONTODO
                        if(this.netname == "")
                                this.netname = "hagar";
                        else
                                this.netname = strcat(this.netname, " hagar");
                }
-               else if (targ.classname == "weapon_bfg") {
-                       this.ammo_cells += targ.count * WEP_CVAR_PRI(crylink, ammo);
+               else if (it.classname == "weapon_bfg") {
+                       this.ammo_cells += it.count * WEP_CVAR_PRI(crylink, ammo);
                        if(this.netname == "")
                                this.netname = "crylink";
                        else
                                this.netname = strcat(this.netname, " crylink");
                }
-               else if (targ.classname == "weapon_grenadelauncher" || targ.classname == "weapon_mortar") {
-                       this.ammo_rockets += targ.count * WEP_CVAR_PRI(mortar, ammo); // WEAPONTODO
+               else if (it.classname == "weapon_grenadelauncher" || it.classname == "weapon_mortar") {
+                       this.ammo_rockets += it.count * WEP_CVAR_PRI(mortar, ammo); // WEAPONTODO
                        if(this.netname == "")
                                this.netname = "mortar";
                        else
                                this.netname = strcat(this.netname, " mortar");
                }
-               else if (targ.classname == "item_armor_body")
+               else if (it.classname == "item_armor_body")
                        this.armorvalue = 100;
-               else if (targ.classname == "item_health_mega")
+               else if (it.classname == "item_health_mega")
                        this.health = 200;
-               //remove(targ); // removing ents in init functions causes havoc, workaround:
-        setthink(targ, SUB_Remove);
-        targ.nextthink = time;
-       }
+               //remove(it); // removing ents in init functions causes havoc, workaround:
+        setthink(it, SUB_Remove);
+        it.nextthink = time;
+       });
        this.spawnflags = 2;
        spawnfunc_target_items(this);
        InitializeEntity(this, target_init_verify, INITPRIO_FINDTARGET);
index 8c6c0eaac6f4283f231ff11fc4438e22f523801f..56df6c3a2c47e615562c1bd190eba45241536c3f 100644 (file)
@@ -21,12 +21,10 @@ void Send_WeaponComplain(entity e, float wpn, float type)
 void Weapon_whereis(Weapon this, entity cl)
 {
        if (!autocvar_g_showweaponspawns) return;
-       FOREACH_ENTITY_FLOAT(weapon, this.m_id,
+       IL_EACH(g_items, it.weapon == this.m_id,
        {
                if (it.classname == "droppedweapon" && autocvar_g_showweaponspawns < 2)
                        continue;
-               if (!(it.flags & FL_ITEM))
-                       continue;
                entity wp = WaypointSprite_Spawn(
                        WP_Weapon,
                        -2, 0,
index bb204a4b54b7742c77cf503b5f9349f4607fb76d..00bc0e5d12397c2e608cae53f245a1593d2d3e3c 100644 (file)
@@ -29,7 +29,7 @@ void weapon_defaultspawnfunc(entity this, Weapon e)
        {
                if (e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
                {
-                       LOG_MAPWARNF("Attempted to spawn a mutator-blocked weapon rejected: prvm_edict server %i", this);
+                       LOG_WARNF("Attempted to spawn a mutator-blocked weapon rejected: prvm_edict server %i", this);
                        startitem_failed = true;
                        return;
                }
index 13f32ee14d2a76e9cae1ec69dea3d01b3fa4c1e9..2a6cd03a4daec752658f6f92d6107b4ea3bdd3ab 100644 (file)
@@ -8,7 +8,7 @@
 #include <common/t_items.qh>
 #include <common/animdecide.qh>
 #include <common/constants.qh>
-#include <common/monsters/all.qh>
+#include <common/monsters/_mod.qh>
 #include <common/notifications/all.qh>
 #include <common/util.qh>
 #include <common/weapons/_all.qh>