]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into divVerent/force_colors_teamplay
authorRudolf Polzer <divverent@xonotic.org>
Thu, 24 May 2012 10:57:36 +0000 (12:57 +0200)
committerRudolf Polzer <divverent@xonotic.org>
Thu, 24 May 2012 10:57:36 +0000 (12:57 +0200)
60 files changed:
_hud_descriptions.cfg
balance25.cfg
balanceFruitieX.cfg
balanceXPM.cfg
balanceXonotic.cfg
defaultXonotic.cfg
effectinfo.txt
effects-ultra.cfg
gfx/hud/default/key_atck.tga [new file with mode: 0644]
gfx/hud/default/key_atck2.tga [new file with mode: 0644]
gfx/hud/default/key_atck2_inv.tga [new file with mode: 0644]
gfx/hud/default/key_atck_inv.tga [new file with mode: 0644]
gfx/vehicles/vth-mover.tga [new file with mode: 0644]
gfx/vehicles/vth-stationary.tga [new file with mode: 0644]
hud_luminos.cfg
hud_luminos_minimal.cfg
hud_luminos_minimal_xhair.cfg
hud_luminos_old.cfg
hud_nexuiz.cfg
qcsrc/client/Main.qc
qcsrc/client/autocvars.qh
qcsrc/client/hud.qc
qcsrc/client/hud_config.qc
qcsrc/client/tturrets.qc
qcsrc/client/vehicles/vehicles.qc
qcsrc/common/campaign_file.qc
qcsrc/common/command/markup.qc
qcsrc/common/constants.qh
qcsrc/common/items.qh
qcsrc/common/mapinfo.qc
qcsrc/common/util.qc
qcsrc/common/util.qh
qcsrc/csqcmodellib/sv_model.qc
qcsrc/menu/anim/keyframe.c
qcsrc/menu/item/inputbox.c
qcsrc/menu/item/inputcontainer.c
qcsrc/menu/item/listbox.c
qcsrc/menu/xonotic/dialog_multiplayer_create_advanced.c
qcsrc/menu/xonotic/dialog_settings_audio.c
qcsrc/menu/xonotic/util.qc
qcsrc/server/autocvars.qh
qcsrc/server/cl_client.qc
qcsrc/server/cl_weaponsystem.qc
qcsrc/server/command/cmd.qc
qcsrc/server/command/radarmap.qc
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/g_subs.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/mutators/gamemode_freezetag.qc
qcsrc/server/mutators/gamemode_keepaway.qc
qcsrc/server/mutators/gamemode_keyhunt.qc
qcsrc/server/mutators/gamemode_nexball.qc
qcsrc/server/mutators/mutator_dodging.qc
qcsrc/server/runematch.qc
qcsrc/server/vehicles/racer.qc
qcsrc/server/vehicles/vehicles.qc
qcsrc/server/w_common.qc
qcsrc/server/w_porto.qc
vehicle_racer.cfg

index 372a6af3e146f635154231a39a71b730efd96fc0..cb95f968132ba7145549310b491ec98885459a7a 100644 (file)
@@ -206,6 +206,7 @@ seta hud_panel_pressedkeys_bg_alpha "" "if set to something else than \"\" = ove
 seta hud_panel_pressedkeys_bg_border "" "if set to something else than \"\" = override default size of border around the background"
 seta hud_panel_pressedkeys_bg_padding "" "if set to something else than \"\" = override default padding of contents from border"
 seta hud_panel_pressedkeys_aspect "" "forced aspect on panel"
+seta hud_panel_pressedkeys_attack "" "show attack buttons too"
 
 seta hud_panel_chat "" "enable/disable this panel"
 seta hud_panel_chat_pos "" "position of this base of the panel"
index bea9ad263a3243ef5904d70fe8de2eca52047a3b..aafb163b441941ea73ad9a0ba736837fcc0bc25f 100644 (file)
@@ -162,6 +162,7 @@ set g_projectiles_damage 2
 // 0: only damage from contents (lava/slime) or exceptions 
 // 1: only self damage or damage from contents or exceptions
 // 2: allow all damage to projectiles normally
+set g_projectiles_keep_owner 0
 set g_projectiles_newton_style 2
 // possible values:
 // 0: absolute velocity projectiles (like Quake)
index 16286fe0f8b85eb63c3529617bef7dc2cb259a74..1bb8989120df04a0f5f3b7864c66c23ab0df2f57 100644 (file)
@@ -162,6 +162,7 @@ set g_projectiles_damage 2
 // 0: only damage from contents (lava/slime) or exceptions 
 // 1: only self damage or damage from contents or exceptions
 // 2: allow all damage to projectiles normally
+set g_projectiles_keep_owner 0
 set g_projectiles_newton_style 2
 // possible values:
 // 0: absolute velocity projectiles (like Quake)
index d3478a969f292339c212b96bc934eb284e9adc2e..759551d8d2357a4a2e53f7f1125d229659802fe7 100644 (file)
@@ -162,6 +162,7 @@ set g_projectiles_damage 1
 // 0: only damage from contents (lava/slime) or exceptions 
 // 1: only self damage or damage from contents or exceptions
 // 2: allow all damage to projectiles normally
+set g_projectiles_keep_owner 0
 set g_projectiles_newton_style 0
 // possible values:
 // 0: absolute velocity projectiles (like Quake)
index b7dbd3db8ceb72ecd803766d758db460b7b4c1bd..52c8a74d84cecfe381db5adbb156bc778f7da233 100644 (file)
@@ -162,6 +162,7 @@ set g_projectiles_damage 2
 // 0: only damage from contents (lava/slime) or exceptions 
 // 1: only self damage or damage from contents or exceptions
 // 2: allow all damage to projectiles normally
+set g_projectiles_keep_owner 0
 set g_projectiles_newton_style 2
 // possible values:
 // 0: absolute velocity projectiles (like Quake)
index 0c399bb183cde7a50c4ff80e690bd59764527ffc..ae552dd16db737b10c27d4f7f64f9519e3d01fac 100644 (file)
@@ -1645,6 +1645,9 @@ seta cl_casings_maxcount 100 "maximum amount of shell casings (must be at least
 seta cl_gibs_maxcount 100 "maximum amount of gibs (must be at least 1)"
 seta cl_vehicle_spiderbot_cross_alpha 0.6
 seta cl_vehicle_spiderbot_cross_size 1
+seta cl_vehicles_hudscale 0.5 
+seta cl_vehicles_hudalpha 0.75
+seta cl_vehicles_hud_tactical 1
 
 //cl_gunalign calculator
 seta menu_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 05c249b976d02cb746dbaa95451bd6c6f16fe9ba..5e06d075e6bf292b1c41e3889b90412272a78dd0 100644 (file)
@@ -7409,4 +7409,4 @@ velocityjitter 64 64 64
 //lightradius 50
 //lightradiusfade 50
 //lightcolor 1 0.9 0.7
-//lightshadow 1
\ No newline at end of file
+//lightshadow 1
index 4c4c09baff0321867c5d99be8f2d7eb933121c51..f92230f16f04f10ecf7df6656e7aedad21a08536 100644 (file)
@@ -1,5 +1,5 @@
 cl_decals 1
-cl_decals_models 1
+cl_decals_models 0
 cl_decals_time 10
 cl_particles_quality 1
 cl_damageeffect 1
diff --git a/gfx/hud/default/key_atck.tga b/gfx/hud/default/key_atck.tga
new file mode 100644 (file)
index 0000000..40a12dc
Binary files /dev/null and b/gfx/hud/default/key_atck.tga differ
diff --git a/gfx/hud/default/key_atck2.tga b/gfx/hud/default/key_atck2.tga
new file mode 100644 (file)
index 0000000..40a12dc
Binary files /dev/null and b/gfx/hud/default/key_atck2.tga differ
diff --git a/gfx/hud/default/key_atck2_inv.tga b/gfx/hud/default/key_atck2_inv.tga
new file mode 100644 (file)
index 0000000..c1f6e42
Binary files /dev/null and b/gfx/hud/default/key_atck2_inv.tga differ
diff --git a/gfx/hud/default/key_atck_inv.tga b/gfx/hud/default/key_atck_inv.tga
new file mode 100644 (file)
index 0000000..c1f6e42
Binary files /dev/null and b/gfx/hud/default/key_atck_inv.tga differ
diff --git a/gfx/vehicles/vth-mover.tga b/gfx/vehicles/vth-mover.tga
new file mode 100644 (file)
index 0000000..d831896
Binary files /dev/null and b/gfx/vehicles/vth-mover.tga differ
diff --git a/gfx/vehicles/vth-stationary.tga b/gfx/vehicles/vth-stationary.tga
new file mode 100644 (file)
index 0000000..31703bc
Binary files /dev/null and b/gfx/vehicles/vth-stationary.tga differ
index df836368301076d984407568c470f5bdc6efef96..6472a257963fad8c9526546031d3d6e7c716779f 100644 (file)
@@ -204,6 +204,7 @@ seta hud_panel_pressedkeys_bg_alpha ""
 seta hud_panel_pressedkeys_bg_border ""
 seta hud_panel_pressedkeys_bg_padding ""
 seta hud_panel_pressedkeys_aspect "1.600000"
+seta hud_panel_pressedkeys_attack "0"
 
 seta hud_panel_chat 1
 seta hud_panel_chat_pos "0.010000 0.700000"
index eef7aed2955353d6205e49a9598b218d4cc6f8d6..bb7e0662e32e3bcbce1060385a3f0d42a6961549 100644 (file)
@@ -204,6 +204,7 @@ seta hud_panel_pressedkeys_bg_alpha ""
 seta hud_panel_pressedkeys_bg_border ""
 seta hud_panel_pressedkeys_bg_padding ""
 seta hud_panel_pressedkeys_aspect "1.600000"
+seta hud_panel_pressedkeys_attack "0"
 
 seta hud_panel_chat 1
 seta hud_panel_chat_pos "0 0.775000"
index 0a77fba082b0c8e590bd4ff58c1bb0c5b8e0f756..e0921ad35337d272f8e0c91a0032864349981cac 100644 (file)
@@ -204,6 +204,7 @@ seta hud_panel_pressedkeys_bg_alpha ""
 seta hud_panel_pressedkeys_bg_border ""
 seta hud_panel_pressedkeys_bg_padding ""
 seta hud_panel_pressedkeys_aspect "1.600000"
+seta hud_panel_pressedkeys_attack "0"
 
 seta hud_panel_chat 1
 seta hud_panel_chat_pos "0 0.775000"
index cd4b1ba711a264fb5c2068a1cf0cc2ed09fcd2d7..119f7b18f6f8cd3f163e7e6ac172db53ed4516ad 100644 (file)
@@ -204,6 +204,7 @@ seta hud_panel_pressedkeys_bg_alpha ""
 seta hud_panel_pressedkeys_bg_border ""
 seta hud_panel_pressedkeys_bg_padding ""
 seta hud_panel_pressedkeys_aspect "1.600000"
+seta hud_panel_pressedkeys_attack "0"
 
 seta hud_panel_chat 1
 seta hud_panel_chat_pos "0.020000 0.780000"
index 67bbde531da8e03e03a4c2e7fb3c8e8ef9f119f8..3cf0feb753e5e08b748ce408a03f42affc78393d 100644 (file)
@@ -204,6 +204,7 @@ seta hud_panel_pressedkeys_bg_alpha ""
 seta hud_panel_pressedkeys_bg_border ""
 seta hud_panel_pressedkeys_bg_padding ""
 seta hud_panel_pressedkeys_aspect "1.600000"
+seta hud_panel_pressedkeys_attack "0"
 
 seta hud_panel_chat 1
 seta hud_panel_chat_pos "0 0.760000"
index 6072652cd92b845b9d91ddaec16aed26cca39251..ec258e27d708af15be8fe763a3d6477900063dfa 100644 (file)
@@ -178,7 +178,7 @@ void CSQC_Init(void)
        DamageInfo_Precache();
        Vehicles_Precache();
        turrets_precache();
-  Announcer_Precache();
+    Announcer_Precache();
        Tuba_Precache();
        
        if(autocvar_cl_reticle)
index 01718c9429aef7a0204045ffe77a138fa6b022f0..dd482a8f252a73de57d9a51ee3976df07e4a5662 100644 (file)
@@ -67,6 +67,7 @@ float autocvar_cl_reticle_stretch;
 float autocvar_cl_stripcolorcodes;
 var float autocvar_cl_vehicle_spiderbot_cross_alpha = 0.6;
 var float autocvar_cl_vehicle_spiderbot_cross_size = 1;
+var float autocvar_cl_vehicles_hud_tactical = 1;
 float autocvar_cl_velocityzoom;
 var float autocvar_cl_velocityzoom_type = 3;
 float autocvar_cl_velocityzoom_speed;
@@ -279,6 +280,7 @@ string autocvar_hud_panel_powerups_progressbar_superweapons;
 float autocvar_hud_panel_powerups_text;
 float autocvar_hud_panel_pressedkeys;
 float autocvar_hud_panel_pressedkeys_aspect;
+float autocvar_hud_panel_pressedkeys_attack;
 float autocvar_hud_panel_racetimer;
 float autocvar_hud_panel_radar;
 float autocvar_hud_panel_radar_foreground_alpha;
index ffd95f4feff69a5896f1fab4ef85e62ce9cd6082..27e0a0dc12cad21aa76e9c1337b5ca01dd46dfef 100644 (file)
@@ -3996,10 +3996,17 @@ void HUD_DrawPressedKeys(void)
        }
 
        vector keysize;
-       keysize = eX * mySize_x * (1/3) + eY * mySize_y * 0.5;
+       keysize = eX * mySize_x * (1/3.0) + eY * mySize_y * (1/(3.0 - !autocvar_hud_panel_pressedkeys_attack));
        float pressedkeys;
        pressedkeys = getstatf(STAT_PRESSED_KEYS);
 
