* Merge.
--HG-- branch : trunk
This commit is contained in:
@@ -136,10 +136,10 @@ Unit(),
|
|||||||
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
|
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
|
||||||
m_lootMoney(0), m_lootRecipient(0),
|
m_lootMoney(0), m_lootRecipient(0),
|
||||||
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
|
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
|
||||||
m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isVehicle(false), m_isTotem(false),
|
m_gossipOptionLoaded(false), m_emoteState(0),
|
||||||
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
|
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
|
||||||
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
|
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
|
||||||
m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formationID(0), m_isSummon(false)
|
m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formationID(0), m_summonMask(SUMMON_MASK_NONE)
|
||||||
{
|
{
|
||||||
m_regenTimer = 200;
|
m_regenTimer = 200;
|
||||||
m_valuesCount = UNIT_END;
|
m_valuesCount = UNIT_END;
|
||||||
@@ -597,9 +597,10 @@ bool Creature::AIM_Initialize(CreatureAI* ai)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(i_AI) delete i_AI;
|
UnitAI *oldAI = i_AI;
|
||||||
i_motionMaster.Initialize();
|
i_motionMaster.Initialize();
|
||||||
i_AI = ai ? ai : FactorySelector::selectAI(this);
|
i_AI = ai ? ai : FactorySelector::selectAI(this);
|
||||||
|
if(oldAI) delete oldAI;
|
||||||
IsAIEnabled = true;
|
IsAIEnabled = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-8
@@ -136,6 +136,16 @@ enum CreatureFlagsExtra
|
|||||||
CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00010000, // cannot be taunted
|
CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00010000, // cannot be taunted
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SummonMask
|
||||||
|
{
|
||||||
|
SUMMON_MASK_NONE = 0x00000000,
|
||||||
|
SUMMON_MASK_SUMMON = 0x00000001,
|
||||||
|
SUMMON_MASK_GUARDIAN = 0x00000002,
|
||||||
|
SUMMON_MASK_TOTEM = 0x00000004,
|
||||||
|
SUMMON_MASK_PET = 0x00000008,
|
||||||
|
SUMMON_MASK_VEHICLE = 0x00000010,
|
||||||
|
};
|
||||||
|
|
||||||
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
|
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
|
||||||
#if defined( __GNUC__ )
|
#if defined( __GNUC__ )
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
@@ -436,11 +446,12 @@ class TRINITY_DLL_SPEC Creature : public Unit
|
|||||||
void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const;
|
void GetRespawnCoord(float &x, float &y, float &z, float* ori = NULL, float* dist =NULL) const;
|
||||||
uint32 GetEquipmentId() const { return m_equipmentId; }
|
uint32 GetEquipmentId() const { return m_equipmentId; }
|
||||||
|
|
||||||
bool isSummon() const { return m_isSummon; }
|
uint32 GetSummonMask() const { return m_summonMask; }
|
||||||
bool isPet() const { return m_isPet; }
|
bool isSummon() const { return m_summonMask & SUMMON_MASK_SUMMON; }
|
||||||
bool isVehicle() const { return m_isVehicle; }
|
bool isPet() const { return m_summonMask & SUMMON_MASK_PET; }
|
||||||
|
bool isVehicle() const { return m_summonMask & SUMMON_MASK_VEHICLE; }
|
||||||
|
bool isTotem() const { return m_summonMask & SUMMON_MASK_TOTEM; }
|
||||||
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
||||||
bool isTotem() const { return m_isTotem; }
|
|
||||||
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
|
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
|
||||||
bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
|
bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
|
||||||
bool isTrigger() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER; }
|
bool isTrigger() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER; }
|
||||||
@@ -669,10 +680,7 @@ class TRINITY_DLL_SPEC Creature : public Unit
|
|||||||
GossipOptionList m_goptions;
|
GossipOptionList m_goptions;
|
||||||
|
|
||||||
uint8 m_emoteState;
|
uint8 m_emoteState;
|
||||||
bool m_isSummon;
|
uint32 m_summonMask;
|
||||||
bool m_isPet; // set only in Pet::Pet
|
|
||||||
bool m_isVehicle; // set only in Vehicle::Vehicle
|
|
||||||
bool m_isTotem; // set only in Totem::Totem
|
|
||||||
ReactStates m_reactState; // for AI, not charmInfo
|
ReactStates m_reactState; // for AI, not charmInfo
|
||||||
void RegenerateMana();
|
void RegenerateMana();
|
||||||
void RegenerateHealth();
|
void RegenerateHealth();
|
||||||
|
|||||||
@@ -64,10 +64,17 @@ namespace FactorySelector
|
|||||||
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
||||||
else if(creature->isTotem())
|
else if(creature->isTotem())
|
||||||
ai_factory = ai_registry.GetRegistryItem("TotemAI");
|
ai_factory = ai_registry.GetRegistryItem("TotemAI");
|
||||||
else if(creature->isSummon() && ((TempSummon*)creature)->m_properties && ((TempSummon*)creature)->m_properties->Type == SUMMON_TYPE_MINIPET)
|
|
||||||
ai_factory = ai_registry.GetRegistryItem("CritterAI");
|
|
||||||
else if(creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
|
else if(creature->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER)
|
||||||
ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
|
ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
|
||||||
|
else if(creature->isSummon() && ((TempSummon*)creature)->m_Properties)
|
||||||
|
{
|
||||||
|
if(((TempSummon*)creature)->m_Properties->Category == SUMMON_CATEGORY_GUARDIAN
|
||||||
|
|| ((TempSummon*)creature)->m_Properties->Type == SUMMON_TYPE_GUARDIAN
|
||||||
|
|| ((TempSummon*)creature)->m_Properties->Type == SUMMON_TYPE_MINION)
|
||||||
|
ai_factory = ai_registry.GetRegistryItem("PetAI");
|
||||||
|
else if(((TempSummon*)creature)->m_Properties->Type == SUMMON_TYPE_MINIPET)
|
||||||
|
ai_factory = ai_registry.GetRegistryItem("CritterAI");
|
||||||
|
}
|
||||||
else if(creature->GetCreatureType() == CREATURE_TYPE_CRITTER)
|
else if(creature->GetCreatureType() == CREATURE_TYPE_CRITTER)
|
||||||
ai_factory = ai_registry.GetRegistryItem("CritterAI");
|
ai_factory = ai_registry.GetRegistryItem("CritterAI");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ class InstanceData;
|
|||||||
class Group;
|
class Group;
|
||||||
class InstanceSave;
|
class InstanceSave;
|
||||||
class WorldObject;
|
class WorldObject;
|
||||||
|
class TempSummon;
|
||||||
|
|
||||||
namespace ZThread
|
namespace ZThread
|
||||||
{
|
{
|
||||||
@@ -414,6 +415,8 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O
|
|||||||
template<class NOTIFIER> void VisitAll(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
template<class NOTIFIER> void VisitAll(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
||||||
template<class NOTIFIER> void VisitWorld(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
template<class NOTIFIER> void VisitWorld(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
||||||
template<class NOTIFIER> void VisitGrid(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
template<class NOTIFIER> void VisitGrid(const float &x, const float &y, float radius, NOTIFIER ¬ifier);
|
||||||
|
|
||||||
|
TempSummon *SummonCreature(uint32 entry, float x, float y, float z, float angle, SummonPropertiesEntry const *properties = NULL, uint32 duration = 0, Unit *summoner = NULL);
|
||||||
private:
|
private:
|
||||||
void LoadVMap(int pX, int pY);
|
void LoadVMap(int pX, int pY);
|
||||||
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
|
void LoadMap(uint32 mapid, uint32 instanceid, int x,int y);
|
||||||
|
|||||||
+73
-20
@@ -44,6 +44,7 @@
|
|||||||
#include "GridNotifiersImpl.h"
|
#include "GridNotifiersImpl.h"
|
||||||
|
|
||||||
#include "TemporarySummon.h"
|
#include "TemporarySummon.h"
|
||||||
|
#include "Totem.h"
|
||||||
|
|
||||||
uint32 GuidHigh2TypeId(uint32 guid_hi)
|
uint32 GuidHigh2TypeId(uint32 guid_hi)
|
||||||
{
|
{
|
||||||
@@ -1578,34 +1579,88 @@ void WorldObject::AddObjectToRemoveList()
|
|||||||
map->AddObjectToRemoveList(this);
|
map->AddObjectToRemoveList(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime)
|
TempSummon *Map::SummonCreature(uint32 entry, float x, float y, float z, float angle, SummonPropertiesEntry const *properties, uint32 duration, Unit *summoner)
|
||||||
{
|
{
|
||||||
TempSummon* pCreature = new TempSummon(GetGUID());
|
uint32 mask = SUMMON_MASK_SUMMON;
|
||||||
|
if(properties)
|
||||||
uint32 team = 0;
|
|
||||||
if (GetTypeId()==TYPEID_PLAYER)
|
|
||||||
team = ((Player*)this)->GetTeam();
|
|
||||||
|
|
||||||
if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), GetMap(), GetPhaseMask(), id, team))
|
|
||||||
{
|
{
|
||||||
delete pCreature;
|
if(properties->Category == SUMMON_CATEGORY_GUARDIAN
|
||||||
|
|| properties->Type == SUMMON_TYPE_GUARDIAN
|
||||||
|
|| properties->Type == SUMMON_TYPE_MINION)
|
||||||
|
mask = SUMMON_MASK_GUARDIAN;
|
||||||
|
else if(properties->Type == SUMMON_TYPE_TOTEM)
|
||||||
|
mask = SUMMON_MASK_TOTEM;
|
||||||
|
else if(properties->Category == SUMMON_CATEGORY_VEHICLE
|
||||||
|
|| properties->Type == SUMMON_TYPE_VEHICLE)
|
||||||
|
mask = SUMMON_MASK_VEHICLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
TempSummon *summon = NULL;
|
||||||
|
bool ok = true;
|
||||||
|
uint32 phase = PHASEMASK_NORMAL, team = 0;
|
||||||
|
if(summoner)
|
||||||
|
{
|
||||||
|
phase = summoner->GetPhaseMask();
|
||||||
|
if(summoner->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
team = ((Player*)summoner)->GetTeam();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(mask)
|
||||||
|
{
|
||||||
|
case SUMMON_MASK_SUMMON:
|
||||||
|
summon = new TempSummon(properties, summoner);
|
||||||
|
ok = summon->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, team);
|
||||||
|
break;
|
||||||
|
case SUMMON_MASK_GUARDIAN:
|
||||||
|
summon = new Guardian(properties, summoner);
|
||||||
|
team = objmgr.GeneratePetNumber();
|
||||||
|
ok = summon->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), this, phase, entry, team);
|
||||||
|
// this enables pet details window (Shift+P)
|
||||||
|
summon->GetCharmInfo()->SetPetNumber(team, false);
|
||||||
|
break;
|
||||||
|
case SUMMON_MASK_TOTEM:
|
||||||
|
summon = new Totem(properties, summoner);
|
||||||
|
ok = summon->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, team);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if(!ok)
|
||||||
|
{
|
||||||
|
delete summon;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
summon->Relocate(x, y, z, angle);
|
||||||
|
if(!summon->IsPositionValid())
|
||||||
|
{
|
||||||
|
sLog.outError("ERROR: Creature (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",summon->GetGUIDLow(),summon->GetEntry(),summon->GetPositionX(),summon->GetPositionY());
|
||||||
|
delete summon;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
summon->InitSummon(duration);
|
||||||
|
|
||||||
|
Add((Creature*)summon);
|
||||||
|
|
||||||
|
return summon;
|
||||||
|
}
|
||||||
|
|
||||||
|
TempSummon* WorldObject::SummonCreature(uint32 entry, float x, float y, float z, float ang, TempSummonType spwtype, uint32 duration)
|
||||||
|
{
|
||||||
|
if(!IsInWorld())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (x == 0.0f && y == 0.0f && z == 0.0f)
|
if (x == 0.0f && y == 0.0f && z == 0.0f)
|
||||||
GetClosePoint(x, y, z, pCreature->GetObjectSize());
|
GetClosePoint(x, y, z, GetObjectSize());
|
||||||
|
|
||||||
pCreature->Relocate(x, y, z, ang);
|
TempSummon *pCreature = GetMap()->SummonCreature(entry, x, y, z, ang, NULL, duration, GetTypeId() == TYPEID_UNIT ? (Unit*)this : NULL);
|
||||||
|
if(!pCreature)
|
||||||
if(!pCreature->IsPositionValid())
|
|
||||||
{
|
|
||||||
sLog.outError("ERROR: Creature (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
|
|
||||||
delete pCreature;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
pCreature->SetHomePosition(x, y, z, ang);
|
pCreature->SetHomePosition(x, y, z, ang);
|
||||||
pCreature->Summon(spwtype, despwtime);
|
pCreature->InitSummon(duration);
|
||||||
|
pCreature->SetTempSummonType(spwtype);
|
||||||
|
|
||||||
if(GetTypeId()==TYPEID_UNIT && ((Creature*)this)->IsAIEnabled)
|
if(GetTypeId()==TYPEID_UNIT && ((Creature*)this)->IsAIEnabled)
|
||||||
((Creature*)this)->AI()->JustSummoned(pCreature);
|
((Creature*)this)->AI()->JustSummoned(pCreature);
|
||||||
@@ -1617,7 +1672,6 @@ TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, fl
|
|||||||
pCreature->CastSpell(pCreature, pCreature->m_spells[0], false, 0, 0, GetGUID());
|
pCreature->CastSpell(pCreature, pCreature->m_spells[0], false, 0, 0, GetGUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
//return the creature therewith the summoner has access to it
|
|
||||||
return pCreature;
|
return pCreature;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1727,7 +1781,6 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
|
|||||||
|
|
||||||
switch(petType)
|
switch(petType)
|
||||||
{
|
{
|
||||||
case GUARDIAN_PET:
|
|
||||||
case POSSESSED_PET:
|
case POSSESSED_PET:
|
||||||
pet->SetUInt32Value(UNIT_FIELD_FLAGS,0);
|
pet->SetUInt32Value(UNIT_FIELD_FLAGS,0);
|
||||||
AddGuardian(pet);
|
AddGuardian(pet);
|
||||||
|
|||||||
+2
-41
@@ -44,19 +44,15 @@ Creature(), m_petType(type), m_removed(false), m_happinessTimer(7500), m_duratio
|
|||||||
m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraRaidUpdateMask(0), m_loading(false),
|
m_resetTalentsCost(0), m_resetTalentsTime(0), m_usedTalentCount(0), m_auraRaidUpdateMask(0), m_loading(false),
|
||||||
m_declinedname(NULL)
|
m_declinedname(NULL)
|
||||||
{
|
{
|
||||||
m_isPet = true;
|
m_summonMask |= SUMMON_MASK_PET;
|
||||||
m_name = "Pet";
|
m_name = "Pet";
|
||||||
m_regenTimer = 4000;
|
m_regenTimer = 4000;
|
||||||
|
|
||||||
// pets always have a charminfo, even if they are not actually charmed
|
// pets always have a charminfo, even if they are not actually charmed
|
||||||
CharmInfo* charmInfo = InitCharmInfo();
|
InitCharmInfo();
|
||||||
|
|
||||||
if(type == POSSESSED_PET) // always passive
|
if(type == POSSESSED_PET) // always passive
|
||||||
SetReactState(REACT_PASSIVE);
|
SetReactState(REACT_PASSIVE);
|
||||||
else if(type == GUARDIAN_PET) // always aggressive
|
|
||||||
SetReactState(REACT_AGGRESSIVE);
|
|
||||||
|
|
||||||
//m_isActive = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pet::~Pet()
|
Pet::~Pet()
|
||||||
@@ -930,41 +926,6 @@ bool Pet::InitStatsForLevel(uint32 petlevel)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GUARDIAN_PET:
|
|
||||||
SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);
|
|
||||||
SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, 1000);
|
|
||||||
|
|
||||||
switch(GetEntry())
|
|
||||||
{
|
|
||||||
case 1964: //force of nature
|
|
||||||
SetCreateHealth(30 + 30*petlevel);
|
|
||||||
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2)));
|
|
||||||
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2)));
|
|
||||||
break;
|
|
||||||
case 15352: //earth elemental 36213
|
|
||||||
SetCreateHealth(100 + 120*petlevel);
|
|
||||||
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
|
|
||||||
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
|
|
||||||
break;
|
|
||||||
case 15438: //fire elemental
|
|
||||||
SetCreateHealth(40*petlevel);
|
|
||||||
SetCreateMana(28 + 10*petlevel);
|
|
||||||
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel));
|
|
||||||
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
SetCreateMana(28 + 10*petlevel);
|
|
||||||
SetCreateHealth(28 + 30*petlevel);
|
|
||||||
|
|
||||||
// FIXME: this is wrong formula, possible each guardian pet have own damage formula
|
|
||||||
//these formula may not be correct; however, it is designed to be close to what it should be
|
|
||||||
//this makes dps 0.5 of pets level
|
|
||||||
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
|
|
||||||
//damage range is then petlevel / 2
|
|
||||||
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
sLog.outError("Pet have incorrect type (%u) for levelup.", getPetType());
|
sLog.outError("Pet have incorrect type (%u) for levelup.", getPetType());
|
||||||
break;
|
break;
|
||||||
|
|||||||
+2
-3
@@ -29,9 +29,8 @@ enum PetType
|
|||||||
{
|
{
|
||||||
SUMMON_PET = 0,
|
SUMMON_PET = 0,
|
||||||
HUNTER_PET = 1,
|
HUNTER_PET = 1,
|
||||||
GUARDIAN_PET = 2,
|
POSSESSED_PET = 2,
|
||||||
POSSESSED_PET = 3,
|
MAX_PET_TYPE = 4,
|
||||||
MAX_PET_TYPE = 4
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern char const* petTypeSuffix[MAX_PET_TYPE];
|
extern char const* petTypeSuffix[MAX_PET_TYPE];
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
|
|||||||
p->setDeathState(CORPSE);
|
p->setDeathState(CORPSE);
|
||||||
}
|
}
|
||||||
else // charmed or possessed
|
else // charmed or possessed
|
||||||
_player->Uncharm();
|
_player->StopCastingCharm();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", flag, spellid);
|
sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", flag, spellid);
|
||||||
@@ -493,7 +493,7 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data )
|
|||||||
_player->RemovePet((Pet*)pet,PET_SAVE_AS_DELETED);
|
_player->RemovePet((Pet*)pet,PET_SAVE_AS_DELETED);
|
||||||
}
|
}
|
||||||
else if(pet->GetGUID() == _player->GetCharmGUID())
|
else if(pet->GetGUID() == _player->GetCharmGUID())
|
||||||
_player->Uncharm();
|
_player->StopCastingCharm();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+29
-55
@@ -1424,9 +1424,6 @@ void Player::setDeathState(DeathState s)
|
|||||||
//FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
|
//FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD)
|
||||||
RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
|
RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
|
||||||
|
|
||||||
// remove uncontrolled pets
|
|
||||||
RemoveGuardians();
|
|
||||||
|
|
||||||
// save value before aura remove in Unit::setDeathState
|
// save value before aura remove in Unit::setDeathState
|
||||||
ressSpellId = GetUInt32Value(PLAYER_SELF_RES_SPELL);
|
ressSpellId = GetUInt32Value(PLAYER_SELF_RES_SPELL);
|
||||||
|
|
||||||
@@ -1886,7 +1883,6 @@ void Player::RemoveFromWorld()
|
|||||||
///- Release charmed creatures, unsummon totems and remove pets/guardians
|
///- Release charmed creatures, unsummon totems and remove pets/guardians
|
||||||
StopCastingCharm();
|
StopCastingCharm();
|
||||||
StopCastingBindSight();
|
StopCastingBindSight();
|
||||||
RemoveGuardians();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++)
|
for(int i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; i++)
|
||||||
@@ -17051,11 +17047,8 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
|
|||||||
// only if current pet in slot
|
// only if current pet in slot
|
||||||
switch(pet->getPetType())
|
switch(pet->getPetType())
|
||||||
{
|
{
|
||||||
case GUARDIAN_PET:
|
|
||||||
m_guardianPets.erase(pet->GetGUID());
|
|
||||||
break;
|
|
||||||
case POSSESSED_PET:
|
case POSSESSED_PET:
|
||||||
m_guardianPets.erase(pet->GetGUID());
|
m_Guardians.erase(pet->GetGUID());
|
||||||
pet->RemoveCharmedOrPossessedBy(NULL);
|
pet->RemoveCharmedOrPossessedBy(NULL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -17098,30 +17091,7 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::RemoveGuardians()
|
void Player::StopCastingCharm()
|
||||||
{
|
|
||||||
while(!m_guardianPets.empty())
|
|
||||||
{
|
|
||||||
uint64 guid = *m_guardianPets.begin();
|
|
||||||
if(Pet* pet = ObjectAccessor::GetPet(guid))
|
|
||||||
pet->Remove(PET_SAVE_AS_DELETED);
|
|
||||||
|
|
||||||
m_guardianPets.erase(guid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Player::HasGuardianWithEntry(uint32 entry)
|
|
||||||
{
|
|
||||||
// pet guid middle part is entry (and creature also)
|
|
||||||
// and in guardian list must be guardians with same entry _always_
|
|
||||||
for(GuardianPetList::const_iterator itr = m_guardianPets.begin(); itr != m_guardianPets.end(); ++itr)
|
|
||||||
if(GUID_ENPART(*itr)==entry)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::Uncharm()
|
|
||||||
{
|
{
|
||||||
Unit* charm = GetCharm();
|
Unit* charm = GetCharm();
|
||||||
if(!charm)
|
if(!charm)
|
||||||
@@ -17295,13 +17265,14 @@ void Player::PetSpellInitialize()
|
|||||||
data << uint32(itr->second); // category cooldown
|
data << uint32(itr->second); // category cooldown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.hexlike();
|
||||||
|
|
||||||
GetSession()->SendPacket(&data);
|
GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::PossessSpellInitialize()
|
void Player::PossessSpellInitialize()
|
||||||
{
|
{
|
||||||
Unit* charm = GetCharm();
|
Unit* charm = GetCharm();
|
||||||
|
|
||||||
if(!charm)
|
if(!charm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -17313,24 +17284,23 @@ void Player::PossessSpellInitialize()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 addlist = 0;
|
WorldPacket data(SMSG_PET_SPELLS, 20+40+1+1);
|
||||||
WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds
|
|
||||||
|
|
||||||
//16
|
//basic info 20
|
||||||
data << uint64(charm->GetGUID());
|
data << uint64(charm->GetGUID());
|
||||||
data << uint32(0x00000000);
|
data << uint32(0); //family
|
||||||
data << uint32(0);
|
data << uint32(0); //0
|
||||||
data << uint8(0) << uint8(0) << uint16(0);
|
data << uint8(0) << uint8(0) << uint16(0); //reactstate, commandstate, 0
|
||||||
|
|
||||||
for(uint32 i = 0; i < 10; i++) //40
|
//action bar 40
|
||||||
{
|
for(uint32 i = 0; i < 10; i++)
|
||||||
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
|
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
|
||||||
}
|
|
||||||
|
|
||||||
data << uint8(addlist); //1
|
//addlist 1
|
||||||
|
data << uint8(0);
|
||||||
|
|
||||||
uint8 count = 0;
|
//cooldown 1
|
||||||
data << uint8(count); // cooldowns count
|
data << uint8(0);
|
||||||
|
|
||||||
GetSession()->SendPacket(&data);
|
GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
@@ -17377,7 +17347,8 @@ void Player::VehicleSpellInitialize()
|
|||||||
void Player::CharmSpellInitialize()
|
void Player::CharmSpellInitialize()
|
||||||
{
|
{
|
||||||
Unit* charm = GetCharm();
|
Unit* charm = GetCharm();
|
||||||
|
if(!charm && GetPetGUID())
|
||||||
|
charm = GetUnit(*this, GetPetGUID());
|
||||||
if(!charm)
|
if(!charm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -17389,14 +17360,12 @@ void Player::CharmSpellInitialize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8 addlist = 0;
|
uint8 addlist = 0;
|
||||||
|
|
||||||
if(charm->GetTypeId() != TYPEID_PLAYER)
|
if(charm->GetTypeId() != TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
CreatureInfo const *cinfo = ((Creature*)charm)->GetCreatureInfo();
|
CreatureInfo const *cinfo = ((Creature*)charm)->GetCreatureInfo();
|
||||||
|
//if(cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK)
|
||||||
if(cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK)
|
|
||||||
{
|
{
|
||||||
for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
|
for(uint32 i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
if(charmInfo->GetCharmSpell(i)->spellId)
|
if(charmInfo->GetCharmSpell(i)->spellId)
|
||||||
++addlist;
|
++addlist;
|
||||||
@@ -17404,10 +17373,11 @@ void Player::CharmSpellInitialize()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds
|
WorldPacket data(SMSG_PET_SPELLS, 20+40+1+4*addlist+1);// first line + actionbar + spellcount + spells + last adds
|
||||||
|
|
||||||
|
//basic info 20
|
||||||
data << uint64(charm->GetGUID());
|
data << uint64(charm->GetGUID());
|
||||||
data << uint32(0x00000000);
|
data << uint32(0);
|
||||||
data << uint32(0);
|
data << uint32(0);
|
||||||
if(charm->GetTypeId() != TYPEID_PLAYER)
|
if(charm->GetTypeId() != TYPEID_PLAYER)
|
||||||
data << uint8(((Creature*)charm)->GetReactState()) << uint8(charmInfo->GetCommandState());
|
data << uint8(((Creature*)charm)->GetReactState()) << uint8(charmInfo->GetCommandState());
|
||||||
@@ -17415,16 +17385,17 @@ void Player::CharmSpellInitialize()
|
|||||||
data << uint8(0) << uint8(0);
|
data << uint8(0) << uint8(0);
|
||||||
data << uint16(0);
|
data << uint16(0);
|
||||||
|
|
||||||
for(uint32 i = 0; i < 10; i++) //40
|
//action bar 40
|
||||||
|
for(uint32 i = 0; i < 10; ++i) //40
|
||||||
{
|
{
|
||||||
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
|
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//add list
|
||||||
data << uint8(addlist); //1
|
data << uint8(addlist); //1
|
||||||
|
|
||||||
if(addlist)
|
if(addlist)
|
||||||
{
|
{
|
||||||
for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
|
for(uint32 i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
CharmSpellEntry *cspell = charmInfo->GetCharmSpell(i);
|
CharmSpellEntry *cspell = charmInfo->GetCharmSpell(i);
|
||||||
if(cspell->spellId)
|
if(cspell->spellId)
|
||||||
@@ -17435,9 +17406,12 @@ void Player::CharmSpellInitialize()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//cooldown
|
||||||
uint8 count = 0;
|
uint8 count = 0;
|
||||||
data << uint8(count); // cooldowns count
|
data << uint8(count); // cooldowns count
|
||||||
|
|
||||||
|
data.hexlike();
|
||||||
|
|
||||||
GetSession()->SendPacket(&data);
|
GetSession()->SendPacket(&data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-10
@@ -298,8 +298,6 @@ typedef std::map<RepListID,FactionState> FactionStateList;
|
|||||||
|
|
||||||
typedef std::map<uint32,ReputationRank> ForcedReactions;
|
typedef std::map<uint32,ReputationRank> ForcedReactions;
|
||||||
|
|
||||||
typedef std::set<uint64> GuardianPetList;
|
|
||||||
|
|
||||||
struct EnchantDuration
|
struct EnchantDuration
|
||||||
{
|
{
|
||||||
EnchantDuration() : item(NULL), slot(MAX_ENCHANTMENT_SLOT), leftduration(0) {};
|
EnchantDuration() : item(NULL), slot(MAX_ENCHANTMENT_SLOT), leftduration(0) {};
|
||||||
@@ -1052,11 +1050,6 @@ class TRINITY_DLL_SPEC Player : public Unit
|
|||||||
|
|
||||||
Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime);
|
Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime);
|
||||||
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
|
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
|
||||||
void RemoveGuardians();
|
|
||||||
bool HasGuardianWithEntry(uint32 entry);
|
|
||||||
void AddGuardian(Pet* pet) { m_guardianPets.insert(pet->GetGUID()); }
|
|
||||||
GuardianPetList const& GetGuardians() const { return m_guardianPets; }
|
|
||||||
void Uncharm();
|
|
||||||
uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
|
uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
|
||||||
|
|
||||||
void Say(const std::string& text, const uint32 language);
|
void Say(const std::string& text, const uint32 language);
|
||||||
@@ -2058,7 +2051,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
|||||||
void SetSeer(WorldObject *target) { m_seer = target; }
|
void SetSeer(WorldObject *target) { m_seer = target; }
|
||||||
void CreateViewpoint(WorldObject *target);
|
void CreateViewpoint(WorldObject *target);
|
||||||
WorldObject* GetViewpoint() const;
|
WorldObject* GetViewpoint() const;
|
||||||
void StopCastingCharm() { Uncharm(); }
|
void StopCastingCharm();
|
||||||
void StopCastingBindSight();
|
void StopCastingBindSight();
|
||||||
|
|
||||||
// Transports
|
// Transports
|
||||||
@@ -2420,8 +2413,6 @@ class TRINITY_DLL_SPEC Player : public Unit
|
|||||||
uint32 m_temporaryUnsummonedPetNumber;
|
uint32 m_temporaryUnsummonedPetNumber;
|
||||||
uint32 m_oldpetspell;
|
uint32 m_oldpetspell;
|
||||||
|
|
||||||
GuardianPetList m_guardianPets;
|
|
||||||
|
|
||||||
// Player summoning
|
// Player summoning
|
||||||
time_t m_summon_expire;
|
time_t m_summon_expire;
|
||||||
uint32 m_summon_mapid;
|
uint32 m_summon_mapid;
|
||||||
|
|||||||
@@ -2386,18 +2386,24 @@ enum SummonCategory
|
|||||||
|
|
||||||
enum SummonType
|
enum SummonType
|
||||||
{
|
{
|
||||||
|
SUMMON_TYPE_NONE = 0,
|
||||||
|
SUMMON_TYPE_WILD1 = 1,
|
||||||
|
SUMMON_TYPE_GUARDIAN = 2,
|
||||||
|
SUMMON_TYPE_MINION = 3,
|
||||||
|
SUMMON_TYPE_TOTEM = 4,
|
||||||
SUMMON_TYPE_MINIPET = 5,
|
SUMMON_TYPE_MINIPET = 5,
|
||||||
|
SUMMON_TYPE_GUARDIAN2 = 6,
|
||||||
|
SUMMON_TYPE_WILD2 = 7,
|
||||||
|
SUMMON_TYPE_WILD3 = 8,
|
||||||
|
SUMMON_TYPE_WILD4 = 9,
|
||||||
|
SUMMON_TYPE_VEHICLE = 10,
|
||||||
|
SUMMON_TYPE_OBJECT = 11,
|
||||||
|
|
||||||
SUMMON_TYPE_CRITTER = 41,
|
SUMMON_TYPE_CRITTER = 41,
|
||||||
SUMMON_TYPE_GUARDIAN = 61,
|
//SUMMON_TYPE_GUARDIAN = 61,
|
||||||
SUMMON_TYPE_TOTEM_SLOT1 = 63,
|
|
||||||
SUMMON_TYPE_WILD = 64,
|
SUMMON_TYPE_WILD = 64,
|
||||||
SUMMON_TYPE_DEMON = 66,
|
SUMMON_TYPE_DEMON = 66,
|
||||||
SUMMON_TYPE_SUMMON = 67,
|
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_UNKNOWN3 = 181,
|
||||||
SUMMON_TYPE_UNKNOWN4 = 187,
|
SUMMON_TYPE_UNKNOWN4 = 187,
|
||||||
SUMMON_TYPE_UNKNOWN1 = 247,
|
SUMMON_TYPE_UNKNOWN1 = 247,
|
||||||
|
|||||||
+4
-4
@@ -276,10 +276,7 @@ class Spell
|
|||||||
void EffectDualWield(uint32 i);
|
void EffectDualWield(uint32 i);
|
||||||
void EffectPickPocket(uint32 i);
|
void EffectPickPocket(uint32 i);
|
||||||
void EffectAddFarsight(uint32 i);
|
void EffectAddFarsight(uint32 i);
|
||||||
void EffectSummonPossessed(uint32 i);
|
|
||||||
void EffectSummonVehicle(uint32 i);
|
|
||||||
void EffectSummonWild(uint32 i);
|
void EffectSummonWild(uint32 i);
|
||||||
void EffectSummonGuardian(uint32 i);
|
|
||||||
void EffectHealMechanical(uint32 i);
|
void EffectHealMechanical(uint32 i);
|
||||||
void EffectJump(uint32 i);
|
void EffectJump(uint32 i);
|
||||||
void EffectTeleUnitsFaceCaster(uint32 i);
|
void EffectTeleUnitsFaceCaster(uint32 i);
|
||||||
@@ -307,7 +304,6 @@ class Spell
|
|||||||
void EffectSummonPlayer(uint32 i);
|
void EffectSummonPlayer(uint32 i);
|
||||||
void EffectActivateObject(uint32 i);
|
void EffectActivateObject(uint32 i);
|
||||||
void EffectApplyGlyph(uint32 i);
|
void EffectApplyGlyph(uint32 i);
|
||||||
void EffectSummonTotem(uint32 i);
|
|
||||||
void EffectEnchantHeldItem(uint32 i);
|
void EffectEnchantHeldItem(uint32 i);
|
||||||
void EffectSummonObject(uint32 i);
|
void EffectSummonObject(uint32 i);
|
||||||
void EffectResurrect(uint32 i);
|
void EffectResurrect(uint32 i);
|
||||||
@@ -600,6 +596,10 @@ class Spell
|
|||||||
void SpellDamageHeal(uint32 i);
|
void SpellDamageHeal(uint32 i);
|
||||||
|
|
||||||
void GetSummonPosition(float &x, float &y, float &z, float radius = 0.0f, uint32 count = 0);
|
void GetSummonPosition(float &x, float &y, float &z, float radius = 0.0f, uint32 count = 0);
|
||||||
|
void SummonTotem (uint32 entry, SummonPropertiesEntry const *properties);
|
||||||
|
void SummonGuardian (uint32 entry, SummonPropertiesEntry const *properties);
|
||||||
|
void SummonPossessed(uint32 entry, SummonPropertiesEntry const *properties);
|
||||||
|
void SummonVehicle (uint32 entry, SummonPropertiesEntry const *properties);
|
||||||
|
|
||||||
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType& skillid, int32& reqSkillValue, int32& skillValue);
|
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType& skillid, int32& reqSkillValue, int32& skillValue);
|
||||||
// -------------------------------------------
|
// -------------------------------------------
|
||||||
|
|||||||
@@ -5440,6 +5440,7 @@ void Aura::CleanupTriggeredSpells()
|
|||||||
if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
|
if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
|
||||||
GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()])
|
GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()])
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_target->RemoveAurasDueToSpell(tSpellId);
|
m_target->RemoveAurasDueToSpell(tSpellId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+150
-217
@@ -3313,15 +3313,12 @@ void Spell::EffectApplyAreaAura(uint32 i)
|
|||||||
|
|
||||||
void Spell::EffectSummonType(uint32 i)
|
void Spell::EffectSummonType(uint32 i)
|
||||||
{
|
{
|
||||||
|
uint32 entry = m_spellInfo->EffectMiscValue[i];
|
||||||
|
if(!entry)
|
||||||
|
return;
|
||||||
|
|
||||||
switch(m_spellInfo->EffectMiscValueB[i])
|
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_WILD:
|
||||||
case SUMMON_TYPE_FROZEN_EARTH:
|
case SUMMON_TYPE_FROZEN_EARTH:
|
||||||
case SUMMON_TYPE_LIGHTWELL:
|
case SUMMON_TYPE_LIGHTWELL:
|
||||||
@@ -3333,39 +3330,45 @@ void Spell::EffectSummonType(uint32 i)
|
|||||||
case SUMMON_TYPE_SUMMON:
|
case SUMMON_TYPE_SUMMON:
|
||||||
EffectSummon(i);
|
EffectSummon(i);
|
||||||
break;
|
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:
|
default:
|
||||||
{
|
{
|
||||||
SummonPropertiesEntry const *SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]);
|
SummonPropertiesEntry const *properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]);
|
||||||
if(!SummonProperties)
|
if(!properties)
|
||||||
{
|
{
|
||||||
sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]);
|
sLog.outError("EffectSummonType: Unhandled summon type %u", m_spellInfo->EffectMiscValueB[i]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch(SummonProperties->Category)
|
switch(properties->Category)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
if(SummonProperties->Type == SUMMON_TYPE_MINIPET)
|
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);
|
EffectSummonCritter(i);
|
||||||
else
|
break;
|
||||||
|
default:
|
||||||
EffectSummonWild(i);
|
EffectSummonWild(i);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SUMMON_CATEGORY_GUARDIAN:
|
||||||
|
SummonGuardian(entry, properties);
|
||||||
|
break;
|
||||||
case SUMMON_CATEGORY_POSSESSED:
|
case SUMMON_CATEGORY_POSSESSED:
|
||||||
EffectSummonPossessed(i);
|
SummonPossessed(entry, properties);
|
||||||
break;
|
break;
|
||||||
case SUMMON_CATEGORY_VEHICLE:
|
case SUMMON_CATEGORY_VEHICLE:
|
||||||
EffectSummonVehicle(i);
|
SummonVehicle(entry, properties);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
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)
|
void Spell::EffectTeleUnitsFaceCaster(uint32 i)
|
||||||
{
|
{
|
||||||
if(!unitTarget)
|
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)
|
void Spell::EffectEnchantHeldItem(uint32 i)
|
||||||
{
|
{
|
||||||
// this is only item spell effect applied to main-hand weapon of target player (players in area)
|
// 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);
|
GetSummonPosition(x, y, z);
|
||||||
|
|
||||||
int32 duration = GetSpellDuration(m_spellInfo);
|
int32 duration = GetSpellDuration(m_spellInfo);
|
||||||
TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
|
TempSummon *critter = m_caster->GetMap()->SummonCreature(pet_entry, x, y, z, m_caster->GetOrientation(), sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]), duration, m_caster);
|
||||||
TempSummon *critter = m_caster->SummonCreature(pet_entry, x, y, z, m_caster->GetOrientation(), summonType, duration);
|
|
||||||
if(!critter)
|
if(!critter)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -6052,8 +5875,6 @@ void Spell::EffectSummonCritter(uint32 i)
|
|||||||
std::string name = player->GetName();
|
std::string name = player->GetName();
|
||||||
name.append(petTypeSuffix[3]);
|
name.append(petTypeSuffix[3]);
|
||||||
critter->SetName( name );
|
critter->SetName( name );
|
||||||
|
|
||||||
critter->SetSummonProperties(sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Spell::EffectKnockBack(uint32 i)
|
void Spell::EffectKnockBack(uint32 i)
|
||||||
@@ -6681,12 +6502,128 @@ void Spell::EffectRedirectThreat(uint32 /*i*/)
|
|||||||
m_caster->SetReducedThreatPercent((uint32)damage, unitTarget->GetGUID());
|
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];
|
int8 slot = (int8)properties->Slot - 1;
|
||||||
if(!entry)
|
|
||||||
|
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;
|
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)
|
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -6705,12 +6642,8 @@ void Spell::EffectSummonPossessed(uint32 i)
|
|||||||
pet->SetCharmedOrPossessedBy(m_caster, true);
|
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;
|
float x, y, z;
|
||||||
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
|
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
|
||||||
Vehicle *vehicle = m_caster->SummonVehicle(entry, x, y, z, m_caster->GetOrientation());
|
Vehicle *vehicle = m_caster->SummonVehicle(entry, x, y, z, m_caster->GetOrientation());
|
||||||
|
|||||||
+129
-41
@@ -22,12 +22,13 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "ObjectAccessor.h"
|
#include "ObjectAccessor.h"
|
||||||
#include "CreatureAI.h"
|
#include "CreatureAI.h"
|
||||||
|
#include "ObjectMgr.h"
|
||||||
|
|
||||||
TempSummon::TempSummon( uint64 summoner ) :
|
TempSummon::TempSummon(SummonPropertiesEntry const *properties, Unit *owner) :
|
||||||
Creature(), m_type(TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN), m_timer(0), m_lifetime(0), m_summoner(summoner)
|
Creature(), m_type(TEMPSUMMON_MANUAL_DESPAWN), m_timer(0), m_lifetime(0)
|
||||||
, m_properties(NULL)
|
, m_Properties(properties), m_summonerGUID(owner->GetGUID())
|
||||||
{
|
{
|
||||||
m_isSummon = true;
|
m_summonMask |= SUMMON_MASK_SUMMON;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TempSummon::Update( uint32 diff )
|
void TempSummon::Update( uint32 diff )
|
||||||
@@ -159,50 +160,23 @@ void TempSummon::Update( uint32 diff )
|
|||||||
Creature::Update( diff );
|
Creature::Update( diff );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TempSummon::Summon(TempSummonType type, uint32 lifetime)
|
void TempSummon::InitSummon(uint32 duration)
|
||||||
{
|
{
|
||||||
m_type = type;
|
m_timer = duration;
|
||||||
m_timer = lifetime;
|
m_lifetime = duration;
|
||||||
m_lifetime = lifetime;
|
|
||||||
|
|
||||||
GetMap()->Add((Creature*)this);
|
if(m_type == TEMPSUMMON_MANUAL_DESPAWN)
|
||||||
|
m_type = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
|
||||||
|
|
||||||
AIM_Initialize();
|
AIM_Initialize();
|
||||||
}
|
|
||||||
|
|
||||||
void TempSummon::UnSummon()
|
if(!m_Properties)
|
||||||
{
|
|
||||||
CleanupsBeforeDelete();
|
|
||||||
AddObjectToRemoveList();
|
|
||||||
|
|
||||||
Unit* owner = GetSummoner();
|
|
||||||
if(owner)
|
|
||||||
{
|
|
||||||
if(owner->GetTypeId() == TYPEID_UNIT && ((Creature*)owner)->IsAIEnabled)
|
|
||||||
((Creature*)owner)->AI()->SummonedCreatureDespawn(this);
|
|
||||||
|
|
||||||
if(!m_properties)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(uint32 slot = m_properties->Slot)
|
|
||||||
{
|
|
||||||
--slot;
|
|
||||||
owner->m_TotemSlot[slot] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TempSummon::SetSummonProperties(SummonPropertiesEntry const *properties)
|
|
||||||
{
|
|
||||||
if(!properties)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_properties = properties;
|
|
||||||
|
|
||||||
if(uint32 slot = m_properties->Slot)
|
|
||||||
{
|
|
||||||
--slot;
|
|
||||||
Unit* owner = GetSummoner();
|
Unit* owner = GetSummoner();
|
||||||
|
if(uint32 slot = m_Properties->Slot)
|
||||||
|
{
|
||||||
|
--slot;
|
||||||
if(owner)
|
if(owner)
|
||||||
{
|
{
|
||||||
if(owner->m_TotemSlot[slot] && owner->m_TotemSlot[slot] != GetGUID())
|
if(owner->m_TotemSlot[slot] && owner->m_TotemSlot[slot] != GetGUID())
|
||||||
@@ -214,11 +188,125 @@ void TempSummon::SetSummonProperties(SummonPropertiesEntry const *properties)
|
|||||||
owner->m_TotemSlot[slot] = GetGUID();
|
owner->m_TotemSlot[slot] = GetGUID();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AIM_Initialize();
|
void TempSummon::SetTempSummonType(TempSummonType type)
|
||||||
|
{
|
||||||
|
m_type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TempSummon::UnSummon()
|
||||||
|
{
|
||||||
|
Unit* owner = GetSummoner();
|
||||||
|
if(owner)
|
||||||
|
{
|
||||||
|
if(owner->GetTypeId() == TYPEID_UNIT && ((Creature*)owner)->IsAIEnabled)
|
||||||
|
((Creature*)owner)->AI()->SummonedCreatureDespawn(this);
|
||||||
|
|
||||||
|
if(m_Properties)
|
||||||
|
{
|
||||||
|
if(uint32 slot = m_Properties->Slot)
|
||||||
|
{
|
||||||
|
--slot;
|
||||||
|
if(owner->m_TotemSlot[slot] = GetGUID())
|
||||||
|
owner->m_TotemSlot[slot] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CleanupsBeforeDelete();
|
||||||
|
AddObjectToRemoveList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TempSummon::SaveToDB()
|
void TempSummon::SaveToDB()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Guardian::Guardian(SummonPropertiesEntry const *properties, Unit *owner) : TempSummon(properties, owner)
|
||||||
|
, m_owner(owner)
|
||||||
|
{
|
||||||
|
m_summonMask |= SUMMON_MASK_GUARDIAN;
|
||||||
|
InitCharmInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Guardian::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number)
|
||||||
|
{
|
||||||
|
SetMapId(map->GetId());
|
||||||
|
SetInstanceId(map->GetInstanceId());
|
||||||
|
SetPhaseMask(phaseMask,false);
|
||||||
|
|
||||||
|
Object::_Create(guidlow, pet_number, HIGHGUID_PET);
|
||||||
|
|
||||||
|
m_DBTableGuid = guidlow;
|
||||||
|
m_originalEntry = Entry;
|
||||||
|
|
||||||
|
if(!InitEntry(Entry))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Guardian::InitSummon(uint32 duration)
|
||||||
|
{
|
||||||
|
TempSummon::InitSummon(duration);
|
||||||
|
|
||||||
|
SetReactState(REACT_AGGRESSIVE);
|
||||||
|
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);
|
||||||
|
|
||||||
|
SetOwnerGUID(m_owner->GetGUID());
|
||||||
|
SetCreatorGUID(m_owner->GetGUID());
|
||||||
|
SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, m_owner->getFaction());
|
||||||
|
m_owner->AddGuardian(this);
|
||||||
|
SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);
|
||||||
|
|
||||||
|
if(m_owner->GetTypeId() == TYPEID_PLAYER)
|
||||||
|
{
|
||||||
|
m_owner->SetUInt64Value(UNIT_FIELD_SUMMON, GetGUID());
|
||||||
|
m_charmInfo->InitCharmCreateSpells();
|
||||||
|
//charmInfo->SetPetNumber(objmgr.GeneratePetNumber(), true);
|
||||||
|
((Player*)m_owner)->CharmSpellInitialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Guardian::InitStatsForLevel(uint32 petlevel)
|
||||||
|
{
|
||||||
|
SetLevel(petlevel);
|
||||||
|
switch(GetEntry())
|
||||||
|
{
|
||||||
|
case 1964: //force of nature
|
||||||
|
SetCreateHealth(30 + 30*petlevel);
|
||||||
|
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 2.5f - (petlevel / 2)));
|
||||||
|
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 2.5f + (petlevel / 2)));
|
||||||
|
break;
|
||||||
|
case 15352: //earth elemental 36213
|
||||||
|
SetCreateHealth(100 + 120*petlevel);
|
||||||
|
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
|
||||||
|
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
|
||||||
|
break;
|
||||||
|
case 15438: //fire elemental
|
||||||
|
SetCreateHealth(40*petlevel);
|
||||||
|
SetCreateMana(28 + 10*petlevel);
|
||||||
|
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel * 4 - petlevel));
|
||||||
|
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SetCreateMana(28 + 10*petlevel);
|
||||||
|
SetCreateHealth(28 + 30*petlevel);
|
||||||
|
// FIXME: this is wrong formula, possible each guardian pet have own damage formula
|
||||||
|
//these formula may not be correct; however, it is designed to be close to what it should be
|
||||||
|
//this makes dps 0.5 of pets level
|
||||||
|
SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)));
|
||||||
|
//damage range is then petlevel / 2
|
||||||
|
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel + (petlevel / 4)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Guardian::UnSummon()
|
||||||
|
{
|
||||||
|
m_owner->m_Guardians.erase(GetGUID());
|
||||||
|
TempSummon::UnSummon();
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,21 +27,34 @@
|
|||||||
class TempSummon : public Creature
|
class TempSummon : public Creature
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit TempSummon(uint64 summoner = 0);
|
explicit TempSummon(SummonPropertiesEntry const *properties, Unit *owner);
|
||||||
virtual ~TempSummon(){};
|
virtual ~TempSummon(){};
|
||||||
void Update(uint32 time);
|
void Update(uint32 time);
|
||||||
void Summon(TempSummonType type, uint32 lifetime);
|
virtual void InitSummon(uint32 lifetime);
|
||||||
virtual void UnSummon();
|
virtual void UnSummon();
|
||||||
|
void SetTempSummonType(TempSummonType type);
|
||||||
void SaveToDB();
|
void SaveToDB();
|
||||||
Unit* GetSummoner() const { return m_summoner ? ObjectAccessor::GetUnit(*this, m_summoner) : NULL; }
|
Unit* GetSummoner() const { return m_summonerGUID ? ObjectAccessor::GetUnit(*this, m_summonerGUID) : NULL; }
|
||||||
|
|
||||||
void SetSummonProperties(SummonPropertiesEntry const *properties);
|
SummonPropertiesEntry const *m_Properties;
|
||||||
SummonPropertiesEntry const *m_properties;
|
|
||||||
private:
|
private:
|
||||||
TempSummonType m_type;
|
TempSummonType m_type;
|
||||||
uint32 m_timer;
|
uint32 m_timer;
|
||||||
uint32 m_lifetime;
|
uint32 m_lifetime;
|
||||||
uint64 m_summoner;
|
uint64 m_summonerGUID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Guardian : public TempSummon
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Guardian(SummonPropertiesEntry const *properties, Unit *owner);
|
||||||
|
bool Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number);
|
||||||
|
void InitSummon(uint32 duration);
|
||||||
|
void UnSummon();
|
||||||
|
void InitStatsForLevel(uint32 level);
|
||||||
|
protected:
|
||||||
|
Unit *m_owner;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -26,9 +26,9 @@
|
|||||||
#include "ObjectMgr.h"
|
#include "ObjectMgr.h"
|
||||||
#include "SpellMgr.h"
|
#include "SpellMgr.h"
|
||||||
|
|
||||||
Totem::Totem() : TempSummon(0)
|
Totem::Totem(SummonPropertiesEntry const *properties, Unit *owner) : TempSummon(properties, owner)
|
||||||
{
|
{
|
||||||
m_isTotem = true;
|
m_summonMask |= SUMMON_MASK_TOTEM;
|
||||||
m_duration = 0;
|
m_duration = 0;
|
||||||
m_type = TOTEM_PASSIVE;
|
m_type = TOTEM_PASSIVE;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ enum TotemType
|
|||||||
class Totem : public TempSummon
|
class Totem : public TempSummon
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Totem();
|
explicit Totem(SummonPropertiesEntry const *properties, Unit *owner);
|
||||||
virtual ~Totem(){};
|
virtual ~Totem(){};
|
||||||
void Update( uint32 time );
|
void Update( uint32 time );
|
||||||
void Summon(Unit* owner);
|
void Summon(Unit* owner);
|
||||||
|
|||||||
+25
-9
@@ -106,7 +106,7 @@ Unit::Unit()
|
|||||||
|
|
||||||
m_addDmgOnce = 0;
|
m_addDmgOnce = 0;
|
||||||
|
|
||||||
for(int i = 0; i < MAX_TOTEM; ++i)
|
for(int i = 0; i < MAX_SUMMON_SLOT; ++i)
|
||||||
m_TotemSlot[i] = 0;
|
m_TotemSlot[i] = 0;
|
||||||
|
|
||||||
m_ObjectSlot[0] = m_ObjectSlot[1] = m_ObjectSlot[2] = m_ObjectSlot[3] = 0;
|
m_ObjectSlot[0] = m_ObjectSlot[1] = m_ObjectSlot[2] = m_ObjectSlot[3] = 0;
|
||||||
@@ -8139,14 +8139,10 @@ void Unit::CombatStopWithPets(bool cast)
|
|||||||
pet->CombatStop(cast);
|
pet->CombatStop(cast);
|
||||||
if(Unit* charm = GetCharm())
|
if(Unit* charm = GetCharm())
|
||||||
charm->CombatStop(cast);
|
charm->CombatStop(cast);
|
||||||
if(GetTypeId()==TYPEID_PLAYER)
|
for(GuardianList::const_iterator itr = m_Guardians.begin(); itr != m_Guardians.end(); ++itr)
|
||||||
{
|
|
||||||
GuardianPetList const& guardians = ((Player*)this)->GetGuardians();
|
|
||||||
for(GuardianPetList::const_iterator itr = guardians.begin(); itr != guardians.end(); ++itr)
|
|
||||||
if(Unit* guardian = Unit::GetUnit(*this,*itr))
|
if(Unit* guardian = Unit::GetUnit(*this,*itr))
|
||||||
guardian->CombatStop(cast);
|
guardian->CombatStop(cast);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool Unit::isAttackingPlayer() const
|
bool Unit::isAttackingPlayer() const
|
||||||
{
|
{
|
||||||
@@ -8362,7 +8358,7 @@ void Unit::RemoveCharmAuras()
|
|||||||
|
|
||||||
void Unit::UnsummonAllTotems()
|
void Unit::UnsummonAllTotems()
|
||||||
{
|
{
|
||||||
for (int8 i = 0; i < MAX_TOTEM; ++i)
|
for (int8 i = 0; i < MAX_SUMMON_SLOT; ++i)
|
||||||
{
|
{
|
||||||
if(!m_TotemSlot[i])
|
if(!m_TotemSlot[i])
|
||||||
continue;
|
continue;
|
||||||
@@ -10447,8 +10443,9 @@ void Unit::setDeathState(DeathState s)
|
|||||||
|
|
||||||
if (s == JUST_DIED)
|
if (s == JUST_DIED)
|
||||||
{
|
{
|
||||||
RemoveAllAurasOnDeath();
|
|
||||||
UnsummonAllTotems();
|
UnsummonAllTotems();
|
||||||
|
RemoveGuardians();
|
||||||
|
RemoveAllAurasOnDeath();
|
||||||
//This is needed to clear visible auras after unit dies
|
//This is needed to clear visible auras after unit dies
|
||||||
UpdateAuras();
|
UpdateAuras();
|
||||||
|
|
||||||
@@ -11404,6 +11401,7 @@ void Unit::RemoveFromWorld()
|
|||||||
if(IsInWorld())
|
if(IsInWorld())
|
||||||
{
|
{
|
||||||
UnsummonAllTotems();
|
UnsummonAllTotems();
|
||||||
|
RemoveGuardians();
|
||||||
RemoveCharmAuras();
|
RemoveCharmAuras();
|
||||||
RemoveBindSightAuras();
|
RemoveBindSightAuras();
|
||||||
RemoveNotOwnSingleTargetAuras();
|
RemoveNotOwnSingleTargetAuras();
|
||||||
@@ -11563,7 +11561,7 @@ void CharmInfo::InitCharmCreateSpells()
|
|||||||
|
|
||||||
InitPetActionBar();
|
InitPetActionBar();
|
||||||
|
|
||||||
for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x)
|
for(uint32 x = 0; x < 4; ++x)
|
||||||
{
|
{
|
||||||
uint32 spellId = ((Creature*)m_unit)->m_spells[x];
|
uint32 spellId = ((Creature*)m_unit)->m_spells[x];
|
||||||
m_charmspells[x].spellId = spellId;
|
m_charmspells[x].spellId = spellId;
|
||||||
@@ -13351,6 +13349,7 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
|
|||||||
|
|
||||||
if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet())
|
if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet())
|
||||||
{
|
{
|
||||||
|
//TODO: this will cause crash when a guardian is charmed
|
||||||
DeleteCharmInfo();
|
DeleteCharmInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13363,6 +13362,23 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Unit::RemoveGuardians()
|
||||||
|
{
|
||||||
|
while(!m_Guardians.empty())
|
||||||
|
{
|
||||||
|
uint64 guid = *m_Guardians.begin();
|
||||||
|
if(Unit* guardian = ObjectAccessor::GetUnit(*this, guid))
|
||||||
|
{
|
||||||
|
if(guardian->GetTypeId() == TYPEID_UNIT)
|
||||||
|
{
|
||||||
|
if(((Creature*)guardian)->isSummon())
|
||||||
|
((TempSummon*)guardian)->UnSummon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_Guardians.erase(guid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Unit::RestoreFaction()
|
void Unit::RestoreFaction()
|
||||||
{
|
{
|
||||||
if(GetTypeId() == TYPEID_PLAYER)
|
if(GetTypeId() == TYPEID_PLAYER)
|
||||||
|
|||||||
@@ -838,6 +838,8 @@ struct AuraSlotEntry
|
|||||||
|
|
||||||
struct SpellProcEventEntry; // used only privately
|
struct SpellProcEventEntry; // used only privately
|
||||||
|
|
||||||
|
typedef std::set<uint64> GuardianList;
|
||||||
|
|
||||||
class TRINITY_DLL_SPEC Unit : public WorldObject
|
class TRINITY_DLL_SPEC Unit : public WorldObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -1304,6 +1306,10 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
|||||||
uint32 m_detectInvisibilityMask;
|
uint32 m_detectInvisibilityMask;
|
||||||
uint32 m_invisibilityMask;
|
uint32 m_invisibilityMask;
|
||||||
|
|
||||||
|
GuardianList m_Guardians;
|
||||||
|
void RemoveGuardians();
|
||||||
|
void AddGuardian(Unit* pet) { m_Guardians.insert(pet->GetGUID()); }
|
||||||
|
|
||||||
uint32 m_ShapeShiftFormSpellId;
|
uint32 m_ShapeShiftFormSpellId;
|
||||||
ShapeshiftForm m_form;
|
ShapeshiftForm m_form;
|
||||||
bool IsInFeralForm() const { return m_form == FORM_CAT || m_form == FORM_BEAR || m_form == FORM_DIREBEAR; }
|
bool IsInFeralForm() const { return m_form == FORM_CAT || m_form == FORM_BEAR || m_form == FORM_DIREBEAR; }
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
Vehicle::Vehicle() : Creature(), m_vehicleId(0)
|
Vehicle::Vehicle() : Creature(), m_vehicleId(0)
|
||||||
{
|
{
|
||||||
m_isVehicle = true;
|
m_summonMask |= SUMMON_MASK_VEHICLE;
|
||||||
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE);
|
m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user