More work on pet spells, typo fix

This commit is contained in:
tomrus88 2008-11-05 21:47:56 +03:00
parent 7adf2001f3
commit d48844a699
9 changed files with 146 additions and 123 deletions

View file

@ -892,6 +892,8 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
uint32 type, timestamp, decompressedSize; uint32 type, timestamp, decompressedSize;
recv_data >> type >> timestamp >> decompressedSize; recv_data >> type >> timestamp >> decompressedSize;
sLog.outDebug("UAD: type %u, time %u, decompressedSize %u", type, timestamp, decompressedSize);
if(type > NUM_ACCOUNT_DATA_TYPES) if(type > NUM_ACCOUNT_DATA_TYPES)
return; return;
@ -943,6 +945,8 @@ void WorldSession::HandleRequestAccountData(WorldPacket& recv_data)
uint32 type; uint32 type;
recv_data >> type; recv_data >> type;
sLog.outDebug("RAD: type %u", type);
if(type > NUM_ACCOUNT_DATA_TYPES) if(type > NUM_ACCOUNT_DATA_TYPES)
return; return;

View file

@ -56,6 +56,8 @@ Pet::Pet(PetType type) : Creature()
m_auraUpdateMask = 0; m_auraUpdateMask = 0;
m_loading = false;
// 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(this); CharmInfo* charmInfo = InitCharmInfo(this);
@ -101,6 +103,8 @@ void Pet::RemoveFromWorld()
bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool current ) bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool current )
{ {
m_loading = true;
uint32 ownerid = owner->GetGUIDLow(); uint32 ownerid = owner->GetGUIDLow();
QueryResult *result; QueryResult *result;
@ -341,6 +345,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu
} }
} }
m_loading = false;
return true; return true;
} }
@ -1277,7 +1282,8 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
ToggleAutocast(itr->first, false); ToggleAutocast(itr->first, false);
oldspell_id = itr->first; oldspell_id = itr->first;
removeSpell(itr->first); //removeSpell(itr->first);
unlearnSpell(itr->first);
break; break;
} }
} }
@ -1299,16 +1305,6 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s
newspell->slotId = tmpslot; newspell->slotId = tmpslot;
m_spells[spell_id] = newspell; m_spells[spell_id] = newspell;
if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
{
if(!IsPassiveSpell(spell_id))
{
WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);
data << uint16(spell_id);
((Player*)GetOwner())->GetSession()->SendPacket(&data);
}
}
if (IsPassiveSpell(spell_id)) if (IsPassiveSpell(spell_id))
CastSpell(this, spell_id, true); CastSpell(this, spell_id, true);
else if(state == PETSPELL_NEW) else if(state == PETSPELL_NEW)
@ -1326,6 +1322,16 @@ bool Pet::learnSpell(uint16 spell_id)
if (!addSpell(spell_id)) if (!addSpell(spell_id))
return false; return false;
if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
{
if(!m_loading)
{
WorldPacket data(SMSG_PET_LEARNED_SPELL, 2);
data << uint16(spell_id);
((Player*)GetOwner())->GetSession()->SendPacket(&data);
}
}
Unit* owner = GetOwner(); Unit* owner = GetOwner();
if(owner->GetTypeId() == TYPEID_PLAYER) if(owner->GetTypeId() == TYPEID_PLAYER)
((Player*)owner)->PetSpellInitialize(); ((Player*)owner)->PetSpellInitialize();
@ -1343,18 +1349,36 @@ void Pet::learnLevelupSpells()
if(itr->ReqLevel <= getLevel()) if(itr->ReqLevel <= getLevel())
learnSpell(itr->SpellId); learnSpell(itr->SpellId);
else else
removeSpell(itr->SpellId); unlearnSpell(itr->SpellId);
} }
} }
void Pet::removeSpell(uint16 spell_id) bool Pet::unlearnSpell(uint16 spell_id)
{
if(removeSpell(spell_id))
{
if(GetOwner()->GetTypeId() == TYPEID_PLAYER)
{
if(!m_loading)
{
WorldPacket data(SMSG_PET_UNLEARNED_SPELL, 2);
data << uint16(spell_id);
((Player*)GetOwner())->GetSession()->SendPacket(&data);
}
}
return true;
}
return false;
}
bool Pet::removeSpell(uint16 spell_id)
{ {
PetSpellMap::iterator itr = m_spells.find(spell_id); PetSpellMap::iterator itr = m_spells.find(spell_id);
if (itr == m_spells.end()) if (itr == m_spells.end())
return; return false;
if(itr->second->state == PETSPELL_REMOVED) if(itr->second->state == PETSPELL_REMOVED)
return; return false;
if(itr->second->state == PETSPELL_NEW) if(itr->second->state == PETSPELL_NEW)
{ {
@ -1366,15 +1390,7 @@ void Pet::removeSpell(uint16 spell_id)
RemoveAurasDueToSpell(spell_id); RemoveAurasDueToSpell(spell_id);
if(GetOwner()->GetTypeId() == TYPEID_PLAYER) return true;
{
if(!IsPassiveSpell(spell_id))
{
WorldPacket data(SMSG_PET_UNLEARNED_SPELL, 2);
data << uint16(spell_id);
((Player*)GetOwner())->GetSession()->SendPacket(&data);
}
}
} }
bool Pet::_removeSpell(uint16 spell_id) bool Pet::_removeSpell(uint16 spell_id)

View file

@ -68,6 +68,7 @@ struct PetSpell
{ {
uint16 slotId; uint16 slotId;
uint16 active; uint16 active;
PetSpellState state : 16; PetSpellState state : 16;
PetSpellType type : 16; PetSpellType type : 16;
}; };
@ -191,7 +192,8 @@ class Pet : public Creature
bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, uint16 slot_id=0xffff, PetSpellType type = PETSPELL_NORMAL); bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, uint16 slot_id=0xffff, PetSpellType type = PETSPELL_NORMAL);
bool learnSpell(uint16 spell_id); bool learnSpell(uint16 spell_id);
void learnLevelupSpells(); void learnLevelupSpells();
void removeSpell(uint16 spell_id); bool unlearnSpell(uint16 spell_id);
bool removeSpell(uint16 spell_id);
bool _removeSpell(uint16 spell_id); bool _removeSpell(uint16 spell_id);
PetSpellMap m_spells; PetSpellMap m_spells;
@ -222,6 +224,7 @@ class Pet : public Creature
int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets) int32 m_duration; // time until unsummon (used mostly for summoned guardians and not used for controlled pets)
int32 m_bonusdamage; int32 m_bonusdamage;
uint64 m_auraUpdateMask; uint64 m_auraUpdateMask;
bool m_loading;
DeclinedName *m_declinedname; DeclinedName *m_declinedname;

