*Fix a crash caused by summon_type_possess.
--HG-- branch : trunk
This commit is contained in:
+40
-1
@@ -1572,7 +1572,6 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
|
||||
{
|
||||
TemporarySummon* pCreature = new TemporarySummon(GetGUID());
|
||||
|
||||
//pCreature->SetInstanceId(GetInstanceId());
|
||||
uint32 team = 0;
|
||||
if (GetTypeId()==TYPEID_PLAYER)
|
||||
team = ((Player*)this)->GetTeam();
|
||||
@@ -1612,6 +1611,46 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
|
||||
return pCreature;
|
||||
}
|
||||
|
||||
Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration)
|
||||
{
|
||||
Pet* pCreature = new Pet(petType);
|
||||
|
||||
Map *map = GetMap();
|
||||
uint32 pet_number = objmgr.GeneratePetNumber();
|
||||
if(!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, entry, pet_number))
|
||||
{
|
||||
sLog.outError("no such creature entry %u", entry);
|
||||
delete pCreature;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pCreature->Relocate(x, y, z, ang);
|
||||
|
||||
if(!pCreature->IsPositionValid())
|
||||
{
|
||||
sLog.outError("ERROR: Pet (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;
|
||||
}
|
||||
|
||||
if(duration > 0)
|
||||
pCreature->SetDuration(duration);
|
||||
|
||||
pCreature->SetOwnerGUID(GetGUID());
|
||||
pCreature->SetCreatorGUID(GetGUID());
|
||||
pCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());
|
||||
|
||||
pCreature->GetCharmInfo()->SetPetNumber(pet_number, false);
|
||||
|
||||
pCreature->AIM_Initialize();
|
||||
|
||||
map->Add((Creature*)pCreature);
|
||||
|
||||
AddGuardian(pCreature);
|
||||
|
||||
return pCreature;
|
||||
}
|
||||
|
||||
GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime)
|
||||
{
|
||||
if(!IsInWorld())
|
||||
|
||||
+1
-1
@@ -85,7 +85,7 @@ Pet::Pet(PetType type) : Creature()
|
||||
// pets always have a charminfo, even if they are not actually charmed
|
||||
CharmInfo* charmInfo = InitCharmInfo(this);
|
||||
|
||||
if(type == MINI_PET) // always passive
|
||||
if(type == MINI_PET || type == POSSESSED_PET) // always passive
|
||||
charmInfo->SetReactState(REACT_PASSIVE);
|
||||
else if(type == GUARDIAN_PET) // always aggressive
|
||||
charmInfo->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
+2
-1
@@ -31,7 +31,8 @@ enum PetType
|
||||
HUNTER_PET = 1,
|
||||
GUARDIAN_PET = 2,
|
||||
MINI_PET = 3,
|
||||
MAX_PET_TYPE = 4
|
||||
POSSESSED_PET = 4,
|
||||
MAX_PET_TYPE = 5
|
||||
};
|
||||
|
||||
extern char const* petTypeSuffix[MAX_PET_TYPE];
|
||||
|
||||
@@ -16163,6 +16163,10 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
|
||||
case GUARDIAN_PET:
|
||||
m_guardianPets.erase(pet->GetGUID());
|
||||
break;
|
||||
case POSSESSED_PET:
|
||||
m_guardianPets.erase(pet->GetGUID());
|
||||
pet->RemoveCharmedOrPossessedBy(NULL);
|
||||
break;
|
||||
default:
|
||||
if(GetPetGUID() == pet->GetGUID())
|
||||
SetPet(NULL);
|
||||
@@ -16247,9 +16251,19 @@ void Player::Uncharm()
|
||||
if(!charm)
|
||||
return;
|
||||
|
||||
if(charm->GetTypeId() == TYPEID_UNIT && ((Creature*)charm)->isPet()
|
||||
&& ((Pet*)charm)->getPetType() == POSSESSED_PET)
|
||||
{
|
||||
((Pet*)charm)->Remove(PET_SAVE_AS_DELETED);
|
||||
}
|
||||
else
|
||||
{
|
||||
charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_CHARM);
|
||||
charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS_PET);
|
||||
charm->RemoveSpellsCausingAura(SPELL_AURA_MOD_POSSESS);
|
||||
}
|
||||
|
||||
assert(!GetCharmGUID());
|
||||
}
|
||||
|
||||
void Player::BuildPlayerChat(WorldPacket *data, uint8 msgtype, const std::string& text, uint32 language) const
|
||||
|
||||
@@ -1006,6 +1006,7 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
int GetTimeInnEnter() const { return time_inn_enter; };
|
||||
void UpdateInnerTime (int time) { time_inn_enter = time; };
|
||||
|
||||
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 RemoveMiniPet();
|
||||
Pet* GetMiniPet();
|
||||
|
||||
+11
-5
@@ -2146,21 +2146,27 @@ void Spell::cancel()
|
||||
} break;
|
||||
}
|
||||
|
||||
finish(false);
|
||||
|
||||
// Unsummon summon as possessed creatures on spell cancel
|
||||
for (int i = 0; i < 3; i++)
|
||||
if(m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (m_spellInfo->Effect[i] == SPELL_EFFECT_SUMMON &&
|
||||
for(int i = 0; i < 3; ++i)
|
||||
{
|
||||
if(m_spellInfo->Effect[i] == SPELL_EFFECT_SUMMON &&
|
||||
(m_spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED ||
|
||||
m_spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED2 ||
|
||||
m_spellInfo->EffectMiscValueB[i] == SUMMON_TYPE_POSESSED3))
|
||||
{
|
||||
((Player*)m_caster)->StopCastingCharm();
|
||||
break;
|
||||
// Possession is removed in the UnSummon function
|
||||
if (m_caster->GetCharm())
|
||||
((TemporarySummon*)m_caster->GetCharm())->UnSummon();
|
||||
//if (m_caster->GetCharm())
|
||||
// ((TemporarySummon*)m_caster->GetCharm())->UnSummon();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finish(false);
|
||||
m_caster->RemoveDynObject(m_spellInfo->Id);
|
||||
m_caster->RemoveGameObject(m_spellInfo->Id,true);
|
||||
}
|
||||
|
||||
+12
-42
@@ -3683,18 +3683,6 @@ void Spell::EffectSummonGuardian(uint32 i)
|
||||
|
||||
for(int32 count = 0; count < amount; ++count)
|
||||
{
|
||||
Pet* spawnCreature = new Pet(GUARDIAN_PET);
|
||||
spawnCreature->setActive(m_caster->isActive());
|
||||
|
||||
Map *map = m_caster->GetMap();
|
||||
uint32 pet_number = objmgr.GeneratePetNumber();
|
||||
if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map,m_spellInfo->EffectMiscValue[i], pet_number))
|
||||
{
|
||||
sLog.outError("no such creature entry %u",m_spellInfo->EffectMiscValue[i]);
|
||||
delete spawnCreature;
|
||||
return;
|
||||
}
|
||||
|
||||
float px, py, pz;
|
||||
// If dest location if present
|
||||
if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION)
|
||||
@@ -3712,47 +3700,27 @@ void Spell::EffectSummonGuardian(uint32 i)
|
||||
}
|
||||
// Summon if dest location not present near caster
|
||||
else
|
||||
m_caster->GetClosePoint(px,py,pz,spawnCreature->GetObjectSize());
|
||||
m_caster->GetClosePoint(px,py,pz,m_caster->GetObjectSize());
|
||||
|
||||
spawnCreature->Relocate(px,py,pz,m_caster->GetOrientation());
|
||||
|
||||
if(!spawnCreature->IsPositionValid())
|
||||
{
|
||||
sLog.outError("ERROR: Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %f Y: %f)",
|
||||
spawnCreature->GetGUIDLow(), spawnCreature->GetEntry(), spawnCreature->GetPositionX(), spawnCreature->GetPositionY());
|
||||
delete spawnCreature;
|
||||
Pet *spawnCreature = ((Player*)m_originalCaster)->SummonPet(m_spellInfo->EffectMiscValue[i], px, py, pz, m_caster->GetOrientation(), GUARDIAN_PET, duration);
|
||||
if(!spawnCreature)
|
||||
return;
|
||||
}
|
||||
|
||||
if(duration > 0)
|
||||
spawnCreature->SetDuration(duration);
|
||||
|
||||
spawnCreature->SetOwnerGUID(m_originalCaster->GetGUID());
|
||||
spawnCreature->setPowerType(POWER_MANA);
|
||||
spawnCreature->SetUInt32Value(UNIT_NPC_FLAGS , 0);
|
||||
spawnCreature->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,m_originalCaster->getFaction());
|
||||
spawnCreature->SetUInt32Value(UNIT_FIELD_FLAGS,0);
|
||||
spawnCreature->SetUInt32Value(UNIT_FIELD_BYTES_1,0);
|
||||
spawnCreature->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP,0);
|
||||
spawnCreature->SetCreatorGUID(m_originalCaster->GetGUID());
|
||||
spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||
|
||||
spawnCreature->InitStatsForLevel(level);
|
||||
spawnCreature->GetCharmInfo()->SetPetNumber(pet_number, false);
|
||||
|
||||
spawnCreature->AIM_Initialize();
|
||||
|
||||
if(m_originalCaster->GetTypeId()==TYPEID_PLAYER)
|
||||
((Player*)m_originalCaster)->AddGuardian(spawnCreature);
|
||||
|
||||
map->Add((Creature*)spawnCreature);
|
||||
}
|
||||
}
|
||||
|
||||
void Spell::EffectSummonPossessed(uint32 i)
|
||||
{
|
||||
uint32 creatureEntry = m_spellInfo->EffectMiscValue[i];
|
||||
if(!creatureEntry)
|
||||
uint32 entry = m_spellInfo->EffectMiscValue[i];
|
||||
if(!entry)
|
||||
return;
|
||||
|
||||
if(m_caster->GetTypeId() != TYPEID_PLAYER)
|
||||
@@ -3760,15 +3728,17 @@ void Spell::EffectSummonPossessed(uint32 i)
|
||||
|
||||
uint32 level = m_caster->getLevel();
|
||||
|
||||
float px, py, pz;
|
||||
m_caster->GetClosePoint(px, py, pz, DEFAULT_WORLD_OBJECT_SIZE);
|
||||
float x, y, z;
|
||||
m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
|
||||
|
||||
int32 duration = GetSpellDuration(m_spellInfo);
|
||||
|
||||
TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN;
|
||||
Pet* pet = ((Player*)m_caster)->SummonPet(entry, x, y, z, m_caster->GetOrientation(), POSSESSED_PET, duration);
|
||||
if(!pet)
|
||||
return;
|
||||
|
||||
Creature* c = m_caster->SummonCreature(creatureEntry, px, py, pz, m_caster->GetOrientation(), summonType, duration);
|
||||
if(c) c->SetCharmedOrPossessedBy(m_caster, true);
|
||||
pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
|
||||
pet->SetCharmedOrPossessedBy(m_caster, true);
|
||||
}
|
||||
|
||||
void Spell::EffectTeleUnitsFaceCaster(uint32 i)
|
||||
|
||||
@@ -12971,6 +12971,10 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
|
||||
if(GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)this)->StopCastingCharm();
|
||||
|
||||
// StopCastingCharm may remove a possessed pet?
|
||||
if(!IsInWorld())
|
||||
return;
|
||||
|
||||
// Set charmed
|
||||
charmer->SetCharm(this);
|
||||
SetCharmerGUID(charmer->GetGUID());
|
||||
|
||||
Reference in New Issue
Block a user