Merge branch 'fruitiex/xpm' into fruitiex/ctsfix
authorFruitieX <fruitiex@gmail.com>
Sun, 12 Dec 2010 10:57:56 +0000 (12:57 +0200)
committerFruitieX <fruitiex@gmail.com>
Sun, 12 Dec 2010 10:57:56 +0000 (12:57 +0200)
26 files changed:
balanceXonotic.cfg
defaultXonotic.cfg
gfx/hud/default/weaponminelayer.tga
gfx/hud/luminos/weaponminelayer.tga
gfx/hud/old/weaponminelayer.tga
gfx/winner.tga
models/sprites/make-sprites.sh
models/sprites/wpn-minelayer_frame0.tga [new file with mode: 0644]
qcsrc/client/scoreboard.qc
qcsrc/client/waypointsprites.qc
qcsrc/common/items.qc
qcsrc/server/autocvars.qh
qcsrc/server/bot/havocbot/role_onslaught.qc
qcsrc/server/cl_client.qc
qcsrc/server/cl_physics.qc
qcsrc/server/cl_player.qc
qcsrc/server/cl_weapons.qc
qcsrc/server/clientcommands.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/race.qc
qcsrc/server/t_items.qc
qcsrc/server/t_quake3.qc
qcsrc/server/teamplay.qc
qcsrc/server/w_seeker.qc

index def0f54..7228328 100644 (file)
@@ -99,7 +99,7 @@ set g_pickup_respawntime_short 15
 set g_pickup_respawntime_medium 20
 set g_pickup_respawntime_long 30
 set g_pickup_respawntime_powerup 120
-set g_pickup_respawntime_weapon 5
+set g_pickup_respawntime_weapon 10
 set g_pickup_respawntime_ammo 25
 set g_pickup_respawntimejitter_short 0
 set g_pickup_respawntimejitter_medium 0
@@ -294,7 +294,7 @@ set g_balance_uzi_bulletconstant 115 // 13.1qu
 // }}}
 // {{{ mortar
 set g_balance_grenadelauncher_primary_type 0
-set g_balance_grenadelauncher_primary_damage 50
+set g_balance_grenadelauncher_primary_damage 44
 set g_balance_grenadelauncher_primary_edgedamage 32
 set g_balance_grenadelauncher_primary_force 300
 set g_balance_grenadelauncher_primary_radius 115
@@ -312,7 +312,7 @@ set g_balance_grenadelauncher_primary_damageforcescale 0
 set g_balance_grenadelauncher_primary_remote_minbouncecnt 0
 
 set g_balance_grenadelauncher_secondary_type 1
-set g_balance_grenadelauncher_secondary_damage 70
+set g_balance_grenadelauncher_secondary_damage 62
 set g_balance_grenadelauncher_secondary_edgedamage 32
 set g_balance_grenadelauncher_secondary_force 300
 set g_balance_grenadelauncher_secondary_radius 150
@@ -333,7 +333,7 @@ set g_balance_grenadelauncher_bouncefactor 0.5
 set g_balance_grenadelauncher_bouncestop 0.12
 // }}}
 // {{{ minelayer
-set g_balance_minelayer_damage 35
+set g_balance_minelayer_damage 42
 set g_balance_minelayer_edgedamage 30
 set g_balance_minelayer_force 250
 set g_balance_minelayer_radius 175
@@ -452,7 +452,7 @@ set g_balance_crylink_secondary_line_lifetime 2 // range: 4000 full, fades to 80
 set g_balance_crylink_secondary_line_fadetime 2
 // }}}
 // {{{ nex
-set g_balance_nex_primary_damage 100
+set g_balance_nex_primary_damage 90
 set g_balance_nex_primary_force 500
 set g_balance_nex_primary_refire 1
 set g_balance_nex_primary_animtime 0.4
@@ -519,10 +519,10 @@ set g_balance_hagar_secondary_refire 0.12
 set g_balance_hagar_secondary_ammo 1
 // }}}
 // {{{ rocketlauncher
-set g_balance_rocketlauncher_damage 90
-set g_balance_rocketlauncher_edgedamage 30
+set g_balance_rocketlauncher_damage 82
+set g_balance_rocketlauncher_edgedamage 32
 set g_balance_rocketlauncher_force 350
-set g_balance_rocketlauncher_radius 125
+set g_balance_rocketlauncher_radius 130
 set g_balance_rocketlauncher_speed 1400
 set g_balance_rocketlauncher_speedaccel 1400
 set g_balance_rocketlauncher_speedstart 800
