]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge remote branch 'origin/master' into samual/keepaway
authorunknown <samual@xonotic.org>
Mon, 29 Nov 2010 08:07:01 +0000 (03:07 -0500)
committerunknown <samual@xonotic.org>
Mon, 29 Nov 2010 08:07:01 +0000 (03:07 -0500)
1  2 
defaultXonotic.cfg
qcsrc/common/util.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_player.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_world.qc
qcsrc/server/progs.src

diff --combined defaultXonotic.cfg
index 3b54b0c365687d1c85581561e59c66d6a459ea92,275c8a28fc9bb6561fb77c71dc79852c4e108f28..c54b50353ff2e998a7b11fdbae5e3030bcf44b34
@@@ -606,8 -606,6 +606,8 @@@ set g_cts_respawn_waves 
  set g_cts_respawn_delay 0.25
  set g_cts_selfdamage 1 "0 = disable all selfdamage and falldamage in cts"
  set g_cts_finish_kill_delay 10 "prevent cheating by running back to the start line, and starting out with more speed than otherwise possible"
 +set g_ka_respawn_delay 0
 +set g_ka_respawn_waves 0
  
  // overtime
  seta timelimit_overtime 2 "duration in minutes of one added overtime, added to the timelimit"
@@@ -1245,28 -1243,6 +1245,28 @@@ set g_balance_keyhunt_damageforcescale 
  seta g_keyhunt_teams_override 0
  set g_keyhunt_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_bckillscore 1 "enable scoring points (y/n) for ball carrier kills"
 +set g_keepaway_pointlimit     -1      "total amount of points you can get, -1 for unlimited"
 +set g_keepaway_pointleadlimit -1      "mercy rule, -1 for unlimited"
 +set g_keepaway_ballcarrier_alpha 0.6 "alpha when the player is the ballcarrier"
 +set g_keepaway_ballcarrier_highspeed 1.5 "speed multiplier done to the person holding the ball"
 +set g_keepaway_ballcarrier_damage     1.5     "damage multiplier while having powerup"
 +set g_keepaway_ballcarrier_force      1.5     "force multiplier while having powerup"
 +set g_keepaway_ballcarrier_selfdamage 1       "self damage multiplier while having powerup"
 +set g_keepaway_ballcarrier_selfforce  1.5     "self force multiplier while having powerup"
 +set g_keepaway_noncarrier_warn        0       "warn players when they kill without holding the ball"
 +set g_keepaway_noncarrier_damage      0.5     "damage done to other players if both you and they don't have the ball"
 +set g_keepaway_noncarrier_force       0.5     "force done to other players if both you and they don't have the ball"
 +set g_keepaway_noncarrier_selfdamage  1       "self damage if you don't have the ball"
 +set g_keepaway_noncarrier_selfforce   1       "self force if you don't have the ball"
 +set g_keepawayball_trail_color        254     "particle trail color from player/ball"
 +set g_keepawayball_damageforcescale   2 "Scale of force which is applied to the ball by weapons/explosions/etc"
 +set g_keepawayball_respawntime        15      "if no one picks up the ball, how long to wait until the ball respawns"
 +seta g_keepaway_teams_override 0
 +set g_keepaway_teams 0
 +
  // so it can be stuffcmd-ed still
  set cl_gravity 800    "but ignored anyway"
  
@@@ -1785,7 -1761,6 +1785,7 @@@ alias cl_hook_gamestart_a
  alias cl_hook_gamestart_rc
  alias cl_hook_gamestart_nexball
  alias cl_hook_gamestart_cts
 +alias cl_hook_gamestart_ka
  alias cl_hook_gameend
  alias cl_hook_activeweapon
  
@@@ -1806,7 -1781,6 +1806,7 @@@ alias sv_hook_gamestart_a
  alias sv_hook_gamestart_rc
  alias sv_hook_gamestart_nexball
  alias sv_hook_gamestart_cts
 +alias sv_hook_gamestart_ka
  alias sv_hook_gamerestart
  alias sv_hook_gameend
  
@@@ -2023,6 -1997,9 +2023,9 @@@ set g_forced_team_yellow "" "list of pl
  set g_forced_team_pink "" "list of player IDs for pink team"
  set g_forced_team_otherwise "default" "action if a non listed player joins (can be default for default action, spectate for forcing to spectate, or red, blue, yellow, pink)"
  
