Merge remote branch 'origin/master' into fruitiex/panelhud
authorFruitieX <fruitiex@gmail.com>
Fri, 24 Dec 2010 01:00:53 +0000 (03:00 +0200)
committerFruitieX <fruitiex@gmail.com>
Fri, 24 Dec 2010 01:00:53 +0000 (03:00 +0200)
42 files changed:
balanceXonotic.cfg
defaultXonotic.cfg
effectinfo.txt
keybinds.txt
models/weapons/g_crylink.md3
models/weapons/g_hlac.md3
models/weapons/g_laser.md3
models/weapons/g_minelayer.md3
models/weapons/g_nex.md3
models/weapons/g_porto.md3
models/weapons/v_crylink.md3
models/weapons/v_hlac.md3
models/weapons/v_hookgun.md3
models/weapons/v_laser.md3
models/weapons/v_minelayer.md3
models/weapons/v_nex.md3
models/weapons/v_porto.md3
qcsrc/client/Defs.qc
qcsrc/client/View.qc
qcsrc/client/hud.qc
qcsrc/client/projectile.qc
qcsrc/menu/gamecommand.qc
qcsrc/menu/xonotic/dialog_multiplayer_create_advanced.c
qcsrc/menu/xonotic/dialog_multiplayer_playersetup.c
qcsrc/menu/xonotic/dialog_settings_effects.c
qcsrc/menu/xonotic/keybinder.c
qcsrc/menu/xonotic/util.qc
qcsrc/server/autocvars.qh
qcsrc/server/bot/havocbot/havocbot.qc
qcsrc/server/bot/havocbot/roles.qc
qcsrc/server/bot/navigation.qc
qcsrc/server/clientcommands.qc
qcsrc/server/g_damage.qc
qcsrc/server/g_subs.qc
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/t_jumppads.qc
qcsrc/server/t_plats.qc
qcsrc/server/w_common.qc
quake.rc
textures/hlac_glass.tga [new file with mode: 0644]
textures/hlac_plasma.tga [new file with mode: 0644]

index 7228328..4855a30 100644 (file)
@@ -356,7 +356,7 @@ set g_balance_minelayer_remote_force 300
 // }}}
 // {{{ electro
 set g_balance_electro_lightning 1
-set g_balance_electro_primary_damage 92
+set g_balance_electro_primary_damage 100
 set g_balance_electro_primary_edgedamage 0
 set g_balance_electro_primary_force 425
 set g_balance_electro_primary_force_up 125
index 18ce4a9..d2d2dca 100644 (file)
@@ -459,7 +459,7 @@ alias g_waypointeditor_unreachable "impulse 107"
 
 locs_enable 0
 pausable 0
-seta g_spawnshieldtime 0.300000 "number of seconds you are invincible after you spawned, this shield is lost after you fire"
+seta g_spawnshieldtime 1.000000 "number of seconds you are invincible after you spawned, this shield is lost after you fire"
 seta g_antilag 2       "AntiLag (0 = no AntiLag, 1 = verified client side hit scan, 2 = server side hit scan in the past, 3 = unverified client side hit scan)"
 set g_antilag_nudge 0 "don't touch"
 set g_antilag_bullets 1 "Bullets AntiLag (0 = no AntiLag, 1 = server side hit scan in the past) - DO NOT TOUCH (severely changes weapon balance)"
@@ -638,10 +638,12 @@ seta timelimit_suddendeath 5 "number of minutes suddendeath mode lasts after all
 set g_tdm 0 "Team Deathmatch: the team who kills their opponents most often wins"
 
 seta teamplay_mode 4 "default teamplay setting in team games. 1 = no friendly fire, self damage. 2 = friendly fire and self damage enabled. 3 = no friendly fire, but self damage enabled. 4 = obey the following four cvars"
-seta g_mirrordamage 0.300000   "for teamplay 4: mirror damage factor"
-seta g_friendlyfire 0.100000   "for teamplay 4: fiendly fire factor"
-seta g_teamdamage_threshold 50 "for teamplay 4: threshold over which to apply mirror damage"
-seta g_teamdamage_resetspeed 30        "for teamplay 4: how fast player's teamdamage count decreases"
+seta g_mirrordamage 0.700000   "for teamplay 4: mirror damage factor"
+seta g_mirrordamage_virtual 1  "for teamplay 4: do not actually apply mirror damage, just show graphics effect for it"
+seta g_friendlyfire 0.500000   "for teamplay 4: fiendly fire factor"
+seta g_friendlyfire_virtual 1  "for teamplay 4: do not actually apply friendly fire, just show graphics effect for it"
+seta g_teamdamage_threshold 40 "for teamplay 4: threshold over which to apply mirror damage"
+seta g_teamdamage_resetspeed 20        "for teamplay 4: how fast player's teamdamage count decreases"
 
 set deathmatch_force_teamplay 0        "Always play TDM instead of DM"
 seta g_balance_teams 0 "automatically balance out players entering instead of asking them for their preferred team"
@@ -936,8 +938,6 @@ alias +fire2 +button3
 alias -fire2 -button3
 alias +attack2 +button3 // old alias from Nexuiz
 alias -attack2 -button3 // old alias name from Nexuiz