@@ -533,7 +533,7 @@ set g_balance_rocketlauncher_ammo 3
 set g_balance_rocketlauncher_health 0
 set g_balance_rocketlauncher_damageforcescale 0
 set g_balance_rocketlauncher_detonatedelay 0.05 // positive: timer till detonation is allowed, negative: "security device" that prevents ANY remote detonation if it could hurt its owner, zero: detonatable at any time
-set g_balance_rocketlauncher_guiderate 40 // max degrees per second
+set g_balance_rocketlauncher_guiderate 42 // max degrees per second
 set g_balance_rocketlauncher_guideratedelay 0.01 // immediate
 set g_balance_rocketlauncher_guidegoal 512 // goal distance for (non-laser) guiding (higher = less control, lower = erratic)
 set g_balance_rocketlauncher_guidedelay 0.15 // delay before guiding kicks in
@@ -610,8 +610,8 @@ set g_balance_campingrifle_reloadtime 2 // matches reload anim
 set g_balance_campingrifle_auto_reload_on_switch 0
 set g_balance_campingrifle_bursttime 0
 set g_balance_campingrifle_primary_tracer 1
-set g_balance_campingrifle_primary_damage 70
-set g_balance_campingrifle_primary_headshotaddeddamage 110
+set g_balance_campingrifle_primary_damage 60
+set g_balance_campingrifle_primary_headshotaddeddamage 100
 set g_balance_campingrifle_primary_spread 0
 set g_balance_campingrifle_primary_force 2
 set g_balance_campingrifle_primary_speed 40000
@@ -624,8 +624,8 @@ set g_balance_campingrifle_primary_burstcost 0
 set g_balance_campingrifle_primary_bullethail 0 // empty magazine on shot
 set g_balance_campingrifle_secondary 1
 set g_balance_campingrifle_secondary_tracer 0
-set g_balance_campingrifle_secondary_damage 50
-set g_balance_campingrifle_secondary_headshotaddeddamage 75
+set g_balance_campingrifle_secondary_damage 42
+set g_balance_campingrifle_secondary_headshotaddeddamage 70
 set g_balance_campingrifle_secondary_spread 0
 set g_balance_campingrifle_secondary_force 2
 set g_balance_campingrifle_secondary_speed 20000
index f591fe3..51eff15 100644 (file)
@@ -596,40 +596,56 @@ set g_respawn_waves 0 "respawn in waves (every n seconds), intended to decrease
 // to force disable delay or waves, set them to 0.125
 set g_ctf_respawn_delay 0
 set g_ctf_respawn_waves 0
+set g_ctf_weapon_stay 1
 set g_dm_respawn_delay 0
 set g_dm_respawn_waves 0
+set g_dm_weapon_stay 0
 set g_dom_respawn_delay 0
 set g_dom_respawn_waves 0
+set g_dom_weapon_stay 0
 set g_lms_respawn_delay 0
 set g_lms_respawn_waves 0
+set g_lms_weapon_stay 0
 set g_rune_respawn_delay 0
 set g_rune_respawn_waves 0
+set g_rune_weapon_stay 0
 set g_tdm_respawn_delay 0
 set g_tdm_respawn_waves 0
+set g_tdm_weapon_stay 0
 set g_kh_respawn_delay 0
 set g_kh_respawn_waves 0
+set g_kh_weapon_stay 0
 set g_arena_respawn_delay 0
 set g_arena_respawn_waves 0
+set g_arena_weapon_stay 0
 set g_ca_respawn_delay 0
 set g_ca_respawn_waves 0
+set g_ca_weapon_stay 0
 set g_ca_damage2score_multiplier 0.01
 set g_ca_round_timelimit 180
 set g_nexball_respawn_delay 0
 set g_nexball_respawn_waves 0
+set g_nexball_weapon_stay 0
 set g_as_respawn_delay 0
 set g_as_respawn_waves 0
+set g_as_weapon_stay 1
 set g_ons_respawn_delay 0
 set g_ons_respawn_waves 0
+set g_ons_weapon_stay 0
 set g_rc_respawn_waves 0
 set g_rc_respawn_delay 0
+set g_rc_weapon_stay 0
 set g_cts_respawn_waves 0
-set g_cts_respawn_delay 0.25
+set g_cts_respawn_delay 0
 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_cts_weapon_stay 1
 set g_freezetag_respawn_waves 0
