waeponarena {all,most}_available
authorMartin Taibr <taibr.martin@gmail.com>
Sun, 25 Aug 2019 18:08:58 +0000 (20:08 +0200)
committerMartin Taibr <taibr.martin@gmail.com>
Sun, 25 Aug 2019 18:08:58 +0000 (20:08 +0200)
15 files changed:
gamemodes-server.cfg
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qh
qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qc
qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qh
qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc
qcsrc/common/gamemodes/gamemode/lms/sv_lms.qh
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/stats.qh
qcsrc/common/t_items.qc
qcsrc/server/defs.qh
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/weapons/spawning.qc
xonotic-server.cfg

index 57c9f7b..b5e46ac 100644 (file)
@@ -226,6 +226,7 @@ set g_ca_round_timelimit 180 "round time limit in seconds"
 seta g_ca_teams_override 0
 set g_ca_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any"
 set g_ca_teams 0
+set g_ca_weaponarena "most" "starting weapons - takes the same options as g_weaponarena"
 
 
 // ==================
@@ -370,6 +371,7 @@ set g_freezetag_frozen_maxtime 60 "frozen players will be automatically unfrozen
 seta g_freezetag_teams_override 0
 set g_freezetag_team_spawns 0 "when 1, players spawn from the team spawnpoints of the map, if any"
 set g_freezetag_teams 0
+set g_freezetag_weaponarena "most_available" "starting weapons - takes the same options as g_weaponarena"
 
 
 // ==========
@@ -433,6 +435,7 @@ set g_lms_extra_lives 0
 set g_lms_regenerate 0
 set g_lms_last_join 3  "if g_lms_join_anytime is false, new players can only join if the worst active player has more than (fraglimit - g_lms_last_join) lives"
 set g_lms_join_anytime 1       "if true, new players can join, but get same amount of lives as the worst player"
+set g_lms_weaponarena "most_available" "starting weapons - takes the same options as g_weaponarena"
 
 
 // =========
index 4105f7c..696e4ee 100644 (file)
@@ -483,11 +483,6 @@ MUTATOR_HOOKFUNCTION(ca, ClientCommand_Spectate)
        return MUT_SPECCMD_CONTINUE;
 }
 
-MUTATOR_HOOKFUNCTION(ca, WantWeapon)
-{
-       M_ARGV(2, bool) = true; // all weapons
-}
-
 MUTATOR_HOOKFUNCTION(ca, HideTeamNagger)
 {
        return true; // doesn't work well with the whole spectator as player thing
@@ -502,6 +497,8 @@ MUTATOR_HOOKFUNCTION(ca, GetPlayerStatus)
 
 MUTATOR_HOOKFUNCTION(ca, SetWeaponArena)
 {
+       LOG_INFOF("CA SetWeaponArena %s", autocvar_g_ca_weaponarena);
        // most weapons arena
-       if (M_ARGV(0, string) == "0" || M_ARGV(0, string) == "") M_ARGV(0, string) = "most";
+       if (M_ARGV(0, string) == "0" || M_ARGV(0, string) == "")
+               M_ARGV(0, string) = autocvar_g_ca_weaponarena;
 }
index c4755fe..27953bd 100644 (file)
@@ -11,6 +11,7 @@ bool autocvar_g_ca_team_spawns;
 //int autocvar_g_ca_teams;
 int autocvar_g_ca_teams_override;
 float autocvar_g_ca_warmup;
+string autocvar_g_ca_weaponarena;
 
 
 int ca_teams;
index c42c744..550cc1b 100644 (file)
@@ -587,7 +587,7 @@ MUTATOR_HOOKFUNCTION(ft, SetWeaponArena)
 {
        // most weapons arena
        if(M_ARGV(0, string) == "0" || M_ARGV(0, string) == "")
-               M_ARGV(0, string) = "most";
+               M_ARGV(0, string) = autocvar_g_freezetag_weaponarena;
 }
 
 MUTATOR_HOOKFUNCTION(ft, FragCenterMessage)
index d637ae4..7cb66bc 100644 (file)
@@ -1,9 +1,12 @@
 #pragma once
 
 #include <common/mutators/base.qh>
+
 int autocvar_g_freezetag_point_limit;
 int autocvar_g_freezetag_point_leadlimit;
 bool autocvar_g_freezetag_team_spawns;
+string autocvar_g_freezetag_weaponarena;
+
 void freezetag_Initialize();
 
 REGISTER_MUTATOR(ft, false)
index 6d420c7..52562fb 100644 (file)
@@ -429,9 +429,12 @@ MUTATOR_HOOKFUNCTION(lms, CheckRules_World)
        return true;
 }
 
