Merge branch 'master' into terencehill/bot_waypoints
authorterencehill <piuntn@gmail.com>
Sat, 23 Dec 2017 17:51:09 +0000 (18:51 +0100)
committerterencehill <piuntn@gmail.com>
Sat, 23 Dec 2017 17:51:09 +0000 (18:51 +0100)
# Conflicts:
# qcsrc/common/triggers/trigger/jumppads.qc
# qcsrc/common/triggers/trigger/jumppads.qh

15 files changed:
minigames.cfg
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/common/gamemodes/gamemode/nexball/sv_weapon.qc
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/mutators/mutator/random_items/sv_random_items.qc
qcsrc/common/teams.qh
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/triggers/trigger/jumppads.qh
qcsrc/common/weapons/weapon/porto.qc
qcsrc/server/bot/default/bot.qc
qcsrc/server/client.qc
qcsrc/server/items.qc
qcsrc/server/items.qh
qcsrc/server/teamplay.qc
qcsrc/server/teamplay.qh

index 754eb0e67b4d57fd95922629fc2e29abd7ae003d..0cdd7a43113fb02ae640a61e7f9f7735953bfadb 100644 (file)
@@ -14,13 +14,5 @@ set sv_minigames_pong_ai_thinkspeed 0.1     "Seconds between AI actions"
 set sv_minigames_pong_ai_tolerance  0.33    "Distance of the ball relative to the paddle size"
 
 
-// Snake? Snake! SNAAAAKE!!
-set sv_minigames_snake_wrap 0 "Wrap around the edges of the screen instead of dying on touch"
-set sv_minigames_snake_delay_initial 0.7 "Initial delay between snake movement"
-set sv_minigames_snake_delay_multiplier 50 "Multiplier of incremental of movement speed (player_score / cvar)"
-set sv_minigames_snake_delay_min 0.1 "Minimum delay between snake movement (at fastest rate)"
-set sv_minigames_snake_lives 3
-
-
 // Bulldozer
 set sv_minigames_bulldozer_startlevel "level1"
index 063cb887f92d51a734ff4d3d740ce09fca7bece6..b52624b7026df8b2f7545ee9136e86690d68e087 100644 (file)
@@ -363,8 +363,8 @@ void Cmd_Scoreboard_Help()
 " -teams,rc,cts,inv,lms/kills +ft,tdm/kills ?+rc,inv/kills" \
 " -teams,lms/deaths +ft,tdm/deaths" \
 " -teams,lms,rc,cts,inv,ka/suicides +ft,tdm/suicides ?+rc,inv/suicides" \
-" +teams/teamkills"\
 " -cts,dm,tdm,ka,ft/frags" /* tdm already has this in "score" */ \
+" +tdm,ft,dom,ons,as/teamkills"\
 " -rc,cts,nb/dmg -rc,cts,nb/dmgtaken" \
 " +ctf/caps +ctf/pickups +ctf/fckills +ctf/returns +ons/caps +ons/takes" \
 " +lms/lives +lms/rank" \
index 705ac6d541ac4d828e98adee8aa291f2fccb0515..3568f221b63fe53fbc440a282cf037bc14a59e6f 100644 (file)
@@ -2,7 +2,7 @@
 
 void W_Nexball_Attack(entity actor, .entity weaponentity, float t);
 void W_Nexball_Attack2(entity actor, .entity weaponentity);
