]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into divVerent/csqcmodel
authorRudolf Polzer <divverent@alientrap.org>
Tue, 6 Dec 2011 21:14:38 +0000 (22:14 +0100)
committerRudolf Polzer <divverent@alientrap.org>
Tue, 6 Dec 2011 21:14:38 +0000 (22:14 +0100)
1  2 
defaultXonotic.cfg
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/defs.qh
qcsrc/server/g_world.qc

diff --combined defaultXonotic.cfg
index 1f11c8110360d57d80687e67a831ddbce6e6007c,03573ca5da144646f3a0048e5b76f14e7d7b5e19..a44d14be06b7bcce447da82d501db33924107bed
@@@ -711,6 -711,7 +711,7 @@@ seta timelimit_suddendeath 5 "number o
  
  // common team values
  set g_tdm 0 "Team Deathmatch: the team who kills their opponents most often wins"
+ set g_tdm_on_dm_maps 0 "when this is set, all DM maps automatically support TDM"
  
  seta teamplay_mode 4 "default teamplay setting in team games. 1 = no friendly fire, self damage. 2 = friendly fire and self damage enabled. 3 = no friendly fire, but self damage enabled. 4 = obey the following four cvars"
  seta g_mirrordamage 0.700000  "for teamplay 4: mirror damage factor"
@@@ -721,7 -722,6 +722,6 @@@ seta g_friendlyfire_virtual_force 1        "fo
  seta g_teamdamage_threshold 40        "for teamplay 4: threshold over which to apply mirror damage"
  seta g_teamdamage_resetspeed 20       "for teamplay 4: how fast player's teamdamage count decreases"
  
- set deathmatch_force_teamplay 0       "Always play TDM instead of DM"
  seta g_balance_teams 0        "automatically balance out players entering instead of asking them for their preferred team"
  seta g_balance_teams_force 0  "automatically balance out teams when players move or disconnect"
  seta g_balance_teams_prevent_imbalance        0       "prevent players from changing to larger teams"
@@@ -1811,6 -1811,11 +1811,6 @@@ set menu_updatecheck 
  set bot_navigation_ignoreplayers 0 // FIXME remove this once the issue is solved
  set bot_sound_monopoly 0 "when enabled, only bots can make any noise"
  
 -// broken, sorry (cannot handle weapon attachment properly)
 -//seta cl_forceplayermodels 0 "force all players to look like you; WARNING: animations can look very bad with this"
 -//seta cl_forceplayermodelsfromxonotic 0 "force models coming from xonotic; WARNING: animations can look very bad with this"
 -//set sv_clforceplayermodels 1 "allow clients to use cl_forcemodels"
 -
  set sv_loddistance1 1024
  set sv_loddistance2 4096
  seta cl_playerdetailreduction 0       "the higher, the less detailed player models are displayed (LOD)"
@@@ -1920,9 -1925,6 +1920,9 @@@ set developer_shtest 0 "experimental sp
  set waypoint_benchmark 0 "quit after waypoint loading to benchmark bot navigation code"
  set g_debug_bot_commands 0 "print scripted bot commands before executing"
  set g_debug_defaultsounds 0 "always use default sounds"
 +set sv_use_csqc_players 0 "set to 1 to network players to CSQC (not compatible to old clients)"
 +set cl_forceplayermodels 0 "set to 1 to make everyone look like yourself (requires server to have sv_use_csqc_players 1)"
 +set cl_precacheplayermodels 0 "TODO please check if this needs to be 1 or if precaching a model the server already requested is fast enough to do it at runtime"
  
  // debug cvars for keyhunt attaching
  set _angles "0 0 0"
index e31a3625e2d272531b3fc31c43d9ae2ed3f4946b,8f45f5367e2ae88756d0fef15a65ea961cb5ab87..c210f848a2955e9b0aaa17cf52af6b92fe8c21c5
@@@ -61,7 -61,6 +61,6 @@@ float autocvar_bot_debug_goalstack
  float autocvar_bot_wander_enable;
  float autocvar_captureleadlimit_override;
  #define autocvar_capturelimit_override cvar("capturelimit_override")