-MUTATOR_HOOKFUNCTION(lms, WantWeapon)
+MUTATOR_HOOKFUNCTION(lms, SetWeaponArena)
 {
-       M_ARGV(2, bool) = true; // all weapons
+       LOG_INFOF("LMS SetWeaponArena %s", autocvar_g_ca_weaponarena);
+       // most weapons arena
+       if(M_ARGV(0, string) == "0" || M_ARGV(0, string) == "")
+               M_ARGV(0, string) = autocvar_g_lms_weaponarena;
 }
 
 MUTATOR_HOOKFUNCTION(lms, GetPlayerStatus)
index 256620a..ba43ecf 100644 (file)
@@ -2,8 +2,12 @@
 
 #include <common/mutators/base.qh>
 #include <common/scores.qh>
+
 .float lms_spectate_warning;
+
 #define autocvar_g_lms_lives_override cvar("g_lms_lives_override")
+string autocvar_g_lms_weaponarena;
+
 void lms_Initialize();
 
 REGISTER_MUTATOR(lms, false)
index 41ba2da..c4a3ef9 100644 (file)
@@ -269,6 +269,7 @@ MUTATOR_HOOKFUNCTION(ok, FilterItem)
 
 MUTATOR_HOOKFUNCTION(ok, SetStartItems, CBC_ORDER_LAST)
 {
+       LOG_INFOF("OK SetStartItems\n");
        WepSet ok_start_items = (WEPSET(OVERKILL_MACHINEGUN) | WEPSET(OVERKILL_NEX) | WEPSET(OVERKILL_SHOTGUN));
 
        if(WEP_OVERKILL_RPC.weaponstart > 0) { ok_start_items |= WEPSET(OVERKILL_RPC); }
@@ -280,6 +281,7 @@ MUTATOR_HOOKFUNCTION(ok, SetStartItems, CBC_ORDER_LAST)
 
 MUTATOR_HOOKFUNCTION(ok, SetWeaponArena)
 {
+       LOG_INFOF("OK SetWeaponArena\n");
        // turn weapon arena off
        M_ARGV(0, string) = "off";
 }
index cf51ea6..697403c 100644 (file)
@@ -43,8 +43,12 @@ const int MAX_CL_STATS = 256;
 #endif
 
 #ifdef SVQC
+/// all the weapons actually spawned in the map, does not include filtered items
 vector weaponsInMap;
+/// all the weapons placed by the mapper (weaponreplace applied), ignores most filters
+vector weaponsInMapAll;
 #endif
+
 REGISTER_STAT(WEAPONS, vectori)
 REGISTER_STAT(WEAPONSINMAP, vectori, weaponsInMap)
 
index 429a013..9695c78 100644 (file)
@@ -1307,6 +1307,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
                        this.is_item = true;
                }
 
