Core/Spells: Added helper function to select random injured healing spell targets

Port From (https://github.com/TrinityCore/TrinityCore/commit/c0f976d23d7fd9ef687d47ae41bed0924bfdd5c7)
This commit is contained in:
hondacrx
2022-02-24 21:04:12 -05:00
parent 67a79c3777
commit f66e622f1d
2 changed files with 78 additions and 13 deletions
+61
View File
@@ -20,6 +20,7 @@ using Game.Entities;
using Game.Spells; using Game.Spells;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Game.Scripting namespace Game.Scripting
{ {
@@ -866,6 +867,66 @@ namespace Game.Scripting
m_spell.m_customError = result; m_spell.m_customError = result;
} }
public void SelectRandomInjuredTargets(List<WorldObject> targets, uint maxTargets, bool prioritizePlayers)
{
if (targets.Count <= maxTargets)
return;
//List of all player targets.
var tempPlayers = targets.Where(p => p.IsPlayer()).ToList();
//List of all injured non player targets.
var tempInjuredUnits = targets.Where(target => target.IsUnit() && !target.ToUnit().IsFullHealth()).ToList();
//List of all none injured non player targets.
var tempNoneInjuredUnits = targets.Where(target => target.IsUnit() && target.ToUnit().IsFullHealth()).ToList();
targets.Clear();
if (prioritizePlayers)
{
if (tempPlayers.Count < maxTargets)
{
// not enough players, add nonplayer targets
// prioritize injured nonplayers over full health nonplayers
if (tempPlayers.Count + tempInjuredUnits.Count < maxTargets)
{
// not enough players + injured nonplayers
// fill remainder with random full health nonplayers
targets.AddRange(tempPlayers);
targets.AddRange(tempInjuredUnits);
targets.AddRange(tempNoneInjuredUnits.Shuffle());
}
else if (tempPlayers.Count + tempInjuredUnits.Count > maxTargets)
{
// randomize injured nonplayers order
// final list will contain all players + random injured nonplayers
targets.AddRange(tempPlayers);
targets.AddRange(tempInjuredUnits.Shuffle());
}
targets.Resize(maxTargets);
return;
}
}
var lookupPlayers = tempPlayers.ToLookup(target => !target.ToUnit().IsFullHealth());
if (lookupPlayers[true].Count() < maxTargets)
{
// not enough injured units
// fill remainder with full health units
targets.AddRange(lookupPlayers[true]);
targets.AddRange(lookupPlayers[false].Shuffle()));
}
else if (lookupPlayers[true].Count() > maxTargets)
{
// select random injured units
targets.AddRange(lookupPlayers[true].Shuffle());
}
targets.Resize(maxTargets);
}
} }
public class AuraScript : BaseSpellScript public class AuraScript : BaseSpellScript
+17 -13
View File
@@ -177,7 +177,7 @@ namespace Scripts.Spells.Shaman
void ResizeTargets(List<WorldObject> targets) void ResizeTargets(List<WorldObject> targets)
{ {
targets.Resize(3); SelectRandomInjuredTargets(targets, 3, true);
} }
public override void Register() public override void Register()
@@ -310,12 +310,7 @@ namespace Scripts.Spells.Shaman
void FilterTargets(List<WorldObject> targets) void FilterTargets(List<WorldObject> targets)
{ {
uint maxTargets = 6; SelectRandomInjuredTargets(targets, 6, true);
if (targets.Count > maxTargets)
{
targets.Sort(new HealthPctOrderPred());
targets.Resize(maxTargets);
}
} }
void CountEffectivelyHealedTarget() void CountEffectivelyHealedTarget()
@@ -586,18 +581,27 @@ namespace Scripts.Spells.Shaman
OnEffectPeriodic.Add(new EffectPeriodicHandler(HandleEffectPeriodic, 1, AuraType.PeriodicDummy)); OnEffectPeriodic.Add(new EffectPeriodicHandler(HandleEffectPeriodic, 1, AuraType.PeriodicDummy));
} }
} }
[Script] // 73921 - Healing Rain
class spell_sha_healing_rain_target_limit : SpellScript
{
void SelectTargets(List<WorldObject> targets)
{
SelectRandomInjuredTargets(targets, 6, true);
}
public override void Register()
{
OnObjectAreaTargetSelect.Add(new ObjectAreaTargetSelectHandler(SelectTargets, 0, Targets.UnitDestAreaAlly));
}
}
[Script] // 52042 - Healing Stream Totem [Script] // 52042 - Healing Stream Totem
class spell_sha_healing_stream_totem_heal : SpellScript class spell_sha_healing_stream_totem_heal : SpellScript
{ {
void SelectTargets(List<WorldObject> targets) void SelectTargets(List<WorldObject> targets)
{ {
targets.RemoveAll(target => !target.ToUnit() || target.ToUnit().IsFullHealth()); SelectRandomInjuredTargets(targets, 1, true);
targets.RandomResize(1);
if (targets.Empty())
targets.Add(GetOriginalCaster());
} }
public override void Register() public override void Register()