set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1500 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
set g_jetpack_maxspeed_side 1200 "max speed of the jetpack in xy direction"
set g_jetpack_maxspeed_up 600 "max speed of the jetpack in z direction"
set g_jetpack_fuel 8 "fuel per second for jetpack"
-set g_jetpack_attenuation 2 "jetpack sound attenuation"
set g_jetpack_reverse_thrust 0 "if not 0, downward acceleration when crouching with the jetpack"
set g_grappling_hook_tarzan 2 // 2: can also pull players
seta cl_gentle_messages 0 "client side gentle mode (only replaces frag messages/centerprints)"
seta cl_gentle_damage 0 "client side gentle mode (only replaces damage flash); when set to 1, a white flash replaces the blood image, when set to 2, a randomly colored flash is used instead"
+set cl_jetpack_attenuation 2 "jetpack sound attenuation"
+
set cl_warpzone_usetrace 1 "do not touch"
set cl_effects_lightningarc_simple 0
float autocvar_crosshair_size;
int autocvar_ekg;
float autocvar_fov;
-float autocvar_g_balance_damagepush_speedfactor; // FIXME check this
bool autocvar_hud_cursormode = true;
float autocvar_hud_colorflash_alpha;
bool autocvar_hud_configure_checkcollisions;
string autocvar__cl_playermodel;
float autocvar_cl_deathglow;
bool autocvar_developer_csqcentities;
-float autocvar_g_jetpack_attenuation; // FIXME check this
+float autocvar_cl_jetpack_attenuation = 2;
bool autocvar_cl_showspectators;
int autocvar_cl_nade_timer;
bool autocvar_r_drawviewmodel;
bool autocvar_cl_race_cptimes_onlyself;
-bool autocvar_cl_race_cptimes_showself = true;
+bool autocvar_cl_race_cptimes_showself = false;
{
if(!this.snd_looping)
{
- sound(this, CH_TRIGGER_SINGLE, SND_JETPACK_FLY, VOL_BASE, autocvar_g_jetpack_attenuation);
+ sound(this, CH_TRIGGER_SINGLE, SND_JETPACK_FLY, VOL_BASE, autocvar_cl_jetpack_attenuation);
this.snd_looping = CH_TRIGGER_SINGLE;
}
}
{
if(this.snd_looping)
{
- sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_g_jetpack_attenuation);
+ sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_cl_jetpack_attenuation);
this.snd_looping = 0;
}
}
othertimestr = strcat("+", ftos_decimals(mytime - othertime, TIME_DECIMALS));
else
othertimestr = TIME_ENCODED_TOSTRING(TIME_ENCODE(othertime));
- othercol = "^3";
+ othercol = "^7";
}
if(cp == 254)
if(this.snd_looping > 0)
{
- sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_g_jetpack_attenuation);
+ sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_cl_jetpack_attenuation);
this.snd_looping = 0;
}
forcefog = strzone(ReadString());
armorblockpercent = ReadByte() / 255.0;
+ damagepush_speedfactor = ReadByte() / 255.0;
serverflags = ReadByte();
const float ALPHA_MIN_VISIBLE = 0.003;
float armorblockpercent;
+float damagepush_speedfactor;
//hooks
int calledhooks;
if(it.damageforcescale)
if(vdist(thisforce, !=, 0))
{
- it.velocity = it.velocity + damage_explosion_calcpush(it.damageforcescale * thisforce, it.velocity, autocvar_g_balance_damagepush_speedfactor);
+ it.velocity = it.velocity + damage_explosion_calcpush(it.damageforcescale * thisforce, it.velocity, damagepush_speedfactor);
UNSET_ONGROUND(it);
}
.float campcheck_nextcheck;
.float campcheck_traveled_distance;
+.vector campcheck_prevorigin;
+
MUTATOR_HOOKFUNCTION(campcheck, PlayerDies)
{
entity frag_target = M_ARGV(2, entity);
MUTATOR_HOOKFUNCTION(campcheck, PlayerPreThink)
{
entity player = M_ARGV(0, entity);
+ bool checked = false;
- if(!game_stopped)
- if(!warmup_stage) // don't consider it camping during warmup?
- if(time >= game_starttime)
+ if(autocvar_g_campcheck_interval)
+ if(!game_stopped && !warmup_stage && time >= game_starttime)
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(IS_REAL_CLIENT(player)) // bots may camp, but that's no reason to constantly kill them
+ if(!forbidWeaponUse(player))
{
- vector dist;
-
// calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement)
- dist = player.prevorigin - player.origin;
- dist.z = 0;
+ vector dist = vec2(player.campcheck_prevorigin - player.origin);
player.campcheck_traveled_distance += fabs(vlen(dist));
if((autocvar_g_campaign && !campaign_bots_may_start) || (time < game_starttime) || (round_handler_IsActive() && !round_handler_IsRoundStarted()))
player.campcheck_traveled_distance = 0;
}
- return;
+ checked = true;
}
- player.campcheck_nextcheck = time + autocvar_g_campcheck_interval; // one of the above checks failed, so keep the timer up to date
+ if(!checked)
+ player.campcheck_nextcheck = time + autocvar_g_campcheck_interval; // one of the above checks failed, so keep the timer up to date
+
+ player.campcheck_prevorigin = player.origin;
+}
+
+MUTATOR_HOOKFUNCTION(campcheck, CopyBody)
+{
+ entity player = M_ARGV(0, entity);
+ entity clone = M_ARGV(1, entity);
+
+ clone.campcheck_prevorigin = player.campcheck_prevorigin;
}
MUTATOR_HOOKFUNCTION(campcheck, PlayerSpawn)
return defaultval;
}
-void Physics_UpdateStats(entity this, float maxspd_mod)
+void Physics_UpdateStats(entity this)
{
+ // update this first, as it's used on all stats (wouldn't want to update them all manually from a mutator hook now, would we?)
+ STAT(MOVEVARS_HIGHSPEED, this) = autocvar_g_movement_highspeed;
+
+ MUTATOR_CALLHOOK(PlayerPhysics_UpdateStats, this);
+ float maxspd_mod = PHYS_HIGHSPEED(this);
+
STAT(MOVEVARS_AIRACCEL_QW, this) = AdjustAirAccelQW(Physics_ClientOption(this, "airaccel_qw", autocvar_sv_airaccel_qw), maxspd_mod);
STAT(MOVEVARS_AIRSTRAFEACCEL_QW, this) = (Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw))
? AdjustAirAccelQW(Physics_ClientOption(this, "airstrafeaccel_qw", autocvar_sv_airstrafeaccel_qw), maxspd_mod)
bool Physics_Valid(string thecvar);
- void Physics_UpdateStats(entity this, float maxspd_mod);
+ void Physics_UpdateStats(entity this);
void PM_UpdateButtons(entity this, entity store);
#define stat_VIEWHEIGHT view_ofs_z
#endif
+#ifdef SVQC
+vector weaponsInMap;
+#endif
REGISTER_STAT(WEAPONS, vectori)
-REGISTER_STAT(WEAPONSINMAP, vectori)
+REGISTER_STAT(WEAPONSINMAP, vectori, weaponsInMap)
REGISTER_STAT(PL_VIEW_OFS, vector)
REGISTER_STAT(PL_CROUCH_VIEW_OFS, vector)
#ifdef SVQC
float W_WeaponRateFactor(entity this);
float game_stopped;
+float game_starttime;
+float round_starttime;
+bool autocvar_g_allow_oldvortexbeam;
+int autocvar_leadlimit;
#endif
REGISTER_STAT(WEAPONRATEFACTOR, float, W_WeaponRateFactor(this))
REGISTER_STAT(GAME_STOPPED, int, game_stopped)
-REGISTER_STAT(GAMESTARTTIME, float)
+REGISTER_STAT(GAMESTARTTIME, float, game_starttime)
REGISTER_STAT(STRENGTH_FINISHED, float)
REGISTER_STAT(INVINCIBLE_FINISHED, float)
/** arc heat in [0,1] */
REGISTER_STAT(ARC_HEAT, float)
REGISTER_STAT(PRESSED_KEYS, int)
/** this stat could later contain some other bits of info, like, more server-side particle config */
-REGISTER_STAT(ALLOW_OLDVORTEXBEAM, bool)
+REGISTER_STAT(ALLOW_OLDVORTEXBEAM, bool, autocvar_g_allow_oldvortexbeam)
REGISTER_STAT(FUEL, int)
REGISTER_STAT(NB_METERSTART, float)
/** compressShotOrigin */
REGISTER_STAT(SHOTORG, int)
-REGISTER_STAT(LEADLIMIT, float)
+REGISTER_STAT(LEADLIMIT, float, autocvar_leadlimit)
REGISTER_STAT(WEAPON_CLIPLOAD, int)
REGISTER_STAT(WEAPON_CLIPSIZE, int)
REGISTER_STAT(SECRETS_TOTAL, float)
REGISTER_STAT(SECRETS_FOUND, float)
REGISTER_STAT(RESPAWN_TIME, float)
-REGISTER_STAT(ROUNDSTARTTIME, float)
+REGISTER_STAT(ROUNDSTARTTIME, float, round_starttime)
REGISTER_STAT(MONSTERS_TOTAL, int)
REGISTER_STAT(MONSTERS_KILLED, int)
REGISTER_STAT(BUFFS, int)
if(!IS_PLAYER(player))
return false;
- int valid = (door.itemkeys & player.itemkeys);
+ entity store = player;
+#ifdef SVQC
+ store = PS(player);
+#endif
+ int valid = (door.itemkeys & store.itemkeys);
door.itemkeys &= ~valid; // only some of the needed keys were given
if(!door.itemkeys)
#ifdef CSQC
bool item_keys_usekey(entity l, entity p)
{
- int valid = (l.itemkeys & p.itemkeys);
+ int valid = (l.itemkeys & p.itemkeys); // TODO: itemkeys isn't networked or anything!
l.itemkeys &= ~valid; // only some of the needed keys were given
return valid != 0;
}
return W_FixWeaponOrder(order, 1);
}
-void W_RandomWeapons(entity e, float n)
+void W_RandomWeapons(entity e, int n)
{
- int i;
- WepSet remaining;
- WepSet result;
- remaining = e.weapons;
- result = '0 0 0';
- for (i = 0; i < n; ++i)
+ WepSet remaining = e.weapons;
+ WepSet result = '0 0 0';
+ for (int j = 0; j < n; ++j)
{
RandomSelection_Init();
FOREACH(Weapons, it != WEP_Null, {
string W_FixWeaponOrder_BuildImpulseList(string o);
string W_FixWeaponOrder_AllowIncomplete(entity this, string order);
string W_FixWeaponOrder_ForceComplete(string order);
-void W_RandomWeapons(entity e, float n);
+void W_RandomWeapons(entity e, int n);
string GetAmmoPicture(.int ammotype);
void sys_phys_fix(entity this, float dt)
{
WarpZone_PlayerPhysics_FixVAngle(this);
- STAT(MOVEVARS_HIGHSPEED, this) = autocvar_g_movement_highspeed;
- MUTATOR_CALLHOOK(PlayerPhysics_UpdateStats, this); // do it BEFORE the function so we can modify highspeed!
- Physics_UpdateStats(this, PHYS_HIGHSPEED(this));
+ Physics_UpdateStats(this);
}
bool sys_phys_override(entity this, float dt)
float autocvar_ekg;
#define autocvar_fraglimit cvar("fraglimit")
#define autocvar_fraglimit_override cvar("fraglimit_override")
-bool autocvar_g_allow_oldvortexbeam;
+//bool autocvar_g_allow_oldvortexbeam;
int autocvar_g_antilag;
float autocvar_g_antilag_nudge;
float autocvar_g_balance_armor_blockpercent;
float autocvar_gameversion_max;
string autocvar_hostname;
bool autocvar_lastlevel;
-int autocvar_leadlimit;
+//int autocvar_leadlimit;
int autocvar_leadlimit_and_fraglimit;
int autocvar_leadlimit_override;
int autocvar_loddebug;
if (IS_SPEC(e)) e = e.enemy;
sf = 0;
- if (e.race_completed) sf |= 1; // forced scoreboard
+ if (CS(e).race_completed) sf |= 1; // forced scoreboard
if (CS(to).spectatee_status) sf |= 2; // spectator ent number follows
if (CS(e).zoomstate) sf |= 4; // zoomed
if (autocvar_sv_showspectators) sf |= 16; // show spectators
{
entity spot = SelectSpawnPoint(this, true);
if (!spot) LOG_FATAL("No spawnpoints for observers?!?");
- this.angles = spot.angles;
- this.angles_z = 0;
+ this.angles = vec2(spot.angles);
this.fixangle = true;
// offset it so that the spectator spawns higher off the ground, looks better this way
setorigin(this, spot.origin + STAT(PL_VIEW_OFS, this));
- this.prevorigin = this.origin;
if (IS_REAL_CLIENT(this))
{
msg_entity = this;
if(autocvar_g_chat_nospectators == 1 || (!warmup_stage && autocvar_g_chat_nospectators == 2))
Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CHAT_NOSPECTATORS);
- if(this.just_joined == false) {
+ if(!CS(this).just_joined)
LogTeamchange(this.playerid, -1, 4);
- } else
- this.just_joined = false;
+ else
+ CS(this).just_joined = false;
}
accuracy_resend(this);
this.items = 0;
this.weapons = '0 0 0';
- this.dual_weapons = '0 0 0';
this.drawonlytoclient = this;
this.weaponmodel = "";
}
SetSpectatee_status(this, 0);
- this.dual_weapons = '0 0 0';
+ PS(this).dual_weapons = '0 0 0';
this.superweapons_finished = (this.weapons & WEPSET_SUPERWEAPONS) ? time + autocvar_g_balance_superweapons_time : 0;
setorigin(this, spot.origin + '0 0 1' * (1 - this.mins.z - 24));
// don't reset back to last position, even if new position is stuck in solid
this.oldorigin = this.origin;
- this.prevorigin = this.origin;
this.lastteleporttime = time; // prevent insane speeds due to changing origin
if(this.conveyor)
IL_REMOVE(g_conveyed, this);
SetSpectatee(this, NULL);
// reset player keys
- this.itemkeys = 0;
+ if(PS(this))
+ PS(this).itemkeys = 0;
MUTATOR_CALLHOOK(PutClientInServer, this);
else
WriteString(channel, "");
WriteByte(channel, this.count * 255.0); // g_balance_armor_blockpercent
+ WriteByte(channel, this.cnt * 255.0); // g_balance_damagepush_speedfactor
WriteByte(channel, serverflags);
WriteCoord(channel, autocvar_g_trueaim_minrange);
}
this.count = autocvar_g_balance_armor_blockpercent;
this.SendFlags |= 1;
}
+ if(this.cnt != autocvar_g_balance_damagepush_speedfactor)
+ {
+ this.cnt = autocvar_g_balance_damagepush_speedfactor;
+ this.SendFlags |= 1;
+ }
}
void ClientInit_Spawn()
LogTeamchange(this.playerid, this.team, 1);
- this.just_joined = true; // stop spamming the eventlog with additional lines when the client connects
+ CS(this).just_joined = true; // stop spamming the eventlog with additional lines when the client connects
CS(this).netname_previous = strzone(this.netname);
sv_notice_join(this);
// update physics stats (players can spawn before physics runs)
- STAT(MOVEVARS_HIGHSPEED, this) = autocvar_g_movement_highspeed;
- MUTATOR_CALLHOOK(PlayerPhysics_UpdateStats, this); // do it BEFORE the function so we can modify highspeed!
- Physics_UpdateStats(this, PHYS_HIGHSPEED(this));
+ Physics_UpdateStats(this);
IL_EACH(g_initforplayer, it.init_for_player, {
it.init_for_player(it, this);
this.superweapons_finished = spectatee.superweapons_finished;
STAT(PRESSED_KEYS, this) = STAT(PRESSED_KEYS, spectatee);
this.weapons = spectatee.weapons;
- this.dual_weapons = spectatee.dual_weapons;
this.vortex_charge = spectatee.vortex_charge;
this.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo;
this.hagar_load = spectatee.hagar_load;
return false;
}
- this.prevorigin = this.origin;
-
bool have_hook = false;
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
{
WarpZone_PlayerPhysics_FixVAngle(this);
- STAT(GAMESTARTTIME, this) = game_starttime;
- STAT(ROUNDSTARTTIME, this) = round_starttime;
- STAT(ALLOW_OLDVORTEXBEAM, this) = autocvar_g_allow_oldvortexbeam;
- STAT(LEADLIMIT, this) = autocvar_leadlimit;
-
- STAT(WEAPONSINMAP, this) = weaponsInMap;
-
if (frametime) {
// physics frames: update anticheat stuff
anticheat_prethink(this);
this.max_armorvalue = 0;
}
- if (STAT(FROZEN, this) == 2)
- {
- this.revive_progress = bound(0, this.revive_progress + frametime * this.revive_speed, 1);
- this.health = max(1, this.revive_progress * start_health);
- this.iceblock.alpha = bound(0.2, 1 - this.revive_progress, 1);
-
- if (this.revive_progress >= 1)
- Unfreeze(this);
- }
- else if (STAT(FROZEN, this) == 3)
+ if(IS_PLAYER(this))
{
- this.revive_progress = bound(0, this.revive_progress - frametime * this.revive_speed, 1);
- this.health = max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * this.revive_progress );
+ if (STAT(FROZEN, this) == 2)
+ {
+ this.revive_progress = bound(0, this.revive_progress + frametime * this.revive_speed, 1);
+ this.health = max(1, this.revive_progress * start_health);
+ this.iceblock.alpha = bound(0.2, 1 - this.revive_progress, 1);
- if (this.health < 1)
+ if (this.revive_progress >= 1)
+ Unfreeze(this);
+ }
+ else if (STAT(FROZEN, this) == 3)
{
- if (this.vehicle)
- vehicles_exit(this.vehicle, VHEF_RELEASE);
- if(this.event_damage)
- this.event_damage(this, this, this.frozen_by, 1, DEATH_NADE_ICE_FREEZE.m_id, this.origin, '0 0 0');
+ this.revive_progress = bound(0, this.revive_progress - frametime * this.revive_speed, 1);
+ this.health = max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * this.revive_progress );
+
+ if (this.health < 1)
+ {
+ if (this.vehicle)
+ vehicles_exit(this.vehicle, VHEF_RELEASE);
+ if(this.event_damage)
+ this.event_damage(this, this, this.frozen_by, 1, DEATH_NADE_ICE_FREEZE.m_id, this.origin, '0 0 0');
+ }
+ else if (this.revive_progress <= 0)
+ Unfreeze(this);
}
- else if (this.revive_progress <= 0)
- Unfreeze(this);
}
MUTATOR_CALLHOOK(PlayerPreThink, this);
ATTRIB(Client, version, int, this.version);
ATTRIB(Client, spectatee_status, int, this.spectatee_status);
ATTRIB(Client, zoomstate, bool, this.zoomstate);
+ ATTRIB(Client, just_joined, bool, this.just_joined);
+ ATTRIB(Client, race_completed, bool, this.race_completed);
METHOD(Client, m_unwind, bool(Client this));
ENDCLASS(Spectator)
CLASS(Player, Client)
+
+ // custom
+
+ ATTRIB(Player, dual_weapons, vector, this.dual_weapons); // TODO: actually WepSet!
+ ATTRIB(Player, itemkeys, int, this.itemkeys);
+
INIT(Player) {
this.classname = STR_PLAYER;
IL_PUSH(g_players, this);
void FixClientCvars(entity e);
// WEAPONTODO: remove this
-WepSet weaponsInMap;
+//WepSet weaponsInMap;
#define weapons _STAT(WEAPONS)
string cvar_purechanges;
float cvar_purechanges_count;
-float game_starttime; //point in time when the countdown to game start is over
-float round_starttime; //point in time when the countdown to round start is over
+//float game_starttime; //point in time when the countdown to game start is over
+//float round_starttime; //point in time when the countdown to round start is over
void W_Porto_Remove (entity p);
.float ammo_fuel;
-.vector prevorigin;
-
//flood fields
.float nickspamtime; // time of last nick change
.float nickspamcount;
setorigin(targ, spot.origin + '0 0 1' * (1 - targ.mins.z - 24));
// don't reset back to last position, even if new position is stuck in solid
targ.oldorigin = targ.origin;
- targ.prevorigin = targ.origin;
Send_Effect(EFFECT_TELEPORT, targ.origin, '0 0 0', 1);
}
bool item_keys_usekey(entity l, entity p)
{
- float valid = l.itemkeys & p.itemkeys;
+ int valid = l.itemkeys & PS(p).itemkeys;
if (!valid) {
- // other has none of the needed keys
+ // player has none of the needed keys
return false;
} else if (l.itemkeys == valid) {
// ALL needed keys were given
return;
// player already picked up this key
- if (toucher.itemkeys & this.itemkeys)
+ if (PS(toucher).itemkeys & this.itemkeys)
return;
- toucher.itemkeys |= this.itemkeys;
+ PS(toucher).itemkeys |= this.itemkeys;
play2(toucher, this.noise);
centerprint(toucher, this.message);
c = 0;
FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
++n;
- if(it.race_completed)
+ if(CS(it).race_completed)
++c;
));
if(n && (n == c))
//clone.weapon = this.weapon;
setorigin(clone, this.origin);
setsize(clone, this.mins, this.maxs);
- clone.prevorigin = this.origin;
clone.reset = SUB_Remove;
clone._ps = this._ps;
#include "../common/notifications/all.qh"
#include "../common/mapinfo.qh"
#include <common/net_linked.qh>
+#include <common/state.qh>
#include "../common/triggers/subs.qh"
#include "../lib/warpzone/util_server.qh"
#include "../lib/warpzone/common.qh"
if(tvalid)
if(cp == race_timed_checkpoint) // finish line
- if (!e.race_completed)
+ if (!CS(e).race_completed)
{
float s;
if(g_race_qualifying)
if(race_completing)
{
- e.race_completed = 1;
+ CS(e).race_completed = 1;
MAKE_INDEPENDENT_PLAYER(e);
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_FINISHED, e.netname);
ClientData_Touch(e);
race_setTime(GetMapname(), t, e.crypto_idfp, e.netname, e, true);
MUTATOR_CALLHOOK(Race_FinalCheckpoint, e);
}
+ if(t < myrecordtime || myrecordtime == 0)
+ e.race_checkpoint_record[cp] = t; // resending done below
+
if(t < recordtime || recordtime == 0)
{
race_checkpoint_records[cp] = t;
FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it.race_checkpoint == cp, LAMBDA(race_SendNextCheckpoint(it, 0)));
}
- if(t < myrecordtime || myrecordtime == 0)
- e.race_checkpoint_record[cp] = t; // resending done below
}
}
else
if(IS_REAL_CLIENT(e))
{
- msg_entity = e;
if(g_race_qualifying)
{
- WRITESPECTATABLE_MSG_ONE(e, {
- WriteHeader(MSG_ONE, TE_CSQC_RACE);
- WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
- WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
- WriteInt24_t(MSG_ONE, t); // time to that intermediate
- WriteInt24_t(MSG_ONE, recordtime); // previously best time
- WriteInt24_t(MSG_ONE, ((tvalid) ? it.race_checkpoint_record[cp] : 0)); // previously best time
- WriteString(MSG_ONE, recordholder); // record holder
+ FOREACH_CLIENT(IS_REAL_CLIENT(it),
+ {
+ if(it == e || (IS_SPEC(it) && it.enemy == e))
+ {
+ msg_entity = it;
+ WriteHeader(MSG_ONE, TE_CSQC_RACE);
+ WriteByte(MSG_ONE, RACE_NET_CHECKPOINT_HIT_QUALIFYING);
+ WriteByte(MSG_ONE, race_CheckpointNetworkID(cp)); // checkpoint the player now is at
+ WriteInt24_t(MSG_ONE, t); // time to that intermediate
+ WriteInt24_t(MSG_ONE, recordtime); // previously best time
+ WriteInt24_t(MSG_ONE, ((tvalid) ? it.race_checkpoint_record[cp] : 0)); // previously best time
+ WriteString(MSG_ONE, recordholder); // record holder
+ }
});
}
}
void race_AbandonRaceCheck(entity p)
{
- if(race_completing && !p.race_completed)
+ if(race_completing && !CS(p).race_completed)
{
- p.race_completed = 1;
+ CS(p).race_completed = 1;
MAKE_INDEPENDENT_PLAYER(p);
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_RACE_ABANDONED, p.netname);
ClientData_Touch(p);
void race_ClearRecords()
{
- float i;
-
- for(i = 0; i < MAX_CHECKPOINTS; ++i)
+ for(int j = 0; j < MAX_CHECKPOINTS; ++j)
{
- race_checkpoint_records[i] = 0;
- if(race_checkpoint_recordholders[i])
- strunzone(race_checkpoint_recordholders[i]);
- race_checkpoint_recordholders[i] = string_null;
+ race_checkpoint_records[j] = 0;
+ if(race_checkpoint_recordholders[j])
+ strunzone(race_checkpoint_recordholders[j]);
+ race_checkpoint_recordholders[j] = string_null;
}
FOREACH_CLIENT(true, LAMBDA(
float l;
l = PlayerScore_Add(e, SP_RACE_LAPS, 0);
- if(e.race_completed)
+ if(CS(e).race_completed)
return l; // not fractional
vector o0, o1;
cb1 = cb1 + bvalue;
}
}
- if(t == NUM_TEAM_2)
+ else if(t == NUM_TEAM_2)
{
if(c2 >= 0)
{
cb2 = cb2 + bvalue;
}
}
- if(t == NUM_TEAM_3)
+ else if(t == NUM_TEAM_3)
{
if(c3 >= 0)
{
cb3 = cb3 + bvalue;
}
}
- if(t == NUM_TEAM_4)
+ else if(t == NUM_TEAM_4)
{
if(c4 >= 0)
{
sprint(this, "Invalid weapon\n");
return false;
}
- if (autocvar_g_weaponswitch_debug == 2 && weaponslot(weaponentity) > 0 && !(wpn.spawnflags & WEP_FLAG_DUALWIELD) && !(this.dual_weapons & wpn.m_wepset))
+ if (autocvar_g_weaponswitch_debug == 2 && weaponslot(weaponentity) > 0 && !(wpn.spawnflags & WEP_FLAG_DUALWIELD) && !(PS(this).dual_weapons & wpn.m_wepset))
return false; // no complaints needed
if (this.weapons & WepSet_FromWeapon(wpn))
{
.entity wepe1 = weaponentities[0];
entity wep1 = actor.(wepe1);
this.m_switchweapon = wep1.m_switchweapon;
- if(!(this.m_switchweapon.spawnflags & WEP_FLAG_DUALWIELD) && !(actor.dual_weapons & wep1.m_switchweapon.m_wepset))
+ entity store = IS_PLAYER(actor) ? PS(actor) : actor;
+ if(!(this.m_switchweapon.spawnflags & WEP_FLAG_DUALWIELD) && !(store.dual_weapons & wep1.m_switchweapon.m_wepset))
{
this.m_weapon = WEP_Null;
this.m_switchingweapon = WEP_Null;