+       if(autocvar_hud_panel_pressedkeys_attack)
+       {
+               drawpic_aspect_skin(pos + eX * keysize_x * 0.5, ((pressedkeys & KEY_ATCK) ? "key_atck_inv.tga" : "key_atck.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               drawpic_aspect_skin(pos + eX * keysize_x * 1.5, ((pressedkeys & KEY_ATCK2) ? "key_atck_inv.tga" : "key_atck.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+               pos_y += keysize_y;
+       }
+
        drawpic_aspect_skin(pos, ((pressedkeys & KEY_CROUCH) ? "key_crouch_inv.tga" : "key_crouch.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
        drawpic_aspect_skin(pos + eX * keysize_x, ((pressedkeys & KEY_FORWARD) ? "key_forward_inv.tga" : "key_forward.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
        drawpic_aspect_skin(pos + eX * keysize_x * 2, ((pressedkeys & KEY_JUMP) ? "key_jump_inv.tga" : "key_jump.tga"), keysize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
index a53112bbd4b0495fe21483484b7818ebfd93c31c..0f990c69410d2646ccb0f8dca6a2281d6f46e3be 100644 (file)
@@ -138,6 +138,7 @@ void HUD_Panel_ExportCfg(string cfgname)
                                        HUD_Write_PanelCvar_q("_dom_layout");
                                        break;
                                case HUD_PANEL_PRESSEDKEYS:
+                                       HUD_Write_PanelCvar_q("_attack");
                                        HUD_Write_PanelCvar_q("_aspect");
                                        break;
                                case HUD_PANEL_ENGINEINFO:
index 2b9ec0297b2ef63411d210cc8a8597bc8438691f..d7abeb0919de42e95d278942f363cb9009336b96 100644 (file)
@@ -235,36 +235,46 @@ void turret_draw2d()
         return; 
 
        float dist = vlen(self.origin - view_origin);
+    float t = (GetPlayerColor(player_localnum) + 1);   
+
        vector o;
-       /*
-       // TODO: Vehicle tactical hud
-       o = project_3d_to_2d(self.origin + '0 0 32');
-       if(o_z < 0 
-       || o_x < (vid_conwidth * waypointsprite_edgeoffset_left) 
-       || o_y < (vid_conheight * waypointsprite_edgeoffset_top) 
-       || o_x > (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right))  
-       || o_y > (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)))
-           return; // Dont draw wp's for turrets out of view
-    o_z = 0;
-    if(hud != HUD_NORMAL)
-    {        
-        switch(hud)
-        {
-            case HUD_SPIDERBOT:
-            case HUD_WAKIZASHI:
-            case HUD_RAPTOR:
-                vector pz = drawgetimagesize("gfx/vehicles/axh-bracket.tga") * 0.25;
-                drawpic(o - pz * 0.5 , "gfx/vehicles/axh-bracket.tga", pz , '1 1 1', 0.75, DRAWFLAG_NORMAL);
-                break;
+       string txt;
+       
+       if(autocvar_cl_vehicles_hud_tactical)
+       if(dist < 10240 && t != self.team)
+       {
+        // TODO: Vehicle tactical hud
+        o = project_3d_to_2d(self.origin + '0 0 32');
+        if(o_z < 0 
+        || o_x < (vid_conwidth * waypointsprite_edgeoffset_left) 
+        || o_y < (vid_conheight * waypointsprite_edgeoffset_top) 
+        || o_x > (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right))  
+        || o_y > (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)))
+            return; // Dont draw wp's for turrets out of view
+        o_z = 0;
+        if(hud != HUD_NORMAL)
+        {        
+            switch(hud)
+            {
+                case HUD_SPIDERBOT:
+                case HUD_WAKIZASHI:
+                case HUD_RAPTOR:
+                    if(self.turret_type == TID_EWHEEL || self.turret_type == TID_WALKER)
+                        txt = "gfx/vehicles/vth-mover.tga";
+                    else
+                        txt = "gfx/vehicles/vth-stationary.tga";
+                        
+                    vector pz = drawgetimagesize(txt) * 0.25;
+                    drawpic(o - pz * 0.5, txt, pz , '1 1 1', 0.75, DRAWFLAG_NORMAL);
+                    break;
+            }
         }
-    }
-    */
+       }
     
        if(dist > self.maxdistance)
         return;
 
        string spriteimage = self.netname;
-       float t = (GetPlayerColor(player_localnum) + 1);        
        float a = self.alpha * autocvar_hud_panel_fg_alpha;
        vector rgb = spritelookupcolor(spriteimage, self.teamradar_color);
 
@@ -280,7 +290,7 @@ void turret_draw2d()
                print(sprintf("WARNING: sprite of name %s has no color, using pink so you notice it\n", spriteimage)); 
        }
 
-       string txt = self.netname;
+       txt = self.netname;
        if(autocvar_g_waypointsprite_spam && waypointsprite_count >= autocvar_g_waypointsprite_spam)
                txt = _("Spam");
        else
@@ -540,37 +550,38 @@ entity turret_gibtoss(string _model, vector _from, vector _to, vector _cmod, flo
 
 void turret_die()
 {    
-    entity headgib;
     
     sound (self, CH_SHOTS, "weapons/rocket_impact.wav", VOL_BASE, ATTN_NORM);
     pointparticles(particleeffectnum("rocket_explode"), self.origin, '0 0 0', 1);
     turret_tid2info(self.turret_type);
-    
-    // Base
-    if(self.turret_type == TID_EWHEEL)
-        turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', TRUE);
-    else if (self.turret_type == TID_WALKER)
-        turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', TRUE);
-    else if (self.turret_type == TID_TESLA)
-        turret_gibtoss(tid2info_base, self.origin + '0 0 18', '0 0 200', '-1 -1 -1', FALSE);
-    else
-    {        
-        if (random() > 0.5)
-        {            
-            turret_gibtoss("models/turrets/base-gib2.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', FALSE);
-            turret_gibtoss("models/turrets/base-gib3.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', FALSE);
-            turret_gibtoss("models/turrets/base-gib4.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', FALSE);
-        }
+    if (!autocvar_cl_nogibs)
+    {
+        // Base
+        if(self.turret_type == TID_EWHEEL)
+            turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 400' + '0.1 0.1 1' * (random() * 400), '-1 -1 -1', TRUE);
+        else if (self.turret_type == TID_WALKER)
+            turret_gibtoss(tid2info_base, self.origin + '0 0 18', self.velocity + '0 0 300' + '0.1 0.1 1' * (random() * 200), '-1 -1 -1', TRUE);
+        else if (self.turret_type == TID_TESLA)
+            turret_gibtoss(tid2info_base, self.origin + '0 0 18', '0 0 200', '-1 -1 -1', FALSE);
         else
-            turret_gibtoss("models/turrets/base-gib1.md3", self.origin + '0 0 8', '0 0 0', '0 0 0', TRUE);
-
-        headgib = turret_gibtoss(tid2info_head, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', TRUE);
-        if(headgib)
-        {
-            headgib.angles = headgib.move_angles = self.tur_head.angles;
-            headgib.avelocity = headgib.move_avelocity = self.tur_head.move_avelocity + randomvec() * 45;
-            headgib.avelocity_y = headgib.move_avelocity_y = headgib.move_avelocity_y * 5;
-            headgib.gravity = 0.5;        
+        {        
+            if (random() > 0.5)
+            {            
+                turret_gibtoss("models/turrets/base-gib2.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', FALSE);
+                turret_gibtoss("models/turrets/base-gib3.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', FALSE);
+                turret_gibtoss("models/turrets/base-gib4.md3", self.origin + '0 0 8', '0 0 50' + randomvec() * 150, '0 0 0', FALSE);
+            }
+            else
+                turret_gibtoss("models/turrets/base-gib1.md3", self.origin + '0 0 8', '0 0 0', '0 0 0', TRUE);
+
+            entity headgib = turret_gibtoss(tid2info_head, self.origin + '0 0 32', '0 0 200' + randomvec() * 200, '-1 -1 -1', TRUE);
+            if(headgib)
+            {
+                headgib.angles = headgib.move_angles = self.tur_head.angles;
+                headgib.avelocity = headgib.move_avelocity = self.tur_head.move_avelocity + randomvec() * 45;
+                headgib.avelocity_y = headgib.move_avelocity_y = headgib.move_avelocity_y * 5;
+                headgib.gravity = 0.5;        
+            }
         }
     }
     
index ccb9cff58363374f82761aa58899984b800b86f8..6081f5a66efdd6ea1e23d947adeb1f3c0a953609 100644 (file)
@@ -661,11 +661,13 @@ void CSQC_WAKIZASHI_HUD()
 void Vehicles_Precache()
 {
 // fixme: HAAAAKKKZZZ!!!!!!!!!!!! (this belongs as a setting in default.cfg)
-    autocvar_cl_vehicles_hudscale = 0.5;
-    autocvar_cl_vehicles_hudalpha = 0.75;
-
+    if(!autocvar_cl_vehicles_hudscale )
+        autocvar_cl_vehicles_hudscale = 0.5;
+    
+    if(!autocvar_cl_vehicles_hudalpha)
+        autocvar_cl_vehicles_hudalpha = 0.75;
 
-       precache_model("models/vehicles/wakizashi.dpm");
+       //precache_model("models/vehicles/wakizashi.dpm");
 
        precache_model("models/vehicles/bomblet.md3");
        precache_model("models/vehicles/clusterbomb.md3");
index 067cd8054de6f311d562bf427190fd806ef1de79..5ab3da67cff47e58a34f3731b1d330d256bb3526 100644 (file)
@@ -38,13 +38,12 @@ float CampaignFile_Load(float offset, float n)
                        {
                                entlen = tokenize(l); // using insane tokenizer for CSV
 
-#define CAMPAIGN_GETARG0                  if(i >= entlen)
-#define CAMPAIGN_GETARG1 CAMPAIGN_GETARG0     error("syntax error in campaign file: line has not enough fields");
-#define CAMPAIGN_GETARG2 CAMPAIGN_GETARG1 a = argv(++i);
-#define CAMPAIGN_GETARG3 CAMPAIGN_GETARG2 if(a == ",")
-#define CAMPAIGN_GETARG4 CAMPAIGN_GETARG3     a = "";
-#define CAMPAIGN_GETARG5 CAMPAIGN_GETARG4 else
-#define CAMPAIGN_GETARG  CAMPAIGN_GETARG5     ++i
+#define CAMPAIGN_GETARG \
+       a = argv(++i); \
+       if(a == ",") \
+               a = ""; \
+       else \
+               ++i
 // What you're seeing here is what people will do when your compiler supports
 // C-style macros but no line continuations.
 
@@ -58,6 +57,10 @@ float CampaignFile_Load(float offset, float n)
                                CAMPAIGN_GETARG; campaign_mutators[campaign_entries] = strzone(a);
                                CAMPAIGN_GETARG; campaign_shortdesc[campaign_entries] = strzone(a);
                                CAMPAIGN_GETARG; campaign_longdesc[campaign_entries] = strzone(strreplace("\\n", "\n", a));
+
+                               if(i > entlen)
+                                       error("syntax error in campaign file: line has not enough fields");
+
                                campaign_entries = campaign_entries + 1;
 
                                if(campaign_entries >= n)                               
index cb1a8cc37144eb23c069b6b1294ccb5510073520..d1562aaac4222c1ebf8eedbbfdf60f7d22ffc001 100644 (file)
@@ -51,6 +51,7 @@ void GenericCommand_markup_init()
        markup_from[i] = "&.."; markup_to[i] = "\x9e"; ++i;
        markup_from[i] = "&.)"; markup_to[i] = "\x9f"; ++i;
        markup_from[i] = "&<|"; markup_to[i] = "\xff"; ++i;
+       unused_float = i;
 }
 
 string GenericCommand_markup(string s2)
index e70a83c391d7b992ce0091e91efc89504fa31c4d..d0149251f49f6827c80eb06eb33e246ed6b9b069 100644 (file)
@@ -127,6 +127,8 @@ const float KEY_LEFT                =       4;
 const float KEY_RIGHT          =       8;
 const float KEY_JUMP           =       16;
 const float KEY_CROUCH         =       32;
+const float KEY_ATCK           =       64;
+const float KEY_ATCK2          =       128;
 
 ///////////////////////////
 // cvar constants
index 5a39d2148c045b1d155250cf8ae71432adbab85a..33fa21f7eeef5fb96bb0986971ce5223f27d0979 100644 (file)
@@ -101,11 +101,16 @@ float WEP_LAST;
 # define WEPSET_BIT(a)                  power2of((a) - WEP_FIRST)
 # define WEPSET_DECLARE_A(a)            float _WS_##a
 # define WEPSET_CLEAR_E(e)              ((e)._WS_weapons = 0)
-# define WEPSET_CLEAR_A(a)              ((_WS_##a) = 0)
+# define WEPSET_CLEAR_A(a)              (_WS_##a = 0)
 # define WEPSET_EMPTY_E(e)              ((e)._WS_weapons == 0)
-# define WEPSET_EMPTY_A(a)              ((_WS_##a) == 0)
-# define WEPSET_COPY_AS(a)              ((_WS_##a) = getstati(STAT_WEAPONS))
+# define WEPSET_EMPTY_A(a)              (_WS_##a == 0)
+# define WEPSET_COPY_AS(a)              (_WS_##a = getstati(STAT_WEAPONS))
 # define WEPSET_ADDSTAT()               addstat(STAT_WEAPONS, AS_INT, _WS_weapons)
+# define WEPSET_WRITE_E(dest,a)         WriteInt24_t(dest, (a)._WS_weapons)
+# define WEPSET_WRITE_A(dest,a)         WriteInt24_t(dest, _WS_##a)
+# define WEPSET_WRITE_W(dest,a)         WriteInt24_t(dest, WEPSET_BIT(a))
+# define WEPSET_READ_E(a)               (a)._WS_weapons = ReadInt24_t()
+# define WEPSET_READ_A(a)               (_WS_##a) = ReadInt24_t()
 # define WEPSET_OP1_EE(a,b,mergeop,x)   ((a)._WS_weapons x (b)._WS_weapons)
 # define WEPSET_OP2_EE(a,b,mergeop,x,y) ((a)._WS_weapons x (b)._WS_weapons y (a)._WS_weapons)
 # define WEPSET_OP1_EA(a,b,mergeop,x)   ((a)._WS_weapons x _WS_##b)
@@ -132,6 +137,11 @@ float WEP_LAST;
 # define WEPSET_EMPTY_A(a)              ((_WS1_##a) == 0 && (_WS2_##a) == 0)
 # define WEPSET_COPY_AS(a)              ((_WS1_##a) = getstati(STAT_WEAPONS), (_WS2_##a) = getstati(STAT_WEAPONS2))
 # define WEPSET_ADDSTAT()               addstat(STAT_WEAPONS, AS_INT, _WS1_weapons); addstat(STAT_WEAPONS2, AS_INT, _WS2_weapons)
+# define WEPSET_WRITE_E(dest,a)         WriteInt24_t(dest, (a)._WS1_weapons); WriteInt24_t(dest, (a)._WS2_weapons)
+# define WEPSET_WRITE_A(dest,a)         WriteInt24_t(dest, _WS1_##a); WriteInt24_t(dest, _WS2_##a)
+# define WEPSET_WRITE_W(dest,a)         WriteInt24_t(dest, WEPSET_BIT1(a)); WriteInt24_t(dest, WEPSET_BIT2(a))
+# define WEPSET_READ_E(a)               (a)._WS1_weapons = ReadInt24_t(); (a)._WS2_weapons = ReadInt24_t()
+# define WEPSET_READ_A(a)               (_WS1_##a) = ReadInt24_t(); (_WS2_##a) = ReadInt24_t()
 # define WEPSET_OP1_EE(a,b,mergeop,x)   (((a)._WS1_weapons x (b)._WS1_weapons) mergeop ((a)._WS2_weapons x (b)._WS2_weapons))
 # define WEPSET_OP2_EE(a,b,mergeop,x,y) (((a)._WS1_weapons x (b)._WS1_weapons y (a)._WS1_weapons) mergeop ((a)._WS2_weapons x (b)._WS2_weapons y (a)._WS2_weapons))
 # define WEPSET_OP1_EA(a,b,mergeop,x)   (((a)._WS1_weapons x _WS1_##b) mergeop ((a)._WS2_weapons x _WS2_##b))
index 9de5098cb349febadfccd332700803fb69abd337..05c93865dbcceed7c2606d9cb567b727e3fe8ad7 100644 (file)
@@ -945,7 +945,7 @@ float MapInfo_Get_ByName_NoFallbacks(string pFilename, float pAllowGenerate, flo
                        MapInfo_Map_author = s;
                else if(t == "has")
                {
-                       t = car(s); s = cdr(s);
+                       t = car(s); // s = cdr(s);
                        if     (t == "weapons") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_WEAPONS;
                        else if(t == "turrets") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_TURRETS;
                        else if(t == "vehicles") MapInfo_Map_supportedFeatures |= MAPINFO_FEATURE_VEHICLES;
index a1e0595891b5bf723ee8a7c41d1ce6c4e8ee1acc..6e534ffc19464a92777b956353b926f48ddd578e 100644 (file)
@@ -1580,6 +1580,109 @@ vector solve_quadratic(float a, float b, float c) // ax^2 + bx + c = 0
        return v;
 }
 
+vector solve_shotdirection(vector myorg, vector myvel, vector eorg, vector evel, float spd, float newton_style)
+{
+       vector ret;
+
+       // make origin and speed relative
+       eorg -= myorg;
+       if(newton_style)
+               evel -= myvel;
+
+       // now solve for ret, ret normalized:
+       //   eorg + t * evel == t * ret * spd
+       // or, rather, solve for t:
+       //   |eorg + t * evel| == t * spd
+       //   eorg^2 + t^2 * evel^2 + 2 * t * (eorg * evel) == t^2 * spd^2
+       //   t^2 * (evel^2 - spd^2) + t * (2 * (eorg * evel)) + eorg^2 == 0
+       vector solution = solve_quadratic(evel * evel - spd * spd, 2 * (eorg * evel), eorg * eorg);
+       // p = 2 * (eorg * evel) / (evel * evel - spd * spd)
+       // q = (eorg * eorg) / (evel * evel - spd * spd)
+       if(!solution_z) // no real solution
+       {
+               // happens if D < 0
+               // (eorg * evel)^2 < (evel^2 - spd^2) * eorg^2
+               // (eorg * evel)^2 / eorg^2 < evel^2 - spd^2
+               // spd^2 < ((evel^2 * eorg^2) - (eorg * evel)^2) / eorg^2
+               // spd^2 < evel^2 * (1 - cos^2 angle(evel, eorg))
+               // spd^2 < evel^2 * sin^2 angle(evel, eorg)
+               // spd < |evel| * sin angle(evel, eorg)
+               return '0 0 0';
+       }
+       else if(solution_x > 0)
+       {
+               // both solutions > 0: take the smaller one
+               // happens if p < 0 and q > 0
+               ret = normalize(eorg + solution_x * evel);
+       }
+       else if(solution_y > 0)
+       {
+               // one solution > 0: take the larger one
+               // happens if q < 0 or q == 0 and p < 0
+               ret = normalize(eorg + solution_y * evel);
+       }
+       else
+       {
+               // no solution > 0: reject
+               // happens if p > 0 and q >= 0
+               // 2 * (eorg * evel) / (evel * evel - spd * spd) > 0
+               // (eorg * eorg) / (evel * evel - spd * spd) >= 0
+               //
+               // |evel| >= spd
+               // eorg * evel > 0
+               //
+               // "Enemy is moving away from me at more than spd"
+               return '0 0 0';
+       }
+
+       // NOTE: we always got a solution if spd > |evel|
+
+       if(newton_style == 2)
+               ret = normalize(ret * spd + myvel);
+
+       return ret;
+}
+
+vector get_shotvelocity(vector myvel, vector mydir, float spd, float newton_style, float mi, float ma)
+{
+       if(!newton_style)
+               return spd * mydir;
+
+       if(newton_style == 2)
+       {
+               // true Newtonian projectiles with automatic aim adjustment
+               //
+               // solve: |outspeed * mydir - myvel| = spd
+               // outspeed^2 - 2 * outspeed * (mydir * myvel) + myvel^2 - spd^2 = 0
+               // outspeed = (mydir * myvel) +- sqrt((mydir * myvel)^2 - myvel^2 + spd^2)
+               // PLUS SIGN!
+               // not defined?
+               // then...
+               // myvel^2 - (mydir * myvel)^2 > spd^2
+               // velocity without mydir component > spd
+               // fire at smallest possible spd that works?
+               // |(mydir * myvel) * myvel - myvel| = spd
+
+               vector solution = solve_quadratic(1, -2 * (mydir * myvel), myvel * myvel - spd * spd);
+
+               float outspeed;
+               if(solution_z)
+                       outspeed = solution_y; // the larger one
+               else
+               {
+                       //outspeed = 0; // slowest possible shot
+                       outspeed = solution_x; // the real part (that is, the average!)
+                       //dprint("impossible shot, adjusting\n");
+               }
+
+               outspeed = bound(spd * mi, outspeed, spd * ma);
+               return mydir * outspeed;
+       }
+
+       // real Newtonian
+       return myvel + spd * mydir;
+}
+
 void check_unacceptable_compiler_bugs()
 {
        if(cvar("_allow_unacceptable_compiler_bugs"))
@@ -2261,3 +2364,55 @@ void queue_to_execute_next_frame(string s)
        }
        to_execute_next_frame = strzone(s);
 }
+
+float cubic_speedfunc(float startspeedfactor, float endspeedfactor, float x)
+{
+       return
+               (((     startspeedfactor + endspeedfactor - 2
+               ) * x - 2 * startspeedfactor - endspeedfactor + 3
+               ) * x + startspeedfactor
+               ) * x;
+}
+
+float cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor)
+{
+       if(startspeedfactor < 0 || endspeedfactor < 0)
+               return FALSE;
+
+       /*
+       // if this is the case, the possible zeros of the first derivative are outside
+       // 0..1
+       We can calculate this condition as condition 
+       if(se <= 3)
+               return TRUE;
+       */
+
+       // better, see below:
+       if(startspeedfactor <= 3 && endspeedfactor <= 3)
+               return TRUE;
+
+       // if this is the case, the first derivative has no zeros at all
+       float se = startspeedfactor + endspeedfactor;
+       float s_e = startspeedfactor - endspeedfactor;
+       if(3 * (se - 4) * (se - 4) + s_e * s_e <= 12) // an ellipse
+               return TRUE;
+
+       // Now let s <= 3, s <= 3, s+e >= 3 (triangle) then we get se <= 6 (top right corner).
+       // we also get s_e <= 6 - se
+       // 3 * (se - 4)^2 + (6 - se)^2
+       // is quadratic, has value 12 at 3 and 6, and value < 12 in between.
+       // Therefore, above "better" check works!
+
+       return FALSE;
+
+       // known good cases:
+       // (0, [0..3])
+       // (0.5, [0..3.8])
+       // (1, [0..4])
+       // (1.5, [0..3.9])
+       // (2, [0..3.7])
+       // (2.5, [0..3.4])
+       // (3, [0..3])
+       // (3.5, [0.2..2.3])
+       // (4, 1)
+}
index 64830ca1d73330931919e01e2b5d537f8c5141ab..3ce173bf638e95d705a70042fc6bfae62f4838aa 100644 (file)
@@ -168,6 +168,9 @@ vector solve_quadratic(float a, float b, float c);
 // z = 1 if a real solution exists, 0 if not
 // if no real solution exists, x contains the real part and y the imaginary part of the complex solutions x+iy and x-iy
 
+vector solve_shotdirection(vector myorg, vector myvel, vector eorg, vector evel, float spd, float newton_style);
+vector get_shotvelocity(vector myvel, vector mydir, float spd, float newton_style, float mi, float ma);
+
 void check_unacceptable_compiler_bugs();
 
 float compressShotOrigin(vector v);
@@ -314,3 +317,20 @@ float ReadApproxPastTime();
 // execute-stuff-next-frame subsystem
 void execute_next_frame();
 void queue_to_execute_next_frame(string s);
+
+// for marking written-to values as unused where it's a good idea to do this
+noref float unused_float;
+
+
+
+// a function f with:
+// f(0) = 0
+// f(1) = 1
+// f'(0) = startspeedfactor
+// f'(1) = endspeedfactor
+float cubic_speedfunc(float startspeedfactor, float endspeedfactor, float x);
+
+// checks whether f'(x) = 0 anywhere from 0 to 1
+// because if this is the case, the function is not usable for platforms
+// as it may exceed 0..1 bounds, or go in reverse
+float cubic_speedfunc_is_sane(float startspeedfactor, float endspeedfactor);
index bf6eefa6971b0b0c3f9687c61e60608e9e13ff3d..e6e4cfe43a091e3f2fd1a5efa615a8e2d6132e66 100644 (file)
@@ -29,6 +29,10 @@ float CSQCModel_Send(entity to, float sf)
        float islocalplayer = (self == to);
        float isnolocalplayer = (isplayer && (self != to));
 
+       unused_float = isplayer;
+       unused_float = islocalplayer;
+       unused_float = isnolocalplayer;
+
        WriteByte(MSG_ENTITY, ENT_CLIENT_MODEL);
        WriteShort(MSG_ENTITY, sf);
 
@@ -59,6 +63,10 @@ void CSQCModel_CheckUpdate()
        float islocalplayer = isplayer; // we set BOTH to 1 here as we need the sendflags
        float isnolocalplayer = isplayer; // we set BOTH to 1 here as we need the sendflags
 
+       unused_float = isplayer;
+       unused_float = islocalplayer;
+       unused_float = isnolocalplayer;
+
 #ifdef CSQCPLAYER_FORCE_UPDATES
        if(isplayer && time > self.csqcmodel_nextforcedupdate)
        {
index de5d54ae1002ad79486867e1a8f4d83da5a152f0..3bcda94e692939b733c668cf09e46b27e59364c6 100644 (file)
@@ -75,8 +75,7 @@ void Keyframe_addAnim(entity me, entity other)
 
        other.parent = me;
 
-       entity f, l;
-       f = me.firstChild;
+       entity l;
        l = me.lastChild;
 
        if(l)
index af6587b5a67ebca90ecdb614524bd94923b5fdd0..572d3a0710dd866bef056667cb2862165d80cf0b 100644 (file)
@@ -226,7 +226,6 @@ void InputBox_draw(entity me)
                                else if(ch2 == "x") // ^x found
                                {
                                        theColor = '1 1 1';
-                                       theTempColor = '0 0 0';
                                        
                                        component = HEXDIGIT_TO_DEC(substring(me.text, i+2, 1));
                                        if (component >= 0) // ^xr found
index e1b14d3b1602d468d08ccdf6b26ef0aaf48b43df..65129b294dd6c0229436da186734c244d30b6b6f 100644 (file)
@@ -153,8 +153,7 @@ float InputContainer_mousePress(entity me, vector pos)
 }
 float InputContainer_mouseRelease(entity me, vector pos)
 {
-       float r;
-       r = SUPER(InputContainer).mouseRelease(me, pos);
+       SUPER(InputContainer).mouseRelease(me, pos); // return value?
        if(me.focused) // am I still eligible for this? (UGLY HACK, but a mouse event could have changed focus away)
                if(me._changeFocusXY(me, pos))
                        return 1;
index 4f8dca622c239e0294ba023b68f8101f737c6f15..0c4f349029236d78c365cc6afdc99df033809ac4 100644 (file)
@@ -182,7 +182,6 @@ float ListBox_mouseRelease(entity me, vector pos)
                // and give it a nice click event
                if(me.nItems > 0)
                {
-                       absSize = boxToGlobalSize(me.size, eX * (1 - me.controlWidth) + eY * me.itemHeight);
                        me.clickListBoxItem(me, me.selectedItem, globalToBox(pos, eY * (me.selectedItem * me.itemHeight - me.scrollPos), eX * (1 - me.controlWidth) + eY * me.itemHeight));
                }
        }
index 226f346b643ae55e715a7b5e5cf87eea887412cf..3fcabaaab6f8aa2e25030b7e420c45b52f308baf 100644 (file)
@@ -25,36 +25,36 @@ void XonoticAdvancedDialog_fill(entity me)
                me.TD(me, 1, 3, makeXonoticTextLabel(0, _("Game settings:")));
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 2.8, e = makeXonoticCheckBox(0, "sv_spectate", _("Allow spectating")));
+               me.TD(me, 1, 2.8, makeXonoticCheckBox(0, "sv_spectate", _("Allow spectating")));
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Spawn shield:")));
-               me.TD(me, 1, 1.6, e = makeXonoticSlider(0, 15, 0.5, "g_spawnshieldtime"));
+               me.TD(me, 1, 1.2, makeXonoticTextLabel(0, _("Spawn shield:")));
+               me.TD(me, 1, 1.6, makeXonoticSlider(0, 15, 0.5, "g_spawnshieldtime"));
        me.TR(me);
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Game speed:")));
-               me.TD(me, 1, 1.6, e = makeXonoticSlider(0.5, 2.0, 0.1, "slowmo"));
+               me.TD(me, 1, 1.2, makeXonoticTextLabel(0, _("Game speed:")));
+               me.TD(me, 1, 1.6, makeXonoticSlider(0.5, 2.0, 0.1, "slowmo"));
        me.TR(me);
        me.TR(me);
                me.TD(me, 1, 3, makeXonoticTextLabel(0, _("Teamplay settings:")));
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Friendly fire scale:")));
-               me.TD(me, 1, 1.6, e = makeXonoticSlider(0, 1.0, 0.05, "g_friendlyfire"));
+               me.TD(me, 1, 1.2, makeXonoticTextLabel(0, _("Friendly fire scale:")));
+               me.TD(me, 1, 1.6, makeXonoticSlider(0, 1.0, 0.05, "g_friendlyfire"));
        me.TR(me);
                me.TDempty(me, 0.4);
-               me.TD(me, 1, 2.6, e = makeXonoticCheckBox(0, "g_friendlyfire_virtual", _("Virtual friendly fire (effect only)")));
+               me.TD(me, 1, 2.6, makeXonoticCheckBox(0, "g_friendlyfire_virtual", _("Virtual friendly fire (effect only)")));
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Friendly fire penalty:")));
-               me.TD(me, 1, 1.6, e = makeXonoticSlider(0, 1.0, 0.05, "g_mirrordamage"));
+               me.TD(me, 1, 1.2, makeXonoticTextLabel(0, _("Friendly fire penalty:")));
+               me.TD(me, 1, 1.6, makeXonoticSlider(0, 1.0, 0.05, "g_mirrordamage"));
        me.TR(me);
                me.TDempty(me, 0.4);
-               me.TD(me, 1, 2.6, e = makeXonoticCheckBox(0, "g_mirrordamage_virtual", _("Virtual penalty (effect only)")));
+               me.TD(me, 1, 2.6, makeXonoticCheckBox(0, "g_mirrordamage_virtual", _("Virtual penalty (effect only)")));
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, _("Teams:")));
+               me.TD(me, 1, 1.2, makeXonoticTextLabel(0, _("Teams:")));
                me.TD(me, 1, 1.6, e = makeXonoticTextSlider("g_tdm_teams_override g_domination_teams_override g_keyhunt_teams_override"));
                        e.addValue(e, "Default", "0");
                        e.addValue(e, "2 teams", "2");
@@ -63,7 +63,7 @@ void XonoticAdvancedDialog_fill(entity me)
                        e.configureXonoticTextSliderValues(e);
        me.TR(me);
        me.TR(me);
-               me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Map voting:")));
+               me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Map voting:")));
                me.TD(me, 1, 2, e = makeXonoticTextSlider("g_maplist_votable"));
                        e.addValue(e, _("No voting"), "0");
                        e.addValue(e, _("2 choices"), "2");
@@ -76,7 +76,7 @@ void XonoticAdvancedDialog_fill(entity me)
                        e.addValue(e, _("9 choices"), "9");
                        e.configureXonoticTextSliderValues(e);
        me.TR(me);
-               me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(0.5, 0, "sv_vote_simple_majority_factor", _("Simple majority wins vcall")));
+               me.TD(me, 1, 3, makeXonoticCheckBoxEx(0.5, 0, "sv_vote_simple_majority_factor", _("Simple majority wins vcall")));
 
        me.gotoRC(me, me.rows - 1, 0);
                me.TD(me, 1, me.columns, e = makeXonoticButton(_("OK"), '0 0 0'));
index 1f1ee385b219b762945dee382ff2916e355a4286..174873fe7fc79f211a41d0321a1bae083b977e65 100644 (file)
@@ -114,12 +114,12 @@ void XonoticAudioSettingsTab_fill(entity me)
                setDependentStringNotEqual(s, "mastervolume", "0");
        me.TR(me);
        me.TR(me);
-               me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "menu_snd_attenuation_method", _("New style sound attenuation")));
+               me.TD(me, 1, 3, makeXonoticCheckBox(0, "menu_snd_attenuation_method", _("New style sound attenuation")));
        me.TR(me);
-               me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "snd_mutewhenidle", _("Mute sounds when not active")));
+               me.TD(me, 1, 3, makeXonoticCheckBox(0, "snd_mutewhenidle", _("Mute sounds when not active")));
        
        me.gotoRC(me, 0, 3.2); me.setFirstColumn(me, me.currentColumn);
-               me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Frequency:")));
+               me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Frequency:")));
                me.TD(me, 1, 2, e = makeXonoticTextSlider("snd_speed"));
                        e.addValue(e, _("8 kHz"), "8000");
                        e.addValue(e, _("11.025 kHz"), "11025");
@@ -131,7 +131,7 @@ void XonoticAudioSettingsTab_fill(entity me)
                        e.addValue(e, _("48 kHz"), "48000");
                        e.configureXonoticTextSliderValues(e);
        me.TR(me);
-               me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Channels:")));
+               me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Channels:")));
                me.TD(me, 1, 2, e = makeXonoticTextSlider("snd_channels"));
                        e.addValue(e, _("Mono"), "1");
                        e.addValue(e, _("Stereo"), "2");
@@ -148,33 +148,15 @@ void XonoticAudioSettingsTab_fill(entity me)
                me.TD(me, 1, 1.8, e = makeXonoticCheckBox(0, "snd_spatialization_control", _("Headphone friendly mode")));
                setDependent(e, "snd_channels", 1.5, 0.5);
        me.TR(me);
-       /*me.TR(me); // Samual: I REALLY don't think these are relevant to anyone, and just clutter up the menu pointlessly. The defaults are fine.
-               me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Spatial voices:")));
-               me.TD(me, 1, 2/3, e = makeXonoticRadioButton(1, "cl_voice_directional", "0", ZCTX(_("VOCS^None"))));
-               me.TD(me, 1, 2/3, e = makeXonoticRadioButton(1, "cl_voice_directional", "2", ZCTX(_("VOCS^Taunts"))));
-               me.TD(me, 1, 2/3, e = makeXonoticRadioButton(1, "cl_voice_directional", "1", ZCTX(_("VOCS^All"))));
        me.TR(me);
-               me.TDempty(me, 0.2);
-               me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Taunt range:")));
-               setDependent(e, "cl_voice_directional", 0.5, -0.5);
-               me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_voice_directional_taunt_attenuation"));
-                       e.addValue(e, ZCTX(_("RNG^Very short")), "3");
-                       e.addValue(e, ZCTX(_("RNG^Short")), "2");
-                       e.addValue(e, ZCTX(_("RNG^Normal")), "0.5");
-                       e.addValue(e, ZCTX(_("RNG^Long")), "0.25");
-                       e.addValue(e, ZCTX(_("RNG^Full")), "0.015625");
-                       e.configureXonoticTextSliderValues(e);
-               setDependent(e, "cl_voice_directional", 0.5, -0.5);
-       me.TR(me);*/
+               me.TD(me, 1, 3, makeXonoticCheckBox(0, "cl_hitsound", _("Hit indication sound")));
        me.TR(me);
-               me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "cl_hitsound", _("Hit indication sound")));
+               me.TD(me, 1, 3, makeXonoticCheckBox(0, "con_chatsound", _("Chat message sound")));
        me.TR(me);
-               me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "con_chatsound", _("Chat message sound")));
+               me.TD(me, 1, 3, makeXonoticCheckBoxEx(2, 0, "menu_sounds", _("Menu sounds")));
        me.TR(me);
-               me.TD(me, 1, 3, e = makeXonoticCheckBoxEx(2, 0, "menu_sounds", _("Menu sounds")));
        me.TR(me);
-       me.TR(me);
-               me.TD(me, 1, 1, e = makeXonoticTextLabel(0, _("Time announcer:")));
+               me.TD(me, 1, 1, makeXonoticTextLabel(0, _("Time announcer:")));
                me.TD(me, 1, 2, e = makeXonoticTextSlider("cl_announcer_maptime"));
                        e.addValue(e, ZCTX(_("WRN^Disabled")), "0");
                        e.addValue(e, _("1 minute"), "1");
@@ -191,13 +173,12 @@ void XonoticAudioSettingsTab_fill(entity me)
                        e.savedValue = 0.65; // default
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 0.8, e = makeXonoticTextLabel(0, _("Frequency:")));
+               me.TD(me, 1, 0.8, makeXonoticTextLabel(0, _("Frequency:")));
                me.TD(me, 1, 2, sl);
        me.TR(me);
        me.TR(me);
                if(cvar("developer"))
-                       me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "showsound", _("Debug info about sounds")));
-       
+                       me.TD(me, 1, 3, makeXonoticCheckBox(0, "showsound", _("Debug info about sounds")));
 
        me.gotoRC(me, me.rows - 1, 0);
                me.TD(me, 1, me.columns, makeXonoticCommandButton(_("Apply immediately"), '0 0 0', "snd_restart; snd_attenuation_method_$menu_snd_attenuation_method; sendcvar cl_hitsound; sendcvar cl_autotaunt; sendcvar cl_voice_directional; sendcvar cl_voice_directional_taunt_attenuation", COMMANDBUTTON_APPLY));
index 78ac9de46c1bc96aeda3db938b27d8bc29b49cfd..4c03eaa5f9caa9edb5255ee3f4a217a904799463 100644 (file)
@@ -622,6 +622,8 @@ float GameType_GetID(float cnt)
        #define GAMETYPE(id) if(i++ == cnt) return id;
        GAMETYPES
        #undef GAMETYPE
+
+       unused_float = i;
        
        return 0;
 }
