X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fplayer.qc;h=cd6c23edb2f764ec325af110c56c55a598ac2294;hp=50708f33eb9b1aa53b0c7ceb7640198990a5df11;hb=050fb0011ae5fb2b36c7c7f3d560f9453807a8ab;hpb=468b023e4b41cbd40bae363aa136b102a63fc811 diff --git a/qcsrc/server/player.qc b/qcsrc/server/player.qc index 50708f33e..cd6c23edb 100644 --- a/qcsrc/server/player.qc +++ b/qcsrc/server/player.qc @@ -97,7 +97,6 @@ void CopyBody(entity this, float keepvelocity) 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; setcefc(clone, getcefc(this)); clone.uncustomizeentityforclient = this.uncustomizeentityforclient; @@ -111,7 +110,6 @@ void CopyBody(entity this, float keepvelocity) //clone.weapon = this.weapon; setorigin(clone, this.origin); setsize(clone, this.mins, this.maxs); - clone.prevorigin = this.origin; clone.reset = SUB_Remove; clone._ps = this._ps; @@ -253,7 +251,7 @@ void calculate_player_respawn_time(entity this) )); if (sdelay_small_count == 0) { - if (g_cts) + if (IS_INDEPENDENT_PLAYER(this)) { // Players play independently. No point in requiring enemies. sdelay_small_count = 1; @@ -266,7 +264,7 @@ void calculate_player_respawn_time(entity this) } if (sdelay_large_count == 0) { - if (g_cts) + if (IS_INDEPENDENT_PLAYER(this)) { // Players play independently. No point in requiring enemies. sdelay_large_count = 1; @@ -311,7 +309,6 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, { float take, save, dh, da; vector v; - float valid_damage_for_weaponstats; float excess; dh = max(this.health, 0); @@ -319,9 +316,9 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, if(!DEATH_ISSPECIAL(deathtype)) { - damage *= sqrt(bound(1.0, this.cvar_cl_handicap, 100.0)); + damage *= bound(1.0, this.cvar_cl_handicap, 10.0); if(this != attacker) - damage /= sqrt(bound(1.0, attacker.cvar_cl_handicap, 100.0)); + damage /= bound(1.0, attacker.cvar_cl_handicap, 10.0); } if (time < this.spawnshieldtime && autocvar_g_spawnshield_blockdamage < 1) @@ -436,7 +433,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, } if(sound_allowed(MSG_BROADCAST, attacker)) - if((this.health < 2 * WEP_CVAR_PRI(blaster, damage) * autocvar_g_balance_selfdamagepercent + 1) || !(DEATH_WEAPONOF(deathtype).spawnflags & WEP_FLAG_CANCLIMB) || attacker != this) // WEAPONTODO: create separate limit for pain notification with laser + if(this.health < 25 || !(DEATH_WEAPONOF(deathtype).spawnflags & WEP_FLAG_CANCLIMB) || take > 20 || attacker != this) if(this.health > 1) // exclude pain sounds for laserjumps as long as you aren't REALLY low on health and would die of the next two { @@ -484,7 +481,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, bool abot = (IS_BOT_CLIENT(attacker)); bool vbot = (IS_BOT_CLIENT(this)); - valid_damage_for_weaponstats = 0; + bool valid_damage_for_weaponstats = false; Weapon awep = WEP_Null; .entity weaponentity = weaponentities[0]; // TODO: unhardcode @@ -497,7 +494,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, awep = attacker.(weaponentity).m_weapon; else awep = DEATH_WEAPONOF(deathtype); - valid_damage_for_weaponstats = 1; + valid_damage_for_weaponstats = true; } dh = dh - max(this.health, 0); @@ -506,10 +503,8 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, { WeaponStats_LogDamage(awep.m_id, abot, this.(weaponentity).m_weapon.m_id, vbot, dh + da); } - if (damage) - { - MUTATOR_CALLHOOK(PlayerDamaged, attacker, this, dh, da, hitloc, deathtype, damage); - } + + MUTATOR_CALLHOOK(PlayerDamaged, attacker, this, dh, da, hitloc, deathtype, damage); if (this.health < 1) { @@ -539,7 +534,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, { delete(this.killindicator); this.killindicator = NULL; - if(this.killindicator_teamchange) + if(CS(this).killindicator_teamchange) defer_ClientKill_Now_TeamChange = true; if(this.classname == "body") @@ -557,15 +552,19 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, // increment frag counter for used weapon type Weapon w = DEATH_WEAPONOF(deathtype); if(w != WEP_Null && accuracy_isgooddamage(attacker, this)) - attacker.accuracy.(accuracy_frags[w.m_id-1]) += 1; + CS(attacker).accuracy.(accuracy_frags[w.m_id-1]) += 1; MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, damage); - excess = M_ARGV(4, float); + damage = M_ARGV(4, float); + excess = max(0, damage - take - save); - Weapon wep = this.(weaponentity).m_weapon; + //Weapon wep = this.(weaponentity).m_weapon; for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { .entity went = weaponentities[slot]; + if(!this.(weaponentity)) + continue; // TODO: clones have no weapon, but we don't want to have to check this all the time + Weapon wep = this.(weaponentity).m_weapon; wep.wr_playerdeath(wep, this, went); } @@ -594,7 +593,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { .entity went = weaponentities[slot]; - SpawnThrownWeapon(this, this.origin + (this.mins + this.maxs) * 0.5, this.(went).m_switchweapon.m_id, went); + SpawnThrownWeapon(this, this.origin + (this.mins + this.maxs) * 0.5, this.(went).m_weapon, went); } // become fully visible @@ -610,12 +609,14 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, set_movetype(this, MOVETYPE_TOSS); // shootable corpse this.solid = SOLID_CORPSE; - this.ballistics_density = autocvar_g_ballistics_density_corpse; + PS(this).ballistics_density = autocvar_g_ballistics_density_corpse; // don't stick to the floor UNSET_ONGROUND(this); // dying animation this.deadflag = DEAD_DYING; + STAT(MOVEVARS_SPECIALCOMMAND, this) = false; // sweet release + // when to allow respawn calculate_player_respawn_time(this); @@ -651,25 +652,34 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage, } // reset fields the weapons may use just in case - FOREACH(Weapons, it != WEP_Null, LAMBDA( - it.wr_resetplayer(it, this); - for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + if(this.classname != "body") + { + FOREACH(Weapons, it != WEP_Null, { - ATTACK_FINISHED_FOR(this, it.m_id, slot) = 0; - } - )); + it.wr_resetplayer(it, this); + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + ATTACK_FINISHED_FOR(this, it.m_id, slot) = 0; + } + }); + } + MUTATOR_CALLHOOK(PlayerDied, this); } } -void MoveToTeam(entity client, int team_colour, int type) +bool 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 + if (!SetPlayerTeamSimple(client, team_colour)) + { + return false; + } 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); + return true; } /** print(), but only print if the server is not local */ @@ -678,6 +688,54 @@ void dedicated_print(string input) if (server_is_dedicated) print(input); } +void PrintToChat(entity player, string text) +{ + text = strcat("\{1}^7", text, "\n"); + sprint(player, text); +} + +void DebugPrintToChat(entity player, string text) +{ + if (autocvar_developer) + { + PrintToChat(player, text); + } +} + +void PrintToChatAll(string text) +{ + text = strcat("\{1}^7", text, "\n"); + bprint(text); +} + +void DebugPrintToChatAll(string text) +{ + if (autocvar_developer) + { + PrintToChatAll(text); + } +} + +void PrintToChatTeam(int teamnum, string text) +{ + text = strcat("\{1}^7", text, "\n"); + FOREACH_CLIENT(IS_REAL_CLIENT(it), + { + if (it.team == teamnum) + { + sprint(it, text); + } + }); +} + +void DebugPrintToChatTeam(int teamnum, string text) +{ + if (autocvar_developer) + { + PrintToChatTeam(teamnum, text); + } +} + /** * message "": do not say, just test flood control * return value: @@ -690,7 +748,8 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc if (!teamsay && !privatesay && substring(msgin, 0, 1) == " ") msgin = substring(msgin, 1, -1); // work around DP say bug (say_team does not have this!) - msgin = formatmessage(source, msgin); + if(source) + msgin = formatmessage(source, msgin); string colorstr; if (!IS_PLAYER(source)) @@ -703,7 +762,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc teamsay = false; } - if(gameover) + if(game_stopped) teamsay = false; if (!source) { @@ -727,7 +786,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc string namestr = ""; if (source) - namestr = autocvar_g_chat_teamcolors ? playername(source) : source.netname; + namestr = playername(source, autocvar_g_chat_teamcolors); string colorprefix = (strdecolorize(namestr) == namestr) ? "^3" : "^7"; @@ -743,10 +802,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc privatemsgprefixlen = strlen(msgstr); msgstr = strcat(msgstr, msgin); cmsgstr = strcat(colorstr, colorprefix, namestr, "^3 tells you:\n^7", msgin); - if(autocvar_g_chat_teamcolors) - privatemsgprefix = strcat("\{1}\{13}* ^3You tell ", playername(privatesay), ": ^7"); - else - privatemsgprefix = strcat("\{1}\{13}* ^3You tell ", privatesay.netname, ": ^7"); + privatemsgprefix = strcat("\{1}\{13}* ^3You tell ", playername(privatesay, autocvar_g_chat_teamcolors), ": ^7"); } else if(teamsay) { @@ -786,7 +842,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc // FLOOD CONTROL int flood = 0; var .float flood_field = floodcontrol_chat; - if(floodcontrol) + if(floodcontrol && source) { float flood_spl; float flood_burst; @@ -880,20 +936,20 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc if (!privatesay && source && !IS_PLAYER(source)) { - if (!gameover) + if (!game_stopped) if (teamsay || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !warmup_stage)) teamsay = -1; // spectators } if(flood) - LOG_INFO("NOTE: ", playername(source), "^7 is flooding.\n"); + LOG_INFO("NOTE: ", playername(source, true), "^7 is flooding.\n"); // build sourcemsgstr by cutting off a prefix and replacing it by the other one if(privatesay) sourcemsgstr = strcat(privatemsgprefix, substring(sourcemsgstr, privatemsgprefixlen, -1)); int ret; - if(source.muted) + if(source && CS(source).muted) { // always fake the message ret = -1; @@ -913,6 +969,13 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc ret = 1; } + if (privatesay && source && !IS_PLAYER(source)) + { + if (!game_stopped) + if ((privatesay && !IS_PLAYER(privatesay)) || (autocvar_g_chat_nospectators == 1) || (autocvar_g_chat_nospectators == 2 && !warmup_stage)) + ret = -1; // just hide the message completely + } + MUTATOR_CALLHOOK(ChatMessage, source, ret); ret = M_ARGV(1, int); @@ -935,11 +998,11 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc centerprint(privatesay, cmsgstr); } } - else if ( teamsay && source.active_minigame ) + else if ( teamsay && CS(source).active_minigame ) { sprint(source, sourcemsgstr); dedicated_print(msgstr); // send to server console too - FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source && it.active_minigame == source.active_minigame && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), sprint(it, msgstr)); + FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source && CS(it).active_minigame == CS(source).active_minigame && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), sprint(it, msgstr)); } else if(teamsay > 0) // team message, only sent to team mates { @@ -964,7 +1027,7 @@ int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodc if (source) { sprint(source, sourcemsgstr); dedicated_print(msgstr); // send to server console too - MX_Say(strcat(playername(source), "^7: ", msgin)); + MX_Say(strcat(playername(source, true), "^7: ", msgin)); } FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), sprint(it, msgstr)); }