X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_player.qc;h=bacb6bcb9e4c5c95cb044333a4056bcbc8e5d22f;hp=6f7c8c2ba17127d904906ede1f1a93491f041519;hb=43eba8ca70f00458db385630f86009f6d7fa849a;hpb=5b22584122d4354ab7819853d0fa5219d14d832e diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index 6f7c8c2ba..bacb6bcb9 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -1,30 +1,40 @@ #include "cl_player.qh" -#include "_all.qh" #include "bot/bot.qh" #include "cheats.qh" #include "g_damage.qh" #include "g_subs.qh" -#include "g_violence.qh" #include "miscfunctions.qh" #include "portals.qh" #include "teamplay.qh" #include "weapons/throwing.qh" #include "command/common.qh" +#include "../common/anim.qh" #include "../common/animdecide.qh" #include "../common/csqcmodel_settings.qh" -#include "../common/deathtypes.qh" +#include "../common/deathtypes/all.qh" #include "../common/triggers/subs.qh" #include "../common/playerstats.qh" -#include "../csqcmodellib/sv_model.qh" +#include "../lib/csqcmodel/sv_model.qh" #include "../common/minigames/sv_minigames.qh" +#include "../common/mutators/mutator/waypoints/waypointsprites.qh" +#include "../common/triggers/include.qh" + #include "weapons/weaponstats.qh" #include "../common/animdecide.qh" -void CopyBody_Think(void) +void Drop_Special_Items(entity player) +{ + // called when the player has become stuck or frozen + // so objective items aren't stuck with the player + + MUTATOR_CALLHOOK(DropSpecialItems, player); +} + +void CopyBody_Think() {SELFPARAM(); if(self.CopyBody_nextthink && time > self.CopyBody_nextthink) { @@ -40,81 +50,78 @@ void CopyBody_Think(void) } void CopyBody(float keepvelocity) {SELFPARAM(); - entity oldself; if (self.effects & EF_NODRAW) return; - oldself = self; - self = spawn(); - self.enemy = oldself; - self.lip = oldself.lip; - self.colormap = oldself.colormap; - self.iscreature = oldself.iscreature; - self.teleportable = oldself.teleportable; - self.damagedbycontents = oldself.damagedbycontents; - self.angles = oldself.angles; - self.v_angle = oldself.v_angle; - self.avelocity = oldself.avelocity; - self.classname = "body"; - self.damageforcescale = oldself.damageforcescale; - self.effects = oldself.effects; - self.glowmod = oldself.glowmod; - self.event_damage = oldself.event_damage; - self.anim_state = oldself.anim_state; - self.anim_time = oldself.anim_time; - self.anim_lower_action = oldself.anim_lower_action; - self.anim_lower_time = oldself.anim_lower_time; - self.anim_upper_action = oldself.anim_upper_action; - self.anim_upper_time = oldself.anim_upper_time; - self.anim_implicit_state = oldself.anim_implicit_state; - self.anim_implicit_time = oldself.anim_implicit_time; - self.anim_lower_implicit_action = oldself.anim_lower_implicit_action; - self.anim_lower_implicit_time = oldself.anim_lower_implicit_time; - self.anim_upper_implicit_action = oldself.anim_upper_implicit_action; - self.anim_upper_implicit_time = oldself.anim_upper_implicit_time; - self.dphitcontentsmask = oldself.dphitcontentsmask; - self.death_time = oldself.death_time; - self.pain_finished = oldself.pain_finished; - self.health = oldself.health; - self.armorvalue = oldself.armorvalue; - self.armortype = oldself.armortype; - self.model = oldself.model; - self.modelindex = oldself.modelindex; - self.skin = oldself.skin; - self.species = oldself.species; - self.movetype = oldself.movetype; - self.solid = oldself.solid; - self.ballistics_density = oldself.ballistics_density; - self.takedamage = oldself.takedamage; - self.customizeentityforclient = oldself.customizeentityforclient; - self.uncustomizeentityforclient = oldself.uncustomizeentityforclient; - self.uncustomizeentityforclient_set = oldself.uncustomizeentityforclient_set; + setself(new(body)); + self.enemy = this; + self.lip = this.lip; + self.colormap = this.colormap; + self.iscreature = this.iscreature; + self.teleportable = this.teleportable; + self.damagedbycontents = this.damagedbycontents; + self.angles = this.angles; + self.v_angle = this.v_angle; + self.avelocity = this.avelocity; + self.damageforcescale = this.damageforcescale; + self.effects = this.effects; + self.glowmod = this.glowmod; + self.event_damage = this.event_damage; + self.anim_state = this.anim_state; + self.anim_time = this.anim_time; + self.anim_lower_action = this.anim_lower_action; + self.anim_lower_time = this.anim_lower_time; + self.anim_upper_action = this.anim_upper_action; + self.anim_upper_time = this.anim_upper_time; + self.anim_implicit_state = this.anim_implicit_state; + self.anim_implicit_time = this.anim_implicit_time; + self.anim_lower_implicit_action = this.anim_lower_implicit_action; + self.anim_lower_implicit_time = this.anim_lower_implicit_time; + self.anim_upper_implicit_action = this.anim_upper_implicit_action; + self.anim_upper_implicit_time = this.anim_upper_implicit_time; + self.dphitcontentsmask = this.dphitcontentsmask; + self.death_time = this.death_time; + self.pain_finished = this.pain_finished; + self.health = this.health; + self.armorvalue = this.armorvalue; + self.armortype = this.armortype; + self.model = this.model; + self.modelindex = this.modelindex; + self.skin = this.skin; + self.species = this.species; + self.movetype = this.movetype; + self.solid = this.solid; + self.ballistics_density = this.ballistics_density; + self.takedamage = this.takedamage; + self.customizeentityforclient = this.customizeentityforclient; + self.uncustomizeentityforclient = this.uncustomizeentityforclient; + self.uncustomizeentityforclient_set = this.uncustomizeentityforclient_set; if (keepvelocity == 1) - self.velocity = oldself.velocity; + self.velocity = this.velocity; self.oldvelocity = self.velocity; - self.alpha = oldself.alpha; - self.fade_time = oldself.fade_time; - self.fade_rate = oldself.fade_rate; - //self.weapon = oldself.weapon; - setorigin(self, oldself.origin); - setsize(self, oldself.mins, oldself.maxs); - self.prevorigin = oldself.origin; + self.alpha = this.alpha; + self.fade_time = this.fade_time; + self.fade_rate = this.fade_rate; + //self.weapon = this.weapon; + setorigin(self, this.origin); + setsize(self, this.mins, this.maxs); + self.prevorigin = this.origin; self.reset = SUB_Remove; - Drag_MoveDrag(oldself, self); + Drag_MoveDrag(this, self); if(self.colormap <= maxclients && self.colormap > 0) - self.colormap = 1024 + oldself.clientcolors; + self.colormap = 1024 + this.clientcolors; CSQCMODEL_AUTOINIT(self); - self.CopyBody_nextthink = oldself.nextthink; - self.CopyBody_think = oldself.think; + self.CopyBody_nextthink = this.nextthink; + self.CopyBody_think = this.think; self.nextthink = time; self.think = CopyBody_Think; // "bake" the current animation frame for clones (they don't get clientside animation) animdecide_load_if_needed(self); animdecide_setframes(self, false, frame, frame1time, frame2, frame2time); - self = oldself; + setself(this); } float player_getspecies() @@ -135,7 +142,7 @@ void player_setupanimsformodel() animdecide_setstate(self, 0, false); } -void player_anim (void) +void player_anim () {SELFPARAM(); int deadbits = (self.anim_state & (ANIMSTATE_DEAD1 | ANIMSTATE_DEAD2)); if(self.deadflag) { @@ -159,13 +166,6 @@ void player_anim (void) animbits |= ANIMSTATE_DUCK; animdecide_setstate(self, animbits, false); animdecide_setimplicitstate(self, (self.flags & FL_ONGROUND)); - - if (self.weaponentity) - { - updateanim(self.weaponentity); - if (!self.weaponentity.animstate_override) - setanim(self.weaponentity, self.weaponentity.anim_idle, true, false, false); - } } void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) @@ -184,11 +184,11 @@ void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, int de if(sound_allowed(MSG_BROADCAST, attacker)) { if (save > 10) - sound (self, CH_SHOTS, "misc/armorimpact.wav", VOL_BASE, ATTEN_NORM); + sound (self, CH_SHOTS, SND_ARMORIMPACT, VOL_BASE, ATTEN_NORM); else if (take > 30) - sound (self, CH_SHOTS, "misc/bodyimpact2.wav", VOL_BASE, ATTEN_NORM); + sound (self, CH_SHOTS, SND_BODYIMPACT2, VOL_BASE, ATTEN_NORM); else if (take > 10) - sound (self, CH_SHOTS, "misc/bodyimpact1.wav", VOL_BASE, ATTEN_NORM); + sound (self, CH_SHOTS, SND_BODYIMPACT1, VOL_BASE, ATTEN_NORM); } if (take > 50) @@ -325,7 +325,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp damage /= sqrt(bound(1.0, attacker.cvar_cl_handicap, 100.0)); } - if(DEATH_ISWEAPON(deathtype, WEP_TUBA.m_id)) + if(DEATH_ISWEAPON(deathtype, WEP_TUBA)) { // tuba causes blood to come out of the ears vector ear1, ear2; @@ -397,11 +397,11 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp if(sound_allowed(MSG_BROADCAST, attacker)) { if (save > 10) - sound (self, CH_SHOTS, "misc/armorimpact.wav", VOL_BASE, ATTEN_NORM); + sound (self, CH_SHOTS, SND_ARMORIMPACT, VOL_BASE, ATTEN_NORM); else if (take > 30) - sound (self, CH_SHOTS, "misc/bodyimpact2.wav", VOL_BASE, ATTEN_NORM); + sound (self, CH_SHOTS, SND_BODYIMPACT2, VOL_BASE, ATTEN_NORM); else if (take > 10) - sound (self, CH_SHOTS, "misc/bodyimpact1.wav", VOL_BASE, ATTEN_NORM); // FIXME possibly remove them? + sound (self, CH_SHOTS, SND_BODYIMPACT1, VOL_BASE, ATTEN_NORM); // FIXME possibly remove them? } if (take > 50) @@ -436,11 +436,11 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp } if(sound_allowed(MSG_BROADCAST, attacker)) - if((self.health < 2 * WEP_CVAR_PRI(blaster, damage) * autocvar_g_balance_selfdamagepercent + 1) || !((get_weaponinfo(DEATH_WEAPONOF(deathtype))).spawnflags & WEP_FLAG_CANCLIMB) || attacker != self) // WEAPONTODO: create separate limit for pain notification with laser + if((self.health < 2 * WEP_CVAR_PRI(blaster, damage) * autocvar_g_balance_selfdamagepercent + 1) || !(DEATH_WEAPONOF(deathtype).spawnflags & WEP_FLAG_CANCLIMB) || attacker != self) // WEAPONTODO: create separate limit for pain notification with laser if(self.health > 1) // 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) + if(deathtype == DEATH_FALL.m_id) PlayerSound(playersound_fall, CH_PAIN, VOICETYPE_PLAYERSOUND); else if(self.health > 75) // TODO make a "gentle" version? PlayerSound(playersound_pain100, CH_PAIN, VOICETYPE_PLAYERSOUND); @@ -471,12 +471,21 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp self.dmg_take = self.dmg_take + take;//max(take - 10, 0); self.dmg_inflictor = inflictor; - float abot, vbot, awep; - abot = (IS_BOT_CLIENT(attacker)); - vbot = (IS_BOT_CLIENT(self)); + if (self != attacker) { + float realdmg = damage - excess; + if (IS_PLAYER(attacker)) { + PlayerScore_Add(attacker, SP_DMG, realdmg); + } + if (IS_PLAYER(self)) { + PlayerScore_Add(self, SP_DMGTAKEN, realdmg); + } + } + + bool abot = (IS_BOT_CLIENT(attacker)); + bool vbot = (IS_BOT_CLIENT(self)); valid_damage_for_weaponstats = 0; - awep = 0; + Weapon awep = WEP_Null; if(vbot || IS_REAL_CLIENT(self)) if(abot || IS_REAL_CLIENT(attacker)) @@ -484,7 +493,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp if(DIFF_TEAM(self, attacker)) { if(DEATH_ISSPECIAL(deathtype)) - awep = attacker.weapon; + awep = get_weaponinfo(attacker.weapon); else awep = DEATH_WEAPONOF(deathtype); valid_damage_for_weaponstats = 1; @@ -494,8 +503,8 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp { dh = dh - max(self.health, 0); da = da - max(self.armorvalue, 0); - WeaponStats_LogDamage(awep, abot, self.weapon, vbot, dh + da); - MUTATOR_CALLHOOK(PlayerDamaged, attacker, self, dh, da, hitloc); + WeaponStats_LogDamage(awep.m_id, abot, self.weapon, vbot, dh + da); + MUTATOR_CALLHOOK(PlayerDamaged, attacker, self, dh, da, hitloc, deathtype); } if (self.health < 1) @@ -510,12 +519,12 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp } if(valid_damage_for_weaponstats) - WeaponStats_LogKill(awep, abot, self.weapon, vbot); + WeaponStats_LogKill(awep.m_id, abot, self.weapon, vbot); if(autocvar_sv_gentle < 1) // TODO make a "gentle" version? if(sound_allowed(MSG_BROADCAST, attacker)) { - if(deathtype == DEATH_DROWN) + if(deathtype == DEATH_DROWN.m_id) PlayerSound(playersound_drown, CH_PAIN, VOICETYPE_PLAYERSOUND); else PlayerSound(playersound_death, CH_PAIN, VOICETYPE_PLAYERSOUND); @@ -530,7 +539,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp defer_ClientKill_Now_TeamChange = true; if(self.classname == "body") - if(deathtype == DEATH_KILL) + if(deathtype == DEATH_KILL.m_id) { // for the lemmings fans, a small harmless explosion Send_Effect(EFFECT_ROCKET_EXPLODE, self.origin, '0 0 0', 1); @@ -542,14 +551,16 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp Obituary (attacker, inflictor, self, deathtype); // increment frag counter for used weapon type - int w = DEATH_WEAPONOF(deathtype); - if(WEP_VALID(w)) + Weapon w = DEATH_WEAPONOF(deathtype); + if(w != WEP_Null) if(accuracy_isgooddamage(attacker, self)) - attacker.accuracy.(accuracy_frags[w-1]) += 1; + attacker.accuracy.(accuracy_frags[w.m_id-1]) += 1; MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, self, deathtype); + excess = frag_damage; - WEP_ACTION(self.weapon, WR_PLAYERDEATH); + Weapon wep = get_weaponinfo(self.weapon); + wep.wr_playerdeath(wep); RemoveGrapplingHook(self); @@ -631,8 +642,12 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp // reset fields the weapons may use just in case for (j = WEP_FIRST; j <= WEP_LAST; ++j) { - WEP_ACTION(j, WR_RESETPLAYER); - ATTACK_FINISHED_FOR(self, j) = 0; + Weapon w = get_weaponinfo(j); + w.wr_resetplayer(w); + for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + ATTACK_FINISHED_FOR(self, j, slot) = 0; + } } } } @@ -892,7 +907,7 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f { sprint(source, sourcemsgstr); dedicated_print(msgstr); // send to server console too - FOR_EACH_REALCLIENT(head) + FOR_EACH_REALCLIENT(head) if(head != source) if(head.active_minigame == source.active_minigame) sprint(head, msgstr); @@ -987,16 +1002,15 @@ void PrecacheGlobalSound(string samplestring) void PrecachePlayerSounds(string f) { - float fh; - string s; - fh = fopen(f, FILE_READ); - if(fh < 0) + int fh = fopen(f, FILE_READ); + if (fh < 0) return; - while((s = fgets(fh))) + for (string s; (s = fgets(fh)); ) { - if(tokenize_console(s) != 3) + int n = tokenize_console(s); + if (n != 3) { - LOG_TRACE("Invalid sound info line: ", s, "\n"); + if (n != 0) LOG_TRACEF("Invalid sound info line: %s\n", s); continue; } PrecacheGlobalSound(strcat(argv(1), " ", argv(2))); @@ -1227,7 +1241,7 @@ void GlobalSound(string sample, float chan, float voicetype) } break; case VOICETYPE_PLAYERSOUND: - sound(self, chan, sample, VOL_BASE, ATTEN_NORM); + _sound(self, chan, sample, VOL_BASE, ATTEN_NORM); break; default: backtrace("Invalid voice type!"); @@ -1242,10 +1256,9 @@ void PlayerSound(.string samplefield, float chan, float voicetype) void VoiceMessage(string type, string msg) {SELFPARAM(); - var .string sample; float voicetype, ownteam; float flood; - sample = GetVoiceMessageSampleField(type); + var .string sample = GetVoiceMessageSampleField(type); if(GetPlayerSoundSampleField_notFound) { @@ -1274,7 +1287,7 @@ void MoveToTeam(entity client, float team_colour, float type) TeamchangeFrags(client); // move the players frags SetPlayerColors(client, team_colour - 1); // set the players colour - Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE, client.origin, '0 0 0'); // kill the player + Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, client.origin, '0 0 0'); // kill the player lockteams = lockteams_backup; // restore the team lock