diff options
author | QAston <none@none> | 2009-04-26 02:48:20 +0200 |
---|---|---|
committer | QAston <none@none> | 2009-04-26 02:48:20 +0200 |
commit | 2d1521dea9d75d47b8f1de52cebe529d14506cfd (patch) | |
tree | b01e48f5e2efdd9b2b2a0d1fd4bcf37a60b46dfa | |
parent | 6909b20f2cc05d4584861f89460083f1334c6be1 (diff) |
*Fix CAST_INTURRUPT_PREVIOUS flag for eventai action cast
*Rewrite .reload all pet_spells command to make it reset actionbars correctly.
--HG--
branch : trunk
-rw-r--r-- | sql/updates/2928_characters_character_pet.sql | 2 | ||||
-rw-r--r-- | src/game/CreatureEventAI.cpp | 2 | ||||
-rw-r--r-- | src/game/Level3.cpp | 7 | ||||
-rw-r--r-- | src/game/Pet.cpp | 113 | ||||
-rw-r--r-- | src/game/Pet.h | 6 | ||||
-rw-r--r-- | src/game/Player.cpp | 46 | ||||
-rw-r--r-- | src/game/Player.h | 5 |
7 files changed, 85 insertions, 96 deletions
diff --git a/sql/updates/2928_characters_character_pet.sql b/sql/updates/2928_characters_character_pet.sql new file mode 100644 index 00000000000..95a34404413 --- /dev/null +++ b/sql/updates/2928_characters_character_pet.sql @@ -0,0 +1,2 @@ +ALTER TABLE character_pet ADD load_flags INT(3) DEFAULT '0' NOT NULL AFTER teachspelldata; +UPDATE characters SET at_login = at_login & ~16 WHERE at_login & 16; diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp index c50243b0fb3..704dad6ad34 100644 --- a/src/game/CreatureEventAI.cpp +++ b/src/game/CreatureEventAI.cpp @@ -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) diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 4b7fce652f5..ae1b0933bbf 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -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 { diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 9c8835b8ded..ccd2e02be87 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -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) + { + 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 { - // permanent controlled pets store state in DB - Tokens tokens = StrSplit(fields[14].GetString(), " "); + 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()); + if (tokens.size() != 20) + { + delete result; + return false; + } - // 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)) + int index; + Tokens::iterator iter; + for(iter = tokens.begin(), index = 0; index < 10; ++iter, ++index ) { - if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) - m_charmInfo->GetActionBarEntry(index)->Type = ACT_DISABLED; + 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); + 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()); + //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; + ++iter; - if(tmp) - AddTeachSpell(tmp, atol((*iter).c_str())); - else - break; + 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) diff --git a/src/game/Pet.h b/src/game/Pet.h index aaa4c786d10..9d7a42e57a0 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -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, diff --git a/src/game/Player.cpp b/src/game/Player.cpp index a400909a43e..d1bbaebd0d6 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -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 diff --git a/src/game/Player.h b/src/game/Player.h index e5c3a80fc71..73e714fe41d 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -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; |