-vector trigger_push_calculatevelocity(vector org, entity tgt, float ht);
+vector trigger_push_calculatevelocity(vector org, entity tgt, float ht, entity pushed_entity);
 
 METHOD(BallStealer, wr_think, void(BallStealer thiswep, entity actor, .entity weaponentity, int fire))
 {
@@ -147,7 +147,7 @@ void W_Nexball_Attack2(entity actor, .entity weaponentity)
        {
                entity _ball = actor.ballcarried;
                W_SetupShot(actor, weaponentity, false, 4, SND_NB_SHOOT1, CH_WEAPON_A, 0);
-               DropBall(_ball, w_shotorg, trigger_push_calculatevelocity(_ball.origin, _ball.enemy, 32));
+               DropBall(_ball, w_shotorg, trigger_push_calculatevelocity(_ball.origin, _ball.enemy, 32, _ball));
                setthink(_ball, W_Nexball_Think);
                _ball.nextthink = time;
                return;
index 7462de81f2a03a37cccab8794fee8e884f6fec79..5eef8f2e37b4b49c96bce413c564cf2ebcbf9b28 100644 (file)
@@ -205,7 +205,7 @@ MUTATOR_HOOKFUNCTION(ok, OnEntityPreSpawn)
                        setorigin(wep, ent.origin);
                        setmodel(wep, MDL_OK_HMG);
                        wep.ok_item = true;
-                       wep.noalign = ent.noalign;
+                       wep.noalign = Item_ShouldKeepPosition(ent);
                        wep.cnt = ent.cnt;
                        wep.team = ent.team;
                        wep.respawntime = g_pickup_respawntime_superweapon;
@@ -221,7 +221,7 @@ MUTATOR_HOOKFUNCTION(ok, OnEntityPreSpawn)
                        setorigin(wep, ent.origin);
                        setmodel(wep, MDL_OK_RPC);
                        wep.ok_item = true;
-                       wep.noalign = ent.noalign;
+                       wep.noalign = Item_ShouldKeepPosition(ent);
                        wep.cnt = ent.cnt;
                        wep.team = ent.team;
                        wep.respawntime = g_pickup_respawntime_superweapon;
index 47234be290531e7d8a4966e313ac0f2bdb1acde7..3d305746269e1a29cbfb718ceb536175d04693af 100644 (file)
@@ -299,7 +299,7 @@ entity RandomItems_ReplaceMapItem(entity item)
        if (!expr_evaluate(autocvar_g_overkill))
        {
                new_item = Item_Create(strzone(new_classname), item.origin,
-                       item.noalign);
+                       Item_ShouldKeepPosition(item));
                random_items_is_spawning = false;
                if (new_item == NULL)
                {
@@ -311,7 +311,7 @@ entity RandomItems_ReplaceMapItem(entity item)
                new_item = spawn();
                new_item.classname = strzone(new_classname);
                new_item.spawnfunc_checked = true;
-               new_item.noalign = item.noalign;
+               new_item.noalign = Item_ShouldKeepPosition(item);
                new_item.ok_item = true;
                Item_Initialize(new_item, new_classname);
                random_items_is_spawning = false;
index 1f8a603dd01744b1dde6a4f13f98b5b32bb61d03..57d644c0448549e13bff834f7cb6fd289d983cc3 100644 (file)
@@ -125,6 +125,42 @@ float Team_ColorToTeam(string team_color)
        return -1;
 }
 
+/// \brief Returns whether team is valid.
+/// \param[in] team_ Team to check.
+/// \return True if team is valid, false otherwise.
+bool Team_IsValidTeam(int team_)
+{
+       switch (team_)
+       {
+               case NUM_TEAM_1:
+               case NUM_TEAM_2:
+               case NUM_TEAM_3:
+               case NUM_TEAM_4:
+               {
+                       return true;
+               }
+       }
+       return false;
+}
+
+/// \brief Returns whether team number is valid.
+/// \param[in] number Team number to check.
+/// \return True if team number is valid, false otherwise.
+bool Team_IsValidNumber(int number)
+{
+       switch (number)
+       {
+               case 1:
+               case 2:
+               case 3:
+               case 4:
+               {
+                       return true;
+               }
+       }
+       return false;
+}
+
 float Team_NumberToTeam(float number)
 {
        switch(number)
index 999a615cb7c9ac9b835cc275482720e06cbd76ac..d10a1e33037d69ae81b22943c8ab26ed8e5ffe63 100644 (file)
@@ -25,19 +25,20 @@ REGISTER_NET_LINKED(ENT_CLIENT_TARGET_PUSH)
          tgt - target entity (can be either a point or a model entity; if it is
                the latter, its midpoint is used)
          ht  - jump height, measured from the higher one of org and tgt's midpoint
+         pushed_entity - object that is to be pushed
 
        Returns: velocity for the jump
  */
-vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
+vector trigger_push_calculatevelocity(vector org, entity tgt, float ht, entity pushed_entity)
 {
        float grav, sdist, zdist, vs, vz, jumpheight;
        vector sdir, torg;
 
        torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
 
-       grav = PHYS_GRAVITY(tgt);
-       if(PHYS_ENTGRAVITY(tgt))
-               grav *= PHYS_ENTGRAVITY(tgt);
+       grav = PHYS_GRAVITY(NULL);
+       if(pushed_entity && PHYS_ENTGRAVITY(pushed_entity))
+               grav *= PHYS_ENTGRAVITY(pushed_entity);
 
        zdist = torg.z - org.z;
        sdist = vlen(torg - org - zdist * '0 0 1');
@@ -135,7 +136,7 @@ bool jumppad_push(entity this, entity targ)
 
        if(this.enemy)
        {
-               targ.velocity = trigger_push_calculatevelocity(targ.origin, this.enemy, this.height);
+               targ.velocity = trigger_push_calculatevelocity(targ.origin, this.enemy, this.height, targ);
        }
        else if(this.target && this.target != "")
        {
@@ -148,7 +149,7 @@ bool jumppad_push(entity this, entity targ)
                        else
                                RandomSelection_AddEnt(e, 1, 1);
                }
-               targ.velocity = trigger_push_calculatevelocity(targ.origin, RandomSelection_chosen_ent, this.height);
+               targ.velocity = trigger_push_calculatevelocity(targ.origin, RandomSelection_chosen_ent, this.height, targ);
        }
        else
        {
@@ -324,7 +325,7 @@ void trigger_push_findtarget(entity this)
                        entity e = spawn();
                        setsize(e, PL_MIN_CONST, PL_MAX_CONST);
                        e.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
-                       e.velocity = trigger_push_calculatevelocity(org, t, this.height);
+                       e.velocity = trigger_push_calculatevelocity(org, t, this.height, e);
                        vel = e.velocity;
                        vector best_target = '0 0 0';
                        vector best_org = '0 0 0';
@@ -348,7 +349,7 @@ void trigger_push_findtarget(entity this)
                                vector flatdir = normalize(dist - eZ * dist.z);
                                vector ofs = flatdir * 0.5 * min(fabs(this.absmax.x - this.absmin.x), fabs(this.absmax.y - this.absmin.y));
                                new_org = org + ofs;
-                               e.velocity = trigger_push_calculatevelocity(new_org, t, this.height);
+                               e.velocity = trigger_push_calculatevelocity(new_org, t, this.height, e);
                                vel = e.velocity;
                                if (vdist(vec2(e.velocity), <, autocvar_sv_maxspeed))
                                        e.velocity = autocvar_sv_maxspeed * flatdir;
@@ -360,7 +361,7 @@ void trigger_push_findtarget(entity this)
                                        valid_best_target = true;
                                }
                                new_org = org - ofs;
-                               e.velocity = trigger_push_calculatevelocity(new_org, t, this.height);
+                               e.velocity = trigger_push_calculatevelocity(new_org, t, this.height, e);
                                vel = e.velocity;
                                if (vdist(vec2(e.velocity), <, autocvar_sv_maxspeed))
                                        e.velocity = autocvar_sv_maxspeed * flatdir;
index a1260c4e5382fc2d5decb130a34e980bb38ac82f..c3b0b339def6c2f0f7b8e5c35f6773c91bcb4aea 100644 (file)
@@ -24,10 +24,11 @@ void trigger_push_use(entity this, entity actor, entity trigger);
          tgt - target entity (can be either a point or a model entity; if it is
                the latter, its midpoint is used)
          ht  - jump height, measured from the higher one of org and tgt's midpoint
+         pushed_entity - object that is to be pushed
 
        Returns: velocity for the jump
  */
-vector trigger_push_calculatevelocity(vector org, entity tgt, float ht);
+vector trigger_push_calculatevelocity(vector org, entity tgt, float ht, entity pushed_entity);
 
 void trigger_push_touch(entity this, entity toucher);
 
index 9738914644ceb482b3936d07c734c4cef9eda899..a134c03ab5cce4368ca971fce13701a3ed1de8d8 100644 (file)
@@ -45,7 +45,7 @@ void W_Porto_Fail(entity this, float failhard)
                {
                        this.flags = FL_ITEM;
                        IL_PUSH(g_items, this);
-                       this.velocity = trigger_push_calculatevelocity(this.origin, this.realowner, 128);
+                       this.velocity = trigger_push_calculatevelocity(this.origin, this.realowner, 128, this);
                        tracetoss(this, this);
                        if(vdist(trace_endpos - this.realowner.origin, <, 128))
                        {
index f599124db7bbb091e73b94bcbebc7cdfc4a0dbbc..20af7e71984dfdac24a5895ec91b7bf128f03b8b 100644 (file)
@@ -438,7 +438,7 @@ void bot_clientconnect(entity this)
        else if(this.bot_forced_team==4)
                this.team = NUM_TEAM_4;
        else
-               JoinBestTeam(this, false, true);
+               JoinBestTeam(this, true);
 
        havocbot_setupbot(this);
 }
index d2fae8b50b1f60350d5d37f88b2de72bdada324e..adfa40aeb6050de44535abf2368ba6dfe901f2ef 100644 (file)
@@ -507,7 +507,7 @@ void PutPlayerInServer(entity this)
        accuracy_resend(this);
 
        if (this.team < 0)
-               JoinBestTeam(this, false, true);
+               JoinBestTeam(this, true);
 
        entity spot = SelectSpawnPoint(this, false);
        if (!spot) {
@@ -877,7 +877,7 @@ void ClientKill_Now_TeamChange(entity this)
 {
        if(this.killindicator_teamchange == -1)
        {
-               JoinBestTeam( this, false, true );
+               JoinBestTeam( this, true );
        }
        else if(this.killindicator_teamchange == -2)
        {
@@ -1189,7 +1189,7 @@ void ClientConnect(entity this)
     {
         int id = this.playerid;
         this.playerid = 0; // silent
-           JoinBestTeam(this, false, false); // if the team number is valid, keep it
+           JoinBestTeam(this, false); // if the team number is valid, keep it
            this.playerid = id;
     }
 
@@ -2002,7 +2002,7 @@ void Join(entity this)
 
        if(!this.team_selected)
        if(autocvar_g_campaign || autocvar_g_balance_teams)
-               JoinBestTeam(this, false, true);
+               JoinBestTeam(this, true);
 
        if(autocvar_g_campaign)
                campaign_bots_may_start = true;
index 29a8609bc628530049fb3b11677599529d320b5b..7d248834f72566af97313317a42a3a50c226f637 100644 (file)
@@ -84,6 +84,11 @@ void Item_SetLoot(entity item, bool loot)
        item.m_isloot = loot;
 }
 
+bool Item_ShouldKeepPosition(entity item)
+{
+       return item.noalign || (item.spawnflags & 1);
+}
+
 bool Item_IsExpiring(entity item)
 {
        return item.m_isexpiring;
index af55eebd4d60e42c34505515b42d3fd85dd1b689..1abcf64e0879442a3b8ade446bc724ca8250e503 100644 (file)
@@ -51,6 +51,13 @@ bool Item_IsLoot(entity item);
 /// \return No return.
 void Item_SetLoot(entity item, bool loot);
 
+/// \brief Returns whether item should keep its position or be dropped to the
+/// ground.
+/// \param[in] item Item to check.
+/// \return True if item should keep its position or false if it should be
+/// dropped to the ground.
+bool Item_ShouldKeepPosition(entity item);
+
 /// \brief Returns whether the item is expiring (i.e. its strength, shield and
 /// superweapon timers expire while it is on the ground).
 /// \param[in] item Item to check.
index fd73969cb81a9d16cb88c55b02bee012cd0dfaa1..33ad8f8ed634f6123bf3a5c247eb83fad0dccf3d 100644 (file)
@@ -545,6 +545,14 @@ void GetTeamCounts(entity ignore)
 bool IsTeamSmallerThanTeam(int team_a, int team_b, entity player,
        bool use_score)
 {
+       if (!Team_IsValidNumber(team_a))
+       {
+               LOG_FATALF("IsTeamSmallerThanTeam: team_a is invalid: %f", team_a);
+       }
+       if (!Team_IsValidNumber(team_b))
+       {
+               LOG_FATALF("IsTeamSmallerThanTeam: team_b is invalid: %f", team_b);
+       }
        if (team_a == team_b)
        {
                return false;
@@ -642,6 +650,14 @@ bool IsTeamSmallerThanTeam(int team_a, int team_b, entity player,
 
 bool IsTeamEqualToTeam(int team_a, int team_b, entity player, bool use_score)
 {
+       if (!Team_IsValidNumber(team_a))
+       {
+               LOG_FATALF("IsTeamEqualToTeam: team_a is invalid: %f", team_a);
+       }
+       if (!Team_IsValidNumber(team_b))
+       {
+               LOG_FATALF("IsTeamEqualToTeam: team_b is invalid: %f", team_b);
+       }
        if (team_a == team_b)
        {
                return true;
@@ -837,53 +853,56 @@ int FindSmallestTeam(entity player, float ignore_player)
        return RandomSelection_chosen_float;
 }
 
-int JoinBestTeam(entity this, bool only_return_best, bool force_best_team)
+void JoinBestTeam(entity this, bool force_best_team)
 {
        // don't join a team if we're not playing a team game
        if (!teamplay)
        {
-               return 0;
+               return;
        }
 
        // find out what teams are available
        CheckAllowedTeams(this);
 
-       // if we don't care what team he ends up on, put him on whatever team he entered as.
-       // if he's not on a valid team, then let other code put him on the smallest team
+       // if we don't care what team they end up on, put them on whatever team they entered as.
+       // if they're not on a valid team, then let other code put them on the smallest team
        if (!force_best_team)
        {
                int selected_team;
-               if(     c1 >= 0 && this.team == NUM_TEAM_1)
+               if ((c1 >= 0) && (this.team == NUM_TEAM_1))
+               {
                        selected_team = this.team;
-               else if(c2 >= 0 && this.team == NUM_TEAM_2)
+               }
+               else if ((c2 >= 0) && (this.team == NUM_TEAM_2))
+               {
                        selected_team = this.team;
-               else if(c3 >= 0 && this.team == NUM_TEAM_3)
+               }
+               else if ((c3 >= 0) && (this.team == NUM_TEAM_3))
+               {
                        selected_team = this.team;
-               else if(c4 >= 0 && this.team == NUM_TEAM_4)
+               }
+               else if ((c4 >= 0) && (this.team == NUM_TEAM_4))
+               {
                        selected_team = this.team;
+               }
                else
+               {
                        selected_team = -1;
+               }
 
                if (selected_team > 0)
                {
-                       if (!only_return_best)
-                       {
-                               SetPlayerTeamSimple(this, selected_team);
-
-                               // when JoinBestTeam is called by client.qc/ClientKill_Now_TeamChange the players team is -1 and thus skipped
-                               // when JoinBestTeam is called by client.qc/ClientConnect the player_id is 0 the log attempt is rejected
-                               LogTeamchange(this.playerid, this.team, 99);
-                       }
-                       return selected_team;
+                       SetPlayerTeamSimple(this, selected_team);
+                       LogTeamchange(this.playerid, this.team, 99);
+                       return;
                }
-               // otherwise end up on the smallest team (handled below)
        }
-
-       int best_team = FindSmallestTeam(this, true);
-       if (only_return_best || this.bot_forced_team)
+       // otherwise end up on the smallest team (handled below)
+       if (this.bot_forced_team)
        {
-               return best_team;
+               return;
        }
+       int best_team = FindSmallestTeam(this, true);
        best_team = Team_NumberToTeam(best_team);
        if (best_team == -1)
        {
@@ -893,12 +912,11 @@ int JoinBestTeam(entity this, bool only_return_best, bool force_best_team)
        TeamchangeFrags(this);
        SetPlayerTeamSimple(this, best_team);
        LogTeamchange(this.playerid, this.team, 2); // log auto join
-       if (!IS_BOT_CLIENT(this))
+       if ((old_team != -1) && !IS_BOT_CLIENT(this))
        {
                AutoBalanceBots(old_team, Team_TeamToNumber(best_team));
        }
        KillPlayerForTeamChange(this);
-       return best_team;
 }
 
 void SV_ChangeTeam(entity this, float _color)
@@ -978,8 +996,15 @@ void SV_ChangeTeam(entity this, float _color)
 
 void AutoBalanceBots(int source_team, int destination_team)
 {
-       if ((source_team == -1) || (destination_team == -1))
+       if (!Team_IsValidNumber(source_team))
+       {
+               LOG_WARNF("AutoBalanceBots: Source team is invalid: %f", source_team);
+               return;
+       }
+       if (!Team_IsValidNumber(destination_team))
        {
+               LOG_WARNF("AutoBalanceBots: Destination team is invalid: %f",
+                       destination_team);
                return;
        }
        if (!autocvar_g_balance_teams ||
@@ -1013,6 +1038,10 @@ void AutoBalanceBots(int source_team, int destination_team)
                        break;
                }
        }
+       if (num_players_source_team < 0)
+       {
+               return;
+       }
        switch (destination_team)
        {
                case 1:
index 1813db04d8d111387a6a1667c6033e9b2e890f6c..7c4ebe77b6c2a82a51ae2949999734d5da4022e8 100644 (file)
@@ -107,7 +107,7 @@ int FindBestTeams(entity player, bool use_score);
 // NOTE: Assumes CheckAllowedTeams has already been called!
 int FindSmallestTeam(entity player, float ignore_player);
 
-int JoinBestTeam(entity this, bool only_return_best, bool force_best_team);
+void JoinBestTeam(entity this, bool force_best_team);
 
 /// \brief Auto balances bots in teams after the player has changed team.
 /// \param[in] source_team Previous team of the player (1, 2, 3, 4).