View file

@ -155,7 +155,6 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )
} }
break; break;
case ACT_DISABLED: //0x8100 spell (disabled), ignore case ACT_DISABLED: //0x8100 spell (disabled), ignore
case ACT_CAST: //0x0100
case ACT_ENABLED: //0xc100 spell case ACT_ENABLED: //0xc100 spell
{ {
Unit* unit_target; Unit* unit_target;
@ -349,7 +348,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )
sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X\n", _player->GetName(), position, spell_id, act_state); sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X\n", _player->GetName(), position, spell_id, act_state);
//if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add
if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_CAST) && spell_id && !pet->HasSpell(spell_id))) if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED) && spell_id && !pet->HasSpell(spell_id)))
{ {
//sign for autocast //sign for autocast
if(act_state == ACT_ENABLED && spell_id) if(act_state == ACT_ENABLED && spell_id)
@ -519,7 +518,8 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)
{ {
uint32 spell_id = itr->first; // Pet::removeSpell can invalidate iterator at erase NEW spell uint32 spell_id = itr->first; // Pet::removeSpell can invalidate iterator at erase NEW spell
++itr; ++itr;
pet->removeSpell(spell_id); //pet->removeSpell(spell_id);
pet->unlearnSpell(spell_id);
} }
for(uint8 i = 0; i < 10; i++) for(uint8 i = 0; i < 10; i++)

View file

@ -2341,7 +2341,6 @@ void Player::SendInitialSpells()
continue; continue;
data << uint16(itr->first); data << uint16(itr->first);
//data << uint16(itr->second->slotId);
data << uint16(0); // it's not slot id data << uint16(0); // it's not slot id
spellCount +=1; spellCount +=1;
@ -2368,13 +2367,13 @@ void Player::SendInitialSpells()
data << uint16(sEntry->Category); // spell category data << uint16(sEntry->Category); // spell category
if(sEntry->Category) // may be wrong, but anyway better than nothing... if(sEntry->Category) // may be wrong, but anyway better than nothing...
{ {
data << uint32(0); data << uint32(0); // cooldown
data << uint32(cooldown); data << uint32(cooldown); // category cooldown
} }
else else
{ {
data << uint32(cooldown); data << uint32(cooldown); // cooldown
data << uint32(0); data << uint32(0); // category cooldown
} }
} }
@ -16002,44 +16001,34 @@ void Player::PetSpellInitialize()
{ {
Pet* pet = GetPet(); Pet* pet = GetPet();
if(pet) if(!pet)
{ return;
uint8 addlist = 0;
sLog.outDebug("Pet Spells Groups"); sLog.outDebug("Pet Spells Groups");
CreatureInfo const *cinfo = pet->GetCreatureInfo();
if(pet->isControlled() && (pet->getPetType() == HUNTER_PET || cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK))
{
for(PetSpellMap::iterator itr = pet->m_spells.begin();itr != pet->m_spells.end();itr++)
{
if(itr->second->state == PETSPELL_REMOVED)
continue;
++addlist;
}
}
// first line + actionbar + spellcount + spells + last adds
WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);
CharmInfo *charmInfo = pet->GetCharmInfo(); CharmInfo *charmInfo = pet->GetCharmInfo();
//16 WorldPacket data(SMSG_PET_SPELLS, 8+4+4+4+10*4);
data << uint64(pet->GetGUID()); data << uint64(pet->GetGUID());
data << uint32(pet->GetCreatureInfo()->family); // creature family (required for pet talents) data << uint32(pet->GetCreatureInfo()->family); // creature family (required for pet talents)
data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
data << uint32(0); data << uint32(0);
data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
for(uint32 i = 0; i < 10; i++) //40 // action bar loop
for(uint32 i = 0; i < 10; i++)
{ {
data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type); data << uint32(charmInfo->GetActionBarEntry(i)->Raw);
} }
data << uint8(addlist); //1 size_t spellsCountPos = data.wpos();
if(addlist && pet->isControlled()) // spells count
uint8 addlist = 0;
data << uint8(addlist); // placeholder
if(pet->isControlled() && ((pet->getPetType() == HUNTER_PET) || ((pet->GetCreatureInfo()->type == CREATURE_TYPE_DEMON) && (getClass() == CLASS_WARLOCK))))
{ {
// spells loop
for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr)
{ {
if(itr->second->state == PETSPELL_REMOVED) if(itr->second->state == PETSPELL_REMOVED)
@ -16047,24 +16036,33 @@ void Player::PetSpellInitialize()
data << uint16(itr->first); data << uint16(itr->first);
data << uint16(itr->second->active); // pet spell active state isn't boolean data << uint16(itr->second->active); // pet spell active state isn't boolean
++addlist;
} }
} }
//data << uint8(0x01) << uint32(0x6010) << uint32(0x01) << uint32(0x05) << uint16(0x00); //15 data.put<uint8>(spellsCountPos, addlist);
uint8 count = 3; //1+8+8+8=25
// if count = 0, then end of packet... uint8 cooldownsCount = pet->m_CreatureSpellCooldowns.size() + pet->m_CreatureCategoryCooldowns.size();
data << count; data << uint8(cooldownsCount);
// uint32 value is spell id...
// uint64 value is constant 0, unknown... for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr)
data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3 {
//data << uint32(0x5fd1) << uint64(0); // if count = 2 data << uint16(itr->first); // spellid
data << uint32(0x8e8c) << uint64(0); // if count = 3 data << uint16(0); // unk
data << uint32(0x8e8b) << uint64(0); // if count = 3 data << uint32(itr->second); // cooldown
data << uint32(0); // category cooldown
}
for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr)
{
data << uint16(itr->first); // spellid
data << uint16(0); // unk
data << uint32(0); // cooldown
data << uint32(itr->second); // category cooldown
}
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
} }
}
void Player::PossessSpellInitialize() void Player::PossessSpellInitialize()
{ {
@ -16087,8 +16085,8 @@ void Player::PossessSpellInitialize()
//16 //16
data << uint64(charm->GetGUID()); data << uint64(charm->GetGUID());
data << uint32(0x00000000); data << uint32(0x00000000);
data << uint8(0) << uint8(0) << uint16(0);
data << uint32(0); data << uint32(0);
data << uint8(0) << uint8(0) << uint16(0);
for(uint32 i = 0; i < 10; i++) //40 for(uint32 i = 0; i < 10; i++) //40
{ {
@ -16097,11 +16095,8 @@ void Player::PossessSpellInitialize()
data << uint8(addlist); //1 data << uint8(addlist); //1
uint8 count = 3; uint8 count = 0;
data << count; data << uint8(count); // cooldowns count
data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3
data << uint32(0x8e8c) << uint64(0); // if count = 3
data << uint32(0x8e8b) << uint64(0); // if count = 3
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
} }
@ -16138,15 +16133,14 @@ 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, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds
data << (uint64)charm->GetGUID() << uint32(0x00000000); data << uint64(charm->GetGUID());
data << uint32(0x00000000);
data << uint32(0);
if(charm->GetTypeId() != TYPEID_PLAYER) if(charm->GetTypeId() != TYPEID_PLAYER)
data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()); data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState());
else else
data << uint8(0) << uint8(0); data << uint8(0) << uint8(0);
data << uint16(0); data << uint16(0);
data << uint32(0);
for(uint32 i = 0; i < 10; i++) //40 for(uint32 i = 0; i < 10; i++) //40
{ {
@ -16168,11 +16162,8 @@ void Player::CharmSpellInitialize()
} }
} }
uint8 count = 3; uint8 count = 0;
data << count; data << uint8(count); // cooldowns count
data << uint32(0x6010) << uint64(0); // if count = 1, 2 or 3
data << uint32(0x8e8c) << uint64(0); // if count = 3
data << uint32(0x8e8b) << uint64(0); // if count = 3
GetSession()->SendPacket(&data); GetSession()->SendPacket(&data);
} }

