M_ARGV(4, float) = frag_damage;
}
-void CalculatePlayerScore(entity scorer){
+void FFAMayhemCalculatePlayerScore(entity scorer){
switch (autocvar_g_mayhem_scoringmethod)
{
default:
//total damage divided by player start health&armor to get how many lives worth of damage they've dealt, then how much that is out of the fraglimit, then calculate new value affected by weight
float playerdamagescore = (((((scorer.total_damage_dealt/(start_health + start_armorvalue)) * 100)/autocvar_g_mayhem_fraglimit) * autocvar_g_mayhem_scoringmethod_1_damage_weight) );
- // * 100 to avoid float inaccuracy at that decimal level
+ // * 100 to avoid float inaccuracy at that decimal level
//playerdamagescore rounded
float roundedplayerdamagescore = ((rint(playerdamagescore*10))/10);
//kills minus suicides, total out of fraglimit, calculate weight
float playerkillscore = ((((PlayerScore_Get(scorer, SP_KILLS) - (PlayerScore_Get(scorer, SP_SUICIDES) * suicide_weight)) * 100) / autocvar_g_mayhem_fraglimit) * autocvar_g_mayhem_scoringmethod_1_frag_weight);
- // * 100 to avoid float inaccuracy at that decimal level
+ // * 100 to avoid float inaccuracy at that decimal level
//only used for debug print, add killscore and damagescore together
float playerscore = (roundedplayerdamagescore + playerkillscore);
//calculated how much score the player has and now calculate total of how much they are supposed to have
float scoretoadd = (playerscorevisual - (PlayerScore_Get(scorer, SP_SCORE) * 100));
- // * 100 to avoid float inaccuracy at that decimal level
+ // * 100 to avoid float inaccuracy at that decimal level
//adjust total score to be what the player is supposed to have
- GameRules_scoring_add_team(scorer, SCORE, (scoretoadd / 100));
- // / 100 to move back to the decimal level
+ GameRules_scoring_add_team(scorer, SCORE, floor(scoretoadd / 100));
+ // / 100 to move back to the decimal level
- if(1){
+ if(0){
//debug printing
if(!IS_BOT_CLIENT(scorer)){
print(sprintf("%f", scorer.total_damage_dealt), " scorer.total_damage_dealt \n");
float playerkillscore = (((PlayerScore_Get(scorer, SP_KILLS) - PlayerScore_Get(scorer, SP_SUICIDES)) * 100)/ autocvar_g_mayhem_fraglimit);
float playerscorevisual = (playerkillscore * autocvar_g_mayhem_visual_score_limit) / 100;
float scoretoadd = (playerscorevisual - PlayerScore_Get(scorer, SP_SCORE));
- GameRules_scoring_add_team(scorer, SCORE, scoretoadd);
+ GameRules_scoring_add_team(scorer, SCORE, floor(scoretoadd));
- if(1){
+ if(0){
//debug printing
if(!IS_BOT_CLIENT(scorer)){
print(sprintf("%f", playerkillscore), " playerkillscore \n");
float roundedplayerdamagescore = ((rint(playerdamagescore*10))/10);
float playerscorevisual = (roundedplayerdamagescore * autocvar_g_mayhem_visual_score_limit);
float scoretoadd = (playerscorevisual - (PlayerScore_Get(scorer, SP_SCORE) * 100));
- GameRules_scoring_add_team(scorer, SCORE, (scoretoadd / 100));
+ GameRules_scoring_add_team(scorer, SCORE, floor(scoretoadd / 100));
- if(1){
+ if(0){
//debug printing
if(!IS_BOT_CLIENT(scorer)){
print(sprintf("%f", scorer.total_damage_dealt), " scorer.total_damage_dealt \n");
MUTATOR_HOOKFUNCTION(mayhem, PlayerDamage_SplitHealthArmor)
{
- if(autocvar_g_mayhem_scoringmethod==2)return;
+ if (autocvar_g_mayhem_scoringmethod==2) return;
entity frag_target = M_ARGV(2, entity);
scorer = frag_target;
}
- CalculatePlayerScore(scorer);
+ FFAMayhemCalculatePlayerScore(scorer);
}
MUTATOR_HOOKFUNCTION(mayhem, GiveFragsForKill, CBC_ORDER_FIRST)
entity frag_attacker = M_ARGV(0, entity);
M_ARGV(2, float) = 0; //score to give for the frag directly
- if(IS_PLAYER(frag_attacker))CalculatePlayerScore(frag_attacker);
+ if (IS_PLAYER(frag_attacker)) FFAMayhemCalculatePlayerScore(frag_attacker);
return true;
}
float autocvar_g_tmayhem_start_ammo_plasma = 180;
float autocvar_g_tmayhem_start_ammo_fuel = 0;
+.float total_damage_dealt;
+
// code from here on is just to support maps that don't have team entities
void tmayhem_SpawnTeam (string teamname, int teamcolor)
{
InitializeEntity(NULL, tmayhem_DelayedInit, INITPRIO_GAMETYPE);
}
+// code up to here is just to support maps that don't have team entities
MUTATOR_HOOKFUNCTION(tmayhem, TeamBalance_CheckAllowedTeams, CBC_ORDER_EXCLUSIVE)
{
start_ammo_fuel = warmup_start_ammo_fuel = autocvar_g_tmayhem_start_ammo_fuel;
}
-//this hook also enables rotting, as players spawn with more hp and armor than what default rot limits are set to this is a bad idea as of now
+//this hook also enables rotting, as players spawn with more hp and armor than what default rot limits are set to this is a bad idea as of now until PlayerRegen is changed
MUTATOR_HOOKFUNCTION(tmayhem, PlayerRegen)
{
if(autocvar_g_tmayhem_regenerate)
float frag_damage = M_ARGV(4, float);
float frag_mirrordamage = M_ARGV(5, float);
- if (IS_PLAYER(frag_target))
- if (!IS_DEAD(frag_target))
- if ((autocvar_g_tmayhem_selfdamage == 0 && frag_target == frag_attacker) || frag_deathtype == DEATH_FALL.m_id)
+ if (IS_PLAYER(frag_target)) //don't ever zero damage to non-players
+ if (!IS_DEAD(frag_target)) //enable anyone to gib corpses
+ if ((autocvar_g_tmayhem_selfdamage == 0 && frag_target == frag_attacker) || frag_deathtype == DEATH_FALL.m_id) //nullify self-damage if self-damage is disabled and always nullify splat
frag_damage = 0;
- frag_mirrordamage = 0;
+ frag_mirrordamage = 0; //no mirror damaging
M_ARGV(4, float) = frag_damage;
M_ARGV(5, float) = frag_mirrordamage;
}
-MUTATOR_HOOKFUNCTION(tmayhem, PlayerDamage_SplitHealthArmor)
-{
- switch(autocvar_g_tmayhem_scoringmethod)
+void TeamMayhemCalculatePlayerScore(entity scorer){
+ switch (autocvar_g_tmayhem_scoringmethod)
{
- //frags only
- case 2:
+ default:
+ case 1:
{
- return;
+ //calculate how much score the player should have based on their damage dealt and frags gotten and then add the missing score
+
+ //give a different weight for suicides if scoring method 1 doesn't have selfdamage2score enabled to harshly punish for suicides to avoid exploiting
+ float suicide_weight = 1 + (autocvar_g_tmayhem_scoringmethod_1_disable_selfdamage2score * (1/autocvar_g_tmayhem_scoringmethod_1_frag_weight));
+
+ //total damage divided by player start health&armor to get how many lives worth of damage they've dealt, then how much that is out of the fraglimit, then calculate new value affected by weight
+ float playerdamagescore = (((((scorer.total_damage_dealt/(start_health + start_armorvalue)) * 100)/autocvar_g_tmayhem_fraglimit) * autocvar_g_tmayhem_scoringmethod_1_damage_weight) );
+ // * 100 to avoid float inaccuracy at that decimal level
+
+ //playerdamagescore rounded
+ float roundedplayerdamagescore = ((rint(playerdamagescore*10))/10);
+
+ //kills minus suicides, total out of fraglimit, calculate weight
+ float playerkillscore = ((((PlayerScore_Get(scorer, SP_KILLS) - (PlayerScore_Get(scorer, SP_SUICIDES) * suicide_weight)) * 100) / autocvar_g_tmayhem_fraglimit) * autocvar_g_tmayhem_scoringmethod_1_frag_weight);
+ // * 100 to avoid float inaccuracy at that decimal level
+
+ //only used for debug print, add killscore and damagescore together
+ float playerscore = (roundedplayerdamagescore + playerkillscore);
+
+ //add killscore and damagescore together to get total score and then adjust it to be total out of the visual score limit
+ float playerscorevisual = ((roundedplayerdamagescore + playerkillscore) * autocvar_g_tmayhem_visual_score_limit);
+
+
+ //calculated how much score the player has and now calculate total of how much they are supposed to have
+ float scoretoadd = (playerscorevisual - (PlayerScore_Get(scorer, SP_SCORE) * 100));
+ // * 100 to avoid float inaccuracy at that decimal level
+
+ //adjust total score to be what the player is supposed to have
+ GameRules_scoring_add_team(scorer, SCORE, floor(scoretoadd / 100));
+ // / 100 to move back to the decimal level
+
+ if(0){
+ //debug printing
+ if(!IS_BOT_CLIENT(scorer)){
+ print(sprintf("%f", scorer.total_damage_dealt), " scorer.total_damage_dealt \n");
+ print(sprintf("%f", playerdamagescore), " playerdamagescore \n");
+ print(sprintf("%f", roundedplayerdamagescore), " rounded playerdamagescore \n");
+ print(sprintf("%f", playerkillscore), " playerkillscore \n");
+ print(sprintf("%f", PlayerScore_Get(scorer, SP_KILLS)), " PlayerScore_Get(scorer, SP_KILLS) \n");
+ print(sprintf("%f", playerscore), " playerscore \n");
+ print(sprintf("%f", playerscorevisual), " visual playerscore \n");
+ print(sprintf("%f", scoretoadd), " scoretoadd \n");
+ print(sprintf("%f", PlayerScore_Get(scorer, SP_SCORE)), " PlayerScore_Get(scorer, SP_SCORE) \n \n");
+ }
+ }
+ return;
}
-
- //damage only
- case 3:
+
+ case 2:
{
- entity frag_attacker = M_ARGV(1, entity);
- entity frag_target = M_ARGV(2, entity);
- float frag_deathtype = M_ARGV(6, float);
- float frag_damage = M_ARGV(7, float);
- float damage_take = bound(0, M_ARGV(4, float), GetResource(frag_target, RES_HEALTH));
- float damage_save = bound(0, M_ARGV(5, float), GetResource(frag_target, RES_ARMOR));
-
- float excess = max(0, frag_damage - damage_take - damage_save);
-
- //non-friendly fire
- if (IS_PLAYER(frag_attacker) && !SAME_TEAM(frag_target, frag_attacker))
- GameRules_scoring_add_team(frag_attacker, SCORE, (frag_damage - excess) * tmayhempointmultiplier * (1/(start_health + start_armorvalue)));
-
- //friendly fire or self damage
- if (frag_target == frag_attacker && IS_PLAYER(frag_attacker) || SAME_TEAM(frag_target, frag_attacker))
- GameRules_scoring_add_team(frag_target, SCORE, (-1 * (frag_damage - excess)) * tmayhempointmultiplier * (1/(start_health + start_armorvalue)));
-
- //handle (environmental hazard) suiciding, check first if player has a registered attacker who most likely pushed them there to avoid punishing pushed players as pushers are already rewarded
- //deathtypes:
- //kill = suicide, drown = drown in water/liquid, hurttrigger = out of the map void or hurt triggers inside maps like electric sparks
- //camp = campcheck, lava = lava, slime = slime
- //team change / rebalance suicides are currently not included
- if (!IS_PLAYER(frag_attacker) && (
- frag_deathtype == DEATH_KILL.m_id ||
- frag_deathtype == DEATH_DROWN.m_id ||
- frag_deathtype == DEATH_HURTTRIGGER.m_id ||
- frag_deathtype == DEATH_CAMP.m_id ||
- frag_deathtype == DEATH_LAVA.m_id ||
- frag_deathtype == DEATH_SLIME.m_id))
- GameRules_scoring_add_team(frag_target, SCORE, (-1 * (frag_damage - excess)) * tmayhempointmultiplier * (1/(start_health + start_armorvalue)));
- return;
+ //calculate how much score the player should have based on their frags gotten and then add the missing score
+ float playerkillscore = (((PlayerScore_Get(scorer, SP_KILLS) - PlayerScore_Get(scorer, SP_SUICIDES)) * 100)/ autocvar_g_tmayhem_fraglimit);
+ float playerscorevisual = (playerkillscore * autocvar_g_tmayhem_visual_score_limit) / 100;
+ float scoretoadd = (playerscorevisual - PlayerScore_Get(scorer, SP_SCORE));
+ GameRules_scoring_add_team(scorer, SCORE, floor(scoretoadd));
+
+ if(0){
+ //debug printing
+ if(!IS_BOT_CLIENT(scorer)){
+ print(sprintf("%f", playerkillscore), " playerkillscore \n");
+ print(sprintf("%f", PlayerScore_Get(scorer, SP_KILLS)), " PlayerScore_Get(scorer, SP_KILLS) \n");
+ print(sprintf("%f", playerscorevisual), " visual playerscore \n");
+ print(sprintf("%f", scoretoadd), " scoretoadd \n");
+ print(sprintf("%f", PlayerScore_Get(scorer, SP_SCORE)), " PlayerScore_Get(scorer, SP_SCORE) \n \n");
+ }
+ }
+ return;
}
-
- //combined damage and frags
- default:
- case 1:
+
+ case 3:
{
- entity frag_attacker = M_ARGV(1, entity);
- entity frag_target = M_ARGV(2, entity);
- float frag_deathtype = M_ARGV(6, float);
- float frag_damage = M_ARGV(7, float);
- float damage_take = bound(0, M_ARGV(4, float), GetResource(frag_target, RES_HEALTH));
- float damage_save = bound(0, M_ARGV(5, float), GetResource(frag_target, RES_ARMOR));
-
- float excess = max(0, frag_damage - damage_take - damage_save);
-
- //non-friendly fire
- if (IS_PLAYER(frag_attacker) && !SAME_TEAM(frag_target, frag_attacker))
- GameRules_scoring_add_team(frag_attacker, SCORE, (frag_damage - excess) * autocvar_g_tmayhem_scoringmethod_1_damage_weight * tmayhempointmultiplier * (1/(start_health + start_armorvalue)));
-
- //friendly fire or self damage
- if ((SAME_TEAM(frag_target, frag_attacker) && frag_target != frag_attacker) || (frag_target == frag_attacker && IS_PLAYER(frag_attacker) && !autocvar_g_tmayhem_scoringmethod_1_disable_selfdamage2score))
- GameRules_scoring_add_team(frag_attacker, SCORE, (-1 * (frag_damage - excess)) * autocvar_g_tmayhem_scoringmethod_1_damage_weight * tmayhempointmultiplier * (1/(start_health + start_armorvalue)));
-
- //handle (environmental hazard) suiciding, check first if player has a registered attacker who most likely pushed them there to avoid punishing pushed players as pushers are already rewarded
- //deathtypes:
- //kill = suicide, drown = drown in water/liquid, hurttrigger = out of the map void or hurt triggers inside maps like electric sparks
- //camp = campcheck, lava = lava, slime = slime
- //team change / rebalance suicides are currently not included
- if (!autocvar_g_tmayhem_scoringmethod_1_disable_selfdamage2score && !IS_PLAYER(frag_attacker) && (
- frag_deathtype == DEATH_KILL.m_id ||
- frag_deathtype == DEATH_DROWN.m_id ||
- frag_deathtype == DEATH_HURTTRIGGER.m_id ||
- frag_deathtype == DEATH_CAMP.m_id ||
- frag_deathtype == DEATH_LAVA.m_id ||
- frag_deathtype == DEATH_SLIME.m_id))
- GameRules_scoring_add_team(frag_target, SCORE, (-1 * (frag_damage - excess)) * autocvar_g_tmayhem_scoringmethod_1_damage_weight * tmayhempointmultiplier * (1/(start_health + start_armorvalue)));
- return;
+ //calculate how much score the player should have based on their damage dealt and then add the missing score
+ float playerdamagescore = (((scorer.total_damage_dealt/(start_health + start_armorvalue)) * 100)/autocvar_g_tmayhem_fraglimit);
+ float roundedplayerdamagescore = ((rint(playerdamagescore*10))/10);
+ float playerscorevisual = (roundedplayerdamagescore * autocvar_g_tmayhem_visual_score_limit);
+ float scoretoadd = (playerscorevisual - (PlayerScore_Get(scorer, SP_SCORE) * 100));
+ GameRules_scoring_add_team(scorer, SCORE, floor(scoretoadd / 100));
+
+ if(0){
+ //debug printing
+ if(!IS_BOT_CLIENT(scorer)){
+ print(sprintf("%f", scorer.total_damage_dealt), " scorer.total_damage_dealt \n");
+ print(sprintf("%f", playerdamagescore), " playerdamagescore \n");
+ print(sprintf("%f", roundedplayerdamagescore), " rounded playerdamagescore \n");
+ print(sprintf("%f", playerscorevisual), " visual playerscore \n");
+ print(sprintf("%f", scoretoadd), " scoretoadd \n");
+ print(sprintf("%f", PlayerScore_Get(scorer, SP_SCORE)), " PlayerScore_Get(scorer, SP_SCORE) \n \n");
+ }
+ }
+ return;
}
}
}
-MUTATOR_HOOKFUNCTION(tmayhem, GiveFragsForKill, CBC_ORDER_FIRST)
+MUTATOR_HOOKFUNCTION(tmayhem, PlayerDamage_SplitHealthArmor)
{
- entity frag_attacker = M_ARGV(0, entity);
- entity frag_target = M_ARGV(1, entity);
+ if (autocvar_g_tmayhem_scoringmethod==2) return;
- if(SAME_TEAM(frag_target, frag_attacker)){
- switch(autocvar_g_tmayhem_scoringmethod)
- {
- //frags only
- case 2:
- {
- //fix 999 score from 30 kills for example
- M_ARGV(2, float) = -1 * tmayhempointmultiplier * 1.0001;
- return true;
- }
+ entity frag_target = M_ARGV(2, entity);
- //damage only
- case 3:
- {
- M_ARGV(2, float) = 0;
- return true;
- }
+ if (StatusEffects_active(STATUSEFFECT_SpawnShield, frag_target) && autocvar_g_spawnshield_blockdamage >= 1)return;
+
+ entity frag_attacker = M_ARGV(1, entity);
+ float frag_deathtype = M_ARGV(6, float);
+ float frag_damage = M_ARGV(7, float);
+ float damage_take = bound(0, M_ARGV(4, float), GetResource(frag_target, RES_HEALTH));
+ float damage_save = bound(0, M_ARGV(5, float), GetResource(frag_target, RES_ARMOR));
+ float excess = max(0, frag_damage - damage_take - damage_save);
+ float total = frag_damage - excess;
- //combined damage and frags
- default:
- case 1:
- {
- //when selfdamage2score is disabled don't enable cheap discounted suicides at the cost of the possibility of
- //punishing for a full life when they only deal a single point worth of self damage to kill themselves
- if(autocvar_g_tmayhem_scoringmethod_1_disable_selfdamage2score && frag_target==frag_attacker){
- M_ARGV(2, float) = -1 * tmayhempointmultiplier * 1.0001;
- } else {
- M_ARGV(2, float) = -autocvar_g_tmayhem_scoringmethod_1_frag_weight * tmayhempointmultiplier * 1.0001;
- }
- return true;
- }
- }
- } else {
- switch(autocvar_g_tmayhem_scoringmethod)
- {
- //frags only
- case 2:
- {
- //fix 999 score from 30 kills for example
- M_ARGV(2, float) = 1 * tmayhempointmultiplier * 1.0001;
- return true;
- }
+ if (total == 0) return;
- //damage only
- case 3:
- {
- M_ARGV(2, float) = 0;
- return true;
- }
+ if (StatusEffects_active(STATUSEFFECT_SpawnShield, frag_target) && autocvar_g_spawnshield_blockdamage < 1)
+ total *= 1 - bound(0, autocvar_g_spawnshield_blockdamage, 1);
- //combined damage and frags
- default:
- case 1:
- {
- M_ARGV(2, float) = autocvar_g_tmayhem_scoringmethod_1_frag_weight * tmayhempointmultiplier * 1.0001;
- return true;
- }
- }
+ entity scorer = NULL; //entity which needs their score to be updated
+
+ if (IS_PLAYER(frag_attacker))
+ {
+ //non-friendly fire
+ if (!SAME_TEAM(frag_target, frag_attacker))
+ frag_attacker.total_damage_dealt += total;
+
+ //friendly fire aka self damage
+ if (SAME_TEAM(frag_target, frag_attacker) || (frag_target == frag_attacker && !autocvar_g_tmayhem_scoringmethod_1_disable_selfdamage2score))
+ frag_attacker.total_damage_dealt -= total;
+
+ scorer = frag_attacker;
+ }
+ else
+ {
+ //handle (environmental hazard) suiciding, check first if player has a registered attacker who most likely pushed them there to avoid punishing pushed players as pushers are already rewarded
+ //deathtypes:
+ //kill = suicide, drown = drown in water/liquid, hurttrigger = out of the map void or hurt triggers inside maps like electric sparks
+ //camp = campcheck, lava = lava, slime = slime
+ //team change / rebalance suicides are currently not included
+ if (!autocvar_g_tmayhem_scoringmethod_1_disable_selfdamage2score && (
+ frag_deathtype == DEATH_KILL.m_id ||
+ frag_deathtype == DEATH_DROWN.m_id ||
+ frag_deathtype == DEATH_HURTTRIGGER.m_id ||
+ frag_deathtype == DEATH_CAMP.m_id ||
+ frag_deathtype == DEATH_LAVA.m_id ||
+ frag_deathtype == DEATH_SLIME.m_id ||
+ frag_deathtype == DEATH_SWAMP.m_id))
+ frag_target.total_damage_dealt -= total;
+
+ scorer = frag_target;
}
+
+ TeamMayhemCalculatePlayerScore(scorer);
+}
+
+MUTATOR_HOOKFUNCTION(tmayhem, GiveFragsForKill, CBC_ORDER_FIRST)
+{
+ entity frag_attacker = M_ARGV(0, entity);
+ M_ARGV(2, float) = 0; //score to give for the frag directly
+
+ if (IS_PLAYER(frag_attacker)) TeamMayhemCalculatePlayerScore(frag_attacker);
+
+ return true;
}