[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:
qsa 2009-12-07 23:18:33 +03:00 committed by VladimirMangos
parent e8b1905630
commit ffca4301d0
10 changed files with 136 additions and 213 deletions

View file

@ -325,26 +325,26 @@ enum TotemCategoryType
// SummonProperties.dbc, col 1
enum SummonPropGroup
{
SUMMON_PROP_GROUP_UNKNOWN1 = 0, // 1160 spells in 3.0.3
SUMMON_PROP_GROUP_UNKNOWN2 = 1, // 861 spells in 3.0.3
SUMMON_PROP_GROUP_PETS = 2, // 52 spells in 3.0.3, pets mostly
SUMMON_PROP_GROUP_CONTROLLABLE = 3, // 13 spells in 3.0.3, mostly controllable
SUMMON_PROP_GROUP_UNKNOWN3 = 4 // 86 spells in 3.0.3, taxi/mounts
SUMMON_PROP_GROUP_WILD = 0,
SUMMON_PROP_GROUP_FRIENDLY = 1,
SUMMON_PROP_GROUP_PETS = 2,
SUMMON_PROP_GROUP_CONTROLLABLE = 3,
SUMMON_PROP_GROUP_VEHICLE = 4
};
// SummonProperties.dbc, col 3
enum SummonPropType
{
SUMMON_PROP_TYPE_UNKNOWN = 0, // different summons, 1330 spells in 3.0.3
SUMMON_PROP_TYPE_OTHER = 0, // different summons, 1330 spells in 3.0.3
SUMMON_PROP_TYPE_SUMMON = 1, // generic summons, 49 spells in 3.0.3
SUMMON_PROP_TYPE_GUARDIAN = 2, // summon guardian, 393 spells in 3.0.3
SUMMON_PROP_TYPE_ARMY = 3, // summon army, 5 spells in 3.0.3
SUMMON_PROP_TYPE_TOTEM = 4, // summon totem, 169 spells in 3.0.3
SUMMON_PROP_TYPE_CRITTER = 5, // critter/minipet, 195 spells in 3.0.3
SUMMON_PROP_TYPE_DK = 6, // summon DRW/Ghoul, 2 spells in 3.0.3
SUMMON_PROP_TYPE_BOMB = 7, // summon bot/bomb, 4 spells in 3.0.3
SUMMON_PROP_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3
SUMMON_PROP_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3
SUMMON_PROP_TYPE_DK = 6, // summon DRW/Ghoul, 2 spells in 3.0.3 "%s's Runeblade"
SUMMON_PROP_TYPE_CONSTRUCT = 7, // summon bot/bomb, 4 spells in 3.0.3 "%s's Construct"
SUMMON_PROP_TYPE_PHASING = 8, // something todo with DK prequest line, 2 spells in 3.0.3 "%s's Opponent"
SUMMON_PROP_TYPE_SIEGE_VEH = 9, // summon different vehicles, 14 spells in 3.0.3 "%s's Vehicle"
SUMMON_PROP_TYPE_DRAKE_VEH = 10, // summon drake (vehicle), 3 spells
SUMMON_PROP_TYPE_LIGHTWELL = 11 // summon lightwell, 6 spells in 3.0.3
};

View file

@ -129,7 +129,7 @@ DBCStorage <SpellRangeEntry> sSpellRangeStore(SpellRangefmt);
DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore(SpellRuneCostfmt);
DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore(SpellShapeshiftfmt);
DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore(StableSlotPricesfmt);
//DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt);
DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt);
DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt);
TalentSpellPosMap sTalentSpellPosMap;
DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt);
@ -206,7 +206,7 @@ void LoadDBCStores(const std::string& dataPath)
{
std::string dbcPath = dataPath+"dbc/";
const uint32 DBCFilesCount = 80;
const uint32 DBCFilesCount = 81;
barGoLink bar( DBCFilesCount );
@ -360,7 +360,7 @@ void LoadDBCStores(const std::string& dataPath)
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRuneCostStore, dbcPath,"SpellRuneCost.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore, dbcPath,"SpellShapeshiftForm.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore, dbcPath,"StableSlotPrices.dbc");
//LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore, dbcPath,"SummonProperties.dbc");
LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore, dbcPath,"Talent.dbc");
// create talent spells set

View file