- float autocvar_deathmatch_force_teamplay;
  #define autocvar_developer cvar("developer")
  float autocvar_developer_fteqccbugs;
  float autocvar_ekg;
@@@ -780,6 -779,7 +779,6 @@@ float autocvar_g_ctf_shield_max_ratio
  float autocvar_g_ctf_shield_min_negscore;
  float autocvar_g_cts_finish_kill_delay;
  float autocvar_g_cts_selfdamage;
 -float autocvar_g_deathglow;
  float autocvar_g_debug_bot_commands;
  float autocvar_g_domination_default_teams;
  float autocvar_g_domination_disable_frags;
@@@ -1129,6 -1129,13 +1128,6 @@@ float autocvar_sv_maxairspeed
  float autocvar_sv_maxairstrafespeed;
  float autocvar_sv_maxspeed;
  string autocvar_sv_motd;
 -string autocvar_sv_player_crouch_maxs;
 -string autocvar_sv_player_crouch_mins;
 -string autocvar_sv_player_crouch_viewoffset;
 -string autocvar_sv_player_headsize;
 -string autocvar_sv_player_maxs;
 -string autocvar_sv_player_mins;
 -string autocvar_sv_player_viewoffset;
  float autocvar_sv_player_jumpanim_minfall;
  float autocvar_sv_precacheplayermodels;
  float autocvar_sv_precacheweapons;
index 0d82ed855c7b8a99175d6014c696904d142c63ca,1a6c9124b8d4f0df84772a80dfe64772a0800c63..c2baf5bcc26c557d66309affcc77c0a2f92c3204
@@@ -158,7 -158,7 +158,7 @@@ vector Spawn_Score(entity spot, float m
                if (thisdist < shortest)
                        shortest = thisdist;
        }
-       if(shortest < mindist)
+       if(shortest > mindist)
                prio += SPAWN_PRIO_GOOD_DISTANCE;
  
        spawn_score = prio * '1 0 0' + shortest * '0 1 0';