-alias +zoom +button4
-alias -zoom -button4
 alias +crouch +button5
 alias -crouch -button5
 alias weapnext "_weapnext_${cl_weaponpriority_useforcycling}"
@@ -951,6 +951,12 @@ alias _weapprev_1 "impulse 16"
 alias _weapprev_2 "impulse 12"
 alias weapbest "impulse 13"
 
+// experimental zoom toggle (can be in wrong state at start of a game, though)
+set _togglezoom +
+alias +zoom "set _togglezoom -; +button4"
+alias -zoom "set _togglezoom +; -button4"
+alias togglezoom "${_togglezoom}zoom"
+
 alias reload "impulse 20"
 
 // movement
@@ -1416,13 +1422,13 @@ seta hud_showbinds_limit 2      "maximum number of bound keys to show for a command.
 
 seta hud_colorflash_alpha 0.5 "starting alpha of the color flash"
 
-seta hud_damage 1 "an improved version of gl_polyblend, draw an image instead when hurt"
+seta hud_damage 0.55 "an improved version of gl_polyblend, draw an image instead when hurt"
 seta hud_damage_gentle_alpha_multiplier 0.25 "how much to multiply alpha of flash when using the cl_gentle version, it's much more opaque than the non-gentle version"
 seta hud_damage_gentle_color "1 0.7 1" "color of flash for cl_gentle version"
 seta hud_damage_color "1 0 0" "color of flash"
 seta hud_damage_factor 0.025 "(damage * factor) = how much to add to the alpha value"
-seta hud_damage_fade_rate 1 "how much to subtract from the alpha value each second"
-seta hud_damage_maxalpha 2 "how much to limit the alpha value to"
+seta hud_damage_fade_rate 0.75 "how much to subtract from the alpha value each second"
+seta hud_damage_maxalpha 1.5 "how much to limit the alpha value to"
 seta hud_damage_pain_threshold 0.1 "how much alpha to ignore (must be bigger than the hud_damage_factor so that e.g. rot is ignored)"
 seta hud_damage_pain_threshold_lower 1.25 "how much we lower pain_threshold with when nearing 0 health (if pain_threshold gets negative then we always draw a flash at alpha = fabs(pain_threshold)"
 seta hud_damage_pain_threshold_lower_health 50 "at which health we start lowering pain_threshold"
@@ -2016,7 +2022,7 @@ utf8_enable 1
 // safe font defaults
 r_font_hinting 1
 r_font_disable_freetype 0
-r_font_size_snapping 2
+r_font_size_snapping 8
 
 // database management
 set sv_db_saveasdump 0 "write server.db in dump format (loads slower, easier to read/parse)"
index 3e69bd8..bb44e5b 100644 (file)
@@ -4694,8 +4694,6 @@ bounce 1.5
 liquidfriction 4
 velocityjitter 16 16 16
 
-
-
 // rocket guiding start
 // underwater bubbles
 effect rocket_guide
@@ -5125,3 +5123,74 @@ originjitter 1 1 1
 velocityjitter 300 300 300
 velocitymultiplier 0.5
 airfriction 3
+
+
+// weak rifle bullet trail (somewhat like a tracer)
+// used in qcsrc/server/w_common.qc:                           zcurveparticles_from_tracetoss(particleeffectnum("tr_bullet"), self.origin, trace_endpos, self.velocity)
+// used in qcsrc/client/projectile.qc:                 trailparticles(self, particleeffectnum("tr_bullet"), from, to)
+effect tr_rifle_weak
+trailspacing 128
+type spark
+color 0x800000 0xFF8020
+alpha 256 256 2560
+size 1.5 1.5
+stretchfactor 1
+velocitymultiplier 0.7
+effect tr_rifle_weak
+notunderwater
+tex 0 8
+trailspacing 48
+type static
+color 0x202020 0x404040
+size 4 4
+sizeincrease 0.4
+alpha 256 256 256
+airfriction -4
+velocityjitter 4 4 4
+type smoke
+effect tr_rifle_weak
+underwater
+trailspacing 192
+type bubble
+tex 62 62
+color 0x404040 0x808080
+size 2 2
+alpha 256 256 128
+gravity -0.125
+bounce 1.5
+liquidfriction 4
+velocityjitter 16 16 16
+
+// red smoke emiter
+// used nowhere in code
+effect red_smoke
+count 2
+type smoke
+tex 0 8
+color 0xff8866 0x331100
+size 60 120
+sizeincrease 0
+alpha 32 64 32
+gravity -0.007
+originjitter 0 0 0
+velocityjitter 0 0 0
+velocitymultiplier 5
+airfriction -1
+rotate 0 360 -30 30
+
+// pipe smoke emiter
+// used nowhere in code
+effect pipe_smoke
+count 2
+type smoke
+tex 0 8
+color 0x999999 0x555555
+size 5 10
+sizeincrease 35
+alpha 32 64 48
+gravity -0.015
+originjitter 0 0 0
+velocityjitter 0 0 5
+velocitymultiplier 15
+airfriction -1
+rotate 0 360 -180 180
index 453e091..da26208 100644 (file)
@@ -29,7 +29,8 @@
 "impulse 14"                            "porto / hook"
 ""                                      ""
 ""                                      "View"
