]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into Mario/vehicles
authorMario <zacjardine@y7mail.com>
Tue, 14 Apr 2015 23:00:35 +0000 (09:00 +1000)
committerMario <zacjardine@y7mail.com>
Tue, 14 Apr 2015 23:00:35 +0000 (09:00 +1000)
29 files changed:
defaultXonotic.cfg
mutators.cfg
qcsrc/client/effects.qc
qcsrc/client/hud.qc
qcsrc/client/hud_config.qc
qcsrc/client/main.qc
qcsrc/client/view.qc
qcsrc/common/util.qc
qcsrc/common/util.qh
qcsrc/common/weapons/w_shockwave.qc
qcsrc/common/weapons/w_vaporizer.qc
qcsrc/menu/xonotic/dialog_firstrun.qc
qcsrc/menu/xonotic/dialog_multiplayer_profile.qc
qcsrc/menu/xonotic/dialog_settings_game_hudconfirm.qc
qcsrc/menu/xonotic/slider_resolution.qc
qcsrc/server/autocvars.qh
qcsrc/server/command/cmd.qc
qcsrc/server/func_breakable.qc
qcsrc/server/g_world.qc
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/mutators/mutator_instagib.qc
qcsrc/server/mutators/mutator_nades.qc
qcsrc/server/mutators/mutator_overkill.qc
qcsrc/server/t_quake3.qc
qcsrc/server/target_spawn.qc
qcsrc/warpzonelib/mathlib.qc
qcsrc/warpzonelib/mathlib.qh
qcsrc/warpzonelib/server.qc
qcsrc/warpzonelib/util_server.qc

index f66dc0128bdb87059cb2a4433fb81f8f7365c75a..4f02d145e0276f7d66ae0a9036c3b9d9d6191cd2 100644 (file)
@@ -545,6 +545,7 @@ gl_picmip_other 1 // so, picmip -1 is best possible quality
 r_mipsprites 1
 r_mipskins 1
 r_shadow_realtime_world_lightmaps 1
+r_shadow_realtime_world_importlightentitiesfrommap 0 // Whether build process uses keepLights is nontransparent and may change, so better make keepLights not matter.
 cl_decals_fadetime 5
 cl_decals_time 1
 seta cl_gunalign 3 "Gun alignment; 1 = center (if allowed by g_shootfromclient) or right, 2 = center (if allowed by g_shootfromclient) or left, 3 = right only, 4 = left only"
index a803d8411011cb7e52f737bd6b0553eaa6cee958..2960588ff692a2d12c23cf4476b0af4756043a52 100644 (file)
@@ -41,7 +41,7 @@ set g_overkill 0 "enable overkill"
 set g_overkill_100a_anyway 1
 set g_overkill_100h_anyway 1
 set g_overkill_powerups_replace 1
-set g_overkill_superguns_respawn_time 20
+set g_overkill_superguns_respawn_time 120
 
 set g_overkill_ammo_charge 0
 set g_overkill_ammo_charge_notice 1
@@ -175,6 +175,7 @@ set g_random_gravity_negative 1000 "negative gravity multiplier"
 //  Nades
 // =======
 set g_nades 0 "enable off-hand grenades"
+set g_nades_throw_offset "0 0 0" "nade throwing offset"
 set g_nades_spawn 1 "give nades right away when player spawns rather than delaying entire refire"
 set g_nades_client_select 0 "allow client side selection of nade type"
 set g_nades_nade_lifetime 3.5