@@@ -341,36 -341,160 +341,36 @@@ string CheckPlayerModel(string plyermod
                // to change a cvar default, we'll have a small leak here.
                FallbackPlayerModel = strzone(cvar_defstring("_cl_playermodel"));
        }
 -      if(strlen(plyermodel) < 4)
 -              return FallbackPlayerModel;
 +      // only in right path
        if( substring(plyermodel,0,14) != "models/player/")
                return FallbackPlayerModel;
 -      else if(autocvar_sv_servermodelsonly)
 +      // only good file extensions
 +      if(substring(plyermodel,-4,4) != ".zym")
 +      if(substring(plyermodel,-4,4) != ".dpm")
 +      if(substring(plyermodel,-4,4) != ".iqm")
 +      if(substring(plyermodel,-4,4) != ".md3")
 +      if(substring(plyermodel,-4,4) != ".psk")
 +              return FallbackPlayerModel;
 +      // forbid the LOD models
 +      if(substring(plyermodel, -9,5) == "_lod1")
 +              return FallbackPlayerModel;
 +      if(substring(plyermodel, -9,5) == "_lod2")
 +              return FallbackPlayerModel;
 +      if(plyermodel != strtolower(plyermodel))
 +              return FallbackPlayerModel;
 +      // also, restrict to server models
 +      if(autocvar_sv_servermodelsonly)
        {
 -              if(substring(plyermodel,-4,4) != ".zym")
 -              if(substring(plyermodel,-4,4) != ".dpm")
 -              if(substring(plyermodel,-4,4) != ".iqm")
 -              if(substring(plyermodel,-4,4) != ".md3")
 -              if(substring(plyermodel,-4,4) != ".psk")
 -                      return FallbackPlayerModel;
 -              // forbid the LOD models
 -              if(substring(plyermodel, -9,5) == "_lod1")
 -                      return FallbackPlayerModel;
 -              if(substring(plyermodel, -9,5) == "_lod2")
 -                      return FallbackPlayerModel;
 -              if(plyermodel != strtolower(plyermodel))
 -                      return FallbackPlayerModel;
                if(!fexists(plyermodel))
                        return FallbackPlayerModel;
        }
        return plyermodel;
  }
  
 -/*
 -=============
 -Client_customizeentityforclient
 -
 -LOD reduction
 -=============
 -*/
 -void Client_uncustomizeentityforclient()
 -{
 -      if(self.modelindex == 0) // no need to uncustomize then
 -              return;
 -      self.modelindex = self.modelindex_lod0;
 -      self.skin = self.skinindex;
 -}
 -
 -float Client_customizeentityforclient()
 +void setplayermodel(entity e, string modelname)
  {
 -      entity modelsource;
 -
 -      if(self.modelindex == 0)
 -              return TRUE;
 -
 -      // forcemodel stuff
 -
 -#ifdef PROFILING
 -      float t0;
 -      t0 = gettime(GETTIME_HIRES); // reference
 -#endif
 -
 -      modelsource = self;
 -
 -#ifdef ALLOW_FORCEMODELS
 -      if(other.cvar_cl_forceplayermodelsfromxonotic)
 -              if not(self.modelindex_lod0_from_xonotic)
 -                      modelsource = other;
 -      if(other.cvar_cl_forceplayermodels && sv_clforceplayermodels)
 -              modelsource = other;
 -#endif
 -
 -      self.skin = modelsource.skinindex;
 -
 -#if 0
 -      if(modelsource == self)
 -              self.skin = modelsource.skinindex;
 -      else
 -              self.skin = mod(modelsource.skinindex, 3); // forbid the fbskins as forced skins
 -#endif
 -
 -      // self: me
 -      // other: the player viewing me
 -      float distance;
 -      float f;
 -
 -      if(other.cvar_cl_playerdetailreduction <= 0)
 -      {
 -              if(other.cvar_cl_playerdetailreduction <= -2)
 -                      self.modelindex = modelsource.modelindex_lod2;
 -              else if(other.cvar_cl_playerdetailreduction <= -1)
 -                      self.modelindex = modelsource.modelindex_lod1;
 -              else
 -                      self.modelindex = modelsource.modelindex_lod0;
 -      }
 -      else
 -      {
 -              distance = vlen(self.origin - other.origin);
 -              f = (distance + 100.0) * other.cvar_cl_playerdetailreduction;
 -              if(f > sv_loddistance2)
 -                      self.modelindex = modelsource.modelindex_lod2;
 -              else if(f > sv_loddistance1)
 -                      self.modelindex = modelsource.modelindex_lod1;
 -              else
 -                      self.modelindex = modelsource.modelindex_lod0;
 -      }
 -
 -#ifdef PROFILING
 -      float t1;
 -      t1 = gettime(GETTIME_HIRES); // reference
 -      client_cefc_accumulator += (t1 - t0);
 -#endif
 -
 -      return TRUE;
 -}
 -
 -void setmodel_lod(entity e, string modelname)
 -{
 -      string s;
 -
 -      if(sv_loddistance1)
 -      {
 -              // FIXME: this only supports 3-letter extensions
 -              s = strcat(substring(modelname, 0, strlen(modelname)-4), "_lod1", substring(modelname, -4, 4));
 -              if(fexists(s))
 -              {
 -                      setmodel(e, s); // players have high precision
 -                      self.modelindex_lod1 = self.modelindex;
 -              }
 -              else
 -                      self.modelindex_lod1 = -1;
 -
 -              s = strcat(substring(modelname, 0, strlen(modelname)-4), "_lod2", substring(modelname, -4, 4));
 -              if(fexists(s))
 -              {
 -                      setmodel(e, s); // players have high precision
 -                      self.modelindex_lod2 = self.modelindex;
 -              }
 -              else
 -                      self.modelindex_lod2 = -1;
 -
 -              precache_model(modelname);
 -              setmodel(e, modelname); // players have high precision
 -              self.modelindex_lod0 = self.modelindex;
 -
 -              if(self.modelindex_lod1 < 0)
 -                      self.modelindex_lod1 = self.modelindex;
 -
 -              if(self.modelindex_lod2 < 0)
 -                      self.modelindex_lod2 = self.modelindex;
 -      }
 -      else
 -      {
 -              precache_model(modelname);
 -              setmodel(e, modelname); // players have high precision
 -              self.modelindex_lod0 = self.modelindex;
 -                      // save it for possible player model forcing
 -      }
 -
 -      s = whichpack(self.model);
 -      self.modelindex_lod0_from_xonotic = ((s == "") || (substring(s, 0, 4) == "data"));
 -
 +      precache_model(modelname);
 +      setmodel(e, modelname);
        player_setupanimsformodel();
        UpdatePlayerSounds();
  }