index 5e1c65f796e159525962b01e0cd69074475710f8..dbb790a883b9c131d1b3aa18c6458abba2e7873a 100644 (file)
@@ -928,6 +928,7 @@ float autocvar_g_playerclip_collisions;
 string autocvar_g_playerstats_uri;
 float autocvar_g_powerups;
 float autocvar_g_projectiles_damage;
+float autocvar_g_projectiles_keep_owner;
 float autocvar_g_projectiles_newton_style;
 float autocvar_g_projectiles_newton_style_2_maxfactor;
 float autocvar_g_projectiles_newton_style_2_minfactor;
index fcc1cca97914ab03ecb4ff69ee10afc57bf377df..704eff0ae00687c5de4402c4dff2a7367d54168e 100644 (file)
@@ -1564,7 +1564,6 @@ void ClientConnect (void)
                        rr = CTS_RECORD;
                else
                        rr = RACE_RECORD;
-               t = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time")));
 
                msg_entity = self;
                race_send_recordtime(MSG_ONE);
@@ -2123,6 +2122,15 @@ void GetPressedKeys(void) {
                self.pressedkeys |= KEY_CROUCH;
        else
                self.pressedkeys &~= KEY_CROUCH;
+
+       if (self.BUTTON_ATCK)
+               self.pressedkeys |= KEY_ATCK;
+       else
+               self.pressedkeys &~= KEY_ATCK;
+       if (self.BUTTON_ATCK2)
+               self.pressedkeys |= KEY_ATCK2;
+       else
+               self.pressedkeys &~= KEY_ATCK2;
 }
 
 /*
index cbbe3d547ff4bcabedf3c6a1e8086fc8415f153f..402b692af1230fba959a89c1fce3aef5a999ab13 100644 (file)
@@ -1077,8 +1077,6 @@ vector W_CalculateProjectileVelocity(vector pvelocity, vector mvelocity, float f
 {
        vector mdirection;
        float mspeed;
-       float outspeed;
-       float nstyle;
        vector outvelocity;
 
        mvelocity = mvelocity * g_weaponspeedfactor;
@@ -1086,48 +1084,7 @@ vector W_CalculateProjectileVelocity(vector pvelocity, vector mvelocity, float f
        mdirection = normalize(mvelocity);
        mspeed = vlen(mvelocity);
 
-       nstyle = autocvar_g_projectiles_newton_style;
-       if(nstyle == 0 || forceAbsolute)
-       {
-               // absolute velocity
-               outvelocity = mvelocity;
-       }
-       else if(nstyle == 1)
-       {
-               // true Newtonian projectiles
-               outvelocity = pvelocity + mvelocity;
-       }
-       else if(nstyle == 2)
-       {
-               // true Newtonian projectiles with automatic aim adjustment
-               //
-               // solve: |outspeed * mdirection - pvelocity| = mspeed
-               // outspeed^2 - 2 * outspeed * (mdirection * pvelocity) + pvelocity^2 - mspeed^2 = 0
-               // outspeed = (mdirection * pvelocity) +- sqrt((mdirection * pvelocity)^2 - pvelocity^2 + mspeed^2)
-               // PLUS SIGN!
-               // not defined?
-               // then...
-               // pvelocity^2 - (mdirection * pvelocity)^2 > mspeed^2
-               // velocity without mdirection component > mspeed
-               // fire at smallest possible mspeed that works?
-               // |(mdirection * pvelocity) * pvelocity - pvelocity| = mspeed
-
-               vector solution;
-               solution = solve_quadratic(1, -2 * (mdirection * pvelocity), pvelocity * pvelocity - mspeed * mspeed);
-               if(solution_z)
-                       outspeed = solution_y; // the larger one
-               else
-               {
-                       //outspeed = 0; // slowest possible shot
-                       outspeed = solution_x; // the real part (that is, the average!)
-                       //dprint("impossible shot, adjusting\n");
-               }
-
-               outspeed = bound(mspeed * autocvar_g_projectiles_newton_style_2_minfactor, outspeed, mspeed * autocvar_g_projectiles_newton_style_2_maxfactor);
-               outvelocity = mdirection * outspeed;
-       }
-       else
-               error("g_projectiles_newton_style must be 0 (absolute), 1 (Newtonian) or 2 (Newtonian + aimfix)!");
+       outvelocity = get_shotvelocity(pvelocity, mdirection, mspeed, (forceAbsolute ? 0 : autocvar_g_projectiles_newton_style), autocvar_g_projectiles_newton_style_2_minfactor, autocvar_g_projectiles_newton_style_2_maxfactor);
 
        return outvelocity;
 }
index f5510d73f92bf5156cfe1f9e3ebd9f18c937b97e..b659d44ccab532d2c12502fe4dee0e160bc0662e 100644 (file)
@@ -226,40 +226,6 @@ void ClientCommand_ready(float request) // todo: anti-spam for toggling readynes
        }
 }
 
-void ClientCommand_reportcvar(float request, float argc, string command)
-{      
-       switch(request)
-       {
-               case CMD_REQUEST_COMMAND:
-               {
-                       if(argv(1) != "")
-                       {
-                               float tokens;
-                               string s;
-                               
-                               if(substring(argv(2), 0, 1) == "$") // undefined cvar: use the default value on the server then
-                               {
-                                       s = strcat(substring(command, argv_start_index(0), argv_end_index(1) - argv_start_index(0)), " \"", cvar_defstring(argv(1)), "\"");
-                                       tokens = tokenize_console(s);
-                               }
-                               
-                               GetCvars(1);
-                               
-                               return;
-                       }
-               }
-                       
-               default:
-                       sprint(self, "Incorrect parameters for ^2reportcvar^7\n");
-               case CMD_REQUEST_USAGE:
-               {
-                       sprint(self, "\nUsage:^3 cmd reportcvar <cvar>\n");
-                       sprint(self, "  Where 'cvar' is the cvar plus arguments to send to the server.\n");
-                       return;
-               }
-       }
-}
-
 void ClientCommand_say(float request, float argc, string command)
 {
        switch(request)
@@ -398,7 +364,7 @@ void ClientCommand_sentcvar(float request, float argc, string command)
                                if(argc == 2) // undefined cvar: use the default value on the server then
                                {
                                        s = strcat(substring(command, argv_start_index(0), argv_end_index(1) - argv_start_index(0)), " \"", cvar_defstring(argv(1)), "\"");
-                                       tokens = tokenize_console(s);
+                                       tokenize_console(s);
                                }
                                
                                GetCvars(1);
@@ -595,7 +561,6 @@ void ClientCommand_(float request)
        CLIENT_COMMAND("mv_getpicture", ClientCommand_mv_getpicture(request, arguments), "Retrieve mapshot picture from the server") \
        CLIENT_COMMAND("join", ClientCommand_join(request), "Become a player in the game") \
        CLIENT_COMMAND("ready", ClientCommand_ready(request), "Qualify as ready to end warmup stage (or restart server if allowed)") \
-       CLIENT_COMMAND("reportcvar", ClientCommand_reportcvar(request, arguments, command), "Old system for sending a client cvar to the server") \
        CLIENT_COMMAND("say", ClientCommand_say(request, arguments, command), "Print a message to chat to all players") \
        CLIENT_COMMAND("say_team", ClientCommand_say_team(request, arguments, command), "Print a message to chat to all team mates") \
        CLIENT_COMMAND("selectteam", ClientCommand_selectteam(request, arguments), "Attempt to choose a team to join into") \
@@ -683,7 +648,6 @@ void SV_ParseClientCommand(string command)
                case "mv_getpicture": break; // handled by server in this file
                case "pause": break; // handled by engine in host_cmd.c
                case "prespawn": break; // handled by engine in host_cmd.c
-               case "reportcvar": break; // handled by server in this file
                case "sentcvar": break; // handled by server in this file
                case "spawn": break; // handled by engine in host_cmd.c
                
index 16f3212eda0cc1852569ac0de61a11d67b1ff470..d8651762965d9d6859dbc05ed205b5ee0407d8dc 100644 (file)
@@ -28,7 +28,7 @@ float FullTraceFraction(vector a, vector mi, vector ma, vector b)
                        c = trace_endpos;
                }
 
-               n += tracebox_inverted(c, mi, ma, b, MOVE_WORLDONLY, world);
+               n += tracebox_inverted(c, mi, ma, b, MOVE_WORLDONLY, world, FALSE);
 
                white += vlen(trace_endpos - c);
                c = trace_endpos;
@@ -424,4 +424,4 @@ float RadarMap_Make(float argc)
        }
        
        return FALSE;
-}
\ No newline at end of file
+}
index 47a72d904a48145139648a28de27725a77038d02..fe1b00b9a643ea68c510bef32f1c9bff13a49be0 100644 (file)
@@ -100,6 +100,7 @@ float maxclients;
 .float         t_length, t_width;
 
 .vector destvec;               // for rain
+.vector destvec2;              // for train
 .float cnt;            // for rain
 .float count;
 //.float cnt2;
index f0ace5ea889ccd7cfc37ee9f8bd846034438dc2d..a49aad27bdc401027a66ca15a1e181140cf765c4 100644 (file)
@@ -140,7 +140,9 @@ void GiveFrags (entity attacker, entity targ, float f, float deathtype)
                // after a frag, exchange the current weapon (or the culprit, if detectable) by a new random weapon
                float culprit;
                culprit = DEATH_WEAPONOF(deathtype);
-               if(!culprit || !WEPSET_CONTAINS_EW(attacker, culprit))
+               if(!culprit)
+                       culprit = attacker.weapon;
+               else if(!WEPSET_CONTAINS_EW(attacker, culprit))
                        culprit = attacker.weapon;
 
                if(g_weaponarena_random_with_laser && culprit == WEP_LASER)
@@ -645,9 +647,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
 
                                                        if(autocvar_g_mirrordamage_virtual)
                                                        {
-                                                               vector v;
-                                                               v = healtharmor_applydamage(attacker.armorvalue, autocvar_g_balance_armor_blockpercent, mirrordamage);
-                                                               v_z = 0; // fteqcc sucks
+                                                               vector v = healtharmor_applydamage(attacker.armorvalue, autocvar_g_balance_armor_blockpercent, mirrordamage);
                                                                attacker.dmg_take += v_x;
                                                                attacker.dmg_save += v_y;
                                                                attacker.dmg_inflictor = inflictor;
@@ -657,9 +657,7 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
 
                                                        if(autocvar_g_friendlyfire_virtual)
                                                        {
-                                                               vector v;
-                                                               v = healtharmor_applydamage(targ.armorvalue, autocvar_g_balance_armor_blockpercent, damage);
-                                                               v_z = 0; // fteqcc sucks
+                                                               vector v = healtharmor_applydamage(targ.armorvalue, autocvar_g_balance_armor_blockpercent, damage);
                                                                targ.dmg_take += v_x;
                                                                targ.dmg_save += v_y;
                                                                targ.dmg_inflictor = inflictor;
index f8aad67240f4d5fdb41624a33e7cd09519bd0e74..df63a70bb85d4f01578823b1b4ea3ceaba48f8ce 100644 (file)
@@ -178,24 +178,29 @@ void SUB_CalcMove_controller_think (void)
        float phasepos;
        float nexttick;
        vector delta;
+       vector delta2;
        vector veloc;
        vector nextpos;
+       delta = self.destvec;
+       delta2 = self.destvec2;
        if(time < self.animstate_endtime) {
-               delta = self.destvec;
                nexttick = time + sys_frametime;
 
-               if(nexttick < self.animstate_endtime) {
-                       traveltime = self.animstate_endtime - self.animstate_starttime;
-                       phasepos = (nexttick - self.animstate_starttime) / traveltime; // range: [0, 1]
+               traveltime = self.animstate_endtime - self.animstate_starttime;
+               phasepos = (nexttick - self.animstate_starttime) / traveltime; // range: [0, 1]
+               if(self.platmovetype != 1)
+               {
                        phasepos = 3.14159265 + (phasepos * 3.14159265); // range: [pi, 2pi]
                        phasepos = cos(phasepos); // cos [pi, 2pi] is in [-1, 1]
                        phasepos = phasepos + 1; // correct range to [0, 2]
                        phasepos = phasepos / 2; // correct range to [0, 1]
-                       nextpos = self.origin + (delta * phasepos);
+               }
+               nextpos = self.origin + (delta * phasepos) + (delta2 * phasepos * phasepos);
+               // derivative: delta + 2 * delta2 * phasepos (e.g. for angle positioning)
 
+               if(nexttick < self.animstate_endtime) {
                        veloc = nextpos - self.owner.origin;
                        veloc = veloc * (1 / sys_frametime); // so it arrives for the next frame
-
                } else {
                        veloc = self.finaldest - self.owner.origin;
                        veloc = veloc * (1 / sys_frametime); // so it arrives for the next frame
@@ -203,6 +208,7 @@ void SUB_CalcMove_controller_think (void)
                self.owner.velocity = veloc;
                self.nextthink = nexttick;
        } else {
+               // derivative: delta + 2 * delta2 (e.g. for angle positioning)
                oldself = self;
                self.owner.think = self.think1;
                self = self.owner;
@@ -211,9 +217,35 @@ void SUB_CalcMove_controller_think (void)
        }
 }
 
-void SUB_CalcMove (vector tdest, float tspeed, void() func)
+void SUB_CalcMove_controller_setbezier (entity controller, vector org, vector control, vector dest)
+{
+       // 0 * (1-t) * (1-t) + 2 * control * t * (1-t) + dest * t * t
+       // 2 * control * t - 2 * control * t * t + dest * t * t
+       // 2 * control * t + (dest - 2 * control) * t * t
+
+       controller.origin = org; // starting point
+       control -= org;
+       dest -= org;
+
+       controller.destvec = 2 * control; // control point
+       controller.destvec2 = dest - 2 * control; // quadratic part required to reach end point
+}
+
+void SUB_CalcMove_controller_setlinear (entity controller, vector org, vector dest)
+{
+       // 0 * (1-t) * (1-t) + 2 * control * t * (1-t) + dest * t * t
+       // 2 * control * t - 2 * control * t * t + dest * t * t
+       // 2 * control * t + (dest - 2 * control) * t * t
+
+       controller.origin = org; // starting point
+       dest -= org;
+
+       controller.destvec = dest; // end point
+       controller.destvec2 = '0 0 0';
+}
+
+void SUB_CalcMove_Bezier (vector tcontrol, vector tdest, float tspeed, void() func)
 {
-       vector  delta;
        float   traveltime;
        entity controller;
 
@@ -224,40 +256,24 @@ void SUB_CalcMove (vector tdest, float tspeed, void() func)
        self.finaldest = tdest;
        self.think = SUB_CalcMoveDone;
 
-       if (tdest == self.origin)
-       {
-               self.velocity = '0 0 0';
-               self.nextthink = self.ltime + 0.1;
-               return;
-       }
+       if(tspeed > 0) // positive: start speed
+               traveltime = 2 * vlen(tcontrol - self.origin) /  tspeed;
+       else // negative: end speed
+               traveltime = 2 * vlen(tcontrol - tdest)       / -tspeed;
 
-       delta = tdest - self.origin;
-       traveltime = vlen (delta) / tspeed;
-
-       if (traveltime < 0.1)
+       if (traveltime < 0.1) // useless anim
        {
                self.velocity = '0 0 0';
                self.nextthink = self.ltime + 0.1;
                return;
        }
 
-       // Very short animations don't really show off the effect
-       // of controlled animation, so let's just use linear movement.
-       // Alternatively entities can choose to specify non-controlled movement.
-        // The only currently implemented alternative movement is linear (value 1)
-       if (traveltime < 0.15 || self.platmovetype == 1)
-       {
-               self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
-               self.nextthink = self.ltime + traveltime;
-               return;
-       }
-
        controller = spawn();
        controller.classname = "SUB_CalcMove_controller";
        controller.owner = self;
-       controller.origin = self.origin; // starting point
+       controller.platmovetype = self.platmovetype;
+       SUB_CalcMove_controller_setbezier(controller, self.origin, tcontrol, tdest);
        controller.finaldest = (tdest + '0 0 0.125'); // where do we want to end? Offset to overshoot a bit.
-       controller.destvec = delta;
        controller.animstate_starttime = time;
        controller.animstate_endtime = time + traveltime;
        controller.think = SUB_CalcMove_controller_think;
@@ -273,6 +289,43 @@ void SUB_CalcMove (vector tdest, float tspeed, void() func)
        self = self.owner;
 }
 
+void SUB_CalcMove (vector tdest, float tspeed, void() func)
+{
+       vector  delta;
+       float   traveltime;
+
+       if (!tspeed)
+               objerror ("No speed is defined!");
+
+       self.think1 = func;
+       self.finaldest = tdest;
+       self.think = SUB_CalcMoveDone;
+
+       if (tdest == self.origin)
+       {
+               self.velocity = '0 0 0';
+               self.nextthink = self.ltime + 0.1;
+               return;
+       }
+
+       delta = tdest - self.origin;
+       traveltime = vlen (delta) / tspeed;
+
+       // Very short animations don't really show off the effect
+       // of controlled animation, so let's just use linear movement.
+       // Alternatively entities can choose to specify non-controlled movement.
+        // The only currently implemented alternative movement is linear (value 1)
+       if (traveltime < 0.15 || self.platmovetype == 1)
+       {
+               self.velocity = delta * (1/traveltime); // QuakeC doesn't allow vector/float division
+               self.nextthink = self.ltime + traveltime;
+               return;
+       }
+
+       // now just run like a bezier curve...
+       SUB_CalcMove_Bezier((self.origin + tdest) * 0.5, tdest, tspeed, func);
+}
+
 void SUB_CalcMoveEnt (entity ent, vector tdest, float tspeed, void() func)
 {
        entity  oldself;
@@ -445,10 +498,11 @@ void WarpZone_tracebox_antilag (entity source, vector v1, vector mi, vector ma,
        tracebox_antilag_force_wz(source, v1, mi, ma, v2, nomonst, forent, lag, TRUE);
 }
 
-float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomonsters, entity forent) // returns the number of traces done, for benchmarking
+float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomonsters, entity forent, float stopatentity) // returns the number of traces done, for benchmarking
 {
        vector pos, dir, t;
        float nudge;
+       entity stopentity;
 
        //nudge = 2 * cvar("collision_impactnudge"); // why not?
        nudge = 0.5;
@@ -481,6 +535,8 @@ float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomon
                        dprint("  trace distance is ", ftos(vlen(pos - trace_endpos)), "\n");
                }
 
+               stopentity = trace_ent;
+
                if(trace_startsolid)
                {
                        // we started inside solid.
@@ -493,6 +549,15 @@ float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomon
                                // t is still inside solid? bad
                                // force advance, then, and retry
                                pos = t + dir * nudge;
+
+                               // but if we hit an entity, stop RIGHT before it
+                               if(stopatentity && stopentity)
+                               {
+                                       trace_ent = stopentity;
+                                       trace_endpos = t;
+                                       trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
+                                       return c;
+                               }
                        }
                        else
                        {
@@ -511,59 +576,9 @@ float tracebox_inverted (vector v1, vector mi, vector ma, vector v2, float nomon
        }
 }
 
-void traceline_inverted (vector v1, vector v2, float nomonsters, entity forent)
+void traceline_inverted (vector v1, vector v2, float nomonsters, entity forent, float stopatentity)
 {
-#if 0
-       vector pos, dir, t;
-       float nudge;
-
-       //nudge = 2 * cvar("collision_impactnudge"); // why not?
-       nudge = 0.5;
-
-       dir = normalize(v2 - v1);
-
-       pos = v1 + dir * nudge;
-
-       for(;;)
-       {
-               if((pos - v1) * dir >= (v2 - v1) * dir)
-               {
-                       // went too far
-                       trace_fraction = 1;
-                       return;
-               }
-
-               traceline(pos, v2, nomonsters, forent);
-
-               if(trace_startsolid)
-               {
-                       // we started inside solid.
-                       // then trace from endpos to pos
-                       t = trace_endpos;
-                       traceline(t, pos, nomonsters, forent);
-                       if(trace_startsolid)
-                       {
-                               // t is inside solid? bad
-                               // force advance, then
-                               pos = pos + dir * nudge;
-                       }
-                       else
-                       {
-                               // we actually LEFT solid!
-                               trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
-                               return;
-                       }
-               }
-               else
-               {
-                       // pos is outside solid?!? but why?!? never mind, just return it.
-                       trace_endpos = pos;
-                       trace_fraction = ((trace_endpos - v1) * dir) / ((v2 - v1) * dir);
-                       return;
-               }
-       }
-#else
-       tracebox_inverted(v1, '0 0 0', '0 0 0', v2, nomonsters, forent);
+       tracebox_inverted(v1, '0 0 0', '0 0 0', v2, nomonsters, forent, stopatentity);
 }
 
 /*
index 1b8585eb60c9fd2e36819745406198c320ed4e71..3826b683af6c16ceb8ca7d33aa108ed06269e8e7 100644 (file)
@@ -2442,12 +2442,8 @@ vector shotorg_adjust(vector vecs, float y_is_right, float visual)
 void attach_sameorigin(entity e, entity to, string tag)
 {
     vector org, t_forward, t_left, t_up, e_forward, e_up;
-    vector org0, ang0;
     float tagscale;
 
-    ang0 = e.angles;
-    org0 = e.origin;
-
     org = e.origin - gettaginfo(to, gettagindex(to, tag));
     tagscale = pow(vlen(v_forward), -2); // undo a scale on the tag
     t_forward = v_forward * tagscale;
index fa5a365ba48316b07c96ed3cdfc6b53619b3a2bb..2a2ae9ee2900fea47c6d90233a5fbae180281d96 100644 (file)
@@ -351,13 +351,11 @@ MUTATOR_DEFINITION(gamemode_freezetag)
        {
                if(time > 1) // game loads at time 1
                        error("This is a game type and it cannot be added at runtime.");
-               g_freezetag = 1;
                freezetag_Initialize();
        }
 
        MUTATOR_ONREMOVE
        {
-               g_freezetag = 0;
                error("This is a game type and it cannot be removed at runtime.");
        }
 
index 9134353e015574860dc4478938633ba80e3a56ec..1f6a82b84b7c9475a29f5d1fdfcd21aa5d624720 100644 (file)
@@ -329,13 +329,11 @@ MUTATOR_DEFINITION(gamemode_keepaway)
        {
                if(time > 1) // game loads at time 1
                        error("This is a game type and it cannot be added at runtime.");
-               g_keepaway = 1;
                ka_Initialize();
        }
 
        MUTATOR_ONREMOVE
        {
-               g_keepaway = 0;
                error("This is a game type and it cannot be removed at runtime.");
        }
 
index 252f1abdad07ab37dd7bcf7542ae8d3ce40f8e49..58d732d7f70b926c6cb13c6f93aa0f9a5807f48e 100644 (file)
@@ -1108,13 +1108,11 @@ MUTATOR_DEFINITION(gamemode_keyhunt)
        {
                if(time > 1) // game loads at time 1
                        error("This is a game type and it cannot be added at runtime.");
-               g_keyhunt = 1;
                kh_Initialize();
        }
 
        MUTATOR_ONREMOVE
        {
-               g_keyhunt = 0;
                error("This is a game type and it cannot be removed at runtime.");
        }
 
index aa56d7647772ac4c5c5593bb6d324ce39b69dcf2..ec8de781e257fa754167f2c028c3e6c5dc5ea3cc 100644 (file)
@@ -962,7 +962,6 @@ MUTATOR_DEFINITION(gamemode_nexball)
 
        MUTATOR_ONADD
        {
-           g_nexball = 1;
                g_nexball_meter_period = autocvar_g_nexball_meter_period;
                if(g_nexball_meter_period <= 0)
                        g_nexball_meter_period = 2; // avoid division by zero etc. due to silly users
index 2d2334c563e2a05480e8f27e0fb898f645fe0f61..bdd39b1283f487fe0e74ab42135b6d66f4b180c7 100644 (file)
@@ -55,6 +55,9 @@ MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics) {
        float velocity_difference;
        float clean_up_and_do_nothing;
 
+    if (self.deadflag != DEAD_NO)
+        return 0;
+
        new_velocity_gain = 0;
        clean_up_and_do_nothing = 0;
 
@@ -241,8 +244,6 @@ MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys) {
                }
        }
 
-
-
        if (dodge_detected == 1) {
                self.last_dodging_time = time;
 
index c3a9a7390fc45fa4bd2d32bfdeb939221ce55f47..239afb04a81c4d72702fa840078e50dc1928c29f 100644 (file)
@@ -343,7 +343,6 @@ void DropAllRunes(entity pl)
 
        entity curse1, rune1, curse2, rune2;
 
-       rune = curse = world;
        rcount = ccount = r = c = 0;
        rune = find(rune, classname, "rune");
        while(rune)
@@ -363,7 +362,6 @@ void DropAllRunes(entity pl)
        numtodrop = autocvar_g_runematch_drop_runes_max;
        prevent_same = !autocvar_g_runematch_allow_same;
 
-       rune = curse = world;
        do
        {
                rune = find(rune, classname, "rune");
index 777820e48c261c26f18cc8c9b093b42abfa71a85..c6523e4b83dcd671668bc6afa50db571afb804e7 100644 (file)
@@ -58,6 +58,7 @@ float autocvar_g_vehicle_racer_rocket_locking_time;
 float autocvar_g_vehicle_racer_rocket_locking_releasetime;
 float autocvar_g_vehicle_racer_rocket_locked_time;
 float autocvar_g_vehicle_racer_rocket_locked_maxangle;
+float autocvar_g_vehicle_racer_rocket_climbspeed;
 
 float autocvar_g_vehicle_racer_respawntime;
 
@@ -72,36 +73,32 @@ vector autocvar_g_vehicle_racer_bouncepain;
 
 var vector racer_force_from_tag(string tag_name, float spring_length, float max_power);
 
-void racer_align4point()
+void racer_align4point(float _delta)
 {
-    vector push_vector, v_add;
+    vector push_vector;
     float fl_push, fr_push, bl_push, br_push;
 
-
     push_vector  = racer_force_from_tag("tag_engine_fr", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
     fr_push      = force_fromtag_normpower;
-    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, frametime, v_add, autocvar_g_vehicle_racer_collision_multiplier);
+    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
     push_vector += racer_force_from_tag("tag_engine_fl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
     fl_push      = force_fromtag_normpower;
-    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, frametime, v_add, autocvar_g_vehicle_racer_collision_multiplier);
+    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
     push_vector += racer_force_from_tag("tag_engine_br", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
     br_push      = force_fromtag_normpower;
-    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, frametime, v_add, autocvar_g_vehicle_racer_collision_multiplier);
+    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
     push_vector += racer_force_from_tag("tag_engine_bl", autocvar_g_vehicle_racer_springlength, autocvar_g_vehicle_racer_hoverpower);
     bl_push      = force_fromtag_normpower;
-    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, frametime, v_add, autocvar_g_vehicle_racer_collision_multiplier);
+    //vehicles_sweap_collision(force_fromtag_origin, self.velocity, _delta, v_add, autocvar_g_vehicle_racer_collision_multiplier);
 
-    self.velocity += (push_vector * frametime);
+   self.velocity += push_vector * _delta;
 
     // Anti ocilation
-    if(self.velocity_z  > 0)
-        self.velocity_z *= 1 - (autocvar_g_vehicle_racer_upforcedamper * frametime);
-
-    self.velocity   += v_add;
-    //self.velocity_z -= autocvar_sv_gravity * frametime;
+    if(self.velocity_z > 0)
+        self.velocity_z *= 1 - autocvar_g_vehicle_racer_upforcedamper * _delta;
 
     push_vector_x =  (fl_push - bl_push);
     push_vector_x += (fr_push - br_push);
@@ -112,12 +109,12 @@ void racer_align4point()
     push_vector_z *= 360;
 
     // Apply angle diffrance
-    self.angles_z += push_vector_z * frametime;
-    self.angles_x += push_vector_x * frametime;
+    self.angles_z += push_vector_z * _delta;
+    self.angles_x += push_vector_x * _delta;
 
     // Apply stabilizer
-    self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * frametime);
-    self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * frametime);
+    self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta);
+    self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * _delta);
 }
 
 void racer_fire_cannon(string tagname)
@@ -209,8 +206,14 @@ void racer_rocket_tracker()
     newvel = oldvel + self.lip;
     makevectors(vectoangles(olddir));
 
+       float time_to_impact = min(vlen(self.enemy.origin - self.origin) / vlen(self.velocity), 1);
+       vector predicted_origin = self.enemy.origin + self.enemy.velocity * time_to_impact;
+
     traceline(self.origin, self.origin + v_forward * 64 - '0 0 32', MOVE_NORMAL, self);
-    newdir = normalize(self.enemy.origin - self.origin);
+    newdir = normalize(predicted_origin - self.origin);
+
+    //vector
+       float height_diff = predicted_origin_z - self.origin_z;
 
     if(vlen(newdir - v_forward) > autocvar_g_vehicle_racer_rocket_locked_maxangle)
     {
@@ -220,11 +223,12 @@ void racer_rocket_tracker()
         return;
     }
 
-    if(trace_fraction != 1.0)
+    if(trace_fraction != 1.0 && trace_ent != self.enemy)
         newdir_z += 16 * sys_frametime;
 
     self.velocity = normalize(olddir + newdir * autocvar_g_vehicle_racer_rocket_turnrate) * newvel;
     self.velocity_z -= 800 * sys_frametime;
+    self.velocity_z += max(height_diff, autocvar_g_vehicle_racer_rocket_climbspeed) * sys_frametime ;
 
     UpdateCSQCProjectile(self);
     return;
@@ -232,11 +236,8 @@ void racer_rocket_tracker()
 
 void racer_fire_rocket(string tagname, entity trg)
 {
-    vector v;
-    entity rocket;
-
-    v = gettaginfo(self, gettagindex(self, tagname));
-    rocket = vehicles_projectile("wakizashi_rocket_launch", "weapons/rocket_fire.wav",
+    vector v = gettaginfo(self, gettagindex(self, tagname));
+    entity rocket = rocket = vehicles_projectile("wakizashi_rocket_launch", "weapons/rocket_fire.wav",
                            v, v_forward * autocvar_g_vehicle_racer_rocket_speed,
                            autocvar_g_vehicle_racer_rocket_damage, autocvar_g_vehicle_racer_rocket_radius, autocvar_g_vehicle_racer_rocket_force, 3,
                            DEATH_WAKIROCKET, PROJECTILE_WAKIROCKET, 20, FALSE, FALSE);
@@ -265,11 +266,11 @@ float racer_frame()
     player  = self;
     racer   = self.vehicle;
     self    = racer;
-    
+
     player.BUTTON_ZOOM = player.BUTTON_CROUCH = 0;
-    
+
     vehicles_painframe();
-    
+
     if(racer.deadflag != DEAD_NO)
     {
         self = player;
@@ -277,7 +278,7 @@ float racer_frame()
         return 1;
     }
 
-    racer_align4point();
+    racer_align4point(frametime);
 
     crosshair_trace(player);
 
@@ -299,84 +300,68 @@ float racer_frame()
     makevectors(racer.angles);
     racer.angles_x *= -1;
 
-
-    ftmp = racer.velocity_z;
+    //ftmp = racer.velocity_z;
     df = racer.velocity * -autocvar_g_vehicle_racer_friction;
-    racer.velocity_z = ftmp;
+    //racer.velocity_z = ftmp;
 
-    if(player.movement_x != 0)
-    {
-        if(player.movement_x > 0)
-            df += v_forward  * autocvar_g_vehicle_racer_speed_forward;
-        else if(player.movement_x < 0)
-            df -= v_forward  * autocvar_g_vehicle_racer_speed_forward;
-    }
-
-    if(player.movement_y != 0)
-    {
-        if(player.movement_y < 0)
-            df -= v_right * autocvar_g_vehicle_racer_speed_strafe;
-        else if(player.movement_y > 0)
-            df += v_right * autocvar_g_vehicle_racer_speed_strafe;
-    }
-    
     if(vlen(player.movement) != 0)
     {
+        if(player.movement_x)
+            df += v_forward * ((player.movement_x > 0) ? autocvar_g_vehicle_racer_speed_forward : -autocvar_g_vehicle_racer_speed_forward);
+
+        if(player.movement_y)
+            df += v_right * ((player.movement_y > 0) ? autocvar_g_vehicle_racer_speed_strafe : -autocvar_g_vehicle_racer_speed_strafe);
+
         if(self.sound_nexttime < time || self.sounds != 1)
-        {        
+        {
             self.sounds = 1;
             self.sound_nexttime = time + 10.922667; //soundlength("vehicles/racer_move.wav");
             sound (self, CH_TRIGGER_SINGLE, "vehicles/racer_move.wav", VOL_VEHICLEENGINE, ATTN_NORM);
         }
     }
     else
-    {        
+    {
         if(self.sound_nexttime < time || self.sounds != 0)
-        {        
+        {
             self.sounds = 0;
             self.sound_nexttime = time + 11.888604; //soundlength("vehicles/racer_idle.wav");
             sound (self, CH_TRIGGER_SINGLE, "vehicles/racer_idle.wav", VOL_VEHICLEENGINE, ATTN_NORM);
-        }        
+        }
     }
-    
+
     // Afterburn
     if (player.BUTTON_JUMP && racer.vehicle_energy >= (autocvar_g_vehicle_racer_afterburn_cost * frametime))
     {
         if(time - racer.wait > 0.2)
-            pointparticles(particleeffectnum("wakizashi_booster_smoke"), self.origin, '0 0 0', 1);            
-        
+            pointparticles(particleeffectnum("wakizashi_booster_smoke"), self.origin, '0 0 0', 1);
+
         racer.wait = time;
         racer.vehicle_energy -= autocvar_g_vehicle_racer_afterburn_cost * frametime;
         df += (v_forward * autocvar_g_vehicle_racer_speed_afterburn);
-        
-        if(self.invincible_finished < time)
-        {            
-            traceline(self.origin, self.origin - '0 0 256', MOVE_NORMAL, self);
+
+        if(racer.invincible_finished < time)
+        {
+            traceline(racer.origin, racer.origin - '0 0 256', MOVE_NORMAL, self);
             if(trace_fraction != 1.0)
                 pointparticles(particleeffectnum("smoke_small"), trace_endpos, '0 0 0', 1);
-            
-            self.invincible_finished = time + 0.1 + (random() * 0.1);
+
+            racer.invincible_finished = time + 0.1 + (random() * 0.1);
         }
 
-        if(self.strength_finished < time)
-        {        
-            //self.sounds = 2;
-            self.strength_finished = time + 10.922667; //soundlength("vehicles/racer_boost.wav");
-            sound (self.tur_head, CH_TRIGGER_SINGLE, "vehicles/racer_boost.wav", VOL_VEHICLEENGINE, ATTN_NORM);            
-        }        
+        if(racer.strength_finished < time)
+        {
+            racer.strength_finished = time + 10.922667; //soundlength("vehicles/racer_boost.wav");
+            sound (racer.tur_head, CH_TRIGGER_SINGLE, "vehicles/racer_boost.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+        }
     }
     else
     {
-        self.strength_finished = 0;
-        sound (self.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTN_NORM);
+        racer.strength_finished = 0;
+        sound (racer.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTN_NORM);
     }
-        
 
-    racer.velocity  += df * frametime;
-
-    df = (vlen(racer.velocity) * autocvar_g_vehicle_racer_downforce * v_up) * frametime;
-    racer.velocity  = racer.velocity - df;
-    player.movement = racer.velocity;
+       df -= v_up * (vlen(racer.velocity) * autocvar_g_vehicle_racer_downforce);
+    player.movement = racer.velocity += df * frametime;
 
     if(player.BUTTON_ATCK)
     if(time > racer.attack_finished_single)
@@ -397,7 +382,6 @@ float racer_frame()
             racer.cnt = 1;
         }
         racer.attack_finished_single = time + autocvar_g_vehicle_racer_cannon_refire;
-        //self.owner.vehicle_energy = racer.vehicle_energy / autocvar_g_vehicle_racer_energy;
     }
 
     if(autocvar_g_vehicle_racer_rocket_locktarget)
@@ -420,16 +404,17 @@ float racer_frame()
     if(time > racer.delay)
     if(player.BUTTON_ATCK2)
     {
-        self.misc_bulletcounter += 1;
+        racer.misc_bulletcounter += 1;
         racer.delay = time + 0.3;
-        if(self.misc_bulletcounter == 1)
-            racer_fire_rocket("tag_rocket_r", (self.lock_strength == 1 && self.lock_target) ? self.lock_target : world);
-        else if(self.misc_bulletcounter == 2)
+
+        if(racer.misc_bulletcounter == 1)
+            racer_fire_rocket("tag_rocket_r", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world);
+        else if(racer.misc_bulletcounter == 2)
         {
-            racer_fire_rocket("tag_rocket_l", (self.lock_strength == 1 && self.lock_target) ? self.lock_target : world);
-            self.lock_strength  = 0;
-            self.lock_target    = world;
-            self.misc_bulletcounter = 0;
+            racer_fire_rocket("tag_rocket_l", (racer.lock_strength == 1 && racer.lock_target) ? racer.lock_target : world);
+            racer.lock_strength  = 0;
+            racer.lock_target    = world;
+            racer.misc_bulletcounter = 0;
 
             racer.delay = time + autocvar_g_vehicle_racer_rocket_refire;
             racer.lip = time;
@@ -437,23 +422,22 @@ float racer_frame()
     }
     player.vehicle_reload1 = bound(0, 100 * ((time - racer.lip) / (racer.delay - racer.lip)), 100);
 
-    if(self.vehicle_flags  & VHF_SHIELDREGEN)
+    if(racer.vehicle_flags  & VHF_SHIELDREGEN)
         vehicles_regen(dmg_time, vehicle_shield, autocvar_g_vehicle_racer_shield, autocvar_g_vehicle_racer_shield_regen_pause, autocvar_g_vehicle_racer_shield_regen, frametime);
 
-    if(self.vehicle_flags  & VHF_HEALTHREGEN)
+    if(racer.vehicle_flags  & VHF_HEALTHREGEN)
         vehicles_regen(dmg_time, vehicle_health, autocvar_g_vehicle_racer_health, autocvar_g_vehicle_racer_health_regen_pause, autocvar_g_vehicle_racer_health_regen, frametime);
 
-    if(self.vehicle_flags  & VHF_ENERGYREGEN)
+    if(racer.vehicle_flags  & VHF_ENERGYREGEN)
         vehicles_regen(wait, vehicle_energy, autocvar_g_vehicle_racer_energy, autocvar_g_vehicle_racer_energy_regen_pause, autocvar_g_vehicle_racer_energy_regen, frametime);
 
 
     VEHICLE_UPDATE_PLAYER(health, racer);
     VEHICLE_UPDATE_PLAYER(energy, racer);
 
-    if(self.vehicle_flags & VHF_HASSHIELD)
+    if(racer.vehicle_flags & VHF_HASSHIELD)
         VEHICLE_UPDATE_PLAYER(shield, racer);
 
-
     player.BUTTON_ATCK = player.BUTTON_ATCK2 = 0;
     setorigin(player,racer.origin + '0 0 32');
     player.velocity = racer.velocity;
@@ -464,32 +448,24 @@ float racer_frame()
 
 void racer_think()
 {
-    /*
-    float a, b, c;a = autocvar_g_vehicle_racer_anglestabilizer;
-    b = autocvar_g_vehicle_racer_springlength;
-    c = autocvar_g_vehicle_racer_hoverpower;
-
-    autocvar_g_vehicle_racer_anglestabilizer = 36;
-    autocvar_g_vehicle_racer_springlength = 96;
-    autocvar_g_vehicle_racer_hoverpower = 300;
-    */
-
-    racer_align4point(); //time - self.nextthink);
-
-    /*
-    //if(self.velocity_z > 0)
-    //    self.velocity_z *= 0.95;
-
-    autocvar_g_vehicle_racer_anglestabilizer = a;
-    autocvar_g_vehicle_racer_springlength = b;
-    autocvar_g_vehicle_racer_hoverpower = c;
-    */
-
-    self.velocity_x *= 0.9;
-    self.velocity_y *= 0.9;
-    self.velocity_z *= 0.8;
-    self.velocity_z += sin(time * 2) * 16;
-    self.nextthink = time; // + 0.05;
+    self.nextthink = time;
+
+    float pushdeltatime = time - self.lastpushtime;
+    if (pushdeltatime > 0.15) pushdeltatime = 0;
+    self.lastpushtime = time;
+    if(!pushdeltatime) return;
+
+    tracebox(self.origin, self.mins, self.maxs, self.origin - ('0 0 1' * autocvar_g_vehicle_racer_springlength), MOVE_NORMAL, self);
+
+    vector df = self.velocity * -autocvar_g_vehicle_racer_friction;
+       df_z += (1 - trace_fraction) * autocvar_g_vehicle_racer_hoverpower + sin(time * 2) * (autocvar_g_vehicle_racer_springlength * 2);
+
+       self.velocity += df * pushdeltatime;
+    if(self.velocity_z > 0)
+        self.velocity_z *= 1 - autocvar_g_vehicle_racer_upforcedamper * pushdeltatime;
+
+    self.angles_x *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime);
+    self.angles_z *= 1 - (autocvar_g_vehicle_racer_anglestabilizer * pushdeltatime);
 }
 
 void racer_enter()