-"+zoom"                                 "zoom"
+"+zoom"                                 "hold zoom"
+"togglezoom"                            "toggle zoom"
 "+showscores"                           "show scores"
 "screenshot"                            "screen shot"
 ""                                      ""
index 8634fea..b325c9c 100644 (file)
Binary files a/models/weapons/g_crylink.md3 and b/models/weapons/g_crylink.md3 differ
index ae76ba7..6e76885 100644 (file)
Binary files a/models/weapons/g_hlac.md3 and b/models/weapons/g_hlac.md3 differ
index b31e260..d1f168a 100644 (file)
Binary files a/models/weapons/g_laser.md3 and b/models/weapons/g_laser.md3 differ
index 60caa41..898c132 100644 (file)
Binary files a/models/weapons/g_minelayer.md3 and b/models/weapons/g_minelayer.md3 differ
index 5594558..6ecb0aa 100644 (file)
Binary files a/models/weapons/g_nex.md3 and b/models/weapons/g_nex.md3 differ
index f0dce9d..78163a9 100644 (file)
Binary files a/models/weapons/g_porto.md3 and b/models/weapons/g_porto.md3 differ
index af34658..c3b9f3c 100644 (file)
Binary files a/models/weapons/v_crylink.md3 and b/models/weapons/v_crylink.md3 differ
index 3bbc34d..887c2a7 100644 (file)
Binary files a/models/weapons/v_hlac.md3 and b/models/weapons/v_hlac.md3 differ
index 4ca6a13..8b96df0 100644 (file)
Binary files a/models/weapons/v_hookgun.md3 and b/models/weapons/v_hookgun.md3 differ
index 836ad36..dc5e267 100644 (file)
Binary files a/models/weapons/v_laser.md3 and b/models/weapons/v_laser.md3 differ
index 648b0f1..529f02f 100644 (file)
Binary files a/models/weapons/v_minelayer.md3 and b/models/weapons/v_minelayer.md3 differ
index 1d45edb..4cafdd1 100644 (file)
Binary files a/models/weapons/v_nex.md3 and b/models/weapons/v_nex.md3 differ
index 5d06b3c..b72113a 100644 (file)
Binary files a/models/weapons/v_porto.md3 and b/models/weapons/v_porto.md3 differ
index 2d78038..88f0a51 100644 (file)
@@ -156,7 +156,7 @@ float               scoreboard_showaccuracy;
 // float               coop;
 // float               deathmatch;
 
-// float               dmg_take;
+float          dmg_take;
 // float               dmg_save;
 // vector              dmg_origin;
 
index 908e6db..121488d 100644 (file)
@@ -676,7 +676,7 @@ void CSQC_UpdateView(float w, float h)
                // fade out
                myhealth_flash = max(0, myhealth_flash - autocvar_hud_damage_fade_rate * frametime);
                // add new damage
-               myhealth_flash = bound(0, myhealth_flash + max(0, myhealth_prev - myhealth) * autocvar_hud_damage_factor, autocvar_hud_damage_maxalpha);
+               myhealth_flash = bound(0, myhealth_flash + dmg_take * autocvar_hud_damage_factor, autocvar_hud_damage_maxalpha);
 
                float pain_threshold, pain_threshold_lower, pain_threshold_lower_health;
                pain_threshold = autocvar_hud_damage_pain_threshold;
index 2f3ec3b..d489955 100644 (file)
@@ -3134,6 +3134,8 @@ void HUD_Notify (void)
        if(!autocvar_hud_panel_notify && !autocvar__hud_configure)
                return;
 
+       drawfont = hud_bigfont;
+
        active_panel = HUD_PANEL_NOTIFY;
        HUD_Panel_UpdateCvars(notify);
        vector pos, mySize;
@@ -3424,6 +3426,8 @@ void HUD_Notify (void)
                        }
                }
        }
+
+       drawfont = hud_font;
 }
 
 // Timer (#5)
index a2cef76..cede03c 100644 (file)
@@ -274,7 +274,7 @@ void Ent_Projectile()
                        case PROJECTILE_ELECTRO: setmodel(self, "models/ebomb.mdl");self.traileffect = particleeffectnum("TR_NEXUIZPLASMA"); break;
                        case PROJECTILE_ROCKET: setmodel(self, "models/rocket.md3");self.traileffect = particleeffectnum("TR_ROCKET"); self.scale = 2; break;
                        case PROJECTILE_BULLET: setmodel(self, "models/tracer.mdl");self.traileffect = particleeffectnum("tr_bullet"); break;
-                       case PROJECTILE_BULLET_GLOWING: setmodel(self, "models/tracer.mdl");self.traileffect = particleeffectnum("tr_bullet"); break;
+                       case PROJECTILE_BULLET_GLOWING: setmodel(self, "models/tracer.mdl");self.traileffect = particleeffectnum("tr_rifle_weak"); break;
                        case PROJECTILE_BULLET_GLOWING_TRACER: setmodel(self, "models/tracer.mdl");self.traileffect = particleeffectnum("tr_rifle"); break;
                        case PROJECTILE_CRYLINK: setmodel(self, "models/plasmatrail.mdl");self.traileffect = particleeffectnum("TR_CRYLINKPLASMA"); break;
                        case PROJECTILE_CRYLINK_BOUNCING: setmodel(self, "models/plasmatrail.mdl");self.traileffect = particleeffectnum("TR_CRYLINKPLASMA"); break;