+               LOG_INFOF("adding weapid 2: %d\n", weaponid);
                weaponsInMap |= WepSet_FromWeapon(Weapons_from(weaponid));
 
                if (   def.instanceOfPowerup
index 6e1020c..b45e209 100644 (file)
@@ -190,10 +190,6 @@ string W_Apply_Weaponreplace(string in);
 void FixIntermissionClient(entity e);
 void FixClientCvars(entity e);
 
-// WEAPONTODO: remove this
-//WepSet weaponsInMap; // lists all the weapons actually spawned in the map, does not include filtered items
-vector weaponsInMapAll; // holds a list of all the weapons that have been placed by the mapper (weaponreplace applied), ignores most filters
-
 .float respawn_countdown; // next number to count
 
 float bot_waypoints_for_items;
index 8680b83..c8405e0 100644 (file)
@@ -474,6 +474,12 @@ void cvar_changes_init()
                BADCVAR("g_grappling_hook");
                BADCVAR("g_jetpack");
 
+               // temporary for testing
+               // TODO remove before 0.8.3 release
+               BADCVAR("g_ca_weaponarena");
+               BADCVAR("g_freezetag_weaponarena");
+               BADCVAR("g_lms_weaponarena");
+
 #undef BADPRESUFFIX
 #undef BADPREFIX
 #undef BADCVAR
index 633ee47..7e9cf5e 100644 (file)
@@ -508,7 +508,7 @@ float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still ne
 
        float t = weaponinfo.weaponstartoverride;
 
-       //print(strcat("want_weapon: ", weaponinfo.netname, " - d: ", ftos(d), ", t: ", ftos(t), ". \n"));
+       //LOG_INFOF("want_weapon: %s - d: %d t: %d\n", weaponinfo.netname, d, t);
 
        // bit order in t:
        // 1: want or not
@@ -522,23 +522,97 @@ float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still ne
        return t;
 }
 
