*Fix CAST_INTURRUPT_PREVIOUS flag for eventai action cast
*Rewrite .reload all pet_spells command to make it reset actionbars correctly. --HG-- branch : trunk
This commit is contained in:
@@ -625,7 +625,7 @@ void CreatureEventAI::ProcessAction(uint16 type, uint32 param1, uint32 param2, u
|
||||
}
|
||||
|
||||
//Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered
|
||||
bool canCast = !(caster->IsNonMeleeSpellCasted(false) && (param3 & CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS));
|
||||
bool canCast = !(caster->IsNonMeleeSpellCasted(false) && !(param3 & CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS));
|
||||
|
||||
// If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them
|
||||
if(param3 & CAST_AURA_NOT_PRESENT)
|
||||
|
||||
+6
-1
@@ -5392,8 +5392,13 @@ bool ChatHandler::HandleResetAllCommand(const char * args)
|
||||
}
|
||||
else if(casename=="pet_spells")
|
||||
{
|
||||
atLogin = AT_LOGIN_RESET_PET_SPELLS;
|
||||
CharacterDatabase.PExecute("UPDATE character_pet SET load_flags = load_flags | '%u' WHERE (load_flags & '%u') = '0'",uint32(AT_LOAD_RESET_SPELLS),uint32(AT_LOAD_RESET_SPELLS));
|
||||
HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers();
|
||||
for(HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
|
||||
if (itr->second->GetPet())
|
||||
itr->second->SetPetAtLoginFlag(AT_LOAD_RESET_SPELLS);
|
||||
sWorld.SendWorldText(LANG_RESETALL_PET_SPELLS);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+70
-51
@@ -50,6 +50,8 @@ m_declinedname(NULL), m_owner(owner)
|
||||
m_name = "Pet";
|
||||
m_regenTimer = 4000;
|
||||
|
||||
owner->SetPetAtLoginFlag(0);
|
||||
|
||||
if(type == POSSESSED_PET) // always passive
|
||||
SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
@@ -100,25 +102,25 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||
QueryResult *result;
|
||||
|
||||
if (petnumber)
|
||||
// known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
||||
// known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType , load_flags "
|
||||
"FROM character_pet WHERE owner = '%u' AND id = '%u'",
|
||||
ownerid, petnumber);
|
||||
else if (current)
|
||||
// current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
||||
// current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType , load_flags "
|
||||
"FROM character_pet WHERE owner = '%u' AND slot = '%u'",
|
||||
ownerid, PET_SAVE_AS_CURRENT );
|
||||
else if (petentry)
|
||||
// known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets)
|
||||
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
||||
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType , load_flags "
|
||||
"FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '%u' OR slot > '%u') ",
|
||||
ownerid, petentry,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
||||
else
|
||||
// any current or other non-stabled pet (for hunter "call pet")
|
||||
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType "
|
||||
// 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
||||
result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType , load_flags "
|
||||
"FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u') ",
|
||||
ownerid,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
||||
|
||||
@@ -264,56 +266,71 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
|
||||
|
||||
m_resetTalentsCost = fields[17].GetUInt32();
|
||||
m_resetTalentsTime = fields[18].GetUInt64();
|
||||
learnLevelupSpells();
|
||||
LearnPetPassives();
|
||||
_LoadSpells();
|
||||
_LoadSpellCooldowns();
|
||||
|
||||
if (!is_temporary_summoned)
|
||||
uint8 loadFlags = fields[21].GetUInt8();
|
||||
if (loadFlags & AT_LOAD_RESET_SPELLS)
|
||||
{
|
||||
// permanent controlled pets store state in DB
|
||||
Tokens tokens = StrSplit(fields[14].GetString(), " ");
|
||||
CharacterDatabase.PExecute("UPDATE character_pet SET load_flags = load_flags & ~ %u WHERE guid = '%d'",uint32(AT_LOAD_RESET_SPELLS),pet_number);
|
||||
loadFlags &= ~uint8(AT_LOAD_RESET_SPELLS);
|
||||
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%d'",pet_number);
|
||||
InitPetCreateSpells();
|
||||
resetTalents(true);
|
||||
learnLevelupSpells();
|
||||
}
|
||||
else
|
||||
{
|
||||
learnLevelupSpells();
|
||||
LearnPetPassives();
|
||||
_LoadSpells();
|
||||
_LoadSpellCooldowns();
|
||||
|
||||
if (tokens.size() != 20)
|
||||
// Load action bar data
|
||||
if (!is_temporary_summoned)
|
||||
{
|
||||
delete result;
|
||||
return false;
|
||||
}
|
||||
// permanent controlled pets store state in DB
|
||||
Tokens tokens = StrSplit(fields[14].GetString(), " ");
|
||||
|
||||
int index;
|
||||
Tokens::iterator iter;
|
||||
for(iter = tokens.begin(), index = 0; index < 10; ++iter, ++index )
|
||||
{
|
||||
m_charmInfo->GetActionBarEntry(index)->Type = atol((*iter).c_str());
|
||||
++iter;
|
||||
m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str());
|
||||
|
||||
// patch for old data where some spells have ACT_DECIDE but should have ACT_CAST
|
||||
// so overwrite old state
|
||||
if(SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction))
|
||||
if (tokens.size() != 20)
|
||||
{
|
||||
if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET)
|
||||
m_charmInfo->GetActionBarEntry(index)->Type = ACT_DISABLED;
|
||||
delete result;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(m_charmInfo->GetActionBarEntry(index)->Type == ACT_ENABLED)
|
||||
ToggleAutocast(spellInfo->Id, true);
|
||||
int index;
|
||||
Tokens::iterator iter;
|
||||
for(iter = tokens.begin(), index = 0; index < 10; ++iter, ++index )
|
||||
{
|
||||
m_charmInfo->GetActionBarEntry(index)->Type = atol((*iter).c_str());
|
||||
++iter;
|
||||
m_charmInfo->GetActionBarEntry(index)->SpellOrAction = atol((*iter).c_str());
|
||||
|
||||
// patch for old data where some spells have ACT_DECIDE but should have ACT_CAST
|
||||
// so overwrite old state
|
||||
if(SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction))
|
||||
{
|
||||
if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET)
|
||||
m_charmInfo->GetActionBarEntry(index)->Type = ACT_DISABLED;
|
||||
|
||||
if(m_charmInfo->GetActionBarEntry(index)->Type == ACT_ENABLED)
|
||||
ToggleAutocast(spellInfo->Id, true);
|
||||
}
|
||||
}
|
||||
|
||||
//init teach spells
|
||||
tokens = StrSplit(fields[15].GetString(), " ");
|
||||
for (iter = tokens.begin(), index = 0; index < 4; ++iter, ++index)
|
||||
{
|
||||
uint32 tmp = atol((*iter).c_str());
|
||||
|
||||
++iter;
|
||||
|
||||
if(tmp)
|
||||
AddTeachSpell(tmp, atol((*iter).c_str()));
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//init teach spells
|
||||
tokens = StrSplit(fields[15].GetString(), " ");
|
||||
for (iter = tokens.begin(), index = 0; index < 4; ++iter, ++index)
|
||||
{
|
||||
uint32 tmp = atol((*iter).c_str());
|
||||
|
||||
++iter;
|
||||
|
||||
if(tmp)
|
||||
AddTeachSpell(tmp, atol((*iter).c_str()));
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
owner->SetPetAtLoginFlag(loadFlags);
|
||||
|
||||
//load spells/cooldowns/auras
|
||||
// Spells should be loaded after pet is added to map, because in CheckCast is check on it
|
||||
@@ -415,7 +432,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||
owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
|
||||
// save pet
|
||||
std::ostringstream ss;
|
||||
ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) "
|
||||
ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags) "
|
||||
<< "VALUES ("
|
||||
<< m_charmInfo->GetPetNumber() << ", "
|
||||
<< GetEntry() << ", "
|
||||
@@ -450,7 +467,8 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||
<< uint32(m_resetTalentsCost) << ", "
|
||||
<< uint64(m_resetTalentsTime) << ", "
|
||||
<< GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", "
|
||||
<< uint32(getPetType()) << ")";
|
||||
<< uint32(getPetType()) << ", "
|
||||
<< (pOwner->GetAtLoginFlag()>>AT_LOAD_PET_FLAGS) << ")";
|
||||
|
||||
CharacterDatabase.Execute( ss.str().c_str() );
|
||||
CharacterDatabase.CommitTransaction();
|
||||
@@ -461,6 +479,7 @@ void Pet::SavePetToDB(PetSaveMode mode)
|
||||
RemoveAllAuras();
|
||||
DeleteFromDB(m_charmInfo->GetPetNumber());
|
||||
}
|
||||
pOwner->SetPetAtLoginFlag(0);
|
||||
}
|
||||
|
||||
void Pet::DeleteFromDB(uint32 guidlow)
|
||||
|
||||
@@ -90,6 +90,12 @@ enum PetTalk
|
||||
PET_TALK_ATTACK = 1
|
||||
};
|
||||
|
||||
enum AtLoadFlags
|
||||
{
|
||||
AT_LOAD_NONE = 0,
|
||||
AT_LOAD_RESET_SPELLS = 1,
|
||||
};
|
||||
|
||||
enum PetNameInvalidReason
|
||||
{
|
||||
PET_NAME_INVALID = 1,
|
||||
|
||||
+1
-45
@@ -14524,12 +14524,6 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
|
||||
InitTalentForLevel();
|
||||
learnDefaultSpells();
|
||||
|
||||
// must be done after aura loading for correct pet talent amount calculation
|
||||
if(HasAtLoginFlag(AT_LOGIN_RESET_PET_SPELLS))
|
||||
{
|
||||
_resetAllPetSpells();
|
||||
}
|
||||
|
||||
_LoadTutorials(holder->GetResult(PLAYER_LOGIN_QUERY_LOADTUTORIALS));
|
||||
|
||||
// must be before inventory (some items required reputation check)
|
||||
@@ -15775,7 +15769,7 @@ void Player::SaveToDB()
|
||||
ss << uint32(m_stableSlots); // to prevent save uint8 as char
|
||||
|
||||
ss << ", ";
|
||||
ss << uint32(m_atLoginFlags);
|
||||
ss << uint32(m_atLoginFlags & ((1<<AT_LOAD_PET_FLAGS) -1));
|
||||
|
||||
ss << ", ";
|
||||
ss << GetZoneId();
|
||||
@@ -18591,44 +18585,6 @@ void Player::resetSpells()
|
||||
learnQuestRewardedSpells();
|
||||
}
|
||||
|
||||
void Player::_resetAllPetSpells()
|
||||
{
|
||||
if(HasAtLoginFlag(AT_LOGIN_RESET_PET_SPELLS))
|
||||
{
|
||||
m_atLoginFlags = m_atLoginFlags & ~AT_LOGIN_RESET_PET_SPELLS;
|
||||
CharacterDatabase.PExecute("UPDATE characters set at_login = at_login & ~ %u WHERE guid ='%u'", uint32(AT_LOGIN_RESET_PET_SPELLS), GetGUIDLow());
|
||||
}
|
||||
|
||||
if (QueryResult * result = CharacterDatabase.PQuery("SELECT id, level, entry FROM character_pet WHERE owner = '%u'", GetGUIDLow()))
|
||||
{
|
||||
// Mod points from owner SPELL_AURA_MOD_PET_TALENT_POINTS
|
||||
uint32 pointMod = GetTotalAuraModifier(SPELL_AURA_MOD_PET_TALENT_POINTS);
|
||||
do
|
||||
{
|
||||
Field *fields = result->Fetch();
|
||||
uint32 petId = fields[0].GetUInt32();
|
||||
uint32 level = fields[1].GetUInt32();
|
||||
uint32 entry = fields[2].GetUInt32();
|
||||
CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry);
|
||||
if (!ci)
|
||||
sLog.outError("Unknown pet (id %d) type saved in character_pet!", petId);
|
||||
CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family);
|
||||
if (!pet_family)
|
||||
sLog.outError("Unknown pet (id %d) type saved in character_pet!", petId);
|
||||
if(pet_family && pet_family->petTalentType >= 0)
|
||||
{
|
||||
uint32 points = (level >= 20) ? ((level - 16) / 4) : 0;
|
||||
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u'", petId);
|
||||
std::ostringstream ss;
|
||||
ss << "UPDATE character_pet SET talentpoints = '"<<points + pointMod<<"' WHERE id = '"<<petId<<"'";
|
||||
sLog.outDebug(ss.str().c_str());
|
||||
CharacterDatabase.Execute(ss.str().c_str());
|
||||
}
|
||||
}
|
||||
while( result->NextRow() );
|
||||
}
|
||||
}
|
||||
|
||||
void Player::learnDefaultSpells()
|
||||
{
|
||||
// learn default race/class spells
|
||||
|
||||
+3
-2
@@ -57,6 +57,7 @@ typedef std::deque<Mail*> PlayerMails;
|
||||
|
||||
#define PLAYER_MAX_SKILLS 127
|
||||
#define PLAYER_MAX_DAILY_QUESTS 25
|
||||
#define AT_LOAD_PET_FLAGS 16
|
||||
|
||||
// Note: SPELLMOD_* values is aura types in fact
|
||||
enum SpellModType
|
||||
@@ -498,7 +499,6 @@ enum AtLoginFlags
|
||||
AT_LOGIN_RESET_SPELLS = 2,
|
||||
AT_LOGIN_RESET_TALENTS = 4,
|
||||
AT_LOGIN_CUSTOMIZE = 8,
|
||||
AT_LOGIN_RESET_PET_SPELLS = 16
|
||||
};
|
||||
|
||||
typedef std::map<uint32, QuestStatusData> QuestStatusMap;
|
||||
@@ -1343,7 +1343,6 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
void learnSpell(uint32 spell_id, bool dependent);
|
||||
void removeSpell(uint32 spell_id, bool disabled = false, bool update_action_bar_for_low_rank = false);
|
||||
void resetSpells();
|
||||
void _resetAllPetSpells();
|
||||
void learnDefaultSpells();
|
||||
void learnQuestRewardedSpells();
|
||||
void learnQuestRewardedSpells(Quest const* quest);
|
||||
@@ -1953,6 +1952,8 @@ class TRINITY_DLL_SPEC Player : public Unit
|
||||
|
||||
bool HasAtLoginFlag(AtLoginFlags f) const { return m_atLoginFlags & f; }
|
||||
void SetAtLoginFlag(AtLoginFlags f) { m_atLoginFlags |= f; }
|
||||
uint32 GetAtLoginFlag() { return m_atLoginFlags; }
|
||||
void SetPetAtLoginFlag(uint8 f) { m_atLoginFlags |= uint32(f<<AT_LOAD_PET_FLAGS); }
|
||||
|
||||
LookingForGroup m_lookingForGroup;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user