@@@ -485,18 -609,16 +485,18 @@@ void PutObserverInServer (void
        self.fixangle = TRUE;
        self.crouch = FALSE;
  
 -      self.view_ofs = '0 0 0'; // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS"
        setorigin (self, spot.origin);
 -      setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY
        self.prevorigin = self.origin;
        self.items = 0;
        self.weapons = 0;
        self.model = "";
        FixPlayermodel();
 -      self.model = "";
 -      self.modelindex = 0;
 +      setmodel(self, "null");
 +      self.drawonlytoclient = self;
 +
 +      setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY
 +      self.view_ofs = '0 0 0'; // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS"
 +
        self.weapon = 0;
        self.weaponname = "";
        self.switchingweapon = 0;
        self.oldvelocity = self.velocity;
        self.fire_endtime = -1;
  
 -      if(sv_loddistance1)
 -              SetCustomizer(self, Client_customizeentityforclient, Client_uncustomizeentityforclient);
 -
        if(g_arena)
        {
                if(self.version_mismatch)
@@@ -597,29 -722,29 +597,29 @@@ void FixPlayermodel(
                {
                        m1 = self.mins;
                        m2 = self.maxs;
 -                      setmodel_lod (self, defaultmodel);
 +                      setplayermodel (self, defaultmodel);
                        setsize (self, m1, m2);
                        chmdl = TRUE;
                }
  
 -              oldskin = self.skinindex;
 -              self.skinindex = defaultskin;
 +              oldskin = self.skin;
 +              self.skin = defaultskin;
        } else {
                if (self.playermodel != self.model || self.playermodel == "")
                {
                        self.playermodel = CheckPlayerModel(self.playermodel); // this is never "", so no endless loop
                        m1 = self.mins;
                        m2 = self.maxs;
 -                      setmodel_lod (self, self.playermodel);
 +                      setplayermodel (self, self.playermodel);
                        setsize (self, m1, m2);
                        chmdl = TRUE;
                }
  
 -              oldskin = self.skinindex;
 -              self.skinindex = stof(self.playerskin);
 +              oldskin = self.skin;
 +              self.skin = stof(self.playerskin);
        }
  
 -      if(chmdl || oldskin != self.skinindex)
 +      if(chmdl || oldskin != self.skin)
                self.species = player_getspecies(); // model or skin has changed
  
        if(!teamplay)
@@@ -724,7 -849,6 +724,7 @@@ void PutClientInServer (void
                        self.effects = EF_FULLBRIGHT;
                else
                        self.effects = 0;
 +              self.effects |= EF_TELEPORT_BIT | EF_RESTARTANIM_BIT;
                self.air_finished = time + 12;
                self.dmg = 2;
                if(autocvar_g_balance_nex_charge)
                        WriteByte(MSG_ONE, TE_CSQC_SPAWN);
                });
  
 -              if(sv_loddistance1)
 -                      SetCustomizer(self, Client_customizeentityforclient, Client_uncustomizeentityforclient);
 -
                self.model = "";
                FixPlayermodel();
 +              self.drawonlytoclient = world;
  
                self.crouch = FALSE;
                self.view_ofs = PL_VIEW_OFS;
@@@ -1187,7 -1313,7 +1187,7 @@@ void ClientKill_TeamChange (float targe
                        self.clientkill_nexttime = time + killtime + autocvar_g_balance_kill_antispam;
                }
  
 -              if(killtime <= 0 || !self.modelindex || self.deadflag != DEAD_NO)
 +              if(killtime <= 0 || self.classname != "player" || self.deadflag != DEAD_NO)
                {
                        ClientKill_Now();
                }
@@@ -1595,8 -1721,6 +1595,8 @@@ void ClientConnect (void
        if(!autocvar_g_campaign)
                Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), autocvar_welcome_message_time, 0);
  
 +      CSQCMODEL_AUTOINIT();
 +
        self.model_randomizer = random();
  }
  