index 104c884..439a1b5 100644 (file)
@@ -75,6 +75,7 @@ void GameCommand(string theCommand)
        if(argv(0) == "sync")
        {
                loadAllCvars(main);
+               updateCompression();
                return;
        }
 
index 417cfa6..87f82a4 100644 (file)
@@ -6,7 +6,7 @@ CLASS(XonoticAdvancedDialog) EXTENDS(XonoticDialog)
        ATTRIB(XonoticAdvancedDialog, title, string, "Advanced server settings")
        ATTRIB(XonoticAdvancedDialog, color, vector, SKINCOLOR_DIALOG_ADVANCED)
        ATTRIB(XonoticAdvancedDialog, intendedWidth, float, 0.5)
-       ATTRIB(XonoticAdvancedDialog, rows, float, 12)
+       ATTRIB(XonoticAdvancedDialog, rows, float, 14)
        ATTRIB(XonoticAdvancedDialog, columns, float, 3)
        ATTRIB(XonoticAdvancedDialog, refilterEntity, entity, NULL)
 ENDCLASS(XonoticAdvancedDialog)
@@ -22,34 +22,40 @@ void XonoticAdvancedDialog_fill(entity me)
 {
        entity e;
        me.TR(me);
-               me.TD(me, 1, 1.2, makeXonoticTextLabel(0, "Game settings:"));
+               me.TD(me, 1, 3, makeXonoticTextLabel(0, "Game settings:"));
        me.TR(me);
                me.TDempty(me, 0.2);
-               me.TD(me, 1, 1.2, e = makeXonoticCheckBox(0, "sv_spectate", "Allow spectating"));
+               me.TD(me, 1, 2.8, e = 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.7, e = makeXonoticSlider(0, 15, 0.5, "g_spawnshieldtime"));
+               me.TD(me, 1, 1.6, e = 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.7, e = makeXonoticSlider(0.5, 2.0, 0.1, "slowmo"));
+               me.TD(me, 1, 1.6, e = makeXonoticSlider(0.5, 2.0, 0.1, "slowmo"));
        me.TR(me);
        me.TR(me);
-               me.TD(me, 1, 1.2, makeXonoticTextLabel(0, "Teamplay settings:"));
+               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.7, e = makeXonoticSlider(0, 1.0, 0.05, "g_friendlyfire"));
+               me.TD(me, 1, 1.6, e = 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.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "Friendly fire penalty:"));
-               me.TD(me, 1, 1.7, e = makeXonoticSlider(0, 1.0, 0.05, "g_mirrordamage"));
+               me.TD(me, 1, 1.6, e = 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.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 1.2, e = makeXonoticTextLabel(0, "Teams:"));
-               me.TD(me, 1, 1.7, e = makeXonoticTextSlider("g_tdm_teams_override g_domination_teams_override g_keyhunt_teams_override"));
+               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");
                        e.addValue(e, "3 teams", "3");
index 5868961..9365544 100644 (file)
@@ -46,7 +46,7 @@ void XonoticPlayerSettingsTab_fill(entity me)
        me.TR(me);
                me.TD(me, 1, 3.0, box = makeXonoticInputBox(1, "_cl_name"));
                        box.forbiddenCharacters = "\r\n\\\"$"; // don't care, isn't getting saved
-                       box.maxLength = -63; // negativ means encoded length in bytes
+                       box.maxLength = -127; // negative means encoded length in bytes
                        label.textEntity = box;
        me.TR(me);
                me.TD(me, 5, 1, e = makeXonoticColorpicker(box));
@@ -141,7 +141,7 @@ void XonoticPlayerSettingsTab_fill(entity me)
                me.TDempty(me, 0.3);
                me.TD(me, 1, 0.7, e = makeXonoticCheckBox(0, "crosshair_color_per_weapon", "Per weapon"));
        me.TR(me);
-               me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "crosshair_dot", "Enable centered dot"));
+               me.TD(me, 1, 3, e = makeXonoticCheckBox(0, "crosshair_dot", "Enable center dot"));
        me.TR(me);
                me.TDempty(me, 0.2);
                me.TD(me, 1, 0.5, e = makeXonoticTextLabel(0, "Size:"));
index 19b232f..cd108f0 100644 (file)
@@ -30,34 +30,6 @@ float someShadowCvarIsEnabled(entity box)
        return FALSE;
 }
 
-float updateCompression()
-{
-       float fh;
-       float have_dds, have_jpg, have_tga;
-       if((have_dds = ((fh = fopen("dds/particles/particlefont.dds", FILE_READ)) >= 0)))
-               fclose(fh);
-       if((have_jpg = ((fh = fopen("particles/particlefont.jpg", FILE_READ)) >= 0)))
-               fclose(fh);
-       if((have_tga = ((fh = fopen("particles/particlefont.tga", FILE_READ)) >= 0)))
-               fclose(fh);
-       if(have_dds && (have_jpg || have_tga))
-       {
-               cvar_set("gl_texturecompression", "0");
-               return 1;
-       }
-       else if(have_dds)
-       {
-               cvar_set("gl_texturecompression", "0");
-               cvar_set("r_texture_dds_load", "1");
-               return 0;
-       }
-       else
-       {
-               cvar_set("gl_texturecompression", cvar_string("r_texture_dds_load"));
-               return 2;
-       }
-}
-
 void XonoticEffectsSettingsTab_fill(entity me)
 {
        entity e, s;
index 3117c65..87273b2 100644 (file)
@@ -137,6 +137,7 @@ void XonoticKeyBinder_keyGrabbed(entity me, float key, float ascii)
                }
        }
        localcmd("\nbind \"", keynumtostring(key), "\" \"", func, "\"\n");
