Merge branch 'master' into mirceakitsune/sandbox
authorMircea Kitsune <sonichedgehog_hyperblast00@yahoo.com>
Sun, 4 Dec 2011 15:26:04 +0000 (17:26 +0200)
committerMircea Kitsune <sonichedgehog_hyperblast00@yahoo.com>
Sun, 4 Dec 2011 15:26:04 +0000 (17:26 +0200)
45 files changed:
defaultXonotic.cfg
models/weapons/g_minstanex.md3
models/weapons/h_minstanex.iqm
models/weapons/h_minstanex.iqm.framegroups
models/weapons/mnex.tga [new file with mode: 0644]
models/weapons/mnex_bump.tga [new file with mode: 0644]
models/weapons/mnex_gloss.tga [new file with mode: 0644]
models/weapons/mnex_glow.tga [new file with mode: 0644]
models/weapons/mnex_reflect.tga [new file with mode: 0644]
models/weapons/mnex_shirt.tga [new file with mode: 0644]
models/weapons/v_minstanex.md3
qcsrc/client/Defs.qc
qcsrc/client/Main.qc
qcsrc/client/View.qc
qcsrc/client/ctf.qc [deleted file]
qcsrc/client/hud.qc
qcsrc/client/main.qh
qcsrc/client/progs.src
qcsrc/client/projectile.qc
qcsrc/client/scoreboard.qc
qcsrc/client/shownames.qc
qcsrc/client/tturrets.qc
qcsrc/client/waypointsprites.qc
qcsrc/common/constants.qh
qcsrc/server/assault.qc
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/defs.qh
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/base.qh
qcsrc/server/mutators/mutator_spawn_near_teammate.qc [new file with mode: 0644]
qcsrc/server/mutators/mutators.qh
qcsrc/server/progs.src
qcsrc/server/race.qc
qcsrc/server/sv_main.qc
scripts/mnex.shader [new file with mode: 0644]
scripts/weapons.shader
textures/nex.tga [deleted file]
textures/nex_bump.tga [deleted file]
textures/nex_gloss.tga [deleted file]
textures/nex_glow.tga [deleted file]
textures/nex_norm.tga [deleted file]
textures/nex_reflect.tga [deleted file]
textures/nex_shirt.tga [deleted file]

index 5cb8439..30fcd8b 100644 (file)
@@ -643,6 +643,8 @@ seta g_freezetag_frozen_force 0.6 "How much to multiply the force on a frozen pl
 
 set g_spawn_furthest 0.5 "this amount of the spawns shall be far away from any players"
 set g_spawn_useallspawns 0 "use all spawns, e.g. also team spawns in non-teamplay, and all spawns, even enemy spawns, in teamplay"
+set g_spawn_near_teammate 0 "if set, players prefer spawns near a team mate"
+set g_spawn_near_teammate_distance 640 "max distance to consider a spawn to be near a team mate"
 // respawn delay
 set g_respawn_delay 2 "number of seconds you have to wait before you can respawn again"
 set g_respawn_waves 0 "respawn in waves (every n seconds), intended to decrease overwhelming base attacks"
index 4575e9b..847e314 100644 (file)
Binary files a/models/weapons/g_minstanex.md3 and b/models/weapons/g_minstanex.md3 differ
index 60d9af6..82b0b23 100644 (file)
Binary files a/models/weapons/h_minstanex.iqm and b/models/weapons/h_minstanex.iqm differ
index 0a59625..9c7e702 100644 (file)
@@ -1,4 +1,10 @@
-1 8 20 0 // fire
-9 5 20 0 // fire2
-15 200 20 1 // idle
-215 40 20 0 // reload
+/*
+Generated framegroups file for h_uzi
+Used by DarkPlaces to simulate frame groups in DPM models.
+*/
+
+1 16 30 0 // h_uzi mgafire
+17 16 30 0 // h_uzi mgafire2
+33 101 3 1 // h_uzi mgaidle
+134 61 30 0 // h_uzi mgareload
+195 16 30 0 // h_uzi mgafire
diff --git a/models/weapons/mnex.tga b/models/weapons/mnex.tga
new file mode 100644 (file)
index 0000000..b4df2a3
Binary files /dev/null and b/models/weapons/mnex.tga differ
diff --git a/models/weapons/mnex_bump.tga b/models/weapons/mnex_bump.tga
new file mode 100644 (file)
index 0000000..98b3a5c
Binary files /dev/null and b/models/weapons/mnex_bump.tga differ
diff --git a/models/weapons/mnex_gloss.tga b/models/weapons/mnex_gloss.tga
new file mode 100644 (file)
index 0000000..8750a0e
Binary files /dev/null and b/models/weapons/mnex_gloss.tga differ
diff --git a/models/weapons/mnex_glow.tga b/models/weapons/mnex_glow.tga
new file mode 100644 (file)
index 0000000..aa54029
Binary files /dev/null and b/models/weapons/mnex_glow.tga differ
diff --git a/models/weapons/mnex_reflect.tga b/models/weapons/mnex_reflect.tga
new file mode 100644 (file)
index 0000000..f7fa7c8
Binary files /dev/null and b/models/weapons/mnex_reflect.tga differ
diff --git a/models/weapons/mnex_shirt.tga b/models/weapons/mnex_shirt.tga
new file mode 100644 (file)
index 0000000..dd371d6
Binary files /dev/null and b/models/weapons/mnex_shirt.tga differ
index d583e1a..d08b8fe 100644 (file)
Binary files a/models/weapons/v_minstanex.md3 and b/models/weapons/v_minstanex.md3 differ
index a1a3240..901380c 100644 (file)
@@ -28,7 +28,7 @@ entity                world;
 float          time;
 float          frametime;
 
-float          player_localentnum;     //the entnum
+float          player_localentnum;     //the entnum of the VIEW entity
 float          player_localnum;        //the playernum
 float          maxclients;     //a constant filled in by the engine. gah, portability eh?
 
index 90f1fcb..2252f6f 100644 (file)
@@ -67,6 +67,11 @@ void CSQC_Init(void)
 
        float i;
 
+#ifdef COMPAT_XON050_ENGINE
+       // old engine lacks implementation of player_localnum
+       player_localnum = player_localentnum - 1;
+#endif
+
        binddb = db_create();
        tempdb = db_create();
        ClientProgsDB = db_load("client.db");
@@ -806,7 +811,7 @@ void Ent_ClientData()
        if(f & 2)
        {
                newspectatee_status = ReadByte();
-               if(newspectatee_status == player_localentnum)
+               if(newspectatee_status == player_localnum + 1)
                        newspectatee_status = -1; // observing
        }
        else
@@ -840,6 +845,8 @@ void Ent_ClientData()
                        prev_health = -1;
        }
        spectatee_status = newspectatee_status;
+
+       // non-COMPAT_XON050_ENGINE: we could get rid of spectatee_status, and derive it from player_localentnum and player_localnum
 }
 
 void Ent_Nagger()
