X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_player.qc;h=e194b026f9dd1b802e115a6b67f389c9d1c97798;hb=d95afcf1229a11a7198936683998d16a1c2500d7;hp=b8b3618de1cb3c8301aa79bd08a25b2cd261db69;hpb=9e92e0e5bdad9052ff3463f67f3fb5a2ab812ed2;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_player.qc b/qcsrc/server/cl_player.qc index b8b3618de..e194b026f 100644 --- a/qcsrc/server/cl_player.qc +++ b/qcsrc/server/cl_player.qc @@ -4,12 +4,12 @@ #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/all.qh" @@ -34,7 +34,7 @@ void Drop_Special_Items(entity player) MUTATOR_CALLHOOK(DropSpecialItems, player); } -void CopyBody_Think(void) +void CopyBody_Think() {SELFPARAM(); if(self.CopyBody_nextthink && time > self.CopyBody_nextthink) { @@ -52,7 +52,7 @@ void CopyBody(float keepvelocity) {SELFPARAM(); if (self.effects & EF_NODRAW) return; - setself(spawn()); + setself(new(body)); self.enemy = this; self.lip = this.lip; self.colormap = this.colormap; @@ -62,7 +62,6 @@ void CopyBody(float keepvelocity) self.angles = this.angles; self.v_angle = this.v_angle; self.avelocity = this.avelocity; - self.classname = "body"; self.damageforcescale = this.damageforcescale; self.effects = this.effects; self.glowmod = this.glowmod; @@ -125,17 +124,6 @@ void CopyBody(float keepvelocity) setself(this); } -float player_getspecies() -{SELFPARAM(); - float s; - get_model_parameters(self.model, self.skin); - s = get_model_parameters_species; - get_model_parameters(string_null, 0); - if(s < 0) - return SPECIES_HUMAN; - return s; -} - void player_setupanimsformodel() {SELFPARAM(); // load animation info @@ -143,7 +131,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) { @@ -166,7 +154,7 @@ void player_anim (void) if(self.crouch) animbits |= ANIMSTATE_DUCK; animdecide_setstate(self, animbits, false); - animdecide_setimplicitstate(self, (self.flags & FL_ONGROUND)); + animdecide_setimplicitstate(self, (IS_ONGROUND(self))); } void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) @@ -221,8 +209,8 @@ void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, int de } } -void calculate_player_respawn_time() -{SELFPARAM(); +void calculate_player_respawn_time(entity this) +{ if(g_ca) return; @@ -235,13 +223,12 @@ void calculate_player_respawn_time() float waves = GAMETYPE_DEFAULTED_SETTING(respawn_waves); float pcount = 1; // Include myself whether or not team is already set right and I'm a "player". - entity pl; if (teamplay) { - FOR_EACH_PLAYER(pl) - if (pl != self) - if (pl.team == self.team) - ++pcount; + FOREACH_CLIENT(IS_PLAYER(it) && it != this, LAMBDA( + if(it.team == this.team) + ++pcount; + )); if (sdelay_small_count == 0) sdelay_small_count = 1; if (sdelay_large_count == 0) @@ -249,9 +236,9 @@ void calculate_player_respawn_time() } else { - FOR_EACH_PLAYER(pl) - if (pl != self) - ++pcount; + FOREACH_CLIENT(IS_PLAYER(it) && it != this, LAMBDA( + ++pcount; + )); if (sdelay_small_count == 0) { if (g_cts) @@ -290,28 +277,27 @@ void calculate_player_respawn_time() sdelay = sdelay_small + (sdelay_large - sdelay_small) * (pcount - sdelay_small_count) / (sdelay_large_count - sdelay_small_count); if(waves) - self.respawn_time = ceil((time + sdelay) / waves) * waves; + this.respawn_time = ceil((time + sdelay) / waves) * waves; else - self.respawn_time = time + sdelay; + this.respawn_time = time + sdelay; if(sdelay < sdelay_max) - self.respawn_time_max = time + sdelay_max; + this.respawn_time_max = time + sdelay_max; else - self.respawn_time_max = self.respawn_time; + this.respawn_time_max = this.respawn_time; - if((sdelay + waves >= 5.0) && (self.respawn_time - time > 1.75)) - self.respawn_countdown = 10; // first number to count down from is 10 + if((sdelay + waves >= 5.0) && (this.respawn_time - time > 1.75)) + this.respawn_countdown = 10; // first number to count down from is 10 else - self.respawn_countdown = -1; // do not count down + this.respawn_countdown = -1; // do not count down if(autocvar_g_forced_respawn) - self.respawn_flags = self.respawn_flags | RESPAWN_FORCE; + this.respawn_flags = this.respawn_flags | RESPAWN_FORCE; } void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) {SELFPARAM(); float take, save, dh, da; - int j; vector v; float valid_damage_for_weaponstats; float excess; @@ -442,15 +428,15 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp // 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(playersound_fall, CH_PAIN, VOICETYPE_PLAYERSOUND); + PlayerSound(self, playersound_fall, CH_PAIN, VOICETYPE_PLAYERSOUND); else if(self.health > 75) // TODO make a "gentle" version? - PlayerSound(playersound_pain100, CH_PAIN, VOICETYPE_PLAYERSOUND); + PlayerSound(self, playersound_pain100, CH_PAIN, VOICETYPE_PLAYERSOUND); else if(self.health > 50) - PlayerSound(playersound_pain75, CH_PAIN, VOICETYPE_PLAYERSOUND); + PlayerSound(self, playersound_pain75, CH_PAIN, VOICETYPE_PLAYERSOUND); else if(self.health > 25) - PlayerSound(playersound_pain50, CH_PAIN, VOICETYPE_PLAYERSOUND); + PlayerSound(self, playersound_pain50, CH_PAIN, VOICETYPE_PLAYERSOUND); else - PlayerSound(playersound_pain25, CH_PAIN, VOICETYPE_PLAYERSOUND); + PlayerSound(self, playersound_pain25, CH_PAIN, VOICETYPE_PLAYERSOUND); } } } @@ -481,7 +467,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp PlayerScore_Add(self, SP_DMGTAKEN, realdmg); } } - + bool abot = (IS_BOT_CLIENT(attacker)); bool vbot = (IS_BOT_CLIENT(self)); @@ -494,7 +480,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp if(DIFF_TEAM(self, attacker)) { if(DEATH_ISSPECIAL(deathtype)) - awep = get_weaponinfo(attacker.weapon); + awep = PS(attacker).m_weapon; else awep = DEATH_WEAPONOF(deathtype); valid_damage_for_weaponstats = 1; @@ -504,7 +490,7 @@ 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.m_id, abot, self.weapon, vbot, dh + da); + WeaponStats_LogDamage(awep.m_id, abot, PS(self).m_weapon.m_id, vbot, dh + da); MUTATOR_CALLHOOK(PlayerDamaged, attacker, self, dh, da, hitloc, deathtype); } @@ -520,15 +506,15 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp } if(valid_damage_for_weaponstats) - WeaponStats_LogKill(awep.m_id, abot, self.weapon, vbot); + WeaponStats_LogKill(awep.m_id, abot, PS(self).m_weapon.m_id, vbot); if(autocvar_sv_gentle < 1) // TODO make a "gentle" version? if(sound_allowed(MSG_BROADCAST, attacker)) { if(deathtype == DEATH_DROWN.m_id) - PlayerSound(playersound_drown, CH_PAIN, VOICETYPE_PLAYERSOUND); + PlayerSound(self, playersound_drown, CH_PAIN, VOICETYPE_PLAYERSOUND); else - PlayerSound(playersound_death, CH_PAIN, VOICETYPE_PLAYERSOUND); + PlayerSound(self, playersound_death, CH_PAIN, VOICETYPE_PLAYERSOUND); } // get rid of kill indicator @@ -560,7 +546,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, self, deathtype); excess = frag_damage; - Weapon wep = get_weaponinfo(self.weapon); + Weapon wep = PS(self).m_weapon; wep.wr_playerdeath(wep); RemoveGrapplingHook(self); @@ -585,7 +571,7 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp // clear waypoints WaypointSprite_PlayerDead(); // throw a weapon - SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, self.switchweapon); + SpawnThrownWeapon (self.origin + (self.mins + self.maxs) * 0.5, PS(self).m_switchweapon.m_id); // become fully visible self.alpha = default_player_alpha; @@ -602,12 +588,12 @@ void PlayerDamage (entity inflictor, entity attacker, float damage, int deathtyp self.solid = SOLID_CORPSE; self.ballistics_density = autocvar_g_ballistics_density_corpse; // don't stick to the floor - self.flags &= ~FL_ONGROUND; + UNSET_ONGROUND(self); // dying animation self.deadflag = DEAD_DYING; // when to allow respawn - calculate_player_respawn_time(); + calculate_player_respawn_time(this); self.death_time = time; if (random() < 0.5) @@ -641,29 +627,39 @@ 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) - { - Weapon w = get_weaponinfo(j); - w.wr_resetplayer(w); - for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + FOREACH(Weapons, it != WEP_Null, LAMBDA( + it.wr_resetplayer(it); + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { - ATTACK_FINISHED_FOR(self, j, slot) = 0; + ATTACK_FINISHED_FOR(self, it.m_id, slot) = 0; } - } + )); } } -float Say(entity source, float teamsay, entity privatesay, string msgin, float floodcontrol) -// message "": do not say, just test flood control -// return value: -// 1 = accept -// 0 = reject -// -1 = fake accept +void MoveToTeam(entity client, int team_colour, int type) +{ + int lockteams_backup = lockteams; // backup any team lock + lockteams = 0; // disable locked teams + TeamchangeFrags(client); // move the players frags + SetPlayerColors(client, team_colour - 1); // set the players colour + Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, client.origin, '0 0 0'); // kill the player + lockteams = lockteams_backup; // restore the team lock + LogTeamchange(client.playerid, client.team, type); +} + +/** + * message "": do not say, just test flood control + * return value: + * 1 = accept + * 0 = reject + * -1 = fake accept + */ +int Say(entity source, float teamsay, entity privatesay, string msgin, bool floodcontrol) { string msgstr, colorstr, cmsgstr, namestr, fullmsgstr, sourcemsgstr, fullcmsgstr, sourcecmsgstr, colorprefix; float flood; var .float flood_field; - entity head; float ret; string privatemsgprefix = string_null; float privatemsgprefixlen = 0; @@ -908,10 +904,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) - if(head != source) - if(head.active_minigame == source.active_minigame) - sprint(head, msgstr); + FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source && it.active_minigame == source.active_minigame, LAMBDA(sprint(it, msgstr))); } else if(teamsay > 0) // team message, only sent to team mates { @@ -919,29 +912,23 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f dedicated_print(msgstr); // send to server console too if(sourcecmsgstr != "") centerprint(source, sourcecmsgstr); - FOR_EACH_REALPLAYER(head) if(head.team == source.team) - if(head != source) - { - sprint(head, msgstr); - if(cmsgstr != "") - centerprint(head, cmsgstr); - } + FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it != source && it.team == source.team, LAMBDA( + sprint(it, msgstr); + if(cmsgstr != "") + centerprint(it, cmsgstr); + )); } else if(teamsay < 0) // spectator message, only sent to spectators { sprint(source, sourcemsgstr); dedicated_print(msgstr); // send to server console too - FOR_EACH_REALCLIENT(head) if (!IS_PLAYER(head)) - if(head != source) - sprint(head, msgstr); + FOREACH_CLIENT(!IS_PLAYER(it) && IS_REAL_CLIENT(it) && it != source, LAMBDA(sprint(it, msgstr))); } else if(sourcemsgstr != msgstr) // trimmed/server fixed message, sent to all players { sprint(source, sourcemsgstr); dedicated_print(msgstr); // send to server console too - FOR_EACH_REALCLIENT(head) - if(head != source) - sprint(head, msgstr); + FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source, LAMBDA(sprint(it, msgstr))); } else bprint(msgstr); // entirely normal message, sent to all players -- bprint sends to server console too. @@ -949,348 +936,3 @@ float Say(entity source, float teamsay, entity privatesay, string msgin, float f return ret; } - -float GetVoiceMessageVoiceType(string type) -{ - if(type == "taunt") - return VOICETYPE_TAUNT; - if(type == "teamshoot") - return VOICETYPE_LASTATTACKER; - return VOICETYPE_TEAMRADIO; -} - -.string GetVoiceMessageSampleField(string type) -{ - GetPlayerSoundSampleField_notFound = 0; - switch(type) - { -#define _VOICEMSG(m) case #m: return playersound_##m; - ALLVOICEMSGS -#undef _VOICEMSG - } - GetPlayerSoundSampleField_notFound = 1; - return playersound_taunt; -} - -.string GetPlayerSoundSampleField(string type) -{ - GetPlayerSoundSampleField_notFound = 0; - switch(type) - { -#define _VOICEMSG(m) case #m: return playersound_##m; - ALLPLAYERSOUNDS -#undef _VOICEMSG - } - GetPlayerSoundSampleField_notFound = 1; - return playersound_taunt; -} - -void PrecacheGlobalSound(string samplestring) -{ - float n, i; - tokenize_console(samplestring); - n = stof(argv(1)); - if(n > 0) - { - for(i = 1; i <= n; ++i) - precache_sound(strcat(argv(0), ftos(i), ".wav")); - } - else - { - precache_sound(strcat(argv(0), ".wav")); - } -} - -void PrecachePlayerSounds(string f) -{ - int fh = fopen(f, FILE_READ); - if (fh < 0) - return; - for (string s; (s = fgets(fh)); ) - { - int n = tokenize_console(s); - if (n != 3) - { - if (n != 0) LOG_TRACEF("Invalid sound info line: %s\n", s); - continue; - } - PrecacheGlobalSound(strcat(argv(1), " ", argv(2))); - } - fclose(fh); - - if (!allvoicesamples) - { -#define _VOICEMSG(m) allvoicesamples = strcat(allvoicesamples, " ", #m); - ALLVOICEMSGS -#undef _VOICEMSG - allvoicesamples = strzone(substring(allvoicesamples, 1, strlen(allvoicesamples) - 1)); - } -} - -void ClearPlayerSounds() -{SELFPARAM(); -#define _VOICEMSG(m) if(self.playersound_##m) { strunzone(self.playersound_##m); self.playersound_##m = string_null; } - ALLPLAYERSOUNDS - ALLVOICEMSGS -#undef _VOICEMSG -} - -float LoadPlayerSounds(string f, float first) -{SELFPARAM(); - float fh; - string s; - var .string field; - fh = fopen(f, FILE_READ); - if(fh < 0) - { - LOG_TRACE("Player sound file not found: ", f, "\n"); - return 0; - } - while((s = fgets(fh))) - { - if(tokenize_console(s) != 3) - continue; - field = GetPlayerSoundSampleField(argv(0)); - if(GetPlayerSoundSampleField_notFound) - field = GetVoiceMessageSampleField(argv(0)); - if(GetPlayerSoundSampleField_notFound) - continue; - if (self.(field)) - strunzone(self.(field)); - self.(field) = strzone(strcat(argv(1), " ", argv(2))); - } - fclose(fh); - return 1; -} - -void UpdatePlayerSounds() -{SELFPARAM(); - if(self.modelindex == self.modelindex_for_playersound) - if(self.skin == self.skin_for_playersound) - return; - self.modelindex_for_playersound = self.modelindex; - self.skin_for_playersound = self.skin; - ClearPlayerSounds(); - LoadPlayerSounds("sound/player/default.sounds", 1); - if(!autocvar_g_debug_defaultsounds) - if(!LoadPlayerSounds(get_model_datafilename(self.model, self.skin, "sounds"), 0)) - LoadPlayerSounds(get_model_datafilename(self.model, 0, "sounds"), 0); -} - -void FakeGlobalSound(string sample, float chan, float voicetype) -{SELFPARAM(); - float n; - float tauntrand; - - if(sample == "") - return; - - tokenize_console(sample); - n = stof(argv(1)); - if(n > 0) - sample = strcat(argv(0), ftos(floor(random() * n + 1)), ".wav"); // randomization - else - sample = strcat(argv(0), ".wav"); // randomization - - switch(voicetype) - { - case VOICETYPE_LASTATTACKER_ONLY: - break; - case VOICETYPE_LASTATTACKER: - if(self.pusher) - { - msg_entity = self; - if(IS_REAL_CLIENT(msg_entity)) - soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NONE); - } - break; - case VOICETYPE_TEAMRADIO: - msg_entity = self; - if(msg_entity.cvar_cl_voice_directional == 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN); - else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); - break; - case VOICETYPE_AUTOTAUNT: - if(!sv_autotaunt) - break; - if(!sv_taunt) - break; - if(autocvar_sv_gentle) - break; - tauntrand = random(); - msg_entity = self; - if (tauntrand < msg_entity.cvar_cl_autotaunt) - { - if (msg_entity.cvar_cl_voice_directional >= 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX)); - else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); - } - break; - case VOICETYPE_TAUNT: - if(IS_PLAYER(self)) - if(self.deadflag == DEAD_NO) - animdecide_setaction(self, ANIMACTION_TAUNT, true); - if(!sv_taunt) - break; - if(autocvar_sv_gentle) - break; - msg_entity = self; - if (msg_entity.cvar_cl_voice_directional >= 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX)); - else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); - break; - case VOICETYPE_PLAYERSOUND: - msg_entity = self; - soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NORM); - break; - default: - backtrace("Invalid voice type!"); - break; - } -} - -void GlobalSound(string sample, float chan, float voicetype) -{SELFPARAM(); - float n; - float tauntrand; - - if(sample == "") - return; - - tokenize_console(sample); - n = stof(argv(1)); - if(n > 0) - sample = strcat(argv(0), ftos(floor(random() * n + 1)), ".wav"); // randomization - else - sample = strcat(argv(0), ".wav"); // randomization - - switch(voicetype) - { - case VOICETYPE_LASTATTACKER_ONLY: - if(self.pusher) - { - msg_entity = self.pusher; - if(IS_REAL_CLIENT(msg_entity)) - { - if(msg_entity.cvar_cl_voice_directional == 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN); - else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); - } - } - break; - case VOICETYPE_LASTATTACKER: - if(self.pusher) - { - msg_entity = self.pusher; - if(IS_REAL_CLIENT(msg_entity)) - { - if(msg_entity.cvar_cl_voice_directional == 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN); - else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); - } - msg_entity = self; - if(IS_REAL_CLIENT(msg_entity)) - soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NONE); - } - break; - case VOICETYPE_TEAMRADIO: - FOR_EACH_REALCLIENT(msg_entity) - if(!teamplay || msg_entity.team == self.team) - { - if(msg_entity.cvar_cl_voice_directional == 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN); - else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); - } - break; - case VOICETYPE_AUTOTAUNT: - if(!sv_autotaunt) - break; - if(!sv_taunt) - break; - if(autocvar_sv_gentle) - break; - tauntrand = random(); - FOR_EACH_REALCLIENT(msg_entity) - if (tauntrand < msg_entity.cvar_cl_autotaunt) - { - if (msg_entity.cvar_cl_voice_directional >= 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX)); - else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); - } - break; - case VOICETYPE_TAUNT: - if(IS_PLAYER(self)) - if(self.deadflag == DEAD_NO) - animdecide_setaction(self, ANIMACTION_TAUNT, true); - if(!sv_taunt) - break; - if(autocvar_sv_gentle) - break; - FOR_EACH_REALCLIENT(msg_entity) - { - if (msg_entity.cvar_cl_voice_directional >= 1) - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX)); - else - soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE); - } - break; - case VOICETYPE_PLAYERSOUND: - _sound(self, chan, sample, VOL_BASE, ATTEN_NORM); - break; - default: - backtrace("Invalid voice type!"); - break; - } -} - -void PlayerSound(.string samplefield, float chan, float voicetype) -{SELFPARAM(); - GlobalSound(self.(samplefield), chan, voicetype); -} - -void VoiceMessage(string type, string msg) -{SELFPARAM(); - float voicetype, ownteam; - float flood; - var .string sample = GetVoiceMessageSampleField(type); - - if(GetPlayerSoundSampleField_notFound) - { - sprint(self, strcat("Invalid voice. Use one of: ", allvoicesamples, "\n")); - return; - } - - voicetype = GetVoiceMessageVoiceType(type); - ownteam = (voicetype == VOICETYPE_TEAMRADIO); - - flood = Say(self, ownteam, world, msg, 1); - - if (IS_SPEC(self) || IS_OBSERVER(self) || flood < 0) - FakeGlobalSound(self.(sample), CH_VOICE, voicetype); - else if (flood > 0) - GlobalSound(self.(sample), CH_VOICE, voicetype); -} - -void MoveToTeam(entity client, float team_colour, float type) -{ - float lockteams_backup; - - lockteams_backup = lockteams; // backup any team lock - - lockteams = 0; // disable locked teams - - TeamchangeFrags(client); // move the players frags - SetPlayerColors(client, team_colour - 1); // set the players colour - Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, client.origin, '0 0 0'); // kill the player - - lockteams = lockteams_backup; // restore the team lock - - LogTeamchange(client.playerid, client.team, type); -}