#include "bot/api.qh"
#include "../common/ent_cs.qh"
+#include "../common/wepent.qh"
#include <common/state.qh>
#include <common/effects/qc/globalsound.qh>
if (e.race_completed) sf |= 1; // forced scoreboard
if (to.spectatee_status) sf |= 2; // spectator ent number follows
if (e.zoomstate) sf |= 4; // zoomed
- if (e.porto_v_angle_held) sf |= 8; // angles held
if (autocvar_sv_showspectators) sf |= 16; // show spectators
WriteHeader(MSG_ENTITY, ENT_CLIENT_CLIENTDATA);
{
WriteByte(MSG_ENTITY, to.spectatee_status);
}
- if (sf & 8)
- {
- WriteAngle(MSG_ENTITY, e.v_angle.x);
- WriteAngle(MSG_ENTITY, e.v_angle.y);
- }
if(sf & 16)
{
this.view_ofs = '0 0 0';
}
- RemoveGrapplingHook(this);
+ RemoveGrapplingHooks(this);
Portal_ClearAll(this);
Unfreeze(this);
SetSpectatee(this, NULL);
if (this.killcount != FRAGS_SPECTATOR)
{
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_SPECTATE, this.netname);
- if(!gameover)
+ if(!game_stopped)
if(autocvar_g_chat_nospectators == 1 || (!warmup_stage && autocvar_g_chat_nospectators == 2))
Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CHAT_NOSPECTATORS);
this.istypefrag = 0;
setthink(this, func_null);
this.nextthink = 0;
- this.hook_time = 0;
this.deadflag = DEAD_NO;
this.crouch = false;
this.revive_progress = 0;
this.weapons = '0 0 0';
this.drawonlytoclient = this;
- this.weaponname = "";
this.weaponmodel = "";
for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
this.fire_endtime = -1;
this.event_damage = func_null;
- STAT(ACTIVEWEAPON, this) = WEP_Null.m_id;
- STAT(SWITCHINGWEAPON, this) = WEP_Null.m_id;
- STAT(SWITCHWEAPON, this) = WEP_Null.m_id;
+ for(int slot = 0; slot < MAX_AXH; ++slot)
+ {
+ entity axh = this.(AuxiliaryXhair[slot]);
+ this.(AuxiliaryXhair[slot]) = NULL;
+
+ if(axh.owner == this && axh != NULL && !wasfreed(axh))
+ delete(axh);
+ }
}
int player_getspecies(entity this)
{
if(teamplay)
{
- string s = Static_Team_ColorName_Lower(player.team);
- if (s != "neutral")
+ switch(player.team)
{
- defaultmodel = cvar_string(strcat("sv_defaultplayermodel_", s));
- defaultskin = cvar(strcat("sv_defaultplayerskin_", s));
+ case NUM_TEAM_1: defaultmodel = autocvar_sv_defaultplayermodel_red; defaultskin = autocvar_sv_defaultplayerskin_red; break;
+ case NUM_TEAM_2: defaultmodel = autocvar_sv_defaultplayermodel_blue; defaultskin = autocvar_sv_defaultplayerskin_blue; break;
+ case NUM_TEAM_3: defaultmodel = autocvar_sv_defaultplayermodel_yellow; defaultskin = autocvar_sv_defaultplayerskin_yellow; break;
+ case NUM_TEAM_4: defaultmodel = autocvar_sv_defaultplayermodel_pink; defaultskin = autocvar_sv_defaultplayerskin_pink; break;
}
}
{
if(teamplay)
{
- string s = Static_Team_ColorName_Lower(player.team);
- if (s != "neutral")
- defaultskin = cvar(strcat("sv_defaultplayerskin_", s));
+ switch(player.team)
+ {
+ case NUM_TEAM_1: defaultskin = autocvar_sv_defaultplayerskin_red; break;
+ case NUM_TEAM_2: defaultskin = autocvar_sv_defaultplayerskin_blue; break;
+ case NUM_TEAM_3: defaultskin = autocvar_sv_defaultplayerskin_yellow; break;
+ case NUM_TEAM_4: defaultskin = autocvar_sv_defaultplayerskin_pink; break;
+ }
}
if(!defaultskin)
WriteByte(MSG_ONE, SVC_SETVIEW);
WriteEntity(MSG_ONE, this);
}
- if (gameover) {
+ if (game_stopped)
TRANSMUTE(Observer, this);
- }
SetSpectatee(this, NULL);
IL_PUSH(g_bot_targets, this);
this.bot_attack = true;
this.monster_attack = true;
+ navigation_dynamicgoal_init(this, false);
PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_JUMP(this) = PHYS_INPUT_BUTTON_ATCK2(this) = false;
for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
- CL_SpawnWeaponentity(this, weaponentities[slot]);
+ .entity weaponentity = weaponentities[slot];
+ entity oldwep = this.(weaponentity);
+ CL_SpawnWeaponentity(this, weaponentity);
+ if(oldwep && oldwep.owner == this)
+ this.(weaponentity).m_gunalign = oldwep.m_gunalign;
}
this.alpha = default_player_alpha;
this.colormod = '1 1 1' * autocvar_g_player_brightness;
it.wr_resetplayer(it, this);
// reload all reloadable weapons
if (it.spawnflags & WEP_FLAG_RELOADABLE) {
- this.weapon_load[it.m_id] = it.reloading_ammo;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ this.(weaponentity).weapon_load[it.m_id] = it.reloading_ammo;
+ }
}
));
delete(spot); // usefull for checking if there are spawnpoints, that let drop through the floor
}
- PS(this).m_switchweapon = w_getbestweapon(this);
- this.cnt = -1; // W_LastWeapon will not complain
- PS(this).m_weapon = WEP_Null;
- this.weaponname = "";
- PS(this).m_switchingweapon = WEP_Null;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(slot == 0)
+ this.(weaponentity).m_switchweapon = w_getbestweapon(this, weaponentity);
+ else
+ this.(weaponentity).m_switchweapon = WEP_Null;
+ this.(weaponentity).m_weapon = WEP_Null;
+ this.(weaponentity).weaponname = "";
+ this.(weaponentity).m_switchingweapon = WEP_Null;
+ this.(weaponentity).cnt = -1;
+ }
+
+ MUTATOR_CALLHOOK(PlayerWeaponSelect, this);
if (!warmup_stage && !this.alivetime)
this.alivetime = time;
}
void KillIndicator_Think(entity this)
{
- if (gameover)
+ if (game_stopped)
{
this.owner.killindicator = NULL;
delete(this);
float killtime;
float starttime;
- if (gameover)
+ if (game_stopped)
return;
killtime = autocvar_g_balance_kill_delay;
void ClientKill (entity this)
{
- if(gameover) return;
+ if(game_stopped) return;
if(this.player_blocked) return;
if(STAT(FROZEN, this)) return;
if (IS_BOT_CLIENT(this)) PlayerStats_GameReport_AddPlayer(this);
if (autocvar_sv_eventlog)
- GameLogEcho(strcat(":join:", ftos(this.playerid), ":", ftos(etof(this)), ":", ((IS_REAL_CLIENT(this)) ? this.netaddress : "bot"), ":", this.netname));
+ GameLogEcho(strcat(":join:", ftos(this.playerid), ":", ftos(etof(this)), ":", ((IS_REAL_CLIENT(this)) ? this.netaddress : "bot"), ":", playername(this, false)));
LogTeamchange(this.playerid, this.team, 1);
stuffcmd(this, strcat("\nfog ", world.fog, "\nr_fog_exp2 0\nr_drawfog 1\n"));
if (autocvar_sv_teamnagger && !(autocvar_bot_vs_human && AvailableTeams() == 2))
- if (!g_ca && !g_cts && !g_race) // teamnagger is currently bad for ca, race & cts
+ if(!MUTATOR_CALLHOOK(HideTeamNagger, this))
send_CSQC_teamnagger();
CSQCMODEL_AUTOINIT(this);
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));
IL_EACH(g_initforplayer, it.init_for_player, {
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_DISCONNECT, this.netname);
- SetSpectatee(this, NULL);
+ if(IS_SPEC(this))
+ SetSpectatee(this, NULL);
MUTATOR_CALLHOOK(ClientDisconnect, this);
Unfreeze(this);
- RemoveGrapplingHook(this);
+ RemoveGrapplingHooks(this);
// Here, everything has been done that requires this player to be a client.
// add a way to see what the items were BEFORE all of these checks for the mutator hook
int items_prev = this.items;
- if((this.items & IT_USING_JETPACK) && !IS_DEAD(this) && !gameover)
+ if((this.items & IT_USING_JETPACK) && !IS_DEAD(this) && !game_stopped)
this.modelflags |= MF_ROCKET;
else
this.modelflags &= ~MF_ROCKET;
this.hit_time = spectatee.hit_time;
this.strength_finished = spectatee.strength_finished;
this.invincible_finished = spectatee.invincible_finished;
+ this.superweapons_finished = spectatee.superweapons_finished;
STAT(PRESSED_KEYS, this) = STAT(PRESSED_KEYS, spectatee);
this.weapons = spectatee.weapons;
this.vortex_charge = spectatee.vortex_charge;
setsize(this, spectatee.mins, spectatee.maxs);
SetZoomState(this, spectatee.zoomstate);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ this.(weaponentity) = spectatee.(weaponentity);
+ }
+
+ for(int slot = 0; slot < MAX_AXH; ++slot)
+ {
+ this.(AuxiliaryXhair[slot]) = spectatee.(AuxiliaryXhair[slot]);
+ }
+
anticheat_spectatecopy(this, spectatee);
this.hud = spectatee.hud;
if(spectatee.vehicle)
if(this.vehicle)
{
- if(!gameover)
+ if(!game_stopped)
{
vehicles_exit(this.vehicle, VHEF_NORMAL);
return;
{
if(!STAT(FROZEN, this))
if(!IS_DEAD(this))
- if(!gameover)
+ if(!game_stopped)
{
entity head, closest_target = NULL;
head = WarpZone_FindRadius(this.origin, autocvar_g_vehicles_enter_radius, true);
}
if (this.netname != this.netname_previous) {
if (autocvar_sv_eventlog) {
- GameLogEcho(strcat(":name:", ftos(this.playerid), ":", this.netname));
+ GameLogEcho(strcat(":name:", ftos(this.playerid), ":", playername(this, false)));
}
if (this.netname_previous) strunzone(this.netname_previous);
this.netname_previous = strzone(this.netname);
MUTATOR_CALLHOOK(PlayerPreThink, this);
- if(autocvar_g_vehicles_enter && (time > this.last_vehiclecheck) && !gameover && !this.vehicle)
+ if(autocvar_g_vehicles_enter && (time > this.last_vehiclecheck) && !game_stopped && !this.vehicle)
if(IS_PLAYER(this) && !STAT(FROZEN, this) && !IS_DEAD(this))
{
FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_vehicles_enter_radius, IS_VEHICLE(it),
if (IS_PLAYER(this)) {
CheckRules_Player(this);
- if (gameover || intermission_running) {
+ if (game_stopped || intermission_running) {
+ this.modelflags &= ~MF_ROCKET;
if(intermission_running)
IntermissionThink(this);
return;
this.prevorigin = this.origin;
+ bool have_hook = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).hook.state)
+ {
+ have_hook = true;
+ break;
+ }
+ }
bool do_crouch = PHYS_INPUT_BUTTON_CROUCH(this);
- if (this.hook.state) {
+ if (have_hook) {
do_crouch = false;
} else if (this.waterlevel >= WATERLEVEL_SWIMMING) {
do_crouch = false;
{
this.items &= ~this.items_added;
- //for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
- //{
- //.entity weaponentity = weaponentities[slot];
- //W_WeaponFrame(this, weaponentity);
- //}
- .entity weaponentity = weaponentities[0]; // TODO
- W_WeaponFrame(this, weaponentity);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ W_WeaponFrame(this, weaponentity);
+
+ if(slot == 0)
+ {
+ this.clip_load = this.(weaponentity).clip_load;
+ this.clip_size = this.(weaponentity).clip_size;
+ }
+ }
this.items_added = 0;
if (this.items & ITEM_Jetpack.m_itemid && (this.items & ITEM_JetpackRegen.m_itemid || this.ammo_fuel >= 0.01))
// WEAPONTODO: Add a weapon request for this
// rot vortex charge to the charge limit
- if (WEP_CVAR(vortex, charge_rot_rate) && this.vortex_charge > WEP_CVAR(vortex, charge_limit) && this.vortex_charge_rottime < time)
- this.vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if (WEP_CVAR(vortex, charge_rot_rate) && this.(weaponentity).vortex_charge > WEP_CVAR(vortex, charge_limit) && this.(weaponentity).vortex_charge_rottime < time)
+ this.(weaponentity).vortex_charge = bound(WEP_CVAR(vortex, charge_limit), this.(weaponentity).vortex_charge - WEP_CVAR(vortex, charge_rot_rate) * frametime / W_TICSPERFRAME, 1);
+ }
if (frametime) player_anim(this);
this.dmg_team = max(0, this.dmg_team - autocvar_g_teamdamage_resetspeed * frametime);
}
- else if (gameover || intermission_running) {
+ else if (game_stopped || intermission_running) {
if(intermission_running)
IntermissionThink(this);
return;
// WEAPONTODO: Add weapon request for this
if (!zoomstate_set) {
- SetZoomState(this,
- PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this)
- || (PHYS_INPUT_BUTTON_ATCK2(this) && PS(this).m_weapon == WEP_VORTEX)
- || (PHYS_INPUT_BUTTON_ATCK2(this) && PS(this).m_weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0)
- );
+ bool wep_zoomed = false;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ Weapon thiswep = this.(weaponentity).m_weapon;
+ if(thiswep != WEP_Null && thiswep.wr_zoom)
+ wep_zoomed += thiswep.wr_zoom(thiswep, this);
+ }
+ SetZoomState(this, PHYS_INPUT_BUTTON_ZOOM(this) || PHYS_INPUT_BUTTON_ZOOMSCRIPT(this) || wep_zoomed);
}
if (this.teamkill_soundtime && time > this.teamkill_soundtime)
// WEAPONTODO: Move into weaponsystem somehow
// if a player goes unarmed after holding a loaded weapon, empty his clip size and remove the crosshair ammo ring
- if (PS(this).m_weapon == WEP_Null)
- this.clip_load = this.clip_size = 0;
+ for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ if(this.(weaponentity).m_weapon == WEP_Null)
+ this.(weaponentity).clip_load = this.(weaponentity).clip_size = 0;
+ }
}
void DrownPlayer(entity this)
CheatFrame(this);
//CheckPlayerJump();
- if (gameover)
+ if (game_stopped)
{
this.solid = SOLID_NOT;
this.takedamage = DAMAGE_NO;
CheckRules_Player(this);
UpdateChatBubble(this);
if (this.impulse) ImpulseCommands(this);
- if (gameover)
+ if (game_stopped)
{
CSQCMODEL_AUTOUPDATE(this);
return;