@@ -1286,7 +1293,7 @@ void Net_ReadRace()
                                strunzone(grecordholder[pos-1]);
                        grecordholder[pos-1] = strzone(ReadString());
                        grecordtime[pos-1] = ReadInt24_t();
-                       if(grecordholder[pos-1] == GetPlayerName(player_localentnum -1))
+                       if(grecordholder[pos-1] == GetPlayerName(player_localnum))
                                race_myrank = pos;
                        break;
                case RACE_NET_SERVER_STATUS:
index ca9841b..d9f6df7 100644 (file)
@@ -371,6 +371,7 @@ void CSQC_UpdateView(float w, float h)
        vector v;
        vector vf_size, vf_min;
        float a;
+
        hud = getstati(STAT_HUD);
 
        if(checkextension("DP_CSQC_MINFPS_QUALITY"))
@@ -407,9 +408,11 @@ void CSQC_UpdateView(float w, float h)
 
        WaypointSprite_Load();
 
+#ifdef COMPAT_XON050_ENGINE
        if(spectatee_status)
                myteam = GetPlayerColor(spectatee_status - 1);
        else
+#endif
                myteam = GetPlayerColor(player_localentnum - 1);
 
        ticrate = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
diff --git a/qcsrc/client/ctf.qc b/qcsrc/client/ctf.qc
deleted file mode 100644 (file)
index 5bf6639..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-#ifdef CTF_EXAMPLE
-
-// NOTE: This file contains lots of debugging stuff
-// it is not really used... can be seen as another sample...
-
-string STR_PLAYER = "player";
-#define FOR_EACH_PLAYER(v) for(v = world; (v = find(v, classname, STR_PLAYER)) != world; )
-
-string ctf_temp_1;
-float order_page;
-
-void menu_close()
-{
-       menu_visible = false;
-       menu_show = menu_show_error;
-       menu_action = menu_sub_null;
-       
-       /*if(ctf_temp_1)
-         strunzone(ctf_temp_1);*/
-       
-       localcmd("\nin_bindmap 0 0;");
-}
-
-void order_menu_render()
-{
-       vector ps, po;
-       float i, p, n;
-       string frags, color;
-       ps = '0 200 0';
-       po = '0 8 0';
-
-       color = getplayerkeyvalue(player_localentnum-1, "topcolor");
-       
-       if(getstati(STAT_CTF_STATE) == CTF_STATE_COMMANDER) {
-               drawstring(ps, _("----- Order Menu -----"), '8 8 0', '1 1 0', 1, 0); ps += po;
-               drawstring(ps, sprintf(_("Order: %s"), ctf_temp_1), '8 8 0', '1 1 0', 1, 0); ps += po;
-               drawcolorcodedstring(ps, _("1) ^3previous page"), '8 8 0', 1, 0); ps += po;
-               drawcolorcodedstring(ps, _("2) ^3next page"), '8 8 0', 1, 0); ps += po;
-               for((n = 2), (p = i = 0); i < maxclients && n > 0; ++i) {
-                       frags = getplayerkeyvalue(i, "frags");
-                       if(!frags || (i+1) == player_localentnum)
-                               continue;
-                       if(frags == "-666" || getplayerkeyvalue(i, "topcolor") != color) // FIXME use GetPlayerTeam
-                               continue;
-                       ++p;
-                       if(p > (8*order_page))
-                       {
-                               // only render current page
-                               ++n;
-                               if(n == 10)
-                                       n = 0;
-                               drawcolorcodedstring(ps, strcat(ftos(n), ") ", GetPlayerName(i), " : ", ftos(getstatf(STAT_CTF_STATE))), '8 8 0', 1, 0); ps += po;
-                       }
-               }
-               drawstring(ps, _("ESC) Exit Menu"), '8 8 0', '1 1 0', 1, 0); ps += po;
-       } else {
-               menu_close();
-       }
-}
-
-float order_menu_action(float bInputType, float nPrimary, float nSecondary)
-{
-       string arg;
-       float p, i, n, chose;
-       string frags, color;
-       if(bInputType != 0) // key down wanted
-               return FALSE;
-       
-       arg = chr2str(nSecondary);
-       chose = stof(chr2str(nPrimary));
-       //str2chr
-       if(arg == "1") {
-               color = getplayerkeyvalue(player_localentnum-1, "topcolor");
-               ++order_page;
-               for(p = i = 0; i < maxclients; ++i) {
-                       frags = getplayerkeyvalue(i, "frags");
-                       if(!frags || (i+1) == player_localentnum)
-                               continue;
-                       if(frags == "-666" || getplayerkeyvalue(i, "topcolor") != color) // FIXME use GetPlayerTeam
-                               continue;
-                       ++p;
-               }
-               if(p <= (8*order_page)) // no ppl on page
-                       order_page = 0;
-       } else if(arg == "2") {
-               color = getplayerkeyvalue(player_localentnum-1, "topcolor");
-               --order_page;
-               if(order_page < 0) {
-                       for(p = i = 0; i < maxclients; ++i) {
-                               frags = getplayerkeyvalue(i, "frags");
-                               if(!frags || (i+1) == player_localentnum)
-                                       continue;
-                               if(frags == "-666" || getplayerkeyvalue(i, "topcolor") != color) // FIXME use GetPlayerTeam
-                                       continue;
-                               ++p;
-                       }
-                       order_page = floor(p/8);
-               }
-       } else if(chose >= 3 && chose <= 9 || arg == "0") { // the 10 needs extra checking, assuming that stof(astring) returns 0
-               if(chose == 0)
-                       chose = 10;
-               n = 2;
-               color = getplayerkeyvalue(player_localentnum-1, "topcolor");
-               for(p = i = 0; i < maxclients && n > 0; ++i) {
-                       frags = getplayerkeyvalue(i, "frags");
-                       if(!frags || (i+1) == player_localentnum)
-                               continue;
-                       if(frags == "-666" || getplayerkeyvalue(i, "topcolor") != color) // FIXME use GetPlayerTeam
-                               continue;
-                       ++p;
-                       if(p > (8*order_page))
-                       {
-                               // only render current page
-                               ++n;
-                               if(n == chose) {
-                                       n = 0;
-                                       break;
-                               }
-                       }
-               }
-               if(n == 0) {
-                       //print(sprintf(_("Issuing order to: %d\n"), i+1));
-                       //print(strcat("cmd order #", ftos(i+1), " ", ctf_temp_1, ";\n"));
-                       localcmd(strcat("\ncmd order #", ftos(i+1), " ", ctf_temp_1, ";"));
-               } else {
-                       print(sprintf(_("Couldn't find player %d\n"), chose));
-               }
-               return TRUE;
-       } else if(nSecondary == K_ESCAPE) {
-               strunzone(ctf_temp_1);
-               menu_close();
-       } else {
-               //print(sprintf(_("Menu action %s does not exist.\n"), arg));
-               return FALSE;
-       }
-       return TRUE;
-}
-
-void order_menu_show()
-{
-       order_page = 0;
-       menu_show = order_menu_render;
-       menu_action = order_menu_action;
-}
-
-
-void ctf_menu_render()
-{
-       vector ps, po;
-       ps = '0 200 0';
-       po = '0 8 0';
-       
-       if(getstati(STAT_CTF_STATE) == CTF_STATE_COMMANDER) {
-               drawstring(ps, _("----- Command Menu -----"), '8 8 0', '1 1 0', 1, 0); ps += po;
-               drawstring(ps, _("Issue orders:"), '8 8 0', '1 1 0', 1, 0); ps += po;
-               drawstring(ps, _(" 1) Attack"), '8 8 0', '1 1 0', 1, 0);
-               drawstring(ps + '80 0 0', " \x0F", '8 8 0', '1 1 1', 1, 0); ps += po;
-               drawstring(ps, strcat(_(" 2) Defend"), " \x0E"), '8 8 0', '1 1 0', 1, 0); ps += po;
-               ps += po;
-               drawstring(ps, _("3) Resign from command."), '8 8 0', '1 1 0', 1, 0); ps += po;
-               drawstring(ps, _("ESC) Exit Menu"), '8 8 0', '1 1 0', 1, 0); ps += po;
-       } else {
-               menu_close();
-       }
-}
-
-float ctf_menu_action(float bInputType, float nPrimary, float nSecondary)
-{
-       string arg;
-       if(bInputType != 0) // key down wanted
-               return FALSE;
-       
-       arg = chr2str(nSecondary);
-
-       if(arg == "1") {
-               ctf_temp_1 = strzone("attack");
-               order_menu_show();
-       } else if(arg == "2") {
-               ctf_temp_1 = strzone("defend");
-               order_menu_show();
-       } else if(arg == "3") {
-               localcmd("\ncmd order resign;");
-               menu_close();
-       } else if(nSecondary == K_ESCAPE) {
-               menu_close();
-       } else {
-               //print(strcat("Menu action ", arg, " does not exist.\n"));
-               return FALSE;
-       }
-       return TRUE;
-}
-
-void ctf_menu_show()
-{
-       if(getstati(STAT_CTF_STATE) < 0)
-               return;
-       menu_show = ctf_menu_render;
-       menu_action = ctf_menu_action;
-       menu_visible = TRUE;
-       //menu_default_binds();
-}
-
-void ctf_view()
-{
-       float stat;
-       stat = getstati(STAT_CTF_STATE);
-       if(stat == CTF_STATE_ATTACK) {
-               drawpic('0 0 0', "gfx/ctf_ic_atk.tga", '64 64 0', '1 1 1', 1, 0);
-       } else if(stat == CTF_STATE_DEFEND) {
-               drawpic('0 0 0', "gfx/ctf_ic_def.tga", '64 64 0', '1 1 1', 1, 0);
-       } else if(stat == CTF_STATE_COMMANDER) {
-               drawstring('0 0 0', _("You're commander!"), '8 8 0', '1 1 1', 1, 0);
-       } else if(stat < 0) {
-       } else {
-               drawstring('0 0 0', _("Awaiting orders..."), '8 8 0', '1 1 1', 0.5, 0);
-       }
-}
-
-#endif
index efa2d31..86b4976 100644 (file)
@@ -432,33 +432,34 @@ float GetAmmoTypeForWep(float i)
 void HUD_Weapons(void)
 {
        // declarations
-       float weapons_stat = getstati(STAT_WEAPONS); 
+       float weapons_stat = getstati(STAT_WEAPONS);
        float i, f, a, j, factor;
-       float screen_ar, center_x, center_y; 
-       float weapon_count, weapon_id, weapon_alpha; 
-       float row, column, rows, columns; 
+       float screen_ar, center_x, center_y;
+       float weapon_count, weapon_id, weapon_alpha;
+       float row, column, rows, columns;
        float aspect = autocvar_hud_panel_weapons_aspect;
-       
+
        float show_accuracy, panel_weapon_accuracy;
-       
+
        float timeout = autocvar_hud_panel_weapons_timeout;
        float timein_effect_length = (autocvar_hud_panel_weapons_timeout_effect ? 0.375 : 0);
        float timeout_effect_length = (autocvar_hud_panel_weapons_timeout_effect ? 0.75 : 0);
-       
+
        float ammo_type, ammo_full, ammo_alpha;
        float barsize_x, barsize_y, baroffset_x, baroffset_y;
-       
+
        float when = autocvar_hud_panel_weapons_complainbubble_time;
        float fadetime = autocvar_hud_panel_weapons_complainbubble_fadetime;
-       
+
        vector weapon_pos, weapon_size;
        local noref vector old_panel_size; // fteqcc sucks
        vector color, ammo_color;
-       
+
        // check to see if we want to continue
-  if(hud != HUD_NORMAL) { return; }
-  
+       if(hud != HUD_NORMAL) { return; }
+
        if(!autocvar__hud_configure)
+       {
                if((!autocvar_hud_panel_weapons) || (spectatee_status == -1))
                        return;
                else if(timeout && time >= weapontime + timeout + timeout_effect_length)
@@ -466,13 +467,14 @@ void HUD_Weapons(void)
                        weaponprevtime = time;
                        return;
                }
+       }
        else
                hud_configure_active_panel = HUD_PANEL_WEAPONS;
 
        // update generic hud functions
        HUD_Panel_UpdateCvars(weapons);
        HUD_Panel_ApplyFadeAlpha();
