mirror of
https://github.com/mangosfour/server.git
synced 2025-12-16 04:37:00 +00:00
[8944] Use DBC data for summon effect functionality.
Also some more local fixes: * Alow multiply same type guardians req. for some spells. * Apply spell duration mods to summons Many summon spells must start work. Great work qsa! :) Thanks The_Game_Master for updaing patch to recent sources. Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
parent
e8b1905630
commit
ffca4301d0
10 changed files with 136 additions and 213 deletions
|
|
@ -3398,54 +3398,99 @@ void Spell::EffectApplyAreaAura(uint32 i)
|
|||
|
||||
void Spell::EffectSummonType(uint32 i)
|
||||
{
|
||||
switch(m_spellInfo->EffectMiscValueB[i])
|
||||
uint32 prop_id = m_spellInfo->EffectMiscValueB[i];
|
||||
SummonPropertiesEntry const *summon_prop = sSummonPropertiesStore.LookupEntry(prop_id);
|
||||
if(!summon_prop)
|
||||
{
|
||||
case SUMMON_TYPE_GUARDIAN:
|
||||
case SUMMON_TYPE_POSESSED:
|
||||
case SUMMON_TYPE_POSESSED2:
|
||||
case SUMMON_TYPE_FORCE_OF_NATURE:
|
||||
case SUMMON_TYPE_GUARDIAN2:
|
||||
case SUMMON_TYPE_GUARDIAN3:
|
||||
// Jewelery statue case (totem like)
|
||||
if(m_spellInfo->SpellIconID == 2056)
|
||||
EffectSummonTotem(i);
|
||||
sLog.outError("EffectSummonType: Unhandled summon type %u", prop_id);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(summon_prop->Group)
|
||||
{
|
||||
// faction handled later on, or loaded from template
|
||||
case SUMMON_PROP_GROUP_WILD:
|
||||
case SUMMON_PROP_GROUP_FRIENDLY:
|
||||
{
|
||||
switch(summon_prop->Type)
|
||||
{
|
||||
case SUMMON_PROP_TYPE_SIEGE_VEH:
|
||||
case SUMMON_PROP_TYPE_DRAKE_VEH:
|
||||
{
|
||||
// TODO
|
||||
// EffectSummonVehicle(i);
|
||||
break;
|
||||
}
|
||||
case SUMMON_PROP_TYPE_TOTEM:
|
||||
{
|
||||
EffectSummonTotem(i, summon_prop->Slot);
|
||||
break;
|
||||
}
|
||||
case SUMMON_PROP_TYPE_SUMMON:
|
||||
case SUMMON_PROP_TYPE_GUARDIAN:
|
||||
case SUMMON_PROP_TYPE_ARMY:
|
||||
case SUMMON_PROP_TYPE_DK:
|
||||
case SUMMON_PROP_TYPE_CONSTRUCT:
|
||||
{
|
||||
// JC golems - 32804, etc -- fits much better totem AI
|
||||
if(m_spellInfo->SpellIconID == 2056)
|
||||
EffectSummonTotem(i);
|
||||
if(prop_id == 832) // scrapbot
|
||||
EffectSummonWild(i, summon_prop->FactionId);
|
||||
else
|
||||
EffectSummonGuardian(i, summon_prop->FactionId);
|
||||
break;
|
||||
}
|
||||
case SUMMON_PROP_TYPE_CRITTER:
|
||||
{
|
||||
EffectSummonCritter(i, summon_prop->FactionId);
|
||||
break;
|
||||
}
|
||||
case SUMMON_PROP_TYPE_OTHER:
|
||||
case SUMMON_PROP_TYPE_PHASING:
|
||||
case SUMMON_PROP_TYPE_LIGHTWELL:
|
||||
{
|
||||
// those are classical totems - effectbasepoints is their hp and not summon ammount!
|
||||
//SUMMON_TYPE_TOTEM = 121: 23035, battlestands
|
||||
//SUMMON_TYPE_TOTEM2 = 647: 52893, Anti-Magic Zone (npc used)
|
||||
if(prop_id == 121 || prop_id == 647)
|
||||
EffectSummonTotem(i);
|
||||
else
|
||||
EffectSummonWild(i, summon_prop->FactionId);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sLog.outError("EffectSummonType: Unhandled summon type %u", summon_prop->Type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SUMMON_PROP_GROUP_PETS:
|
||||
{
|
||||
// FIXME : multiple summons - not yet supported as pet
|
||||
//1562 - force of nature - sid 33831
|
||||
//1161 - feral spirit - sid 51533
|
||||
if(prop_id == 1562) // 3 uncontrolable instead of one controllable :/
|
||||
EffectSummonGuardian(i, summon_prop->FactionId);
|
||||
else
|
||||
EffectSummonGuardian(i);
|
||||
EffectSummon(i);
|
||||
break;
|
||||
case SUMMON_TYPE_WILD:
|
||||
case SUMMON_TYPE_QUEST_WILD:
|
||||
case SUMMON_TYPE_CREATURE:
|
||||
EffectSummonWild(i);
|
||||
}
|
||||
case SUMMON_PROP_GROUP_CONTROLLABLE:
|
||||
{
|
||||
// no type here
|
||||
// maybe wrong - but thats the handler currently used for those
|
||||
EffectSummonGuardian(i, summon_prop->FactionId);
|
||||
break;
|
||||
case SUMMON_TYPE_DEMON:
|
||||
case SUMMON_TYPE_INFERNO:
|
||||
EffectSummonDemon(i);
|
||||
break;
|
||||
case SUMMON_TYPE_SUMMON:
|
||||
case SUMMON_TYPE_ELEMENTAL:
|
||||
EffectSummon(i);
|
||||
break;
|
||||
case SUMMON_TYPE_CRITTER:
|
||||
case SUMMON_TYPE_CRITTER2:
|
||||
case SUMMON_TYPE_CRITTER3:
|
||||
case SUMMON_TYPE_QUEST_CRITTER:
|
||||
EffectSummonCritter(i);
|
||||
break;
|
||||
case SUMMON_TYPE_TOTEM_SLOT1:
|
||||
case SUMMON_TYPE_TOTEM_SLOT2:
|
||||
case SUMMON_TYPE_TOTEM_SLOT3:
|
||||
case SUMMON_TYPE_TOTEM_SLOT4:
|
||||
case SUMMON_TYPE_TOTEM:
|
||||
EffectSummonTotem(i);
|
||||
break;
|
||||
case SUMMON_TYPE_UNKNOWN1:
|
||||
case SUMMON_TYPE_UNKNOWN2:
|
||||
case SUMMON_TYPE_UNKNOWN3:
|
||||
case SUMMON_TYPE_UNKNOWN4:
|
||||
case SUMMON_TYPE_UNKNOWN5:
|
||||
}
|
||||
case SUMMON_PROP_GROUP_VEHICLE:
|
||||
{
|
||||
// TODO
|
||||
// EffectSummonVehicle(i);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]);
|
||||
sLog.outError("EffectSummonType: Unhandled summon group type %u", summon_prop->Group);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -3463,6 +3508,10 @@ void Spell::EffectSummon(uint32 i)
|
|||
uint32 level = m_caster->getLevel();
|
||||
Pet* spawnCreature = new Pet(SUMMON_PET);
|
||||
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
if(Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
|
||||
|
||||
if (m_caster->GetTypeId()==TYPEID_PLAYER && spawnCreature->LoadPetFromDB((Player*)m_caster,pet_entry))
|
||||
{
|
||||
// Summon in dest location
|
||||
|
|
@ -3476,7 +3525,6 @@ void Spell::EffectSummon(uint32 i)
|
|||
}
|
||||
|
||||
// set timer for unsummon
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
if (duration > 0)
|
||||
spawnCreature->SetDuration(duration);
|
||||
|
||||
|
|
@ -3515,7 +3563,6 @@ void Spell::EffectSummon(uint32 i)
|
|||
}
|
||||
|
||||
// set timer for unsummon
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
if (duration > 0)
|
||||
spawnCreature->SetDuration(duration);
|
||||
|
||||
|
|
@ -3786,7 +3833,7 @@ void Spell::EffectAddFarsight(uint32 i)
|
|||
((Player*)m_caster)->SetFarSightGUID(dynObj->GetGUID());
|
||||
}
|
||||
|
||||
void Spell::EffectSummonWild(uint32 i)
|
||||
void Spell::EffectSummonWild(uint32 i, uint32 forceFaction)
|
||||
{
|
||||
uint32 creature_entry = m_spellInfo->EffectMiscValue[i];
|
||||
if (!creature_entry)
|
||||
|
|
@ -3802,9 +3849,7 @@ void Spell::EffectSummonWild(uint32 i)
|
|||
{
|
||||
uint16 skill202 = ((Player*)m_caster)->GetSkillValue(SKILL_ENGINERING);
|
||||
if (skill202)
|
||||
{
|
||||
level = skill202/5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3814,6 +3859,8 @@ void Spell::EffectSummonWild(uint32 i)
|
|||
float center_z = m_targets.m_destZ;
|
||||
|
||||
float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN;
|
||||
|
||||
int32 amount = damage > 0 ? damage : 1;
|
||||
|
||||
|
|
@ -3838,30 +3885,23 @@ void Spell::EffectSummonWild(uint32 i)
|
|||
else
|
||||
m_caster->GetClosePoint(px, py, pz, 3.0f);
|
||||
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
if(Creature *summon = m_caster->SummonCreature(creature_entry, px, py, pz, m_caster->GetOrientation(), summonType, duration))
|
||||
{
|
||||
summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||
summon->SetCreatorGUID(m_caster->GetGUID());
|
||||
|
||||
TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN;
|
||||
|
||||
m_caster->SummonCreature(creature_entry, px, py, pz, m_caster->GetOrientation(), summonType, duration);
|
||||
if(forceFaction)
|
||||
summon->setFaction(forceFaction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::EffectSummonGuardian(uint32 i)
|
||||
void Spell::EffectSummonGuardian(uint32 i, uint32 forceFaction)
|
||||
{
|
||||
uint32 pet_entry = m_spellInfo->EffectMiscValue[i];
|
||||
if (!pet_entry)
|
||||
return;
|
||||
|
||||
// set timer for unsummon
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
|
||||
// Search old Guardian only for players (if casted spell not have duration or cooldown)
|
||||
// FIXME: some guardians have control spell applied and controlled by player and anyway player can't summon in this time
|
||||
// so this code hack in fact
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER && (duration <= 0 || GetSpellRecoveryTime(m_spellInfo) == 0))
|
||||
if(m_caster->FindGuardianWithEntry(pet_entry))
|
||||
return; // find old guardian, ignore summon
|
||||
|
||||
// in another case summon new
|
||||
uint32 level = m_caster->getLevel();
|
||||
|
||||
|
|
@ -3885,6 +3925,9 @@ void Spell::EffectSummonGuardian(uint32 i)
|
|||
float center_z = m_targets.m_destZ;
|
||||
|
||||
float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
if(Player* modOwner = m_caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
|
||||
|
||||
int32 amount = damage > 0 ? damage : 1;
|
||||
|
||||
|
|
@ -3936,8 +3979,8 @@ void Spell::EffectSummonGuardian(uint32 i)
|
|||
|
||||
spawnCreature->SetOwnerGUID(m_caster->GetGUID());
|
||||
spawnCreature->setPowerType(POWER_MANA);
|
||||
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
spawnCreature->setFaction(m_caster->getFaction());
|
||||
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS, spawnCreature->GetCreatureInfo()->npcflag);
|
||||
spawnCreature->setFaction(forceFaction ? forceFaction : m_caster->getFaction());
|
||||
spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS, 0);
|
||||
spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
|
||||
|
|
@ -5847,21 +5890,9 @@ void Spell::EffectApplyGlyph(uint32 i)
|
|||
}
|
||||
}
|
||||
|
||||
void Spell::EffectSummonTotem(uint32 i)
|
||||
void Spell::EffectSummonTotem(uint32 i, uint8 slot)
|
||||
{
|
||||
uint8 slot = 0;
|
||||
switch(m_spellInfo->EffectMiscValueB[i])
|
||||
{
|
||||
case SUMMON_TYPE_TOTEM_SLOT1: slot = 0; break;
|
||||
case SUMMON_TYPE_TOTEM_SLOT2: slot = 1; break;
|
||||
case SUMMON_TYPE_TOTEM_SLOT3: slot = 2; break;
|
||||
case SUMMON_TYPE_TOTEM_SLOT4: slot = 3; break;
|
||||
// Battle standard case
|
||||
case SUMMON_TYPE_TOTEM: slot = 254; break;
|
||||
// jewelery statue case, like totem without slot
|
||||
case SUMMON_TYPE_GUARDIAN: slot = 255; break;
|
||||
default: return;
|
||||
}
|
||||
slot = slot ? (slot - 1): 255;
|
||||
|
||||
if(slot < MAX_TOTEM)
|
||||
{
|
||||
|
|
@ -6353,7 +6384,7 @@ void Spell::EffectCharge2(uint32 /*i*/)
|
|||
m_caster->Attack(unitTarget,true);
|
||||
}
|
||||
|
||||
void Spell::EffectSummonCritter(uint32 i)
|
||||
void Spell::EffectSummonCritter(uint32 i, uint32 forceFaction)
|
||||
{
|
||||
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
|
@ -6413,9 +6444,9 @@ void Spell::EffectSummonCritter(uint32 i)
|
|||
|
||||
critter->SetOwnerGUID(m_caster->GetGUID());
|
||||
critter->SetCreatorGUID(m_caster->GetGUID());
|
||||
critter->setFaction(m_caster->getFaction());
|
||||
critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||
|
||||
critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||
critter->setFaction(forceFaction ? forceFaction : m_caster->getFaction());
|
||||
critter->AIM_Initialize();
|
||||
critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter...
|
||||
//critter->InitLevelupSpellsForLevel(); // none?
|
||||
|
|
@ -6778,65 +6809,6 @@ void Spell::EffectSkill(uint32 /*i*/)
|
|||
sLog.outDebug("WORLD: SkillEFFECT");
|
||||
}
|
||||
|
||||
void Spell::EffectSummonDemon(uint32 i)
|
||||
{
|
||||
// select center of summon position
|
||||
float center_x = m_targets.m_destX;
|
||||
float center_y = m_targets.m_destY;
|
||||
float center_z = m_targets.m_destZ;
|
||||
|
||||
float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
|
||||
|
||||
int32 amount = damage > 0 ? damage : 1;
|
||||
|
||||
if (m_spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_INFERNO)
|
||||
amount = 1;
|
||||
|
||||
for(int32 count = 0; count < amount; ++count)
|
||||
{
|
||||
float px, py, pz;
|
||||
// If dest location if present
|
||||
if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
|
||||
{
|
||||
// Summon 1 unit in dest location
|
||||
if (count == 0)
|
||||
{
|
||||
px = m_targets.m_destX;
|
||||
py = m_targets.m_destY;
|
||||
pz = m_targets.m_destZ;
|
||||
}
|
||||
// Summon in random point all other units if location present
|
||||
else
|
||||
m_caster->GetRandomPoint(center_x,center_y,center_z,radius,px,py,pz);
|
||||
}
|
||||
// Summon if dest location not present near caster
|
||||
else
|
||||
m_caster->GetClosePoint(px,py,pz,3.0f);
|
||||
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
|
||||
Creature* Charmed = m_caster->SummonCreature(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(),TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,duration);
|
||||
if (!Charmed) // something fatal, not attempt more
|
||||
return;
|
||||
|
||||
// might not always work correctly, maybe the creature that dies from CoD casts the effect on itself and is therefore the caster?
|
||||
Charmed->SetLevel(m_caster->getLevel());
|
||||
|
||||
// TODO: Add damage/mana/hp according to level
|
||||
|
||||
// Enslave demon effect, without mana cost and cooldown
|
||||
if (m_spellInfo->EffectMiscValue[i] == 89) // Inferno summon
|
||||
{
|
||||
// Enslave demon effect, without mana cost and cooldown
|
||||
m_caster->CastSpell(Charmed, 20882, true); // FIXME: enslave does not scale with level, level 62+ minions cannot be enslaved
|
||||
|
||||
// Inferno effect for non player calls
|
||||
if (m_spellInfo->EffectMiscValueB[i]!=SUMMON_TYPE_INFERNO)
|
||||
Charmed->CastSpell(Charmed, 22703, true, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::EffectSpiritHeal(uint32 /*i*/)
|
||||
{
|
||||
// TODO player can't see the heal-animation - he should respawn some ticks later
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue