--HG--
branch : trunk
This commit is contained in:
megamage
2009-02-20 12:05:58 -06:00
8 changed files with 111 additions and 67 deletions
+40 -1
View File
@@ -1606,7 +1606,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();
@@ -1646,6 +1645,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, GetPhaseMask(), 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
View File
@@ -53,7 +53,7 @@ m_declinedname(NULL)
// 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
View File
@@ -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];
+14
View File
@@ -16870,6 +16870,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);
@@ -16955,11 +16959,21 @@ 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
{
*data << (uint8)msgtype;
+1
View File
@@ -1033,6 +1033,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();
+10 -4
View File
@@ -2109,21 +2109,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)
{
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);
}
+27 -50
View File
@@ -3732,9 +3732,16 @@ void Spell::EffectSummonGuardian(uint32 i)
return;
}
// trigger
if(!m_originalCaster || m_originalCaster->GetTypeId() != TYPEID_PLAYER
&& !((Creature*)m_originalCaster)->isTotem()/*m_spellInfo->Id == 40276*/)
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;
@@ -3746,20 +3753,20 @@ void Spell::EffectSummonGuardian(uint32 i)
// 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_originalCaster->GetTypeId() == TYPEID_PLAYER && (duration <= 0 || GetSpellRecoveryTime(m_spellInfo)==0) )
if(((Player*)m_originalCaster)->HasGuardianWithEntry(pet_entry))
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 = m_originalCaster->getLevel();
uint32 level = caster->getLevel();
// level of pet summoned using engineering item based at engineering skill level
if(m_originalCaster->GetTypeId()==TYPEID_PLAYER && m_CastItem)
if(m_CastItem)
{
ItemPrototype const *proto = m_CastItem->GetProto();
if(proto && proto->RequiredSkill == SKILL_ENGINERING)
{
uint16 skill202 = ((Player*)m_originalCaster)->GetSkillValue(SKILL_ENGINERING);
uint16 skill202 = caster->GetSkillValue(SKILL_ENGINERING);
if(skill202)
{
level = skill202/5;
@@ -3778,18 +3785,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_caster->GetPhaseMask(),
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
@@ -3808,47 +3803,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 = caster->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)
@@ -3856,15 +3831,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)
+8 -2
View File
@@ -7648,7 +7648,8 @@ void Unit::SetCharm(Unit* pet)
void Unit::AddPlayerToVision(Player* plr)
{
if (m_sharedVision.empty() && GetTypeId() == TYPEID_UNIT)
if (m_sharedVision.empty() && GetTypeId() == TYPEID_UNIT
&& !((Creature*)this)->isPet() && !((Creature*)this)->isVehicle())
{
setActive(true);
GetMap()->SwitchGridContainers((Creature*)this, true);
@@ -7660,7 +7661,8 @@ void Unit::AddPlayerToVision(Player* plr)
void Unit::RemovePlayerFromVision(Player* plr)
{
m_sharedVision.remove(plr);
if (m_sharedVision.empty() && GetTypeId() == TYPEID_UNIT)
if (m_sharedVision.empty() && GetTypeId() == TYPEID_UNIT
&& !((Creature*)this)->isPet() && !((Creature*)this)->isVehicle())
{
setActive(false);
GetMap()->SwitchGridContainers((Creature*)this, false);
@@ -12383,6 +12385,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());