-       
+
        // calculate fading effect to weapon images for when the panel is idle
        if(autocvar_hud_panel_weapons_fade)
        {
@@ -511,7 +513,7 @@ void HUD_Weapons(void)
 
                weaponorder_cmp_str = string_null;
        }
-       
+
        // determine which weapons are going to be shown
        if (autocvar_hud_panel_weapons_onlyowned)
        {
@@ -520,25 +522,25 @@ void HUD_Weapons(void)
                        if (weapons_stat == 0) // create some fake weapons anyway
                                for(i = 0; i <= WEP_LAST-WEP_FIRST; i += floor((WEP_LAST-WEP_FIRST)/5))
                                        weapons_stat |= power2of(i);
-                                       
+
                        if(menu_enabled != 2)
                                HUD_Panel_DrawBg(1); // also draw the bg of the entire panel
                }
-               
+
                // do we own this weapon?
                for(i = 0; i <= WEP_LAST-WEP_FIRST; ++i)
                        if(weapons_stat & weaponorder[i].weapons)
                                ++weapon_count;
-               
+
                // add it anyway if weaponcomplain is shown
                if((!autocvar__hud_configure) 
                        && (autocvar_hud_panel_weapons_complainbubble 
                                && time - complain_weapon_time < when + fadetime))
                                        ++weapon_count;
-                       
+
                // might as well commit suicide now, no reason to live ;)
                if (weapon_count == 0) { return; }
-               
+
                // reduce size of the panel
                if (panel_size_y > panel_size_x)
                {
@@ -623,12 +625,12 @@ void HUD_Weapons(void)
                }
        }
 