-void weaponarena_available_update(entity this)
+/// Weapons the player normally starts with outside weapon arena.
+WepSet weapons_start()
 {
+       WepSet ret = '0 0 0';
        FOREACH(Weapons, it != WEP_Null, {
-               // if no weapons are available, just fall back to normal weapons (most weapons arena)
-               bool wep_available = ((weaponsInMapAll) ? !!(weaponsInMapAll & WepSet_FromWeapon(it)) : (it.spawnflags & WEP_FLAG_NORMAL));
-               if(wep_available && !(it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && !(it.spawnflags & WEP_FLAG_HIDDEN))
-                       g_weaponarena_weapons |= WepSet_FromWeapon(it);
+               int w = want_weapon(it, false); // TODO too complicated? see my MR, test CTS/courtfun - ballstealer
+               if(w & 1)
+                       ret |= it.m_wepset;
        });
-       start_weapons |= g_weaponarena_weapons;
-       if(warmup_stage)
-               warmup_start_weapons |= g_weaponarena_weapons;
+       return ret;
+}
+
+WepSet weapons_all()
+{
+       WepSet ret = '0 0 0';
+       FOREACH(Weapons, it != WEP_Null, {
+               if(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED))
+                       ret |= it.m_wepset;
+       });
+       return ret;
+}
+
+WepSet weapons_devall()
+{
+       WepSet ret = '0 0 0';
+       FOREACH(Weapons, it != WEP_Null,
+       {
+               ret |= it.m_wepset;
+       });
+       return ret;
+}
+
+WepSet weapons_most()
+{
+       WepSet ret = '0 0 0';
+       FOREACH(Weapons, it != WEP_Null, {
+               if(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && (it.spawnflags & WEP_FLAG_NORMAL) && !(it.spawnflags & WEP_FLAG_HIDDEN))
+                       ret |= it.m_wepset;
+       });
+       return ret;
+}
+
+void weaponarena_available_all_update(entity this)
+{
+       LOG_INFOF("weaponarena_available_all_update %v\n", weaponsInMapAll);
+
+       if (weaponsInMapAll)
+       {
+               start_weapons = warmup_start_weapons = g_weaponarena_weapons = weapons_start() | (weaponsInMapAll & weapons_all());
+       }
+       else
+       {
+               // if no weapons are available on the map, just fall back to all weapons arena
+               start_weapons = warmup_start_weapons = g_weaponarena_weapons = weapons_all();
+       }
+}
+
+void weaponarena_available_devall_update(entity this)
+{
+       LOG_INFOF("weaponarena_available_devall_update %v\n", weaponsInMapAll);
+
+       if (weaponsInMapAll)
+       {
+               start_weapons = warmup_start_weapons = g_weaponarena_weapons = weapons_start() | weaponsInMapAll;
+       }
+       else
+       {
+               // if no weapons are available on the map, just fall back to devall weapons arena
+               start_weapons = warmup_start_weapons = g_weaponarena_weapons = weapons_devall();
+       }
+}
+
+void weaponarena_available_most_update(entity this) // TODO cleanup
+{
+       LOG_INFOF("weaponarena_available_most_update %v\n", weaponsInMapAll);
+
+       if (weaponsInMapAll)
+       {
+               start_weapons = warmup_start_weapons = g_weaponarena_weapons = weapons_start() | (weaponsInMapAll & weapons_most());
+       }
+       else
+       {
+               // if no weapons are available on the map, just fall back to most weapons arena
+               start_weapons = warmup_start_weapons = g_weaponarena_weapons = weapons_most();
+       }
 }
 
 void readplayerstartcvars()
 {
+       LOG_INFOF("readplayerstartcvars\n");
        float i, t;
-       string s;
 
        // initialize starting values for players
        start_weapons = '0 0 0';
@@ -560,16 +634,17 @@ void readplayerstartcvars()
        g_weaponarena = 0;
        g_weaponarena_weapons = '0 0 0';
 
-       s = cvar_string("g_weaponarena");
+       string s = cvar_string("g_weaponarena");
 
        MUTATOR_CALLHOOK(SetWeaponArena, s);
        s = M_ARGV(0, string);
+       LOG_INFOF("arena: %s", s);
 
        if (s == "0" || s == "")
        {
                // no arena
        }
-       else if (s == "off")
+       else if (s == "off") // TODO remove? CA and others don't respect this
        {
                // forcibly turn off weaponarena
        }
@@ -577,40 +652,43 @@ void readplayerstartcvars()
        {
                g_weaponarena = 1;
                g_weaponarena_list = "All Weapons";
-               FOREACH(Weapons, it != WEP_Null, {
-                       if(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED))
-                               g_weaponarena_weapons |= (it.m_wepset);
-               });
+               g_weaponarena_weapons = weapons_all();
        }
        else if (s == "devall")
        {
                g_weaponarena = 1;
-               g_weaponarena_list = "All Weapons"; // TODO: report as more than just all weapons?
-               FOREACH(Weapons, it != WEP_Null,
-               {
-                       g_weaponarena_weapons |= (it.m_wepset);
-               });
+               g_weaponarena_list = "Dev All Weapons";
+               g_weaponarena_weapons = weapons_devall();
        }
        else if (s == "most")
        {
                g_weaponarena = 1;
                g_weaponarena_list = "Most Weapons";
-               FOREACH(Weapons, it != WEP_Null, {
-                       if(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED) && (it.spawnflags & WEP_FLAG_NORMAL) && !(it.spawnflags & WEP_FLAG_HIDDEN))
-                               g_weaponarena_weapons |= (it.m_wepset);
-               });
+               g_weaponarena_weapons = weapons_most();
        }
-       else if (s == "available")
+       else if (s == "all_available")
        {
-               g_weaponarena = 2;
-               g_weaponarena_list = "Most Weapons";
-               // include weapons the player would start with
-               FOREACH(Weapons, it != WEP_Null, {
-                       int w = want_weapon(it, false);
-                       if(w & 1)
-                               g_weaponarena_weapons |= (it.m_wepset);
-               });
-               InitializeEntity(NULL, weaponarena_available_update, INITPRIO_FINDTARGET);
+               g_weaponarena = 1;
+               g_weaponarena_list = "All Available Weapons";
+
+               // this needs to run after weaponsInMapAll is initialized
+               InitializeEntity(NULL, weaponarena_available_all_update, INITPRIO_FINDTARGET);
+       }
+       else if (s == "devall_available")
+       {
+               g_weaponarena = 1;
+               g_weaponarena_list = "Dev All Available Weapons";
+
+               // this needs to run after weaponsInMapAll is initialized
+               InitializeEntity(NULL, weaponarena_available_devall_update, INITPRIO_FINDTARGET);
+       }
+       else if (s == "most_available")
+       {
+               g_weaponarena = 1;
+               g_weaponarena_list = "Most Available Weapons";
+
+               // this needs to run after weaponsInMapAll is initialized
+               InitializeEntity(NULL, weaponarena_available_most_update, INITPRIO_FINDTARGET);
        }
        else if (s == "none")
        {
@@ -691,7 +769,7 @@ void readplayerstartcvars()
                        "g_random_start_plasma"));
        }
 
