Commit 80afa873 authored by Mario's avatar Mario

Merge branch 'master' into martin-t/maxshotdist

parents 5fd09585 fca1fc15
Pipeline #5605347 failed with stage
in 13 minutes and 25 seconds
......@@ -30,7 +30,7 @@ test_sv_game:
- wget -O data/maps/g-23.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.cache
- wget -O data/maps/g-23.waypoints.hardwired https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/g-23.waypoints.hardwired
- make
- EXPECT=04d63df6a5d73bd335612543efd944d6
- EXPECT=37be9dc5489925451eb497390fdf58b9
- HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
| tee /dev/stderr
| grep '^:'
......
......@@ -97,7 +97,7 @@ seta hud_panel_physics_speed_unit "1" "speed unit (1 = qu/s, 2 = m/s, 3 = km/h,
seta hud_panel_itemstime_progressbar_maxtime "30" "when left time is at least this amount, the status bar is full"
seta hud_panel_itemstime_hidespawned "1" "if 1 hide an item from the panel when all the occurrences of it are available again; if 2 hide it when at least one occurrence is available again"
seta hud_panel_itemstime_hidelarge "0" "if 1 hide large armor and health from the panel"
seta hud_panel_itemstime_hidebig "0" "if 1 hide big armor and health from the panel"
seta hud_panel_quickmenu_file "" "load the quick menu from this file (empty or 0 to disable)"
seta hud_panel_quickmenu_translatecommands 0 "when the game is translated, translate strings inside commands too (useful for chat commands)"
......
......@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 1
set g_pickup_armorbig 50
set g_pickup_armorbig_max 200
set g_pickup_armorbig_anyway 1
set g_pickup_armorlarge 100
set g_pickup_armorlarge_max 200
set g_pickup_armorlarge_anyway 1
set g_pickup_armormega 100
set g_pickup_armormega_max 200
set g_pickup_armormega_anyway 1
set g_pickup_healthsmall 5
set g_pickup_healthsmall_max 200
set g_pickup_healthsmall_anyway 1
set g_pickup_healthmedium 25
set g_pickup_healthmedium_max 200
set g_pickup_healthmedium_anyway 1
set g_pickup_healthlarge 50
set g_pickup_healthlarge_max 200
set g_pickup_healthlarge_anyway 1
set g_pickup_healthbig 50
set g_pickup_healthbig_max 200
set g_pickup_healthbig_anyway 1
set g_pickup_healthmega 100
set g_pickup_healthmega_max 200
set g_pickup_healthmega_anyway 1
......
......@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 0
set g_pickup_armorbig 50
set g_pickup_armorbig_max 999
set g_pickup_armorbig_anyway 0
set g_pickup_armorlarge 100
set g_pickup_armorlarge_max 999
set g_pickup_armorlarge_anyway 0
set g_pickup_armormega 100
set g_pickup_armormega_max 999
set g_pickup_armormega_anyway 0
set g_pickup_healthsmall 5
set g_pickup_healthsmall_max 999
set g_pickup_healthsmall_anyway 0
set g_pickup_healthmedium 25
set g_pickup_healthmedium_max 999
set g_pickup_healthmedium_anyway 0
set g_pickup_healthlarge 50
set g_pickup_healthlarge_max 999
set g_pickup_healthlarge_anyway 0
set g_pickup_healthbig 50
set g_pickup_healthbig_max 999
set g_pickup_healthbig_anyway 0
set g_pickup_healthmega 100
set g_pickup_healthmega_max 999
set g_pickup_healthmega_anyway 0
......
......@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 1
set g_pickup_armorbig 50
set g_pickup_armorbig_max 100
set g_pickup_armorbig_anyway 1
set g_pickup_armorlarge 100
set g_pickup_armorlarge_max 100
set g_pickup_armorlarge_anyway 1
set g_pickup_armormega 100
set g_pickup_armormega_max 100
set g_pickup_armormega_anyway 1
set g_pickup_healthsmall 5
set g_pickup_healthsmall_max 200
set g_pickup_healthsmall_anyway 1
set g_pickup_healthmedium 25
set g_pickup_healthmedium_max 200
set g_pickup_healthmedium_anyway 1
set g_pickup_healthlarge 50
set g_pickup_healthlarge_max 200
set g_pickup_healthlarge_anyway 1
set g_pickup_healthbig 50
set g_pickup_healthbig_max 200
set g_pickup_healthbig_anyway 1
set g_pickup_healthmega 100
set g_pickup_healthmega_max 200
set g_pickup_healthmega_anyway 0
......
......@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 1
set g_pickup_armorbig 50
set g_pickup_armorbig_max 200
set g_pickup_armorbig_anyway 1
set g_pickup_armorlarge 100
set g_pickup_armorlarge_max 200
set g_pickup_armorlarge_anyway 1
set g_pickup_armormega 100
set g_pickup_armormega_max 200
set g_pickup_armormega_anyway 1
set g_pickup_healthsmall 5
set g_pickup_healthsmall_max 200
set g_pickup_healthsmall_anyway 1
set g_pickup_healthmedium 25
set g_pickup_healthmedium_max 200
set g_pickup_healthmedium_anyway 1
set g_pickup_healthlarge 50
set g_pickup_healthlarge_max 200
set g_pickup_healthlarge_anyway 1
set g_pickup_healthbig 50
set g_pickup_healthbig_max 200
set g_pickup_healthbig_anyway 1
set g_pickup_healthmega 100
set g_pickup_healthmega_max 200
set g_pickup_healthmega_anyway 1
......
......@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 1
set g_pickup_armorbig 50
set g_pickup_armorbig_max 200
set g_pickup_armorbig_anyway 1
set g_pickup_armorlarge 100
set g_pickup_armorlarge_max 200
set g_pickup_armorlarge_anyway 1
set g_pickup_armormega 100
set g_pickup_armormega_max 200
set g_pickup_armormega_anyway 1
set g_pickup_healthsmall 5
set g_pickup_healthsmall_max 200
set g_pickup_healthsmall_anyway 1
set g_pickup_healthmedium 25
set g_pickup_healthmedium_max 200
set g_pickup_healthmedium_anyway 1
set g_pickup_healthlarge 50
set g_pickup_healthlarge_max 200
set g_pickup_healthlarge_anyway 1
set g_pickup_healthbig 50
set g_pickup_healthbig_max 200
set g_pickup_healthbig_anyway 1
set g_pickup_healthmega 100
set g_pickup_healthmega_max 200
set g_pickup_healthmega_anyway 1
......
......@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 1
set g_pickup_armorbig 50
set g_pickup_armorbig_max 200
set g_pickup_armorbig_anyway 1
set g_pickup_armorlarge 100
set g_pickup_armorlarge_max 200
set g_pickup_armorlarge_anyway 1
set g_pickup_armormega 100
set g_pickup_armormega_max 200
set g_pickup_armormega_anyway 1
set g_pickup_healthsmall 5
set g_pickup_healthsmall_max 200
set g_pickup_healthsmall_anyway 1
set g_pickup_healthmedium 25
set g_pickup_healthmedium_max 200
set g_pickup_healthmedium_anyway 1
set g_pickup_healthlarge 50
set g_pickup_healthlarge_max 200
set g_pickup_healthlarge_anyway 1
set g_pickup_healthbig 50
set g_pickup_healthbig_max 200
set g_pickup_healthbig_anyway 1
set g_pickup_healthmega 100
set g_pickup_healthmega_max 200
set g_pickup_healthmega_anyway 1
......
......@@ -72,18 +72,18 @@ set g_pickup_armormedium_anyway 0
set g_pickup_armorbig 50
set g_pickup_armorbig_max 100
set g_pickup_armorbig_anyway 0
set g_pickup_armorlarge 100
set g_pickup_armorlarge_max 200
set g_pickup_armorlarge_anyway 0
set g_pickup_armormega 100
set g_pickup_armormega_max 200
set g_pickup_armormega_anyway 0
set g_pickup_healthsmall 5
set g_pickup_healthsmall_max 200
set g_pickup_healthsmall_anyway 0
set g_pickup_healthmedium 25
set g_pickup_healthmedium_max 100
set g_pickup_healthmedium_anyway 0
set g_pickup_healthlarge 50
set g_pickup_healthlarge_max 100
set g_pickup_healthlarge_anyway 0
set g_pickup_healthbig 50
set g_pickup_healthbig_max 100
set g_pickup_healthbig_anyway 0
set g_pickup_healthmega 100
set g_pickup_healthmega_max 200
set g_pickup_healthmega_anyway 0
......
......@@ -382,17 +382,17 @@ set bot_ai_friends_aware_pickup_radius "500" "Bots will not pickup items if a te
set bot_ai_ignoregoal_timeout 3 "Ignore goals making bots to get stuck in front of a wall for N seconds"
set bot_ai_bunnyhop_skilloffset 7 "Bots with skill equal or greater than this value will perform the \"bunnyhop\" technique"
set bot_ai_bunnyhop_startdistance 200 "Run to goals located further than this distance"
set bot_ai_bunnyhop_stopdistance 200 "Stop jumping after reaching this distance to the goal"
set bot_ai_bunnyhop_stopdistance 300 "Stop jumping after reaching this distance to the goal"
set bot_ai_bunnyhop_firstjumpdelay 0.2 "Start running to the goal only if it was seen for more than N seconds"
set bot_god 0 "god mode for bots"
set bot_ai_navigation_jetpack 0 "Enable bots to navigate maps using the jetpack"
set bot_ai_navigation_jetpack_mindistance 3500 "Bots will try fly to objects located farther than this distance"
// Better don't touch these, there are hard to tweak!
set bot_ai_aimskill_order_mix_1st 0.01 "Amount of the 1st filter output to apply to the aiming angle"
set bot_ai_aimskill_order_mix_2nd 0.1 "Amount of the 1st filter output to apply to the aiming angle"
set bot_ai_aimskill_order_mix_3th 0.01 "Amount of the 1st filter output to apply to the aiming angle"
set bot_ai_aimskill_order_mix_4th 0.05 "Amount of the 1st filter output to apply to the aiming angle"
set bot_ai_aimskill_order_mix_5th 0.01 "Amount of the 1st filter output to apply to the aiming angle"
set bot_ai_aimskill_order_mix_2nd 0.1 "Amount of the 2nd filter output to apply to the aiming angle"
set bot_ai_aimskill_order_mix_3th 0.01 "Amount of the 3th filter output to apply to the aiming angle"
set bot_ai_aimskill_order_mix_4th 0.05 "Amount of the 4th filter output to apply to the aiming angle"
set bot_ai_aimskill_order_mix_5th 0.01 "Amount of the 5th filter output to apply to the aiming angle"
set bot_ai_aimskill_order_filter_1st 0.4 "Position filter"
set bot_ai_aimskill_order_filter_2nd 0.4 "Movement filter"
set bot_ai_aimskill_order_filter_3th 0.2 "Acceleration filter"
......@@ -1072,7 +1072,7 @@ alias gl_flashblend_update "_gl_flashblend_update_$r_shadow_realtime_dlight$r_sh
set sv_clones 0 "number of clones a player may make (reset by the \"kill\" command)"
set cl_handicap 1 "the higher, the more damage you will receive (client setting) NOTE: reconnect or use sendcvar command to update the choice."
set cl_handicap 1 "multiplies damage received and divides damage dealt NOTE: reconnect or use 'sendcvar cl_handicap' to update the choice."
seta cl_clippedspectating 1 "movement collision for spectators so that you can't pass through walls and such. (client setting) NOTE: reconnect or use sendcvar command to update the choice."
......
......@@ -18,7 +18,7 @@ alias asay_drop "say_team (%l) dropped %w ; impulse 17"
// =================
// gamestart hooks
// =================
seta cl_matchcount 0 // incremented by cl_hook_gameend and used by playerstats to know when to
seta cl_matchcount 0 // incremented by cl_hook_gameend and used by playerstats to know when to
alias _cl_hook_gamestart "set _cl_hook_gametype $1; _cl_hook_gamestart_stage2"
alias _cl_hook_gamestart_stage2 "cl_hook_gamestart_all; cl_hook_gamestart_${_cl_hook_gametype}"
alias cl_hook_gamestart_all
......@@ -278,7 +278,7 @@ set g_ctf_dropped_capture_delay 1 "dropped capture delay"
set g_ctf_dropped_capture_radius 100 "allow dropped flags to be automatically captured by base flags if the dropped flag is within this radius of it"
set g_ctf_flag_damageforcescale 2
set g_ctf_portalteleport 0 "allow flag carriers to go through portals made in portal gun without dropping the flag"
set g_ctf_reverse 0 "if enabled, flags positions are switched: you have to capture the enemy's flag from your own base by bringing it to your own flag in the enemy base"
set g_ctf_reverse 0 "if enabled, you score by bringing your own flag to an enemy's flag in their base"
set g_ctf_flag_collect_delay 1
set g_ctf_flag_health 0
set g_ctf_flag_dropped_waypoint 2 "show dropped flag waypointsprite when a flag is lost. 1 = team only, 2 = for all players"
......
......@@ -53,7 +53,7 @@ set g_overkill_powerups_replace 1
set g_overkill_filter_healthmega 0
set g_overkill_filter_armormedium 0
set g_overkill_filter_armorbig 0
set g_overkill_filter_armorlarge 0
set g_overkill_filter_armormega 0
set g_overkill_ammo_charge 0
set g_overkill_ammo_charge_notice 1
......@@ -304,7 +304,7 @@ set g_new_toys_use_pickupsound 1 "play the 'new toys, new toys!' roflsound when
// buffs
// =======
set cl_buffs_autoreplace 1 "automatically drop current buff when picking up another"
set g_buffs 0 "enable buffs (requires buff items or powerups)"
set g_buffs -1 "enable buffs (requires buff items or powerups)"
set g_buffs_effects 1 "show particle effects from carried buffs"
set g_buffs_waypoint_distance 1024 "maximum distance at which buff waypoint can be seen from item"
set g_buffs_randomize 1 "randomize buff type when player drops buff"
......@@ -312,7 +312,7 @@ set g_buffs_random_lifetime 30 "re-spawn the buff again if it hasn't been touche
set g_buffs_random_location 0 "randomize buff location on start and when reset"
set g_buffs_random_location_attempts 10 "number of random locations a single buff will attempt to respawn at before giving up"
set g_buffs_spawn_count 0 "how many buffs to spawn on the map if none exist already"
set g_buffs_replace_powerups 1 "replace powerups on the map with random buffs"
set g_buffs_replace_powerups 0 "replace powerups on the map with random buffs"
set g_buffs_cooldown_activate 5 "cooldown period when buff is first activated"
set g_buffs_cooldown_respawn 3 "cooldown period when buff is reloading"
set g_buffs_ammo 1 "ammo buff: infinite ammunition"
......@@ -377,6 +377,8 @@ set g_buffs_luck 1 "luck buff: randomly increased damage"
set g_buffs_luck_time 60 "luck buff carry time"
set g_buffs_luck_chance 0.15 "chance for 'critical' hit (multiplied damage) with luck buff"
set g_buffs_luck_damagemultiplier 3 "luck damage multiplier"
set g_buffs_flight 0 "flight buff: crouch jump to reverse your gravity!"
set g_buffs_flight_time 60 "flight buff carry time"
// ==============
......
......@@ -424,10 +424,11 @@ seta notification_INFO_WEAPON_TUBA_SUICIDE "1" "0 = off, 1 = print to console, 2
seta notification_INFO_WEAPON_VAPORIZER_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
seta notification_INFO_WEAPON_VORTEX_MURDER "1" "0 = off, 1 = print to console, 2 = print to console and chatbox (if notification_allow_chatboxprint is enabled)"
// MSG_CENTER notifications (count = 230):
// MSG_CENTER notifications (count = 231):
seta notification_CENTER_ALONE "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ASSAULT_ATTACKING "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ASSAULT_DEFENDING "1" "0 = off, 1 = centerprint"
seta notification_CENTER_ASSAULT_OBJ_DESTROYED "1" "0 = off, 1 = centerprint"
seta notification_CENTER_CAMPCHECK "1" "0 = off, 1 = centerprint"
seta notification_CENTER_COINTOSS "1" "0 = off, 1 = centerprint"
seta notification_CENTER_COUNTDOWN_BEGIN "1" "0 = off, 1 = centerprint"
......@@ -886,4 +887,4 @@ seta notification_show_sprees_info "3" "Show spree information in MSG_INFO messa
seta notification_show_sprees_info_newline "1" "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself"
seta notification_show_sprees_info_specialonly "1" "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement"
// Notification counts (total = 820): MSG_ANNCE = 89, MSG_INFO = 320, MSG_CENTER = 230, MSG_MULTI = 153, MSG_CHOICE = 28
// Notification counts (total = 821): MSG_ANNCE = 89, MSG_INFO = 320, MSG_CENTER = 231, MSG_MULTI = 153, MSG_CHOICE = 28
......@@ -120,7 +120,7 @@ int serverflags;
float uid2name_dialog;
float gameover_time;
float intermission_time;
.bool csqcmodel_isdead; // used by shownames and miscfunctions (entcs_IsDead) to know when a player is dead
......
......@@ -114,6 +114,8 @@ void HUD_InfoMessages()
InfoMessage(s);
}
MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize);
if(!warmup_stage && gametype == MAPINFO_TYPE_LMS)
{
entity sk;
......
......@@ -283,8 +283,9 @@ void HUD_Mod_KH(vector pos, vector mySize)
mod_active = 1; // keyhunt should never hide the mod icons panel
// Read current state
int state = STAT(KH_KEYS);
if(!state) return;
int i, key_state;
int all_keys, team1_keys, team2_keys, team3_keys, team4_keys, dropped_keys, carrying_keys;
all_keys = team1_keys = team2_keys = team3_keys = team4_keys = dropped_keys = carrying_keys = 0;
......@@ -315,9 +316,7 @@ void HUD_Mod_KH(vector pos, vector mySize)
}
// Calculate slot measurements
vector slot_size;
if(all_keys == 4 && mySize.x * 0.5 < mySize.y && mySize.y * 0.5 < mySize.x)
{
// Quadratic arrangement
......@@ -347,11 +346,10 @@ void HUD_Mod_KH(vector pos, vector mySize)
// Make icons blink in case of RUN HERE
float blink = 0.6 + sin(2*M_PI*time) / 2.5; // Oscillate between 0.2 and 1
float alpha;
alpha = 1;
float alpha = 1;
if(carrying_keys)
{
float blink = 0.6 + sin(2 * M_PI * time) * 0.4; // Oscillate between 0.2 and 1
switch(myteam)
{
case NUM_TEAM_1: if(team1_keys == all_keys) alpha = blink; break;
......@@ -359,6 +357,7 @@ void HUD_Mod_KH(vector pos, vector mySize)
case NUM_TEAM_3: if(team3_keys == all_keys) alpha = blink; break;
case NUM_TEAM_4: if(team4_keys == all_keys) alpha = blink; break;
}
}
// Draw icons
......
......@@ -63,7 +63,7 @@ void HUD_Powerups()
{
int allItems = STAT(ITEMS);
int allBuffs = STAT(BUFFS);
int strengthTime, shieldTime, superTime;
float strengthTime, shieldTime, superTime;
// Initialize items
if(!autocvar__hud_configure)
......@@ -72,7 +72,7 @@ void HUD_Powerups()
return;
if(STAT(HEALTH) <= 0 && autocvar_hud_panel_powerups_hide_ondeath)
return;
if(!(allItems & (ITEM_Strength.m_itemid | ITEM_Shield.m_itemid | IT_SUPERWEAPON)) && !allBuffs) return;
//if(!(allItems & (ITEM_Strength.m_itemid | ITEM_Shield.m_itemid | IT_SUPERWEAPON)) && !allBuffs) return;
strengthTime = bound(0, STAT(STRENGTH_FINISHED) - time, 99);
shieldTime = bound(0, STAT(INVINCIBLE_FINISHED) - time, 99);
......
......@@ -312,10 +312,10 @@ void HUD_Radar()
else
{
vector c0, c1, c2, c3, span;
c0 = rotate(mi_min, teamradar_angle * DEG2RAD);
c1 = rotate(mi_max, teamradar_angle * DEG2RAD);
c2 = rotate('1 0 0' * mi_min.x + '0 1 0' * mi_max.y, teamradar_angle * DEG2RAD);
c3 = rotate('1 0 0' * mi_max.x + '0 1 0' * mi_min.y, teamradar_angle * DEG2RAD);
c0 = Rotate(mi_min, teamradar_angle * DEG2RAD);
c1 = Rotate(mi_max, teamradar_angle * DEG2RAD);
c2 = Rotate('1 0 0' * mi_min.x + '0 1 0' * mi_max.y, teamradar_angle * DEG2RAD);
c3 = Rotate('1 0 0' * mi_max.x + '0 1 0' * mi_min.y, teamradar_angle * DEG2RAD);
span = '0 0 0';
span.x = max(c0_x, c1_x, c2_x, c3_x) - min(c0_x, c1_x, c2_x, c3_x);
span.y = max(c0_y, c1_y, c2_y, c3_y) - min(c0_y, c1_y, c2_y, c3_y);
......
......@@ -50,15 +50,15 @@ void HUD_Timer()
}
vector timer_color;
if(gameover_time || minutesLeft >= 5 || warmup_stage || timelimit == 0)
if(intermission_time || minutesLeft >= 5 || warmup_stage || timelimit == 0)
timer_color = '1 1 1'; //white
else if(minutesLeft >= 1)
timer_color = '1 1 0'; //yellow
else
timer_color = '1 0 0'; //red
if (gameover_time) {
timer = seconds_tostring(max(0, floor(gameover_time - STAT(GAMESTARTTIME))));
if (intermission_time) {
timer = seconds_tostring(max(0, floor(intermission_time - STAT(GAMESTARTTIME))));
} else if (autocvar_hud_panel_timer_increment || (!warmup_stage && timelimit == 0) || (warmup_stage && warmup_timeleft <= 0)) {
if (time < STAT(GAMESTARTTIME))
timer = seconds_tostring(0); //while restart is still active, show 00:00
......
......@@ -31,7 +31,7 @@ vector HUD_GetFontsize(string cvarname);
float PreviewExists(string name);
vector rotate(vector v, float a);
vector Rotate(vector v, float a);
#define IS_DEAD(s) (((s).classname == "csqcmodel") ? (s).csqcmodel_isdead : ((s).health <= 0))
......
......@@ -157,3 +157,10 @@ MUTATOR_HOOKABLE(DrawCrosshair, EV_NO_ARGS);
/** Return true to not draw scoreboard */
MUTATOR_HOOKABLE(DrawScoreboard, EV_NO_ARGS);
/** Called when drawing info messages, allows adding new info messages */
#define EV_DrawInfoMessages(i, o) \
/** pos */ i(vector, MUTATOR_ARGV_0_vector) \
/** mySize */ i(vector, MUTATOR_ARGV_1_vector) \
/**/
MUTATOR_HOOKABLE(DrawInfoMessages, EV_DrawInfoMessages);
......@@ -49,34 +49,41 @@ void Draw_ShowNames(entity this)
hit = !(trace_fraction < 1 && (trace_networkentity != this.sv_entnum && trace_ent.entnum != this.sv_entnum));
}
// handle tag fading
bool overlap = false;
int overlap = -1;
vector o = project_3d_to_2d(this.origin + eZ * autocvar_hud_shownames_offset);
if (autocvar_hud_shownames_crosshairdistance)
{
float d = autocvar_hud_shownames_crosshairdistance;
float w = o.x - vid_conwidth / 2;
float h = o.y - vid_conheight / 2;
if (d * d > w * w + h * h) this.pointtime = time;
if (this.pointtime + autocvar_hud_shownames_crosshairdistance_time <= time)
overlap = 1;
else if(!autocvar_hud_shownames_crosshairdistance_antioverlap)
overlap = 0;
}
float dist = vlen(this.origin - view_origin);
if (autocvar_hud_shownames_antioverlap)
if (overlap == -1 && autocvar_hud_shownames_antioverlap)
{
// fade tag out if another tag that is closer to you overlaps
LL_EACH(shownames_ent, it != this && entcs_receiver(i), {
entity entcs = NULL;
LL_EACH(shownames_ent, it != this, {
entcs = entcs_receiver(i);
if (!(entcs && entcs.has_sv_origin))
continue;
vector eo = project_3d_to_2d(it.origin);
if (eo.z < 0 || eo.x < 0 || eo.y < 0 || eo.x > vid_conwidth || eo.y > vid_conheight) continue;
eo.z = 0;
if (vdist(((eX * o.x + eY * o.y) - eo), <, autocvar_hud_shownames_antioverlap_distance)
&& vdist((it.origin - view_origin), <, dist))
{
overlap = true;
overlap = 1;
break;
}
});
}
bool onscreen = (o.z >= 0 && o.x >= 0 && o.y >= 0 && o.x <= vid_conwidth && o.y <= vid_conheight);
if (autocvar_hud_shownames_crosshairdistance)
{
float d = autocvar_hud_shownames_crosshairdistance;
float w = o.x - vid_conwidth / 2;
float h = o.y - vid_conheight / 2;
if (d * d > w * w + h * h) this.pointtime = time;
if (this.pointtime + autocvar_hud_shownames_crosshairdistance_time <= time) overlap = true;
else overlap = (autocvar_hud_shownames_crosshairdistance_antioverlap ? overlap : false); // override what antioverlap says unless allowed by cvar.
}
if (!this.fadedelay) this.fadedelay = time + SHOWNAMES_FADEDELAY;
if (this.csqcmodel_isdead) // dead player, fade out slowly
{
......@@ -87,7 +94,7 @@ void Draw_ShowNames(entity this)
this.alpha = max(0, this.alpha - SHOWNAMES_FADESPEED * frametime);
this.fadedelay = 0; // reset fade in delay, enemy has left the view
}
else if (overlap) // tag overlap detected, fade out
else if (overlap > 0) // tag overlap detected, fade out
{
this.alpha = max(0, this.alpha - SHOWNAMES_FADESPEED * frametime);
}
......@@ -193,8 +200,6 @@ void Draw_ShowNames_All()
it.sameteam = false;
}
bool dead = entcs_IsDead(i) || entcs_IsSpectating(i);
if(gametype == MAPINFO_TYPE_CA)
dead = (dead || entcs_IsEliminated(i));
if (!it.csqcmodel_isdead) setorigin(it, entcs.origin);
it.csqcmodel_isdead = dead;
Draw_ShowNames(it);
......
......@@ -20,7 +20,7 @@ vector teamradar_texcoord_to_2dcoord(vector in)
vector out;
in -= teamradar_origin3d_in_texcoord;
out = rotate(in, teamradar_angle * DEG2RAD);
out = Rotate(in, teamradar_angle * DEG2RAD);
out.y = - out.y; // screen space is reversed
out = out * teamradar_size;
......@@ -42,7 +42,7 @@ vector teamradar_2dcoord_to_texcoord(vector in)
out = out / teamradar_size;
out_y = - out_y; // screen space is reversed
out = rotate(out, -teamradar_angle * DEG2RAD);
out = Rotate(out, -teamradar_angle * DEG2RAD);
out += teamradar_origin3d_in_texcoord;
......
......@@ -747,7 +747,7 @@ bool WantEventchase(entity this)
{
if(autocvar_cl_orthoview)
return false;
if(intermission)
if(STAT(GAMEOVER) || intermission)
return true;
if(this.viewloc)
return true;
......@@ -940,7 +940,7 @@ void HUD_Crosshair(entity this)
{
float f, i, j;
vector v;
if(!scoreboard_active && !camera_active && intermission != 2 &&
if(!scoreboard_active && !camera_active && intermission != 2 && !STAT(GAMEOVER) &&
spectatee_status != -1 && !csqcplayer.viewloc && !MUTATOR_CALLHOOK(DrawCrosshair) &&
!HUD_MinigameMenu_IsOpened() )
{
......@@ -1748,8 +1748,8 @@ void CSQC_UpdateView(entity this, float w, float h)
if(!postinit)
PostInit();
if(intermission && !gameover_time)
gameover_time = time;
if(intermission && !intermission_time)
intermission_time = time;
if(intermission && !isdemo() && !(calledhooks & HOOK_END))
{
......
......@@ -13,9 +13,9 @@ MACRO_END
// #define PROP(public, fld, set, sv, cl)
#define ENTCS_NETPROPS(ent, PROP) PROP(false, sv_entnum, ENTCS_SET_NORMAL, {}, {}) /* sentinel */ \
PROP(false, origin, ENTCS_SET_NORMAL, \
{ WriteShort(chan, ent.origin.x); WriteShort(chan, ent.origin.y); \
WriteShort(chan, ent.origin.z); }, \
{ ent.has_sv_origin = true; vector v; v.x = ReadShort(); v.y = ReadShort(); v.z = ReadShort(); setorigin(ent, v); }) \
{ WriteCoord(chan, ent.origin.x); WriteCoord(chan, ent.origin.y); \
WriteCoord(chan, ent.origin.z); }, \
{ ent.has_sv_origin = true; vector v; v.x = ReadCoord(); v.y = ReadCoord(); v.z = ReadCoord(); setorigin(ent, v); }) \
\
PROP(false, angles_y, ENTCS_SET_NORMAL, \
{ WriteByte(chan, ent.angles.y / 360 * 256); }, \
......@@ -73,6 +73,11 @@ MACRO_END
entity player = this.owner;
sf |= BIT(0); // assume private
do {
if (!(IS_PLAYER(player)))
{
sf &= ENTCS_PUBLICMASK; // no private updates
break;
}
if (radar_showennemies) break;
if (SAME_TEAM(to, player)) break;
if (!(IS_PLAYER(to) || to.caplayer) && time > game_starttime) break;
......
......@@ -68,17 +68,6 @@ REGISTER_NET_TEMP(CLIENT_ENTCS)
/**
* @param i zero indexed player
*/
.int frags;
bool entcs_IsEliminated(int i)
{
bool unconnected = !playerslots[i].gotscores;
entity e = entcs_receiver(i);
return unconnected || ((e) ? e.frags : stof(getplayerkeyvalue(i, "frags"))) == FRAGS_LMS_LOSER;
}
/**
* @param i zero indexed player
*/
int entcs_GetClientColors(int i)
{
......
......@@ -1638,7 +1638,7 @@ bool ons_Teleport(entity player, entity tele_target, float range, bool tele_effe
loc += tele_target.origin + '0 0 128' * iteration_scale;
tracebox(loc, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), loc, MOVE_NORMAL, player);
tracebox(loc, STAT(PL_MIN, player), STAT(PL_MAX, player), loc, MOVE_NORMAL, player);
if(trace_fraction == 1.0 && !trace_startsolid)
{
traceline(tele_target.origin, loc, MOVE_NOMONSTERS, tele_target); // double check to make sure we're not spawning outside the NULL
......@@ -1757,7 +1757,7 @@ MUTATOR_HOOKFUNCTION(ons, PlayerSpawn)
iteration_scale -= i / 10;
loc = closest_target.origin + '0 0 96' * iteration_scale;
loc += ('0 1 0' * random()) * 128 * iteration_scale;
tracebox(loc, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), loc, MOVE_NORMAL, player);
tracebox(loc, STAT(PL_MIN, player), STAT(PL_MAX, player), loc, MOVE_NORMAL, player);
if(trace_fraction == 1.0 && !trace_startsolid)
{
traceline(closest_target.origin, loc, MOVE_NOMONSTERS, closest_target); // double check to make sure we're not spawning outside the NULL
......@@ -1808,7 +1808,7 @@ MUTATOR_HOOKFUNCTION(ons, PlayerSpawn)
iteration_scale -= i / 10;
loc = closest_target.origin + '0 0 128' * iteration_scale;
loc += ('0 1 0' * random()) * 256 * iteration_scale;
tracebox(loc, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), loc, MOVE_NORMAL, player);
tracebox(loc, STAT(PL_MIN, player), STAT(PL_MAX, player), loc, MOVE_NORMAL, player);
if(trace_fraction == 1.0 && !trace_startsolid)
{
traceline(closest_target.origin, loc, MOVE_NOMONSTERS, closest_target); // double check to make sure we're not spawning outside the NULL
......
......@@ -14,3 +14,14 @@ string Item_Model(string item_mdl)
#endif
return output;
}
string Item_Sound(string it_snd)
{
string output = strcat("misc/", it_snd);
#ifdef SVQC
MUTATOR_CALLHOOK(ItemSound, it_snd, output);
return M_ARGV(1, string);
#else
return output;
#endif
}
......@@ -4,7 +4,7 @@
#include "item.qh"
REGISTRY(Items, BITS(5))
REGISTRY(Items, BITS(7))
#define Items_from(i) _Items_from(i, NULL)
REGISTER_REGISTRY(Items)
#define REGISTER_ITEM(id, class) REGISTER(Items, ITEM, id, m_id, NEW(class))
......
......@@ -15,17 +15,33 @@ ENDCLASS(Inventory)
REGISTER_NET_LINKED(ENT_CLIENT_INVENTORY)
const int Inventory_groups_major = 16;
const int Inventory_groups_minor = 8; // ceil(Items_MAX / Inventory_groups_major)
#define G_MAJOR(id) (floor((id) / Inventory_groups_minor))
#define G_MINOR(id) ((id) % Inventory_groups_minor)
#ifdef CSQC
NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew)
{
make_pure(this);
const int bits = ReadInt24_t();
FOREACH(Items, bits & BIT(it.m_id), {
.int fld = inv_items[it.m_id];
int prev = this.(fld);
int next = this.(fld) = ReadByte();
LOG_TRACEF("%s: %.0f -> %.0f", it.m_name, prev, next);
});
const int majorBits = ReadShort();
for (int i = 0; i < Inventory_groups_major; ++i) {
if (!(majorBits & BIT(i))) {
continue;
}
const int minorBits = ReadByte();
for (int j = 0; j < Inventory_groups_minor; ++j) {
if (!(minorBits & BIT(j))) {
continue;
}
const GameItem it = Items_from(Inventory_groups_minor * i + j);
.int fld = inv_items[it.m_id];
int prev = this.(fld);
int next = this.(fld) = ReadByte();
LOG_TRACEF("%s: %.0f -> %.0f", it.m_name, prev, next);
}
}
return true;
}
#endif
......@@ -34,22 +50,56 @@ NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew)
void Inventory_Write(Inventory data)
{
if (!data) {
WriteInt24_t(MSG_ENTITY, 0);
WriteShort(MSG_ENTITY, 0);
return;
}
TC(Inventory, data);
int bits = 0;
int majorBits = 0;
FOREACH(Items, true, {
.int fld = inv_items[it.m_id];
bits = BITSET(bits, BIT(it.m_id), data.inventory.(fld) != (data.inventory.(fld) = data.(fld)));
const bool changed = data.inventory.(fld) != data.(fld);
if (changed) {