+ // player statistics server URI
+ set g_playerstats_uri ""
  // other config files
  exec balanceXonotic.cfg
  exec ctfscoring-ai.cfg
diff --combined qcsrc/common/util.qc
index 823709c9505c83482e85636d6339159b083d480e,e4db850a9fc4bbea0e29450533753e033cd237f3..176ac8fc64660c37037b321de6dc3786049ed54b
@@@ -1,43 -1,3 +1,3 @@@
- // checkextension wrapper for log
- float sqrt(float f); // declared later
- float exp(float f); // declared later
- float pow(float f, float e); // declared later
- float checkextension(string s); // declared later
- float log_synth(float f)
- {
-       float p, l;
-       if(f < 0)
-               return sqrt(-1); // nan? -inf?
-       if(f == 0)
-               return sqrt(-1); // ACTUALLY this should rather be -inf, but we cannot create a +inf in QC
-       if(f + f == f)
-               return l; // +inf
-       if(f < 1)
-       {
-               f = 1 / f;
-               p = -1;
-       }
-       else
-               p = 1;
-       while(f > 2)
-       {
-               f = sqrt(f);
-               p *= 2;
-       }
-       // two steps are good enough
-       l = ((6-f) * f - 5) / 4.32808512266689022212;
-       l += exp(-l) * f - 1;
-       l += exp(-l) * f - 1;
-       return l * p;
- }
- float log(float f)
- {
-       if(checkextension("DP_QC_LOG"))
-               return log_builtin(f);
-       else
-               return log_synth(f);
- }
  string wordwrap_buffer;
  
  void wordwrap_buffer_put(string s)
@@@ -439,7 -399,6 +399,7 @@@ string GametypeNameFromType(float g
        else if (g == GAME_RACE) return "rc";
        else if (g == GAME_NEXBALL) return "nexball";
        else if (g == GAME_CTS) return "cts";
 +      else if (g == GAME_KEEPAWAY) return "ka";
        return "dm";
  }
  