@@ -497,20 +473,22 @@ void racer_enter()
     self.movetype = MOVETYPE_BOUNCE;
     self.owner.vehicle_health = (self.vehicle_health / autocvar_g_vehicle_racer_health)  * 100;
     self.owner.vehicle_shield = (self.vehicle_shield / autocvar_g_vehicle_racer_shield)  * 100;
-    
+
     if(self.owner.flagcarried)
        setorigin(self.owner.flagcarried, '-190 0 96');
+
+       //targetdrone_spawn(self.origin + '0 0 512' + randomvec() * 256, 1);
 }
 
 void racer_exit(float eject)
 {
     vector spot;
-    
+
     self.think      = racer_think;
     self.nextthink  = time;
-    self.movetype   = MOVETYPE_TOSS;
+    self.movetype   = MOVETYPE_BOUNCE;
     sound (self.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTN_NORM);
-    
+
     if not (self.owner)
         return;
 
@@ -525,15 +503,27 @@ void racer_exit(float eject)
        }
        else
        {
-           self.owner.velocity = normalize(self.velocity) * autocvar_sv_maxairspeed;
+               if(vlen(self.velocity) > 2 * autocvar_sv_maxairspeed)
+               {
+                       self.owner.velocity = normalize(self.velocity) * autocvar_sv_maxairspeed * 2;
+                       self.owner.velocity_z += 200;
+                       spot = self.origin + v_forward * 32 + '0 0 32';
+                       spot = vehicles_findgoodexit(spot);
+               }
+               else
+               {
+                       self.owner.velocity = self.velocity * 0.5;
+                       self.owner.velocity_z += 10;
+                       spot = self.origin - v_forward * 200 + '0 0 32';
+                       spot = vehicles_findgoodexit(spot);
+               }
            self.owner.oldvelocity = self.owner.velocity;
-           spot = self.origin - v_forward * 200 + '0 0 64';
-           spot = vehicles_findgoodexit(spot);
            setorigin(self.owner , spot);
        }
        antilag_clear(self.owner);
     self.owner = world;
 }
