#include <common/effects/all.qh>
#include "bot/api.qh"
#include "cheats.qh"
+#include "clientkill.qh"
#include "g_damage.qh"
#include "handicap.qh"
#include "miscfunctions.qh"
#include "../common/minigames/sv_minigames.qh"
+#include <common/gamemodes/_mod.qh>
+
#include "../common/physics/player.qh"
#include "../common/effects/qc/_mod.qh"
#include "../common/mutators/mutator/waypoints/waypointsprites.qh"
clone.effects = this.effects;
clone.glowmod = this.glowmod;
clone.event_damage = this.event_damage;
+ clone.event_heal = this.event_heal;
clone.anim_state = this.anim_state;
clone.anim_time = this.anim_time;
clone.anim_lower_action = this.anim_lower_action;
if (take > 100)
Violence_GibSplash_At(hitloc, force * -0.2, 3, 1, this, attacker);
- SetResourceAmountExplicit(this, RESOURCE_ARMOR, GetResourceAmount(this, RESOURCE_ARMOR) - save);
- SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - take);
+ TakeResource(this, RESOURCE_ARMOR, save);
+ TakeResource(this, RESOURCE_HEALTH, take);
// pause regeneration for 5 seconds
this.pauseregen_finished = max(this.pauseregen_finished, time + autocvar_g_balance_pause_health_regen);
{
if (!(this.flags & FL_GODMODE))
{
- SetResourceAmountExplicit(this, RESOURCE_ARMOR, GetResourceAmount(this, RESOURCE_ARMOR) - save);
- SetResourceAmountExplicit(this, RESOURCE_HEALTH, GetResourceAmount(this, RESOURCE_HEALTH) - take);
+ TakeResource(this, RESOURCE_ARMOR, save);
+ TakeResource(this, RESOURCE_HEALTH, take);
// pause regeneration for 5 seconds
if(take)
this.pauseregen_finished = max(this.pauseregen_finished, time + autocvar_g_balance_pause_health_regen);
this.v_angle_y = this.v_angle.y + (random() * 2 - 1) * shake;
this.v_angle_x = bound(-90, this.v_angle.x, 90);
}
+
+ if (this != attacker) {
+ float realdmg = damage - excess;
+ if (IS_PLAYER(attacker) && DIFF_TEAM(attacker, this)) {
+ GameRules_scoring_add(attacker, DMG, realdmg);
+ }
+ if (IS_PLAYER(this)) {
+ GameRules_scoring_add(this, DMGTAKEN, realdmg);
+ }
+ }
}
else
this.max_armorvalue += (save + take);
this.dmg_take = this.dmg_take + take;//max(take - 10, 0);
this.dmg_inflictor = inflictor;
- if (this != attacker) {
- float realdmg = damage - excess;
- if (IS_PLAYER(attacker)) {
- GameRules_scoring_add(attacker, DMG, realdmg);
- }
- if (IS_PLAYER(this)) {
- GameRules_scoring_add(this, DMGTAKEN, realdmg);
- }
- }
-
bool abot = (IS_BOT_CLIENT(attacker));
bool vbot = (IS_BOT_CLIENT(this));
if(this.classname != "body")
Obituary (attacker, inflictor, this, deathtype, weaponentity);
- // increment frag counter for used weapon type
- Weapon w = DEATH_WEAPONOF(deathtype);
+ // increment frag counter for used weapon type
+ Weapon w = DEATH_WEAPONOF(deathtype);
if(w != WEP_Null && accuracy_isgooddamage(attacker, this))
CS(attacker).accuracy.(accuracy_frags[w.m_id-1]) += 1;
// when we get here, player actually dies
- Unfreeze(this); // remove any icy remains
- SetResourceAmountExplicit(this, RESOURCE_HEALTH, 0); // Unfreeze resets health, so we need to set it back
+ Unfreeze(this, false); // remove any icy remains
// clear waypoints
WaypointSprite_PlayerDead(this);
// set damage function to corpse damage
this.event_damage = PlayerCorpseDamage;
+ this.event_heal = func_null;
// call the corpse damage function just in case it wants to gib
this.event_damage(this, inflictor, attacker, excess, deathtype, weaponentity, hitloc, force);
}
}
-bool MoveToTeam(entity client, int team_colour, int type)
+bool PlayerHeal(entity targ, entity inflictor, float amount, float limit)
{
- int lockteams_backup = lockteams; // backup any team lock
- lockteams = 0; // disable locked teams
- TeamchangeFrags(client); // move the players frags
- if (!SetPlayerTeamSimple(client, team_colour))
- {
+ if(GetResourceAmount(targ, RESOURCE_HEALTH) <= 0 || GetResourceAmount(targ, RESOURCE_HEALTH) >= limit)
return false;
- }
- Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, DMG_NOWEP, client.origin, '0 0 0'); // kill the player
- lockteams = lockteams_backup; // restore the team lock
- LogTeamchange(client.playerid, client.team, type);
- return true;
-}
-
-/**
- * message "": do not say, just test flood control
- * return value:
- * 1 = accept
- * 0 = reject
- * -1 = fake accept
- */
-int Say(entity source, int teamsay, entity privatesay, string msgin, bool floodcontrol)
-{
- if (!teamsay && !privatesay && substring(msgin, 0, 1) == " ")
- msgin = substring(msgin, 1, -1); // work around DP say bug (say_team does not have this!)
-
- if(source)
- msgin = formatmessage(source, msgin);
-
- string colorstr;
- if (!IS_PLAYER(source))
- colorstr = "^0"; // black for spectators
- else if(teamplay)
- colorstr = Team_ColorCode(source.team);
- else
- {
- colorstr = "";
- teamsay = false;
- }
-
- if(game_stopped)
- teamsay = false;
-
- if (!source) {
- colorstr = "";
- teamsay = false;
- }
-
- if(msgin != "")
- msgin = trigger_magicear_processmessage_forallears(source, teamsay, privatesay, msgin);
-
- /*
- * using bprint solves this... me stupid
- // how can we prevent the message from appearing in a listen server?
- // for now, just give "say" back and only handle say_team
- if(!teamsay)
- {
- clientcommand(source, strcat("say ", msgin));
- return;
- }
- */
-
- string namestr = "";
- if (source)
- namestr = playername(source, autocvar_g_chat_teamcolors);
-
- string colorprefix = (strdecolorize(namestr) == namestr) ? "^3" : "^7";
-
- string msgstr, cmsgstr;
- string privatemsgprefix = string_null;
- int privatemsgprefixlen = 0;
- if (msgin == "") {
- msgstr = cmsgstr = "";
- } else {
- if(privatesay)
- {
- msgstr = strcat("\{1}\{13}* ", colorprefix, namestr, "^3 tells you: ^7");
- privatemsgprefixlen = strlen(msgstr);
- msgstr = strcat(msgstr, msgin);
- cmsgstr = strcat(colorstr, colorprefix, namestr, "^3 tells you:\n^7", msgin);
- privatemsgprefix = strcat("\{1}\{13}* ^3You tell ", playername(privatesay, autocvar_g_chat_teamcolors), ": ^7");
- }
- else if(teamsay)
- {
- if(strstrofs(msgin, "/me", 0) >= 0)
- {
- //msgin = strreplace("/me", "", msgin);
- //msgin = substring(msgin, 3, strlen(msgin));
- msgin = strreplace("/me", strcat(colorstr, "(", colorprefix, namestr, colorstr, ")^7"), msgin);
- msgstr = strcat("\{1}\{13}^4* ", "^7", msgin);
- }
- else
- msgstr = strcat("\{1}\{13}", colorstr, "(", colorprefix, namestr, colorstr, ") ^7", msgin);
- cmsgstr = strcat(colorstr, "(", colorprefix, namestr, colorstr, ")\n^7", msgin);
- }
- else
- {
- if(strstrofs(msgin, "/me", 0) >= 0)
- {
- //msgin = strreplace("/me", "", msgin);
- //msgin = substring(msgin, 3, strlen(msgin));
- msgin = strreplace("/me", strcat(colorprefix, namestr), msgin);
- msgstr = strcat("\{1}^4* ", "^7", msgin);
- }
- else {
- msgstr = "\{1}";
- msgstr = strcat(msgstr, (namestr != "") ? strcat(colorprefix, namestr, "^7: ") : "^7");
- msgstr = strcat(msgstr, msgin);
- }
- cmsgstr = "";
- }
- msgstr = strcat(strreplace("\n", " ", msgstr), "\n"); // newlines only are good for centerprint
- }
-
- string fullmsgstr = msgstr;
- string fullcmsgstr = cmsgstr;
-
- // FLOOD CONTROL
- int flood = 0;
- var .float flood_field = floodcontrol_chat;
- if(floodcontrol && source)
- {
- float flood_spl;
- float flood_burst;
- float flood_lmax;
- float lines;
- if(privatesay)
- {
- flood_spl = autocvar_g_chat_flood_spl_tell;
- flood_burst = autocvar_g_chat_flood_burst_tell;
- flood_lmax = autocvar_g_chat_flood_lmax_tell;
- flood_field = floodcontrol_chattell;
- }
- else if(teamsay)
- {
- flood_spl = autocvar_g_chat_flood_spl_team;
- flood_burst = autocvar_g_chat_flood_burst_team;
- flood_lmax = autocvar_g_chat_flood_lmax_team;
- flood_field = floodcontrol_chatteam;
- }
- else
- {
- flood_spl = autocvar_g_chat_flood_spl;
- flood_burst = autocvar_g_chat_flood_burst;
- flood_lmax = autocvar_g_chat_flood_lmax;
- flood_field = floodcontrol_chat;
- }
- flood_burst = max(0, flood_burst - 1);
- // to match explanation in default.cfg, a value of 3 must allow three-line bursts and not four!
-
- // do flood control for the default line size
- if(msgstr != "")
- {
- getWrappedLine_remaining = msgstr;
- msgstr = "";
- lines = 0;
- while(getWrappedLine_remaining && (!flood_lmax || lines <= flood_lmax))
- {
- msgstr = strcat(msgstr, " ", getWrappedLineLen(82.4289758859709, strlennocol)); // perl averagewidth.pl < gfx/vera-sans.width
- ++lines;
- }
- msgstr = substring(msgstr, 1, strlen(msgstr) - 1);
-
- if(getWrappedLine_remaining != "")
- {
- msgstr = strcat(msgstr, "\n");
- flood = 2;
- }
-
- if (time >= source.(flood_field))
- {
- source.(flood_field) = max(time - flood_burst * flood_spl, source.(flood_field)) + lines * flood_spl;
- }
- else
- {
- flood = 1;
- msgstr = fullmsgstr;
- }
- }
- else
- {
- if (time >= source.(flood_field))
- source.(flood_field) = max(time - flood_burst * flood_spl, source.(flood_field)) + flood_spl;
- else
- flood = 1;
- }
-
- if (timeout_status == TIMEOUT_ACTIVE) // when game is paused, no flood protection
- source.(flood_field) = flood = 0;
- }
-
- string sourcemsgstr, sourcecmsgstr;
- if(flood == 2) // cannot happen for empty msgstr
- {
- if(autocvar_g_chat_flood_notify_flooder)
- {
- sourcemsgstr = strcat(msgstr, "\n^3FLOOD CONTROL: ^7message too long, trimmed\n");
- sourcecmsgstr = "";
- }
- else
- {
- sourcemsgstr = fullmsgstr;
- sourcecmsgstr = fullcmsgstr;
- }
- cmsgstr = "";
- }
- else
- {
- sourcemsgstr = msgstr;
- sourcecmsgstr = cmsgstr;
- }
-
- if (!privatesay && source && !IS_PLAYER(source))
- {
- 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, true), "^7 is flooding.");
-
- // 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 && CS(source).muted)
- {
- // always fake the message
- ret = -1;
- }
- else if(flood == 1)
- {
- if (autocvar_g_chat_flood_notify_flooder)
- {
- sprint(source, strcat("^3FLOOD CONTROL: ^7wait ^1", ftos(source.(flood_field) - time), "^3 seconds\n"));
- ret = 0;
- }
- else
- ret = -1;
- }
- else
- {
- 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);
-
- if(sourcemsgstr != "" && ret != 0)
- {
- if(ret < 0) // faked message, because the player is muted
- {
- sprint(source, sourcemsgstr);
- if(sourcecmsgstr != "" && !privatesay)
- centerprint(source, sourcecmsgstr);
- }
- else if(privatesay) // private message, between 2 people only
- {
- sprint(source, sourcemsgstr);
- if (!autocvar_g_chat_tellprivacy) { dedicated_print(msgstr); } // send to server console too if "tellprivacy" is disabled
- if(!MUTATOR_CALLHOOK(ChatMessageTo, privatesay, source))
- {
- sprint(privatesay, msgstr);
- if(cmsgstr != "")
- centerprint(privatesay, cmsgstr);
- }
- }
- 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 && 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
- {
- sprint(source, sourcemsgstr);
- dedicated_print(msgstr); // send to server console too
- if(sourcecmsgstr != "")
- centerprint(source, sourcecmsgstr);
- FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && it != source && it.team == source.team && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), {
- 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
- FOREACH_CLIENT(!IS_PLAYER(it) && IS_REAL_CLIENT(it) && it != source && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), sprint(it, msgstr));
- }
- else
- {
- if (source) {
- sprint(source, sourcemsgstr);
- dedicated_print(msgstr); // send to server console too
- MX_Say(strcat(playername(source, true), "^7: ", msgin));
- }
- FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != source && !MUTATOR_CALLHOOK(ChatMessageTo, it, source), sprint(it, msgstr));
- }
- }
-
- return ret;
+ GiveResourceWithLimit(targ, RESOURCE_HEALTH, amount, limit);
+ return true;
}