- wget -O data/maps/stormkeep.waypoints https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints
- wget -O data/maps/stormkeep.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints.cache
- make
- - EXPECT=6535600492e1cb63af8e449570bffe4a
+ - EXPECT=bf2cc71d0f8c160bd28a417978aa6a1a
- HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
| tee /dev/stderr
| grep '^:'
seta hud_progressbar_health_color "" "R G B vector of the progress bar background color"
seta hud_progressbar_armor_color "" "R G B vector of the progress bar background color"
seta hud_progressbar_fuel_color "" "R G B vector of the progress bar background color"
+seta hud_progressbar_oxygen_color "" "R G B vector of the progress bar background color"
seta hud_progressbar_nexball_color "" "R G B vector of the progress bar background color"
seta hud_progressbar_speed_color "" "R G B vector of the progress bar background color"
seta hud_progressbar_acceleration_color "" "R G B vector of the progress bar background color"
// ===========
// this means that timelimit can be overidden globally and fraglimit can be overidden for each game mode: DM/TDM, Domination, CTF, and Runematch.
set leadlimit 0
-set leadlimit_and_fraglimit 0 "if set, leadlimit is ANDed with fraglimit (otherwise ORed)"
+set leadlimit_and_fraglimit 0 "both leadlimit AND fraglimit must be reached"
set timelimit_override -1 "Time limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
set fraglimit_override -1 "Frag limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
set leadlimit_override -1 "Lead limit overriding the mapinfo specified one (use 0 to play without limit, and -1 to use the mapinfo's limit)"
seta hud_progressbar_health_color "0.83 0.12 0"
seta hud_progressbar_armor_color "0.28 0.8 0"
seta hud_progressbar_fuel_color "0.77 0.67 0"
+seta hud_progressbar_oxygen_color "0.1 1 1"
seta hud_progressbar_nexball_color "0.2 0.65 0.93"
seta hud_progressbar_speed_color "0.77 0.67 0"
seta hud_progressbar_acceleration_color "0.2 0.65 0.93"
seta hud_progressbar_health_color "0.6 0 0"
seta hud_progressbar_armor_color "0 0.6 0"
seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_oxygen_color "0 1 1"
seta hud_progressbar_nexball_color "0.7 0.1 0"
seta hud_progressbar_speed_color "1 0.75 0"
seta hud_progressbar_acceleration_color "0.5 0.75 1"
seta hud_progressbar_health_color "0.6 0 0"
seta hud_progressbar_armor_color "0 0.6 0"
seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_oxygen_color "0 1 1"
seta hud_progressbar_nexball_color "0.7 0.1 0"
seta hud_progressbar_speed_color "1 0.75 0"
seta hud_progressbar_acceleration_color "0.5 0.75 1"
seta hud_progressbar_health_color "0.6 0 0"
seta hud_progressbar_armor_color "0 0.6 0"
seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_oxygen_color "0 1 1"
seta hud_progressbar_nexball_color "0.7 0.1 0"
seta hud_progressbar_speed_color "1 0.75 0"
seta hud_progressbar_acceleration_color "0.5 0.75 1"
seta hud_progressbar_health_color "0.6 0 0"
seta hud_progressbar_armor_color "0 0.6 0"
seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_oxygen_color "0 1 1"
seta hud_progressbar_nexball_color "0.7 0.1 0"
seta hud_progressbar_speed_color "1 0.75 0"
seta hud_progressbar_acceleration_color "0.5 0.75 1"
seta hud_progressbar_health_color "0.6 0 0"
seta hud_progressbar_armor_color "0 0.6 0"
seta hud_progressbar_fuel_color "0.6 0.6 0"
+seta hud_progressbar_oxygen_color "0 1 1"
seta hud_progressbar_nexball_color "0.7 0.1 0"
seta hud_progressbar_speed_color "1 0.75 0"
seta hud_progressbar_acceleration_color "0.5 0.75 1"
set g_campcheck_interval 10
set g_campcheck_damage 100
set g_campcheck_distance 1800
+set g_campcheck_typecheck 0 "damage campers who are typing"
// ==========
float autocvar_hud_progressbar_alpha;
vector autocvar_hud_progressbar_armor_color;
vector autocvar_hud_progressbar_fuel_color;
+vector autocvar_hud_progressbar_oxygen_color = '0.1 1 1';
vector autocvar_hud_progressbar_health_color;
vector autocvar_hud_progressbar_nexball_color;
vector autocvar_hud_progressbar_shield_color;
HUD_Write_Cvar("hud_progressbar_health_color");
HUD_Write_Cvar("hud_progressbar_armor_color");
HUD_Write_Cvar("hud_progressbar_fuel_color");
+ HUD_Write_Cvar("hud_progressbar_oxygen_color");
HUD_Write_Cvar("hud_progressbar_nexball_color");
HUD_Write_Cvar("hud_progressbar_speed_color");
HUD_Write_Cvar("hud_progressbar_acceleration_color");
void HUD_HealthArmor()
{
- int armor, health, fuel;
+ int armor, health, fuel, air_time;
if(!autocvar__hud_configure)
{
if((!autocvar_hud_panel_healtharmor) || (spectatee_status == -1))
prev_armor = 0;
}
fuel = STAT(FUEL);
+ air_time = bound(0, STAT(AIR_FINISHED) - time, 10);
}
else
{
health = 150;
armor = 75;
fuel = 20;
+ air_time = 6;
}
HUD_Panel_LoadCvars();
mySize -= '2 2 0' * panel_bg_padding;
}
+ float air_alpha = 1;
+ if (STAT(AIR_FINISHED) && time > STAT(AIR_FINISHED))
+ {
+ air_alpha = blink_synced(0.5, 0.5, 7, STAT(AIR_FINISHED), -1);
+ air_time = 10;
+ }
+
int baralign = autocvar_hud_panel_healtharmor_baralign;
int iconalign = autocvar_hud_panel_healtharmor_iconalign;
if(fuel)
HUD_Panel_DrawProgressBar(pos, vec2(mySize.x, 0.2 * mySize.y), "progressbar", fuel/100, 0, (baralign == 1 || baralign == 3), autocvar_hud_progressbar_fuel_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
+ if(air_time)
+ HUD_Panel_DrawProgressBar(pos + eY * 0.8 * mySize.y, vec2(mySize.x, 0.2 * mySize.y), "progressbar", air_time / 10, 0, (baralign == 1 || baralign == 3), autocvar_hud_progressbar_oxygen_color, air_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
}
else
{
armor_offset.y = mySize.y;
}
- bool health_baralign, armor_baralign, fuel_baralign;
+ bool health_baralign, armor_baralign, fuel_baralign, air_align;
bool health_iconalign, armor_iconalign;
if (autocvar_hud_panel_healtharmor_flip)
{
armor_baralign = (autocvar_hud_panel_healtharmor_baralign == 2 || autocvar_hud_panel_healtharmor_baralign == 1);
health_baralign = (autocvar_hud_panel_healtharmor_baralign == 3 || autocvar_hud_panel_healtharmor_baralign == 1);
- fuel_baralign = health_baralign;
+ air_align = fuel_baralign = health_baralign;
armor_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 2 || autocvar_hud_panel_healtharmor_iconalign == 1);
health_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 3 || autocvar_hud_panel_healtharmor_iconalign == 1);
}
{
health_baralign = (autocvar_hud_panel_healtharmor_baralign == 2 || autocvar_hud_panel_healtharmor_baralign == 1);
armor_baralign = (autocvar_hud_panel_healtharmor_baralign == 3 || autocvar_hud_panel_healtharmor_baralign == 1);
- fuel_baralign = armor_baralign;
+ air_align = fuel_baralign = armor_baralign;
health_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 2 || autocvar_hud_panel_healtharmor_iconalign == 1);
armor_iconalign = (autocvar_hud_panel_healtharmor_iconalign == 3 || autocvar_hud_panel_healtharmor_iconalign == 1);
}
if (health <= autocvar_hud_panel_healtharmor_progressbar_gfx_lowhealth)
{
- float BLINK_FACTOR = 0.15;
- float BLINK_BASE = 0.85;
- float BLINK_FREQ = 9;
- pain_health_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
+ pain_health_alpha = blink(0.85, 0.15, 9);
}
}
HUD_Panel_DrawProgressBar(pos + health_offset, mySize, autocvar_hud_panel_healtharmor_progressbar_health, p_health/maxhealth, is_vertical, health_baralign, autocvar_hud_progressbar_health_color, autocvar_hud_progressbar_alpha * panel_fg_alpha * pain_health_alpha, DRAWFLAG_NORMAL);
DrawNumIcon(pos + armor_offset, mySize, armor, "armor", is_vertical, armor_iconalign, HUD_Get_Num_Color(armor, maxarmor), 1);
}
- if(fuel)
+ vector cell_size = mySize;
+ if (fuel || air_time)
{
if (is_vertical)
mySize.x *= 0.2 / 2; //if vertical always halve x to not cover too much numbers with 3 digits
mySize.x *= 2; //restore full panel size
else if (panel_ar < 1/4)
mySize.y *= 2; //restore full panel size
- HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", fuel/100, is_vertical, fuel_baralign, autocvar_hud_progressbar_fuel_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
+ if (fuel)
+ HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", fuel/100, is_vertical, fuel_baralign, autocvar_hud_progressbar_fuel_color, panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
+ if (air_time)
+ {
+ if (panel_ar > 1 && panel_ar < 4)
+ pos.y += cell_size.y;
+ else if (panel_ar > 1/4 && panel_ar <= 1)
+ pos.x += cell_size.x;
+ if (is_vertical)
+ pos.x += cell_size.x - mySize.x;
+ else
+ pos.y += cell_size.y - mySize.y;
+ HUD_Panel_DrawProgressBar(pos, mySize, "progressbar", air_time / 10, is_vertical, air_align, autocvar_hud_progressbar_oxygen_color, air_alpha * panel_fg_alpha * 0.8, DRAWFLAG_NORMAL);
+ }
}
}
return boxsize * (0.5 * (1 - sz));
}
+// NOTE base is the central value
+// freq: circle frequency, = 2*pi*frequency in hertz
+// start_pos:
+// -1 start from the lower value
+// 0 start from the base value
+// 1 start from the higher value
+float blink_synced(float base, float range, float freq, float start_time, int start_pos)
+{
+ // note:
+ // RMS = sqrt(base^2 + 0.5 * range^2)
+ // thus
+ // base = sqrt(RMS^2 - 0.5 * range^2)
+ // ensure RMS == 1
+
+ return base + range * sin((time - start_time - (M_PI / 2) * start_pos) * freq);
+}
+
+float blink(float base, float range, float freq)
+{
+ return blink_synced(base, range, freq, 0, 0);
+}
+
void drawborderlines(float thickness, vector pos, vector dim, vector color, float theAlpha, float drawflag)
{
vector line_dim = '0 0 0';
vector expandingbox_resize_centered_box_offset(float sz, vector boxsize, float boxxsizefactor);
+float blink_synced(float base, float range, float freq, float start_time, int start_blink);
+float blink(float base, float range, float freq);
+
void drawborderlines(float thickness, vector pos, vector dim, vector color, float theAlpha, float drawflag);
void drawpic_tiled(vector pos, string pic, vector sz, vector area, vector color, float theAlpha, float drawflag);
X(neutral);
#undef X
- const float BLINK_FACTOR = 0.15;
- const float BLINK_BASE = 0.85;
- // note:
- // RMS = sqrt(BLINK_BASE^2 + 0.5 * BLINK_FACTOR^2)
- // thus
- // BLINK_BASE = sqrt(RMS^2 - 0.5 * BLINK_FACTOR^2)
- // ensure RMS == 1
- const float BLINK_FREQ = 5; // circle frequency, = 2*pi*frequency in hertz
-
#define X(team, cond) \
string team##_icon = string_null, team##_icon_prevstatus = string_null; \
int team##_alpha, team##_alpha_prevstatus; \
switch (team##flag) { \
case 1: team##_icon = "flag_" #team "_taken"; break; \
case 2: team##_icon = "flag_" #team "_lost"; break; \
- case 3: team##_icon = "flag_" #team "_carrying"; team##_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; \
+ case 3: team##_icon = "flag_" #team "_carrying"; team##_alpha = blink(0.85, 0.15, 5); break; \
default: \
if ((stat_items & CTF_SHIELDED) && (cond)) { \
team##_icon = "flag_" #team "_shielded"; \
switch (team##flag_prevstatus) { \
case 1: team##_icon_prevstatus = "flag_" #team "_taken"; break; \
case 2: team##_icon_prevstatus = "flag_" #team "_lost"; break; \
- case 3: team##_icon_prevstatus = "flag_" #team "_carrying"; team##_alpha_prevstatus = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ); break; \
+ case 3: team##_icon_prevstatus = "flag_" #team "_carrying"; team##_alpha_prevstatus = blink(0.85, 0.15, 5); break; \
default: \
if (team##flag == 3) { \
team##_icon_prevstatus = "flag_" #team "_carrying"; /* make it more visible */\
{
mod_active = 1; // keepaway should always show the mod HUD
- float BLINK_FACTOR = 0.15;
- float BLINK_BASE = 0.85;
- float BLINK_FREQ = 5;
- float kaball_alpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
+ float kaball_alpha = blink(0.85, 0.15, 5);
int stat_items = STAT(ITEMS);
int kaball = (stat_items/IT_KEY1) & 1;
float autocvar_g_campcheck_damage;
float autocvar_g_campcheck_distance;
float autocvar_g_campcheck_interval;
+bool autocvar_g_campcheck_typecheck;
REGISTER_MUTATOR(campcheck, expr_evaluate(autocvar_g_campcheck));
entity frag_attacker = M_ARGV(1, entity);
entity frag_target = M_ARGV(2, entity);
- if(IS_PLAYER(frag_target))
- if(IS_PLAYER(frag_attacker))
- if(frag_attacker != frag_target)
+ if(frag_attacker != frag_target && IS_PLAYER(frag_target) && IS_PLAYER(frag_attacker))
{
frag_target.campcheck_traveled_distance = autocvar_g_campcheck_distance;
frag_attacker.campcheck_traveled_distance = autocvar_g_campcheck_distance;
if(autocvar_g_campcheck_interval)
if(!game_stopped && !warmup_stage && time >= game_starttime)
- if(IS_PLAYER(player))
- if(!IS_DEAD(player))
- if(!STAT(FROZEN, player))
- if(!PHYS_INPUT_BUTTON_CHAT(player))
- if(IS_REAL_CLIENT(player)) // bots may camp, but that's no reason to constantly kill them
+ if(IS_PLAYER(player) && !IS_DEAD(player) && !STAT(FROZEN, player))
+ if(autocvar_g_campcheck_typecheck || !PHYS_INPUT_BUTTON_CHAT(player))
+ if(IS_REAL_CLIENT(player)) // only apply to real clients (bots may "camp" due to missing waypoints in the map, but that's no reason to constantly kill them, clones can't move)
if(!weaponLocked(player))
{
// calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement)
if (autocvar_hud_panel_itemstime_hidespawned == 2)
picalpha = 1;
else if (item_available)
- {
- float BLINK_FACTOR = 0.15;
- float BLINK_BASE = 0.85;
- float BLINK_FREQ = 5;
- picalpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
- }
+ picalpha = blink(0.85, 0.15, 5);
else
picalpha = 0.5;
t = floor(item_time - time + 0.999);
REGISTER_STAT(DAMAGE_DEALT_TOTAL, int)
REGISTER_STAT(TYPEHIT_TIME, float)
REGISTER_STAT(SUPERWEAPONS_FINISHED, float)
+REGISTER_STAT(AIR_FINISHED, float)
REGISTER_STAT(VEHICLESTAT_HEALTH, int)
REGISTER_STAT(VEHICLESTAT_SHIELD, int)
REGISTER_STAT(VEHICLESTAT_ENERGY, int)
this.strength_finished = 0;
this.invincible_finished = 0;
this.superweapons_finished = 0;
+ this.air_finished_stat = 0;
//this.dphitcontentsmask = 0;
this.dphitcontentsmask = DPCONTENTS_SOLID;
if (autocvar_g_playerclip_collisions)
STAT(BUFFS, this) = 0;
STAT(BUFF_TIME, this) = 0;
- this.air_finished = time + 12;
+ this.air_finished = time + autocvar_g_balance_contents_drowndelay;
this.waterlevel = WATERLEVEL_NONE;
this.watertype = CONTENT_EMPTY;
this.strength_finished = spectatee.strength_finished;
this.invincible_finished = spectatee.invincible_finished;
this.superweapons_finished = spectatee.superweapons_finished;
+ this.air_finished_stat = spectatee.air_finished_stat;
STAT(PRESSED_KEYS, this) = STAT(PRESSED_KEYS, spectatee);
STAT(WEAPONS, this) = STAT(WEAPONS, spectatee);
this.punchangle = spectatee.punchangle;
if(this.air_finished < time)
PlayerSound(this, playersound_gasp, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
this.air_finished = time + autocvar_g_balance_contents_drowndelay;
+ this.air_finished_stat = 0;
}
else if (this.air_finished < time)
{ // drown!
Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_drowning * autocvar_g_balance_contents_damagerate, DEATH_DROWN.m_id, DMG_NOWEP, this.origin, '0 0 0');
this.pain_finished = time + 0.5;
}
+ this.air_finished_stat = this.air_finished;
}
+ else
+ this.air_finished_stat = this.air_finished;
}
.bool move_qcphysics;
.float crouch; // Crouching or not?
const .float superweapons_finished = _STAT(SUPERWEAPONS_FINISHED);
+const .float air_finished_stat = _STAT(AIR_FINISHED);
.float cnt; // used in too many places
.float count;
this.flags &= ~FL_INWATER;
this.dmgtime = 0;
}
- this.air_finished = time + 12;
+ this.air_finished = time + autocvar_g_balance_contents_drowndelay;
}
}