+
 void racer_impact()
 {
     if(autocvar_g_vehicle_racer_bouncepain_x)
@@ -554,7 +544,7 @@ void racer_spawn()
 
     setsize(self, RACER_MIN * 0.5, RACER_MAX * 0.5);
     self.bouncefactor = autocvar_g_vehicle_racer_bouncefactor;
-    self.bouncestop = autocvar_g_vehicle_racer_bouncestop;    
+    self.bouncestop = autocvar_g_vehicle_racer_bouncestop;
     self.vehicle_impact = racer_impact;
     //self.destvec = autocvar_g_vehicle_racer_bouncepain;
 }
@@ -604,8 +594,8 @@ void racer_die()
     self.wait         = time;
     self.cnt          = 1 + random() * 2;
     self.touch        = racer_deadtouch;
-    
-    pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);    
+
+    pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);
 
     if(random() < 0.5)
         self.avelocity_z  = 32;
@@ -661,7 +651,7 @@ void spawnfunc_vehicle_racer()
 
     precache_sound ("weapons/lasergun_fire.wav");
     precache_sound ("weapons/rocket_fire.wav");
-    
+
     precache_sound ("vehicles/racer_idle.wav");
     precache_sound ("vehicles/racer_move.wav");
     precache_sound ("vehicles/racer_boost.wav");