+       localcmd("-zoom\n"); // to make sure we aren't in togglezoom'd state
 }
 void XonoticKeyBinder_editUserbind(entity me, string theName, string theCommandPress, string theCommandRelease)
 {
@@ -197,7 +198,7 @@ void KeyBinder_Bind_Clear(entity btn, entity me)
                        //localcmd("\nunbind \"", keynumtostring(k), "\"\n");
                        localcmd("\nbind \"", keynumtostring(k), "\" \"", KEY_NOT_BOUND_CMD, "\"\n");
        }
-
+       localcmd("-zoom\n"); // to make sure we aren't in togglezoom'd state
 }
 void XonoticKeyBinder_clickListBoxItem(entity me, float i, vector where)
 {
index 1cb4cf5..c968c60 100644 (file)
@@ -454,3 +454,34 @@ string HUD_Panel_GetSettingName(float theSetting)
                default: return "";
        }
 }
+
+float updateCompression()
+{
+       float fh;
+       float have_dds, have_jpg, have_tga;
+       if((have_dds = ((fh = fopen("dds/particles/particlefont.dds", FILE_READ)) >= 0)))
+               fclose(fh);
+       if((have_jpg = ((fh = fopen("particles/particlefont.jpg", FILE_READ)) >= 0)))
+               fclose(fh);
+       if((have_tga = ((fh = fopen("particles/particlefont.tga", FILE_READ)) >= 0)))
+               fclose(fh);
+       if(have_dds && (have_jpg || have_tga))
+       {
+               // both? Let's only use good quality precompressed files
+               cvar_set("gl_texturecompression", "0");
+               return 1;
+       }
+       else if(have_dds)
+       {
+               // DDS only? We probably always want texture compression
+               cvar_set("gl_texturecompression", "1");
+               cvar_set("r_texture_dds_load", "1");
+               return 0;
+       }
+       else
+       {
+               // TGA only? Allow runtime compression
+               cvar_set("gl_texturecompression", cvar_string("r_texture_dds_load"));
+               return 2;
+       }
+}
index c5beab2..48873ec 100644 (file)
@@ -722,6 +722,7 @@ float autocvar_g_freezetag_revive_extra_size;
 float autocvar_g_freezetag_revive_time;
 float autocvar_g_freezetag_warmup;
 #define autocvar_g_friendlyfire cvar("g_friendlyfire")
+#define autocvar_g_friendlyfire_virtual cvar("g_friendlyfire_virtual")
 float autocvar_g_full_getstatus_responses;
 float autocvar_g_fullbrightitems;
 float autocvar_g_fullbrightplayers;
@@ -789,7 +790,9 @@ float autocvar_g_midair_shieldtime;
 float autocvar_g_minstagib_ammo_drop;
 float autocvar_g_minstagib_extralives;
 float autocvar_g_minstagib_speed_highspeed;
+float autocvar_g_mirrordamage;
 #define autocvar_g_mirrordamage cvar("g_mirrordamage")
+#define autocvar_g_mirrordamage_virtual cvar("g_mirrordamage_virtual")
 float autocvar_g_monster_zombie_attack_run_damage;
 float autocvar_g_monster_zombie_attack_run_delay;
 float autocvar_g_monster_zombie_attack_run_force;
index c1785a8..d8287df 100644 (file)
@@ -21,7 +21,8 @@ void havocbot_ai()
                }
                else
                {
-                       self.havocbot_role();
+                       if not(self.jumppadcount)
+                               self.havocbot_role();
                }
 
                // TODO: tracewalk() should take care of this job (better path finding under water)
@@ -452,14 +453,7 @@ void havocbot_movetogoal()
        // Handling of jump pads
        if(self.jumppadcount)
        {
-               if(self.flags & FL_ONGROUND)
-               {
-                       self.jumppadcount = FALSE;
-                       if(self.aistatus & AI_STATUS_OUT_JUMPPAD)
-                               self.aistatus &~= AI_STATUS_OUT_JUMPPAD;
-               }
-
-               // If got stuck on the jump pad try to reach the farther visible item
+               // If got stuck on the jump pad try to reach the farthest visible item
                if(self.aistatus & AI_STATUS_OUT_JUMPPAD)
                {
                        if(fabs(self.velocity_z)<50)
@@ -507,11 +501,20 @@ void havocbot_movetogoal()
                                local float threshold;
                                threshold = maxspeed * 0.2;
                                if(fabs(self.velocity_x) < threshold  &&  fabs(self.velocity_y) < threshold)
+                               {
+                                       dprint("Warning: ", self.netname, " got stuck on a jumppad, trying to get out of it now\n");
                                        self.aistatus |= AI_STATUS_OUT_JUMPPAD;
+                               }
                                return;
                        }
+
+                       // Don't chase players while using a jump pad
+                       if(self.goalcurrent.classname=="player" || self.goalstack01.classname=="player")
+                               return;
                }
        }