-       // draw the background, then change the virtual size of it to better fit other items inside 
+       // draw the background, then change the virtual size of it to better fit other items inside
        HUD_Panel_DrawBg(1);
        if(panel_bg_padding)
        {
                panel_pos += '1 1 0' * panel_bg_padding;
-               panel_size -= '1 1 0' * panel_bg_padding;
+               panel_size -= '2 2 0' * panel_bg_padding;
        }
 
        // after the sizing and animations are done, update the other values
@@ -636,7 +638,7 @@ void HUD_Weapons(void)
        rows = bound(1, floor((sqrt(4 * aspect * rows * weapon_count + rows * rows) + rows + 0.5) / 2), weapon_count);
        columns = ceil(weapon_count/rows);
        weapon_size = eX * panel_size_x*(1/columns) + eY * panel_size_y*(1/rows);
-       
+
        // calculate position/size for visual bar displaying ammount of ammo status
        if (autocvar_hud_panel_weapons_ammo)
        {
@@ -670,10 +672,10 @@ void HUD_Weapons(void)
                // retrieve information about the current weapon to be drawn
                self = weaponorder[i];
                weapon_id = self.impulse;
-               
+
                // skip if this weapon doesn't exist
                if (!self || self.impulse < 0) { continue; }
-               
+
                // skip this weapon if we don't own it (and onlyowned is enabled)-- or if weapons_complainbubble is showing for this weapon
                if (autocvar_hud_panel_weapons_onlyowned
                        && !((weapons_stat & self.weapons) 
@@ -681,7 +683,7 @@ void HUD_Weapons(void)
                                && time - complain_weapon_time < when + fadetime 
                                && autocvar_hud_panel_weapons_complainbubble)))
                                        continue;