-set g_freezetag_respawn_delay 0.25
+set g_freezetag_respawn_delay 0
+set g_freezetag_weapon_stay 1
 set g_ka_respawn_delay 0
 set g_ka_respawn_waves 0
+set g_ka_weapon_stay 0
 
 // overtime
 seta timelimit_overtime 2 "duration in minutes of one added overtime, added to the timelimit"
@@ -1538,7 +1554,8 @@ sv_gameplayfix_q2airaccelerate 1
 sv_gameplayfix_stepmultipletimes 1
 
 // delay for "kill" to prevent abuse
-set g_balance_kill_delay 5
+set g_balance_kill_delay 2
+set g_balance_kill_antispam 5
 
 // this feature is currently buggy in the engine (it appears to PREVENT any dropping in lots of maps, leading to weirdly aligned entities, and in some cases even CAUSES them to drop through solid, like in facing worlds nex)
 sv_gameplayfix_droptofloorstartsolid 0
index 3fbccf9..4e31286 100644 (file)
Binary files a/gfx/hud/default/weaponminelayer.tga and b/gfx/hud/default/weaponminelayer.tga differ
index 3fbccf9..4e31286 100644 (file)
Binary files a/gfx/hud/luminos/weaponminelayer.tga and b/gfx/hud/luminos/weaponminelayer.tga differ
index 444247f..0c82a48 100644 (file)
Binary files a/gfx/hud/old/weaponminelayer.tga and b/gfx/hud/old/weaponminelayer.tga differ
index 70bb566..c713a85 100644 (file)
Binary files a/gfx/winner.tga and b/gfx/winner.tga differ
index 50131ee..87f24a6 100644 (file)
@@ -189,6 +189,7 @@ sprite wpn-hookgun        "Hook"          008000 000000 0.0 # dark green
 sprite wpn-fireball       "Fireball"      ff8000 000000 0.0 # orange
 sprite wpn-hlac           "HLAC"          00ff00 000000 0.0 # green
 sprite wpn-campingrifle   "Rifle"         80ff00 000000 0.0 # orange
+sprite wpn-minelayer      "Mine Layer"    ccff00 000000 0.0 # yellowish orange
 
 sprite dom-neut           "Control point" 00ffff 000000 0.0
 sprite dom-red            "Control point" ff0000 000000 0.0
