]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into martin-t/AMMO
authorMartin Taibr <taibr.martin@gmail.com>
Sun, 1 Sep 2019 14:03:14 +0000 (16:03 +0200)
committerMartin Taibr <taibr.martin@gmail.com>
Sun, 1 Sep 2019 14:03:14 +0000 (16:03 +0200)
1  2 
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc
qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qc
qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc
qcsrc/common/t_items.qc
qcsrc/server/miscfunctions.qc
xonotic-server.cfg

index 8f769a4595fb650a535ab31e8af770d172e7e161,4721cb38015ea7cb4ea306accd3f3389eaa14d14..c966e16d8059954fdd80058ed17d72e2edcac1d1
@@@ -333,7 -333,7 +333,7 @@@ MUTATOR_HOOKFUNCTION(ca, GiveFragsForKi
  
  MUTATOR_HOOKFUNCTION(ca, SetStartItems)
  {
 -      start_items       &= ~IT_UNLIMITED_AMMO;
 +      start_items       &= ~IT_UNLIMITED_BOTH;
        start_health       = warmup_start_health       = cvar("g_lms_start_health");
        start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
        start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
@@@ -483,11 -483,6 +483,6 @@@ MUTATOR_HOOKFUNCTION(ca, ClientCommand_
        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,12 -497,14 +497,14 @@@ MUTATOR_HOOKFUNCTION(ca, GetPlayerStatu
  
  MUTATOR_HOOKFUNCTION(ca, SetWeaponArena)
  {
-       // 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;
  }
  
  MUTATOR_HOOKFUNCTION(ca, SV_ParseServerCommand)
  {
-       shuffleteams_on_reset_map = !allowed_to_spawn;
+       string cmd_name = M_ARGV(0, string);
+       if (cmd_name == "shuffleteams")
+               shuffleteams_on_reset_map = !allowed_to_spawn;
        return false;
  }
index 1158719fc2ac3027ec994d8e114d54bc9c7223a4,b1feaa9917c2cb913ce91f9465f795d6f40305ab..ed0209a7a7bf6a284dbedcdafe14093614ea055b
@@@ -549,7 -549,7 +549,7 @@@ MUTATOR_HOOKFUNCTION(ft, PlayerPreThink
  
  MUTATOR_HOOKFUNCTION(ft, SetStartItems)
  {
 -      start_items &= ~IT_UNLIMITED_AMMO;
 +      start_items &= ~IT_UNLIMITED_BOTH;
        //start_health       = warmup_start_health       = cvar("g_lms_start_health");
        //start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
        start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
@@@ -587,9 -587,8 +587,8 @@@ MUTATOR_HOOKFUNCTION(ft, TeamBalance_Ch
  
  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)
  
  MUTATOR_HOOKFUNCTION(ft, SV_ParseServerCommand)
  {
-       shuffleteams_on_reset_map = !(round_handler_IsActive() && !round_handler_IsRoundStarted());
+       string cmd_name = M_ARGV(0, string);
+       if (cmd_name == "shuffleteams")
+               shuffleteams_on_reset_map = !(round_handler_IsActive() && !round_handler_IsRoundStarted());
        return false;
  }
  
index fa76eaf2f6e269e6d8b5fe05557f5231efd42081,bd6401d172931ea66eb07776258bc26258e8c1ca..6df1cb130943fe927f84f44a9670ce534015c316
@@@ -323,7 -323,7 +323,7 @@@ MUTATOR_HOOKFUNCTION(lms, GiveFragsForK
  
  MUTATOR_HOOKFUNCTION(lms, SetStartItems)
  {
 -      start_items &= ~IT_UNLIMITED_AMMO;
 +      start_items &= ~IT_UNLIMITED_BOTH;
        start_health       = warmup_start_health       = cvar("g_lms_start_health");
        start_armorvalue   = warmup_start_armorvalue   = cvar("g_lms_start_armor");
        start_ammo_shells  = warmup_start_ammo_shells  = cvar("g_lms_start_ammo_shells");
@@@ -429,9 -429,10 +429,10 @@@ MUTATOR_HOOKFUNCTION(lms, CheckRules_Wo
        return true;
  }
  
- MUTATOR_HOOKFUNCTION(lms, WantWeapon)
+ MUTATOR_HOOKFUNCTION(lms, SetWeaponArena)
  {
-       M_ARGV(2, bool) = true; // all weapons
+       if(M_ARGV(0, string) == "0" || M_ARGV(0, string) == "")
+               M_ARGV(0, string) = autocvar_g_lms_weaponarena;
  }
  
  MUTATOR_HOOKFUNCTION(lms, GetPlayerStatus)
diff --combined qcsrc/common/t_items.qc
index cd3162e5c9809be6517cbc179b1c7b2a0d00d113,a5786888c18169abdfb93a44200b9383feab5a8d..663f14be89fd68a01422aa7416a6d7651eded7d8
@@@ -356,8 -356,8 +356,8 @@@ bool ItemSend(entity this, entity to, i
        {
                WriteShort(MSG_ENTITY, this.colormap);
                WriteByte(MSG_ENTITY, this.glowmod.x * 255.0);
-         WriteByte(MSG_ENTITY, this.glowmod.y * 255.0);
-         WriteByte(MSG_ENTITY, this.glowmod.z * 255.0);
+               WriteByte(MSG_ENTITY, this.glowmod.y * 255.0);
+               WriteByte(MSG_ENTITY, this.glowmod.z * 255.0);
        }
  
        if(sf & ISF_DROP)
@@@ -402,7 -402,7 +402,7 @@@ bool have_pickup_item(entity this
        return true;
  }
  
- void Item_Show (entity e, int mode)
+ void Item_Show(entity e, int mode)
  {
        e.effects &= ~(EF_ADDITIVE | EF_STARDUST | EF_FULLBRIGHT | EF_NODEPTHTEST);
        e.ItemStatus &= ~ITS_STAYWEP;
@@@ -479,13 -479,13 +479,13 @@@ float Item_ItemsTime_UpdateTime(entity 
  void Item_ItemsTime_SetTime(entity e, float t);
  void Item_ItemsTime_SetTimesForAllPlayers();
  
- void Item_Respawn (entity this)
+ void Item_Respawn(entity this)
  {
        Item_Show(this, 1);
        sound(this, CH_TRIGGER, this.itemdef.m_respawnsound, VOL_BASE, ATTEN_NORM);     // play respawn sound
        setorigin(this, this.origin);
  
-     if (Item_ItemsTime_Allow(this.itemdef) || (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS))
+       if (Item_ItemsTime_Allow(this.itemdef) || (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS))
        {
                float t = Item_ItemsTime_UpdateTime(this, 0);
                Item_ItemsTime_SetTime(this, t);
        Send_Effect(EFFECT_ITEM_RESPAWN, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
  }
  
- void Item_RespawnCountdown (entity this)
+ void Item_RespawnCountdown(entity this)
  {
        if(this.item_respawncounter >= ITEM_RESPAWN_TICKS)
        {
@@@ -624,7 -624,7 +624,7 @@@ float adjust_respawntime(float normal_r
                }
        }
        TeamBalance_Destroy(balance);
-       
        if (players >= 2) {
                return normal_respawntime * (r / (players + o) + l);
        } else {
@@@ -1008,8 -1008,8 +1008,8 @@@ void Item_FindTeam(entity this
                });
  
                e = RandomSelection_chosen_ent;
-               e.state = 0;
-               Item_Show(e, 1);
+               if (!e)
+                       return;
  
                IL_EACH(g_items, it.team == this.team,
                {
                                        Item_Show(it, -1);
                                        it.state = 1; // state 1 = initially hidden item, apparently
                                }
+                               else
+                                       Item_Reset(it);
                                it.effects &= ~EF_NODRAW;
                        }
                });
-               Item_Reset(this);
        }
  }
  
@@@ -1172,7 -1172,7 +1172,7 @@@ void _StartItem(entity this, entity def
  {
        string itemname = def.m_name;
        Model itemmodel = def.m_model;
-     Sound pickupsound = def.m_sound;
+       Sound pickupsound = def.m_sound;
        float(entity player, entity item) pickupevalfunc = def.m_pickupevalfunc;
        float pickupbasevalue = def.m_botvalue;
        int itemflags = def.m_itemflags;
        startitem_failed = false;
  
        this.item_model_ent = itemmodel;
-     this.item_pickupsound_ent = pickupsound;
+       this.item_pickupsound_ent = pickupsound;
  
-     if(def.m_iteminit)
-       def.m_iteminit(def, this);
+       if(def.m_iteminit)
+               def.m_iteminit(def, this);
  
        if(!this.respawntime) // both need to be set
        {
                        || (def.instanceOfHealth && def != ITEM_HealthSmall)
                        || (def.instanceOfArmor && def != ITEM_ArmorSmall)
                        || (itemid & (IT_KEY1 | IT_KEY2))
-               ) 
+               )
                {
                        if(!this.target || this.target == "")
                                this.target = "###item###"; // for finding the nearest item using findnearest
        }
  
        this.state = 0;
-       if(this.team) // broken, no idea why.
+       if(this.team)
        {
                if(!this.cnt)
                        this.cnt = 1; // item probability weight
@@@ -1497,7 -1497,7 +1497,7 @@@ spawnfunc(target_items
        {
                for(int j = 0; j < n; ++j)
                {
 -                      if     (argv(j) == "unlimited_ammo")         this.items |= IT_UNLIMITED_AMMO;
 +                      if     (argv(j) == "unlimited_ammo")         this.items |= IT_UNLIMITED_BOTH;
                        else if(argv(j) == "unlimited_weapon_ammo")  this.items |= IT_UNLIMITED_WEAPON_AMMO;
                        else if(argv(j) == "unlimited_superweapons") this.items |= IT_UNLIMITED_SUPERWEAPONS;
                        else if(argv(j) == "strength")               this.items |= ITEM_Strength.m_itemid;
        for(int j = 0; j < n; ++j)
        {
                FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(argv(j)) == it.netname, {
-             it.wr_init(it);
-             break;
+                       it.wr_init(it);
+                       break;
                });
        }
  }
@@@ -1763,7 -1763,7 +1763,7 @@@ float GiveItems(entity e, float beginar
                                got += GiveValue(e, strength_finished, op, val);
                                got += GiveValue(e, invincible_finished, op, val);
                                got += GiveValue(e, superweapons_finished, op, val);
 -                              got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
 +                              got += GiveBit(e, items, IT_UNLIMITED_BOTH, op, val);
                        case "all":
                                got += GiveBit(e, items, ITEM_Jetpack.m_itemid, op, val);
                                got += GiveResourceValue(e, RES_HEALTH, op, val);
                                got += GiveResourceValue(e, RES_FUEL, op, val);
                                break;
                        case "unlimited_ammo":
 -                              got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
 +                              got += GiveBit(e, items, IT_UNLIMITED_BOTH, op, val);
                                break;
                        case "unlimited_weapon_ammo":
                                got += GiveBit(e, items, IT_UNLIMITED_WEAPON_AMMO, op, val);
index 47dd2aa5069a7912a13f4cbace34306729d009ee,4cc848b67342e53181701fe6b06f1463d9319db3..c82f076d39531003262d0671667806ccc29ef88c
@@@ -390,6 -390,8 +390,8 @@@ REPLICATE(autoswitch, bool, "cl_autoswi
  
  REPLICATE(cvar_cl_allow_uid2name, bool, "cl_allow_uid2name");
  
+ REPLICATE(cvar_cl_allow_uidranking, bool, "cl_allow_uidranking");
  REPLICATE(cvar_cl_autoscreenshot, int, "cl_autoscreenshot");
  
  REPLICATE(cvar_cl_autotaunt, float, "cl_autotaunt");
@@@ -398,6 -400,8 +400,8 @@@ REPLICATE(cvar_cl_clippedspectating, bo
  
  REPLICATE(cvar_cl_handicap, float, "cl_handicap");
  
+ REPLICATE(cvar_cl_gunalign, int, "cl_gunalign");
  REPLICATE(cvar_cl_jetpack_jump, bool, "cl_jetpack_jump");
  
  REPLICATE(cvar_cl_movement_track_canjump, bool, "cl_movement_track_canjump");
@@@ -429,6 -433,9 +433,9 @@@ void GetCvars(entity this, entity store
  {
        string s = string_null;
  
+       if (f == 0)
+               LOG_INFO("Warning: requesting cvar values is deprecated. Client should send them automatically using REPLICATE.\n");
        if (f > 0)
                s = strcat1(argv(f));
  
@@@ -484,13 -491,12 +491,12 @@@ string playername(entity p, bool team_c
          return p.netname;
  }
  
- float want_weapon(entity weaponinfo, float allguns) // WEAPONTODO: what still needs done?
+ float want_weapon(entity weaponinfo, float allguns)
  {
-       int i = weaponinfo.m_id;
        int d = 0;
        bool allow_mutatorblocked = false;
  
-       if(!i)
+       if(!weaponinfo.m_id)
                return 0;
  
        bool mutator_returnvalue = MUTATOR_CALLHOOK(WantWeapon, weaponinfo, d, allguns, allow_mutatorblocked);
  
        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
        return t;
  }
  
+ /// Weapons the player normally starts with outside weapon arena.
+ WepSet weapons_start()
+ {
+       WepSet ret = '0 0 0';
+       FOREACH(Weapons, it != WEP_Null, {
+               int w = want_weapon(it, false);
+               if (w & 1)
+                       ret |= it.m_wepset;
+       });
+       return ret;
+ }
+ WepSet weapons_all()
+ {
+       WepSet ret = '0 0 0';
+       FOREACH(Weapons, it != WEP_Null, {
+               if (!(it.spawnflags & (WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_SPECIALATTACK)))
+                       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_NORMAL) && !(it.spawnflags & (WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_SPECIALATTACK)))
+                       ret |= it.m_wepset;
+       });
+       return ret;
+ }
+ void weaponarena_available_all_update(entity this)
+ {
+       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)
+ {
+       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)
+ {
+       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()
  {
        float i, t;
-       string s;
  
        // initialize starting values for players
        start_weapons = '0 0 0';
        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);
        {
                g_weaponarena = 1;
                g_weaponarena_list = "All Weapons";
-               FOREACH(Weapons, it != WEP_Null, {
-                       if(!(it.spawnflags & (WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_SPECIALATTACK)))
-                               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_NORMAL) && !(it.spawnflags & (WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_SPECIALATTACK)))
-                               g_weaponarena_weapons |= (it.m_wepset);
-               });
+               g_weaponarena_weapons = weapons_most();
+       }
+       else if (s == "all_available")
+       {
+               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")
        {
        {
                g_weapon_stay = 0; // incompatible
                start_weapons = g_weaponarena_weapons;
 -              start_items |= IT_UNLIMITED_AMMO;
 +              start_items |= IT_UNLIMITED_BOTH;
        }
        else
        {
                start_items |= IT_UNLIMITED_SUPERWEAPONS;
  
        if(!cvar("g_use_ammunition"))
 -              start_items |= IT_UNLIMITED_AMMO;
 +              start_items |= IT_UNLIMITED_WEAPON_AMMO;
  
        if(start_items & IT_UNLIMITED_WEAPON_AMMO)
        {
                start_ammo_plasma = cvar("g_start_ammo_plasma");
                start_ammo_fuel = cvar("g_start_ammo_fuel");
                random_start_weapons_count = cvar("g_random_start_weapons_count");
-               SetResource(random_start_ammo, RES_SHELLS, cvar(
-                       "g_random_start_shells"));
-               SetResource(random_start_ammo, RES_BULLETS, cvar(
-                       "g_random_start_bullets"));
-               SetResource(random_start_ammo, RES_ROCKETS,
-                       cvar("g_random_start_rockets"));
-               SetResource(random_start_ammo, RES_CELLS, cvar(
-                       "g_random_start_cells"));
-               SetResource(random_start_ammo, RES_PLASMA, cvar(
-                       "g_random_start_plasma"));
-       }
-       if (warmup_stage)
-       {
-               warmup_start_ammo_shells = start_ammo_shells;
-               warmup_start_ammo_nails = start_ammo_nails;
-               warmup_start_ammo_rockets = start_ammo_rockets;
-               warmup_start_ammo_cells = start_ammo_cells;
-               warmup_start_ammo_plasma = start_ammo_plasma;
-               warmup_start_ammo_fuel = start_ammo_fuel;
-               warmup_start_health = start_health;
-               warmup_start_armorvalue = start_armorvalue;
-               warmup_start_weapons = start_weapons;
-               warmup_start_weapons_default = start_weapons_default;
-               warmup_start_weapons_defaultmask = start_weapons_defaultmask;
-               if (!g_weaponarena && !g_ca && !g_freezetag)
-               {
-                       warmup_start_ammo_shells = cvar("g_warmup_start_ammo_shells");
-                       warmup_start_ammo_nails = cvar("g_warmup_start_ammo_nails");
-                       warmup_start_ammo_rockets = cvar("g_warmup_start_ammo_rockets");
-                       warmup_start_ammo_cells = cvar("g_warmup_start_ammo_cells");
-                       warmup_start_ammo_plasma = cvar("g_warmup_start_ammo_plasma");
-                       warmup_start_ammo_fuel = cvar("g_warmup_start_ammo_fuel");
-                       warmup_start_health = cvar("g_warmup_start_health");
-                       warmup_start_armorvalue = cvar("g_warmup_start_armor");
-                       warmup_start_weapons = '0 0 0';
-                       warmup_start_weapons_default = '0 0 0';
-                       warmup_start_weapons_defaultmask = '0 0 0';
-                       FOREACH(Weapons, it != WEP_Null, {
-                               int w = want_weapon(it, g_warmup_allguns);
-                               WepSet s = (it.m_wepset);
-                               if(w & 1)
-                                       warmup_start_weapons |= s;
-                               if(w & 2)
-                                       warmup_start_weapons_default |= s;
-                               if(w & 4)
-                                       warmup_start_weapons_defaultmask |= s;
-                       });
-               }
+               SetResource(random_start_ammo, RES_SHELLS, cvar("g_random_start_shells"));
+               SetResource(random_start_ammo, RES_BULLETS, cvar("g_random_start_bullets"));
+               SetResource(random_start_ammo, RES_ROCKETS,cvar("g_random_start_rockets"));
+               SetResource(random_start_ammo, RES_CELLS, cvar("g_random_start_cells"));
+               SetResource(random_start_ammo, RES_PLASMA, cvar("g_random_start_plasma"));
+       }
+       warmup_start_ammo_shells = start_ammo_shells;
+       warmup_start_ammo_nails = start_ammo_nails;
+       warmup_start_ammo_rockets = start_ammo_rockets;
+       warmup_start_ammo_cells = start_ammo_cells;
+       warmup_start_ammo_plasma = start_ammo_plasma;
+       warmup_start_ammo_fuel = start_ammo_fuel;
+       warmup_start_health = start_health;
+       warmup_start_armorvalue = start_armorvalue;
+       warmup_start_weapons = start_weapons;
+       warmup_start_weapons_default = start_weapons_default;
+       warmup_start_weapons_defaultmask = start_weapons_defaultmask;
+       if (!g_weaponarena)
+       {
+               warmup_start_ammo_shells = cvar("g_warmup_start_ammo_shells");
+               warmup_start_ammo_nails = cvar("g_warmup_start_ammo_nails");
+               warmup_start_ammo_rockets = cvar("g_warmup_start_ammo_rockets");
+               warmup_start_ammo_cells = cvar("g_warmup_start_ammo_cells");
+               warmup_start_ammo_plasma = cvar("g_warmup_start_ammo_plasma");
+               warmup_start_ammo_fuel = cvar("g_warmup_start_ammo_fuel");
+               warmup_start_health = cvar("g_warmup_start_health");
+               warmup_start_armorvalue = cvar("g_warmup_start_armor");
+               warmup_start_weapons = '0 0 0';
+               warmup_start_weapons_default = '0 0 0';
+               warmup_start_weapons_defaultmask = '0 0 0';
+               FOREACH(Weapons, it != WEP_Null, {
+                       int w = want_weapon(it, g_warmup_allguns);
+                       WepSet s = it.m_wepset;
+                       if(w & 1)
+                               warmup_start_weapons |= s;
+                       if(w & 2)
+                               warmup_start_weapons_default |= s;
+                       if(w & 4)
+                               warmup_start_weapons_defaultmask |= s;
+               });
        }
  
        if (g_jetpack)
        start_ammo_cells = max(0, start_ammo_cells);
        start_ammo_plasma = max(0, start_ammo_plasma);
        start_ammo_fuel = max(0, start_ammo_fuel);
-       SetResource(random_start_ammo, RES_SHELLS, max(0,
-               GetResource(random_start_ammo, RES_SHELLS)));
-       SetResource(random_start_ammo, RES_BULLETS, max(0,
-               GetResource(random_start_ammo, RES_BULLETS)));
-       SetResource(random_start_ammo, RES_ROCKETS, max(0,
-               GetResource(random_start_ammo, RES_ROCKETS)));
-       SetResource(random_start_ammo, RES_CELLS, max(0,
-               GetResource(random_start_ammo, RES_CELLS)));
-       SetResource(random_start_ammo, RES_PLASMA, max(0,
-               GetResource(random_start_ammo, RES_PLASMA)));
+       SetResource(random_start_ammo, RES_SHELLS,
+               max(0, GetResource(random_start_ammo, RES_SHELLS)));
+       SetResource(random_start_ammo, RES_BULLETS,
+               max(0, GetResource(random_start_ammo, RES_BULLETS)));
+       SetResource(random_start_ammo, RES_ROCKETS,
+               max(0, GetResource(random_start_ammo, RES_ROCKETS)));
+       SetResource(random_start_ammo, RES_CELLS,
+               max(0, GetResource(random_start_ammo, RES_CELLS)));
+       SetResource(random_start_ammo, RES_PLASMA,
+               max(0, GetResource(random_start_ammo, RES_PLASMA)));
  
        warmup_start_ammo_shells = max(0, warmup_start_ammo_shells);
        warmup_start_ammo_nails = max(0, warmup_start_ammo_nails);
@@@ -748,9 -841,9 +841,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));
diff --combined xonotic-server.cfg
index 35a51144252f3ad76e456855ae6477e700620182,158b32ecd597d837df4224d0dff3f96b29fa9515..59a455b6a3cf20d4dcce8282c5c2f3de34fd3942
@@@ -190,12 -190,12 +190,12 @@@ set g_pinata 0 "if set to 1 you will no
  set g_weapon_stay 0 "1: ghost weapons can be picked up too but give no ammo, 2: ghost weapons refill ammo to one pickup size, thrown guns have no ammo"
  set g_weapon_throwable 1 "if set to 1, weapons can be dropped"
  set g_powerups -1 "if set to 0 the strength and shield (invincibility) will not spawn on the map, if 1 they will spawn in all game modes, -1 is game mode default"
 -set g_use_ammunition 1 "if set to 0 all weapons have unlimited ammunition"
 +set g_use_ammunition 1 "if set to 0 all weapons have unlimited ammo"
  set g_pickup_items -1 "if set to 0 all items (health, armor, ammo, weapons...) are removed from the map, if 1 they are forced to spawn"
  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\""
+ 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"