-                                       
+
                // figure out the drawing position of weapon
                weapon_pos = (panel_pos 
                        + eX * column * weapon_size_x 
@@ -723,19 +725,19 @@ void HUD_Weapons(void)
                                case 1: // weapon number
                                        drawstring(weapon_pos, ftos(weapon_id), '1 1 0' * 0.5 * weapon_size_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
                                        break;
-                                       
+
                                case 2: // bind
                                        drawstring(weapon_pos, getcommandkey(ftos(weapon_id), strcat("impulse ", ftos(weapon_id))), '1 1 0' * 0.5 * weapon_size_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
                                        break;
-                                       
+
                                case 3: // weapon name
                                        drawstring(weapon_pos, self.netname, '1 1 0' * 0.5 * weapon_size_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
                                        break;
-                                       
+
                                default: // nothing
                                        break;
                        }
-                       
+
                        // draw ammo status bar
                        if(autocvar_hud_panel_weapons_ammo && self.weapon != WEP_TUBA && self.weapon != WEP_LASER && self.weapon != WEP_PORTO)
                        {
@@ -769,7 +771,7 @@ void HUD_Weapons(void)
                {
                        drawpic_aspect_skin(weapon_pos, strcat("weapon", self.netname), weapon_size, '0 0 0', panel_fg_alpha * 0.5, DRAWFLAG_NORMAL);
                }
-               
+
                // draw the complain message
                if(time - complain_weapon_time < when + fadetime && self.weapon == complain_weapon && autocvar_hud_panel_weapons_complainbubble)
                {
@@ -2692,7 +2694,11 @@ void HUD_Score(void)
        string sign;
        vector distribution_color;
        entity tm, pl, me;
+#ifdef COMPAT_XON050_ENGINE
        me = (spectatee_status > 0) ? playerslots[spectatee_status - 1] : playerslots[player_localentnum - 1];
+#else
+       me = playerslots[player_localentnum - 1];
+#endif
 
        if((scores_flags[ps_primary] & SFL_TIME) && !teamplay) { // race/cts record display on HUD
                string timer, distrtimer;
@@ -3567,7 +3573,7 @@ void HUD_Mod_Race(vector pos, vector mySize)
 {
        mod_active = 1; // race should never hide the mod icons panel
        entity me;
-       me = playerslots[player_localentnum - 1];
+       me = playerslots[player_localnum];
        float t, score;
        float f; // yet another function has this
        score = me.(scores[ps_primary]);
@@ -3675,7 +3681,7 @@ void HUD_Mod_Race(vector pos, vector mySize)
                drawcolorcodedstring_aspect(namepos, s, '1 0.2 0' * squareSize, panel_fg_alpha * a, DRAWFLAG_NORMAL);
                drawstring_aspect(rankpos, rankname, '1 0.15 0' * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
        } else if(race_status == 2) {
-               if(race_status_name == GetPlayerName(player_localentnum -1) || !race_myrank || race_myrank < rank)
+               if(race_status_name == GetPlayerName(player_localnum) || !race_myrank || race_myrank < rank)
                        drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrankgreen", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
                else
                        drawpic_aspect_skin(medalPos + '0.1 0 0' * squareSize, "race_newrankyellow", '1 1 0' * 0.8 * squareSize, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
@@ -4121,7 +4127,11 @@ void HUD_InfoMessages(void)
                        if(spectatee_status == -1)
                                s = _("^1Observing");
                        else
+#ifdef COMPAT_XON050_ENGINE
                                s = sprintf(_("^1Spectating: ^7%s"), GetPlayerName(spectatee_status - 1));
+#else
+                               s = sprintf(_("^1Spectating: ^7%s"), GetPlayerName(player_localentnum - 1));
+#endif
                        drawInfoMessage(s)
 
                        if(spectatee_status == -1)
@@ -4144,7 +4154,7 @@ void HUD_InfoMessages(void)
                        else if(gametype == GAME_LMS)
                        {
                                entity sk;
-                               sk = playerslots[player_localentnum - 1];
+                               sk = playerslots[player_localnum];
                                if(sk.(scores[ps_primary]) >= 666)
                                        s = _("^1Match has already begun");
                                else if(sk.(scores[ps_primary]) > 0)
@@ -4883,7 +4893,11 @@ void HUD_Main (void)
                        drawfill(eY * i * hud_configure_realGridSize_y, eY + eX * vid_conwidth, '0.5 0.5 0.5', autocvar_hud_configure_grid_alpha, DRAWFLAG_NORMAL);
        }
 
+#ifdef COMPAT_XON050_ENGINE
     current_player = (spectatee_status > 0) ? spectatee_status : player_localentnum;
+#else
+    current_player = player_localentnum;
+#endif
 
        // draw the dock
        if(autocvar_hud_dock != "" && autocvar_hud_dock != "0")
index 499e84b..bd9ffe6 100644 (file)
@@ -17,14 +17,6 @@ float menu_visible;
 var void() menu_show;
 var float(float bInputType, float nPrimary, float nSecondary) menu_action;
 
-// --------------------------------------------------------------------------
-// CTF
-
-#ifdef CTF_EXAMPLE
-void() ctf_menu_show;
-string ctf_temp_1;
-#endif
-
 // --------------------------------------------------------------------------
 // Onslaught
 
index a4d8b70..06b3e8b 100644 (file)
@@ -42,8 +42,6 @@ sortlist.qc
 miscfunctions.qc
 teamplay.qc
 
-ctf.qc
-
 teamradar.qc
 hud_config.qc
 hud.qc
index e17d7ba..e8274c8 100644 (file)
@@ -75,7 +75,7 @@ void Projectile_Draw()
                        Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
                if(!(self.move_flags & FL_ONGROUND))
                        if(self.velocity != '0 0 0')
-                               self.angles = vectoangles(self.velocity);
+                               self.move_angles = self.angles = vectoangles(self.velocity);
        }
        else
        {
index d4c2043..3124b4b 100644 (file)
@@ -894,7 +894,7 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz
                {
                        if(pl.team != tm.team)
                                continue;
-                       HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localentnum - 1), i);
+                       HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), i);
                        pos_y += 1.25 * hud_fontsize_y;
                        ++i;
                }
@@ -903,7 +903,7 @@ vector HUD_Scoreboard_MakeTable(vector pos, entity tm, vector rgb, vector bg_siz
                {
                        if(pl.team == COLOR_SPECTATOR)
                                continue;
-                       HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localentnum - 1), i);
+                       HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), i);
                        pos_y += 1.25 * hud_fontsize_y;
                        ++i;
                }
@@ -1147,7 +1147,7 @@ vector HUD_DrawScoreboardRankings(vector pos, entity pl,  vector rgb, vector bg_
                        continue;
                n = grecordholder[i];
                p = race_PlaceName(i+1);
-               if(grecordholder[i] == GetPlayerName(player_localentnum - 1))
+               if(grecordholder[i] == GetPlayerName(player_localnum))
                        drawfill(pos, '1 0 0' * sbwidth + '0 1.25 0' * hud_fontsize_y, hl_rgb, scoreboard_highlight_alpha_self, DRAWFLAG_NORMAL);
                else if(!mod(i, 2) && scoreboard_highlight)
                        drawfill(pos, '1 0 0' * sbwidth + '0 1.25 0' * hud_fontsize_y, hl_rgb, scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
@@ -1296,7 +1296,7 @@ void HUD_DrawScoreboard()
                if(pl.team != COLOR_SPECTATOR)
                        continue;
                pos_y += 1.25 * hud_fontsize_y;
-               HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localentnum - 1), specs);
+               HUD_PrintScoreboardItem(pos, pl, (pl.sv_entnum == player_localnum), specs);
                ++specs;
        }
 
index 21e8bcd..d5e2488 100644 (file)
@@ -13,7 +13,11 @@ void Draw_ShowNames(entity ent)
        if(!autocvar_hud_shownames)
                return;
        
+#ifdef COMPAT_XON050_ENGINE
        if((ent.sv_entnum == player_localentnum) || (ent.sv_entnum == spectatee_status)) // ent is me or person i'm spectating
+#else
+       if(ent.sv_entnum == player_localentnum) // ent is me or person i'm spectating
+#endif
                if not (autocvar_hud_shownames_self && autocvar_chase_active) 
                        return;
 
index f4a53ca..89f1be7 100644 (file)
@@ -264,7 +264,7 @@ void turret_draw2d()
         return;
 
        string spriteimage = self.netname;
-       float t = (GetPlayerColor(player_localentnum - 1) + 1); 
+       float t = (GetPlayerColor(player_localnum) + 1);        
        float a = self.alpha * autocvar_hud_panel_fg_alpha;
        vector rgb = spritelookupcolor(spriteimage, self.teamradar_color);
 
index ac85f8c..6d9b0ee 100644 (file)
@@ -403,7 +403,7 @@ void Draw_WaypointSprite()
 
        InterpolateOrigin_Do();
 
-       t = GetPlayerColor(player_localentnum - 1) + 1;
+       t = GetPlayerColor(player_localnum) + 1;
 
        spriteimage = "";
 
index d838f09..7e5e99e 100644 (file)
@@ -574,3 +574,9 @@ float HUD_MENU_ENABLE               = 0;
 #define SERVERFLAG_ALLOW_FULLBRIGHT 1
 #define SERVERFLAG_TEAMPLAY 2
 #define SERVERFLAG_PLAYERSTATS 4
+
+// spawnpoint prios
+#define SPAWN_PRIO_NEAR_TEAMMATE_FOUND    200
+#define SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM 100
+#define SPAWN_PRIO_RACE_PREVIOUS_SPAWN     50
+#define SPAWN_PRIO_GOOD_DISTANCE           10
index 45fa5c7..425bbf7 100644 (file)
@@ -47,6 +47,13 @@ void assault_objective_use() {
        self = oldself;
 }
 
+vector target_objective_spawn_evalfunc(entity player, entity spot, vector current)
+{
+       if(self.health < 0 || self.health >= ASSAULT_VALUE_INACTIVE)
+               return '-1 0 0';
+       return current;
+}
+
 void spawnfunc_target_objective() {
        if(!g_assault)
        {
@@ -57,6 +64,7 @@ void spawnfunc_target_objective() {
        self.use = assault_objective_use;
        assault_objective_reset();
        self.reset = assault_objective_reset;
+       self.spawn_evalfunc = target_objective_spawn_evalfunc;
 }
 
 
index 564e9ae..175d6dc 100644 (file)
@@ -1065,7 +1065,6 @@ float autocvar_skill_auto;
 #define autocvar_slowmo cvar("slowmo")
 float autocvar_snd_soundradius;
 float autocvar_spawn_debug;
-float autocvar_spawn_debugview;
 float autocvar_speedmeter;
 float autocvar_sv_accelerate;
 var float autocvar_sv_accuracy_data_share = 1;
index 40039ea..c21fc78 100644 (file)
@@ -123,7 +123,7 @@ void spawnpoint_use()
 // Returns:
 //   _x: prio (-1 if unusable)
 //   _y: weight
-vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoint)
+vector Spawn_Score(entity spot, float mindist, float teamcheck)
 {
        float shortest, thisdist;
        float prio;
@@ -151,55 +151,37 @@ vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoi
                        return '-1 0 0';
        }
 
+       shortest = vlen(world.maxs - world.mins);
+       FOR_EACH_PLAYER(player) if (player != self)
+       {
+               thisdist = vlen(player.origin - spot.origin);
+               if (thisdist < shortest)
+                       shortest = thisdist;
+       }
+       if(shortest < mindist)
+               prio += SPAWN_PRIO_GOOD_DISTANCE;
+
+       spawn_score = prio * '1 0 0' + shortest * '0 1 0';
+       spawn_spot = spot;
+
        // filter out spots for assault
        if(spot.target != "") {
                entity ent;
-               float good, found;
+               float found;
 
                found = 0;
-               good = 0;
                for(ent = world; (ent = find(ent, targetname, spot.target)); )
                {
                        ++found;
-                       if(ent.classname == "target_objective")
+                       if(ent.spawn_evalfunc)
                        {
-                               if(ent.health < 0 || ent.health >= ASSAULT_VALUE_INACTIVE)
-                                       continue;
-                       }
-                       else if(ent.classname == "trigger_race_checkpoint")
-                       {
-                               if(!anypoint) // spectators may spawn everywhere
-                               {
-                                       if(g_race_qualifying)
-                                       {
-                                               // spawn at first
-                                               if(ent.race_checkpoint != 0)
-                                                       continue;
-                                               if(spot.race_place != race_lowest_place_spawn)
-                                                       continue;
-                                       }
-                                       else
-                                       {
-                                               if(ent.race_checkpoint != self.race_respawn_checkpoint)
-                                                       continue;
-                                               // try reusing the previous spawn
-                                               if(ent == self.race_respawn_spotref || spot == self.race_respawn_spotref)
-                                                       prio += 1;
-                                               if(ent.race_checkpoint == 0)
-                                               {
-                                                       float pl;
-                                                       pl = self.race_place;
-                                                       if(pl > race_highest_place_spawn)
-                                                               pl = 0;
-                                                       if(pl == 0 && !self.race_started)
-                                                               pl = race_highest_place_spawn; // use last place if he has not even touched finish yet
-                                                       if(spot.race_place != pl)
-                                                               continue;
-                                               }
-                                       }
-                               }
+                               entity oldself = self;
+                               self = ent;
+                               spawn_score = ent.spawn_evalfunc(oldself, spot, spawn_score);
+                               self = oldself;
+                               if(spawn_score_x < 0)
+                                       return spawn_score;
                        }
-                       ++good;
                }
 
                if(!found)
@@ -207,95 +189,42 @@ vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoi
                        dprint("WARNING: spawnpoint at ", vtos(spot.origin), " could not find its target ", spot.target, "\n");
                        return '-1 0 0';
                }
-
-               if(good < found) // at least one was bad
-                       return '-1 0 0';
        }
 
-       player = playerlist;
-       shortest = vlen(world.maxs - world.mins);
-       for(player = playerlist; player; player = player.chain)
-               if (player != self)
-               {
-                       thisdist = vlen(player.origin - spot.origin);
-                       if (thisdist < shortest)
-                               shortest = thisdist;
-               }
-       return prio * '1 0 0' + shortest * '0 1 0';
+       MUTATOR_CALLHOOK(Spawn_Score);
+       return spawn_score;
+}
+
+void Spawn_ScoreAll(entity firstspot, float mindist, float teamcheck)
+{
+       entity spot;
+       for(spot = firstspot; spot; spot = spot.chain)
+               spot.spawnpoint_score = Spawn_Score(spot, mindist, teamcheck);
 }
 