View file

@ -65,7 +65,7 @@ Quest::Quest(Field * questRecord)
ReqItemId[i] = questRecord[39+i].GetUInt32(); ReqItemId[i] = questRecord[39+i].GetUInt32();
for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i)
ReqItemCount[i] = questRecord[42+i].GetUInt32(); ReqItemCount[i] = questRecord[43+i].GetUInt32();
for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i)
ReqSourceId[i] = questRecord[47+i].GetUInt32(); ReqSourceId[i] = questRecord[47+i].GetUInt32();

View file

@ -9897,7 +9897,7 @@ void CharmInfo::InitEmptyActionBar()
{ {
for(uint32 x = 1; x < 10; ++x) for(uint32 x = 1; x < 10; ++x)
{ {
PetActionBar[x].Type = ACT_CAST; PetActionBar[x].Type = ACT_ENABLED;
PetActionBar[x].SpellOrAction = 0; PetActionBar[x].SpellOrAction = 0;
} }
PetActionBar[0].Type = ACT_COMMAND; PetActionBar[0].Type = ACT_COMMAND;
@ -9916,7 +9916,7 @@ void CharmInfo::InitPossessCreateSpells()
if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x])) if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x]))
m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true); m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true);
else else
AddSpellToAB(0, ((Creature*)m_unit)->m_spells[x], ACT_CAST); AddSpellToAB(0, ((Creature*)m_unit)->m_spells[x], ACT_ENABLED);
} }
} }
@ -9959,7 +9959,7 @@ void CharmInfo::InitCharmCreateSpells()
if(onlyselfcast || !IsPositiveSpell(spellId)) //only self cast and spells versus enemies are autocastable if(onlyselfcast || !IsPositiveSpell(spellId)) //only self cast and spells versus enemies are autocastable
newstate = ACT_DISABLED; newstate = ACT_DISABLED;
else else
newstate = ACT_CAST; newstate = ACT_ENABLED;
AddSpellToAB(0, spellId, newstate); AddSpellToAB(0, spellId, newstate);
} }
@ -9970,7 +9970,7 @@ bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)
{ {
for(uint8 i = 0; i < 10; i++) for(uint8 i = 0; i < 10; i++)
{ {
if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_CAST) && PetActionBar[i].SpellOrAction == oldid) if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED) && PetActionBar[i].SpellOrAction == oldid)
{ {
PetActionBar[i].SpellOrAction = newid; PetActionBar[i].SpellOrAction = newid;
if(!oldid) if(!oldid)

View file

@ -593,8 +593,18 @@ struct CleanDamage
struct UnitActionBarEntry struct UnitActionBarEntry
{ {
uint32 Type; union
uint32 SpellOrAction; {
struct
{
uint16 Type;
uint16 SpellOrAction;
};
struct
{
uint32 Raw;
};
};
}; };
#define MAX_DECLINED_NAME_CASES 5 #define MAX_DECLINED_NAME_CASES 5
@ -616,13 +626,12 @@ enum CurrentSpellTypes
enum ActiveStates enum ActiveStates
{ {
ACT_ENABLED = 0xC100, ACT_PASSIVE = 0x0100, // 0x0100 - passive
ACT_DISABLED = 0x8100, ACT_DISABLED = 0x8100, // 0x8000 - castable
ACT_COMMAND = 0x0700, ACT_ENABLED = 0xC100, // 0x4000 | 0x8000 - auto cast + castable
ACT_REACTION = 0x0600, ACT_COMMAND = 0x0700, // 0x0100 | 0x0200 | 0x0400
ACT_CAST = 0x0100, ACT_REACTION = 0x0600, // 0x0200 | 0x0400
ACT_PASSIVE = 0x0000, ACT_DECIDE = 0x0001 // what is it?
ACT_DECIDE = 0x0001
}; };
enum ReactStates enum ReactStates

View file

@ -19,7 +19,7 @@
#ifndef _UPDATEFIELDS_AUTO_H #ifndef _UPDATEFIELDS_AUTO_H
#define _UPDATEFIELDS_AUTO_H #define _UPDATEFIELDS_AUTO_H
// Auto generated for version 3, 0, 3, 9155 // Auto generated for version 3, 0, 3, 9183
enum EObjectFields enum EObjectFields
{ {