- 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=6f94374cbd7ebda9ac951f92562022d8
+ - EXPECT=74f3802009cec230bdaa3b87235368ca
- HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
| tee /dev/stderr
| grep '^:'
seta hud_panel_weapons_ammo_full_plasma 180 "show 100% of the status bar at this ammo count"
seta hud_panel_weapons_ammo_full_rockets 160 "show 100% of the status bar at this ammo count"
seta hud_panel_weapons_ammo_full_fuel 100 "show 100% of the status bar at this ammo count"
+seta hud_panel_weapons_hide_ondeath 0 "hide this panel when dead"
seta hud_panel_ammo_maxammo "40" "when you have this much ammo, the ammo status bar is full"
+seta hud_panel_ammo_hide_ondeath 0 "hide this panel when dead"
+
+seta hud_panel_powerups_hide_ondeath 0 "hide this panel when dead"
seta hud_panel_healtharmor_maxhealth "200" "when you have this much health, the health status bar is full"
seta hud_panel_healtharmor_maxarmor "200" "when you have this much armor, the armor status bar is full"
seta hud_panel_healtharmor_progressbar_gfx_damage 5 "show damage effect when damaged at least by this amount; 0 disables the effect"
seta hud_panel_healtharmor_progressbar_gfx_lowhealth 40 "health progressbar blinks when health is lower than this amount"
+seta hud_panel_healtharmor_hide_ondeath 0 "hide this panel when dead"
seta hud_panel_timer_increment "0" "show elapsed time instead of remaining time"
set g_balance_shotgun_switchdelay_drop 0.2
set g_balance_shotgun_switchdelay_raise 0.2
set g_balance_shotgun_weaponreplace ""
-set g_balance_shotgun_weaponstart 0
+set g_balance_shotgun_weaponstart 1
set g_balance_shotgun_weaponstartoverride -1
set g_balance_shotgun_weaponthrowable 1
// }}}
set g_balance_hagar_primary_radius 65
set g_balance_hagar_primary_refire 0.16667
set g_balance_hagar_primary_speed 2200
-set g_balance_hagar_primary_spread 0.03
+set g_balance_hagar_primary_spread 0
set g_balance_hagar_reload_ammo 0
set g_balance_hagar_reload_time 2
set g_balance_hagar_secondary 1
set g_balance_shockwave_switchdelay_drop 0.2
set g_balance_shockwave_switchdelay_raise 0.2
set g_balance_shockwave_weaponreplace ""
-set g_balance_shockwave_weaponstart 1
+set g_balance_shockwave_weaponstart 0
set g_balance_shockwave_weaponstartoverride -1
set g_balance_shockwave_weaponthrowable 0
// }}}
bool autocvar_hud_panel_physics_dynamichud = true;
bool autocvar_hud_panel_centerprint_dynamichud = true;
bool autocvar_hud_panel_itemstime_dynamichud = true;
+bool autocvar_hud_panel_healtharmor_hide_ondeath = false;
+bool autocvar_hud_panel_ammo_hide_ondeath = false;
+bool autocvar_hud_panel_powerups_hide_ondeath = false;
+bool autocvar_hud_panel_weapons_hide_ondeath = false;
bool autocvar_hud_panel_ammo;
bool autocvar_hud_panel_ammo_iconalign;
int autocvar_hud_panel_ammo_maxammo;
string autocvar_hud_skin;
float autocvar_menu_mouse_speed;
string autocvar_menu_skin;
-float autocvar_r_drawviewmodel;
int autocvar_r_fakelight;
int autocvar_r_fullbright;
float autocvar_r_letterbox;
float autocvar_crosshair_rpc_alpha = 1;
float autocvar_crosshair_rpc_size = 1;
int autocvar_cl_nade_timer;
+bool autocvar_r_drawviewmodel;
bool autocvar_cl_items_nofade;
{
int i;
// global hud alpha fade (scoreboard-related panels behave differently and override it temporarly)
- if(menu_enabled == 1)
+ if(hud_configure_menu_open == 1)
hud_fade_alpha = 1;
else if(!autocvar__hud_configure)
hud_fade_alpha = (1 - scoreboard_fade_alpha) * (1 - autocvar__menu_alpha);
float teamnagger;
-float hud_configure_checkcollisions;
-float hud_configure_prev;
-vector hud_configure_gridSize;
-vector hud_configure_realGridSize;
-
int hudShiftState;
const int S_SHIFT = 1;
const int S_CTRL = 2;
const int S_ALT = 4;
-float menu_enabled; // 1 showing the entire HUD, 2 showing only the clicked panel
-
float hud_fade_alpha;
string hud_skin_path;
if (autocvar__hud_configure) { \
if (!panel_enabled) \
panel_bg_alpha = 0.25; \
- else if (menu_enabled == 2 && panel == highlightedPanel) \
+ else if (hud_configure_menu_open == 2 && panel == highlightedPanel) \
panel_bg_alpha = (1 - autocvar__menu_alpha) * max(cvar("hud_configure_bg_minalpha"), panel_bg_alpha) + autocvar__menu_alpha * panel_bg_alpha;\
else \
panel_bg_alpha = max(cvar("hud_configure_bg_minalpha"), panel_bg_alpha); \
// return smoothly faded pos and size of given panel when a dialog is active
// don't center too wide panels, it doesn't work with different resolutions
#define HUD_Panel_UpdatePosSize_ForMenu() MACRO_BEGIN { \
- vector menu_enable_size = panel_size; \
+ vector new_size = panel_size; \
float max_panel_width = 0.52 * vid_conwidth; \
if(panel_size.x > max_panel_width) \
{ \
- menu_enable_size.x = max_panel_width; \
- menu_enable_size.y = panel_size.y * (menu_enable_size.x / panel_size.x); \
+ new_size.x = max_panel_width; \
+ new_size.y = panel_size.y * (new_size.x / panel_size.x); \
} \
- vector menu_enable_pos = eX * (panel_bg_border + 0.5 * max_panel_width) + eY * 0.5 * vid_conheight - 0.5 * menu_enable_size; \
- panel_pos = (1 - autocvar__menu_alpha) * panel_pos + (autocvar__menu_alpha) * menu_enable_pos; \
- panel_size = (1 - autocvar__menu_alpha) * panel_size + (autocvar__menu_alpha) * menu_enable_size; \
+ vector new_pos = eX * (panel_bg_border + 0.5 * max_panel_width) + eY * 0.5 * vid_conheight - 0.5 * new_size; \
+ panel_pos = (1 - autocvar__menu_alpha) * panel_pos + (autocvar__menu_alpha) * new_pos; \
+ panel_size = (1 - autocvar__menu_alpha) * panel_size + (autocvar__menu_alpha) * new_size; \
} MACRO_END
// Scale the pos and size vectors to absolute coordinates
HUD_Panel_GetPadding(); \
panel.current_panel_bg_alpha = panel_bg_alpha; \
panel.current_panel_fg_alpha = panel_fg_alpha; \
- if (menu_enabled == 2 && panel == highlightedPanel) { \
+ if (hud_configure_menu_open == 2 && panel == highlightedPanel) { \
HUD_Panel_UpdatePosSize_ForMenu(); \
} else { \
panel_bg_alpha *= hud_fade_alpha; \
panel_pos = stov(cvar_string(strcat("hud_panel_", panel.panel_name, "_pos"))); \
panel_size = stov(cvar_string(strcat("hud_panel_", panel.panel_name, "_size"))); \
HUD_Panel_ScalePosSize(); \
- if (menu_enabled == 2 && panel == highlightedPanel) { \
+ if (hud_configure_menu_open == 2 && panel == highlightedPanel) { \
HUD_Panel_UpdatePosSize_ForMenu(); \
} \
panel_bg_border_str = cvar_string(strcat("hud_panel_", panel.panel_name, "_bg_border")); \
void HUD_Configure_Exit_Force()
{
- if (menu_enabled)
+ if (hud_configure_menu_open)
{
- menu_enabled = 0;
+ hud_configure_menu_open = 0;
localcmd("togglemenu\n");
}
cvar_set("_hud_configure", "0");
{
if (bInputType == 1)
return true;
- menu_enabled = 1;
+ hud_configure_menu_open = 1;
localcmd("menu_showhudexit\n");
}
else if(nPrimary == K_BACKSPACE && hudShiftState & S_CTRL)
{
if (bInputType == 1)
return true;
- if (!menu_enabled)
+ if (!hud_configure_menu_open)
cvar_set("_hud_configure", "0");
}
else if(nPrimary == K_TAB && hudShiftState & S_CTRL) // switch panel
void HUD_Panel_EnableMenu()
{
- menu_enabled = 2;
+ hud_configure_menu_open = 2;
localcmd("menu_showhudoptions ", highlightedPanel.panel_name, "\n");
}
float mouse_over_panel;
{
if(prevMouseClicked)
highlightedAction = 0;
- if(menu_enabled == 2)
+ if(hud_configure_menu_open == 2)
mouse_over_panel = 0;
else
mouse_over_panel = HUD_Panel_Check_Mouse_Pos(true);
if(autocvar__menu_alpha != _menu_alpha_prev)
{
if(autocvar__menu_alpha == 0)
- menu_enabled = 0;
+ hud_configure_menu_open = 0;
_menu_alpha_prev = autocvar__menu_alpha;
}
}
else if(hud_configure_prev)
{
- if(menu_enabled)
- menu_enabled = 0;
+ if(hud_configure_menu_open)
+ hud_configure_menu_open = 0;
if(autocvar_hud_cursormode)
setcursormode(0);
hud_dynamic_shake_factor = -1;
float prevMouseClickedTime; // time during previous left mouse click, to check for doubleclicks
vector prevMouseClickedPos; // pos during previous left mouse click, to check for doubleclicks
+float hud_configure_prev;
+float hud_configure_checkcollisions;
+vector hud_configure_gridSize;
+vector hud_configure_realGridSize;
+float hud_configure_menu_open; // 1 showing the entire HUD, 2 showing only the clicked panel
+
void HUD_Panel_ExportCfg(string cfgname);
void HUD_Panel_Mouse();
if(hud != HUD_NORMAL) return;
if(!autocvar__hud_configure)
{
- if(!autocvar_hud_panel_ammo) return;
- if(spectatee_status == -1) return;
+ if((!autocvar_hud_panel_ammo) || (spectatee_status == -1))
+ return;
+ if(STAT(HEALTH) < 1 && autocvar_hud_panel_ammo_hide_ondeath)
+ return;
}
HUD_Panel_UpdateCvars();
// this panel fades only when the menu does
float hud_fade_alpha_save = hud_fade_alpha;
- if(menu_enabled == 1)
+ if(hud_configure_menu_open == 1)
hud_fade_alpha = 1;
else
hud_fade_alpha = 1 - autocvar__menu_alpha;
int armor, health, fuel;
if(!autocvar__hud_configure)
{
- if(!autocvar_hud_panel_healtharmor) return;
+ if((!autocvar_hud_panel_healtharmor) || (spectatee_status == -1))
+ return;
if(hud != HUD_NORMAL) return;
- if(spectatee_status == -1) return;
health = STAT(HEALTH);
if(health <= 0)
{
+ health = 0;
prev_health = -1;
- return;
+ if(autocvar_hud_panel_healtharmor_hide_ondeath)
+ return;
}
armor = STAT(ARMOR);
- // code to check for spectatee_status changes is in Ent_ClientData()
+ // code to check for spectatee_status changes is in ENT_CLIENT_CLIENTDATA
// prev_p_health and prev_health can be set to -1 there
if (prev_p_health == -1)
// Initialize items
if(!autocvar__hud_configure)
{
- if(!autocvar_hud_panel_powerups) return;
- if(spectatee_status == -1) return;
- if(STAT(HEALTH) <= 0) return;
+ if((!autocvar_hud_panel_powerups) || (spectatee_status == -1))
+ 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;
strengthTime = bound(0, STAT(STRENGTH_FINISHED) - time, 99);
for(tm = teams.sort_next; tm; tm = tm.sort_next) {
if(tm.team == NUM_SPECTATOR)
continue;
- if(!tm.team && teamplay)
+ if(!tm.team)
continue;
+
if (tm.team == myteam)
drawfill(pos + eX * score_size * i, eX * score_size + eY * fontsize.y, '1 1 1', highlight_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
drawstring_aspect(pos + eX * score_size * i, ftos(tm.(teamscores(ts_primary))), eX * score_size + eY * fontsize.y, Team_ColorRGB(tm.team) * 0.8, panel_fg_alpha, DRAWFLAG_NORMAL);
for(tm = teams.sort_next; tm; tm = tm.sort_next) {
if(tm.team == NUM_SPECTATOR)
continue;
- if(!tm.team && teamplay)
+ if(!tm.team)
continue;
+
score = tm.(teamscores(ts_primary));
if(autocvar__hud_configure)
score = 123;
case "rank": return CTX(_("SCO^rank"));
case "returns": return CTX(_("SCO^returns"));
case "revivals": return CTX(_("SCO^revivals"));
+ case "rounds": return CTX(_("SCO^rounds won"));
case "score": return CTX(_("SCO^score"));
case "suicides": return CTX(_("SCO^suicides"));
case "takes": return CTX(_("SCO^takes"));
if (sbt_highlight)
if (!(i % 2))
{
- if (i == sbt_num_fields-1)
- column_dim.x = sbt_field_size[i] + hud_fontsize.x * 0.5;
- else
- column_dim.x = sbt_field_size[i] + hud_fontsize.x;
+ column_dim.x = sbt_field_size[i] + hud_fontsize.x;
drawfill(pos - eX * hud_fontsize.x * 0.5, column_dim, '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
}
TC(bool, is_self); TC(int, pl_number);
string str;
bool is_spec = (entcs_GetTeam(pl.sv_entnum) == NUM_SPECTATOR);
- if(is_spec && !is_self)
- rgb = '0 0 0';
vector h_pos = item_pos;
vector h_size = eX * panel_size.x + eY * hud_fontsize.y * 1.25;
// row highlighting
for (int i = 0; i < rows; ++i)
- drawfill(pos + eY * weapon_height + eY * height * i, eX * tmp.x + eY * fontsize, '1 1 1', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+ drawfill(pos + eY * weapon_height + eY * height * i, eX * tmp.x + eY * fontsize, rgb, sbt_highlight_alpha, DRAWFLAG_NORMAL);
}
average_accuracy = 0;
{
// frametime checks allow to toggle the scoreboard even when the game is paused
if(scoreboard_active) {
- if(menu_enabled == 1)
+ if(hud_configure_menu_open == 1)
scoreboard_fade_alpha = 1;
float scoreboard_fadeinspeed = autocvar_hud_panel_scoreboard_fadeinspeed;
if (scoreboard_fadeinspeed && frametime)
HUD_Scale_Disable();
float hud_fade_alpha_save = hud_fade_alpha;
- if(menu_enabled == 1)
+ if(hud_configure_menu_open == 1)
hud_fade_alpha = 1;
else
hud_fade_alpha = scoreboard_fade_alpha * (1 - autocvar__menu_alpha);
{
if(tm.team == NUM_SPECTATOR)
continue;
- if(!tm.team && teamplay)
+ if(!tm.team)
continue;
draw_beginBoldFont();
{
if(tm.team == NUM_SPECTATOR)
continue;
- if(!tm.team && teamplay)
- continue;
pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
}
if(pl.team != NUM_SPECTATOR)
continue;
pos.y += 1.25 * hud_fontsize.y;
- Scoreboard_DrawItem(pos, panel_bg_color, pl, (pl.sv_entnum == player_localnum), specs);
+ Scoreboard_DrawItem(pos, '0 0 0', pl, (pl.sv_entnum == player_localnum), specs);
++specs;
}
{
if((!autocvar_hud_panel_weapons) || (spectatee_status == -1))
return;
+ if(STAT(HEALTH) <= 0 && autocvar_hud_panel_weapons_hide_ondeath)
+ return;
if(timeout && time >= weapontime + timeout + timeout_effect_length)
if(autocvar_hud_panel_weapons_timeout_effect == 3 || (autocvar_hud_panel_weapons_timeout_effect == 1 && !(autocvar_hud_panel_weapons_timeout_fadebgmin + autocvar_hud_panel_weapons_timeout_fadefgmin)))
{
{
if(autocvar__hud_configure)
{
- if(menu_enabled != 2)
+ if(hud_configure_menu_open != 2)
HUD_Panel_DrawBg(1); // also draw the bg of the entire panel
}
float g_trueaim_minrange;
-float hud;
+int hud;
float view_quality;
int num_spectators;
/** is new to client */ i(bool, MUTATOR_ARGV_1_bool) \
/**/
MUTATOR_HOOKABLE(Ent_Update, EV_Ent_Update);
+
+/** Return true to not draw crosshair */
+MUTATOR_HOOKABLE(DrawCrosshair, EV_NO_ARGS);
float f, i, j;
vector v;
if(!scoreboard_active && !camera_active && intermission != 2 &&
- spectatee_status != -1 && !csqcplayer.viewloc &&
+ spectatee_status != -1 && !csqcplayer.viewloc && !MUTATOR_CALLHOOK(DrawCrosshair) &&
!HUD_MinigameMenu_IsOpened() )
{
if (!autocvar_crosshair_enabled) // main toggle for crosshair rendering
DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(NADE_TIMER), '0.25 0.90 1' + ('1 0 0' * STAT(NADE_TIMER)) - ('0 1 1' * STAT(NADE_TIMER)), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
drawstring_aspect(eY * 0.64 * vid_conheight, ((autocvar_cl_nade_timer == 2) ? _("Nade timer") : ""), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
}
+ else if(STAT(CAPTURE_PROGRESS))
+ {
+ DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(CAPTURE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+ drawstring_aspect(eY * 0.64 * vid_conheight, _("Capture progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
+ }
else if(STAT(REVIVE_PROGRESS))
{
DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
float oldr_useinfinitefarclip;
void cl_notice_run();
+
float prev_myteam;
int lasthud;
float vh_notice_time;
else if(csqcplayer.viewloc) { setproperty(VF_FOV, GetViewLocationFOV(110)); } // enforce 110 fov, so things dont look odd
else { setproperty(VF_FOV, GetCurrentFov(fov)); }
- // Camera for demo playback
- if(camera_active)
+ if(camera_active) // Camera for demo playback
{
if(autocvar_camera_enable)
CSQC_Demo_Camera();
round_handler_Init(7, autocvar_g_onslaught_warmup, autocvar_g_onslaught_round_timelimit);
FOREACH_CLIENT(IS_PLAYER(it), {
- it.ons_roundlost = true;
+ STAT(ROUNDLOST, it) = true;
it.player_blocked = true;
nades_Clear(it);
MUTATOR_HOOKFUNCTION(ons, reset_map_global)
{
FOREACH_CLIENT(IS_PLAYER(it), {
- it.ons_roundlost = false;
+ STAT(ROUNDLOST, it) = false;
it.ons_deathloc = '0 0 0';
PutClientInServer(it);
});
entity spectatee = M_ARGV(0, entity);
entity client = M_ARGV(1, entity);
- client.ons_roundlost = spectatee.ons_roundlost; // make spectators see it too
+ STAT(ROUNDLOST, client) = STAT(ROUNDLOST, spectatee); // make spectators see it too
}
MUTATOR_HOOKFUNCTION(ons, SV_ParseClientCommand)
.float teleport_antispam;
-.bool ons_roundlost = _STAT(ROUNDLOST);
-
// waypoint sprites
.entity bot_basewaypoint; // generator waypointsprite
|| (SAME_TEAM(targ, this))
|| (STAT(FROZEN, targ))
|| (targ.alpha != 0 && targ.alpha < 0.5)
+ || (MUTATOR_CALLHOOK(MonsterValidTarget, this, targ))
)
{
// if any of the above checks fail, target is not valid
if(IS_PLAYER(player))
if(IS_REAL_CLIENT(player)) // bots may camp, but that's no reason to constantly kill them
if(!IS_DEAD(player))
+ if(!forbidWeaponUse(player))
if(!STAT(FROZEN, player))
if(!PHYS_INPUT_BUTTON_CHAT(player))
if(autocvar_g_campcheck_interval)
if (autocvar_hud_panel_itemstime_dynamicsize)
{
if (autocvar__hud_configure)
- if (menu_enabled != 2)
+ if (hud_configure_menu_open != 2)
HUD_Panel_DrawBg(1); // also draw the bg of the entire panel
// reduce panel to avoid spacing items
if(it.msnt_timer < time)
if(SAME_TEAM(player, it))
if(time > it.spawnshieldtime) // spawn shielding
+ if(!forbidWeaponUse(it))
if(STAT(FROZEN, it) == 0)
if(it != player)
{
#include "sound.qh"
-REGISTRY(Sounds, BITS(8))
+REGISTRY(Sounds, BITS(9))
#define Sounds_from(i) _Sounds_from(i, SND_Null)
REGISTER_REGISTRY(Sounds)
REGISTER_STAT(ROUNDLOST, int)
REGISTER_STAT(BUFF_TIME, float)
REGISTER_STAT(CTF_FLAGSTATUS, int)
+REGISTER_STAT(CAPTURE_PROGRESS, float)
REGISTER_STAT(ENTRAP_ORB, float)
REGISTER_STAT(ENTRAP_ORB_ALPHA, float)
REGISTER_STAT(ITEMSTIME, int, autocvar_sv_itemstime)
}
#endif
+
/*
==============================
SUB_UseTargets
==============================
*/
-void SUB_UseTargets(entity this, entity actor, entity trigger)
+
+void SUB_UseTargets_Ex(entity this, entity actor, entity trigger, bool preventReuse)
{
//
// check for a delay
int aw_flag = this.antiwall_flag;
for(entity t = NULL; (t = find(t, targetname, s)); )
{
- if(t.use)
+ if(t.use && (t.sub_target_used != time || !preventReuse))
{
if(this.target_random)
{
t.antiwall_flag = aw_flag;
t.use(t, actor, this);
+ if(preventReuse)
+ t.sub_target_used = time;
}
}
}
}
if(this.target_random && RandomSelection_chosen_ent)
+ {
RandomSelection_chosen_ent.use(RandomSelection_chosen_ent, actor, this);
+ if(preventReuse)
+ RandomSelection_chosen_ent.sub_target_used = time;
+ }
}
+void SUB_UseTargets(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, false); }
+void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger) { SUB_UseTargets_Ex(this, actor, trigger, true); }
+
void SUB_UseTargets_self(entity this)
{
SUB_UseTargets(this, NULL, NULL);
void target_voicescript_next(entity pl);
void target_voicescript_clear(entity pl);
+
+void SUB_UseTargets_PreventReuse(entity this, entity actor, entity trigger);
#endif
+.float sub_target_used;
+
.float volume, atten;
.vector dest;
CLASS(Shockwave, Weapon)
/* ammotype */ //ATTRIB(Shockwave, ammo_field, .int, ammo_none);
/* impulse */ ATTRIB(Shockwave, impulse, int, 2);
-/* flags */ ATTRIB(Shockwave, spawnflags, int, WEP_FLAG_NORMAL | WEP_TYPE_HITSCAN | WEP_FLAG_CANCLIMB | WEP_TYPE_MELEE_SEC);
+/* flags */ ATTRIB(Shockwave, spawnflags, int, WEP_TYPE_HITSCAN | WEP_FLAG_CANCLIMB | WEP_TYPE_MELEE_SEC);
/* rating */ ATTRIB(Shockwave, bot_pickupbasevalue, float, BOT_PICKUP_RATING_LOW);
/* color */ ATTRIB(Shockwave, wpcolor, vector, '0.5 0.25 0');
/* modelname */ ATTRIB(Shockwave, mdl, string, "shotgun");
float(string url, float id, string content_type, string delim, float buf, float keyid) crypto_uri_postbuf = #513;
//description:
//use -1 as buffer handle to justs end delim as postdata
+
+//DP_USERMOVETYPES
+//idea: divVerent
+//darkplaces implementation: Mario
+//movetype definitions:
+float MOVETYPE_USER_FIRST = 128;
+float MOVETYPE_USER_LAST = 191;
+//description:
+//user defined movetypes can be added between the start and end points, without producing unknown movetype warnings
CSQCModel_Hook_PreDraw(this, isplayer);
+ if(isplayer)
+ {
+ if(this.entnum == player_localentnum)
+ this.renderflags |= RF_EXTERNALMODEL;
+ else
+ this.renderflags &= ~RF_EXTERNALMODEL;
+ }
+
// inherit draw flags easily
entity root = this;
while(root.tag_entity)
#define MISSILE_IS_GUIDED(m) ((m.missile_flags & MIF_GUIDED_ALL) ? true : false)
#define MISSILE_IS_TRACKING(m) ((m.missile_flags & MIF_GUIDED_TRACKING) ? true : false)
-
////
.entity player_stats;
return "Map switch will happen after scoreboard.";
}
+bool autocvar_sv_gameplayfix_multiplethinksperframe;
+void RunThink(entity this)
+{
+ // don't let things stay in the past.
+ // it is possible to start that way by a trigger with a local time.
+ if(this.nextthink <= 0 || this.nextthink > time + frametime)
+ return;
+
+ float oldtime = time; // do we need to save this?
+
+ for (int iterations = 0; iterations < 128 && !wasfreed(this); iterations++)
+ {
+ time = max(oldtime, this.nextthink);
+ this.nextthink = 0;
+
+ if(getthink(this))
+ getthink(this)(this);
+ // mods often set nextthink to time to cause a think every frame,
+ // we don't want to loop in that case, so exit if the new nextthink is
+ // <= the time the qc was told, also exit if it is past the end of the
+ // frame
+ if(this.nextthink <= time || this.nextthink > oldtime + frametime || !autocvar_sv_gameplayfix_multiplethinksperframe)
+ break;
+ }
+
+ time = oldtime;
+}
+
bool autocvar_sv_freezenonclients;
bool autocvar_sv_gameplayfix_delayprojectiles;
void Physics_Frame()
if(it.move_qcphysics)
Movetype_Physics_NoMatchTicrate(it, PHYS_INPUT_TIMELENGTH, false);
+
+ if(it.movetype >= MOVETYPE_USER_FIRST && it.movetype <= MOVETYPE_USER_LAST) // these cases have no think handling
+ {
+ // handle thinking here
+ if (getthink(it) && it.nextthink > 0 && it.nextthink <= time + frametime)
+ RunThink(it);
+ }
});
if(autocvar_sv_gameplayfix_delayprojectiles >= 0)
}
if (autocvar_sv_eventlog_console)
{
- LOG_INFO(s, "\n");
+ dedicated_print(strcat(s, "\n"));
}
}
/** called when a monster looks for another target */
MUTATOR_HOOKABLE(MonsterFindTarget, EV_NO_ARGS);
+/**
+ * called when validating a monster's target
+ */
+#define EV_MonsterValidTarget(i, o) \
+ /** monster */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** target */ i(entity, MUTATOR_ARGV_1_entity) \
+ /**/
+MUTATOR_HOOKABLE(MonsterValidTarget, EV_MonsterValidTarget);
+
/** called to change a random monster to a miniboss */
#define EV_MonsterCheckBossFlag(i, o) \
/** monster */ i(entity, MUTATOR_ARGV_0_entity) \
/** data */ i(string, MUTATOR_ARGV_2_string) \
/**/
MUTATOR_HOOKABLE(URI_GetCallback, EV_URI_GetCallback);
+
+/**
+ * return true to prevent weapon use for a player
+ */
+ #define EV_ForbidWeaponUse(i, o) \
+ /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /**/
+MUTATOR_HOOKABLE(ForbidWeaponUse, EV_ForbidWeaponUse);
+
+/** called when a player spawns as player, after shared setup, before his weapon is chosen (so items may be changed in here) */
+#define EV_CopyBody(i, o) \
+ /** player */ i(entity, MUTATOR_ARGV_0_entity) \
+ /** newly created clone */ i(entity, MUTATOR_ARGV_1_entity) \
+ /** keepvelocity? */ i(bool, MUTATOR_ARGV_2_bool) \
+ /**/
+MUTATOR_HOOKABLE(CopyBody, EV_CopyBody);
// misc globals
float domination_roundbased;
float domination_teams;
+
+void AnimateDomPoint(entity this);
// "bake" the current animation frame for clones (they don't get clientside animation)
animdecide_load_if_needed(clone);
animdecide_setframes(clone, false, frame, frame1time, frame2, frame2time);
+
+ MUTATOR_CALLHOOK(CopyBody, this, clone, keepvelocity);
}
void player_setupanimsformodel(entity this)
void CopyBody_Think(entity this);
void CopyBody(entity this, float keepvelocity);
+void dedicated_print(string input);
+
void player_setupanimsformodel(entity this);
void player_anim(entity this);
return normalize(leftwish + rightwish + frontwish);
}
-float beamsweep_badpoint(vector point,float waterok)
+bool beamsweep_badpoint(vector point, bool waterok)
{
- float pc,pc2;
-
if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
- return 1;
-
- pc = pointcontents(point);
- pc2 = pointcontents(point - '0 0 1');
-
- switch(pc)
+ return true;
+
+ int pc = pointcontents(point);
+ int pc2 = pointcontents(point - '0 0 1');
+
+ if(pc == CONTENT_EMPTY && pc2 == CONTENT_SOLID)
+ return false;
+ if(pc == CONTENT_EMPTY && pc2 == CONTENT_WATER && waterok)
+ return false;
+ if(pc == CONTENT_WATER && waterok)
+ return false;
+ return true;
+
+ /*switch(pc)
{
case CONTENT_SOLID: break;
case CONTENT_SLIME: break;
case CONTENT_LAVA: break;
case CONTENT_SKY:
- return 1;
+ return true;
case CONTENT_EMPTY:
if (pc2 == CONTENT_SOLID)
break;
}
- return 1;
+ return true;*/
}
//#define BEAMSTEER_VISUAL
float beamsweep(entity this, vector from, vector dir,float length, float step,float step_up, float step_down)
{
float i;
- vector a,b,u,d;
+ vector a, b, u, d;
u = '0 0 1' * step_up;
d = '0 0 1' * step_down;
if(bm_left + bm_right < 0.15)
{
- vr = normalize((v_forward*-1) + v_right * 0.75);
- vl = normalize((v_forward*-1) - v_right * 0.75);
+ vr = normalize((v_forward*-1) + v_right * 0.90);
+ vl = normalize((v_forward*-1) - v_right * 0.90);
bm_right = beamsweep(this, this.origin, vr, length, step, step_up, step_down);
bm_left = beamsweep(this, this.origin, vl, length, step, step_up, step_down);
{
if(autocvar_g_campaign && pl && IS_REAL_CLIENT(pl))
return 1; // special case for campaign and player joining
- else
- error(sprintf("Too few teams available for %s\n", MapInfo_Type_ToString(MapInfo_CurrentGametype())));
+ else if(totalteams == 1) // single team
+ LOG_TRACEF("Only 1 team available for %s, you may need to fix your map", MapInfo_Type_ToString(MapInfo_CurrentGametype()));
+ else // no teams, major no no
+ error(sprintf("No teams available for %s\n", MapInfo_Type_ToString(MapInfo_CurrentGametype())));
}
// count how many players are in each team
// make sure you call makevectors first (FIXME?)
void W_SetupShot_Dir_ProjectileSize_Range(entity ent, .entity weaponentity, vector s_forward, vector mi, vector ma, float antilag, float recoil, Sound snd, float chan, float maxdamage, float range)
{
- TC(Sound, snd);
+ TC(Sound, snd);
float nudge = 1; // added to traceline target and subtracted from result TOOD(divVerent): do we still need this? Doesn't the engine do this now for us?
float oldsolid;
vector vecs, dv;
break;
float dist_taken = max(autocvar_g_ballistics_mindistance, vlen(trace_endpos - start));
- solid_penetration_left *= (dist_taken / maxdist);
+ // fraction_used_of_what_is_left = dist_taken / maxdist
+ // solid_penetration_left = solid_penetration_left - solid_penetration_left * fraction_used_of_what_is_left
+ solid_penetration_left *= 1 - dist_taken / maxdist;
+ solid_penetration_left = max(solid_penetration_left, 0);
// Only show effect when going through a player (invisible otherwise)
if (hit && (hit.solid != SOLID_BSP))
if (gameover) return true;
if (STAT(FROZEN, player)) return true;
if (player.weapon_blocked) return true;
+ if (MUTATOR_CALLHOOK(ForbidWeaponUse, player)) return true;
return false;
}
vector CL_Weapon_GetShotOrg(float wpn);
-float forbidWeaponUse(entity player);
+bool forbidWeaponUse(entity player);
void W_AttachToShotorg(entity actor, .entity weaponentity, entity flash, vector offset);