@@ -685,7 +675,7 @@ void spawnfunc_vehicle_racer()
         self.vehicle_flags |= VHF_HEALTHREGEN;
 
     self.think = racer_dinit;
-    
+
     if(g_assault)
         self.nextthink = time + 0.5;
     else
index 20c74d3a17e24deb0012882c634c9d527d4747d0..bfd13a0e7d52941c5494b2104d160b9d20126c73 100644 (file)
@@ -84,9 +84,9 @@ void SendAuxiliaryXhair2(entity own, vector loc, vector clr, float axh_id)
 // End AuxiliaryXhair
 
 /**
-    Notifies the client that he enterd a vehicle, and sends 
+    Notifies the client that he enterd a vehicle, and sends
     realavent data.
-    
+
     only sends vehicle_id atm (wich is a HUD_* constant, ex. HUD_SPIDERBOT)
 **/
 void CSQCVehicleSetup(entity own, float vehicle_id)
@@ -115,6 +115,118 @@ void CSQCVehicleSetup(entity own, float vehicle_id)
 .float  lock_strength;
 .float  lock_time;
 .float  lock_soundtime;
+float  DAMAGE_TARGETDRONE = 10;
+
+vector targetdrone_getnewspot()
+{
+
+       vector spot;
+       float i;
+       for(i = 0; i < 100; ++i)
+       {
+               spot = self.origin + randomvec() * 1024;
+               tracebox(spot, self.mins, self.maxs, spot, MOVE_NORMAL, self);
+               if(trace_fraction == 1.0 && trace_startsolid == 0 && trace_allsolid == 0)
+                       return spot;
+       }
+       return self.origin;
+}
+void targetdrone_think();
+void targetdrone_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
+void targetdrone_renwe()
+{
+       self.think = targetdrone_think;
+       self.nextthink = time + 0.1;
+       setorigin(self, targetdrone_getnewspot());
+       self.health = 200;
+       self.takedamage = DAMAGE_TARGETDRONE;
+       self.event_damage = targetdrone_damage;
+       self.solid = SOLID_BBOX;
+       setmodel(self, "models/runematch/rune.mdl");
+       self.effects = EF_LOWPRECISION;
+       self.scale = 10;
+       self.movetype = MOVETYPE_BOUNCEMISSILE;
+       setsize(self, '-100 -100 -100', '100 100 100');
+
+}
+void targetdrone_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+       self.health -= damage;
+       if(self.health <= 0)
+       {
+               pointparticles(particleeffectnum("explosion_medium"), self.origin, '0 0 0', 1);
+
+               if(!self.cnt)
+                       remove(self);
+               else
+               {
+                       self.think = targetdrone_renwe;
+                       self.nextthink = time + 1 + random() * 2;
+                       self.solid = SOLID_NOT;
+                       setmodel(self, "");
+               }
+       }
+}
+entity targetdrone_getfear()
+{
+       entity fear;
+       float i;
+
+       for(i = 64; i <= 1024; i += 64)
+       {
+               fear = findradius(self.origin, i);
+               while(fear)
+               {
+                       if(fear.bot_dodge)
+                               return fear;
+
+                       fear = fear.chain;
+               }
+       }
+
+       return world;
+}
+void targetdrone_think()
+{
+       self.nextthink = time + 0.1;
+
+       if(self.enemy)
+       if(self.enemy.deadflag != DEAD_NO)
+               self.enemy = targetdrone_getfear();
+
+       if(!self.enemy)
+               self.enemy = targetdrone_getfear();
+
+       vector newdir;
+
+       if(self.enemy)
+               newdir = steerlib_push(self.enemy.origin) + randomvec() * 0.75;
+       else
+               newdir = randomvec() * 0.75;
+
+       newdir = newdir * 0.5 + normalize(self.velocity) * 0.5;
+
+       if(self.enemy)
+               self.velocity = normalize(newdir) * (500 + (1024 / min(vlen(self.enemy.origin - self.origin), 1024)) * 700);
+       else
+               self.velocity = normalize(newdir) * 750;
+
+       tracebox(self.origin, self.mins, self.maxs, self.origin + self.velocity * 2, MOVE_NORMAL, self);
+       if(trace_fraction != 1.0)
+               self.velocity = self.velocity * -1;
+
+       //normalize((normalize(self.velocity) * 0.5 + newdir * 0.5)) * 750;
+}
+
+void targetdrone_spawn(vector _where, float _autorenew)
+{
+       entity drone = spawn();
+       setorigin(drone, _where);
+       drone.think = targetdrone_renwe;
+       drone.nextthink = time + 0.1;
+       drone.cnt = _autorenew;
+}
+
 void vehicles_locktarget(float incr, float decr, float _lock_time)
 {
     if(self.lock_target && self.lock_target.deadflag != DEAD_NO)
@@ -132,7 +244,7 @@ void vehicles_locktarget(float incr, float decr, float _lock_time)
             self.lock_soundtime = time + 0.5;
             play2(self.owner, "vehicles/locked.wav");
         }
