#include "cl_player.qh"
-#include "bot/bot.qh"
+#include "bot/api.qh"
#include "cheats.qh"
#include "g_damage.qh"
#include "g_subs.qh"
MUTATOR_CALLHOOK(DropSpecialItems, player);
}
-void CopyBody_Think()
-{SELFPARAM();
+void CopyBody_Think(entity this)
+{
if(this.CopyBody_nextthink && time > this.CopyBody_nextthink)
{
- this.CopyBody_think();
+ this.CopyBody_think(this);
if(wasfreed(this))
return;
this.CopyBody_nextthink = this.nextthink;
- this.CopyBody_think = this.think;
- this.think = CopyBody_Think;
+ this.CopyBody_think = getthink(this);
+ setthink(this, CopyBody_Think);
}
CSQCMODEL_AUTOUPDATE(this);
this.nextthink = time;
clone.modelindex = this.modelindex;
clone.skin = this.skin;
clone.species = this.species;
- clone.movetype = this.movetype;
+ clone.move_qcphysics = false; // don't run gamecode logic on clones, too many
+ set_movetype(clone, this.move_movetype);
clone.solid = this.solid;
clone.ballistics_density = this.ballistics_density;
clone.takedamage = this.takedamage;
- clone.customizeentityforclient = this.customizeentityforclient;
+ setcefc(clone, getcefc(this));
clone.uncustomizeentityforclient = this.uncustomizeentityforclient;
clone.uncustomizeentityforclient_set = this.uncustomizeentityforclient_set;
if (keepvelocity == 1)
CSQCMODEL_AUTOINIT(clone);
clone.CopyBody_nextthink = this.nextthink;
- clone.CopyBody_think = this.think;
+ clone.CopyBody_think = getthink(this);
clone.nextthink = time;
- clone.think = CopyBody_Think;
+ setthink(clone, CopyBody_Think);
// "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);
}
-void player_setupanimsformodel()
-{SELFPARAM();
+void player_setupanimsformodel(entity this)
+{
// load animation info
- animdecide_load_if_needed(self);
- animdecide_setstate(self, 0, false);
+ animdecide_load_if_needed(this);
+ animdecide_setstate(this, 0, false);
}
-void player_anim ()
-{SELFPARAM();
+void player_anim(entity this)
+{
int deadbits = (this.anim_state & (ANIMSTATE_DEAD1 | ANIMSTATE_DEAD2));
if(IS_DEAD(this)) {
if (!deadbits) {
int animbits = deadbits;
if(STAT(FROZEN, this))
animbits |= ANIMSTATE_FROZEN;
- if(this.movetype == MOVETYPE_FOLLOW)
+ if(this.move_movetype == MOVETYPE_FOLLOW)
animbits |= ANIMSTATE_FOLLOW;
if(this.crouch)
animbits |= ANIMSTATE_DUCK;
save = v.y;
}
- frag_damage = damage;
- MUTATOR_CALLHOOK(PlayerDamage_SplitHealthArmor, inflictor, attacker, this, force, take, save);
- take = bound(0, damage_take, this.health);
- save = bound(0, damage_save, this.armorvalue);
+ MUTATOR_CALLHOOK(PlayerDamage_SplitHealthArmor, inflictor, attacker, this, force, take, save, deathtype, damage);
+ take = bound(0, M_ARGV(4, float), this.health);
+ save = bound(0, M_ARGV(5, float), this.armorvalue);
excess = max(0, damage - take - save);
if(sound_allowed(MSG_BROADCAST, attacker))
// exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two
{
if(deathtype == DEATH_FALL.m_id)
- PlayerSound(this, playersound_fall, CH_PAIN, VOICETYPE_PLAYERSOUND);
+ PlayerSound(this, playersound_fall, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
else if(this.health > 75)
- PlayerSound(this, playersound_pain100, CH_PAIN, VOICETYPE_PLAYERSOUND);
+ PlayerSound(this, playersound_pain100, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
else if(this.health > 50)
- PlayerSound(this, playersound_pain75, CH_PAIN, VOICETYPE_PLAYERSOUND);
+ PlayerSound(this, playersound_pain75, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
else if(this.health > 25)
- PlayerSound(this, playersound_pain50, CH_PAIN, VOICETYPE_PLAYERSOUND);
+ PlayerSound(this, playersound_pain50, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
else
- PlayerSound(this, playersound_pain25, CH_PAIN, VOICETYPE_PLAYERSOUND);
+ PlayerSound(this, playersound_pain25, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
}
}
}
valid_damage_for_weaponstats = 1;
}
+ dh = dh - max(this.health, 0);
+ da = da - max(this.armorvalue, 0);
if(valid_damage_for_weaponstats)
{
- dh = dh - max(this.health, 0);
- da = da - max(this.armorvalue, 0);
WeaponStats_LogDamage(awep.m_id, abot, PS(this).m_weapon.m_id, vbot, dh + da);
+ }
+ if (dh + da)
+ {
MUTATOR_CALLHOOK(PlayerDamaged, attacker, this, dh, da, hitloc, deathtype);
}
if(sound_allowed(MSG_BROADCAST, attacker))
{
if(deathtype == DEATH_DROWN.m_id)
- PlayerSound(this, playersound_drown, CH_PAIN, VOICETYPE_PLAYERSOUND);
+ PlayerSound(this, playersound_drown, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
else
- PlayerSound(this, playersound_death, CH_PAIN, VOICETYPE_PLAYERSOUND);
+ PlayerSound(this, playersound_death, CH_PAIN, VOL_BASE, VOICETYPE_PLAYERSOUND);
}
// get rid of kill indicator
if(this.killindicator)
{
- remove(this.killindicator);
- this.killindicator = world;
+ delete(this.killindicator);
+ this.killindicator = NULL;
if(this.killindicator_teamchange)
defer_ClientKill_Now_TeamChange = true;
if(accuracy_isgooddamage(attacker, this))
attacker.accuracy.(accuracy_frags[w.m_id-1]) += 1;
- MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype);
- excess = frag_damage;
+ MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, damage);
+ excess = M_ARGV(4, float);
Weapon wep = PS(this).m_weapon;
- WITHSELF(this, wep.wr_playerdeath(wep));
+ /*for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
+ {
+ .entity weaponentity = weaponentities[slot];
+ wep.wr_playerdeath(wep, this, weaponentity);
+ }*/
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+ wep.wr_playerdeath(wep, this, weaponentity);
RemoveGrapplingHook(this);
// view from the floor
this.view_ofs = '0 0 -8';
// toss the corpse
- this.movetype = MOVETYPE_TOSS;
+ set_movetype(this, MOVETYPE_TOSS);
// shootable corpse
this.solid = SOLID_CORPSE;
this.ballistics_density = autocvar_g_ballistics_density_corpse;
// set up to fade out later
SUB_SetFade (this, time + 6 + random (), 1);
// reset body think wrapper broken by SUB_SetFade
- if(this.classname == "body" && this.think != CopyBody_Think) {
- this.CopyBody_think = this.think;
+ if(this.classname == "body" && getthink(this) != CopyBody_Think) {
+ this.CopyBody_think = getthink(this);
this.CopyBody_nextthink = this.nextthink;
- this.think = CopyBody_Think;
+ setthink(this, CopyBody_Think);
this.nextthink = time;
}
// reset fields the weapons may use just in case
FOREACH(Weapons, it != WEP_Null, LAMBDA(
- WITHSELF(this, it.wr_resetplayer(it));
+ it.wr_resetplayer(it, this);
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
{
ATTACK_FINISHED_FOR(this, it.m_id, slot) = 0;
LogTeamchange(client.playerid, client.team, type);
}
+/** print(), but only print if the server is not local */
+void dedicated_print(string input)
+{
+ if (server_is_dedicated) print(input);
+}
+
/**
* message "": do not say, just test flood control
* return value:
if (!teamsay && !privatesay) if (substring(msgin, 0, 1) == " ")
msgin = substring(msgin, 1, -1); // work around DP say bug (say_team does not have this!)
- msgin = formatmessage(msgin);
+ msgin = formatmessage(source, msgin);
string colorstr;
if (!IS_PLAYER(source))
// for now, just give "say" back and only handle say_team
if(!teamsay)
{
- clientcommand(self, strcat("say ", msgin));
+ clientcommand(source, strcat("say ", msgin));
return;
}
*/
sourcecmsgstr = cmsgstr;
}
- if(!privatesay)
- if (!IS_PLAYER(source))
+ if (!privatesay && source && !IS_PLAYER(source))
{
if (!intermission_running)
if(teamsay || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !(warmup_stage || gameover)))
dedicated_print(msgstr); // send to server console too
FOREACH_CLIENT(!IS_PLAYER(it) && IS_REAL_CLIENT(it) && it != source, sprint(it, msgstr));
}
- else {
- if (sourcemsgstr != msgstr) { // trimmed/server fixed message, sent to all players
+ else
+ {
+ if (source) {
sprint(source, sourcemsgstr);
dedicated_print(msgstr); // send to server console too
- FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source, sprint(it, msgstr));
- } else { // entirely normal message, sent to all players -- bprint sends to server console too.
- bprint(msgstr);
+ MX_Say(strcat(playername(source), "^7: ", msgin));
}
- if (source) MX_Say(strcat(playername(source), "^7: ", msgin));
+ FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source, sprint(it, msgstr));
}
}