Core/Shared: Move container functions to shared project under Trinity::Container namespace. Also implement RandomResizeList which takes a predicate function as parameter.
Core/ScriptedAI: Extend SummonList::DoAction to take a predicate function as parameter and allow specifying a maximum number of units to be selected.
This commit is contained in:
@@ -223,7 +223,7 @@ class UnitAI
|
||||
targetList.reverse();
|
||||
|
||||
if (targetType == SELECT_TARGET_RANDOM)
|
||||
Trinity::RandomResizeList(targetList, maxTargets);
|
||||
Trinity::Containers::RandomResizeList(targetList, maxTargets);
|
||||
else
|
||||
targetList.resize(maxTargets);
|
||||
}
|
||||
|
||||
@@ -30,18 +30,6 @@ void SummonList::DoZoneInCombat(uint32 entry)
|
||||
}
|
||||
}
|
||||
|
||||
void SummonList::DoAction(uint32 entry, int32 info)
|
||||
{
|
||||
for (iterator i = begin(); i != end();)
|
||||
{
|
||||
Creature* summon = Unit::GetCreature(*me, *i);
|
||||
++i;
|
||||
if (summon && summon->IsAIEnabled
|
||||
&& (!entry || summon->GetEntry() == entry))
|
||||
summon->AI()->DoAction(info);
|
||||
}
|
||||
}
|
||||
|
||||
void SummonList::DespawnEntry(uint32 entry)
|
||||
{
|
||||
for (iterator i = begin(); i != end();)
|
||||
|
||||
@@ -38,7 +38,18 @@ class SummonList : public std::list<uint64>
|
||||
void Despawn(Creature* summon) { remove(summon->GetGUID()); }
|
||||
void DespawnEntry(uint32 entry);
|
||||
void DespawnAll();
|
||||
void DoAction(uint32 entry, int32 info);
|
||||
|
||||
template <class Predicate> void DoAction(int32 info, Predicate& predicate, uint16 max = 0)
|
||||
{
|
||||
Trinity::Containers::RandomResizeList<uint64, Predicate>(*this, predicate, max);
|
||||
for (iterator i = begin(); i != end(); )
|
||||
{
|
||||
Creature* summon = Unit::GetCreature(*me, *i++);
|
||||
if (summon && summon->IsAIEnabled)
|
||||
summon->AI()->DoAction(info);
|
||||
}
|
||||
}
|
||||
|
||||
void DoZoneInCombat(uint32 entry = 0);
|
||||
void RemoveNotExisting();
|
||||
bool HasEntry(uint32 entry);
|
||||
@@ -46,6 +57,22 @@ class SummonList : public std::list<uint64>
|
||||
Creature* me;
|
||||
};
|
||||
|
||||
class EntryCheckPredicate
|
||||
{
|
||||
public:
|
||||
EntryCheckPredicate(uint32 entry) : _entry(entry) {}
|
||||
bool operator()(uint64 guid) { return GUID_ENPART(guid) == _entry; }
|
||||
|
||||
private:
|
||||
uint32 _entry;
|
||||
};
|
||||
|
||||
class DummyEntryCheckPredicate
|
||||
{
|
||||
public:
|
||||
bool operator()(uint64) { return true; }
|
||||
};
|
||||
|
||||
struct ScriptedAI : public CreatureAI
|
||||
{
|
||||
explicit ScriptedAI(Creature* creature);
|
||||
|
||||
@@ -1023,7 +1023,7 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal)
|
||||
// Select a random dungeon from the compatible list
|
||||
// TODO - Select the dungeon based on group item Level, not just random
|
||||
// Create a new proposal
|
||||
pProposal = new LfgProposal(SelectRandomContainerElement(compatibleDungeons));
|
||||
pProposal = new LfgProposal(Trinity::Containers::SelectRandomContainerElement(compatibleDungeons));
|
||||
pProposal->cancelTime = time_t(time(NULL)) + LFG_TIME_PROPOSAL;
|
||||
pProposal->state = LFG_PROPOSAL_INITIATING;
|
||||
pProposal->queues = check;
|
||||
|
||||
@@ -1432,7 +1432,7 @@ void GameObject::Use(Unit* user)
|
||||
if (info->summoningRitual.casterTargetSpell && info->summoningRitual.casterTargetSpell != 1) // No idea why this field is a bool in some cases
|
||||
for (uint32 i = 0; i < info->summoningRitual.casterTargetSpellTargets; i++)
|
||||
// m_unique_users can contain only player GUIDs
|
||||
if (Player* target = ObjectAccessor::GetPlayer(*this, SelectRandomContainerElement(m_unique_users)))
|
||||
if (Player* target = ObjectAccessor::GetPlayer(*this, Trinity::Containers::SelectRandomContainerElement(m_unique_users)))
|
||||
spellCaster->CastSpell(target, info->summoningRitual.casterTargetSpell, true);
|
||||
|
||||
// finish owners spell
|
||||
|
||||
@@ -878,20 +878,6 @@ class WorldObject : public Object, public WorldLocation
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
template<class T>
|
||||
void RandomResizeList(std::list<T> &_list, uint32 _size)
|
||||
{
|
||||
size_t list_size = _list.size();
|
||||
|
||||
while (list_size > _size)
|
||||
{
|
||||
typename std::list<T>::iterator itr = _list.begin();
|
||||
std::advance(itr, urand(0, list_size - 1));
|
||||
_list.erase(itr);
|
||||
--list_size;
|
||||
}
|
||||
}
|
||||
|
||||
// Binary predicate to sort WorldObjects based on the distance to a reference WorldObject
|
||||
class ObjectDistanceOrderPred
|
||||
{
|
||||
|
||||
@@ -14956,7 +14956,7 @@ Unit* Unit::SelectNearbyTarget(Unit* exclude, float dist) const
|
||||
return NULL;
|
||||
|
||||
// select random
|
||||
return SelectRandomContainerElement(targets);
|
||||
return Trinity::Containers::SelectRandomContainerElement(targets);
|
||||
}
|
||||
|
||||
void Unit::ApplyAttackTimePercentMod(WeaponAttackType att, float val, bool apply)
|
||||
|
||||
@@ -479,7 +479,7 @@ void PoolGroup<Quest>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32
|
||||
{
|
||||
do
|
||||
{
|
||||
uint32 questId = SelectRandomContainerElement(currentQuests);
|
||||
uint32 questId = Trinity::Containers::SelectRandomContainerElement(currentQuests);
|
||||
newQuests.insert(questId);
|
||||
currentQuests.erase(questId);
|
||||
} while (newQuests.size() < limit && !currentQuests.empty()); // failsafe
|
||||
@@ -491,7 +491,7 @@ void PoolGroup<Quest>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32
|
||||
// activate <limit> random quests
|
||||
do
|
||||
{
|
||||
uint32 questId = SelectRandomContainerElement(newQuests);
|
||||
uint32 questId = Trinity::Containers::SelectRandomContainerElement(newQuests);
|
||||
spawns.ActivateObject<Quest>(questId, poolId);
|
||||
PoolObject tempObj(questId, 0.0f);
|
||||
Spawn1Object(&tempObj);
|
||||
|
||||
@@ -1055,7 +1055,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
|
||||
if ((*j)->IsAffectedOnSpell(m_spellInfo))
|
||||
maxTargets += (*j)->GetAmount();
|
||||
|
||||
Trinity::RandomResizeList(targets, maxTargets);
|
||||
Trinity::Containers::RandomResizeList(targets, maxTargets);
|
||||
}
|
||||
|
||||
// for compability with older code - add only unit and go targets
|
||||
@@ -1350,7 +1350,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
|
||||
|
||||
if (m_spellInfo->Id == 5246) //Intimidating Shout
|
||||
unitTargets.remove(m_targets.GetUnitTarget());
|
||||
Trinity::RandomResizeList(unitTargets, maxTargets);
|
||||
Trinity::Containers::RandomResizeList(unitTargets, maxTargets);
|
||||
}
|
||||
|
||||
CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex);
|
||||
@@ -1368,7 +1368,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
|
||||
if ((*j)->IsAffectedOnSpell(m_spellInfo))
|
||||
maxTargets += (*j)->GetAmount();
|
||||
|
||||
Trinity::RandomResizeList(gObjTargets, maxTargets);
|
||||
Trinity::Containers::RandomResizeList(gObjTargets, maxTargets);
|
||||
}
|
||||
for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr)
|
||||
AddGOTarget(*itr, effMask);
|
||||
|
||||
@@ -774,7 +774,7 @@ void Spell::EffectDummy(SpellEffIndex effIndex)
|
||||
uint32 maxTargets = std::min<uint32>(3, attackers.size());
|
||||
for (uint32 i = 0; i < maxTargets; ++i)
|
||||
{
|
||||
Unit* attacker = SelectRandomContainerElement(attackers);
|
||||
Unit* attacker = Trinity::Containers::SelectRandomContainerElement(attackers);
|
||||
AddUnitTarget(attacker, 1 << 1);
|
||||
attackers.erase(attacker);
|
||||
}
|
||||
@@ -2008,7 +2008,7 @@ void Spell::EffectEnergize(SpellEffIndex effIndex)
|
||||
if (!avalibleElixirs.empty())
|
||||
{
|
||||
// cast random elixir on target
|
||||
m_caster->CastSpell(unitTarget, SelectRandomContainerElement(avalibleElixirs), true, m_CastItem);
|
||||
m_caster->CastSpell(unitTarget, Trinity::Containers::SelectRandomContainerElement(avalibleElixirs), true, m_CastItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2602,7 +2602,7 @@ void World::SendAutoBroadcast()
|
||||
|
||||
std::string msg;
|
||||
|
||||
msg = SelectRandomContainerElement(m_Autobroadcasts);
|
||||
msg = Trinity::Containers::SelectRandomContainerElement(m_Autobroadcasts);
|
||||
|
||||
uint32 abcenter = sWorld->getIntConfig(CONFIG_AUTOBROADCAST_CENTER);
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ class boss_sulfuron : public CreatureScript
|
||||
{
|
||||
std::list<Creature*> healers = DoFindFriendlyMissingBuff(45.0f, SPELL_INSPIRE);
|
||||
if (!healers.empty())
|
||||
DoCast(SelectRandomContainerElement(healers), SPELL_INSPIRE);
|
||||
DoCast(Trinity::Containers::SelectRandomContainerElement(healers), SPELL_INSPIRE);
|
||||
|
||||
DoCast(me, SPELL_INSPIRE);
|
||||
events.ScheduleEvent(EVENT_INSPIRE, urand(20000, 26000));
|
||||
|
||||
@@ -147,7 +147,7 @@ class boss_moam : public CreatureScript
|
||||
targetList.push_back((*itr)->getTarget());
|
||||
}
|
||||
|
||||
Trinity::RandomResizeList(targetList, 5);
|
||||
Trinity::Containers::RandomResizeList(targetList, 5);
|
||||
|
||||
for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
|
||||
DoCast(*itr, SPELL_DRAIN_MANA);
|
||||
|
||||
@@ -206,7 +206,7 @@ class spell_saviana_conflagration_init : public SpellScriptLoader
|
||||
unitList.remove_if (ConflagrationTargetSelector());
|
||||
uint8 maxSize = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 3);
|
||||
if (unitList.size() > maxSize)
|
||||
Trinity::RandomResizeList(unitList, maxSize);
|
||||
Trinity::Containers::RandomResizeList(unitList, maxSize);
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex effIndex)
|
||||
|
||||
+4
-2
@@ -263,7 +263,8 @@ public:
|
||||
if (instance)
|
||||
instance->SetData(TYPE_ANUBARAK, IN_PROGRESS);
|
||||
//Despawn Scarab Swarms neutral
|
||||
Summons.DoAction(NPC_SCARAB, ACTION_SCARAB_SUBMERGE);
|
||||
EntryCheckPredicate pred(NPC_SCARAB);
|
||||
Summons.DoAction(ACTION_SCARAB_SUBMERGE, pred);
|
||||
//Spawn Burrow
|
||||
for (int i=0; i < 4; i++)
|
||||
me->SummonCreature(NPC_BURROW, AnubarakLoc[i+2]);
|
||||
@@ -304,7 +305,8 @@ public:
|
||||
|
||||
if (IsHeroic() && m_uiNerubianShadowStrikeTimer <= uiDiff)
|
||||
{
|
||||
Summons.DoAction(NPC_BURROWER, ACTION_SHADOW_STRIKE);
|
||||
EntryCheckPredicate pred(NPC_BURROWER);
|
||||
Summons.DoAction(ACTION_SHADOW_STRIKE, pred);
|
||||
m_uiNerubianShadowStrikeTimer = 30*IN_MILLISECONDS;
|
||||
} else m_uiNerubianShadowStrikeTimer -= uiDiff;
|
||||
|
||||
|
||||
@@ -386,7 +386,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
|
||||
++targetCount;
|
||||
if (Is25ManRaid())
|
||||
++targetCount;
|
||||
Trinity::RandomResizeList<Player*>(targets, targetCount);
|
||||
Trinity::Containers::RandomResizeList<Player*>(targets, targetCount);
|
||||
if (targets.size() > 1)
|
||||
{
|
||||
Talk(SAY_PACT_OF_THE_DARKFALLEN);
|
||||
@@ -409,7 +409,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
|
||||
{
|
||||
std::list<Player*> targets;
|
||||
SelectRandomTarget(false, &targets);
|
||||
Trinity::RandomResizeList<Player*>(targets, uint32(Is25ManRaid() ? 4 : 2));
|
||||
Trinity::Containers::RandomResizeList<Player*>(targets, uint32(Is25ManRaid() ? 4 : 2));
|
||||
for (std::list<Player*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
|
||||
DoCast(*itr, SPELL_TWILIGHT_BLOODBOLT);
|
||||
DoCast(me, SPELL_TWILIGHT_BLOODBOLT_TARGET);
|
||||
@@ -481,7 +481,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
|
||||
return tempTargets.front();
|
||||
}
|
||||
|
||||
return SelectRandomContainerElement(tempTargets);
|
||||
return Trinity::Containers::SelectRandomContainerElement(tempTargets);
|
||||
}
|
||||
|
||||
std::set<uint64> _vampires;
|
||||
@@ -658,7 +658,7 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader
|
||||
{
|
||||
uint32 targetCount = (targets.size() + 2) / 3;
|
||||
targets.remove_if (BloodboltHitCheck(static_cast<LanaThelAI*>(GetCaster()->GetAI())));
|
||||
Trinity::RandomResizeList(targets, targetCount);
|
||||
Trinity::Containers::RandomResizeList(targets, targetCount);
|
||||
// mark targets now, effect hook has missile travel time delay (might cast next in that time)
|
||||
for (std::list<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
|
||||
GetCaster()->GetAI()->SetGUID((*itr)->GetGUID(), GUID_BLOODBOLT);
|
||||
|
||||
@@ -1272,7 +1272,7 @@ class spell_deathbringer_boiling_blood : public SpellScriptLoader
|
||||
if (unitList.empty())
|
||||
return;
|
||||
|
||||
Unit* target = SelectRandomContainerElement(unitList);
|
||||
Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList);
|
||||
unitList.clear();
|
||||
unitList.push_back(target);
|
||||
}
|
||||
|
||||
@@ -605,7 +605,7 @@ class boss_lady_deathwhisper : public CreatureScript
|
||||
return;
|
||||
|
||||
// select random cultist
|
||||
Creature* cultist = SelectRandomContainerElement(temp);
|
||||
Creature* cultist = Trinity::Containers::SelectRandomContainerElement(temp);
|
||||
DoCast(cultist, cultist->GetEntry() == NPC_CULT_FANATIC ? SPELL_DARK_TRANSFORMATION_T : SPELL_DARK_EMPOWERMENT_T, true);
|
||||
Talk(uint8(cultist->GetEntry() == NPC_CULT_FANATIC ? SAY_DARK_TRANSFORMATION : SAY_DARK_EMPOWERMENT));
|
||||
}
|
||||
|
||||
@@ -781,7 +781,7 @@ class spell_putricide_ooze_channel : public SpellScriptLoader
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* target = SelectRandomContainerElement(targetList);
|
||||
Unit* target = Trinity::Containers::SelectRandomContainerElement(targetList);
|
||||
targetList.clear();
|
||||
targetList.push_back(target);
|
||||
_target = target;
|
||||
|
||||
@@ -498,7 +498,7 @@ class spell_rotface_mutated_infection : public SpellScriptLoader
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
Unit* target = SelectRandomContainerElement(targets);
|
||||
Unit* target = Trinity::Containers::SelectRandomContainerElement(targets);
|
||||
targets.clear();
|
||||
targets.push_back(target);
|
||||
_target = target;
|
||||
|
||||
@@ -329,6 +329,7 @@ class boss_sindragosa : public CreatureScript
|
||||
events.ScheduleEvent(EVENT_LAND_GROUND, 1);
|
||||
break;
|
||||
case POINT_LAND_GROUND:
|
||||
{
|
||||
me->SetCanFly(false);
|
||||
me->SetDisableGravity(false);
|
||||
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
|
||||
@@ -337,8 +338,10 @@ class boss_sindragosa : public CreatureScript
|
||||
me->GetMotionMaster()->MovementExpired();
|
||||
_isInAirPhase = false;
|
||||
// trigger Asphyxiation
|
||||
summons.DoAction(NPC_ICE_TOMB, ACTION_TRIGGER_ASPHYXIATION);
|
||||
EntryCheckPredicate pred(NPC_ICE_TOMB);
|
||||
summons.DoAction(ACTION_TRIGGER_ASPHYXIATION, pred);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1097,7 +1100,7 @@ class spell_sindragosa_unchained_magic : public SpellScriptLoader
|
||||
unitList.remove_if(UnchainedMagicTargetSelector());
|
||||
uint32 maxSize = uint32(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 2);
|
||||
if (unitList.size() > maxSize)
|
||||
Trinity::RandomResizeList(unitList, maxSize);
|
||||
Trinity::Containers::RandomResizeList(unitList, maxSize);
|
||||
}
|
||||
|
||||
void Register()
|
||||
@@ -1401,7 +1404,7 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader
|
||||
if (unitList.empty())
|
||||
return;
|
||||
|
||||
Unit* target = SelectRandomContainerElement(unitList);
|
||||
Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList);
|
||||
unitList.clear();
|
||||
unitList.push_back(target);
|
||||
}
|
||||
@@ -1418,7 +1421,7 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader
|
||||
if (unitList.empty())
|
||||
return;
|
||||
|
||||
SelectRandomContainerElement(unitList)->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
|
||||
Trinity::Containers::SelectRandomContainerElement(unitList)->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
|
||||
}
|
||||
|
||||
void Register()
|
||||
|
||||
@@ -554,7 +554,8 @@ class boss_the_lich_king : public CreatureScript
|
||||
if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
|
||||
tirion->AI()->EnterEvadeMode();
|
||||
DoCastAOE(SPELL_KILL_FROSTMOURNE_PLAYERS);
|
||||
summons.DoAction(NPC_STRANGULATE_VEHICLE, ACTION_TELEPORT_BACK);
|
||||
EntryCheckPredicate pred(NPC_STRANGULATE_VEHICLE);
|
||||
summons.DoAction(ACTION_TELEPORT_BACK, pred);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
@@ -595,12 +596,15 @@ class boss_the_lich_king : public CreatureScript
|
||||
events.ScheduleEvent(EVENT_OUTRO_TALK_8, 17000, 0, PHASE_OUTRO);
|
||||
break;
|
||||
case ACTION_TELEPORT_BACK:
|
||||
summons.DoAction(NPC_STRANGULATE_VEHICLE, ACTION_TELEPORT_BACK);
|
||||
{
|
||||
EntryCheckPredicate pred(NPC_STRANGULATE_VEHICLE);
|
||||
summons.DoAction(ACTION_TELEPORT_BACK, pred);
|
||||
if (!IsHeroic())
|
||||
Talk(SAY_LK_FROSTMOURNE_ESCAPE);
|
||||
else
|
||||
DoCastAOE(SPELL_TRIGGER_VILE_SPIRIT_HEROIC);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -2550,7 +2554,7 @@ class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader
|
||||
if (unitList.empty())
|
||||
return;
|
||||
|
||||
_target = SelectRandomContainerElement(unitList);
|
||||
_target = Trinity::Containers::SelectRandomContainerElement(unitList);
|
||||
unitList.clear();
|
||||
unitList.push_back(_target);
|
||||
GetCaster()->GetAI()->SetGUID(_target->GetGUID());
|
||||
@@ -2758,7 +2762,7 @@ class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoa
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
_target = SelectRandomContainerElement(targets);
|
||||
_target = Trinity::Containers::SelectRandomContainerElement(targets);
|
||||
}
|
||||
|
||||
void HandleScript(SpellEffIndex effIndex)
|
||||
|
||||
@@ -1196,7 +1196,7 @@ class spell_dreamwalker_summoner : public SpellScriptLoader
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
Unit* target = SelectRandomContainerElement(targets);
|
||||
Unit* target = Trinity::Containers::SelectRandomContainerElement(targets);
|
||||
targets.clear();
|
||||
targets.push_back(target);
|
||||
}
|
||||
@@ -1242,7 +1242,7 @@ class spell_dreamwalker_summon_suppresser : public SpellScriptLoader
|
||||
std::list<Creature*> summoners;
|
||||
GetCreatureListWithEntryInGrid(summoners, caster, NPC_WORLD_TRIGGER, 100.0f);
|
||||
summoners.remove_if (Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));
|
||||
Trinity::RandomResizeList(summoners, 2);
|
||||
Trinity::Containers::RandomResizeList(summoners, 2);
|
||||
if (summoners.empty())
|
||||
return;
|
||||
|
||||
|
||||
@@ -1368,7 +1368,7 @@ class npc_captain_arnath : public CreatureScript
|
||||
case EVENT_ARNATH_PW_SHIELD:
|
||||
{
|
||||
std::list<Creature*> targets = DoFindFriendlyMissingBuff(40.0f, SPELL_POWER_WORD_SHIELD);
|
||||
DoCast(SelectRandomContainerElement(targets), SPELL_POWER_WORD_SHIELD);
|
||||
DoCast(Trinity::Containers::SelectRandomContainerElement(targets), SPELL_POWER_WORD_SHIELD);
|
||||
Events.ScheduleEvent(EVENT_ARNATH_PW_SHIELD, urand(15000, 20000));
|
||||
break;
|
||||
}
|
||||
@@ -1822,7 +1822,7 @@ class spell_frost_giant_death_plague : public SpellScriptLoader
|
||||
unitList.remove_if (DeathPlagueTargetSelector(GetCaster()));
|
||||
if (!unitList.empty())
|
||||
{
|
||||
Unit* target = SelectRandomContainerElement(unitList);
|
||||
Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList);
|
||||
unitList.clear();
|
||||
unitList.push_back(target);
|
||||
}
|
||||
@@ -1909,7 +1909,7 @@ class spell_svalna_revive_champion : public SpellScriptLoader
|
||||
void RemoveAliveTarget(std::list<Unit*>& unitList)
|
||||
{
|
||||
unitList.remove_if(AliveCheck());
|
||||
Trinity::RandomResizeList(unitList, 2);
|
||||
Trinity::Containers::RandomResizeList(unitList, 2);
|
||||
}
|
||||
|
||||
void Land(SpellEffIndex /*effIndex*/)
|
||||
|
||||
@@ -424,7 +424,8 @@ class boss_gothik : public CreatureScript
|
||||
{
|
||||
if (instance)
|
||||
instance->SetData(DATA_GOTHIK_GATE, GO_STATE_ACTIVE);
|
||||
summons.DoAction(0, 0);
|
||||
DummyEntryCheckPredicate pred;
|
||||
summons.DoAction(0, pred); //! Magic numbers fail
|
||||
summons.DoZoneInCombat();
|
||||
mergedSides = true;
|
||||
}
|
||||
@@ -447,7 +448,8 @@ class boss_gothik : public CreatureScript
|
||||
DoScriptText(SAY_TELEPORT, me);
|
||||
DoTeleportTo(PosGroundLiveSide);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
summons.DoAction(0, 0);
|
||||
DummyEntryCheckPredicate pred;
|
||||
summons.DoAction(0, pred); //! Magic numbers fail
|
||||
summons.DoZoneInCombat();
|
||||
events.ScheduleEvent(EVENT_BOLT, 1000);
|
||||
events.ScheduleEvent(EVENT_HARVEST, urand(3000, 15000));
|
||||
|
||||
@@ -1678,7 +1678,7 @@ class spell_pursue : public SpellScriptLoader
|
||||
else
|
||||
{
|
||||
//! In the end, only one target should be selected
|
||||
_target = SelectRandomContainerElement(targets);
|
||||
_target = Trinity::Containers::SelectRandomContainerElement(targets);
|
||||
FilterTargetsSubsequently(targets);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,7 +290,7 @@ class boss_general_vezax : public CreatureScript
|
||||
if (size < playersMin)
|
||||
return NULL;
|
||||
|
||||
return SelectRandomContainerElement(PlayerList);
|
||||
return Trinity::Containers::SelectRandomContainerElement(PlayerList);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -139,7 +139,7 @@ class boss_emalon : public CreatureScript
|
||||
case EVENT_OVERCHARGE:
|
||||
if (!summons.empty())
|
||||
{
|
||||
Creature* minion = Unit::GetCreature(*me, SelectRandomContainerElement(summons));
|
||||
Creature* minion = Unit::GetCreature(*me, Trinity::Containers::SelectRandomContainerElement(summons));
|
||||
if (minion && minion->isAlive())
|
||||
{
|
||||
minion->CastSpell(me, SPELL_OVERCHARGED, true);
|
||||
|
||||
@@ -134,7 +134,8 @@ public:
|
||||
if (!phase || phase == PHASE_CHASE)
|
||||
{
|
||||
phase = PHASE_STRIKE;
|
||||
summons.DoAction(EVENT_VOLCANO, 0);
|
||||
DummyEntryCheckPredicate pred;
|
||||
summons.DoAction(EVENT_VOLCANO, pred);
|
||||
events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE);
|
||||
me->SetSpeed(MOVE_RUN, 1.2f);
|
||||
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
|
||||
|
||||
@@ -812,7 +812,7 @@ public:
|
||||
}
|
||||
if (!UnitsWithMana.empty())
|
||||
{
|
||||
DoCast(SelectRandomContainerElement(UnitsWithMana), SPELL_MANA_BURN);
|
||||
DoCast(Trinity::Containers::SelectRandomContainerElement(UnitsWithMana), SPELL_MANA_BURN);
|
||||
ManaBurnTimer = 8000 + (rand() % 10 * 1000); // 8-18 sec cd
|
||||
}
|
||||
else
|
||||
|
||||
@@ -250,7 +250,7 @@ class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* target = SelectRandomContainerElement(tempTargets);
|
||||
Unit* target = Trinity::Containers::SelectRandomContainerElement(tempTargets);
|
||||
unitList.clear();
|
||||
unitList.push_back(target);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TRINITY_CONTAINERS_H
|
||||
#define TRINITY_CONTAINERS_H
|
||||
|
||||
namespace Trinity
|
||||
{
|
||||
namespace Containers
|
||||
{
|
||||
template<class T>
|
||||
void RandomResizeList(std::list<T> &list, uint32 size)
|
||||
{
|
||||
size_t list_size = list.size();
|
||||
|
||||
while (list_size > size)
|
||||
{
|
||||
typename std::list<T>::iterator itr = list.begin();
|
||||
std::advance(itr, urand(0, list_size - 1));
|
||||
list.erase(itr);
|
||||
--list_size;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class Predicate>
|
||||
void RandomResizeList(std::list<T> &list, Predicate& predicate, uint32 size)
|
||||
{
|
||||
//! First use predicate filter
|
||||
std::list<T> listCopy;
|
||||
for (typename std::list<T>::iterator itr = list.begin(); itr != list.end(); ++itr)
|
||||
if (predicate(*itr))
|
||||
listCopy.push_back(*itr);
|
||||
|
||||
if (size)
|
||||
RandomResizeList(listCopy, size);
|
||||
|
||||
list = listCopy;
|
||||
}
|
||||
|
||||
/* Select a random element from a container. Note: make sure you explicitly empty check the container */
|
||||
template <class C> typename C::value_type const& SelectRandomContainerElement(C const& container)
|
||||
{
|
||||
typename C::const_iterator it = container.begin();
|
||||
std::advance(it, urand(0, container.size() - 1));
|
||||
return *it;
|
||||
}
|
||||
};
|
||||
//! namespace Containers
|
||||
};
|
||||
//! namespace Trinity
|
||||
|
||||
#endif //! #ifdef TRINITY_CONTAINERS_H
|
||||
@@ -20,7 +20,7 @@
|
||||
#define _UTIL_H
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#include "Containers.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -653,12 +653,4 @@ public:
|
||||
};
|
||||
};
|
||||
|
||||
/* Select a random element from a container. Note: make sure you explicitly empty check the container */
|
||||
template <class C> typename C::value_type const& SelectRandomContainerElement(C const& container)
|
||||
{
|
||||
typename C::const_iterator it = container.begin();
|
||||
std::advance(it, urand(0, container.size() - 1));
|
||||
return *it;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user