-        
+
         return;
     }
 
@@ -144,28 +256,30 @@ void vehicles_locktarget(float incr, float decr, float _lock_time)
         if(trace_ent.deadflag != DEAD_NO)
             trace_ent = world;
 
-        if not (trace_ent.vehicle_flags & VHF_ISVEHICLE || trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET)
+        if not (trace_ent.vehicle_flags & VHF_ISVEHICLE ||
+                               trace_ent.turrcaps_flags & TFL_TURRCAPS_ISTURRET ||
+                               trace_ent.takedamage == DAMAGE_TARGETDRONE)
             trace_ent = world;
     }
 
     if(self.lock_target == world && trace_ent != world)
         self.lock_target = trace_ent;
-    
-    if(self.lock_target && trace_ent == self.lock_target) 
-    {            
+
+    if(self.lock_target && trace_ent == self.lock_target)
+    {
         if(self.lock_strength != 1 && self.lock_strength + incr >= 1)
         {
             play2(self.owner, "vehicles/lock.wav");
             self.lock_soundtime = time + 0.8;
-        }        
+        }
         else if (self.lock_strength != 1 && self.lock_soundtime < time)
-        {            
+        {
             play2(self.owner, "vehicles/locking.wav");
             self.lock_soundtime = time + 0.3;
         }
-        
-    }    
-        
+
+    }
+
     // Have a locking target
     // Trace hit current target
     if(trace_ent == self.lock_target && trace_ent != world)
@@ -237,8 +351,8 @@ void vehicles_projectile_damage(entity inflictor, entity attacker, float damage,
 {
     // Ignore damage from oterh projectiles from my owner (dont mess up volly's)
     if(inflictor.owner == self.owner)
-        return; 
-    
+        return;
+
     self.health -= damage;
     self.velocity += force;
     if(self.health < 1)
@@ -377,21 +491,21 @@ float vehicles_crushable(entity e)
 }
 
 void vehilces_impact(float _minspeed, float _speedfac, float _maxpain)
-{    
+{
     if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
         return;
-    
+
     if(self.play_time < time)
-    {                    
+    {
         float wc = vlen(self.velocity - self.oldvelocity);
         //dprint("oldvel: ", vtos(self.oldvelocity), "\n");
         //dprint("vel: ", vtos(self.velocity), "\n");
         if(_minspeed < wc)
         {
-            float take = take = min(_speedfac * wc, _maxpain);
+            float take = min(_speedfac * wc, _maxpain);
             Damage (self, world, world, take, DEATH_FALL, self.origin, '0 0 0');
             self.play_time = time + 0.25;
-            
+
             //dprint("wc: ", ftos(wc), "\n");
             //dprint("take: ", ftos(take), "\n");
         }
@@ -409,14 +523,14 @@ void vehicles_touch()
         {
             if(vlen(self.velocity) != 0)
                 Damage(other, self, self.owner, autocvar_g_vehicles_crush_dmg, DEATH_VHCRUSH, '0 0 0', normalize(other.origin - self.origin) * autocvar_g_vehicles_crush_force);
-            
+
             return; // Dont do selfdamage when hitting "soft targets".
         }
-        
+
         if(self.play_time < time)
         if(self.vehicle_impact)
             self.vehicle_impact();
-        
+
         return;
     }
 
@@ -449,7 +563,7 @@ void vehicles_enter()
     if(self.team)
     if(self.team != other.team)
         return;
-        
+
     RemoveGrapplingHook(other);
 
     self.vehicle_ammo1   = 0;
@@ -519,19 +633,19 @@ void vehicles_enter()
     vehicles_clearrturn();
 
     CSQCVehicleSetup(self.owner, self.hud);
-    
+
     if(other.flagcarried)
     {
         if(!autocvar_g_vehicles_allow_flagcarry)
             DropFlag(other.flagcarried, world, world);
         else
-        {            
+        {
             other.flagcarried.scale = 1;
-            setattachment(other.flagcarried, self, ""); 
+            setattachment(other.flagcarried, self, "");
             setorigin(other, '0 0 96');
         }
     }
-    
+
     self.vehicle_enter();
     antilag_clear(other);
 }
@@ -545,17 +659,17 @@ vector vehicles_findgoodexit(vector prefer_spot)
 {
     //vector exitspot;
     float mysize;
-    
+
     tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, prefer_spot, MOVE_NORMAL, self.owner);
     if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
         return prefer_spot;
-    
+
     mysize = vlen(self.maxs - self.mins);
     float i;
     vector v, v2;
     v2 = 0.5 * (self.absmin + self.absmax);
     for(i = 0; i < 100; ++i)
-    {        
+    {
         v = randomvec();
         v_z = 0;
         v = v2 + normalize(v) * mysize;
@@ -563,13 +677,13 @@ vector vehicles_findgoodexit(vector prefer_spot)
         if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
             return v;
     }
-    
+
     /*
     exitspot = (self.origin + '0 0 48') + v_forward * mysize;
     tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
     if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
         return exitspot;
-    
+
     exitspot = (self.origin + '0 0 48') - v_forward * mysize;
     tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
     if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
@@ -579,13 +693,13 @@ vector vehicles_findgoodexit(vector prefer_spot)
     tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
     if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
         return exitspot;
-    
+
     exitspot = (self.origin + '0 0 48') - v_right * mysize;
     tracebox(self.origin + '0 0 32', PL_MIN, PL_MAX, exitspot, MOVE_NORMAL, self.owner);
     if(trace_fraction == 1.0 && !trace_startsolid && !trace_allsolid)
         return exitspot;
     */
-    
+
     return self.origin;
 }
 
@@ -594,14 +708,14 @@ vector vehicles_findgoodexit(vector prefer_spot)
     custom code goes in self.vehicle_exit
 **/
 void vehicles_exit(float eject)
-{      
+{
     entity oldself;
     if(self.flags & FL_CLIENT)
     {
         oldself = self;
         self = self.vehicle;
     }
-    
+
        self.flags |= FL_NOTARGET;
 
     if (self.owner)
@@ -629,7 +743,7 @@ void vehicles_exit(float eject)
         self.owner.hud            = HUD_NORMAL;
         self.owner.switchweapon   = self.switchweapon;
         //self.owner.BUTTON_USE     = 0;
-        
+
         CSQCVehicleSetup(self.owner, HUD_NORMAL);
     }
 
@@ -646,19 +760,19 @@ void vehicles_exit(float eject)
         self.team = 0;
     else
         self.team = self.tur_head.team;
-    
+
     if(self.owner.flagcarried)
     {
         self.owner.flagcarried.scale = 0.6;
-        setattachment(self.owner.flagcarried, self.owner, ""); 
+        setattachment(self.owner.flagcarried, self.owner, "");
         setorigin(self.owner.flagcarried, FLAG_CARRY_POS);
     }
-    
+
     sound (self, CH_TRIGGER_SINGLE, "misc/null.wav", 1, ATTN_NORM);
     self.vehicle_exit(eject);
     self.owner = world;
     vehicles_reset_colors();
-    
+
     if(oldself)
         self = oldself;
 }
@@ -691,25 +805,25 @@ void shieldhit_think()
 }
 
 void vehicles_painframe()
-{    
+{
     if(self.owner.vehicle_health <= 50)
     if(self.pain_frame < time)
-    {  
-        float _ftmp;  
+    {
+        float _ftmp;
         _ftmp = self.owner.vehicle_health / 50;
         self.pain_frame = time + 0.1 + (random() * 0.5 * _ftmp);
         pointparticles(particleeffectnum("smoke_small"), (self.origin + (randomvec() * 80)), '0 0 0', 1);
-        
+
         if(self.vehicle_flags & VHF_DMGSHAKE)
             self.velocity += randomvec() * 30;
-        
+
         if(self.vehicle_flags & VHF_DMGROLL)
             if(self.vehicle_flags & VHF_DMGHEADROLL)
                 self.tur_head.angles += randomvec();
             else
                 self.angles += randomvec();
-        
-    }    
+
+    }
 }
 
 void vehicles_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
@@ -743,7 +857,7 @@ void vehicles_damage(entity inflictor, entity attacker, float damage, float deat
             self.vehicle_shieldent.colormod = '2 0 0';
             self.vehicle_shield             = 0;
             self.vehicle_shieldent.alpha    = 0.75;
-            
+
                if(sound_allowed(MSG_BROADCAST, attacker))
                 spamsound (self, CH_PAIN, "onslaught/ons_hit2.wav", VOL_BASE, ATTN_NORM);   // FIXME: PLACEHOLDER
         }
@@ -786,11 +900,11 @@ void vehicles_clearrturn()
         {
             ret.classname   = "";
             ret.think       = SUB_Remove;
-            ret.nextthink   = time + 0.1;            
-            
+            ret.nextthink   = time + 0.1;
+
             if(ret.waypointsprite_attached)
                 WaypointSprite_Kill(ret.waypointsprite_attached);
-            
+
             return;
         }
         ret = ret.chain;
@@ -806,7 +920,7 @@ void vehicles_return()
 
     if(self.waypointsprite_attached)
         WaypointSprite_Kill(self.waypointsprite_attached);
-            
+
     remove(self);
 }
 
@@ -814,50 +928,50 @@ void vehicles_showwp_goaway()
 {
     if(self.waypointsprite_attached)
         WaypointSprite_Kill(self.waypointsprite_attached);
-            
+
     remove(self);
-    
+
 }
 
 void vehicles_showwp()
 {
     entity oldself;
     vector rgb;
-    
+
     if(self.cnt)
-    {        
+    {
         self.think      = vehicles_return;
         self.nextthink  = self.cnt;
-    }    
+    }
     else
     {
         self.think      = vehicles_return;
         self.nextthink  = time +1;
-        
+
         oldself = self;
         self = spawn();
         setmodel(self, "null");
         self.team = oldself.enemy.team;
         self.enemy = oldself.enemy;
         setorigin(self, oldself.enemy.pos1);
-        
+
         self.nextthink = time + 5;
         self.think = vehicles_showwp_goaway;
     }
-    
+
     if(teamplay && self.team)
            rgb = TeamColor(self.team);
     else
            rgb = '1 1 1';
     WaypointSprite_Spawn("vehicle", 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, TRUE, RADARICON_POWERUP, rgb);
     if(self.waypointsprite_attached)
-    {        
-        WaypointSprite_UpdateRule(self.waypointsprite_attached, self.enemy.team, SPRITERULE_DEFAULT);        
+    {
+        WaypointSprite_UpdateRule(self.waypointsprite_attached, self.enemy.team, SPRITERULE_DEFAULT);
         if(oldself == world)
-            WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, self.nextthink);        
+            WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, self.nextthink);
         WaypointSprite_Ping(self.waypointsprite_attached);
-    }    
-    
+    }
+
     if(oldself != world)
         self = oldself;
 }
@@ -865,28 +979,28 @@ void vehicles_showwp()
 void vehicles_setreturn()
 {
     entity ret;
-    
+
     vehicles_clearrturn();
 
     ret = spawn();
     ret.classname   = "vehicle_return";
-    ret.enemy       = self;    
+    ret.enemy       = self;
     ret.team        = self.team;
     ret.think       = vehicles_showwp;
-    
+
     if(self.deadflag != DEAD_NO)
     {
         ret.cnt         = time + self.vehicle_respawntime;
-        ret.nextthink   = min(time + self.vehicle_respawntime, time + self.vehicle_respawntime - 5);        
-    }        
+        ret.nextthink   = min(time + self.vehicle_respawntime, time + self.vehicle_respawntime - 5);
+    }
     else
     {
-        ret.nextthink   = min(time + self.vehicle_respawntime, time + self.vehicle_respawntime - 1);        
+        ret.nextthink   = min(time + self.vehicle_respawntime, time + self.vehicle_respawntime - 1);
     }
-    
+
     setmodel(ret, "null");
     setorigin(ret, self.pos1 + '0 0 96');
-       
+
 }
 
 void vehicles_configcheck(string  configname, float check_cvar)