index 781836469bf40192a2941adfe7017857784c0ee6,68f699f3711b7cc4d3250a5dd5c755c29cc753d6..7e6a9894288013df585ef8075e0bc16c242ca11f
@@@ -603,10 -603,16 +603,16 @@@ void PutObserverInServer (void
  
        Portal_ClearAll(self);
  
+       if(self.alivetime)
+       {
+               PlayerStats_Event(self, PLAYERSTATS_ALIVETIME, time - self.alivetime);
+               self.alivetime = 0;
+       }
        if(self.flagcarried)
                DropFlag(self.flagcarried, world, world);
  
 -      if(self.ballcarried)
 +      if(self.ballcarried && g_nexball)
                DropBall(self.ballcarried, self.origin + self.ballcarried.origin, self.velocity);
  
        WaypointSprite_PlayerDead();
@@@ -1074,6 -1080,9 +1080,9 @@@ void PutClientInServer (void
                self.switchweapon = w_getbestweapon(self);
                self.cnt = self.switchweapon;
                self.weapon = 0;
+               if(!self.alivetime)
+                       self.alivetime = time;
        } else if(self.classname == "observer" || (g_ca && !allowed_to_spawn)) {
                PutObserverInServer ();
        }
@@@ -1701,6 -1710,8 +1710,8 @@@ void ClientConnect (void
        send_CSQC_cr_maxbullets(self);
  
        CheatInitClient();
+       PlayerStats_AddPlayer(self);
  }
  
  /*
@@@ -1721,6 -1732,8 +1732,8 @@@ void ClientDisconnect (void
                return;
        }
  
+       PlayerStats_AddGlobalInfo(self);
        CheatShutdownClient();
  
        if(self.hitplotfh >= 0)
  
        if(self.flagcarried)
                DropFlag(self.flagcarried, world, world);
 -      if(self.ballcarried)
 +      if(self.ballcarried && g_nexball)
                DropBall(self.ballcarried, self.origin + self.ballcarried.origin, self.velocity);
  
        // Here, everything has been done that requires this player to be a client.
@@@ -1987,9 -2000,6 +2000,9 @@@ string getTimeoutText(float addOneSecon
  
  void player_powerups (void)
  {
 +      // add a way to see what the items were BEFORE all of these checks for the mutator hook
 +      olditems = self.items;
 +      
        if((self.items & IT_USING_JETPACK) && !self.deadflag)
        {
                SoundEntity_StartSound(self, CHAN_PLAYER, "misc/jetpack_fly.wav", VOL_BASE, cvar("g_jetpack_attenuation"));
                                sprint(self, "^3You are on speed\n");
                        }
                }
 -              return;
        }
 -
 -      if (self.items & IT_STRENGTH)
 +      else // if we're not in minstagib, continue. I added this else to replace the "return" which was here that broke the callhook for this function -- This code is nasty.
        {
 -              play_countdown(self.strength_finished, "misc/poweroff.wav");
 -              self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
 -              if (time > self.strength_finished && cvar("g_balance_powerup_timer"))
 +              if (self.items & IT_STRENGTH)
                {
 -                      self.items = self.items - (self.items & IT_STRENGTH);
 -                      sprint(self, "^3Strength has worn off\n");
 +                      play_countdown(self.strength_finished, "misc/poweroff.wav");
 +                      self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
 +                      if (time > self.strength_finished && cvar("g_balance_powerup_timer"))
 +                      {
 +                              self.items = self.items - (self.items & IT_STRENGTH);
 +                              sprint(self, "^3Strength has worn off\n");
 +                      }
                }
 -      }
 -      else
 -      {
 -              if (time < self.strength_finished)
 +              else
                {
 -                      self.items = self.items | IT_STRENGTH;
 -                      sprint(self, "^3Strength infuses your weapons with devastating power\n");
 +                      if (time < self.strength_finished)
 +                      {
 +                              self.items = self.items | IT_STRENGTH;
 +                              sprint(self, "^3Strength infuses your weapons with devastating power\n");
 +                      }
                }
 -      }
 -      if (self.items & IT_INVINCIBLE)
 -      {
 -              play_countdown(self.invincible_finished, "misc/poweroff.wav");
 -              self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
 -              if (time > self.invincible_finished && cvar("g_balance_powerup_timer"))
 +              if (self.items & IT_INVINCIBLE)
                {
 -                      self.items = self.items - (self.items & IT_INVINCIBLE);
 -                      sprint(self, "^3Shield has worn off\n");
 +                      play_countdown(self.invincible_finished, "misc/poweroff.wav");
 +                      self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
 +                      if (time > self.invincible_finished && cvar("g_balance_powerup_timer"))
 +                      {
 +                              self.items = self.items - (self.items & IT_INVINCIBLE);
 +                              sprint(self, "^3Shield has worn off\n");
 +                      }
                }
 -      }
 -      else
 -      {
 -              if (time < self.invincible_finished)
 +              else
                {
 -                      self.items = self.items | IT_INVINCIBLE;
 -                      sprint(self, "^3Shield surrounds you\n");
 +                      if (time < self.invincible_finished)
 +                      {
 +                              self.items = self.items | IT_INVINCIBLE;
 +                              sprint(self, "^3Shield surrounds you\n");
 +                      }
                }
 -      }
  
 -      if(cvar("g_nodepthtestplayers"))
 -              self.effects = self.effects | EF_NODEPTHTEST;
 +              if(cvar("g_nodepthtestplayers"))
 +                      self.effects = self.effects | EF_NODEPTHTEST;
  
 -      if(cvar("g_fullbrightplayers"))
 -              self.effects = self.effects | EF_FULLBRIGHT;
 +              if(cvar("g_fullbrightplayers"))
 +                      self.effects = self.effects | EF_FULLBRIGHT;
  
 -      // midair gamemode: damage only while in the air
 -      // if in midair mode, being on ground grants temporary invulnerability
 -      // (this is so that multishot weapon don't clear the ground flag on the
 -      // first damage in the frame, leaving the player vulnerable to the
 -      // remaining hits in the same frame)
 -      if (self.flags & FL_ONGROUND)
 -      if (g_midair)
 -              self.spawnshieldtime = max(self.spawnshieldtime, time + cvar("g_midair_shieldtime"));
 +              // midair gamemode: damage only while in the air
 +              // if in midair mode, being on ground grants temporary invulnerability
 +              // (this is so that multishot weapon don't clear the ground flag on the
 +              // first damage in the frame, leaving the player vulnerable to the
 +              // remaining hits in the same frame)
 +              if (self.flags & FL_ONGROUND)
 +              if (g_midair)
 +                      self.spawnshieldtime = max(self.spawnshieldtime, time + cvar("g_midair_shieldtime"));
  
 -      if (time >= game_starttime)
 -      if (time < self.spawnshieldtime)
 -              self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT);
 +              if (time >= game_starttime)
 +              if (time < self.spawnshieldtime)
 +                      self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT);
 +      }
 +      
 +      MUTATOR_CALLHOOK(PlayerPowerups);
  }
  
  float CalcRegen(float current, float stable, float regenfactor, float regenframetime)
index 765c7802d2a10707f29bff7b672ae99673e635ae,cb20a91a4f3eee6246a6b666ea7db291cae22556..b76e9a693471711b078c2690aaad753671ef1782
@@@ -455,7 -455,7 +455,7 @@@ void PlayerDamage (entity inflictor, en
        damage_take = take;
        damage_save = save;
        damage_force = force;
 -      MUTATOR_CALLHOOK(PlayerDamage);
 +      MUTATOR_CALLHOOK(PlayerDamage_SplitHealthArmor);
        take = bound(0, damage_take, self.health);
        save = bound(0, damage_save, self.armorvalue);
  
                float defer_ClientKill_Now_TeamChange;
                defer_ClientKill_Now_TeamChange = FALSE;
  
+               if(self.alivetime)
+               {
+                       PlayerStats_Event(self, PLAYERSTATS_ALIVETIME, time - self.alivetime);
+                       self.alivetime = 0;
+               }
                if(valid_damage_for_weaponstats)
                        WeaponStats_LogKill(DEATH_WEAPONOF(deathtype), self.weapon);
  
                        else
                                DropFlag(self.flagcarried, world, attacker);
                }
 -              if(self.ballcarried)
 +              if(self.ballcarried && g_nexball)
                        DropBall(self.ballcarried, self.origin, self.velocity);
                Portal_ClearAllLater(self);
                // clear waypoints
diff --combined qcsrc/server/defs.qh
index fc9523dd12ae54cb5b214961e1debbc4e8b5b376,6d967e656665c2a3f291cb68a716af60e8d3c000..cff78f1919ac0347c55eb3022d2912867f01bcae
@@@ -17,7 -17,7 +17,7 @@@ float require_spawnfunc_prefix; // if t
  
  float ctf_score_value(string parameter);
  
 -float g_dm, g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught, g_assault, g_arena, g_ca, g_lms, g_runematch, g_race, g_nexball, g_cts;
 +float g_dm, g_domination, g_ctf, g_tdm, g_keyhunt, g_onslaught, g_assault, g_arena, g_ca, g_lms, g_runematch, g_race, g_nexball, g_cts, g_keepaway;
  float g_cloaked, g_footsteps, g_jump_grunt, g_grappling_hook, g_midair, g_minstagib, g_pinata, g_norecoil, g_minstagib_invis_alpha, g_bloodloss;
  float g_warmup_limit;
  float g_warmup_allguns;
@@@ -263,7 -263,8 +263,8 @@@ float blockSpectators; //if set, new o
  void checkSpectatorBlock();
  
  .float winning;
- .float jointime;
+ .float jointime; // time of joining
+ .float alivetime; // time of being alive
  
  float isJoinAllowed();
  #define PREVENT_JOIN_TEXT "^1You may not join the game at this time.\n\nThe player limit reached maximum capacity."
@@@ -554,8 -555,8 +555,8 @@@ void target_voicescript_clear(entity pl
  .string target4;
  .float trigger_reverse;
  
 -// Nexball
 -.entity ballcarried;
 +// Nexball 
 +.entity ballcarried; // Also used for keepaway
  .float metertime;
  float g_nexball_meter_period;
  
diff --combined qcsrc/server/g_damage.qc
index 39188027c4b934df1723249b6e198d99e24047c0,cde87fec1791e028dc3b09e94f4fa4123d9912d4..b8c6d4cf04d397bcc326c2ca17c4c57c58ab2923
@@@ -120,12 -120,14 +120,14 @@@ void GiveFrags (entity attacker, entit
                {
                        // teamkill
                        PlayerScore_Add(attacker, SP_KILLS, -1); // or maybe add a teamkills field?
+                       PlayerStats_Event(attacker, PLAYERSTATS_KILLS, -1);
                }
        }
        else
        {
                // regular frag
                PlayerScore_Add(attacker, SP_KILLS, 1);
+               PlayerStats_Event(attacker, PLAYERSTATS_KILLS, 1);
        }
  
        PlayerScore_Add(targ, SP_DEATHS, 1);
@@@ -623,16 -625,7 +625,16 @@@ void Damage (entity targ, entity inflic
                        force = force * g_weaponforcefactor;
                        mirrorforce *= g_weaponforcefactor;
                }
 -
 +              
 +              // should this be changed at all? If so, in what way?
 +              frag_attacker = attacker;
 +              frag_target = targ;
 +              frag_damage = damage;
 +              frag_force = force;
 +              MUTATOR_CALLHOOK(PlayerDamage_Calculate);
 +              damage = frag_damage;
 +              force = frag_force;
 +              
                // apply strength multiplier
                if ((attacker.items & IT_STRENGTH) && !g_minstagib)
                {
diff --combined qcsrc/server/g_world.qc
index 473f5b6384494e24003c4bc54aca9b8f2301823a,1b9596909d5e072b0662e40fa0c36260165073c1..527f8117723797ce4b743b2691e932f9be7bea08
@@@ -329,7 -329,6 +329,7 @@@ void cvar_changes_init(
                BADCVAR("g_runematch");
                BADCVAR("g_tdm");
                BADCVAR("g_nexball");
 +              BADCVAR("g_keepaway");
                BADCVAR("teamplay");
  
                // long
@@@ -898,6 -897,8 +898,8 @@@ void spawnfunc_worldspawn (void
                cvar_set("sv_curl_serverpackages", substring(s, 1, -1));
        }
  
+       PlayerStats_Init();
        world_initialized = 1;
  }
  
@@@ -1398,12 -1399,13 +1400,13 @@@ RULE
  
  void DumpStats(float final)
  {
-       local float file;
-       local string s;
-       local float to_console;
-       local float to_eventlog;
-       local float to_file;
-       local float i;
+       float file;
+       string s;
+       float to_console;
+       float to_eventlog;
+       float to_file;
+       float i;
+       entity e;
  
        to_console = cvar("sv_logscores_console");
        to_eventlog = cvar("sv_eventlog");
                fputs(file, ":end\n");
                fclose(file);
        }
+       // send statistics
+       FOR_EACH_CLIENT(e)
+               PlayerStats_AddGlobalInfo(e);
+       PlayerStats_Shutdown();
  }
  
  void FixIntermissionClient(entity e)
@@@ -2719,6 -2726,10 +2727,10 @@@ void MapVote_Start(
        if(mapvote_run)
                return;
  
+       // wait for stats to be sent first
+       if(!playerstats_sent)
+               return;
        MapInfo_Enumerate();
        if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1))
                mapvote_run = TRUE;
@@@ -2893,6 -2904,8 +2905,8 @@@ void RestoreGame(
  
  void SV_Shutdown()
  {
+       entity e;
        if(gameover > 1) // shutting down already?
                return;
  
                world_initialized = 0;
                print("Saving persistent data...\n");
                Ban_SaveBans();
+               FOR_EACH_CLIENT(e)
+                       PlayerStats_AddGlobalInfo(e);
+               PlayerStats_Shutdown();
                if(!cheatcount_total)
                {
                        if(cvar("sv_db_saveasdump"))
diff --combined qcsrc/server/progs.src
index 1e6e057b2f7b030635be77885c6d305de3e13925,58cf66339003c0640f78c8deecef5236f9d3124e..9d40e069259afe3868d44ce74d706556d57754a0
@@@ -41,6 -41,7 +41,7 @@@ csqceffects.q
  
  anticheat.qh
  cheats.qh
+ playerstats.qh
  
  portals.qh
  
@@@ -176,10 -177,10 +177,11 @@@ playerdemo.q
  
  anticheat.qc
  cheats.qc
+ playerstats.qc
  
  mutators/base.qc
  mutators/gamemode_keyhunt.qc
 +mutators/gamemode_keepaway.qc
  mutators/mutator_nix.qc
  mutators/mutator_dodging.qc
  mutators/mutator_rocketflying.qc