index df688465739685158b99a52f0346115d2012818b..95623505b83e297d2a7e63e12a4f78e378838d5b 100644 (file)
@@ -46,7 +46,9 @@ void cl_effects_lightningarc(vector from, vector to,float seglength,float drifts
     if(length < 1)
         return;
 
-    steps      = floor(length / seglength);
+    // Use at most 16 te_lightning1 segments, as these eat up beam list segments.
+    // TODO: Change this to R_BeginPolygon code, then we no longer have this limit.
+    steps      = min(16, floor(length / seglength));
     if(steps < 1)
     {
         te_lightning1(world,from,to);
@@ -64,8 +66,9 @@ void cl_effects_lightningarc(vector from, vector to,float seglength,float drifts
             dirnew = normalize(direction * (1 - drift) + randomvec() * drift);
             pos = pos_l +  dirnew * steplength;
             te_lightning1(world,pos_l,pos);
-            if(random() < branchfactor)
-                cl_effects_lightningarc(pos, pos + (dirnew * length * 0.25),seglength,drifts,drifte,min(branchfactor + branchfactor_add,1),branchfactor_add);
+            // WTF endless recursion if branchfactor is 1.0 (possibly due to adding branchfactor_add). FIXME
+            // if(random() < branchfactor)
+            //     cl_effects_lightningarc(pos, pos + (dirnew * length * 0.25),seglength,drifts,drifte,min(branchfactor + branchfactor_add,1),branchfactor_add);
 
             pos_l = pos;
         }
index 105cce5f2ea850f6cc95fbc25283b304e726f325..74a5df16627d45735fbbbbb876475ea428da3bf8 100644 (file)
@@ -146,6 +146,46 @@ float HUD_GetRowCount(float item_count, vector size, float item_aspect)
        return bound(1, floor((sqrt(4 * item_aspect * aspect * item_count + aspect * aspect) + aspect + 0.5) / 2), item_count);
 }
 
+vector HUD_GetTableSize(float item_count, vector psize, float item_aspect)
+{
+       float columns, rows;
+       float ratio, best_ratio = 0;
+       float best_columns = 1, best_rows = 1;
+       bool vertical = (psize.x / psize.y >= item_aspect);
+       if(vertical)
+       {
+               psize = eX * psize.y + eY * psize.x;
+               item_aspect = 1 / item_aspect;
+       }
+
+       rows = ceil(sqrt(item_count));
+       columns = ceil(item_count/rows);
+       while(columns >= 1)
+       {
+               ratio = (psize.x/columns) / (psize.y/rows);
+               if(ratio > item_aspect)
+                       ratio = item_aspect * item_aspect / ratio;
+
+               if(ratio <= best_ratio)
+                       break; // ratio starts decreasing by now, skip next configurations
+
+               best_columns = columns;
+               best_rows = rows;
+               best_ratio = ratio;
+
+               if(columns == 1)
+                       break;
+
+               --columns;
+               rows = ceil(item_count/columns);
+       }
+
+       if(vertical)
+               return eX * best_rows + eY * best_columns;
+       else
+               return eX * best_columns + eY * best_rows;
+}
+
 float stringwidth_colors(string s, vector theSize)
 {
        return stringwidth(s, true, theSize);
@@ -430,7 +470,8 @@ void HUD_Weapons(void)
        float screen_ar;
        vector center = '0 0 0';
        float weapon_count, weapon_id;
-       float row, column, rows = 0, columns;
+       float row, column, rows = 0, columns = 0;
+       bool vertical_order = true;
        float aspect = autocvar_hud_panel_weapons_aspect;
 
        float timeout = autocvar_hud_panel_weapons_timeout;
@@ -505,6 +546,17 @@ void HUD_Weapons(void)
                if(!weapons_stat)
                        for(i = WEP_FIRST; i <= WEP_LAST; i += floor((WEP_LAST-WEP_FIRST)/5))
                                weapons_stat |= WepSet_FromWeapon(i);
+
+               #if 0
+               /// debug code
+               if(cvar("wep_add"))
+               {
+                       weapons_stat = '0 0 0';
+                       float countw = 1 + floor((floor(time * cvar("wep_add"))) % WEP_COUNT);
+                       for(i = WEP_FIRST; i <= countw; ++i)
+                               weapons_stat |= WepSet_FromWeapon(i);
+               }
+               #endif
        }
 
        // determine which weapons are going to be shown
@@ -522,6 +574,7 @@ void HUD_Weapons(void)
                        if((weapons_stat & WepSet_FromWeapon(weaponorder[i].weapon)) || (weaponorder[i].weapon == complain_weapon))
                                ++weapon_count;
 
+
                // might as well commit suicide now, no reason to live ;)
                if (weapon_count == 0)
                {
@@ -533,27 +586,32 @@ void HUD_Weapons(void)
                vector padded_panel_size = panel_size - '2 2 0' * panel_bg_padding;
 
                // get the all-weapons layout
-               rows = HUD_GetRowCount(WEP_COUNT, padded_panel_size, aspect);
-               columns = ceil(WEP_COUNT / rows);
+               vector table_size = HUD_GetTableSize(WEP_COUNT, padded_panel_size, aspect);
+               columns = table_size.x;
+               rows = table_size.y;
                weapon_size.x = padded_panel_size.x / columns;
                weapon_size.y = padded_panel_size.y / rows;
 
-               // reduce rows and columns as needed
                // NOTE: although weapons should aways look the same even if onlyowned is enabled,
                // we enlarge them a bit when possible to better match the desired aspect ratio
-               if(padded_panel_size.y > padded_panel_size.x)
+               if(padded_panel_size.x / padded_panel_size.y < aspect)
                {
-                       columns = ceil(weapon_count / rows);
+                       // maximum number of rows that allows to display items with the desired aspect ratio
+                       float max_rows = floor(padded_panel_size.y / (weapon_size.x / aspect));
+                       columns = min(columns, ceil(weapon_count / max_rows));
                        rows = ceil(weapon_count / columns);
                        weapon_size.y = min(padded_panel_size.y / rows, weapon_size.x / aspect);
                        weapon_size.x = min(padded_panel_size.x / columns, aspect * weapon_size.y);
+                       vertical_order = false;
                }
                else
                {
-                       rows = ceil(weapon_count / columns);
+                       float max_columns = floor(padded_panel_size.x / (weapon_size.y * aspect));
+                       rows = min(rows, ceil(weapon_count / max_columns));
                        columns = ceil(weapon_count / rows);
                        weapon_size.x = min(padded_panel_size.x / columns, aspect * weapon_size.y);
                        weapon_size.y = min(padded_panel_size.y / rows, weapon_size.x / aspect);
+                       vertical_order = true;
                }
 
                // reduce size of the panel
@@ -691,9 +749,12 @@ void HUD_Weapons(void)
 
        if(!rows) // if rows is > 0 onlyowned code has already updated these vars
        {
-               rows = HUD_GetRowCount(weapon_count, panel_size, aspect);
-               columns = ceil(weapon_count/rows);
-               weapon_size = eX * panel_size.x*(1/columns) + eY * panel_size.y*(1/rows);
+               vector table_size = HUD_GetTableSize(WEP_COUNT, panel_size, aspect);
+               columns = table_size.x;
+               rows = table_size.y;
+               weapon_size.x = panel_size.x / columns;
+               weapon_size.y = panel_size.y / rows;
+               vertical_order = (panel_size.x / panel_size.y >= aspect);
        }
 
        // calculate position/size for visual bar displaying ammount of ammo status
@@ -850,12 +911,33 @@ void HUD_Weapons(void)
                        drawstring_aspect(weapon_pos + '1 1 0' * padding, s, weapon_size - '2 2 0' * padding, '1 1 1', panel_fg_alpha * a, DRAWFLAG_NORMAL);
                }
 
+               #if 0
+               /// debug code
+               if(!autocvar_hud_panel_weapons_onlyowned)
+               {
+                       drawfill(weapon_pos + '1 1 0', weapon_size - '2 2 0', '1 1 1', panel_fg_alpha * 0.2, DRAWFLAG_NORMAL);
+                       drawstring(weapon_pos, ftos(i + 1), label_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               }
+               #endif
+
                // continue with new position for the next weapon
-               ++row;
-               if(row >= rows)
+               if(vertical_order)
                {
-                       row = 0;
                        ++column;
+                       if(column >= columns)
+                       {
+                               column = 0;
+                               ++row;
+                       }
+               }
+               else
+               {
+                       ++row;
+                       if(row >= rows)
+                       {
+                               row = 0;
+                               ++column;
+                       }
                }
        }
 
@@ -4204,12 +4286,12 @@ void HUD_CenterPrint (void)
        {
                if(!autocvar_hud_panel_centerprint) return;
 
-               if (hud_configure_prev && hud_configure_prev != -1)
+               if(hud_configure_prev)
                        reset_centerprint_messages();
        }
        else
        {
-               if (!hud_configure_prev)
+               if(!hud_configure_prev)
                        reset_centerprint_messages();
                if (time > hud_configure_cp_generation_time)
                {
index 898f3eb56f00f9cf6bb1195ba6d31e7a41035e74..4ddc049ba167395173809af150f5cd88707525ac 100644 (file)
@@ -1233,7 +1233,7 @@ void HUD_Configure_Frame()
                        return;
                }
 
-               if(!hud_configure_prev || hud_configure_prev == -1)
+               if(!hud_configure_prev)
                {
                        if(autocvar_hud_cursormode)
                                setcursormode(1);
index aa7a1836b913ae9538cdf6355dfb42277f5ac13f..e0d8052a87fd6f9950c99e5f60dbadf4b9d4b679 100644 (file)
@@ -158,8 +158,6 @@ void CSQC_Init(void)
        WarpZone_Init();
 
        hud_skin_path = strzone(strcat("gfx/hud/", autocvar_hud_skin));
-       hud_configure_prev = -1;
-
        draw_currentSkin = strzone(strcat("gfx/menu/", cvar_string("menu_skin")));
 }
 
index 4947e9d5c6648a165a5493a58c6bbef48f1a4e2c..6eac9dac52370d7f8d89b0a9105cf7cd75d6693a 100644 (file)
@@ -761,7 +761,7 @@ void UpdateCrosshair()
                wcross_alpha_goal_prev = wcross_alpha;
                wcross_color_goal_prev = wcross_color;
 
-               if(shottype == SHOTTYPE_HITTEAM || (shottype == SHOTTYPE_HITOBSTRUCTION && autocvar_crosshair_hittest_blur && !autocvar_chase_active))
+               if(spectatee_status == -1 && shottype == SHOTTYPE_HITTEAM || (shottype == SHOTTYPE_HITOBSTRUCTION && autocvar_crosshair_hittest_blur && !autocvar_chase_active))
                {
                        wcross_blur = 1;
                        wcross_alpha *= 0.75;
index 99fecda0bbfc2855600c02a3ec2629845511f730..49d707f077be45adc59a7867322022ed9be41d96 100644 (file)
@@ -500,19 +500,6 @@ string ScoreString(int pFlags, float pValue)
        return valstr;
 }
 
-float dotproduct(vector a, vector b)
-{
-       return a.x * b.x + a.y * b.y + a.z * b.z;
-}
-
-vector cross(vector a, vector b)
-{
-       return
-               '1 0 0' * (a.y * b.z - a.z * b.y)
-       +       '0 1 0' * (a.z * b.x - a.x * b.z)
-       +       '0 0 1' * (a.x * b.y - a.y * b.x);
-}
-
 // compressed vector format:
 // like MD3, just even shorter
 //   4 bit pitch (16 angles), 0 is -90, 8 is 0, 16 would be 90
index 4de610f26fcc2113587a64019db6b55fb71ae647..b2cdf8dcaf2232be15fb675e2140d4018d686b64 100644 (file)
@@ -109,9 +109,6 @@ const float TIME_FACTOR = 100;
 
 string ScoreString(float vflags, float value);
 
-float dotproduct(vector a, vector b);
-vector cross(vector a, vector b);
-
 void compressShortVector_init();
 vector decompressShortVector(float data);
 float compressShortVector(vector vec);
index 24b8634b91dd1a6b6eb04defa40d2f8f8cecd466..3f40c5397fcfb8d34b96f4db4e0132c8b07bc5d1 100644 (file)
@@ -553,13 +553,11 @@ void W_Shockwave_Attack(void)
                        center = CENTER_OR_VIEWOFS(head);
 
                        // find the closest point on the enemy to the center of the attack
-                       float ang; // angle between shotdir and h
                        float h; // hypotenuse, which is the distance between attacker to head
                        float a; // adjacent side, which is the distance between attacker and the point on w_shotdir that is closest to head.origin
 
                        h = vlen(center - self.origin);
-                       ang = acos(dotproduct(normalize(center - self.origin), w_shotdir));
-                       a = h * cos(ang);
+                       a = h * (normalize(center - self.origin) * w_shotdir);
                        // WEAPONTODO: replace with simpler method
 
                        vector nearest_on_line = (w_shotorg + a * w_shotdir);
index 14377edb8651489cc9901c1d26d7c3c54658d74a..b67056f7e2257926c58cfdcc29bf7e1510da82b1 100644 (file)
@@ -164,8 +164,10 @@ float W_Vaporizer(float req)
                                                W_DecreaseAmmo(WEP_CVAR_SEC(vaporizer, ammo));
 
                                        // ugly instagib hack to reuse the fire mode of the laser
+                                       int oldwep = self.weapon; // we can't avoid this hack
+                                       self.weapon = WEP_BLASTER;
                                        W_Blaster_Attack(
-                                               WEP_VAPORIZER | HITTYPE_SECONDARY,
+                                               WEP_BLASTER | HITTYPE_SECONDARY,
                                                WEP_CVAR_SEC(vaporizer, shotangle),
                                                WEP_CVAR_SEC(vaporizer, damage),
                                                WEP_CVAR_SEC(vaporizer, edgedamage),
@@ -176,6 +178,7 @@ float W_Vaporizer(float req)
                                                WEP_CVAR_SEC(vaporizer, delay),
                                                WEP_CVAR_SEC(vaporizer, lifetime)
                                        );
+                                       self.weapon = oldwep;
 
                                        // now do normal refire
                                        weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(vaporizer, animtime), w_ready);
index 9c38e0e04f4eed5bafe417a2fd31e2fd5286ec5b..c9238a979313f1086226ce5082b1e2c92038aaf5 100644 (file)
@@ -59,7 +59,8 @@ void XonoticFirstRunDialog_fill(entity me)
                me.TD(me, 1, 3.75, box = makeXonoticInputBox(1, "_cl_name"));
                        box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved
                        box.maxLength = -127; // negative means encoded length in bytes
-                       box.saveImmediately = 1;
+                       box.saveImmediately = 0;  // Sorry, can't do this, it spams "name" commands.
+                       box.enableClearButton = 0;
                        label.textEntity = box;
        me.TR(me);
                me.TD(me, 5, 1.25, e = makeXonoticColorpicker(box));
index 06bf7924444ffc6651b595f2e3536bb7c7b6f931..8c24885439e8ec9b16ac9aff2837f032fc0289dd 100644 (file)
@@ -51,7 +51,7 @@ void XonoticProfileTab_fill(entity me)
                me.TD(me, 1, 3.0, box = makeXonoticInputBox(1, "_cl_name"));
                        box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved
                        box.maxLength = -127; // negative means encoded length in bytes
-                       box.saveImmediately = 1;
+                       box.saveImmediately = 0;  // Sorry, can't do this, it spams "name" commands.
                        box.enableClearButton = 0;
                        label.textEntity = box;
        me.TR(me);
index 9f327c3f51245c96cf4df83480c6eaceb88c92e5..12312c36bbe7b6b4e1e27caf235d0931fab69171 100644 (file)
@@ -13,11 +13,11 @@ ENDCLASS(XonoticHUDConfirmDialog)
 void HUDSetup_Start(entity me, entity btn)
 {
        if (!(gamestatus & (GAME_CONNECTED | GAME_ISSERVER)))
-               localcmd("map hudsetup/hudsetup", "\n");
+               localcmd("map _hudsetup\n");
        else
                localcmd("togglemenu 0\n");
 
-       localcmd("_hud_configure 1", "\n");
+       localcmd("_hud_configure 1\n");
 }
 
 void XonoticHUDConfirmDialog_fill(entity me)
index 476c441ed1a96a40afc2e3fcb2d7ff9b70a17d75..c1443628106e7b4b2947d8a86c669d6c2a2a5e88 100644 (file)
@@ -7,6 +7,8 @@ CLASS(XonoticResolutionSlider) EXTENDS(XonoticTextSlider)
        METHOD(XonoticResolutionSlider, saveCvars, void(entity))
        METHOD(XonoticResolutionSlider, draw, void(entity))
        ATTRIB(XonoticResolutionSlider, vid_fullscreen, float, -1)
+       ATTRIB(XonoticResolutionSlider, maxAllowedWidth, float, 0)
+       ATTRIB(XonoticResolutionSlider, maxAllowedHeight, float, 0)
 ENDCLASS(XonoticResolutionSlider)
 entity makeXonoticResolutionSlider();
 float updateConwidths(float width, float height, float pixelheight);
@@ -87,6 +89,10 @@ entity makeXonoticResolutionSlider()
 }
 void XonoticResolutionSlider_addResolution(entity me, float w, float h, float pixelheight)
 {
+       if (me.maxAllowedWidth && w > me.maxAllowedWidth)
+               return;
+       if (me.maxAllowedHeight && h > me.maxAllowedHeight)
+               return;
        float i;
        for (i = 0; i < me.nValues; ++i)
        {
@@ -138,6 +144,8 @@ void XonoticResolutionSlider_loadResolutions(entity me, float fullscreen)
        }
        // NOW we can safely clear.
        me.clearValues(me);
+       me.maxAllowedWidth = 0;
+       me.maxAllowedHeight = 0;
 
        if (fullscreen)
        {
@@ -161,6 +169,21 @@ void XonoticResolutionSlider_loadResolutions(entity me, float fullscreen)
 
        if(me.nValues == 0)
        {
+               // Get workarea.
+               r = getresolution(-2);
+               // If workarea is not supported, get desktop size.
+               if(r.x == 0 && r.y == 0)
+                       r = getresolution(-1);
+
+               // Add it, and limit all other resolutions to the workarea/desktop size.
+               if(r.x != 0 || r.y != 0)
+               {
+                       me.maxAllowedWidth = r.x;
+                       me.maxAllowedHeight = r.y;
+                       me.addResolution(me, r.x, r.y, r.z);
+               }
+
+               // Add nice hardcoded defaults.
                me.addResolution(me, 640, 480, 1); // pc res
 #if 0
                me.addResolution(me, 720, 480, 1.125); // DVD NTSC 4:3
index bcb9d28d70240e779e942a25b3c5764e7252298a..015c13f148c56e93b7c27ef9519de321165073f4 100644 (file)
@@ -785,6 +785,7 @@ float autocvar_g_random_gravity_positive;
 float autocvar_g_random_gravity_negative;
 float autocvar_g_random_gravity_delay;
 float autocvar_g_nades;
+vector autocvar_g_nades_throw_offset;
 float autocvar_g_nades_spawn;
 float autocvar_g_nades_spawn_count;
 float autocvar_g_nades_client_select;
index d4f2a01754d6d637f8c1eae254b1a8220f3a2fc9..e9c3af16af4d83af980e1112c8a157481602f710 100644 (file)
@@ -825,6 +825,15 @@ void ClientCommand_macro_write_aliases(float fh)
 
 void SV_ParseClientCommand(string command)
 {
+       // If invalid UTF-8, don't even parse it
+       string command2 = "";
+       float len = strlen(command);
+       float i;
+       for (i = 0; i < len; ++i)
+               command2 = strcat(command2, chr2str(str2chr(command, i)));
+       if (command != command2)
+               return;
+
        // if we're banned, don't even parse the command
        if(Ban_MaybeEnforceBanOnce(self))
                return;
index 6a651a0b0dc24e0bf3d51dfdb9813c4c2fd88b93..be6104f1fa6d2c653cc6acb25bc3f818cab46840 100644 (file)
@@ -91,7 +91,7 @@ void func_breakable_look_destroyed()
                self.dropped_origin = self.origin;
 
        if(self.mdl_dead == "")
-               self.model = "";
+               self.effects |= EF_NODRAW;
        else {
                if (self.origin == '0 0 0')     {       // probably no origin brush, so don't spawn in the middle of the map..
                        floorZ = self.absmin.z;
@@ -99,16 +99,24 @@ void func_breakable_look_destroyed()
                        self.origin_z = floorZ;
                }
                setmodel(self, self.mdl_dead);
+               self.effects &= ~EF_NODRAW;
        }
 
+       CSQCMODEL_AUTOUPDATE();
+
        self.solid = SOLID_NOT;
 }
 
 void func_breakable_look_restore()
 {
        setmodel(self, self.mdl);
+       self.effects &= ~EF_NODRAW;
+
        if(self.mdl_dead != "") // only do this if we use mdl_dead, to behave better with misc_follow
                setorigin(self, self.dropped_origin);
+
+       CSQCMODEL_AUTOUPDATE();
+
        self.solid = SOLID_BSP;
 }
 
@@ -144,7 +152,7 @@ void func_breakable_behave_restore()
 
 void func_breakable_init_for_player(entity player)
 {
-       if (self.noise1 && self.state == 0)
+       if (self.noise1 && self.state == 0 && clienttype(player) == CLIENTTYPE_REAL)
        {
                msg_entity = player;
                soundto (MSG_ONE, self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
index 5c34419ca77b6c18523660f598329c091e1b200e..ecc3005a335a22469769bc8c2e9668ac5b64eaa0 100644 (file)
@@ -315,15 +315,21 @@ void cvar_changes_init()
                // does nothing visible
                BADCVAR("captureleadlimit_override");
                BADCVAR("g_balance_kill_delay");
+               BADCVAR("g_ca_point_limit");
                BADCVAR("g_ca_point_leadlimit");
                BADCVAR("g_ctf_captimerecord_always");
                BADCVAR("g_ctf_flag_glowtrails");
                BADCVAR("g_ctf_flag_pickup_verbosename");
                BADCVAR("g_domination_point_leadlimit");
                BADCVAR("g_forced_respawn");
+               BADCVAR("g_freezetag_point_limit");
+               BADCVAR("g_freezetag_point_leadlimit");
                BADCVAR("g_keyhunt_point_leadlimit");
                BADPREFIX("g_mod_");
+               BADCVAR("g_invasion_point_limit");
                BADCVAR("g_nexball_goalleadlimit");
+               BADCVAR("g_tdm_point_limit");
+               BADCVAR("g_tdm_point_leadlimit");
                BADCVAR("leadlimit_and_fraglimit");
                BADCVAR("leadlimit_override");
                BADCVAR("pausable");
index 2e6eb4ff732533e927fc4359459ea5fec9f940f6..5ea2924cc4a40184fc80f9197ac49cebdb0dfab0 100644 (file)
@@ -89,13 +89,11 @@ float ctf_CheckPassDirection(vector head_center, vector passer_center, vector pa
                makevectors(passer_angle);
 
                // find the closest point on the enemy to the center of the attack
-               float ang; // angle between shotdir and h
                float h; // hypotenuse, which is the distance between attacker to head
                float a; // adjacent side, which is the distance between attacker and the point on w_shotdir that is closest to head.origin
 
                h = vlen(head_center - passer_center);
-               ang = acos(dotproduct(normalize(head_center - passer_center), v_forward));
-               a = h * cos(ang);
+               a = h * (normalize(head_center - passer_center) * v_forward);
 
                vector nearest_on_line = (passer_center + a * v_forward);
                float distance_from_line = vlen(nearest_to_passer - nearest_on_line);
index 141172e2fb6f1d680dc8bb36c7a3c698f7c87cb5..b3502b0f783573c6467ec9752dc13d4d13326f0b 100644 (file)
@@ -246,6 +246,18 @@ MUTATOR_HOOKFUNCTION(instagib_PlayerDamage)
 
                if(IS_PLAYER(frag_attacker))
                if(DEATH_ISWEAPON(frag_deathtype, WEP_VAPORIZER))
+               {
+                       if(frag_target.armorvalue)
+                       {
+                               frag_target.armorvalue -= 1;
+                               frag_damage = 0;
+                               frag_target.damage_dealt += 1;
+                               frag_attacker.damage_dealt += 1; // TODO: change this to a specific hitsound for armor hit
+                               Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_INSTAGIB_LIVES_REMAINING, frag_target.armorvalue);
+                       }
+               }
+
+               if(IS_PLAYER(frag_attacker) && DEATH_ISWEAPON(frag_deathtype, WEP_BLASTER))
                {
                        if(frag_deathtype & HITTYPE_SECONDARY)
                        {
@@ -257,14 +269,6 @@ MUTATOR_HOOKFUNCTION(instagib_PlayerDamage)
                                        frag_force = '0 0 0';
                                }
                        }
-                       else if(frag_target.armorvalue)
-                       {
-                               frag_target.armorvalue -= 1;
-                               frag_damage = 0;
-                               frag_target.damage_dealt += 1;
-                               frag_attacker.damage_dealt += 1; // TODO: change this to a specific hitsound for armor hit
-                               Send_Notification(NOTIF_ONE, frag_target, MSG_CENTER, CENTER_INSTAGIB_LIVES_REMAINING, frag_target.armorvalue);
-                       }
                }
        }
 
@@ -281,7 +285,7 @@ MUTATOR_HOOKFUNCTION(instagib_PlayerDamage)
                frag_mirrordamage = 0;
        }
 
-       if(frag_target.items & IT_STRENGTH)
+       if((frag_target.buffs & BUFF_INVISIBLE) || (frag_target.items & IT_STRENGTH))
                yoda = 1;
 
        return false;
index 10f1aec26b951669e6768f06556e3580f46ee181..4e91fb2e5e628d41f12076d83aaf2184df47c826 100644 (file)
@@ -551,12 +551,12 @@ void nade_boom()
 
 void nade_touch()
 {
-       float is_weapclip = 0;
+       /*float is_weapclip = 0;
        if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NODRAW)
        if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NONSOLID))
        if (!(trace_dphitcontents & DPCONTENTS_OPAQUE))
-               is_weapclip = 1;
-       if(ITEM_TOUCH_NEEDKILL() || is_weapclip)
+               is_weapclip = 1;*/
+       if(ITEM_TOUCH_NEEDKILL()) // || is_weapclip)
        {
                remove(self);
                return;
@@ -666,7 +666,13 @@ void toss_nade(entity e, vector _velocity, float _time)
 
        Kill_Notification(NOTIF_ONE_ONLY, e, MSG_CENTER_CPID, CPID_NADES);
 
-       setorigin(_nade, w_shotorg + (v_right * 25) * -1);
+       vector offset = (v_forward * autocvar_g_nades_throw_offset.x)
+                                 + (v_right * autocvar_g_nades_throw_offset.y)
+                                 + (v_up * autocvar_g_nades_throw_offset.z);
+       if(autocvar_g_nades_throw_offset == '0 0 0')
+               offset = '0 0 0';
+
+       setorigin(_nade, w_shotorg + offset + (v_right * 25) * -1);
        //setmodel(_nade, "models/weapons/v_ok_grenade.md3");
        //setattachment(_nade, world, "");
        PROJECTILE_MAKETRIGGER(_nade);
@@ -677,7 +683,7 @@ void toss_nade(entity e, vector _velocity, float _time)
        if (trace_startsolid)
                setorigin(_nade, e.origin);
 
-       if(self.v_angle.x >= 70 && self.v_angle.x <= 110)
+       if(self.v_angle.x >= 70 && self.v_angle.x <= 110 && self.BUTTON_CROUCH)
                _nade.velocity = '0 0 100';
        else if(autocvar_g_nades_nade_newton_style == 1)
                _nade.velocity = e.velocity + _velocity;
index df9e37aa68761a165d2e2e4df3748eeba86bea5c..8441c49bb92765fb7452c11b19049056c4833a16 100644 (file)
@@ -64,6 +64,7 @@ MUTATOR_HOOKFUNCTION(ok_PlayerDamage_SplitHealthArmor)
 MUTATOR_HOOKFUNCTION(ok_PlayerDies)
 {
        entity oldself = self;
+       entity targ = ((frag_attacker) ? frag_attacker : frag_target);
 
        if(self.flags & FL_MONSTER)
        {
@@ -80,7 +81,7 @@ MUTATOR_HOOKFUNCTION(ok_PlayerDies)
        self.gravity = 1;
        self.reset = SUB_Remove;
        setorigin(self, frag_target.origin + '0 0 32');
-       self.velocity = '0 0 200' + normalize(frag_attacker.origin - self.origin) * 500;
+       self.velocity = '0 0 200' + normalize(targ.origin - self.origin) * 500;
        self.classname = "droppedweapon"; // hax
        SUB_SetFade(self, time + 5, 1);
        self = oldself;
@@ -137,6 +138,8 @@ MUTATOR_HOOKFUNCTION(ok_PlayerPreThink)
                self.jump_interval = time + WEP_CVAR_PRI(blaster, refire) * W_WeaponRateFactor();
                makevectors(self.v_angle);
 
+               int oldwep = self.weapon;
+               self.weapon = WEP_BLASTER;
                W_Blaster_Attack(
                        WEP_BLASTER | HITTYPE_SECONDARY,
                        WEP_CVAR_SEC(vaporizer, shotangle),
@@ -149,6 +152,7 @@ MUTATOR_HOOKFUNCTION(ok_PlayerPreThink)
                        WEP_CVAR_SEC(vaporizer, delay),
                        WEP_CVAR_SEC(vaporizer, lifetime)
                );
+               self.weapon = oldwep;
        }
 
        self.weapon_blocked = false;
index 35b81c699a59bb2561b40f1450466ba91ea37c17..ed90bf054c0c1aeeed5668afd43c3b3e0eb09d26 100644 (file)
@@ -25,11 +25,11 @@ void spawnfunc_ammo_cells()          { spawnfunc_item_rockets();        }
 
 // Rail -> Vortex
 void spawnfunc_weapon_railgun()      { spawnfunc_weapon_vortex();          }
-void spawnfunc_ammo_slugs()          { spawnfunc_item_plasma();          }
+void spawnfunc_ammo_slugs()          { spawnfunc_item_cells();          }
 
 // BFG -> Crylink
 void spawnfunc_weapon_bfg()          { spawnfunc_weapon_crylink();      }
-void spawnfunc_ammo_bfg()            { spawnfunc_item_plasma();          }
+void spawnfunc_ammo_bfg()            { spawnfunc_item_cells();          }
 
 // RL -> RL
 void spawnfunc_ammo_rockets()        { spawnfunc_item_rockets();        }
index 28145a2934669877af6e0b0ac054afcb952bd457..b4b9b1830509f846efa7aa64f3d701600a07974b 100644 (file)
@@ -229,6 +229,9 @@ void target_spawn_edit_entity(entity e, string msg, entity kt, entity t2, entity
 
                        self = oldself;
                        activator = oldactivator;
+
+                       // We called an external function, so we have to re-tokenize msg.
+                       n = tokenize_console(msg);
                }
                else
                {
index d86af8a00ec786760c15a9440b525a7160d4a0ab..c9cde9072c34210fb2f387f137569dfa35f71d9e 100644 (file)
@@ -290,3 +290,11 @@ int isunordered(float x, float y)
 {
        return !(x < y || x == y || x > y);
 }
+
+vector cross(vector a, vector b)
+{
+       return
+               '1 0 0' * (a.y * b.z - a.z * b.y)
+       +       '0 1 0' * (a.z * b.x - a.x * b.z)
+       +       '0 0 1' * (a.x * b.y - a.y * b.x);
+}
index a37ba63de6c63b87ed3dad63d12ea1ad4637fe52..ddd494de5b8422e5560cb68301d5fada7b43d73d 100644 (file)
@@ -112,4 +112,8 @@ const float M_2_PI     = 0.63661977236758134308;  /* 2/pi */
 const float M_2_SQRTPI = 1.12837916709551257390;  /* 2/sqrt(pi) */
 const float M_SQRT2    = 1.41421356237309504880;  /* sqrt(2) */
 const float M_SQRT1_2  = 0.70710678118654752440;  /* 1/sqrt(2) */
+
+// Non-<math.h> stuff follows here.
+vector cross(vector a, vector b);
+
 #endif
index 5d529c12e215ab78c66f85c48d7c79a8f3800147..c4dc7287f1c182e79ac96e009a8000902678043c 100644 (file)
@@ -537,7 +537,7 @@ void WarpZone_InitStep_UpdateTransform()
 {
        vector org, ang, norm, point;
        float area;
-       vector tri, a, b, c, p, q, n;
+       vector tri, a, b, c, n;
        float i_s, i_t, n_t;
        string tex;
 
@@ -561,11 +561,7 @@ void WarpZone_InitStep_UpdateTransform()
                        a = getsurfacepoint(self, i_s, tri.x);
                        b = getsurfacepoint(self, i_s, tri.y);
                        c = getsurfacepoint(self, i_s, tri.z);
-                       p = b - a;
-                       q = c - a;
-                       n =     '1 0 0' * (q.y * p.z - q.z * p.y)
-                       +       '0 1 0' * (q.z * p.x - q.x * p.z)
-                       +       '0 0 1' * (q.x * p.y - q.y * p.x);
+                       n = cross(c - a, b - a);
                        area = area + vlen(n);
                        norm = norm + n;
                        point = point + vlen(n) * (a + b + c);
index 79cff0174a3a98f3c046a68777de6c07e3bb7eee..b94eafbdafd4e422af7dd6eb5c31933156dbb988 100644 (file)
@@ -77,8 +77,12 @@ void WarpZoneLib_ExactTrigger_Init()
                makevectors (self.angles);
                self.movedir = v_forward;
        }
-       self.warpzone_isboxy = 1;
-       if(self.model != "")
+       if(self.model == "")
+       {
+               // It's a box! No need to match with exacttriggers.
+               self.warpzone_isboxy = 1;
+       }
+       else
        {
                mi = self.mins;
                ma = self.maxs;
@@ -87,11 +91,11 @@ void WarpZoneLib_ExactTrigger_Init()
                // let mapper-set mins/maxs override the model's bounds if set
                if(mi != '0 0 0' || ma != '0 0 0')
                {
+                       // It's a box! No need to match with exacttriggers.
                        self.mins = mi;
                        self.maxs = ma;
+                       self.warpzone_isboxy = 1;
                }
-               else
-                       self.warpzone_isboxy = 0; // enable exacttrigger matching
        }
        setorigin(self, self.origin);
        if(self.scale)