@@@ -2617,26 -2741,42 +2617,26 @@@ void PlayerPreThink (void
  
                if(frametime)
                {
 -                      if(self.health <= 0 && autocvar_g_deathglow)
 -                      {
 -                              if(self.glowmod_x > 0)
 -                                      self.glowmod_x -= autocvar_g_deathglow * frametime;
 -                              else
 -                                      self.glowmod_x = -1;
 -                              if(self.glowmod_y > 0)
 -                                      self.glowmod_y -= autocvar_g_deathglow * frametime;
 -                              else
 -                                      self.glowmod_y = -1;
 -                              if(self.glowmod_z > 0)
 -                                      self.glowmod_z -= autocvar_g_deathglow * frametime;
 -                              else
 -                                      self.glowmod_z = -1;
 -                      }
 -                      else
 +#ifndef NO_LEGACY_NETWORKING
 +                      self.glowmod = colormapPaletteColor(self.clientcolors & 0x0F, TRUE) * 2;
 +#endif
 +
 +                      if(self.weapon == WEP_NEX && autocvar_g_balance_nex_charge)
                        {
 -                              // set weapon and player glowmod
 -                              self.glowmod = colormapPaletteColor(self.clientcolors & 0x0F, TRUE) * 2;
 +                              self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit);
 +                              self.weaponentity_glowmod_y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit);
 +                              self.weaponentity_glowmod_z = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit);
  
 -                              if(self.weapon == WEP_NEX && autocvar_g_balance_nex_charge)
 +                              if(self.nex_charge > autocvar_g_balance_nex_charge_animlimit)
                                {
 -                                      self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit);
 -                                      self.weaponentity_glowmod_y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit);
 -                                      self.weaponentity_glowmod_z = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit);
 -
 -                                      if(self.nex_charge > autocvar_g_balance_nex_charge_animlimit)
 -                                      {
 -                                              self.weaponentity_glowmod_x = self.weaponentity_glowmod_x + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit);
 -                                              self.weaponentity_glowmod_y = self.weaponentity_glowmod_y + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit);
 -                                              self.weaponentity_glowmod_z = self.weaponentity_glowmod_z + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit);
 -                                      }
 +                                      self.weaponentity_glowmod_x = self.weaponentity_glowmod_x + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit);
 +                                      self.weaponentity_glowmod_y = self.weaponentity_glowmod_y + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit);
 +                                      self.weaponentity_glowmod_z = self.weaponentity_glowmod_z + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit);
                                }
 -                              else
 -                                      self.weaponentity_glowmod = self.glowmod;
                        }
 +                      else
 +                              self.weaponentity_glowmod = colormapPaletteColor(self.clientcolors & 0x0F, TRUE) * 2;
 +
                        player_powerups();
                }
  