@@ -984,9 +1098,9 @@ float vehicle_initialize(string  net_name,
 
     if(self.team && !teamplay)
         self.team = 0;
-        
+
     self.vehicle_flags |= VHF_ISVEHICLE;
-    
+
     setmodel(self, bodymodel);
 
     self.vehicle_viewport   = spawn();
@@ -1005,8 +1119,8 @@ float vehicle_initialize(string  net_name,
     self.PlayerPhysplug      = physproc;
     self.event_damage        = vehicles_damage;
     self.touch               = vehicles_touch;
-    self.think               = vehicles_spawn;    
-    self.nextthink           = time;        
+    self.think               = vehicles_spawn;
+    self.nextthink           = time;
     self.vehicle_respawntime = _respawntime;
     self.vehicle_spawn       = spawnproc;
 
@@ -1045,7 +1159,7 @@ float vehicle_initialize(string  net_name,
     self.pos1 = self.origin;
     self.pos2 = self.angles;
     self.tur_head.team = self.team;
-    
+
     return TRUE;
 }
 
index 1cd8b812cee7e1bc324b824d964459269820bd9d..a2f23956eed6f4f3f7b0389d523e8062555fb2d1 100644 (file)
@@ -243,31 +243,58 @@ void W_BallisticBullet_LeaveSolid_think()
        UpdateCSQCProjectile(self);
 }
 
-float W_BallisticBullet_LeaveSolid(entity e, vector vel, float constant)
+float W_BallisticBullet_LeaveSolid(float eff)
 {
        // move the entity along its velocity until it's out of solid, then let it resume
-
+       vector vel = self.velocity;
        float dt, dst, velfactor, v0, vs;
        float maxdist;
        float E0_m, Es_m;
+       float constant = self.dmg_radius * (other.ballistics_density ? other.ballistics_density : 1);
 
        // outside the world? forget it
        if(self.origin_x > world.maxs_x || self.origin_y > world.maxs_y || self.origin_z > world.maxs_z || self.origin_x < world.mins_x || self.origin_y < world.mins_y || self.origin_z < world.mins_z)
                return 0;
 
+       // special case for zero density and zero bullet constant: 
+
+       if(self.dmg_radius == 0)
+       {
+               if(other.ballistics_density < 0)
+                       constant = 0; // infinite travel distance
+               else
+                       return 0; // no penetration
+       }
+       else
+       {
+               if(other.ballistics_density < 0)
+                       constant = 0; // infinite travel distance
+               else if(other.ballistics_density == 0)
+                       constant = self.dmg_radius;
+               else
+                       constant = self.dmg_radius * other.ballistics_density;
+       }
+
        // E(s) = E0 - constant * s, constant = area of bullet circle * material constant / mass
        v0 = vlen(vel);
 
        E0_m = 0.5 * v0 * v0;
-       maxdist = E0_m / constant;
-       // maxdist = 0.5 * v0 * v0 / constant
-       // dprint("max dist = ", ftos(maxdist), "\n");
 
-       if(maxdist <= autocvar_g_ballistics_mindistance)
-               return 0;
+       if(constant)
+       {
+               maxdist = E0_m / constant;
+               // maxdist = 0.5 * v0 * v0 / constant
+               // dprint("max dist = ", ftos(maxdist), "\n");
 
-       traceline_inverted (self.origin, self.origin + normalize(vel) * maxdist, MOVE_NORMAL, self);
+               if(maxdist <= autocvar_g_ballistics_mindistance)
+                       return 0;
+       }
+       else
+       {
+               maxdist = vlen(other.maxs - other.mins) + 1; // any distance, as long as we leave the entity
+       }
 
+       traceline_inverted (self.origin, self.origin + normalize(vel) * maxdist, MOVE_NORMAL, self, TRUE);
        if(trace_fraction == 1) // 1: we never got out of solid
                return 0;
 
@@ -300,6 +327,13 @@ float W_BallisticBullet_LeaveSolid(entity e, vector vel, float constant)
        self.flags |= FL_ONGROUND; // prevent moving
        self.W_BallisticBullet_LeaveSolid_velocity = vel;
 
+       if(eff >= 0)
+               if(vlen(trace_endpos - self.origin) > 4)
+               {
+                       endzcurveparticles();
+                       trailparticles(self, eff, self.origin, trace_endpos);
+               }
+
        return 1;
 }
 
@@ -313,6 +347,12 @@ void W_BallisticBullet_Touch (void)
        PROJECTILE_TOUCH;
        W_BallisticBullet_Hit ();
 
+       if(self.dmg_radius < 0) // these NEVER penetrate solid
+       {
+               remove(self);
+               return;
+       }
+
        // if we hit "weapclip", bail out
        //
        // rationale of this check:
@@ -333,12 +373,8 @@ void W_BallisticBullet_Touch (void)
                return;
        }
 
-       density = other.ballistics_density;
-       if(density == 0)
-               density = 1;
-
        // go through solid!
-       if(!W_BallisticBullet_LeaveSolid(self, self.velocity, self.dmg_radius * density))
+       if(!W_BallisticBullet_LeaveSolid(-1))
        {
                remove(self);
                return;
@@ -386,7 +422,12 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
        proj.nextthink = time + lifetime; // min(pLifetime, vlen(world.maxs - world.mins) / pSpeed);
        W_SetupProjectileVelocityEx(proj, dir, v_up, pSpeed, 0, 0, spread, antilagging);
        proj.angles = vectoangles(proj.velocity);
-       proj.dmg_radius = autocvar_g_ballistics_materialconstant / bulletconstant;
+       if(bulletconstant > 0)
+               proj.dmg_radius = autocvar_g_ballistics_materialconstant / bulletconstant;
+       else if(bulletconstant == 0)
+               proj.dmg_radius = 0;
+       else
+               proj.dmg_radius = -1;
        // so: bulletconstant = bullet mass / area of bullet circle
        setorigin(proj, start);
        proj.flags = FL_PROJECTILE;
@@ -470,6 +511,9 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
                                W_BallisticBullet_Hit();
                        }
 
+                       if(proj.dmg_radius < 0) // these NEVER penetrate solid
+                               break;
+
                        // if we hit "weapclip", bail out
                        //
                        // rationale of this check:
@@ -487,15 +531,13 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
                        if not(trace_dphitcontents & DPCONTENTS_OPAQUE)
                                break;
 
-                       density = other.ballistics_density;
-                       if(density == 0)
-                               density = 1;
-
                        // go through solid!
-                       if(!W_BallisticBullet_LeaveSolid(self, self.velocity, self.dmg_radius * density))
+                       if(!W_BallisticBullet_LeaveSolid((other && (other.solid != SOLID_BSP)) ? eff : -1))
                                break;
 
                        W_BallisticBullet_LeaveSolid_think();
+
+                       self.projectiledeathtype |= HITTYPE_BOUNCE;
                }
                frametime = savetime;
                self = oldself;
@@ -588,7 +630,7 @@ void W_PrepareExplosionByDamage(entity attacker, void() explode)
        self.takedamage = DAMAGE_NO;
        self.event_damage = SUB_Null;
        
-       if not(g_ca)
+       if((attacker.flags & FL_CLIENT) && !autocvar_g_projectiles_keep_owner)
        {
                self.owner = attacker;
                self.realowner = attacker;
index 1fb823da91fcedad865f5cec22a3ebab3008c94d..3134a8bb3b66805ac2981732e10952a432a4478d 100644 (file)
@@ -326,7 +326,6 @@ float w_porto(float req)
                                        ClientData_Touch(self);
                                }
                        }
-                       v_angle_save = self.v_angle;
                        if(self.porto_v_angle_held)
                                makevectors(self.porto_v_angle); // override the previously set angles
 
index 33fb4140baa7b79a3938cb63029e745f781ab7ef..a3aa34de800b1f7bd599b6f3c88629687f6df3e7 100644 (file)
@@ -4,57 +4,58 @@ set g_vehicle_racer_health              190
 set g_vehicle_racer_health_regen        0
 set g_vehicle_racer_health_regen_pause  0
 
-set g_vehicle_racer_shield              75
-set g_vehicle_racer_shield_regen        25
+set g_vehicle_racer_shield              70
+set g_vehicle_racer_shield_regen        30
 set g_vehicle_racer_shield_regen_pause  1
 
-set g_vehicle_racer_energy              125
+set g_vehicle_racer_energy              100
 set g_vehicle_racer_energy_regen        40
 set g_vehicle_racer_energy_regen_pause  1
 
-set g_vehicle_racer_speed_stop          2000
-set g_vehicle_racer_speed_forward       800
+set g_vehicle_racer_speed_stop          2500
+set g_vehicle_racer_speed_forward       500
 set g_vehicle_racer_speed_strafe        500
-set g_vehicle_racer_speed_afterburn     2000
-set g_vehicle_racer_friction            0.4
-set g_vehicle_racer_afterburn_cost      60      // energy consumed per second
+set g_vehicle_racer_speed_afterburn     3000
+set g_vehicle_racer_friction            0.3
+set g_vehicle_racer_afterburn_cost      50      // energy consumed per second
 
 set g_vehicle_racer_hovertype           0       // 0 = hover, != 0 = maglev
-set g_vehicle_racer_hoverpower          5000    // NOTE!! x 4 (4 engines)
+set g_vehicle_racer_hoverpower          7500    // NOTE!! x 4 (4 engines)
 set g_vehicle_racer_upforcedamper       10
 
 set g_vehicle_racer_downforce            0.01
-set g_vehicle_racer_springlength         65
+set g_vehicle_racer_springlength         70
 set g_vehicle_racer_collision_multiplier 0.05
 set g_vehicle_racer_anglestabilizer      1.75
 
 set g_vehicle_racer_turnspeed          200
 set g_vehicle_racer_pitchspeed         100
-set g_vehicle_racer_maxpitch           25
-set g_vehicle_racer_turnroll           32
+set g_vehicle_racer_maxpitch           20
+set g_vehicle_racer_turnroll           16
 
 set g_vehicle_racer_cannon_speed        9000
-set g_vehicle_racer_cannon_damage       20
+set g_vehicle_racer_cannon_damage       25
 set g_vehicle_racer_cannon_radius       100
 set g_vehicle_racer_cannon_refire       0.1
-set g_vehicle_racer_cannon_cost         4
+set g_vehicle_racer_cannon_cost         10
 set g_vehicle_racer_cannon_spread       0.0125
 set g_vehicle_racer_cannon_force        50
 
 set g_vehicle_racer_rocket_speed       1000
 set g_vehicle_racer_rocket_accel       1400
-set g_vehicle_racer_rocket_turnrate    0.17
-set g_vehicle_racer_rocket_damage      160
+set g_vehicle_racer_rocket_turnrate    0.1
+set g_vehicle_racer_rocket_damage      165
 set g_vehicle_racer_rocket_force       350
 set g_vehicle_racer_rocket_radius      125
 set g_vehicle_racer_rocket_refire      6
 set g_vehicle_racer_rocket_cost        0
+set g_vehicle_racer_rocket_climbspeed  1750
 
 set g_vehicle_racer_rocket_locktarget           1
 set g_vehicle_racer_rocket_locking_time         0.4
-set g_vehicle_racer_rocket_locking_releasetime  1.6
+set g_vehicle_racer_rocket_locking_releasetime  1.5
 set g_vehicle_racer_rocket_locked_time          5
-set g_vehicle_racer_rocket_locked_maxangle      1.46
+set g_vehicle_racer_rocket_locked_maxangle      1.75
 
 set g_vehicle_racer_blowup_radius           250
 set g_vehicle_racer_blowup_coredamage       250
@@ -63,6 +64,6 @@ set g_vehicle_racer_blowup_forceintensity   250
 
 set g_vehicle_racer_bouncefactor 0.25   // Factor of old velocity to keep after colission
 set g_vehicle_racer_bouncestop 0        // if != 0, New veloctiy after bounce = 0 if new velocity < this
-set g_vehicle_racer_bouncepain "35 2 250" // "minspeed_for_pain speedchange_to_pain_factor max_damage"
+set g_vehicle_racer_bouncepain "60 0.75 300" // "minspeed_for_pain speedchange_to_pain_factor max_damage"
 
 set g_vehicle_racer_mass                    900