-       if (warmup_stage)
+       if (warmup_stage && !g_ca && !g_freezetag) // TODO remove?
        {
                warmup_start_ammo_shells = start_ammo_shells;
                warmup_start_ammo_nails = start_ammo_nails;
@@ -705,7 +783,7 @@ void readplayerstartcvars()
                warmup_start_weapons_default = start_weapons_default;
                warmup_start_weapons_defaultmask = start_weapons_defaultmask;
 
-               if (!g_weaponarena && !g_ca && !g_freezetag)
+               if (!g_weaponarena)
                {
                        warmup_start_ammo_shells = cvar("g_warmup_start_ammo_shells");
                        warmup_start_ammo_nails = cvar("g_warmup_start_ammo_nails");
@@ -773,9 +851,9 @@ void precache_playermodel(string m)
        float globhandle, i, n;
        string f;
 
-       if(substring(m, -9,5) == "_lod1")
+       if(substring(m, -9, 5) == "_lod1")
                return;
-       if(substring(m, -9,5) == "_lod2")
+       if(substring(m, -9, 5) == "_lod2")
                return;
        precache_model(m);
        f = strcat(substring(m, 0, -5), "_lod1", substring(m, -4, -1));
index d5c79d0..0922b50 100644 (file)
@@ -28,7 +28,7 @@ string W_Apply_Weaponreplace(string in)
 
 void weapon_defaultspawnfunc(entity this, Weapon e)
 {
-       Weapon wpn = e;
+       Weapon wpn = e; // TODO unify wpn and e
        e = wpn = wpn.m_spawnfunc_hookreplace(wpn, this);
        this.classname = wpn.m_canonical_spawnfunc;
        if (!Item_IsLoot(this) && !this.m_isreplaced)
index 993d77e..158b32e 100644 (file)
@@ -195,7 +195,7 @@ set g_pickup_items -1 "if set to 0 all items (health, armor, ammo, weapons...) a
 set g_pickup_respawntime_scaling_reciprocal 0 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `reciprocal` (with `offset` and `linear` set to 0) can be used to achieve a constant number of items spawned *per player*"
 set g_pickup_respawntime_scaling_offset 0 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `offset` offsets the curve left or right - the results are not intuitive and I recommend plotting the respawn time and the number of items per player to see what's happening"
 set g_pickup_respawntime_scaling_linear 1 "Multiply respawn time by `reciprocal / (p + offset) + linear` where `p` is the current number of players, takes effect with 2 or more players present, `linear` can be used to simply scale the respawn time linearly"
-set g_weaponarena "0"  "put in a list of weapons to enable a weapon arena mode, or try \"all\" or \"most\" or \"available\""
+set g_weaponarena "0"  "put in a list of weapons to enable a weapon arena mode, or try \"all\", \"most\", \"all_available\" or \"most_available\" (available only gives the weapon if the map normally has it as a pickup item)"
 set g_weaponarena_random "0"   "if set to a number, only that weapon count is given on every spawn (randomly)"
 set g_weaponarena_random_with_blaster "1"      "additionally, always provide the blaster in random weapon arena games"
 set g_spawnpoints_auto_move_out_of_solid 0 "if set to 1 you will see a warning if a spawn point was placed inside a solid"