@@@ -3049,6 -3189,4 +3049,6 @@@ void PlayerPostThink (void
        if(g_race)
                dprint(sprintf("%f %.6f\n", time, race_GetFractionalLapCount(self)));
        */
 +
 +      CSQCMODEL_AUTOUPDATE();
  }
index a602e9242b12751dd158afdb0d18621ac9ca8e0e,4d04712379744f15809b4860e385a46ac6fd5ad5..fe269a210c0e989ef6d9c58c140f9d00acd4cf1c
@@@ -134,6 -134,7 +134,6 @@@ void CopyBody(float keepvelocity
        self.enemy = oldself;
        self.lip = oldself.lip;
        self.colormap = oldself.colormap;
 -      self.glowmod = oldself.glowmod;
        self.iscreature = oldself.iscreature;
        self.damagedbycontents = oldself.damagedbycontents;
        self.angles = oldself.angles;
        self.classname = "body";
        self.damageforcescale = oldself.damageforcescale;
        self.effects = oldself.effects;
 +      self.glowmod = oldself.glowmod;
        self.event_damage = oldself.event_damage;
        self.animstate_startframe = oldself.animstate_startframe;
        self.animstate_numframes = oldself.animstate_numframes;
        self.armortype = oldself.armortype;
        self.model = oldself.model;
        self.modelindex = oldself.modelindex;
 -      self.modelindex_lod0 = oldself.modelindex_lod0;
 -      self.modelindex_lod0_from_xonotic = oldself.modelindex_lod0_from_xonotic;
 -      self.modelindex_lod1 = oldself.modelindex_lod1;
 -      self.modelindex_lod2 = oldself.modelindex_lod2;
 -      self.skinindex = oldself.skinindex;
 +      self.skin = oldself.skin;
        self.species = oldself.species;
        self.movetype = oldself.movetype;
        self.nextthink = oldself.nextthink;
  float player_getspecies()
  {
        float s;
 -      get_model_parameters(self.model, self.skinindex);
 +      get_model_parameters(self.model, self.skin);
        s = get_model_parameters_species;
        get_model_parameters(string_null, 0);
        if(s < 0)
@@@ -226,6 -230,7 +226,7 @@@ void player_setupanimsformodel(
        self.anim_backright = animfixfps(self, '21 1 1');
        self.anim_backleft  = animfixfps(self, '22 1 1');
        self.anim_melee = animfixfps(self, '23 1 1');
+       self.anim_duckwalkbackwards = animfixfps(self, '24 1 1');
        // TODO introspect models for finding right "fps" value (1/duration)
        // reset animstate now
        setanim(self, self.anim_idle, TRUE, FALSE, TRUE);
@@@ -282,7 -287,9 +283,9 @@@ void player_anim (void
                }
                else if (self.crouch)
                {
-                       if (self.movement_x * self.movement_x + self.movement_y * self.movement_y > 20)
+                       if (self.movement_x < 0)
+                               setanim(self, self.anim_duckwalkbackwards, TRUE, FALSE, FALSE);
+                       else if (self.movement_x * self.movement_x + self.movement_y * self.movement_y > 20)
                                setanim(self, self.anim_duckwalk, TRUE, FALSE, FALSE);
                        else
                                setanim(self, self.anim_duckidle, TRUE, FALSE, FALSE);
@@@ -1145,18 -1152,18 +1148,18 @@@ float LoadPlayerSounds(string f, float 
  }
  
  .float modelindex_for_playersound;
 -.float skinindex_for_playersound;
 +.float skin_for_playersound;
  void UpdatePlayerSounds()
  {
        if(self.modelindex == self.modelindex_for_playersound)
 -      if(self.skinindex == self.skinindex_for_playersound)
 +      if(self.skin == self.skin_for_playersound)
                return;
        self.modelindex_for_playersound = self.modelindex;
 -      self.skinindex_for_playersound = self.skinindex;
 +      self.skin_for_playersound = self.skin;
        ClearPlayerSounds();
        LoadPlayerSounds("sound/player/default.sounds", 1);
        if(!autocvar_g_debug_defaultsounds)
 -              if(!LoadPlayerSounds(get_model_datafilename(self.model, self.skinindex, "sounds"), 0))
 +              if(!LoadPlayerSounds(get_model_datafilename(self.model, self.skin, "sounds"), 0))
                        LoadPlayerSounds(get_model_datafilename(self.model, 0, "sounds"), 0);
  }
  
diff --combined qcsrc/server/defs.qh
index bd890f4333412f5bc43beb3677fc05d1395c67c3,d32c27aad13fa54ccd4b6187de649c5b5282c986..6b39cdb4c4f40ebbdaa0c5167c8b60d1816e7a9f
@@@ -130,6 -130,7 +130,7 @@@ float maxclients
  .vector anim_draw; // player pulls out a weapon
  // .vector anim_duck; // player crouches (from idle to duckidle)
  .vector anim_duckwalk; // player walking while crouching
+ .vector anim_duckwalkbackwards; // player walking while crouching
  .vector anim_duckjump; // player jumping from a crouch
  .vector anim_duckidle; // player idling while crouching
  .vector anim_idle; // player standing
@@@ -319,6 -320,7 +320,6 @@@ float default_weapon_alpha
  
  .float() customizeentityforclient;
  .float cvar_cl_handicap;
 -.float cvar_cl_playerdetailreduction;
  .float cvar_cl_clippedspectating;
  .float cvar_cl_autoscreenshot;
  .float cvar_cl_movement_track_canjump;
  .float cvar_cl_forceplayermodelsfromxonotic;
  float sv_clforceplayermodels;
  #endif
 -float sv_loddistance1;
 -float sv_loddistance2;
  .float cvar_cl_gunalign;
  .float cvar_cl_noantilag;
  
@@@ -346,6 -350,12 +347,6 @@@ void AnnounceTo(entity e, string snd)
  
  .float version_nagtime;
  
 -.float modelindex_lod0;
 -.float modelindex_lod0_from_xonotic;
 -.float skinindex;
 -.float modelindex_lod1;
 -.float modelindex_lod2;
 -
  #define NUM_JUMPPADSUSED 3
  .float jumppadcount;
  .entity jumppadsused[NUM_JUMPPADSUSED];
diff --combined qcsrc/server/g_world.qc
index 69df066abea6fe25990ec0817dd15a354315fe02,d0474b8ed4e92633c8ee3a83747db22eff59ea99..79641ed70eb130a7c292ecd8e4c3c9b754b85be6
@@@ -718,6 -718,10 +718,10 @@@ void spawnfunc_worldspawn (void
        //      dom_init();
  
        GameLogInit(); // prepare everything
+       // NOTE for matchid:
+       // changing the logic generating it is okay. But:
+       // it HAS to stay <= 64 chars
+       // character set: ASCII 33-126 without the following characters: : ; ' " \ $
        if(autocvar_sv_eventlog)
        {
                s = sprintf("%d.%s.%06d", ftos(autocvar_sv_eventlog_files_counter), strftime(FALSE, "%s"), floor(random() * 1000000));
                s = "";
                n = tokenize_console(cvar_string("sv_curl_serverpackages"));
                for(i = 0; i < n; ++i)
 -                      if(substring(argv(i), -14, -1) != ".serverpackage")
 +                      if(substring(argv(i), -14, -1) != "-serverpackage.txt")
 +                      if(substring(argv(i), -14, -1) != ".serverpackage") // OLD legacy
                                s = strcat(s, " ", argv(i));
 +              fd = search_begin("*-serverpackage.txt", TRUE, FALSE);
 +              if(fd >= 0)
 +              {
 +                      j = search_getsize(fd);
 +                      for(i = 0; i < j; ++i)
 +                              s = strcat(s, " ", search_getfilename(fd, i));
 +                      search_end(fd);
 +              }
                fd = search_begin("*.serverpackage", TRUE, FALSE);
                if(fd >= 0)
                {