#include "../common/mapobjects/teleporters.qh"
#include "../common/mapobjects/target/spawnpoint.qh"
#include <common/mapobjects/trigger/counter.qh>
+#include <common/mapobjects/trigger/swamp.qh>
#include "../common/vehicles/all.qh"
if (IS_PLAYER(this))
{
- if(GetResourceAmount(this, RESOURCE_HEALTH) >= 1)
+ if(GetResource(this, RES_HEALTH) >= 1)
{
// despawn effect
Send_Effect(EFFECT_SPAWN_NEUTRAL, this.origin, '0 0 0', 1);
if(this.damagedbycontents)
IL_REMOVE(g_damagedbycontents, this);
this.damagedbycontents = false;
- SetResourceAmountExplicit(this, RESOURCE_HEALTH, FRAGS_SPECTATOR);
+ SetResourceExplicit(this, RES_HEALTH, FRAGS_SPECTATOR);
SetSpectatee_status(this, etof(this));
this.takedamage = DAMAGE_NO;
this.solid = SOLID_NOT;
set_movetype(this, MOVETYPE_FLY_WORLDONLY); // user preference is controlled by playerprethink
this.flags = FL_CLIENT | FL_NOTARGET;
this.effects = 0;
- SetResourceAmountExplicit(this, RESOURCE_ARMOR, autocvar_g_balance_armor_start); // was 666?!
+ SetResourceExplicit(this, RES_ARMOR, autocvar_g_balance_armor_start); // was 666?!
this.pauserotarmor_finished = 0;
this.pauserothealth_finished = 0;
this.pauseregen_finished = 0;
if(axh.owner == this && axh != NULL && !wasfreed(axh))
delete(axh);
}
-
+
if (mutator_returnvalue)
{
// mutator prevents resetting teams+score
{
SetPlayerTeam(this, -1, TEAM_CHANGE_SPECTATOR);
this.frags = FRAGS_SPECTATOR;
- }
+ }
+ if (CS(this).just_joined)
+ CS(this).just_joined = false;
}
int player_getspecies(entity this)
this.effects = EF_TELEPORT_BIT | EF_RESTARTANIM_BIT;
if (warmup_stage) {
- SetResourceAmount(this, RESOURCE_SHELLS, warmup_start_ammo_shells);
- SetResourceAmount(this, RESOURCE_BULLETS, warmup_start_ammo_nails);
- SetResourceAmount(this, RESOURCE_ROCKETS, warmup_start_ammo_rockets);
- SetResourceAmount(this, RESOURCE_CELLS, warmup_start_ammo_cells);
- SetResourceAmount(this, RESOURCE_PLASMA, warmup_start_ammo_plasma);
- SetResourceAmount(this, RESOURCE_FUEL, warmup_start_ammo_fuel);
- SetResourceAmount(this, RESOURCE_HEALTH, warmup_start_health);
- SetResourceAmount(this, RESOURCE_ARMOR, warmup_start_armorvalue);
+ SetResource(this, RES_SHELLS, warmup_start_ammo_shells);
+ SetResource(this, RES_BULLETS, warmup_start_ammo_nails);
+ SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets);
+ SetResource(this, RES_CELLS, warmup_start_ammo_cells);
+ SetResource(this, RES_PLASMA, warmup_start_ammo_plasma);
+ SetResource(this, RES_FUEL, warmup_start_ammo_fuel);
+ SetResource(this, RES_HEALTH, warmup_start_health);
+ SetResource(this, RES_ARMOR, warmup_start_armorvalue);
STAT(WEAPONS, this) = WARMUP_START_WEAPONS;
} else {
- SetResourceAmount(this, RESOURCE_SHELLS, start_ammo_shells);
- SetResourceAmount(this, RESOURCE_BULLETS, start_ammo_nails);
- SetResourceAmount(this, RESOURCE_ROCKETS, start_ammo_rockets);
- SetResourceAmount(this, RESOURCE_CELLS, start_ammo_cells);
- SetResourceAmount(this, RESOURCE_PLASMA, start_ammo_plasma);
- SetResourceAmount(this, RESOURCE_FUEL, start_ammo_fuel);
- SetResourceAmount(this, RESOURCE_HEALTH, start_health);
- SetResourceAmount(this, RESOURCE_ARMOR, start_armorvalue);
+ SetResource(this, RES_SHELLS, start_ammo_shells);
+ SetResource(this, RES_BULLETS, start_ammo_nails);
+ SetResource(this, RES_ROCKETS, start_ammo_rockets);
+ SetResource(this, RES_CELLS, start_ammo_cells);
+ SetResource(this, RES_PLASMA, start_ammo_plasma);
+ SetResource(this, RES_FUEL, start_ammo_fuel);
+ SetResource(this, RES_HEALTH, start_health);
+ SetResource(this, RES_ARMOR, start_armorvalue);
STAT(WEAPONS, this) = start_weapons;
if (MUTATOR_CALLHOOK(ForbidRandomStartWeapons, this) == false)
{
this.pauseregen_finished += f;
}
- this.damageforcescale = 2;
+ this.damageforcescale = autocvar_g_player_damageforcescale;
this.death_time = 0;
this.respawn_flags = 0;
this.respawn_time = 0;
this.angles = spot.angles;
this.angles_z = 0; // never spawn tilted even if the spot says to
if (IS_BOT_CLIENT(this))
+ {
this.v_angle = this.angles;
+ bot_aim_reset(this);
+ }
this.fixangle = true; // turn this way immediately
this.oldvelocity = this.velocity = '0 0 0';
this.avelocity = '0 0 0';
STAT(REVIVE_PROGRESS, this) = 0;
this.revival_time = 0;
+ // TODO: we can't set these in the PlayerSpawn hook since the target code is called before it!
+ STAT(BUFFS, this) = 0;
+ STAT(BUFF_TIME, this) = 0;
+
this.air_finished = time + 12;
this.waterlevel = WATERLEVEL_NONE;
this.watertype = CONTENT_EMPTY;
if(this.conveyor)
IL_REMOVE(g_conveyed, this);
this.conveyor = NULL; // prevent conveyors at the previous location from moving a freshly spawned player
+ if(this.swampslug)
+ delete(this.swampslug);
+ this.in_swamp = false;
STAT(HUD, this) = HUD_NORMAL;
this.event_damage = PlayerDamage;
});
{
- //string s = spot.target;
- //spot.target = string_null;
+ string s = spot.target;
+ if(g_assault || g_race) // TODO: make targeting work in assault & race without this hack
+ spot.target = string_null;
SUB_UseTargets(spot, this, NULL);
- //spot.target = s;
+ if(g_assault || g_race)
+ spot.target = s;
}
Unfreeze(this, false);
return s;
}
+bool autocvar_sv_qcphysics = false; // TODO this is for testing - remove when qcphysics work
+
/**
=============
ClientConnect
if (IS_REAL_CLIENT(this))
sv_notice_join(this);
- this.move_qcphysics = true;
+ this.move_qcphysics = autocvar_sv_qcphysics;
// update physics stats (players can spawn before physics runs)
Physics_UpdateStats(this);
PutClientInServer(this);
}
+ERASEABLE
void PrintToChat(entity client, string text)
{
text = strcat("\{1}^7", text, "\n");
sprint(client, text);
}
+ERASEABLE
void DebugPrintToChat(entity client, string text)
{
if (autocvar_developer)
}
}
+ERASEABLE
void PrintToChatAll(string text)
{
text = strcat("\{1}^7", text, "\n");
bprint(text);
}
+ERASEABLE
void DebugPrintToChatAll(string text)
{
if (autocvar_developer)
}
}
+ERASEABLE
void PrintToChatTeam(int team_num, string text)
{
text = strcat("\{1}^7", text, "\n");
});
}
+ERASEABLE
void DebugPrintToChatTeam(int team_num, string text)
{
if (autocvar_developer)
float mina, maxa, limith, limita;
maxa = autocvar_g_balance_armor_rotstable;
mina = autocvar_g_balance_armor_regenstable;
- limith = GetResourceLimit(this, RESOURCE_HEALTH);
- limita = GetResourceLimit(this, RESOURCE_ARMOR);
+ limith = GetResourceLimit(this, RES_HEALTH);
+ limita = GetResourceLimit(this, RES_ARMOR);
regen_health_rotstable = regen_health_rotstable * max_mod;
regen_health_stable = regen_health_stable * max_mod;
limith = limith * limit_mod;
limita = limita * limit_mod;
- SetResourceAmount(this, RESOURCE_ARMOR, CalcRotRegen(GetResourceAmount(this, RESOURCE_ARMOR), mina, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear,
+ SetResource(this, RES_ARMOR, CalcRotRegen(GetResource(this, RES_ARMOR), mina, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear,
regen_mod * frametime * (time > this.pauseregen_finished), maxa, autocvar_g_balance_armor_rot, autocvar_g_balance_armor_rotlinear,
rot_mod * frametime * (time > this.pauserotarmor_finished), limita));
- SetResourceAmount(this, RESOURCE_HEALTH, CalcRotRegen(GetResourceAmount(this, RESOURCE_HEALTH), regen_health_stable, regen_health, regen_health_linear,
+ SetResource(this, RES_HEALTH, CalcRotRegen(GetResource(this, RES_HEALTH), regen_health_stable, regen_health, regen_health_linear,
regen_mod * frametime * (time > this.pauseregen_finished), regen_health_rotstable, regen_health_rot, regen_health_rotlinear,
rot_mod * frametime * (time > this.pauserothealth_finished), limith));
}
// if player rotted to death... die!
// check this outside above checks, as player may still be able to rot to death
- if(GetResourceAmount(this, RESOURCE_HEALTH) < 1)
+ if(GetResource(this, RES_HEALTH) < 1)
{
if(this.vehicle)
vehicles_exit(this.vehicle, VHEF_RELEASE);
maxf = autocvar_g_balance_fuel_rotstable;
minf = autocvar_g_balance_fuel_regenstable;
- limitf = GetResourceLimit(this, RESOURCE_FUEL);
+ limitf = GetResourceLimit(this, RES_FUEL);
- SetResourceAmount(this, RESOURCE_FUEL, CalcRotRegen(GetResourceAmount(this, RESOURCE_FUEL), minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear,
+ SetResource(this, RES_FUEL, CalcRotRegen(GetResource(this, RES_FUEL), minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear,
frametime * (time > this.pauseregen_finished) * ((this.items & ITEM_JetpackRegen.m_itemid) != 0),
maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, frametime * (time > this.pauserotfuel_finished), limitf));
}
MUTATOR_CALLHOOK(SpectateCopy, spectatee, this);
PS(this) = PS(spectatee);
this.armortype = spectatee.armortype;
- SetResourceAmountExplicit(this, RESOURCE_ARMOR, GetResourceAmount(spectatee, RESOURCE_ARMOR));
- SetResourceAmountExplicit(this, RESOURCE_CELLS, GetResourceAmount(spectatee, RESOURCE_CELLS));
- SetResourceAmountExplicit(this, RESOURCE_PLASMA, GetResourceAmount(spectatee, RESOURCE_PLASMA));
- SetResourceAmountExplicit(this, RESOURCE_SHELLS, GetResourceAmount(spectatee, RESOURCE_SHELLS));
- SetResourceAmountExplicit(this, RESOURCE_BULLETS, GetResourceAmount(spectatee, RESOURCE_BULLETS));
- SetResourceAmountExplicit(this, RESOURCE_ROCKETS, GetResourceAmount(spectatee, RESOURCE_ROCKETS));
- SetResourceAmountExplicit(this, RESOURCE_FUEL, GetResourceAmount(spectatee, RESOURCE_FUEL));
+ SetResourceExplicit(this, RES_ARMOR, GetResource(spectatee, RES_ARMOR));
+ SetResourceExplicit(this, RES_CELLS, GetResource(spectatee, RES_CELLS));
+ SetResourceExplicit(this, RES_PLASMA, GetResource(spectatee, RES_PLASMA));
+ SetResourceExplicit(this, RES_SHELLS, GetResource(spectatee, RES_SHELLS));
+ SetResourceExplicit(this, RES_BULLETS, GetResource(spectatee, RES_BULLETS));
+ SetResourceExplicit(this, RES_ROCKETS, GetResource(spectatee, RES_ROCKETS));
+ SetResourceExplicit(this, RES_FUEL, GetResource(spectatee, RES_FUEL));
this.effects = spectatee.effects & EFMASK_CHEAP; // eat performance
- SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(spectatee, RESOURCE_HEALTH));
+ SetResourceExplicit(this, RES_HEALTH, GetResource(spectatee, RES_HEALTH));
CS(this).impulse = 0;
this.items = spectatee.items;
STAT(LAST_PICKUP, this) = STAT(LAST_PICKUP, spectatee);
{
if(PHYS_INPUT_BUTTON_INFO(this)) // BUTTON_INFO hides initial MOTD
CS(this).motd_actived_time = -2; // wait until BUTTON_INFO gets released
- else if(CS(this).motd_actived_time == -2 || IS_PLAYER(this) || IS_SPEC(this))
+ else if (CS(this).motd_actived_time == -2)
{
- // instanctly hide MOTD
+ // instantly hide MOTD
CS(this).motd_actived_time = 0;
Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
}
+ else if (IS_PLAYER(this) || IS_SPEC(this))
+ {
+ // FIXME occasionally for some reason MOTD never goes away
+ // delay MOTD removal a little bit in the hope it fixes this bug
+ if (CS(this).motd_actived_time == -1) // MOTD marked to fade away as soon as client becomes player or spectator
+ CS(this).motd_actived_time = -(5 + floor(random() * 10)); // add small delay
+ else //if (CS(this).motd_actived_time < -2)
+ CS(this).motd_actived_time++;
+ }
}
}
}
this.items_added = 0;
- if ((this.items & ITEM_Jetpack.m_itemid) && ((this.items & ITEM_JetpackRegen.m_itemid) || GetResourceAmount(this, RESOURCE_FUEL) >= 0.01))
+ if ((this.items & ITEM_Jetpack.m_itemid) && ((this.items & ITEM_JetpackRegen.m_itemid) || GetResource(this, RES_FUEL) >= 0.01))
this.items_added |= IT_FUEL;
this.items |= this.items_added;
}
else if(autocvar_g_vehicles_enter)
{
- if(!STAT(FROZEN, this))
- if(!IS_DEAD(this))
- if(!game_stopped)
+ if(!game_stopped && !STAT(FROZEN, this) && !IS_DEAD(this) && !IS_INDEPENDENT_PLAYER(this))
{
entity head, closest_target = NULL;
head = WarpZone_FindRadius(this.origin, autocvar_g_vehicles_enter_radius, true);
while(head) // find the closest acceptable target to enter
{
- if(IS_VEHICLE(head))
- if(!IS_DEAD(head))
+ if(IS_VEHICLE(head) && !IS_DEAD(head) && head.takedamage != DAMAGE_NO)
if(!head.owner || ((head.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(head.owner, this)))
- if(head.takedamage != DAMAGE_NO)
{
if(closest_target)
{
if (this.netname == "" || this.netname != CS(this).netname_previous)
{
bool assume_unchanged = (CS(this).netname_previous == "");
+ if (autocvar_sv_name_maxlength > 0 && strlennocol(this.netname) > autocvar_sv_name_maxlength)
+ {
+ int new_length = textLengthUpToLength(this.netname, autocvar_sv_name_maxlength, strlennocol);
+ this.netname = strzone(strcat(substring(this.netname, 0, new_length), "^7"));
+ sprint(this, sprintf("Warning: your name is longer than %d characters, it has been truncated.\n", autocvar_sv_name_maxlength));
+ assume_unchanged = false;
+ // stuffcmd(this, strcat("name ", this.netname, "\n")); // maybe?
+ }
if (isInvisibleString(this.netname))
{
this.netname = strzone(sprintf("Player#%d", this.playerid));
+ sprint(this, "Warning: invisible names are not allowed.\n");
assume_unchanged = false;
// stuffcmd(this, strcat("name ", this.netname, "\n")); // maybe?
}
if (STAT(FROZEN, this) == FROZEN_TEMP_REVIVING)
{
STAT(REVIVE_PROGRESS, this) = bound(0, STAT(REVIVE_PROGRESS, this) + frametime * this.revive_speed, 1);
- SetResourceAmountExplicit(this, RESOURCE_HEALTH, max(1, STAT(REVIVE_PROGRESS, this) * start_health));
+ SetResourceExplicit(this, RES_HEALTH, max(1, STAT(REVIVE_PROGRESS, this) * start_health));
this.iceblock.alpha = bound(0.2, 1 - STAT(REVIVE_PROGRESS, this), 1);
if (STAT(REVIVE_PROGRESS, this) >= 1)
else if (STAT(FROZEN, this) == FROZEN_TEMP_DYING)
{
STAT(REVIVE_PROGRESS, this) = bound(0, STAT(REVIVE_PROGRESS, this) - frametime * this.revive_speed, 1);
- SetResourceAmountExplicit(this, RESOURCE_HEALTH, max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * STAT(REVIVE_PROGRESS, this)));
+ SetResourceExplicit(this, RES_HEALTH, max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * STAT(REVIVE_PROGRESS, this)));
- if (GetResourceAmount(this, RESOURCE_HEALTH) < 1)
+ if (GetResource(this, RES_HEALTH) < 1)
{
if (this.vehicle)
vehicles_exit(this.vehicle, VHEF_RELEASE);
MUTATOR_CALLHOOK(PlayerPreThink, this);
if(autocvar_g_vehicles_enter && (time > this.last_vehiclecheck) && !game_stopped && !this.vehicle)
- if(IS_PLAYER(this) && !STAT(FROZEN, this) && !IS_DEAD(this))
+ if(IS_PLAYER(this) && !STAT(FROZEN, this) && !IS_DEAD(this) && !IS_INDEPENDENT_PLAYER(this))
{
- FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_vehicles_enter_radius, IS_VEHICLE(it),
+ FOREACH_ENTITY_RADIUS(this.origin, autocvar_g_vehicles_enter_radius, IS_VEHICLE(it) && !IS_DEAD(it) && it.takedamage != DAMAGE_NO,
{
- if(!IS_DEAD(it) && it.takedamage != DAMAGE_NO)
- if((it.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(it.owner, this))
- {
- Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_GUNNER);
- }
- else if(!it.owner)
+ if(!it.owner)
{
if(!it.team || SAME_TEAM(this, it))
Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER);
else if(autocvar_g_vehicles_steal)
Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_STEAL);
}
+ else if((it.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(it.owner, this))
+ {
+ Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_VEHICLE_ENTER_GUNNER);
+ }
});
this.last_vehiclecheck = time + 1;
}
if (this.waypointsprite_attachedforcarrier) {
- vector v = healtharmor_maxdamage(GetResourceAmount(this, RESOURCE_HEALTH), GetResourceAmount(this, RESOURCE_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id);
- WaypointSprite_UpdateHealth(this.waypointsprite_attachedforcarrier, '1 0 0' * v);
- }
+ float hp = healtharmor_maxdamage(GetResource(this, RES_HEALTH), GetResource(this, RES_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x;
+ WaypointSprite_UpdateHealth(this.waypointsprite_attachedforcarrier, hp);
+ }
CSQCMODEL_AUTOUPDATE(this);
}
teamsay = false;
}
- if(game_stopped)
- teamsay = false;
-
if (!source) {
colorstr = "";
teamsay = false;
int privatemsgprefixlen = 0;
if (msgin != "")
{
+ bool found_me = false;
+ if(strstrofs(msgin, "/me", 0) >= 0)
+ {
+ string newmsgin = "";
+ string newnamestr = ((teamsay) ? strcat(colorstr, "(", colorprefix, namestr, colorstr, ")", "^7") : strcat(colorprefix, namestr, "^7"));
+ FOREACH_WORD(msgin, true,
+ {
+ if(strdecolorize(it) == "/me")
+ {
+ found_me = true;
+ newmsgin = cons(newmsgin, newnamestr);
+ }
+ else
+ newmsgin = cons(newmsgin, it);
+ });
+ msgin = newmsgin;
+ }
+
if(privatesay)
{
msgstr = strcat("\{1}\{13}* ", colorprefix, namestr, "^3 tells you: ^7");
}
else if(teamsay)
{
- if(strstrofs(msgin, "/me", 0) >= 0)
+ if(found_me)
{
//msgin = strreplace("/me", "", msgin);
//msgin = substring(msgin, 3, strlen(msgin));
- msgin = strreplace("/me", strcat(colorstr, "(", colorprefix, namestr, colorstr, ")^7"), msgin);
+ //msgin = strreplace("/me", strcat(colorstr, "(", colorprefix, namestr, colorstr, ")^7"), msgin);
msgstr = strcat("\{1}\{13}^4* ", "^7", msgin);
}
else
}
else
{
- if(strstrofs(msgin, "/me", 0) >= 0)
+ if(found_me)
{
//msgin = strreplace("/me", "", msgin);
//msgin = substring(msgin, 3, strlen(msgin));
- msgin = strreplace("/me", strcat(colorprefix, namestr), msgin);
- msgstr = strcat("\{1}^4* ", "^7", msgin);
+ //msgin = strreplace("/me", strcat(colorprefix, namestr), msgin);
+ msgstr = strcat("\{1}^4* ^7", msgin);
}
else {
msgstr = "\{1}";
MUTATOR_CALLHOOK(ChatMessage, source, ret);
ret = M_ARGV(1, int);
+ string event_log_msg = "";
+
if(sourcemsgstr != "" && ret != 0)
{
if(ret < 0) // faked message, because the player is muted
FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source && CS(it).active_minigame == CS(source).active_minigame && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), {
sprint(it, msgstr);
});
+ event_log_msg = sprintf(":chat_minigame:%d:%s:%s", source.playerid, CS(source).active_minigame.netname, msgin);
+
}
else if(teamsay > 0) // team message, only sent to team mates
{
if(cmsgstr != "")
centerprint(it, cmsgstr);
});
+ event_log_msg = sprintf(":chat_team:%d:%d:%s", source.playerid, source.team, strreplace("\n", " ", msgin));
}
else if(teamsay < 0) // spectator message, only sent to spectators
{
FOREACH_CLIENT(!(IS_PLAYER(it) || it.caplayer) && IS_REAL_CLIENT(it) && it != source && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), {
sprint(it, msgstr);
});
+ event_log_msg = sprintf(":chat_spec:%d:%s", source.playerid, strreplace("\n", " ", msgin));
}
else
{
FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), {
sprint(it, msgstr);
});
+ event_log_msg = sprintf(":chat:%d:%s", source.playerid, strreplace("\n", " ", msgin));
}
}
+ if (autocvar_sv_eventlog && (event_log_msg != "")) {
+ GameLogEcho(event_log_msg);
+ }
+
return ret;
}
store.impulse = this.impulse;
this.impulse = 0;
- bool typing = this.buttonchat || this.button14;
+ bool typing = this.buttonchat || this.button12;
store.button0 = (typing) ? 0 : this.button0;
//button1?!