-float spawn_allbad;
-float spawn_allgood;
-entity Spawn_FilterOutBadSpots(entity firstspot, entity playerlist, float mindist, float teamcheck, float anypoint)
+entity Spawn_FilterOutBadSpots(entity firstspot, float mindist, float teamcheck)
 {
        entity spot, spotlist, spotlistend;
-       spawn_allgood = TRUE;
-       spawn_allbad = TRUE;
 
        spotlist = world;
        spotlistend = world;
 
+       Spawn_ScoreAll(firstspot, mindist, teamcheck);
+
        for(spot = firstspot; spot; spot = spot.chain)
        {
-               spot.spawnpoint_score = Spawn_Score(spot, playerlist, teamcheck, anypoint);
-
-               if(autocvar_spawn_debugview)
-               {
-                       setmodel(spot, "models/runematch/rune.mdl");
-                       if(spot.spawnpoint_score_y < mindist)
-                       {
-                               spot.colormod = '1 0 0';
-                               spot.scale = 1;
-                       }
-                       else
-                       {
-                               spot.colormod = '0 1 0';
-                               spot.scale = spot.spawnpoint_score_y / mindist;
-                       }
-               }
-
                if(spot.spawnpoint_score_x >= 0) // spawning allowed here
                {
-                       if(spot.spawnpoint_score_y < mindist)
-                       {
-                               // too short distance
-                               spawn_allgood = FALSE;
-                       }
-                       else
-                       {
-                               // perfect
-                               spawn_allbad = FALSE;
-
-                               if(spotlistend)
-                                       spotlistend.chain = spot;
-                               spotlistend = spot;
-                               if(!spotlist)
-                                       spotlist = spot;
-
-                               /*
-                               if(teamcheck >= 0)
-                               if(spot.team != teamcheck)
-                                       error("invalid spawn added");
-
-                               print("added ", etos(spot), "\n");
-                               */
-                       }
+                       if(spotlistend)
+                               spotlistend.chain = spot;
+                       spotlistend = spot;
+                       if(!spotlist)
+                               spotlist = spot;
                }
        }
        if(spotlistend)
                spotlistend.chain = world;
 
-       /*
-               entity e;
-               if(teamcheck >= 0)
-                       for(e = spotlist; e; e = e.chain)
-                       {
-                               print("seen ", etos(e), "\n");
-                               if(e.team != teamcheck)
-                                       error("invalid spawn found");
-                       }
-       */
-
        return spotlist;
 }
 
@@ -322,8 +251,7 @@ Finds a point to respawn
 entity SelectSpawnPoint (float anypoint)
 {
        float teamcheck;
-       entity firstspot_new;
-       entity spot, firstspot, playerlist;
+       entity spot, firstspot;
 
        spot = find (world, classname, "testplayerstart");
        if (spot)
@@ -354,8 +282,6 @@ entity SelectSpawnPoint (float anypoint)
                // if we get here, we either require team spawns but have none, or we require non-team spawns and have none; use any spawn then
 
 
-       // get the list of players
-       playerlist = findchain(classname, "player");
        // get the entire list of spots
        firstspot = findchain(classname, "info_player_deathmatch");
        // filter out the bad ones
@@ -366,38 +292,22 @@ entity SelectSpawnPoint (float anypoint)
        }
        else
        {
-               firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, 100, teamcheck, anypoint);
-               if(!firstspot_new)
-                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, -1, teamcheck, anypoint);
-               firstspot = firstspot_new;
+               float mindist;
+               if (arena_roundbased && !g_ca)
+                       mindist = 800;
+               else
+                       mindist = 100;
+               firstspot = Spawn_FilterOutBadSpots(firstspot, mindist, teamcheck);
 
                // there is 50/50 chance of choosing a random spot or the furthest spot
                // (this means that roughly every other spawn will be furthest, so you
                // usually won't get fragged at spawn twice in a row)
-               if (arena_roundbased && !g_ca)
-               {
-                       firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, 800, teamcheck, anypoint);
-                       if(firstspot_new)
-                               firstspot = firstspot_new;
-                       spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
-               }
-               else if (random() > autocvar_g_spawn_furthest)
+               if (random() > autocvar_g_spawn_furthest)
                        spot = Spawn_WeightedPoint(firstspot, 1, 1, 1);
                else
                        spot = Spawn_WeightedPoint(firstspot, 1, 5000, 5); // chooses a far far away spawnpoint
        }
 