+       else if(self.aistatus & AI_STATUS_OUT_JUMPPAD)
+               self.aistatus &~= AI_STATUS_OUT_JUMPPAD;
 
        // If there is a trigger_hurt right below try to use the jetpack or make a rocketjump
        if(skill>6)
@@ -726,7 +729,7 @@ void havocbot_movetogoal()
                        // (only when the bot is on the ground or jumping intentionally)
                        self.aistatus &~= AI_STATUS_DANGER_AHEAD;
 
-                       if(trace_fraction == 1)
+                       if(trace_fraction == 1 && self.jumppadcount == 0)
                        if(self.flags & FL_ONGROUND || self.aistatus & AI_STATUS_RUNNING || self.BUTTON_JUMP == TRUE)
                        {
                                // Look downwards
index cfd0503..514c364 100644 (file)
@@ -315,7 +315,6 @@ void havocbot_chooserole_ka()
 void havocbot_chooserole()
 {
        dprint("choosing a role...\n");
-       navigation_clearroute();
        self.bot_strategytime = 0;
        if (g_ctf)
                havocbot_chooserole_ctf();
index f3e5c26..9e1a92a 100644 (file)
@@ -897,6 +897,7 @@ void navigation_goalrating_start()
        self.navigation_jetpack_goal = world;
        navigation_bestrating = -1;
        self.navigation_hasgoals = FALSE;
+       navigation_clearroute();
        navigation_bestgoal = world;
        navigation_markroutes(world);
 };
index adaf36f..9203d87 100644 (file)
@@ -261,7 +261,7 @@ void SV_ParseClientCommand(string s) {
                if not(self.flags & FL_CLIENT)
                        return;
 
-               if((inWarmupStage && 0 >= g_warmup_limit) // with unlimited warmup players have to be able to restart
+               if((inWarmupStage)
                   || autocvar_sv_ready_restart || g_race_qualifying == 2)
                {
                        if(!readyrestart_happened || autocvar_sv_ready_restart_repeatable)
index 6ab2900..2ad648e 100644 (file)
@@ -102,7 +102,7 @@ void UpdateFrags(entity player, float f)
 
 // NOTE: f=0 means still count as a (positive) kill, but count no frags for it
 void W_SwitchWeapon_Force(entity e, float w);
-void GiveFrags (entity attacker, entity targ, float f)
+void GiveFrags (entity attacker, entity targ, float f, float deathtype)
 {
        float w;
 
@@ -139,19 +139,36 @@ void GiveFrags (entity attacker, entity targ, float f)
        if(targ != attacker) // not for suicides
        if(g_weaponarena_random)
        {
-               // after a frag, choose another random weapon set
-               if(inWarmupStage)
-                       w = warmup_start_weapons;
-               else
-                       w = start_weapons;
+               // 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 || !(attacker.weapons & W_WeaponBit(culprit)))
+                       culprit = attacker.weapon;
 
-               attacker.weapons = randombits(w - (w & W_WeaponBit(attacker.weapon)), g_weaponarena_random, TRUE);
-               if(attacker.weapons < 0)
+               if(g_weaponarena_random_with_laser && culprit == WEPBIT_LASER)
                {
-                       // error from randombits: no weapon available
-                       // this means we can just give ALL weapons
-                       attacker.weapons = w;
+                       // no exchange
+               }
+               else
+               {
+                       if(inWarmupStage)
+                               w = warmup_start_weapons;
+                       else
+                               w = start_weapons;
+
+                       // all others (including the culprit): remove
+                       w &~= attacker.weapons;
+
+                       // among the remaining ones, choose one by random
+                       w = randombits(w, 1, FALSE);
+                       if(w)
+                       {
+                               attacker.weapons |= w;
+                               attacker.weapons &~= W_WeaponBit(culprit);
+                       }
                }
+
+               // after a frag, choose another random weapon set
                if not(attacker.weapons & W_WeaponBit(attacker.weapon))
                        W_SwitchWeapon_Force(attacker, w_getbestweapon(attacker));
        }
@@ -301,7 +318,7 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
                        if(deathtype != DEATH_TEAMCHANGE && deathtype != DEATH_QUIET)
                        {
                                LogDeath("suicide", deathtype, targ, targ);
-                               GiveFrags(attacker, targ, -1);
+                               GiveFrags(attacker, targ, -1, deathtype);
                        }
 
                        if (targ.killcount > 2)
@@ -325,7 +342,7 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
                                else
                                        type = KILL_TEAM_BLUE;
 
-                               GiveFrags(attacker, targ, -1);
+                               GiveFrags(attacker, targ, -1, deathtype);
 
                                Send_CSQC_Centerprint(attacker, s, "", type, MSG_KILL);
 
@@ -379,10 +396,10 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
                                {
                                        UpdateFrags(attacker, ctf_score_value("score_kill"));
                                        PlayerScore_Add(attacker, SP_CTF_FCKILLS, 1);
-                                       GiveFrags(attacker, targ, 0); // for logging
+                                       GiveFrags(attacker, targ, 0, deathtype); // for logging
                                }
                                else
-                                       GiveFrags(attacker, targ, 1);
+                                       GiveFrags(attacker, targ, 1, deathtype);
 
                                if (targ.killcount > 2) {
                                        Send_KillNotification(s, ftos(targ.killcount), a, KILL_END_SPREE, MSG_SPREE);
@@ -441,7 +458,7 @@ void Obituary (entity attacker, entity inflictor, entity targ, float deathtype)
                        if(strstrofs(msg, "%", 0) < 0)
                                msg = strcat("%s ", msg);
 
-                       GiveFrags(targ, targ, -1);
+                       GiveFrags(targ, targ, -1, deathtype);
                        if(PlayerScore_Add(targ, SP_SCORE, 0) == -5) {
                                AnnounceTo(targ, "botlike");
                        }
@@ -565,6 +582,28 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                                                        else
                                                                damage = autocvar_g_friendlyfire * damage;
                                                        // mirrordamage will be used LATER
+
+                                                       if(autocvar_g_mirrordamage_virtual)
+                                                       {
+                                                               vector v;
+                                                               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;
+                                                               mirrordamage = 0;
+                                                               mirrorforce = 0;
+                                                       }
+
+                                                       if(autocvar_g_friendlyfire_virtual)
+                                                       {
+                                                               vector v;
+                                                               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;
+                                                               damage = 0;
+                                                               force = '0 0 0';
+                                                       }
                                                }
                                                else
                                                        damage = 0;
@@ -606,12 +645,11 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
                        if (DEATH_ISWEAPON(deathtype, WEP_LASER))
                        {
                                damage = 0;
+                               mirrordamage = 0;
                                if (targ != attacker)
                                {
                                        if ((targ.health >= 1) && (targ.classname == "player"))
                                                centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, "Secondary fire inflicts no damage!"));
-                                       damage = 0;
-                                       mirrordamage = 0;
                                        force = '0 0 0';
                                        // keep mirrorforce
                                        attacker = targ;
@@ -841,17 +879,18 @@ void Damage (entity targ, entity inflictor, entity attacker, float damage, float
        {
                attacker = attacker_save;
                if(g_minstagib)
-                       if(mirrordamage > 0)
+               if(mirrordamage > 0)
+               {
+                       // just lose extra LIVES, don't kill the player for mirror damage
+                       if(attacker.armorvalue > 0)
                        {
-                               // just lose extra LIVES, don't kill the player for mirror damage
-                               if(attacker.armorvalue > 0)
-                               {
-                                       attacker.armorvalue = attacker.armorvalue - 1;
-                                       centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, "^3Remaining extra lives: ",ftos(attacker.armorvalue)));
-                                       attacker.hitsound += 1;
-                               }
-                               mirrordamage = 0;
+                               attacker.armorvalue = attacker.armorvalue - 1;
+                               centerprint(attacker, strcat(DAMAGE_CENTERPRINT_SPACER, "^3Remaining extra lives: ",ftos(attacker.armorvalue)));
+                               attacker.hitsound += 1;
                        }
+                       mirrordamage = 0;
+               }
+
                force = normalize(attacker.origin + attacker.view_ofs - hitloc) * mirrorforce;
                Damage(attacker, inflictor, attacker, mirrordamage, DEATH_MIRRORDAMAGE, attacker.origin, force);
        }
index 47f3a5a..8ba71e4 100644 (file)
@@ -698,6 +698,33 @@ void LODmodel_attach()
                        SetCustomizer(self, LOD_customize, LOD_uncustomize);
 }
 
+void ApplyMinMaxScaleAngles(entity e)
+{
+       if(e.angles_x != 0 || e.angles_z != 0 || self.avelocity_x != 0 || self.avelocity_z != 0) // "weird" rotation
+       {
+               e.maxs = '1 1 1' * vlen(
+                       '1 0 0' * max(-e.mins_x, e.maxs_x) +
+                       '0 1 0' * max(-e.mins_y, e.maxs_y) +
+                       '0 0 1' * max(-e.mins_z, e.maxs_z)
+               );
+               e.mins = -e.maxs;
+       }
+       else if(e.angles_y != 0 || self.avelocity_y != 0) // yaw only is a bit better
+       {
+               e.maxs_x = vlen(
+                       '1 0 0' * max(-e.mins_x, e.maxs_x) +
+                       '0 1 0' * max(-e.mins_y, e.maxs_y)
+               );
+               e.maxs_y = e.maxs_x;
+               e.mins_x = -e.maxs_x;
+               e.mins_y = -e.maxs_x;
+       }
+       if(e.scale)
+               setsize(e, e.mins * e.scale, e.maxs * e.scale);
+       else
+               setsize(e, e.mins, e.maxs);
+}
+
 void SetBrushEntityModel()
 {
        if(self.model != "")
@@ -707,10 +734,7 @@ void SetBrushEntityModel()
                InitializeEntity(self, LODmodel_attach, INITPRIO_FINDTARGET);
        }
        setorigin(self, self.origin);
-       if(self.scale)
-               setsize(self, self.mins * self.scale, self.maxs * self.scale);
-       else
-               setsize(self, self.mins, self.maxs);
+       ApplyMinMaxScaleAngles(self);
 }
 
 void SetBrushEntityModelNoLOD()
@@ -721,10 +745,7 @@ void SetBrushEntityModelNoLOD()
                setmodel(self, self.model); // no precision needed
        }
        setorigin(self, self.origin);
-       if(self.scale)
-               setsize(self, self.mins * self.scale, self.maxs * self.scale);
-       else
-               setsize(self, self.mins, self.maxs);
+       ApplyMinMaxScaleAngles(self);
 }
 
 /*
index a5192b1..e2a123a 100644 (file)
@@ -325,6 +325,7 @@ void cvar_changes_init()
                BADCVAR("g_ctf");
                BADCVAR("g_dm");
                BADCVAR("g_domination");
+               BADCVAR("g_freezetag");
                BADCVAR("g_keyhunt");
                BADCVAR("g_keyhunt_teams");
                BADCVAR("g_onslaught");
@@ -452,6 +453,8 @@ void cvar_changes_init()
                BADCVAR("sv_vote_master_password");
                BADCVAR("sv_vote_simple_majority_factor");
                BADCVAR("timelimit_override");
+               BADCVAR("g_warmup");
+               BADPREFIX("g_warmup_");
 
                if(autocvar_g_minstagib)
                {
index 113e9f4..a40982c 100644 (file)
@@ -915,8 +915,15 @@ void readplayerstartcvars()
 
        g_weaponarena = 0;
        s = cvar_string("g_weaponarena");
-       if (s == "0")
+       if (s == "0" || s == "")
        {
+               if(g_lms || g_ca)
+                       s = "most";
+       }
+
+       if (s == "off")
+       {
+               // forcibly turn off weaponarena
        }
        else if (s == "all")
        {
index 36048e8..1e72b76 100644 (file)
@@ -127,9 +127,9 @@ vector trigger_push_calculatevelocity(vector org, entity tgt, float ht)
 
 void trigger_push_touch()
 {
-       if (self.active == ACTIVE_NOT) 
-               return;         
-               
+       if (self.active == ACTIVE_NOT)
+               return;
+
        // FIXME: add a .float for whether an entity should be tossed by jumppads
        if (!other.iscreature)
        if (other.classname != "corpse")
@@ -171,7 +171,7 @@ void trigger_push_touch()
                }
                local float ct;
                ct = clienttype(other);
-               if( ct == CLIENTTYPE_REAL)
+               if( ct == CLIENTTYPE_REAL || ct == CLIENTTYPE_BOT)
                {
                        local float i;
                        local float found;
@@ -185,11 +185,14 @@ void trigger_push_touch()
                                other.jumppadcount = other.jumppadcount + 1;
                        }
 
-                       if(self.message)
-                               centerprint(other, self.message);
+                       if(ct == CLIENTTYPE_REAL)
+                       {
+                               if(self.message)
+                                       centerprint(other, self.message);
+                       }
+                       else
+                               other.lastteleporttime = time;
                }
-               else if(ct == CLIENTTYPE_BOT)
-                       other.lastteleporttime = time;
                else
                        other.jumppadcount = TRUE;
 
@@ -289,8 +292,8 @@ void spawnfunc_trigger_push()
        SetMovedir ();
 
        EXACTTRIGGER_INIT;
-       
-       self.active = ACTIVE_ACTIVE;    
+
+       self.active = ACTIVE_ACTIVE;
        self.use = trigger_push_use;
        self.touch = trigger_push_touch;
 
index 3089ab6..f3afdf5 100644 (file)
@@ -536,6 +536,7 @@ void spawnfunc_func_pendulum()
 
        self.blocked = generic_plat_blocked;
 
+       self.avelocity_z = 0.0000001;
        if not(InitMovingBrushTrigger())
                return;
 
@@ -1433,8 +1434,10 @@ void spawnfunc_func_door_rotating()
        self.angles = '0 0 0';
 
        self.max_health = self.health;
+       self.avelocity = self.movedir;
        if not(InitMovingBrushTrigger())
                return;
+       self.velocity = '0 0 0';
        //self.effects |= EF_LOWPRECISION;
        self.classname = "door_rotating";
 
index 49e2773..24f4340 100644 (file)
@@ -391,6 +391,8 @@ void fireBallisticBullet(vector start, vector dir, float spread, float pSpeed, f
 
                if(tracereffects & EF_RED)
                        eff = particleeffectnum("tr_rifle");
+               else if(tracereffects & EF_BLUE)
+                       eff = particleeffectnum("tr_rifle_weak");
                else
                        eff = particleeffectnum("tr_bullet");
 
index 725fa43..a85fbab 100644 (file)
--- a/quake.rc
+++ b/quake.rc
@@ -8,4 +8,4 @@ stuffcmds
 //startdemos demos/demo1 demos/demo2 demos/demo3
 //startdemos
 //play announcer/male/welcome.ogg
-crypto_keygen 0 http://rm.endoftheinternet.org/~xonotic/keygen/?ca=0&key=
+crypto_keygen 0 http://ca.xonotic.org/?ca=0&key=
diff --git a/textures/hlac_glass.tga b/textures/hlac_glass.tga
new file mode 100644 (file)
index 0000000..e0ed0a7
Binary files /dev/null and b/textures/hlac_glass.tga differ
diff --git a/textures/hlac_plasma.tga b/textures/hlac_plasma.tga
new file mode 100644 (file)
index 0000000..5603b16
Binary files /dev/null and b/textures/hlac_plasma.tga differ