diff --git a/models/sprites/wpn-minelayer_frame0.tga b/models/sprites/wpn-minelayer_frame0.tga
new file mode 100644 (file)
index 0000000..b2d2905
Binary files /dev/null and b/models/sprites/wpn-minelayer_frame0.tga differ
index 502c448..31cdc45 100644 (file)
@@ -883,8 +883,10 @@ float HUD_WouldDrawScoreboard() {
                return 1;
        else if (intermission == 1)
                return 1;
-       else if (getstati(STAT_HEALTH) <= 0 && autocvar_cl_deathscoreboard)
+       else if (getstati(STAT_HEALTH) <= 0 && autocvar_cl_deathscoreboard && gametype != GAME_CTS)
                return 1;
+    else if (spectatee_status == -1)
+        return 1;
        else if (scoreboard_showscores_force)
                return 1;
        return 0;
index fad229f..2cd5078 100644 (file)
@@ -425,6 +425,7 @@ void WaypointSprite_Load()
        waypointsprite_distancefadealpha = autocvar_g_waypointsprite_distancefadealpha;
        waypointsprite_distancefadescale = autocvar_g_waypointsprite_distancefadescale;
        waypointsprite_distancefadedistance = waypointsprite_fadedistance * autocvar_g_waypointsprite_distancefadedistancemultiplier;
+       waypointsprite_alpha = autocvar_g_waypointsprite_alpha;
 
        if(!waypointsprite_initialized)
        {
index 37ffb25..5387c05 100644 (file)
@@ -1,5 +1,5 @@
 // WEAPON PLUGIN SYSTEM
-entity weapon_info[24];
+entity weapon_info[WEP_MAXCOUNT];
 entity dummy_weapon_info;
 
 void register_weapon(float id, float(float) func, float ammotype, float i, float weapontype, float pickupbasevalue, string modelname, string shortname, string wname)
@@ -43,7 +43,7 @@ void register_weapons_done()
 
        float i;
        weaponorder_byid = "";
-       for(i = 24; i >= 1; --i)
+       for(i = WEP_MAXCOUNT; i >= 1; --i)
                if(weapon_info[i-1])
                        weaponorder_byid = strcat(weaponorder_byid, " ", ftos(i));
        weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
index eb344da..c5beab2 100644 (file)
@@ -382,6 +382,7 @@ float autocvar_g_balance_keyhunt_score_destroyed_ownfactor;
 float autocvar_g_balance_keyhunt_score_push;
 float autocvar_g_balance_keyhunt_throwvelocity;
 float autocvar_g_balance_kill_delay;
+float autocvar_g_balance_kill_antispam;
 float autocvar_g_balance_laser_primary_animtime;
 float autocvar_g_balance_laser_primary_damage;
 float autocvar_g_balance_laser_primary_delay;
@@ -1028,6 +1029,8 @@ float autocvar_g_weapon_throwable;
 string autocvar_g_xonoticversion;
 float autocvar_gamecfg;
 float autocvar_gameversion;
+float autocvar_gameversion_min;
+float autocvar_gameversion_max;
 string autocvar_hostname;
 float autocvar_lastlevel;
 float autocvar_leadlimit;
@@ -1083,6 +1086,7 @@ float autocvar_sv_dodging_sound;
 float autocvar_sv_dodging_up_speed;
 float autocvar_sv_dodging_wall_distance_threshold;
 float autocvar_sv_dodging_wall_dodging;
+float autocvar_sv_doublejump;
 float autocvar_sv_eventlog;
 float autocvar_sv_eventlog_console;
 float autocvar_sv_eventlog_files;
index af6eeb6..bc84340 100644 (file)
@@ -35,7 +35,7 @@ void havocbot_goalrating_ons_offenseitems(float ratingscale, vector org, float s
                needarmor = TRUE;
 
        // Needs weapons?
-       for(i = WEP_FIRST; i < WEP_LAST ; ++i)
+       for(i = WEP_FIRST; i <= WEP_LAST ; ++i)
        {
                // Find weapon
                if(power2of(i-1) & self.weapons)
index 5ff519b..ba6c2e5 100644 (file)
@@ -1222,6 +1222,7 @@ Called when a client types 'kill' in the console
 =============
 */
 
+.float clientkill_nexttime;
 void ClientKill_Now_TeamChange()
 {
        if(self.killindicator_teamchange == -1)
@@ -1229,6 +1230,14 @@ void ClientKill_Now_TeamChange()
                self.team = -1;
                JoinBestTeam( self, FALSE, FALSE );
        }
+       else if(self.killindicator_teamchange == -2)
+       {
+               if(g_ca)
+                       self.caplayer = 0;
+               if(blockSpectators)
+                       sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
+               PutObserverInServer();
+       }
        else
                SV_ChangeTeam(self.killindicator_teamchange - 1);
 }
@@ -1263,6 +1272,11 @@ void KillIndicator_Think()
                ClientKill_Now(); // no oldself needed
                return;
        }
+    else if(g_cts && self.health == 1) // health == 1 means that it's silent
+    {
+        self.nextthink = time + 1;
+        self.cnt -= 1;
+    }
        else
        {
                if(self.cnt <= 10)
@@ -1275,6 +1289,8 @@ void KillIndicator_Think()
                        {
                                if(self.owner.killindicator_teamchange == -1)
                                        centerprint(self.owner, strcat("Changing team in ", ftos(self.cnt), " seconds"));
+                               else if(self.owner.killindicator_teamchange == -2)
+                                       centerprint(self.owner, strcat("Spectating in ", ftos(self.cnt), " seconds"));
                                else
                                        centerprint(self.owner, strcat("Changing to ", ColoredTeamName(self.owner.killindicator_teamchange), " in ", ftos(self.cnt), " seconds"));
                        }
@@ -1286,19 +1302,25 @@ void KillIndicator_Think()
        }
 }
 
-void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto
+void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 = spec
 {
        float killtime;
        entity e;
        killtime = autocvar_g_balance_kill_delay;
 
-       if(g_race_qualifying)
+       if(g_race_qualifying || g_cts)
                killtime = 0;
 
        self.killindicator_teamchange = targetteam;
 
-       if(!self.killindicator)
+    if(!self.killindicator)
        {
+               if(self.modelindex && self.deadflag == DEAD_NO)
+               {
+                       killtime = max(killtime, self.clientkill_nexttime - time);
+                       self.clientkill_nexttime = time + killtime + autocvar_g_balance_kill_antispam;
+               }
+
                if(killtime <= 0 || !self.modelindex || self.deadflag != DEAD_NO)
                {
                        ClientKill_Now();
@@ -1334,10 +1356,14 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto
        }
        if(self.killindicator)
        {
-               if(targetteam)
-                       self.killindicator.colormod = TeamColor(targetteam);
-               else
+               if(targetteam == 0) // just die
                        self.killindicator.colormod = '0 0 0';
+               else if(targetteam == -1) // auto
+                       self.killindicator.colormod = '0 1 0';
+               else if(targetteam == -2) // spectate
+                       self.killindicator.colormod = '0.5 0.5 0.5';
+               else
+                       self.killindicator.colormod = TeamColor(targetteam);
        }
 }
 
@@ -1355,20 +1381,15 @@ void ClientKill (void)
                ClientKill_TeamChange(0);
 }
 
-void CTS_ClientKill_Think (void)
-{
-       self = self.owner; // set self to the player to be killed
-       sprint(self, "^1You were killed in order to prevent cheating!");
-       ClientKill_Now();
-}
-
-void CTS_ClientKill (float t) // silent version of ClientKill
+void CTS_ClientKill (entity e) // silent version of ClientKill
 {
-       entity e;
-       e = spawn();
-       e.owner = self;
-       e.think = CTS_ClientKill_Think;
-       e.nextthink = t;
+    e.killindicator = spawn();
+    e.killindicator.owner = e;
+    e.killindicator.think = KillIndicator_Think;
+    e.killindicator.nextthink = time + (e.lip) * 0.05;
+    e.killindicator.cnt = ceil(autocvar_g_cts_finish_kill_delay);
+    e.killindicator.health = 1; // this is used to indicate that it should be silent
+    e.lip = 0;
 }
 
 void DoTeamChange(float destteam)
@@ -2718,7 +2739,7 @@ void PlayerPreThink (void)
                                if(frametime)
                                        player_anim();
                                button_pressed = (self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE);
-                               force_respawn = (g_lms || (g_ca) || autocvar_g_forced_respawn);
+                               force_respawn = (g_lms || g_ca || g_cts || autocvar_g_forced_respawn);
                                if (self.deadflag == DEAD_DYING)
                                {
                                        if(force_respawn)
index ed459ae..e2feca9 100644 (file)
@@ -30,7 +30,7 @@ void PlayerJump (void)
        float doublejump;
 
        doublejump = FALSE;
-       if (sv_doublejump)
+       if (autocvar_sv_doublejump)
        {
                tracebox(self.origin + '0 0 0.01', self.mins, self.maxs, self.origin - '0 0 0.01', MOVE_NORMAL, self);
                if (trace_fraction < 1 && trace_plane_normal_z > 0.7)
index 27bd209..9fa4784 100644 (file)
@@ -669,7 +669,12 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, float deatht
                waves = 0;
                sdelay = cvar(strcat("g_", GetGametype(), "_respawn_delay"));
                if(!sdelay)
-                       sdelay = autocvar_g_respawn_delay;
+        {
+            if(g_cts)
+                sdelay = 0; // no respawn delay in CTS
+            else
+                sdelay = autocvar_g_respawn_delay;
+        }
                waves = cvar(strcat("g_", GetGametype(), "_respawn_waves"));
                if(!waves)
                        waves = autocvar_g_respawn_waves;
index db79588..cfe0126 100644 (file)
@@ -275,6 +275,8 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce)
                return;
        if (g_ca)
                return;
+    if (g_cts)
+        return;
        if(!autocvar_g_weapon_throwable)
                return;
        if(autocvar_g_weapon_stay == 1)
index 92e4b8a..adaf36f 100644 (file)
@@ -164,11 +164,10 @@ void SV_ParseClientCommand(string s) {
                } else {
                        self.version = stof(argv(1));
                }
-               if(self.version != autocvar_gameversion)
+               if(self.version < autocvar_gameversion_min || self.version > autocvar_gameversion_max)
                {
-                       self.classname = "observer";
                        self.version_mismatch = 1;
-                       PutClientInServer();
+                       ClientKill_TeamChange(-2); // observe
                } else if(autocvar_g_campaign || autocvar_g_balance_teams || autocvar_g_balance_teams_force) {
                        //JoinBestTeam(self, FALSE, TRUE);
                } else if(teams_matter && !autocvar_sv_spectate && !(self.team_forced > 0)) {
@@ -211,17 +210,7 @@ void SV_ParseClientCommand(string s) {
                        }
                }
                if(self.classname == "player" && autocvar_sv_spectate == 1) {
-                       if(self.flagcarried)
-                               DropFlag(self.flagcarried, world, world);
-                       if(self.ballcarried && g_nexball)
-                               DropBall(self.ballcarried, self.origin, self.velocity);
-                       WaypointSprite_PlayerDead();
-                       self.classname = "observer";
-                       if(g_ca)
-                               self.caplayer = 0;
-                       if(blockSpectators)
-                               sprint(self, strcat("^7You have to become a player within the next ", ftos(autocvar_g_maxplayers_spectator_blocktime), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));
-                       PutClientInServer();
+                       ClientKill_TeamChange(-2); // observe
                }
        } else if(cmd == "join") {
                if not(self.flags & FL_CLIENT)
@@ -256,15 +245,15 @@ void SV_ParseClientCommand(string s) {
                } else if(lockteams) {
                        sprint( self, "^7The game has already begun, you must wait until the next map to be able to join a team.\n");
                } else if( argv(1) == "red" ) {
-                       DoTeamChange(COLOR_TEAM1);
+                       ClientKill_TeamChange(COLOR_TEAM1);
                } else if( argv(1) == "blue" ) {
-                       DoTeamChange(COLOR_TEAM2);
+                       ClientKill_TeamChange(COLOR_TEAM2);
                } else if( argv(1) == "yellow" ) {
-                       DoTeamChange(COLOR_TEAM3);
+                       ClientKill_TeamChange(COLOR_TEAM3);
                } else if( argv(1) == "pink" ) {
-                       DoTeamChange(COLOR_TEAM4);
+                       ClientKill_TeamChange(COLOR_TEAM4);
                } else if( argv(1) == "auto" ) {
-                       DoTeamChange(-1);
+                       ClientKill_TeamChange(-1);
                } else {
                        sprint( self, strcat( "selectteam none/red/blue/yellow/pink/auto - \"", argv(1), "\" not recognised\n" ) );
                }
index c9a7e61..76ce748 100644 (file)
@@ -427,7 +427,6 @@ float sv_maxidle;
 float sv_maxidle_spectatorsareidle;
 
 float sv_pogostick;
-float sv_doublejump;
 float tracebox_hits_trigger_hurt(vector start, vector mi, vector ma, vector end);
 
 float next_pingtime;
index f064e53..6ab2900 100644 (file)
@@ -295,7 +295,8 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
                {
                        if (deathtype == DEATH_TEAMCHANGE || deathtype == DEATH_AUTOTEAMCHANGE)
                                msg = ColoredTeamName(targ.team); // TODO: check if needed?
-                       Send_CSQC_Centerprint(targ, msg, "", deathtype, MSG_SUICIDE);
+            if(!g_cts) // no "killed your own dumb self" message in CTS
+                Send_CSQC_Centerprint(targ, msg, "", deathtype, MSG_SUICIDE);
 
                        if(deathtype != DEATH_TEAMCHANGE && deathtype != DEATH_QUIET)
                        {
index 8e052e8..225a345 100644 (file)
@@ -880,8 +880,10 @@ float want_weapon(string cvarprefix, entity weaponinfo, float allguns)
                        t = (weaponinfo.spawnflags & WEP_FLAG_NORMAL);
                else if(t < -1)
                        t = 0;
-               else if (g_race || g_cts)
-                       t = (i == WEP_LASER);
+               else if (g_race)
+                       t = (i == WEP_LASER || i == WEP_SHOTGUN);
+               else if (g_cts)
+                       t = (i == WEP_SHOTGUN);
                else if (g_nexball)
                        t = 0; // weapon is set a few lines later
                else
@@ -981,16 +983,23 @@ void readplayerstartcvars()
        if (g_weaponarena)
        {
                start_weapons = g_weaponarena;
-               if (g_weaponarena & (WEPBIT_GRENADE_LAUNCHER | WEPBIT_MINE_LAYER | WEPBIT_HAGAR | WEPBIT_ROCKET_LAUNCHER))
-                       start_ammo_rockets = 999;
-               if (g_weaponarena & WEPBIT_SHOTGUN)
-                       start_ammo_shells = 999;
-               if (g_weaponarena & (WEPBIT_ELECTRO | WEPBIT_CRYLINK | WEPBIT_NEX | WEPBIT_MINSTANEX | WEPBIT_HLAC | WEPBIT_HOOK))
-                       start_ammo_cells = 999;
-               if (g_weaponarena & (WEPBIT_UZI | WEPBIT_CAMPINGRIFLE))
-                       start_ammo_nails = 999;
-               if (g_weaponarena & WEPBIT_HOOK)
-                       start_ammo_fuel = 999;
+               for (j = WEP_FIRST; j <= WEP_LAST; ++j)
+               {
+                       e = get_weaponinfo(j);
+                       if(start_weapons & e.weapons)
+                       {
+                               if(e.items & IT_ROCKETS)
+                                       start_ammo_rockets = 999;
+                               if(e.items & IT_SHELLS)
+                                       start_ammo_shells = 999;
+                               if(e.items & IT_CELLS)
+                                       start_ammo_cells = 999;
+                               if(e.items & IT_NAILS)
+                                       start_ammo_nails = 999;
+                               if(e.items & IT_FUEL)
+                                       start_ammo_fuel = 999;
+                       }
+               }
                start_items |= IT_UNLIMITED_AMMO;
        }
        else if (g_minstagib)
@@ -1207,6 +1216,8 @@ void readlevelcvars(void)
        sv_gentle = cvar("sv_gentle");
        sv_foginterval = cvar("sv_foginterval");
        g_cloaked = cvar("g_cloaked");
+    if(g_cts)
+        g_cloaked = 1; // always enable cloak in CTS
        g_jump_grunt = cvar("g_jump_grunt");
        g_footsteps = cvar("g_footsteps");
        g_grappling_hook = cvar("g_grappling_hook");
@@ -1290,7 +1301,9 @@ void readlevelcvars(void)
 
        g_pinata = cvar("g_pinata");
 
-       g_weapon_stay = cvar("g_weapon_stay");
+    g_weapon_stay = cvar(strcat("g_", GetGametype(), "_weapon_stay"));
+    if(!g_weapon_stay)
+        g_weapon_stay = cvar("g_weapon_stay");
 
        if (!g_weapon_stay && (cvar("deathmatch") == 2))
                g_weapon_stay = 1;
@@ -1743,6 +1756,14 @@ void objerror(string s)
     objerror_builtin(s);
 }
 
+.float remove_except_protected_forbidden;
+void remove_except_protected(entity e)
+{
+       if(e.remove_except_protected_forbidden)
+               error("not allowed to remove this at this point");
+       remove_builtin(e);
+}
+
 void remove_unsafely(entity e)
 {
     remove_builtin(e);
@@ -1793,6 +1814,11 @@ void InitializeEntitiesRun()
     entity startoflist;
     startoflist = initialize_entity_first;
     initialize_entity_first = world;
+    remove = remove_except_protected;
+    for (self = startoflist; self; self = self.initialize_entity_next)
+    {
+       self.remove_except_protected_forbidden = 1;
+    }
     for (self = startoflist; self; )
     {
         entity e;
@@ -1802,6 +1828,7 @@ void InitializeEntitiesRun()
         self.initialize_entity_order = 0;
         self.initialize_entity = func_null;
         self.initialize_entity_next = world;
+       self.remove_except_protected_forbidden = 0;
         if (self.classname == "initialize_entity")
         {
             entity e_old;
@@ -1810,9 +1837,16 @@ void InitializeEntitiesRun()
             self = e_old;
         }
         //dprint("Delayed initialization: ", self.classname, "\n");
-        func();
+        if(func != func_null)
+            func();
+        else
+        {
+            eprint(self);
+            backtrace(strcat("Null function in: ", self.classname, "\n"));
+        }
         self = e;
     }
+    remove = remove_unsafely;
 }
 
 .float uncustomizeentityforclient_set;
index 80a379a..9817b3b 100644 (file)
@@ -308,7 +308,7 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
                                        race_setTime(GetMapname(), t, e.crypto_idfp, e.netname, e);
                                        if(g_cts && autocvar_g_cts_finish_kill_delay)
                                        {
-                                               CTS_ClientKill(autocvar_g_cts_finish_kill_delay);
+                                               CTS_ClientKill(e);
                                        }
                                }
                                if(t < recordtime || recordtime == 0)
@@ -742,11 +742,21 @@ void trigger_race_checkpoint_verify()
                for(trigger = world; (trigger = find(trigger, classname, "trigger_multiple")); )
                        for(targ = world; (targ = find(targ, targetname, trigger.target)); )
                                if (targ.classname == "target_checkpoint" || targ.classname == "target_startTimer" || targ.classname == "target_stopTimer") {
-                                       targ.wait = -2;
+                                       trigger.wait = 0;
+                                       trigger.delay = 0;
+                                       targ.wait = 0;
                                        targ.delay = 0;
 
-                                       setsize(targ, trigger.mins, trigger.maxs);
-                                       setorigin(targ, trigger.origin);
+                    // These just make the game crash on some maps with oddly shaped triggers. 
+                    // (on the other hand they used to fix the case when two players ran through a checkpoint at once, 
+                    // and often one of them just passed through without being registered. Hope it's fixed  in a better way now.
+                    // (happened on item triggers too)
+                    //
+                                       //targ.wait = -2;
+                                       //targ.delay = 0;
+
+                                       //setsize(targ, trigger.mins, trigger.maxs);
+                                       //setorigin(targ, trigger.origin);
                                        //remove(trigger);
                                }
        }
index 5a86bee..143b3be 100644 (file)
@@ -590,7 +590,7 @@ float weapon_pickupevalfunc(entity player, entity item)
        // If custom weapon priorities for bots is enabled rate most wanted weapons higher
        if( bot_custom_weapon && c )
        {
-               for(i = WEP_FIRST; i < WEP_LAST ; ++i)
+               for(i = WEP_FIRST; i <= WEP_LAST ; ++i)
                {
                        // Find weapon
                        if( (get_weaponinfo(i)).weapons & item.weapons  != item.weapons )
@@ -630,7 +630,7 @@ float commodity_pickupevalfunc(entity player, entity item)
        c = 0;
 
        // Detect needed ammo
-       for(i = WEP_FIRST; i < WEP_LAST ; ++i)
+       for(i = WEP_FIRST; i <= WEP_LAST ; ++i)
        {
                wi = get_weaponinfo(i);
 
index 241b8f7..44036ad 100644 (file)
@@ -47,11 +47,13 @@ void target_init_verify()
                for(targ = world; (targ = find(targ, targetname, trigger.target)); )
                        if (targ.classname == "target_init" || targ.classname == "target_give" || targ.classname == "target_items")
                        {
-                               targ.wait = -2;
+                               trigger.wait = 0;
+                               trigger.delay = 0;
+                               targ.wait = 0;
                                targ.delay = 0;
 
-                               setsize(targ, trigger.mins, trigger.maxs);
-                               setorigin(targ, trigger.origin);
+                               //setsize(targ, trigger.mins, trigger.maxs);
+                               //setorigin(targ, trigger.origin);
                                //remove(trigger);
                        }
 }
@@ -59,7 +61,7 @@ void target_init_verify()
 void spawnfunc_target_init()
 {
        self.spawnflags = 0; // remove all weapons except the ones listed below
-       self.netname = "laser uzi"; // keep these weapons through the remove trigger
+       self.netname = "shotgun"; // keep these weapons through the remove trigger
        spawnfunc_target_items();
        InitializeEntity(self, target_init_verify, INITPRIO_FINDTARGET);
 }
@@ -98,7 +100,9 @@ void target_give_init()
                        self.armorvalue = 100;
                else if (targ.classname == "item_health_mega")
                        self.health = 200;
-               remove(targ);
+               //remove(targ); // removing ents in init functions causes havoc, workaround:
+        targ.think = SUB_Remove;
+        targ.nextthink = time;
        }
        self.spawnflags = 2;
        spawnfunc_target_items();
index 1c8f517..9cb52c1 100644 (file)
@@ -517,7 +517,7 @@ void PrintWelcomeMessage(entity pl)
                modifications = strcat(modifications, ", No start weapons");
        if(autocvar_sv_gravity < 800)
                modifications = strcat(modifications, ", Low gravity");
-       if(g_cloaked)
+       if(g_cloaked && !g_cts)
                modifications = strcat(modifications, ", Cloaked");
        if(g_grappling_hook)
                modifications = strcat(modifications, ", Hook");
@@ -525,7 +525,7 @@ void PrintWelcomeMessage(entity pl)
                modifications = strcat(modifications, ", Midair");
        if(g_pinata)
                modifications = strcat(modifications, ", Pinata");
-       if(g_weapon_stay)
+       if(g_weapon_stay && !g_cts)
                modifications = strcat(modifications, ", Weapons stay");
        if(g_bloodloss > 0)
                modifications = strcat(modifications, ", Bloodloss");
index 4ab7f4f..eb64ddd 100644 (file)
@@ -158,7 +158,7 @@ void Seeker_Fire_Missile(vector f_diff)
 {
        local entity missile;
 
-       if not(self.owner.items & IT_UNLIMITED_WEAPON_AMMO)
+       if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
                self.ammo_rockets = self.ammo_rockets - autocvar_g_balance_seeker_missile_ammo;
 
        makevectors(self.v_angle);