-       if(autocvar_spawn_debugview)
-       {
-               print("spot mindistance: ", vtos(spot.spawnpoint_score), "\n");
-
-               entity e;
-               if(teamcheck >= 0)
-                       for(e = firstspot; e; e = e.chain)
-                               if(e.team != teamcheck)
-                                       error("invalid spawn found");
-       }
-
        if (!spot)
        {
                if(autocvar_spawn_debug)
@@ -1086,12 +996,6 @@ void PutClientInServer (void)
 
                race_PostSpawn(spot);
 
-               if(autocvar_spawn_debug)
-               {
-                       sprint(self, strcat("spawnpoint origin:  ", vtos(spot.origin), "\n"));
-                       remove(spot);   // usefull for checking if there are spawnpoints, that let drop through the floor
-               }
-
                //stuffcmd(self, "chase_active 0");
                //stuffcmd(self, "set viewsize $tmpviewsize \n");
 
@@ -1130,8 +1034,15 @@ void PutClientInServer (void)
                        activator = world;
                self = oldself;
 
+               spawn_spot = spot;
                MUTATOR_CALLHOOK(PlayerSpawn);
 
+               if(autocvar_spawn_debug)
+               {
+                       sprint(self, strcat("spawnpoint origin:  ", vtos(spot.origin), "\n"));
+                       remove(spot);   // usefull for checking if there are spawnpoints, that let drop through the floor
+               }
+
                self.switchweapon = w_getbestweapon(self);
                self.cnt = -1; // W_LastWeapon will not complain
                self.weapon = 0;
index 53c90c3..c3b6cf3 100644 (file)
@@ -671,3 +671,6 @@ float serverflags;
 .float misc_bulletcounter;     // replaces uzi & hlac bullet counter.
 
 void PlayerUseKey();
+
+typedef vector(entity player, entity spot, vector current) spawn_evalfunc_t;
+.spawn_evalfunc_t spawn_evalfunc;
index 5751dbd..263f53d 100644 (file)
@@ -309,6 +309,7 @@ void cvar_changes_init()
                BADPREFIX("sv_master");
                BADPREFIX("sv_weaponstats_");
                BADPREFIX("sv_waypointsprite_");
+               BADCVAR("rescan_pending");
 
                // these can contain player IDs, so better hide
                BADPREFIX("g_forced_team_");
@@ -400,6 +401,7 @@ void cvar_changes_init()
                BADPREFIX("timelimit_");
                BADCVAR("gameversion");
                BADPREFIX("gameversion_");
+               BADCVAR("sv_namechangetimer");
 
                // allowed changes to server admins (please sync this to server.cfg)
                // vi commands:
index 87fa4d6..0e98a56 100644 (file)
@@ -1101,6 +1101,8 @@ void readlevelcvars(void)
                MUTATOR_ADD(mutator_rocketflying);
        if(cvar("g_vampire"))
                MUTATOR_ADD(mutator_vampire);
+       if(cvar("g_spawn_near_teammate"))
+               MUTATOR_ADD(mutator_spawn_near_teammate);
        if(cvar("g_sandbox"))
                MUTATOR_ADD(sandbox);
 
index 621e4db..174c102 100644 (file)
@@ -45,6 +45,7 @@ MUTATOR_HOOKABLE(MakePlayerObserver);
        // called when a player becomes observer, after shared setup
 
 MUTATOR_HOOKABLE(PlayerSpawn);
+       entity spawn_spot; // spot that was used, or world
        // called when a player spawns as player, after shared setup, before his weapon is chosen (so items may be changed in here)
 
 MUTATOR_HOOKABLE(ClientDisconnect);
@@ -191,3 +192,11 @@ MUTATOR_HOOKABLE(SV_ParseClientCommand);
 
 MUTATOR_HOOKABLE(SV_StartFrame);
        // runs globally each server frame
+MUTATOR_HOOKABLE(Spawn_Score);
+       // called when a spawnpoint is being evaluated
+       // return 1 to make the spawnpoint unusable
+       // INPUT
+       entity self; // player wanting to spawn
+       entity spawn_spot; // spot to be evaluated
+       // IN+OUT
+       vector spawn_score; // _x is priority, _y is "distance"
diff --git a/qcsrc/server/mutators/mutator_spawn_near_teammate.qc b/qcsrc/server/mutators/mutator_spawn_near_teammate.qc
new file mode 100644 (file)
index 0000000..4d0746d
--- /dev/null
@@ -0,0 +1,59 @@
+float autocvar_g_spawn_near_teammate_distance;
+.entity msnt_lookat;
+
+MUTATOR_HOOKFUNCTION(msnt_Spawn_Score)
+{
+       entity p;
+
+       spawn_spot.msnt_lookat = world;
+
+       if(!teamplay)
+               return 0;
+
+       RandomSelection_Init();
+       FOR_EACH_PLAYER(p) if(p != self) if(p.team == self.team) if(!p.deadflag)
+       {
+               float l = vlen(spawn_spot.origin - p.origin);
+               if(l > autocvar_g_spawn_near_teammate_distance)
+                       continue;
+               if(l < 48)
+                       continue;
+               if(!checkpvs(spawn_spot.origin, p))
+                       continue;
+               RandomSelection_Add(p, 0, string_null, 1, 1);
+       }
+
+       if(RandomSelection_chosen_ent)
+       {
+               spawn_spot.msnt_lookat = RandomSelection_chosen_ent;
+               spawn_score_x += SPAWN_PRIO_NEAR_TEAMMATE_FOUND;
+       }
+       else if(self.team == spawn_spot.team)
+               spawn_score_x += SPAWN_PRIO_NEAR_TEAMMATE_SAMETEAM; // prefer same team, if we can't find a spawn near teammate
+
+       return 0;
+}
+
+MUTATOR_HOOKFUNCTION(msnt_PlayerSpawn)
+{
+       if(spawn_spot.msnt_lookat)
+       {
+               self.angles = vectoangles(spawn_spot.msnt_lookat.origin - self.origin);
+               self.angles_x = -self.angles_x;
+               /*
+               sprint(self, "You should be looking at ", spawn_spot.msnt_lookat.netname, "^7.\n");
+               sprint(self, "distance: ", vtos(spawn_spot.msnt_lookat.origin - self.origin), "\n");
+               sprint(self, "angles: ", vtos(self.angles), "\n");
+               */
+       }
+
+       return 0;
+}
+
+MUTATOR_DEFINITION(mutator_spawn_near_teammate)
+{
+       MUTATOR_HOOK(Spawn_Score, msnt_Spawn_Score, CBC_ORDER_ANY);
+       MUTATOR_HOOK(PlayerSpawn, msnt_PlayerSpawn, CBC_ORDER_ANY);
+
+       return 0;
+}
index 349d945..1cd0792 100644 (file)
@@ -9,3 +9,4 @@ MUTATOR_DECLARATION(mutator_rocketflying);
 MUTATOR_DECLARATION(mutator_vampire);
 
 MUTATOR_DECLARATION(sandbox);
+MUTATOR_DECLARATION(mutator_spawn_near_teammate);
index c69c54f..6dd08bb 100644 (file)
@@ -195,6 +195,7 @@ mutators/mutator_nix.qc
 mutators/mutator_dodging.qc
 mutators/mutator_rocketflying.qc
 mutators/mutator_vampire.qc
+mutators/mutator_spawn_near_teammate.qc
 mutators/sandbox.qc
 
 ../warpzonelib/anglestransform.qc
index f6ca986..911106a 100644 (file)
@@ -635,7 +635,7 @@ void trigger_race_checkpoint_verify()
                        // race only (middle of the race)
                        g_race_qualifying = 0;
                        self.race_place = 0;
-                       if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), world, 0, FALSE, FALSE))
+                       if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), 0, FALSE))
                                error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(self.race_place), " (used for respawning in race) - bailing out"));
 
                        if(i == 0)