@ -136,7 +136,7 @@ extern DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore;
extern DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore;
extern DBCStorage <SpellEntry> sSpellStore;
extern DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore;
//extern DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore;
extern DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore;
extern DBCStorage <TalentEntry> sTalentStore;
extern DBCStorage <TalentTabEntry> sTalentTabStore;
extern DBCStorage <TaxiNodesEntry> sTaxiNodesStore;

View file

@ -1544,17 +1544,15 @@ struct StableSlotPricesEntry
uint32 Price;
};
/* unused currently
struct SummonPropertiesEntry
{
uint32 Id; // 0
uint32 Group; // 1, enum SummonPropGroup, 0 - can't be controlled?, 1 - something guardian?, 2 - pet?, 3 - something controllable?, 4 - taxi/mount?
uint32 Group; // 1, enum SummonPropGroup
uint32 FactionId; // 2, 14 rows > 0
uint32 Type; // 3, enum SummonPropType
uint32 Slot; // 4, 0-6
uint32 Slot; // 4, if type = SUMMON_PROP_TYPE_TOTEM, its actual slot 0-6
uint32 Flags; // 5, enum SummonPropFlags
};
*/
#define MAX_TALENT_RANK 5
#define MAX_PET_TALENT_RANK 3 // use in calculations, expected <= MAX_TALENT_RANK

View file

@ -93,7 +93,7 @@ const char SpellRangefmt[]="nffffxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char SpellRuneCostfmt[]="niiii";
const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxx";
const char StableSlotPricesfmt[] = "ni";
//const char SummonPropertiesfmt[] = "niiiii";
const char SummonPropertiesfmt[] = "niiiii";
const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx";
const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix";
const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii";

View file

@ -2442,38 +2442,6 @@ enum DiminishingGroup
DIMINISHING_LIMITONLY
};
enum SummonType
{
SUMMON_TYPE_CRITTER = 41,
SUMMON_TYPE_GUARDIAN = 61,
SUMMON_TYPE_TOTEM_SLOT1 = 63,
SUMMON_TYPE_WILD = 64,
SUMMON_TYPE_POSESSED = 65,
SUMMON_TYPE_DEMON = 66,
SUMMON_TYPE_SUMMON = 67,
SUMMON_TYPE_TOTEM_SLOT2 = 81,
SUMMON_TYPE_TOTEM_SLOT3 = 82,
SUMMON_TYPE_TOTEM_SLOT4 = 83,
SUMMON_TYPE_TOTEM = 121,
SUMMON_TYPE_UNKNOWN3 = 181,
SUMMON_TYPE_UNKNOWN4 = 187,
SUMMON_TYPE_UNKNOWN1 = 247,
SUMMON_TYPE_CRITTER2 = 407,
SUMMON_TYPE_CRITTER3 = 307,
SUMMON_TYPE_UNKNOWN5 = 409,
SUMMON_TYPE_UNKNOWN2 = 427,
SUMMON_TYPE_POSESSED2 = 428,
SUMMON_TYPE_QUEST_CRITTER = 487,
SUMMON_TYPE_QUEST_WILD = 587,
SUMMON_TYPE_INFERNO = 711,
SUMMON_TYPE_GUARDIAN2 = 713,
SUMMON_TYPE_LIGHTWELL = 1141,
SUMMON_TYPE_GUARDIAN3 = 1161,
SUMMON_TYPE_CREATURE = 1302,
SUMMON_TYPE_ELEMENTAL = 1561,
SUMMON_TYPE_FORCE_OF_NATURE = 1562
};
enum ResponseCodes
{
RESPONSE_SUCCESS = 0x00,

View file

@ -2225,13 +2225,6 @@ void Spell::SetTargetMap(uint32 effIndex,uint32 targetMode,UnitList& TagUnitMap)
}
break;
case SPELL_EFFECT_SUMMON:
if (m_spellInfo->EffectMiscValueB[effIndex] == SUMMON_TYPE_POSESSED ||
m_spellInfo->EffectMiscValueB[effIndex] == SUMMON_TYPE_POSESSED2)
{
if (m_targets.getUnitTarget())
TagUnitMap.push_back(m_targets.getUnitTarget());
}
else
TagUnitMap.push_back(m_caster);
break;
case SPELL_EFFECT_SUMMON_CHANGE_ITEM:
@ -4603,24 +4596,17 @@ SpellCastResult Spell::CheckCast(bool strict)
// This is generic summon effect
case SPELL_EFFECT_SUMMON:
{
switch(m_spellInfo->EffectMiscValueB[i])
if(SummonPropertiesEntry const *summon_prop = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]))
{
case SUMMON_TYPE_POSESSED:
case SUMMON_TYPE_POSESSED2:
case SUMMON_TYPE_DEMON:
case SUMMON_TYPE_SUMMON:
case SUMMON_TYPE_ELEMENTAL:
case SUMMON_TYPE_INFERNO:
if(summon_prop->Group == SUMMON_PROP_GROUP_PETS)
{
if(m_caster->GetPetGUID())
return SPELL_FAILED_ALREADY_HAVE_SUMMON;
if(m_caster->GetCharmGUID())
return SPELL_FAILED_ALREADY_HAVE_CHARM;
break;
}
}
break;
}
// Not used for summon?
case SPELL_EFFECT_SUMMON_PHANTASM:

View file

@ -248,8 +248,8 @@ class Spell
void EffectDualWield(uint32 i);
void EffectPickPocket(uint32 i);
void EffectAddFarsight(uint32 i);
void EffectSummonWild(uint32 i);
void EffectSummonGuardian(uint32 i);
void EffectSummonWild(uint32 i, uint32 forceFaction = 0);
void EffectSummonGuardian(uint32 i, uint32 forceFaction = 0);
void EffectHealMechanical(uint32 i);
void EffectJump(uint32 i);
void EffectTeleUnitsFaceCaster(uint32 i);
@ -277,7 +277,7 @@ class Spell
void EffectSummonPlayer(uint32 i);
void EffectActivateObject(uint32 i);
void EffectApplyGlyph(uint32 i);
void EffectSummonTotem(uint32 i);
void EffectSummonTotem(uint32 i, uint8 slot = 0);
void EffectEnchantHeldItem(uint32 i);
void EffectSummonObject(uint32 i);
void EffectResurrect(uint32 i);
@ -299,7 +299,7 @@ class Spell
void EffectMilling(uint32 i);
void EffectRenamePet(uint32 i);
void EffectSendTaxi(uint32 i);
void EffectSummonCritter(uint32 i);
void EffectSummonCritter(uint32 i, uint32 forceFaction = 0);
void EffectKnockBack(uint32 i);
void EffectPlayerPull(uint32 i);
void EffectDispelMechanic(uint32 i);
@ -314,7 +314,6 @@ class Spell
void EffectAddExtraAttacks(uint32 i);
void EffectSpiritHeal(uint32 i);
void EffectSkinPlayerCorpse(uint32 i);
void EffectSummonDemon(uint32 i);
void EffectStealBeneficialBuff(uint32 i);
void EffectUnlearnSpecialization(uint32 i);
void EffectHealPct(uint32 i);

View file

@ -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)
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);
EffectSummonGuardian(i, summon_prop->FactionId);
break;
case SUMMON_TYPE_WILD:
case SUMMON_TYPE_QUEST_WILD:
case SUMMON_TYPE_CREATURE:
EffectSummonWild(i);
}
case SUMMON_PROP_TYPE_CRITTER:
{
EffectSummonCritter(i, summon_prop->FactionId);
break;
case SUMMON_TYPE_DEMON:
case SUMMON_TYPE_INFERNO:
EffectSummonDemon(i);
}
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;
case SUMMON_TYPE_SUMMON:
case SUMMON_TYPE_ELEMENTAL:
}
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
EffectSummon(i);
break;
case SUMMON_TYPE_CRITTER:
case SUMMON_TYPE_CRITTER2:
case SUMMON_TYPE_CRITTER3:
case SUMMON_TYPE_QUEST_CRITTER:
EffectSummonCritter(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_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,11 +3849,9 @@ void Spell::EffectSummonWild(uint32 i)
{
uint16 skill202 = ((Player*)m_caster)->GetSkillValue(SKILL_ENGINERING);
if (skill202)
{
level = skill202/5;
}
}
}
// select center of summon position
float center_x = m_targets.m_destX;
@ -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

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8943"
#define REVISION_NR "8944"
#endif // __REVISION_NR_H__