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:
Machiavelli
2012-04-08 17:40:05 +02:00
parent e636531da3
commit bc96df1aae
33 changed files with 153 additions and 82 deletions
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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
-14
View File
@@ -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
{
+1 -1
View File
@@ -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)
+2 -2
View File
@@ -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);
+3 -3
View File
@@ -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);
+2 -2
View File
@@ -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);
}
}
}
+1 -1
View File
@@ -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)
@@ -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);
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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);
}
+66
View File
@@ -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
+1 -9
View File
@@ -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