// }}}
// {{{ 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
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)"
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"
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}"
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
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_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 0.55 "an improved version of gl_polyblend, draw an image instead when hurt"
+seta hud_damage_gentle_alpha_multiplier 0.10 "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"
// safe font defaults
r_font_hinting 1
r_font_disable_freetype 0
-r_font_size_snapping 2
+r_font_size_snapping 4
// database management
set sv_db_saveasdump 0 "write server.db in dump format (loads slower, easier to read/parse)"
liquidfriction 4
velocityjitter 16 16 16
-
-
// rocket guiding start
// underwater bubbles
effect rocket_guide
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
"impulse 14" "porto / hook"
"" ""
"" "View"
-"+zoom" "zoom"
+"+zoom" "hold zoom"
+"togglezoom" "toggle zoom"
"+showscores" "show scores"
"screenshot" "screen shot"
"" ""
// float coop;
// float deathmatch;
-// float dmg_take;
+float dmg_take;
// float dmg_save;
// vector dmg_origin;
#endif
float i;
- CSQC_CheckEngine();
binddb = db_create();
tempdb = db_create();
ClientProgsDB = db_load("client.db");
compressShortVector_init();
- drawfont = 0;
+ drawfont = FONT_USER+1;
menu_visible = FALSE;
menu_show = menu_show_error;
menu_action = menu_sub_null;
serverflags = ReadByte();
+ cr_maxbullets = ReadByte();
+
if(!postinit)
PostInit();
}
Net_WeaponComplain();
bHandled = true;
break;
- case TE_CSQC_CR_MAXBULLETS:
- cr_maxbullets = ReadByte();
- bHandled = true;
- break;
default:
// No special logic for this temporary entity; return 0 so the engine can handle it
bHandled = false;
// 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;
{
ts = centerprint_messages[i];
drawfontscale = sz * '1 1 0';
- drawfont = hud_bigfont;
pos_x = (vid_conwidth - stringwidth(ts, TRUE, centerprint_fontsize)) * 0.5;
if (ts != "")
{
// half height for empty lines looks better
pos_y = pos_y + sz * centerprint_fontsize_y * 0.5;
drawfontscale = '1 1 0';
- drawfont = hud_font;
}
}
drawstring(wpnpos, getcommandkey(ftos(weapid), strcat("impulse ", ftos(weapid))), '1 1 0' * 0.5 * wpnsize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
// draw ammo status bar
- if(autocvar_hud_panel_weapons_ammo && weapid != WEP_TUBA && weapid != WEP_LASER && weapid != WEP_PORTO)
+ if(autocvar_hud_panel_weapons_ammo && self.weapon != WEP_TUBA && self.weapon != WEP_LASER && self.weapon != WEP_PORTO)
{
a = 0;
- type = GetAmmoTypeForWep(weapid);
+ type = GetAmmoTypeForWep(self.weapon);
if(type != -1)
a = getstati(GetAmmoStat(type)); // how much ammo do we have?
ammo_size_y = newSize;
}
- drawfont = hud_bigfont;
float i, stat_items, currently_selected;
if (autocvar_hud_panel_ammo_onlycurrent)
{
column = column + 1;
}
}
- drawfont = hud_font;
}
void DrawNumIcon(vector myPos, vector mySize, float x, string icon, float vertical, float icon_right_align, vector color, float alpha)
rightexact = strength_time;
}
- drawfont = hud_bigfont;
float baralign = autocvar_hud_panel_powerups_baralign;
float iconalign = autocvar_hud_panel_powerups_iconalign;
}
}
}
- drawfont = hud_font;
}
// Health/armor (#3)
vector barsize;
vector picpos, numpos;
- drawfont = hud_bigfont;
float baralign = autocvar_hud_panel_healtharmor_baralign;
float iconalign = autocvar_hud_panel_healtharmor_iconalign;
}
}
}
- drawfont = hud_font;
}
// Notification area (#4)
timer = seconds_tostring(timeleft);
}
- drawfont = hud_bigfont;
drawstring_aspect(pos, timer, mySize, timer_color, panel_fg_alpha, DRAWFLAG_NORMAL);
- drawfont = hud_font;
}
// Radar (#6)
// race record display
if (distribution <= 0)
HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawfont = hud_bigfont;
drawstring_aspect(pos, timer, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawfont = hud_font;
} else if (!teamplay) { // non-teamgames
if ((spectatee_status == -1 && !autocvar__hud_configure) || autocvar_hud_panel_score_rankings)
{
distribution_str = strcat("+", distribution_str);
HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
}
- drawfont = hud_bigfont;
drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize_x + eY * mySize_y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
- drawfont = hud_font;
drawstring_aspect(pos + eX * 0.75 * mySize_x, distribution_str, eX * 0.25 * mySize_x + eY * (1/3) * mySize_y, distribution_color, panel_fg_alpha, DRAWFLAG_NORMAL);
} else { // teamgames
float max_fragcount;
else if(tm.team == myteam) {
if (max_fragcount == score)
HUD_Panel_DrawHighlight(pos, eX * 0.75 * mySize_x + eY * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
- drawfont = hud_bigfont;
drawstring_aspect(pos, ftos(score), eX * 0.75 * mySize_x + eY * mySize_y, GetTeamRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
- drawfont = hud_font;
} else {
if (max_fragcount == score)
HUD_Panel_DrawHighlight(pos + eX * 0.75 * mySize_x + eY * (1/3) * rows * mySize_y, score_size, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
}
mySize = newSize;
- drawfont = hud_bigfont;
float a, t;
string s, forcetime;
}
}
}
-
- drawfont = hud_font;
}
// Vote window (#9)
redalive = getstati(STAT_REDALIVE);
bluealive = getstati(STAT_BLUEALIVE);
- drawfont = hud_bigfont;
vector redpos, bluepos;
if(mySize_x > mySize_y)
{
drawpic_aspect_skin(bluepos, "player_blue.tga", eX * mySize_x + eY * 0.3 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
drawstring_aspect(bluepos + eY * 0.3 * mySize_y, ftos(bluealive), eX * mySize_x + eY * 0.2 * mySize_y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
}
- drawfont = hud_font;
}
// CTF HUD modicon section
if not((scores_flags[ps_primary] & SFL_TIME) && !teamplay) // race/cts record display on HUD
return; // no records in the actual race
- drawfont = hud_bigfont;
-
// clientside personal record
string rr;
if(gametype == GAME_CTS)
strunzone(race_status_name_prev);
race_status_name_prev = string_null;
}
- drawfont = hud_font;
}
void DrawDomItem(vector myPos, vector mySize, float aspect_ratio, float layout, float i)
vector color;
color = HUD_Get_Num_Color (prevfps, 100);
- drawfont = hud_bigfont;
drawstring_aspect(pos, strcat("FPS: ", ftos_decimals(prevfps, autocvar_hud_panel_engineinfo_framecounter_decimals)), mySize, color, panel_fg_alpha, DRAWFLAG_NORMAL);
- drawfont = hud_font;
}
// Info messages panel (#14)
drawfill(eY * i * hud_configure_realGridSize_y, eY + eX * vid_conwidth, '0.5 0.5 0.5', autocvar_hud_configure_grid_alpha, DRAWFLAG_NORMAL);
}
+ current_player = (spectatee_status > 0) ? spectatee_status : player_localentnum;
+
// draw the dock
if(autocvar_hud_dock != "" && autocvar_hud_dock != "0")
{
vector color;
float hud_dock_color_team = autocvar_hud_dock_color_team;
if((teamplay) && hud_dock_color_team) {
- f = stof(getplayerkey(player_localentnum - 1, "colors"));
+ f = stof(getplayerkey(current_player - 1, "colors"));
color = colormapPaletteColor(mod(f, 16), 1) * hud_dock_color_team;
}
else if(autocvar_hud_configure_teamcolorforced && autocvar__hud_configure && hud_dock_color_team) {
{
string hud_dock_color = autocvar_hud_dock_color;
if(hud_dock_color == "shirt") {
- f = stof(getplayerkey(player_localentnum - 1, "colors"));
+ f = stof(getplayerkey(current_player - 1, "colors"));
color = colormapPaletteColor(floor(f / 16), 0);
}
else if(hud_dock_color == "pants") {
- f = stof(getplayerkey(player_localentnum - 1, "colors"));
+ f = stof(getplayerkey(current_player - 1, "colors"));
color = colormapPaletteColor(mod(f, 16), 1);
}
else
var float panel_bg_padding;
var string panel_bg_padding_str;
+float current_player;
+
// Because calling lots of functions in QC apparently cuts fps in half on many machines:
// ----------------------
// MACRO HELL STARTS HERE
// Get value for panel_bg_color: if "" fetch default, else use panel_bg_color. Convert pants, shirt or teamcolor into a vector.
#define HUD_Panel_GetColor()\
if((teamplay) && panel_bg_color_team) {\
- panel_bg_color = colormapPaletteColor(mod(stof(getplayerkey(player_localentnum - 1, "colors")), 16), 1) * panel_bg_color_team;\
+ panel_bg_color = colormapPaletteColor(mod(stof(getplayerkey(current_player - 1, "colors")), 16), 1) * panel_bg_color_team;\
} else if (autocvar_hud_configure_teamcolorforced && autocvar__hud_configure && panel_bg_color_team) {\
panel_bg_color = '1 0 0' * panel_bg_color_team;\
} else {\
panel_bg_color = autocvar_hud_panel_bg_color;\
} else {\
if(panel_bg_color_str == "shirt") {\
- panel_bg_color = colormapPaletteColor(floor(stof(getplayerkey(player_localentnum - 1, "colors")) / 16), 0);\
+ panel_bg_color = colormapPaletteColor(floor(stof(getplayerkey(current_player - 1, "colors")) / 16), 0);\
} else if(panel_bg_color_str == "pants") {\
- panel_bg_color = colormapPaletteColor(mod(stof(getplayerkey(player_localentnum - 1, "colors")), 16), 1);\
+ panel_bg_color = colormapPaletteColor(mod(stof(getplayerkey(current_player - 1, "colors")), 16), 1);\
} else {\
panel_bg_color = stov(panel_bg_color_str);\
}\
string hud_title[MAX_HUD_FIELDS + 1];
float hud_num_fields;
-float hud_font;
-float hud_bigfont;
-
string scores_label[MAX_SCORE];
float scores_flags[MAX_SCORE];
string teamscores_label[MAX_SCORE];
img_size_y = isize;
img_size_x = isize / 0.75; // 4:3 x can be stretched easily, height is defined in isize
- drawfont = hud_font;
pos_y = pos_y + img_size_y;
label = MapVote_FormatMapItem(id, map, count, tsize, hud_fontsize);
rgb = MapVote_RGB(id);
- drawfont = hud_font;
pos_y = pos_y + hud_fontsize_y;
label = MapVote_FormatMapItem(id, "Don't care", count, tsize, hud_fontsize);
if(i >= 0 || ymax < (vid_conheight*0.5))
ymax = vid_conheight - ymin;
- drawfont = hud_bigfont;
hud_fontsize = HUD_GetFontsize("hud_fontsize");
pos_y = ymin;
pos_y += 22;
pos_x = xmin;
- drawfont = hud_font;
-
// base for multi-column stuff...
ymin = pos_y;
if(mv_abstain)
return tm;
}
-void CSQC_CheckEngine()
-{
- hud_font = FONT_USER+1;
- hud_bigfont = FONT_USER+2;
-}
-
vector HUD_GetFontsize(string cvarname)
{
vector v;
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;
hud_num_fields = 0;
- drawfont = hud_font;
hud_fontsize = HUD_GetFontsize("hud_fontsize");
for(i = 0; i < argc - 1; ++i)
drawfill(pos + '0 1 0' * weapon_height + '0 1 0' * height * i, '1 0 0' * sbwidth + '0 1 0' * fontsize, '1 1 1', scoreboard_highlight_alpha, DRAWFLAG_NORMAL);
}
- drawfont = hud_bigfont;
average_accuracy = 0;
float weapons_with_stats;
weapons_with_stats = 0;
pos_y += height;
}
}
- drawfont = hud_font;
if(weapons_with_stats)
average_accuracy = floor(average_accuracy / weapons_with_stats);
pos_z = 0;
// Heading
- drawfont = hud_bigfont;
drawstring(pos, "Scoreboard", '24 24 0', '1 1 1', scoreboard_alpha_fg, DRAWFLAG_NORMAL);
centerprint_start_x = vid_conwidth - 0.5 * (pos_x + stringwidth("Scoreboard", FALSE, '24 24 0'));
pos_y += 24;
- drawfont = hud_font;
-
// Draw the scoreboard
vector bg_size = drawgetimagesize("gfx/scoreboard/scoreboard_bg") * autocvar_scoreboard_bg_scale;
if(argv(0) == "sync")
{
loadAllCvars(main);
+ updateCompression();
return;
}
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)
{
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");
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));
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:"));
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;
}
}
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)
{
//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)
{
METHOD(XonoticPicmipSlider, configureXonoticPicmipSlider, void(entity))
METHOD(XonoticPicmipSlider, draw, void(entity))
METHOD(XonoticPicmipSlider, autofix, void(entity))
+ ATTRIB(XonoticPicmipSlider, have_s3tc, float, 0)
ENDCLASS(XonoticPicmipSlider)
entity makeXonoticPicmipSlider(); // note: you still need to call addValue and configureXonoticTextSliderValues!
#endif
{
me.configureXonoticTextSlider(me, "gl_picmip");
me.autofix(me);
+ me.have_s3tc = GL_Have_TextureCompression();
}
-float texmemsize()
+float texmemsize(float s3tc)
{
return
(
2500 * pow(0.5, max(0, cvar("gl_picmip") + cvar("gl_picmip_other")))
+ 1500 * pow(0.5, max(0, cvar("gl_picmip") + cvar("gl_picmip_world")))
- ) * ((cvar("r_texture_dds_load") || cvar("gl_texturecompression")) ? 0.4 : 1.0); // TC: normalmaps 50%, other 25%, few incompressible, guessing 40% as conservative average
+ ) * (s3tc && ((cvar("r_texture_dds_load") || cvar("gl_texturecompression")) ? 0.4 : 1.0)); // TC: normalmaps 50%, other 25%, few incompressible, guessing 40% as conservative average
}
void XonoticPicmipSlider_autofix(entity me)
{
max_soft = cvar("sys_memsize_physical");
if(max_hard > 0)
{
- while(me.value > 0 && texmemsize() > max_hard)
+ while(me.value > 0 && texmemsize(me.have_s3tc) > max_hard)
me.setValue(me, me.value - 1);
}
// TODO also check the soft limit!
+float GL_CheckExtension(string ext)
+{
+ return (strstrofs(strcat(" ", cvar_string("gl_info_extensions"), " "), strcat(" ", ext, " "), 0) >= 0);
+}
+
+float GL_Have_TextureCompression()
+{
+ return (GL_CheckExtension("GL_EXT_texture_compression_s3tc") && GL_CheckExtension("GL_ARB_texture_compression"));
+}
+
float tooltipdb;
void loadTooltips()
{
default: return "";
}
}
+
+float updateCompression()
+{
+ float fh;
+ float have_dds, have_jpg, have_tga;
+ float can_dds;
+ 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);
+ can_dds = GL_Have_TextureCompression();
+ if(have_dds && (have_jpg || have_tga))
+ {
+ // both? Let's only use good quality precompressed files
+ // but ONLY if we actually support it!
+ if(can_dds)
+ {
+ cvar_set("gl_texturecompression", "0");
+ return 1;
+ }
+ else
+ {
+ cvar_set("gl_texturecompression", "0");
+ cvar_set("r_texture_dds_load", "0");
+ return 0;
+ }
+ }
+ else if(have_dds)
+ {
+ // DDS only? We probably always want texture compression
+ cvar_set("gl_texturecompression", "1");
+ cvar_set("r_texture_dds_load", "1");
+ if(!can_dds)
+ print("^1ERROR: Texture compression is required but not supported.\n^1Expect visual problems.\n");
+ return 0;
+ }
+ else
+ {
+ // TGA only? Allow runtime compression
+ if(can_dds)
+ {
+ cvar_set("gl_texturecompression", cvar_string("r_texture_dds_load"));
+ return 2;
+ }
+ else
+ {
+ cvar_set("gl_texturecompression", "0");
+ cvar_set("r_texture_dds_load", "0");
+ return 0;
+ }
+ }
+}
+float GL_CheckExtension(string ext);
+float GL_Have_TextureCompression();
+
void forAllDescendants(entity root, void(entity, entity) funcPre, void(entity, entity) funcPost, entity pass);
void saveAllCvars(entity root);
void loadAllCvars(entity root);
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;
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;
}
else
{
- self.havocbot_role();
+ if not(self.jumppadcount)
+ self.havocbot_role();
}
// TODO: tracewalk() should take care of this job (better path finding under water)
// 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)
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)
// (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
void havocbot_chooserole()
{
dprint("choosing a role...\n");
- navigation_clearroute();
self.bot_strategytime = 0;
if (g_ctf)
havocbot_chooserole_ctf();
self.navigation_jetpack_goal = world;
navigation_bestrating = -1;
self.navigation_hasgoals = FALSE;
+ navigation_clearroute();
navigation_bestgoal = world;
navigation_markroutes(world);
};
void race_SendRankings(float pos, float prevpos, float del, float msg);
void send_CSQC_teamnagger() {
- WriteByte(0, SVC_TEMPENTITY);
- WriteByte(0, TE_CSQC_TEAMNAGGER);
-}
-
-void send_CSQC_cr_maxbullets(entity e) {
- msg_entity = e;
- WriteByte(MSG_ONE, SVC_TEMPENTITY);
- WriteByte(MSG_ONE, TE_CSQC_CR_MAXBULLETS);
- WriteByte(MSG_ONE, autocvar_g_balance_campingrifle_magazinecapacity);
+ WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
+ WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER);
}
void Announce(string snd) {
WriteByte(MSG_ENTITY, autocvar_g_balance_nex_secondary); // client has to know if it should zoom or not
WriteByte(MSG_ENTITY, autocvar_g_balance_campingrifle_secondary); // client has to know if it should zoom or not
WriteByte(MSG_ENTITY, serverflags); // client has to know if it should zoom or not
+ WriteByte(MSG_ENTITY, autocvar_g_balance_campingrifle_magazinecapacity); // rifle max bullets
return TRUE;
}
if (g_domination)
set_dom_state();
- send_CSQC_cr_maxbullets(self);
CheatInitClient();
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)
// 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;
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));
}
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)
else
type = KILL_TEAM_BLUE;
- GiveFrags(attacker, targ, -1);
+ GiveFrags(attacker, targ, -1, deathtype);
Send_CSQC_Centerprint(attacker, s, "", type, MSG_KILL);
{
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);
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");
}
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;
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;
{
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);
}
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 != "")
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()
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);
}
/*
BADPREFIX("gl_");
BADPREFIX("joy");
BADPREFIX("hud_");
+ BADPREFIX("m_");
BADPREFIX("menu_");
BADPREFIX("net_slist_");
BADPREFIX("r_");
BADPREFIX("sbar_");
BADPREFIX("scr_");
BADPREFIX("snd_");
+ BADPREFIX("show");
+ BADPREFIX("sensitivity");
BADPREFIX("userbind");
BADPREFIX("v_");
BADPREFIX("vid_");
BADCVAR("g_ctf");
BADCVAR("g_dm");
BADCVAR("g_domination");
+ BADCVAR("g_freezetag");
BADCVAR("g_keyhunt");
BADCVAR("g_keyhunt_teams");
BADCVAR("g_onslaught");
BADCVAR("leadlimit_and_fraglimit");
BADCVAR("leadlimit_override");
BADCVAR("sv_checkforpacketsduringsleep");
+ BADCVAR("pausable");
+ BADCVAR("sv_timeout");
BADPREFIX("crypto_");
BADPREFIX("g_chat_");
BADPREFIX("net_");
BADCVAR("sv_vote_master_password");
BADCVAR("sv_vote_simple_majority_factor");
BADCVAR("timelimit_override");
+ BADCVAR("g_warmup");
+ BADPREFIX("g_warmup_");
if(autocvar_g_minstagib)
{
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")
{
playerstats_waitforme = TRUE;
}
+//#NO AUTOCVARS START
void PlayerStats_Shutdown()
{
string p, pn;
bufstr_set(b, i++, sprintf("T %s.%06d", strftime(FALSE, "%s"), floor(random() * 1000000)));
bufstr_set(b, i++, sprintf("G %s", GetGametype()));
bufstr_set(b, i++, sprintf("M %s", GetMapname()));
+ bufstr_set(b, i++, sprintf("S %s", cvar_string("hostname")));
+ bufstr_set(b, i++, sprintf("C %d", cvar_purechanges_count));
for(p = playerstats_last; (pn = db_get(playerstats_db, sprintf("%s:*", p))) != ""; p = pn)
{
bufstr_set(b, i++, sprintf("P %s", p));
db_close(playerstats_db);
playerstats_db = -1;
}
+//#NO AUTOCVARS END
void PlayerStats_AddGlobalInfo(entity p)
{
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")
}
local float ct;
ct = clienttype(other);
- if( ct == CLIENTTYPE_REAL)
+ if( ct == CLIENTTYPE_REAL || ct == CLIENTTYPE_BOT)
{
local float i;
local float found;
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;
SetMovedir ();
EXACTTRIGGER_INIT;
-
- self.active = ACTIVE_ACTIVE;
+
+ self.active = ACTIVE_ACTIVE;
self.use = trigger_push_use;
self.touch = trigger_push_touch;
self.blocked = generic_plat_blocked;
+ self.avelocity_z = 0.0000001;
if not(InitMovingBrushTrigger())
return;
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";
if(tracereffects & EF_RED)
eff = particleeffectnum("tr_rifle");
+ else if(tracereffects & EF_BLUE)
+ eff = particleeffectnum("tr_rifle_weak");
else
eff = particleeffectnum("tr_bullet");
#ifdef REGISTER_WEAPON
-REGISTER_WEAPON(MINE_LAYER, w_minelayer, IT_ROCKETS, 4, WEP_FLAG_NORMAL | WEP_TYPE_SPLASH, BOT_PICKUP_RATING_HIGH, "minelayer", "minelayer", "Mine Layer");
+REGISTER_WEAPON(MINE_LAYER, w_minelayer, IT_ROCKETS, 4, WEP_TYPE_SPLASH, BOT_PICKUP_RATING_HIGH, "minelayer", "minelayer", "Mine Layer");
#else
#ifdef SVQC
void W_Mine_Think (void);
//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=