@@ -643,7 +643,7 @@ void trigger_race_checkpoint_verify()
                                // qualifying only
                                g_race_qualifying = 1;
                                self.race_place = race_lowest_place_spawn;
-                               if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), world, 0, FALSE, FALSE))
+                               if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), 0, FALSE))
                                        error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(self.race_place), " (used for qualifying) - bailing out"));
                                
                                // race only (initial spawn)
@@ -651,7 +651,7 @@ void trigger_race_checkpoint_verify()
                                for(p = 1; p <= race_highest_place_spawn; ++p)
                                {
                                        self.race_place = p;
-                                       if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), world, 0, FALSE, FALSE))
+                                       if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), 0, FALSE))
                                                error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(self.race_place), " (used for initially spawning in race) - bailing out"));
                                }
                        }
@@ -663,7 +663,7 @@ void trigger_race_checkpoint_verify()
                self.race_checkpoint = race_NextCheckpoint(0);
                g_race_qualifying = 1;
                self.race_place = race_lowest_place_spawn;
-               if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), world, 0, FALSE, FALSE))
+               if(!Spawn_FilterOutBadSpots(findchain(classname, "info_player_deathmatch"), 0, FALSE))
                        error(strcat("Checkpoint ", ftos(i), " misses a spawnpoint with race_place==", ftos(self.race_place), " (used for qualifying) - bailing out"));
        }
        else
@@ -764,6 +764,38 @@ void trigger_race_checkpoint_verify()
        self = oldself;
 }
 
+vector trigger_race_checkpoint_spawn_evalfunc(entity player, entity spot, vector current)
+{
+       if(g_race_qualifying)
+       {
+               // spawn at first
+               if(self.race_checkpoint != 0)
+                       return '-1 0 0';
+               if(spot.race_place != race_lowest_place_spawn)
+                       return '-1 0 0';
+       }
+       else
+       {
+               if(self.race_checkpoint != player.race_respawn_checkpoint)
+                       return '-1 0 0';
+               // try reusing the previous spawn
+               if(self == player.race_respawn_spotref || spot == player.race_respawn_spotref)
+                       current_x += SPAWN_PRIO_RACE_PREVIOUS_SPAWN;
+               if(self.race_checkpoint == 0)
+               {
+                       float pl;
+                       pl = player.race_place;
+                       if(pl > race_highest_place_spawn)
+                               pl = 0;
+                       if(pl == 0 && !player.race_started)
+                               pl = race_highest_place_spawn; // use last place if he has not even touched finish yet
+                       if(spot.race_place != pl)
+                               return '-1 0 0';
+               }
+       }
+       return current;
+}
+
 void spawnfunc_trigger_race_checkpoint()
 {
        vector o;
@@ -811,6 +843,7 @@ void spawnfunc_trigger_race_checkpoint()
        }
 
        self.sprite.waypointsprite_visible_for_player = race_waypointsprite_visible_for_player;
+       self.spawn_evalfunc = trigger_race_checkpoint_spawn_evalfunc;
 
        InitializeEntity(self, trigger_race_checkpoint_verify, INITPRIO_FINDTARGET);
 }
index e0722e7..7ec4b49 100644 (file)
@@ -231,15 +231,6 @@ void StartFrame (void)
        RuneMatchGivePoints();
        bot_serverframe();
 
-       if(autocvar_spawn_debugview)
-       {
-               RandomSelection_Init();
-               for(self = world; (self = find(self, classname, "player")); )
-                       RandomSelection_Add(self, 0, string_null, 1, 0);
-               self = RandomSelection_chosen_ent;
-               SelectSpawnPoint(0);
-       }
-
        FOR_EACH_PLAYER(self)
                self.porto_forbidden = max(0, self.porto_forbidden - 1);
 
diff --git a/scripts/mnex.shader b/scripts/mnex.shader
new file mode 100644 (file)
index 0000000..718c93e
--- /dev/null
@@ -0,0 +1,9 @@
+MNex-Diffuse
+{
+       dpglossexponentmod  64
+       dpreflectcube env/exomorph/exomorph
+       {
+               map models/weapons/mnex.tga
+               rgbgen lightingDiffuse
+       }
+}
\ No newline at end of file
index c093eb3..1243955 100644 (file)
@@ -54,14 +54,6 @@ shotgun2
                rgbgen lightingDiffuse
        }
 }
-nex
-{
-       dpreflectcube cubemaps/default/sky
-       {
-               map textures/nex.tga
-               rgbgen lightingDiffuse
-       }
-}
 rl
 {
        dpreflectcube cubemaps/default/sky
diff --git a/textures/nex.tga b/textures/nex.tga
deleted file mode 100644 (file)
index 7ff7027..0000000
Binary files a/textures/nex.tga and /dev/null differ
diff --git a/textures/nex_bump.tga b/textures/nex_bump.tga
deleted file mode 100644 (file)
index b833a51..0000000
Binary files a/textures/nex_bump.tga and /dev/null differ
diff --git a/textures/nex_gloss.tga b/textures/nex_gloss.tga
deleted file mode 100644 (file)
index 8bfd691..0000000
Binary files a/textures/nex_gloss.tga and /dev/null differ
diff --git a/textures/nex_glow.tga b/textures/nex_glow.tga
deleted file mode 100644 (file)
index aa6c324..0000000
Binary files a/textures/nex_glow.tga and /dev/null differ
diff --git a/textures/nex_norm.tga b/textures/nex_norm.tga
deleted file mode 100644 (file)
index a5bafa8..0000000
Binary files a/textures/nex_norm.tga and /dev/null differ
diff --git a/textures/nex_reflect.tga b/textures/nex_reflect.tga
deleted file mode 100644 (file)
index c44e7be..0000000
Binary files a/textures/nex_reflect.tga and /dev/null differ
diff --git a/textures/nex_shirt.tga b/textures/nex_shirt.tga
deleted file mode 100644 (file)
index 7cd8f52..0000000
Binary files a/textures/nex_shirt.tga and /dev/null differ