Core/Spells: implement summon properties parameter types based on the leaked enumerated strings values

Summon spells can now be commanded to interpret their basepoints depending on the parameter type that has been assigned to the summon properties dbc record Id

* implemented SummonCreatureExtraArgs to reduce the amount of arguments in Map::SummonCreature
This commit is contained in:
Ovahlord committed 2021-08-15 10:35:02 +02:00
1 parent c927ca98ba
commit 8ac7e71690
14 files changed
+305 -100

No files matched your search

@@ -0,0 +1,88 @@
DROP TABLE IF EXISTS `summon_properties_parameters`;
CREATE TABLE `summon_properties_parameters` (
`RecID` int UNSIGNED NOT NULL COMMENT 'SummonProperties.dbc Identifier',
`ParamType` tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`RecID`)
);
INSERT INTO `summon_properties_parameters` (`RecID`, `ParamType`) VALUES
-- Converted values from Spell::EffectSummonType and some new additions
(65, 7),
(64, 2),
(61, 2),
(67, 2),
(711, 1),
(81, 1),
(63, 1),
(1761, 2),
(41, 2),
(2909, 2),
(1101, 2),
(66, 2),
(648, 2),
(2301, 2),
(1061, 2),
(1261, 2),
(629, 2),
(181, 2),
(715, 2),
(1562, 2),
(833, 2),
(1161, 2),
(713, 2),
(3097, 2),
(2929, 2),
-- Vehicles (summon properties control 4)
(161, 4), -- Most spells with that ID use bp = 0 but one does actually use a ride spell so we can assume a RIDE_VEHICLE_HARDCODED fallback for parameter 4
(327, 3),
(367, 3),
(467, 3),
(488, 4), -- Ride spell
(493, 3),
(607, 4), -- Ride spell
(689, 4), -- Ride spell
(708, 4), -- Ride Spell
(710, 4), -- Ride Spell
(716, 4), -- Ride Spell
(718, 4), -- Ride Spell
(760, 4), -- Ride Spell
(780, 3),
(801, 4), -- Ride Spell
(824, 4), -- Ride Spell
(827, 4), -- Ride Spell
(843, 4), -- Ride Spell
(861, 4), -- Ride Spell
(1081, 4), -- Ride Spell
(1201, 3),
(1281, 4), -- Ride Spell
(1321, 3),
(1541, 4), -- Ride Spell
(1601, 4), -- Ride Spell
(1621, 4), -- Ride Spell
(1641, 3),
(1821, 4), -- Ride Spell
(1861, 3),
(2321, 3),
(2601, 3),
(2742, 3),
(2914, 3),
(2932, 4), -- Ride Spell
(2933, 3),
(2947, 3),
(2948, 4), -- Ride Spell
(2976, 3),
(2977, 3),
(2986, 3),
(3006, 3),
(3021, 4), -- Ride Spell
(3033, 3),
(3035, 4), -- Ride Spell
(3038, 4), -- Ride Spell
(3090, 4), -- Ride Spell
(3099, 4), -- Ride Spell
(3105, 4), -- Ride Spell
(3112, 4), -- Ride Spell
(3118, 3),
(3131, 3),
(3134, 4), -- Ride Spell
(3144, 3);
+35 -24
View File
@@ -2021,12 +2021,13 @@ void WorldObject::AddObjectToRemoveList()
map->AddObjectToRemoveList(this);
}
TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, Unit* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/, ObjectGuid privateObjectOwner /*= ObjectGuid::Empty*/, uint32 health /*= 0*/)
TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonCreatureExtraArgs const& summonArgs /*= { }*/)
{
uint32 mask = UNIT_MASK_SUMMON;
if (properties)
if (summonArgs.SummonProperties)
{
switch (properties->Control)
switch (summonArgs.SummonProperties->Control)
{
case SUMMON_CATEGORY_PET:
mask = UNIT_MASK_GUARDIAN;
@@ -2041,7 +2042,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
case SUMMON_CATEGORY_ALLY:
case SUMMON_CATEGORY_UNK:
{
switch (SummonTitle(properties->Title))
switch (SummonTitle(summonArgs.SummonProperties->Title))
{
case SummonTitle::Minion:
case SummonTitle::Guardian:
@@ -2060,7 +2061,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
mask = UNIT_MASK_MINION;
break;
default:
if (properties->Flags & 512) // Mirror Image, Summon Gargoyle
if (summonArgs.SummonProperties->Flags & 512) // Mirror Image, Summon Gargoyle
mask = UNIT_MASK_GUARDIAN;
break;
}
@@ -2075,33 +2076,33 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
switch (mask)
{
case UNIT_MASK_SUMMON:
summon = new TempSummon(properties, summoner, false);
summon = new TempSummon(summonArgs.SummonProperties, summonArgs.Summoner, false);
break;
case UNIT_MASK_GUARDIAN:
summon = new Guardian(properties, summoner, false);
summon = new Guardian(summonArgs.SummonProperties, summonArgs.Summoner, false);
break;
case UNIT_MASK_PUPPET:
summon = new Puppet(properties, summoner);
summon = new Puppet(summonArgs.SummonProperties, summonArgs.Summoner);
break;
case UNIT_MASK_TOTEM:
summon = new Totem(properties, summoner);
summon = new Totem(summonArgs.SummonProperties, summonArgs.Summoner);
break;
case UNIT_MASK_MINION:
summon = new Minion(properties, summoner, false);
summon = new Minion(summonArgs.SummonProperties, summonArgs.Summoner, false);
break;
}
// Create creature entity
if (!summon->Create(GenerateLowGuid<HighGuid::Unit>(), this, entry, pos, nullptr, vehId, true))
if (!summon->Create(GenerateLowGuid<HighGuid::Unit>(), this, entry, pos, nullptr, summonArgs.VehicleRecID, true))
{
delete summon;
return nullptr;
}
// Add summon to transport if summoner is on a transport as well
if (summon->GetTransGUID().IsEmpty() && summoner)
if (summon->GetTransGUID().IsEmpty() && summonArgs.Summoner)
{
if (Transport* transport = summoner->GetTransport())
if (Transport* transport = summonArgs.Summoner->GetTransport())
{
float x, y, z, o;
pos.GetPosition(x, y, z, o);
@@ -2113,22 +2114,26 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert
}
// Inherit summoner's Phaseshift
if (summoner)
PhasingHandler::InheritPhaseShift(summon, summoner);
if (summonArgs.Summoner)
PhasingHandler::InheritPhaseShift(summon, summonArgs.Summoner);
// Initialize tempsummon fields
summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId);
summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, summonArgs.SummonSpellId);
summon->SetHomePosition(pos);
summon->InitStats(duration);
summon->SetPrivateObjectOwner(privateObjectOwner);
summon->InitStats(summonArgs.SummonDuration);
summon->SetPrivateObjectOwner(summonArgs.PrivateObjectOwner);
// Handle health argument (totem health via base points)
if (health)
// Handle health argument
if (summonArgs.SummonHealth)
{
summon->SetMaxHealth(health);
summon->SetHealth(health);
summon->SetMaxHealth(summonArgs.SummonHealth);
summon->SetHealth(summonArgs.SummonHealth);
}
// Handle creature level argument
if (summonArgs.CreatureLevel)
summon->SetLevel(summonArgs.CreatureLevel);
AddToMap(summon->ToCreature());
summon->InitSummon();
@@ -2153,7 +2158,7 @@ void Map::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= null
return;
for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr)
if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, nullptr, itr->time))
if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, SummonCreatureExtraArgs().SetSummonDuration(itr->time)))
if (list)
list->push_back(summon);
}
@@ -2183,7 +2188,13 @@ TempSummon* WorldObject::SummonCreature(uint32 entry, Position const& pos, TempS
{
if (Map* map = FindMap())
{
if (TempSummon* summon = map->SummonCreature(entry, pos, nullptr, despawnTime, ToUnit(), 0, vehId, privateObjectOwner))
SummonCreatureExtraArgs extraArgs;
extraArgs.SummonDuration = despawnTime;
extraArgs.Summoner = ToUnit();
extraArgs.VehicleRecID = vehId;
extraArgs.PrivateObjectOwner = privateObjectOwner;
if (TempSummon* summon = map->SummonCreature(entry, pos, extraArgs))
{
summon->SetTempSummonType(despawnType);
return summon;
+43
View File
@@ -10285,3 +10285,46 @@ ByteBuffer QuestPOIWrapper::BuildQueryData() const
return tempBuffer;
}
void ObjectMgr::LoadSummonPropertiesParameters()
{
_summonPropertiesParametersStore.clear();
uint32 oldMSTime = getMSTime();
// 0 1
QueryResult result = WorldDatabase.Query("SELECT `RecID`, `ParamType` FROM summon_properties_parameters");
if (!result)
{
TC_LOG_INFO("server.loading", ">> Loaded 0 summon properties parameters. DB table `summon_properties_parameters` is empty.");
return;
}
uint32 count = 0;
do
{
Field* fields = result->Fetch();
uint32 recID = fields[0].GetUInt32();
uint8 parameterType = fields[1].GetUInt8();
if (!sSummonPropertiesStore.LookupEntry(recID))
{
TC_LOG_ERROR("sql.sql", "Table `summon_properties_parameters` has data for nonexistent summon properties record (ID: %u), skipped", recID);
continue;
};
_summonPropertiesParametersStore[recID] = parameterType;
++count;
}
while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u summon properties parameters in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
uint8 const* ObjectMgr::GetSummonPropertiesParameter(uint32 summonPropertiesRecID) const
{
return Trinity::Containers::MapGetValuePtr(_summonPropertiesParametersStore, summonPropertiesRecID);
}
+7
View File
@@ -1265,6 +1265,8 @@ class TC_GAME_API ObjectMgr
void LoadTaxiNodeLevelData();
void LoadSummonPropertiesParameters();
std::string GeneratePetName(uint32 entry) const;
uint32 GetBaseXP(uint8 level);
uint32 GetXPForLevel(uint8 level) const;
@@ -1608,6 +1610,8 @@ class TC_GAME_API ObjectMgr
return &itr->second;
}
uint8 const* GetSummonPropertiesParameter(uint32 summonPropertiesRecID) const;
private:
// first free id for selected id type
uint32 _auctionId;
@@ -1790,6 +1794,9 @@ class TC_GAME_API ObjectMgr
HotfixData _hotfixData;
std::set<uint32> _transportMaps; // Helper container storing map ids that are for transports only, loaded from gameobject_template
typedef std::unordered_map<uint32, uint8> SummonPropertiesParametersContainer; // [recID][ParameterType]
SummonPropertiesParametersContainer _summonPropertiesParametersStore;
};
#define sObjectMgr ObjectMgr::instance()
+20 -1
View File
@@ -333,6 +333,25 @@ inline bool CompareRespawnInfo::operator()(RespawnInfo const* a, RespawnInfo con
return a->type < b->type;
}
struct TC_GAME_API SummonCreatureExtraArgs
{
public:
SummonCreatureExtraArgs() { }
SummonCreatureExtraArgs& SetSummonDuration(uint32 duration) { SummonDuration = duration; return *this; }
SummonPropertiesEntry const* SummonProperties = nullptr;
Unit* Summoner = nullptr;
uint32 SummonDuration = 0;
uint32 SummonSpellId = 0;
uint32 VehicleRecID = 0;
uint32 SummonHealth = 0;
uint32 RideSpell = 0;
uint8 SeatNumber = 0;
uint8 CreatureLevel = 0;
ObjectGuid PrivateObjectOwner;
};
class TC_GAME_API Map : public GridRefManager<NGridType>
{
friend class MapReference;
@@ -539,7 +558,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
void UpdateIteratorBack(Player* player);
TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, Unit* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0, ObjectGuid privateObjectOwner = ObjectGuid::Empty, uint32 health = 0);
TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonCreatureExtraArgs const& summonArgs = { });
void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = nullptr);
Player* GetPlayer(ObjectGuid const& guid);
AreaTrigger* GetAreaTrigger(ObjectGuid const& guid);
+12
View File
@@ -237,4 +237,16 @@ struct TC_GAME_API CastSpellExtraArgs
} SpellValueOverrides;
};
enum class SummonPropertiesParamType : uint8
{
None = 0,
Health = 1,
NumUnitsMin = 2, // Minimum 1
SeatNumber = 3,
RideSpell = 4,
CreatureLevel = 5,
MaxSummons = 6, // Totem Slot
NumUnitsMax = 7 // Fail if less than 1
};
#endif // TRINITY_SPELLDEFINES_H
+70 -67
View File
@@ -1856,79 +1856,74 @@ void Spell::EffectSummonType(SpellEffIndex effIndex)
if (Player* modOwner = m_originalCaster->GetSpellModOwner())
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
// determine how many units should be summoned
uint32 numSummons = 0;
SummonCreatureExtraArgs extraArgs;
extraArgs.SummonProperties = properties;
extraArgs.SummonDuration = duration;
extraArgs.Summoner = m_originalCaster;
extraArgs.SummonSpellId = m_spellInfo->Id;
extraArgs.PrivateObjectOwner = privateObjectOwner;
// some spells need to summon many units, for those spells number of summons is stored in effect value
// however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
// and in spell attributes, possibly we need to add a table for those)
// so here's a list of MiscValueB values, which is currently most generic check
switch (properties->ID)
uint32 summonCount = 1;
if (uint8 const* parameter = sObjectMgr->GetSummonPropertiesParameter(properties->ID))
{
case 64:
case 61:
case 1101:
case 66:
case 648:
case 2301:
case 1061:
case 1261:
case 629:
case 181:
case 715:
case 1562:
case 833:
case 1161:
case 713:
case 3097:
case 2929:
numSummons = (damage > 0) ? damage : 1;
break;
default:
numSummons = 1;
break;
}
// Some totems are being summoned with a certain amount of health
uint32 health = (properties->Flags & SUMMON_PROP_FLAG_TOTEM) != 0 && damage ? damage : 0;
if (numSummons == 1)
{
if (TempSummon* summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_originalCaster, m_spellInfo->Id, 0, privateObjectOwner, health))
switch (SummonPropertiesParamType(*parameter))
{
// Summoned vehicles shall be mounted right away if possible
if (properties->Control == SUMMON_CATEGORY_VEHICLE && summon->IsVehicle())
{
// The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
uint32 spellId = VEHICLE_SPELL_RIDE_HARDCODED;
int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
if (basePoints > MAX_VEHICLE_SEATS)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
spellId = spellInfo->Id;
}
CastSpellExtraArgs args(TRIGGERED_FULL_MASK);
// if we have small value, it indicates seat position
if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
args.SpellValueOverrides.AddMod(SPELLVALUE_BASE_POINT0, basePoints);
m_originalCaster->CastSpell(summon, spellId, args);
}
ExecuteLogEffectSummonObject(effIndex, summon);
case SummonPropertiesParamType::None: // Default behavior
break;
case SummonPropertiesParamType::Health:
extraArgs.SummonHealth = damage;
break;
case SummonPropertiesParamType::NumUnitsMin: // Minimum 1
summonCount = std::max<int32>(damage, 1);
break;
case SummonPropertiesParamType::SeatNumber:
if (damage > 0 && damage < MAX_VEHICLE_SEATS)
extraArgs.SeatNumber = damage;
break;
case SummonPropertiesParamType::RideSpell:
if (sSpellMgr->GetSpellInfo(damage))
extraArgs.RideSpell = damage;
else // There is one spell with RecID 161 (52200) that uses bp as ride spell while most spells do not so we can assume that this parameter falls back to the hardcoded spell
extraArgs.RideSpell = VEHICLE_SPELL_RIDE_HARDCODED;
break;
case SummonPropertiesParamType::CreatureLevel:
extraArgs.CreatureLevel = damage;
break;
case SummonPropertiesParamType::MaxSummons: // @todo: handle and research (number of allowed units in one summon slot?)
break;
case SummonPropertiesParamType::NumUnitsMax: // Fails if less than 1
if (damage <= 0)
return;
summonCount = damage;
break;
default:
break;
}
}
else
for (uint32 i = 0; i < summonCount; ++i)
{
float radius = m_spellInfo->Effects[effIndex].CalcRadius();
for (uint8 i = 0; i < numSummons; ++i)
Position dest = *destTarget;
if (summonCount > 1)
{
// Multiple summons are summoned at random points within the destination radius
Position pos = m_caster->GetRandomPoint(*destTarget, radius);
if (TempSummon* summon = m_caster->GetMap()->SummonCreature(entry, pos, properties, duration, m_originalCaster, m_spellInfo->Id, 0, privateObjectOwner, health))
ExecuteLogEffectSummonObject(effIndex, summon);
float radius = m_spellInfo->Effects[effIndex].CalcRadius();
dest = m_caster->GetRandomPoint(*destTarget, radius);
}
if (TempSummon* summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, extraArgs))
{
ExecuteLogEffectSummonObject(effIndex, summon);
if (summonCount == 1 && summon->IsVehicle())
{
if (extraArgs.SeatNumber)
m_originalCaster->CastSpell(summon, VEHICLE_SPELL_RIDE_HARDCODED, CastSpellExtraArgs(true).AddSpellBP0(extraArgs.SeatNumber));
else if (extraArgs.RideSpell)
m_originalCaster->CastSpell(summon, extraArgs.RideSpell, true);
}
}
}
}
@@ -2512,8 +2507,16 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex)
if (!owner)
{
if (SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67))
if (TempSummon* summon = m_caster->GetMap()->SummonCreature(petentry, *destTarget, properties, m_spellInfo->GetDuration(), m_originalCaster, m_spellInfo->Id, false))
{
SummonCreatureExtraArgs extraArgs;
extraArgs.SummonProperties = properties;
extraArgs.SummonDuration = m_spellInfo->GetDuration();
extraArgs.Summoner = m_originalCaster;
extraArgs.SummonSpellId = m_spellInfo->Id;
if (TempSummon* summon = m_caster->GetMap()->SummonCreature(petentry, *destTarget, extraArgs))
ExecuteLogEffectSummonObject(effIndex, summon);
}
return;
}
@@ -2543,7 +2546,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex)
{
OldSummon->SetHealth(OldSummon->GetMaxHealth());
OldSummon->SetPower(OldSummon->GetPowerType(),
OldSummon->GetMaxPower(OldSummon->GetPowerType()));
OldSummon->GetMaxPower(OldSummon->GetPowerType()));
}
if (owner->GetTypeId() == TYPEID_PLAYER && OldSummon->isControlled())
+3
View File
@@ -2195,6 +2195,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Calendar data...");
sCalendarMgr->LoadFromDB();
TC_LOG_INFO("server.loading", "Loading Summon Properties parameter data...");
sObjectMgr->LoadSummonPropertiesParameters();
TC_LOG_INFO("server.loading", "Loading Item loot...");
sLootItemStorage->LoadStorageFromDB();
@@ -488,7 +488,12 @@ struct boss_ascendant_council_controller final : public BossAI
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, terrastra);
if (SummonPropertiesEntry const* entry = sSummonPropertiesStore.LookupEntry(PROPERTY_DEFAULT))
me->GetMap()->SummonCreature(BOSS_ELEMENTIUM_MONSTROSITY, me->GetPosition(), entry, 0, me);
{
SummonCreatureExtraArgs extraArgs;
extraArgs.Summoner = me;
extraArgs.SummonProperties = entry;
me->GetMap()->SummonCreature(BOSS_ELEMENTIUM_MONSTROSITY, me->GetPosition(), extraArgs);
}
break;
case EVENT_PREPARE_ULTIMATE_ABILITY:
if (events.IsInPhase(PHASE_FELUDIUS_IGNACIOUS))
@@ -213,10 +213,10 @@ class instance_vortex_pinnacle : public InstanceMapScript
{
case EVENT_SUMMON_ZEPHYRS:
if (instance->IsGridLoaded(SouthZephyrSummonLocation))
if (TempSummon* zephyr = instance->SummonCreature(NPC_ZEPHYR, SouthZephyrSummonLocation, nullptr, 18 * IN_MILLISECONDS))
if (TempSummon* zephyr = instance->SummonCreature(NPC_ZEPHYR, SouthZephyrSummonLocation, SummonCreatureExtraArgs().SetSummonDuration(18 * IN_MILLISECONDS)))
zephyr->GetMotionMaster()->MovePath(PATH_ZEPHYR_SOUTH, false);
if (instance->IsGridLoaded(NorthZephyrSummonLocation))
if (TempSummon* zephyr = instance->SummonCreature(NPC_ZEPHYR, NorthZephyrSummonLocation, nullptr, 18 * IN_MILLISECONDS))
if (TempSummon* zephyr = instance->SummonCreature(NPC_ZEPHYR, NorthZephyrSummonLocation, SummonCreatureExtraArgs().SetSummonDuration(18 * IN_MILLISECONDS)))
zephyr->GetMotionMaster()->MovePath(PATH_ZEPHYR_NORTH, false);
_events.Repeat(10s);
break;
@@ -1590,7 +1590,14 @@ class spell_halion_damage_aoe_summon : public SpellScriptLoader
uint32 duration = uint32(GetSpellInfo()->GetDuration());
Position pos = caster->GetPosition();
if (Creature* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id))
SummonCreatureExtraArgs extraArgs;
extraArgs.SummonProperties = properties;
extraArgs.SummonDuration = duration;
extraArgs.Summoner = caster;
extraArgs.SummonSpellId = GetSpellInfo()->Id;
if (Creature* summon = caster->GetMap()->SummonCreature(entry, pos, extraArgs))
if (summon->IsAIEnabled)
summon->AI()->SetData(DATA_STACKS_DISPELLED, GetSpellValue()->EffectBasePoints[EFFECT_1]);
}
@@ -1470,7 +1470,14 @@ class spell_putricide_mutated_transformation : public SpellScriptLoader
uint32 duration = uint32(GetSpellInfo()->GetDuration());
Position pos = caster->GetPosition();
TempSummon* summon = caster->GetMap()->SummonCreature(entry, pos, properties, duration, caster, GetSpellInfo()->Id);
SummonCreatureExtraArgs extraArgs;
extraArgs.SummonProperties = properties;
extraArgs.SummonDuration = duration;
extraArgs.Summoner = caster;
extraArgs.SummonSpellId = GetSpellInfo()->Id;
TempSummon* summon = caster->GetMap()->SummonCreature(entry, pos, extraArgs);
if (!summon || !summon->IsVehicle())
return;
@@ -1043,7 +1043,7 @@ class boss_the_lich_king : public CreatureScript
}
break;
case EVENT_FROSTMOURNE_HEROIC:
if (TempSummon* terenas = me->GetMap()->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE_H, TerenasSpawnHeroic, nullptr, 50000))
if (TempSummon* terenas = me->GetMap()->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE_H, TerenasSpawnHeroic, SummonCreatureExtraArgs().SetSummonDuration(50000)))
{
terenas->AI()->DoAction(ACTION_FROSTMOURNE_INTRO);
std::list<Creature*> triggers;
@@ -1269,7 +1269,7 @@ class instance_icecrown_citadel : public InstanceMapScript
}
break;
case EVENT_TELEPORT_TO_FROSTMOURNE: // Harvest Soul (normal mode)
if (Creature* terenas = instance->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE, TerenasSpawn, nullptr, 63000))
if (Creature* terenas = instance->SummonCreature(NPC_TERENAS_MENETHIL_FROSTMOURNE, TerenasSpawn, SummonCreatureExtraArgs().SetSummonDuration(63000)))
{
terenas->AI()->DoAction(ACTION_FROSTMOURNE_INTRO);
std::list<Creature*> triggers;
@@ -1281,7 +1281,7 @@ class instance_icecrown_citadel : public InstanceMapScript
visual->CastSpell(visual, SPELL_FROSTMOURNE_TELEPORT_VISUAL, true);
}
if (Creature* warden = instance->SummonCreature(NPC_SPIRIT_WARDEN, SpiritWardenSpawn, nullptr, 63000))
if (Creature* warden = instance->SummonCreature(NPC_SPIRIT_WARDEN, SpiritWardenSpawn, SummonCreatureExtraArgs().SetSummonDuration(63000)))
{
terenas->AI()->AttackStart(warden);
warden->GetThreatManager().AddThreat(terenas, 300000.0f, nullptr, true, true);