Commit a692581c authored by terencehill's avatar terencehill

Merge branch 'master' into terencehill/bot_waypoints

parents 67640b08 d9ddf453
Pipeline #33888902 failed with stage
in 12 minutes and 1 second
......@@ -29,7 +29,7 @@ test_sv_game:
- 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=c2ae476e90317feda0756669a21ce1e7
- EXPECT=bb534e81ce09934ceadfd952a8ecd016
- HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
| tee /dev/stderr
| grep '^:'
......
......@@ -159,11 +159,11 @@ seta hud_damage_pain_threshold_lower_health 50 "at which health we start lowerin
seta hud_damage_pain_threshold_pulsating_min 0.6 "minimum value when calculating the pulse: max(pulsating_min, fabs(sin(PI * time / period))"
seta hud_damage_pain_threshold_pulsating_period 0.8 "one pulse every X seconds"
seta hud_powerup 0 "power of the sharpen effect when owning the shield or strength powerups, default is 0.5"
seta hud_powerup 0 "power of the sharpen effect when owning the shield or strength powerups"
seta hud_postprocessing 1 "enables the ability for effects such as hud_damage_blur and hud_contents to apply a postprocessing method upon the screen - enabling this disables manual editing of the postprocess cvars"
seta hud_postprocessing_maxbluralpha 0 "maximum alpha which the blur postprocess can be, default is 0.5"
seta hud_postprocessing_maxblurradius 8 "maximum radius which the blur postprocess can be, default is 8"
seta hud_postprocessing_maxbluralpha 0 "maximum alpha which the blur postprocess can be"
seta hud_postprocessing_maxblurradius 8 "maximum radius which the blur postprocess can be"
seta hud_contents 1 "an improved version of gl_polyblend for liquids such as water/lava/slime, draw a filler when inside the liquid"
seta hud_contents_blur 10 "Use postprocessing to blur the screen when you are inside a liquid. Higher values = more blur"
......
......@@ -60,8 +60,8 @@ set g_balance_shotgun_secondary_alt_animtime 0.2
set g_balance_shotgun_secondary_alt_refire 1.2
set g_balance_shotgun_switchdelay_drop 0.2
set g_balance_shotgun_switchdelay_raise 0.2
set g_balance_shotgun_weaponreplace "shockwave"
set g_balance_shotgun_weaponstart 0
set g_balance_shotgun_weaponreplace ""
set g_balance_shotgun_weaponstart 1
set g_balance_shotgun_weaponstartoverride -1
set g_balance_shotgun_weaponthrowable 1
// }}}
......@@ -260,9 +260,9 @@ set g_balance_crylink_secondary_ammo 3
set g_balance_crylink_secondary_animtime 0.2
set g_balance_crylink_secondary_bouncedamagefactor 0.5
set g_balance_crylink_secondary_bounces 0
set g_balance_crylink_secondary_damage 50
set g_balance_crylink_secondary_edgedamage 15
set g_balance_crylink_secondary_force -400
set g_balance_crylink_secondary_damage 10
set g_balance_crylink_secondary_edgedamage 5
set g_balance_crylink_secondary_force -200
set g_balance_crylink_secondary_joindelay 0
set g_balance_crylink_secondary_joinexplode 0
set g_balance_crylink_secondary_joinexplode_damage 0
......@@ -270,17 +270,17 @@ set g_balance_crylink_secondary_joinexplode_edgedamage 0
set g_balance_crylink_secondary_joinexplode_force 0
set g_balance_crylink_secondary_joinexplode_radius 0
set g_balance_crylink_secondary_joinspread 0
set g_balance_crylink_secondary_linkexplode 1
set g_balance_crylink_secondary_linkexplode 0
set g_balance_crylink_secondary_middle_fadetime 5
set g_balance_crylink_secondary_middle_lifetime 5
set g_balance_crylink_secondary_other_fadetime 5
set g_balance_crylink_secondary_other_lifetime 5
set g_balance_crylink_secondary_radius 70
set g_balance_crylink_secondary_refire 0.8
set g_balance_crylink_secondary_shots 1
set g_balance_crylink_secondary_speed 3000
set g_balance_crylink_secondary_spread 0
set g_balance_crylink_secondary_spreadtype 1
set g_balance_crylink_secondary_other_fadetime 2
set g_balance_crylink_secondary_other_lifetime 2
set g_balance_crylink_secondary_radius 100
set g_balance_crylink_secondary_refire 0.65
set g_balance_crylink_secondary_shots 5
set g_balance_crylink_secondary_speed 7000
set g_balance_crylink_secondary_spread 0.08
set g_balance_crylink_secondary_spreadtype 0
set g_balance_crylink_switchdelay_drop 0.2
set g_balance_crylink_switchdelay_raise 0.2
set g_balance_crylink_weaponreplace ""
......@@ -725,7 +725,7 @@ set g_balance_shockwave_melee_traces 10
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
// }}}
......@@ -753,10 +753,10 @@ set g_balance_arc_beam_heat 0
set g_balance_arc_burst_heat 5
set g_balance_arc_beam_maxangle 10
set g_balance_arc_beam_nonplayerdamage 80
set g_balance_arc_beam_range 1250
set g_balance_arc_beam_range 1500
set g_balance_arc_beam_refire 0.25
set g_balance_arc_beam_returnspeed 8
set g_balance_arc_beam_tightness 0.5
set g_balance_arc_beam_tightness 0.6
set g_balance_arc_bolt 1
set g_balance_arc_bolt_ammo 1
set g_balance_arc_bolt_damage 25
......@@ -883,7 +883,7 @@ set g_balance_okmachinegun_primary_ammo 1
set g_balance_okmachinegun_primary_damage 25
set g_balance_okmachinegun_primary_force 5
set g_balance_okmachinegun_primary_refire 0.1
set g_balance_okmachinegun_primary_solidpenetration 13.1
set g_balance_okmachinegun_primary_solidpenetration 63
set g_balance_okmachinegun_primary_spread_add 0.012
set g_balance_okmachinegun_primary_spread_max 0.05
set g_balance_okmachinegun_primary_spread_min 0
......
......@@ -9,7 +9,7 @@ cl_playerdetailreduction 4
gl_flashblend 0
gl_picmip 0
gl_texturecompression_2d 0
gl_texturecompression_sky 1
gl_texturecompression_sky 0
mod_q3bsp_nolightmaps 0
r_bloom 0
r_coronas 1
......
......@@ -118,7 +118,7 @@ void HUD_InfoMessages()
MUTATOR_CALLHOOK(DrawInfoMessages, pos, mySize);
if(!warmup_stage && gametype == MAPINFO_TYPE_LMS)
if(!warmup_stage && ISGAMETYPE(LMS))
{
entity sk;
sk = playerslots[player_localnum];
......
......@@ -54,9 +54,9 @@ void HUD_Mod_CA(vector myPos, vector mySize)
mod_active = 1; // required in each mod function that always shows something
int layout;
if(gametype == MAPINFO_TYPE_CA)
if(ISGAMETYPE(CA))
layout = autocvar_hud_panel_modicons_ca_layout;
else //if(gametype == MAPINFO_TYPE_FREEZETAG)
else //if(ISGAMETYPE(FREEZETAG))
layout = autocvar_hud_panel_modicons_freezetag_layout;
int rows, columns;
float aspect_ratio;
......@@ -528,7 +528,7 @@ void HUD_Mod_Race(vector pos, vector mySize)
// clientside personal record
string rr;
if(gametype == MAPINFO_TYPE_CTS)
if(ISGAMETYPE(CTS))
rr = CTS_RECORD;
else
rr = RACE_RECORD;
......
......@@ -18,7 +18,7 @@ void HUD_Physics()
{
if(!autocvar_hud_panel_physics) return;
if(spectatee_status == -1 && (autocvar_hud_panel_physics == 1 || autocvar_hud_panel_physics == 3)) return;
if(autocvar_hud_panel_physics == 3 && !(gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_CTS)) return;
if(autocvar_hud_panel_physics == 3 && !(ISGAMETYPE(RACE) || ISGAMETYPE(CTS))) return;
}
HUD_Panel_LoadCvars();
......
......@@ -98,7 +98,7 @@ void HUD_RaceTimer ()
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_racetimer) return;
if(!(gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_CTS)) return;
if(!(ISGAMETYPE(RACE) || ISGAMETYPE(CTS))) return;
if(spectatee_status == -1) return;
}
......
......@@ -343,7 +343,7 @@ void HUD_Radar()
IL_EACH(g_radaricons, it.teamradar_icon, {
if ( hud_panel_radar_mouse )
if ( GetResourceAmount(it, RESOURCE_HEALTH) >= 0 )
if ( it.team == myteam + 1 || gametype == MAPINFO_TYPE_RACE || !teamplay )
if ( it.team == myteam + 1 || ISGAMETYPE(RACE) || !teamplay )
{
vector coord = teamradar_texcoord_to_2dcoord(teamradar_3dcoord_to_texcoord(it.origin));
if(vdist((mousepos - coord), <, 8))
......
......@@ -140,7 +140,7 @@ void HUD_Score()
if(!autocvar__hud_configure)
{
if(!autocvar_hud_panel_score) return;
if(spectatee_status == -1 && (gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_CTS)) return;
if(spectatee_status == -1 && (ISGAMETYPE(RACE) || ISGAMETYPE(CTS))) return;
}
HUD_Panel_LoadCvars();
......
......@@ -1145,7 +1145,7 @@ bool Scoreboard_WouldDraw()
return true;
else if (intermission == 2)
return false;
else if (spectatee_status != -1 && STAT(HEALTH) <= 0 && autocvar_cl_deathscoreboard && gametype != MAPINFO_TYPE_CTS && !active_minigame)
else if (spectatee_status != -1 && STAT(HEALTH) <= 0 && autocvar_cl_deathscoreboard && !ISGAMETYPE(CTS) && !active_minigame)
return true;
else if (scoreboard_showscores_force)
return true;
......@@ -1404,7 +1404,7 @@ vector Scoreboard_Rankings_Draw(vector pos, entity pl, vector rgb, vector bg_siz
vector hl_rgb = rgb + '0.5 0.5 0.5';
pos.y += hud_fontsize.y;
drawstring(pos + eX * panel_bg_padding, ((gametype == MAPINFO_TYPE_CTF) ? _("Capture time rankings") : _("Rankings")), hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
drawstring(pos + eX * panel_bg_padding, ((ISGAMETYPE(CTF)) ? _("Capture time rankings") : _("Rankings")), hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
pos.y += 1.25 * hud_fontsize.y;
if(panel.current_panel_bg != "0")
pos.y += panel_bg_border;
......@@ -1498,7 +1498,7 @@ float scoreboard_time;
bool have_weapon_stats;
bool Scoreboard_AccuracyStats_WouldDraw(float ypos)
{
if (gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_NEXBALL)
if (ISGAMETYPE(CTS) || ISGAMETYPE(RACE) || ISGAMETYPE(NEXBALL))
return false;
if (!autocvar_hud_panel_scoreboard_accuracy || warmup_stage || ypos > 0.91 * vid_conheight)
return false;
......@@ -1666,7 +1666,7 @@ void Scoreboard_Draw()
if (Scoreboard_AccuracyStats_WouldDraw(pos.y))
pos = Scoreboard_AccuracyStats_Draw(pos, panel_bg_color, bg_size);
if(gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE || (autocvar_hud_panel_scoreboard_ctf_leaderboard && gametype == MAPINFO_TYPE_CTF && STAT(CTF_SHOWLEADERBOARD))) {
if(ISGAMETYPE(CTS) || ISGAMETYPE(RACE) || (autocvar_hud_panel_scoreboard_ctf_leaderboard && ISGAMETYPE(CTF) && STAT(CTF_SHOWLEADERBOARD))) {
if(race_speedaward) {
drawcolorcodedstring(pos, sprintf(_("Speed award: %d%s ^7(%s^7)"), race_speedaward, race_speedaward_unit, ColorTranslateRGB(race_speedaward_holder)), hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
pos.y += 1.25 * hud_fontsize.y;
......@@ -1707,7 +1707,7 @@ void Scoreboard_Draw()
tl = STAT(TIMELIMIT);
fl = STAT(FRAGLIMIT);
ll = STAT(LEADLIMIT);
if(gametype == MAPINFO_TYPE_LMS)
if(ISGAMETYPE(LMS))
{
if(tl > 0)
str = strcat(str, sprintf(_(" for up to ^1%1.0f minutes^7"), tl));
......
......@@ -9,7 +9,7 @@
void HUD_Vote()
{
if(autocvar_cl_allow_uid2name == -1 && (gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE || (serverflags & SERVERFLAG_PLAYERSTATS)))
if(autocvar_cl_allow_uid2name == -1 && (ISGAMETYPE(CTS) || ISGAMETYPE(RACE) || (serverflags & SERVERFLAG_PLAYERSTATS)))
{
// this dialog gets overriden by the uid2name menu dialog, if it exists
// TODO remove this client side uid2name dialog in the next release
......
......@@ -140,6 +140,9 @@ void CSQC_Init()
registercvar("cl_spawn_near_teammate", "1");
registercvar("cl_weapon_switch_reload", "1");
registercvar("cl_weapon_switch_fallback_to_impulse", "1");
if(autocvar_cl_lockview)
cvar_set("cl_lockview", "0");
......
......@@ -11,6 +11,8 @@ string minimapname;
bool postinit;
entity gametype;
// temporary hack
#define ISGAMETYPE(NAME) (gametype == MAPINFO_TYPE_##NAME)
float FONT_USER = 8;
......
......@@ -128,7 +128,7 @@ void Draw_ShowNames(entity this)
// FIXME: alpha is negative when dead, breaking death fade
if (!this.csqcmodel_isdead) a *= f;
}
if (a < ALPHA_MIN_VISIBLE && gametype != MAPINFO_TYPE_CTS) return;
if (a < ALPHA_MIN_VISIBLE && ISGAMETYPE(CTS)) return;
if (vdist(this.origin - view_origin, >=, max_shot_distance)) return;
float dist = vlen(this.origin - view_origin);
if (autocvar_hud_shownames_maxdistance)
......
......@@ -1539,7 +1539,7 @@ void HUD_Draw(entity this)
if(autocvar_r_letterbox == 0)
if(autocvar_viewsize < 120)
{
if(!(gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_CTS))
if(!(ISGAMETYPE(RACE) || ISGAMETYPE(CTS)))
Accuracy_LoadLevels();
HUD_Main();
......@@ -2467,7 +2467,7 @@ void CSQC_UpdateView(entity this, float w, float h)
else if(cvar("r_glsl_postprocess") == 2)
cvar_set("r_glsl_postprocess", "0");
/*if(gametype == MAPINFO_TYPE_CTF)
/*if(ISGAMETYPE(CTF))
{
ctf_view();
} else */
......
......@@ -41,5 +41,8 @@ void(entity bot) havocbot_ast_reset_role;
void(entity this, float ratingscale, vector org, float sradius) havocbot_goalrating_items;
void(entity this, float ratingscale, vector org, float sradius) havocbot_goalrating_enemyplayers;
// assault game mode: Which team is attacking in this round?
float assault_attacker_team;
// predefined spawnfuncs
void target_objective_decrease_activate(entity this);
......@@ -7,7 +7,7 @@ REGISTER_MUTATOR(cl_nb, true);
MUTATOR_HOOKFUNCTION(cl_nb, WantEventchase)
{
if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WEPSET(NEXBALL)))
if(autocvar_cl_eventchase_nexball && ISGAMETYPE(NEXBALL) && !(WepSet_GetFromStat() & WEPSET(NEXBALL)))
return true;
return false;
}
......
......@@ -424,27 +424,7 @@ void _MapInfo_Map_Reset()
string _MapInfo_GetDefault(Gametype t)
{
switch(t)
{
case MAPINFO_TYPE_DEATHMATCH: return "30 20 0";
case MAPINFO_TYPE_TEAM_DEATHMATCH: return "50 20 2 0";
case MAPINFO_TYPE_DOMINATION: return "200 20 0";
case MAPINFO_TYPE_CTF: return "300 20 10 0";
case MAPINFO_TYPE_LMS: return "9 20 0";
case MAPINFO_TYPE_CA: return "10 20 0";
case MAPINFO_TYPE_KEYHUNT: return "1000 20 3 0";
case MAPINFO_TYPE_ASSAULT: return "20 0";
case MAPINFO_TYPE_RACE: return "20 5 7 15 0";
case MAPINFO_TYPE_ONSLAUGHT: return "20 0";
case MAPINFO_TYPE_NEXBALL: return "5 20 0";
case MAPINFO_TYPE_CTS: return "20 0 0";
case MAPINFO_TYPE_FREEZETAG: return "10 20 0";
// NOTE: DO NOT ADD ANY MORE GAME TYPES HERE
// THIS IS JUST LEGACY SUPPORT FOR NEXUIZ MAPS
// ONLY ADD NEW STUFF TO _MapInfo_GetDefaultEx
// THIS FUNCTION WILL EVENTUALLY BE REMOVED
default: return "";
}
return t.m_legacydefaults;
}
void _MapInfo_Map_ApplyGametype(string s, Gametype pWantedType, Gametype pThisType, int load_default)
......@@ -457,7 +437,7 @@ void _MapInfo_Map_ApplyGametype(string s, Gametype pWantedType, Gametype pThisTy
if(load_default)
_MapInfo_Map_ApplyGametype(_MapInfo_GetDefault(pThisType), pWantedType, pThisType, false);
if(pWantedType == MAPINFO_TYPE_ASSAULT || pWantedType == MAPINFO_TYPE_ONSLAUGHT || pWantedType == MAPINFO_TYPE_RACE || pWantedType == MAPINFO_TYPE_CTS) // these modes don't use fraglimit
if(!pWantedType.frags) // these modes don't use fraglimit
{
cvar_set("fraglimit", "0");
}
......@@ -485,6 +465,8 @@ void _MapInfo_Map_ApplyGametype(string s, Gametype pWantedType, Gametype pThisTy
// rc = timelimit timelimit_qualification laps laps_teamplay
if(pWantedType == MAPINFO_TYPE_RACE)
{
cvar_set("fraglimit", "0"); // special case!
sa = car(s); if(sa == "") sa = cvar_string("timelimit");
cvar_set("g_race_qualifying_timelimit", sa);
s = cdr(s);
......@@ -502,7 +484,7 @@ void _MapInfo_Map_ApplyGametype(string s, Gametype pWantedType, Gametype pThisTy
s = cdr(s);
}
if(pWantedType == MAPINFO_TYPE_ASSAULT || pWantedType == MAPINFO_TYPE_ONSLAUGHT || pWantedType == MAPINFO_TYPE_CTS) // these modes don't use fraglimit
if(!pWantedType.frags) // these modes don't use fraglimit
{
cvar_set("leadlimit", "0");
}
......@@ -742,22 +724,19 @@ void _MapInfo_Parse_Settemp(string pFilename, string acl, float type, string s,
float MapInfo_isRedundant(string fn, string t)
{
// normalize file name
fn = strreplace("_", "-", fn);
fn = strreplace("_", "", fn);
fn = strreplace("-", "", fn);
// normalize visible title
t = strreplace(": ", "-", t);
t = strreplace(":", "-", t);
t = strreplace(" ", "-", t);
t = strreplace("_", "-", t);
t = strreplace("'", "-", t);
if(!strcasecmp(fn, t))
return true;
t = strreplace(":", "", t);
t = strreplace(" ", "", t);
t = strreplace("_", "", t);
t = strreplace("-", "", t);
t = strreplace("'", "", t);
t = strdecolorize(t);
// we allow the visible title to have punctuation the file name does
// not, but not vice versa
t = strreplace("-", "", t);
if(!strcasecmp(fn, t))
return true;
......
This diff is collapsed.
......@@ -1103,7 +1103,8 @@ void spawn_held_nade(entity player, entity nowner, float ntime, int ntype, strin
n.alpha = Nades_from(STAT(NADE_BONUS_TYPE, n)).m_alpha;
setmodel(fn, MDL_NADE_VIEW);
setattachment(fn, player.(weaponentity), "");
//setattachment(fn, player.(weaponentity), "");
fn.viewmodelforclient = player;
fn.realowner = fn.owner = player;
fn.colormod = Nades_from(STAT(NADE_BONUS_TYPE, n)).m_color;
fn.colormap = player.colormap;
......
......@@ -51,8 +51,7 @@ void W_OverkillHeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity
SpawnCasing (((random () * 50 + 50) * v_right) - (v_forward * (random () * 25 + 25)) - ((random () * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity);
}
int slot = weaponslot(weaponentity);
ATTACK_FINISHED(actor, slot) = time + WEP_CVAR_PRI(okhmg, refire) * W_WeaponRateFactor(actor);
ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR_PRI(okhmg, refire) * W_WeaponRateFactor(actor);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(okhmg, refire), W_OverkillHeavyMachineGun_Attack_Auto);
}
......
......@@ -45,8 +45,7 @@ void W_OverkillMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weap
SpawnCasing(((random() * 50 + 50) * v_right) - (v_forward * (random() * 25 + 25)) - ((random() * 5 - 70) * v_up), 2, vectoangles(v_forward),'0 250 0', 100, 3, actor, weaponentity);
}
int slot = weaponslot(weaponentity);
ATTACK_FINISHED(actor, slot) = time + WEP_CVAR_PRI(okmachinegun, refire) * W_WeaponRateFactor(actor);
ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR_PRI(okmachinegun, refire) * W_WeaponRateFactor(actor);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR_PRI(okmachinegun, refire), W_OverkillMachineGun_Attack_Auto);
}
......
......@@ -102,7 +102,7 @@ MUTATOR_HOOKFUNCTION(ok, PlayerDies)
entity frag_attacker = M_ARGV(1, entity);
entity frag_target = M_ARGV(2, entity);
entity targ = ((frag_attacker) ? frag_attacker : frag_target);
entity targ = ((IS_PLAYER(frag_attacker)) ? frag_attacker : frag_target);
ok_DropItem(frag_target, targ);
......
......@@ -36,11 +36,15 @@ void _Movetype_WallFriction(entity this, vector stepnormal) // SV_WallFriction
vector planes[MAX_CLIP_PLANES];
int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnormal, float stepheight) // SV_FlyMove
{
if(dt <= 0)
return 0;
int blocked = 0;
int i, j, numplanes = 0;
float time_left = dt, grav = 0;
vector push;
vector primal_velocity, original_velocity, restore_velocity;
vector primal_velocity, original_velocity;
vector restore_velocity = this.velocity;
for(i = 0; i < MAX_CLIP_PLANES; ++i)
planes[i] = '0 0 0';
......@@ -59,7 +63,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
}
}
original_velocity = primal_velocity = restore_velocity = this.velocity;
original_velocity = primal_velocity = this.velocity;
for(int bumpcount = 0;bumpcount < MAX_CLIP_PLANES;bumpcount++)
{
......@@ -67,8 +71,7 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
break;
push = this.velocity * time_left;
_Movetype_PushEntity(this, push, true);
if(trace_startsolid)
if(!_Movetype_PushEntity(this, push, true, false))
{
// we got teleported by a touch function
// let's abort the move
......@@ -113,22 +116,19 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
vector org = this.origin;
vector steppush = '0 0 1' * stepheight;
_Movetype_PushEntity(this, steppush, true);
if(trace_startsolid)
if(!_Movetype_PushEntity(this, steppush, true, false))
{
blocked |= 8;
break;
}
_Movetype_PushEntity(this, push, true);
if(trace_startsolid)
if(!_Movetype_PushEntity(this, push, true, false))
{
blocked |= 8;
break;
}
float trace2_fraction = trace_fraction;
steppush = '0 0 1' * (org.z - this.origin_z);
_Movetype_PushEntity(this, steppush, true);
if(trace_startsolid)
steppush = vec3(0, 0, org.z - this.origin_z);
if(!_Movetype_PushEntity(this, steppush, true, false))
{
blocked |= 8;
break;
......@@ -501,20 +501,32 @@ void _Movetype_PushEntityTrace(entity this, vector push)
tracebox(this.origin, this.mins, this.maxs, end, type, this);
}
float _Movetype_PushEntity(entity this, vector push, bool failonstartsolid) // SV_PushEntity
bool _Movetype_PushEntity(entity this, vector push, bool failonstartsolid, bool dolink) // SV_PushEntity
{
_Movetype_PushEntityTrace(this, push);
if(trace_startsolid && failonstartsolid)
return trace_fraction;
{
int oldtype = this.move_nomonsters;
this.move_nomonsters = MOVE_NOMONSTERS;
_Movetype_PushEntityTrace(this, push);
this.move_nomonsters = oldtype;
if(trace_startsolid)
return true;
}
this.origin = trace_endpos;
vector last_origin = this.origin;
if(dolink)
_Movetype_LinkEdict(this, true);
if(trace_fraction < 1)
if(this.solid >= SOLID_TRIGGER && (!IS_ONGROUND(this) || (this.groundentity != trace_ent)))
_Movetype_Impact(this, trace_ent);
return trace_fraction;
return (this.origin == last_origin); // false if teleported by touch
}
......
......@@ -95,7 +95,7 @@ void _Movetype_LinkEdict_TouchAreaGrid(entity this);
void _Movetype_LinkEdict(entity this, float touch_triggers);
vector _Movetype_ClipVelocity(vector vel, vector norm, float f);
void _Movetype_PushEntityTrace(entity this, vector push);
float _Movetype_PushEntity(entity this, vector push, float failonstartsolid);
bool _Movetype_PushEntity(entity this, vector push, float failonstartsolid, bool dolink);
void Movetype_Physics_NoMatchTicrate(entity this, float movedt, bool isclient);
void Movetype_Physics_MatchTicrate(entity this, float tr, bool sloppy);
......
......@@ -44,14 +44,14 @@ void _Movetype_Physics_Toss(entity this, float dt) // SV_Physics_Toss
for (int bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump)
{
vector move = this.velocity * movetime;
_Movetype_PushEntity(this, move, true);
_Movetype_PushEntity(this, move, true, false);
if (wasfreed(this))
return;
if (trace_startsolid)
{
_Movetype_UnstickEntity(this);
_Movetype_PushEntity(this, move, false);
_Movetype_PushEntity(this, move, false, false);
if (wasfreed(this))
return;
}
......
......@@ -100,10 +100,7 @@ void _Movetype_Physics_Walk(entity this, float dt) // SV_WalkMove
// move up
vector upmove = '0 0 1' * PHYS_STEPHEIGHT(this);
_Movetype_PushEntity(this, upmove, true);
if(wasfreed(this))
return;
if(trace_startsolid)
if(!_Movetype_PushEntity(this, upmove, true, true))
{
// we got teleported when upstepping... must abort the move
return;
......@@ -156,11 +153,7 @@ void _Movetype_Physics_Walk(entity this, float dt) // SV_WalkMove
// move down
vector downmove = '0 0 0';
downmove.z = -PHYS_STEPHEIGHT(this) + start_velocity.z * dt;
_Movetype_PushEntity(this, downmove, true);
if(wasfreed(this))
return;
if(trace_startsolid)
if(!_Movetype_PushEntity(this, downmove, true, true))
{
// we got teleported when downstepping... must abort the move
return;
......
......@@ -8,6 +8,7 @@ bool autocvar_bot_sound_monopoly;
.entity realowner;
bool sound_allowed(int to, entity e)
{
if(!e) return true; // save on a few checks
for ( ; ; )
{
if (e.classname == "body") e = e.enemy;
......
......@@ -1401,7 +1401,7 @@ int group_count = 1;
void setItemGroup(entity this)
{
if(!IS_SMALL(this.itemdef))
if(!IS_SMALL(this.itemdef) || Item_IsLoot(this))
return;
FOREACH_ENTITY_RADIUS(this.origin, 120, (it != this) && IS_SMALL(it.itemdef),
......
......@@ -1298,6 +1298,7 @@ float matchacl(string acl, string str)
if(s == t)
{
r = d;
break; // if we found a killing case, apply it! other settings may be allowed in the future, but this one is caught
}
}
return r;
......
......@@ -539,17 +539,33 @@ void W_Arc_Beam(float burst, entity actor, .entity weaponentity)
getthink(beam)(beam);
}
void Arc_Smoke(entity actor, .entity weaponentity)
void W_Arc_Attack(Weapon thiswep, entity actor, .entity weaponentity, int fire)
{
if(!actor.(weaponentity).arc_beam || wasfreed(actor.(weaponentity).arc_beam))
{
w_ready(thiswep, actor, weaponentity, fire);
return;
}
// attack handled by the beam itself, this is just a loop to keep the attack happening!
// NOTE: arc doesn't use a refire
//ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR_PRI(arc, refire) * W_WeaponRateFactor(actor);
actor.(weaponentity).wframe = WFRAME_FIRE1;
weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(arc, beam_animtime), W_Arc_Attack);
}
void Arc_Smoke(Weapon thiswep, entity actor, .entity weaponentity, int fire)
{
// TODO: spamming this without checking any refires is asking for trouble!
makevectors(actor.v_angle);
W_SetupShot_Range(actor,weaponentity,false,0,SND_Null,0,0,0,WEP_ARC.m_id); // TODO: probably doesn't need deathtype, since this is just a prefire effect
W_SetupShot_Range(actor,weaponentity,false,0,SND_Null,0,0,0,thiswep.m_id); // TODO: probably doesn't need deathtype, since this is just a prefire effect
vector smoke_origin = w_shotorg + actor.velocity*frametime;
if ( actor.arc_overheat > time )
{
if ( random() < actor.(weaponentity).arc_heat_percent )
Send_Effect(EFFECT_ARC_SMOKE, smoke_origin, '0 0 0', 1 );
if ( PHYS_INPUT_BUTTON_ATCK(actor) || PHYS_INPUT_BUTTON_ATCK2(actor) )
if ( (fire & 1) || (fire & 2) )
{
Send_Effect(EFFECT_ARC_OVERHEAT_FIRE, smoke_origin, w_shotdir, 1 );
if ( !actor.arc_smoke_sound )
......@@ -568,7 +584,7 @@ void Arc_Smoke(entity actor, .entity weaponentity)
}
if ( actor.arc_smoke_sound && ( actor.arc_overheat <= time ||
!( PHYS_INPUT_BUTTON_ATCK(actor) || PHYS_INPUT_BUTTON_ATCK2(actor) ) ) || actor.(weaponentity).m_switchweapon != WEP_ARC )
!( PHYS_INPUT_BUTTON_ATCK(actor) || PHYS_INPUT_BUTTON_ATCK2(actor) ) ) || actor.(weaponentity).m_switchweapon != thiswep )
{
actor.arc_smoke_sound = 0;
sound(actor, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
......@@ -603,14 +619,14 @@ METHOD(Arc, wr_aim, void(entity thiswep, entity actor, .entity weaponentity))
METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, int fire))
{
Arc_Player_SetHeat(actor, weaponentity);
Arc_Smoke(actor, weaponentity);
Arc_Smoke(thiswep, actor, weaponentity, fire);
bool beam_fire2 = ((fire & 2) && !WEP_CVAR(arc, bolt));
if (time >= actor.arc_overheat)
if ((fire & 1) || beam_fire2 || actor.(weaponentity).arc_beam.beam_bursting)
{
#if 0
if(actor.(weaponentity).arc_BUTTON_ATCK_prev)
{
#if 0
......@@ -620,6 +636,7 @@ METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, i
#endif
weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(arc, beam_animtime), w_ready);
}
#endif
if((!actor.(weaponentity).arc_beam) || wasfreed(actor.(weaponentity).arc_beam))
{
......@@ -629,7 +646,8 @@ METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, i
if(!actor.(weaponentity).arc_BUTTON_ATCK_prev)
{
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
actor.(weaponentity).wframe = WFRAME_FIRE1;
weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(arc, beam_animtime), W_Arc_Attack);
actor.(weaponentity).arc_BUTTON_ATCK_prev = true;
}
}
......@@ -648,10 +666,9 @@ METHOD(Arc, wr_think, void(entity thiswep, entity actor, .entity weaponentity, i
if(actor.(weaponentity).arc_BUTTON_ATCK_prev)
{
int slot = weaponslot(weaponentity);
sound(actor, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM);
weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
ATTACK_FINISHED(actor, slot) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor(actor);
ATTACK_FINISHED(actor, weaponentity) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor(actor);
}
actor.(weaponentity).arc_BUTTON_ATCK_prev = false;
......
......@@ -50,8 +50,7 @@ void W_Devastator_Explode(entity this, entity directhitentity)
if(!(this.realowner.items & IT_UNLIMITED_WEAPON_AMMO))
{
this.realowner.cnt = thiswep.m_id;
int slot = weaponslot(weaponentity);
ATTACK_FINISHED(this.realowner, slot) = time;
ATTACK_FINISHED(this.realowner, weaponentity) = time;
this.realowner.(weaponentity).m_switchweapon = w_getbestweapon(this.realowner, weaponentity);
}
}
......@@ -144,8 +143,7 @@ void W_Devastator_DoRemoteExplode(entity this, .entity weaponentity)
if(!(this.realowner.items & IT_UNLIMITED_WEAPON_AMMO))
{
this.realowner.cnt = thiswep.m_id;
int slot = weaponslot(weaponentity);
ATTACK_FINISHED(this.realowner, slot) = time;
ATTACK_FINISHED(this.realowner, weaponentity) = time;
this.realowner.(weaponentity).m_switchweapon = w_getbestweapon(this.realowner, weaponentity);
}
}
......@@ -488,7 +486,7 @@ METHOD(Devastator, wr_checkammo1, bool(entity thiswep, entity actor, .entity wea