aboutsummaryrefslogtreecommitdiff
path: root/src/game/SpellEffects.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/SpellEffects.cpp')
-rw-r--r--src/game/SpellEffects.cpp371
1 files changed, 152 insertions, 219 deletions
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index e363b2cb41e..583087a5106 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -3313,15 +3313,12 @@ void Spell::EffectApplyAreaAura(uint32 i)
void Spell::EffectSummonType(uint32 i)
{
+ uint32 entry = m_spellInfo->EffectMiscValue[i];
+ if(!entry)
+ return;
+
switch(m_spellInfo->EffectMiscValueB[i])
{
- case SUMMON_TYPE_GUARDIAN:
- EffectSummonGuardian(i);
- break;
- case SUMMON_TYPE_FORCE_OF_NATURE:
- case SUMMON_TYPE_FERAL_SPIRIT:
- EffectSummonGuardian(i);
- break;
case SUMMON_TYPE_WILD:
case SUMMON_TYPE_FROZEN_EARTH:
case SUMMON_TYPE_LIGHTWELL:
@@ -3333,39 +3330,45 @@ void Spell::EffectSummonType(uint32 i)
case SUMMON_TYPE_SUMMON:
EffectSummon(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_UNKNOWN3:
- case SUMMON_TYPE_UNKNOWN4:
- case SUMMON_TYPE_UNKNOWN5:
- break;
default:
{
- SummonPropertiesEntry const *SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]);
- if(!SummonProperties)
+ SummonPropertiesEntry const *properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]);
+ if(!properties)
{
sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]);
return;
}
- switch(SummonProperties->Category)
+ switch(properties->Category)
{
default:
- if(SummonProperties->Type == SUMMON_TYPE_MINIPET)
- EffectSummonCritter(i);
- else
- EffectSummonWild(i);
+ switch(properties->Type)
+ {
+ case SUMMON_TYPE_GUARDIAN:
+ case SUMMON_TYPE_MINION:
+ SummonGuardian(entry, properties);
+ break;
+ case SUMMON_TYPE_VEHICLE:
+ SummonVehicle(entry, properties);
+ break;
+ case SUMMON_TYPE_TOTEM:
+ SummonTotem(entry, properties);
+ break;
+ case SUMMON_TYPE_MINIPET:
+ EffectSummonCritter(i);
+ break;
+ default:
+ EffectSummonWild(i);
+ break;
+ }
+ break;
+ case SUMMON_CATEGORY_GUARDIAN:
+ SummonGuardian(entry, properties);
break;
case SUMMON_CATEGORY_POSSESSED:
- EffectSummonPossessed(i);
+ SummonPossessed(entry, properties);
break;
case SUMMON_CATEGORY_VEHICLE:
- EffectSummonVehicle(i);
+ SummonVehicle(entry, properties);
break;
}
break;
@@ -3701,101 +3704,6 @@ void Spell::EffectSummonWild(uint32 i)
}
}
-void Spell::EffectSummonGuardian(uint32 i)
-{
- uint32 pet_entry = m_spellInfo->EffectMiscValue[i];
- if(!pet_entry)
- return;
-
- // Jewelery statue case (totem like)
- if(m_spellInfo->SpellIconID==2056)
- {
- EffectSummonTotem(i);
- return;
- }
-
- Player *caster = NULL;
- if(m_originalCaster)
- {
- if(m_originalCaster->GetTypeId() == TYPEID_PLAYER)
- caster = (Player*)m_originalCaster;
- else if(((Creature*)m_originalCaster)->isTotem())
- caster = m_originalCaster->GetCharmerOrOwnerPlayerOrPlayerItself();
- }
-
- if(!caster)
- {
- EffectSummonWild(i);
- 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(duration <= 0 || GetSpellRecoveryTime(m_spellInfo)==0)
- if(caster->HasGuardianWithEntry(pet_entry))
- return; // find old guardian, ignore summon
-
- // in another case summon new
- uint32 level = caster->getLevel();
-
- // level of pet summoned using engineering item based at engineering skill level
- if(m_CastItem)
- {
- ItemPrototype const *proto = m_CastItem->GetProto();
- if(proto && proto->RequiredSkill == SKILL_ENGINERING)
- {
- uint16 skill202 = caster->GetSkillValue(SKILL_ENGINERING);
- if(skill202)
- {
- level = skill202/5;
- }
- }
- }
-
- // 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 = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
-
- int32 amount = damage > 0 ? damage : 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,m_caster->GetObjectSize());
-
- Pet *spawnCreature = caster->SummonPet(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(), GUARDIAN_PET, duration);
- if(!spawnCreature)
- return;
-
- spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0);
- spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
- }
-}
-
void Spell::EffectTeleUnitsFaceCaster(uint32 i)
{
if(!unitTarget)
@@ -5525,90 +5433,6 @@ void Spell::EffectApplyGlyph(uint32 i)
}
}
-void Spell::EffectSummonTotem(uint32 i)
-{
- 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;
- }
-
- if(slot < MAX_TOTEM)
- {
- uint64 guid = m_caster->m_TotemSlot[slot];
- if(guid != 0)
- {
- Creature *OldTotem = ObjectAccessor::GetCreature(*m_caster, guid);
- if(OldTotem && OldTotem->isTotem())
- ((Totem*)OldTotem)->UnSummon();
- }
- }
-
- uint32 team = 0;
- if (m_caster->GetTypeId()==TYPEID_PLAYER)
- team = ((Player*)m_caster)->GetTeam();
-
- Totem* pTotem = new Totem;
-
- if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_caster->GetPhaseMask(),
- m_spellInfo->EffectMiscValue[i], team ))
- {
- delete pTotem;
- return;
- }
-
- float x,y,z;
- GetSummonPosition(x, y, z);
-
- // totem must be at same Z in case swimming caster and etc.
- if( fabs( z - m_caster->GetPositionZ() ) > 5 )
- z = m_caster->GetPositionZ();
-
- pTotem->Relocate(x, y, z, m_caster->GetOrientation());
-
- if(slot < MAX_TOTEM)
- m_caster->m_TotemSlot[slot] = pTotem->GetGUID();
-
- pTotem->SetOwner(m_caster->GetGUID());
- pTotem->SetTypeBySummonSpell(m_spellInfo); // must be after Create call where m_spells initilized
-
- int32 duration=GetSpellDuration(m_spellInfo);
- if(Player* modOwner = m_caster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id,SPELLMOD_DURATION, duration);
- pTotem->SetDuration(duration);
-
- if (damage) // if not spell info, DB values used
- {
- pTotem->SetMaxHealth(damage);
- pTotem->SetHealth(damage);
- }
-
- pTotem->SetUInt32Value(UNIT_CREATED_BY_SPELL,m_spellInfo->Id);
-
- if(m_caster->GetTypeId() == TYPEID_PLAYER)
- pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
-
- pTotem->Summon(m_caster);
-
- if(slot < MAX_TOTEM && m_caster->GetTypeId() == TYPEID_PLAYER)
- {
- WorldPacket data(SMSG_TOTEM_CREATED, 1+8+4+4);
- data << uint8(slot);
- data << uint64(pTotem->GetGUID());
- data << uint32(duration);
- data << uint32(m_spellInfo->Id);
- ((Player*)m_caster)->SendDirectMessage(&data);
- }
-}
-
void Spell::EffectEnchantHeldItem(uint32 i)
{
// this is only item spell effect applied to main-hand weapon of target player (players in area)
@@ -6031,8 +5855,7 @@ void Spell::EffectSummonCritter(uint32 i)
GetSummonPosition(x, y, z);
int32 duration = GetSpellDuration(m_spellInfo);
- TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
- TempSummon *critter = m_caster->SummonCreature(pet_entry, x, y, z, m_caster->GetOrientation(), summonType, duration);
+ TempSummon *critter = m_caster->GetMap()->SummonCreature(pet_entry, x, y, z, m_caster->GetOrientation(), sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]), duration, m_caster);
if(!critter)
return;
@@ -6052,8 +5875,6 @@ void Spell::EffectSummonCritter(uint32 i)
std::string name = player->GetName();
name.append(petTypeSuffix[3]);
critter->SetName( name );
-
- critter->SetSummonProperties(sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]));
}
void Spell::EffectKnockBack(uint32 i)
@@ -6681,12 +6502,128 @@ void Spell::EffectRedirectThreat(uint32 /*i*/)
m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID());
}
-void Spell::EffectSummonPossessed(uint32 i)
+void Spell::SummonTotem(uint32 entry, SummonPropertiesEntry const *properties)
{
- uint32 entry = m_spellInfo->EffectMiscValue[i];
- if(!entry)
+ int8 slot = (int8)properties->Slot - 1;
+
+ if(slot >= 0 && slot < MAX_TOTEM)
+ {
+ uint64 guid = m_caster->m_TotemSlot[slot];
+ if(guid != 0)
+ {
+ Creature *OldTotem = ObjectAccessor::GetCreature(*m_caster, guid);
+ if(OldTotem && OldTotem->isTotem())
+ ((Totem*)OldTotem)->UnSummon();
+ }
+ }
+
+ uint32 team = 0;
+ if (m_caster->GetTypeId()==TYPEID_PLAYER)
+ team = ((Player*)m_caster)->GetTeam();
+
+ Totem* pTotem = new Totem(properties, m_caster);
+
+ if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_caster->GetPhaseMask(),
+ entry, team ))
+ {
+ delete pTotem;
+ return;
+ }
+
+ float x,y,z;
+ GetSummonPosition(x, y, z);
+
+ // totem must be at same Z in case swimming caster and etc.
+ if( fabs( z - m_caster->GetPositionZ() ) > 5 )
+ z = m_caster->GetPositionZ();
+
+ pTotem->Relocate(x, y, z, m_caster->GetOrientation());
+
+ if(slot < MAX_TOTEM)
+ m_caster->m_TotemSlot[slot] = pTotem->GetGUID();
+
+ pTotem->SetOwner(m_caster->GetGUID());
+ pTotem->SetTypeBySummonSpell(m_spellInfo); // must be after Create call where m_spells initilized
+
+ int32 duration=GetSpellDuration(m_spellInfo);
+ if(Player* modOwner = m_caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(m_spellInfo->Id,SPELLMOD_DURATION, duration);
+ pTotem->SetDuration(duration);
+
+ if (damage) // if not spell info, DB values used
+ {
+ pTotem->SetMaxHealth(damage);
+ pTotem->SetHealth(damage);
+ }
+
+ pTotem->SetUInt32Value(UNIT_CREATED_BY_SPELL,m_spellInfo->Id);
+
+ if(m_caster->GetTypeId() == TYPEID_PLAYER)
+ pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);
+
+ pTotem->Summon(m_caster);
+
+ if(slot >= 0 && slot < MAX_TOTEM && m_caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ WorldPacket data(SMSG_TOTEM_CREATED, 1+8+4+4);
+ data << uint8(slot);
+ data << uint64(pTotem->GetGUID());
+ data << uint32(duration);
+ data << uint32(m_spellInfo->Id);
+ ((Player*)m_caster)->SendDirectMessage(&data);
+ }
+}
+
+void Spell::SummonGuardian(uint32 entry, SummonPropertiesEntry const *properties)
+{
+ Unit *caster = m_originalCaster;
+ if(caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())
+ caster = caster->GetOwner();
+ if(!caster)
return;
+ // in another case summon new
+ uint32 level = caster->getLevel();
+
+ // level of pet summoned using engineering item based at engineering skill level
+ if(m_CastItem && caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ ItemPrototype const *proto = m_CastItem->GetProto();
+ if(proto && proto->RequiredSkill == SKILL_ENGINERING)
+ {
+ uint16 skill202 = ((Player*)caster)->GetSkillValue(SKILL_ENGINERING);
+ if(skill202)
+ {
+ level = skill202/5;
+ }
+ }
+ }
+
+ //float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ float radius = 5.0f;
+ int32 amount = damage > 0 ? damage : 1;
+ int32 duration = GetSpellDuration(m_spellInfo);
+ TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
+ Map *map = caster->GetMap();
+
+ for(int32 count = 0; count < amount; ++count)
+ {
+ float px, py, pz;
+ GetSummonPosition(px, py, pz, radius, count);
+
+ TempSummon *summon = map->SummonCreature(entry, px, py, pz, m_caster->GetOrientation(), properties, duration, caster);
+ if(!summon)
+ return;
+
+ if(summon->GetSummonMask() | SUMMON_MASK_GUARDIAN)
+ ((Guardian*)summon)->InitStatsForLevel(level);
+
+ summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
+ }
+}
+
+void Spell::SummonPossessed(uint32 entry, SummonPropertiesEntry const *properties)
+{
if(m_caster->GetTypeId() != TYPEID_PLAYER)
return;
@@ -6705,12 +6642,8 @@ void Spell::EffectSummonPossessed(uint32 i)
pet->SetCharmedOrPossessedBy(m_caster, true);
}
-void Spell::EffectSummonVehicle(uint32 i)
+void Spell::SummonVehicle(uint32 entry, SummonPropertiesEntry const *properties)
{
- uint32 entry = m_spellInfo->EffectMiscValue[i];
- if(!entry)
- return;
-
float x, y, z;
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
Vehicle *vehicle = m_caster->SummonVehicle(entry, x, y, z, m_caster->GetOrientation());