diff options
author | megamage <none@none> | 2009-05-28 18:22:54 -0500 |
---|---|---|
committer | megamage <none@none> | 2009-05-28 18:22:54 -0500 |
commit | cfa2e223c03b2b6fbc7bce39ba942ebbecd95c5a (patch) | |
tree | d27375776985bd1b75f18001acdee2aa725fee4e | |
parent | 4a7a63e4388baceb4ada57f978fc2dbd303c8213 (diff) |
[7903] Load and save for pets only talents. Not store unused (in fact) free talent point amount. Author: VladimirMangos
* Other pet spell types auto-learned at level setup/load.
* Code will cleanup pet_spell table from non-talents spell if detect any at load.
* Free talents points recalculated at loading and levelup so store its in DB useless.
Note: bug with not highlighting learned pet talents (except first line) until learn one more talent not fixed.
--HG--
branch : trunk
-rw-r--r-- | sql/characters.sql | 23 | ||||
-rw-r--r-- | sql/updates/7903_01_characters_character_pet.sql | 4 | ||||
-rw-r--r-- | src/game/Pet.cpp | 93 | ||||
-rw-r--r-- | src/game/Pet.h | 1 |
4 files changed, 79 insertions, 42 deletions
diff --git a/sql/characters.sql b/sql/characters.sql index 6785c3a59a8..6b27a1753cd 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -15,6 +15,28 @@ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +/* + +-- +-- Table structure for table `character_db_version` +-- + +DROP TABLE IF EXISTS `character_db_version`; +CREATE TABLE `character_db_version` ( + `required_7903_01_characters_character_pet` bit(1) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; + +-- +-- Dumping data for table `character_db_version` +-- + +LOCK TABLES `character_db_version` WRITE; +INSERT INTO `character_db_version` VALUES +(NULL); +UNLOCK TABLES; + +*/ + -- -- Table structure for table `account_data` -- @@ -538,7 +560,6 @@ CREATE TABLE `character_pet` ( `level` int(11) unsigned NOT NULL default '1', `exp` int(11) unsigned NOT NULL default '0', `Reactstate` tinyint(1) unsigned NOT NULL default '0', - `talentpoints` int(11) unsigned NOT NULL default '0', `name` varchar(100) default 'Pet', `renamed` tinyint(1) unsigned NOT NULL default '0', `slot` int(11) unsigned NOT NULL default '0', diff --git a/sql/updates/7903_01_characters_character_pet.sql b/sql/updates/7903_01_characters_character_pet.sql new file mode 100644 index 00000000000..834aac200bb --- /dev/null +++ b/sql/updates/7903_01_characters_character_pet.sql @@ -0,0 +1,4 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_7887_01_characters_character_pet required_7903_01_characters_character_pet bit; + +ALTER TABLE `character_pet` + DROP `talentpoints`; diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index dabc366b874..4d7c851b2df 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -90,25 +90,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 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags " + // known petnumber entry 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, 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 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags " + // current pet (slot 0) 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, 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 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags " + // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, 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 - result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags " + // 0 1 2(?) 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 + result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, 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); @@ -125,7 +125,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool return false; } - uint32 summon_spell_id = fields[18].GetUInt32(); + uint32 summon_spell_id = fields[17].GetUInt32(); SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id); bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0; @@ -166,7 +166,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool return false; } - setPetType(PetType(fields[19].GetUInt8())); + setPetType(PetType(fields[18].GetUInt8())); SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction()); SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id); @@ -180,25 +180,11 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool m_charmInfo->SetPetNumber(pet_number, IsPermanentPetFor(owner)); - // set current pet as current - // 0=current - // 1..MAX_PET_STABLES in stable slot - // PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning)) - if(fields[8].GetUInt32() != 0) - { - CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'", - PET_SAVE_NOT_IN_SLOT, ownerid, PET_SAVE_AS_CURRENT, m_charmInfo->GetPetNumber()); - CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'", - PET_SAVE_AS_CURRENT, ownerid, m_charmInfo->GetPetNumber()); - CharacterDatabase.CommitTransaction(); - } - SetDisplayId(fields[3].GetUInt32()); SetNativeDisplayId(fields[3].GetUInt32()); uint32 petlevel = fields[4].GetUInt32(); SetUInt32Value(UNIT_NPC_FLAGS, 0); - SetName(fields[9].GetString()); + SetName(fields[8].GetString()); switch (getPetType()) { @@ -211,14 +197,13 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool break; case HUNTER_PET: SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); - SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[7].GetUInt32()); SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); - SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[10].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED); + SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[9].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); // this enables popup window (pet abandon, cancel) SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS)); - SetPower(POWER_HAPPINESS, fields[13].GetUInt32()); + SetPower(POWER_HAPPINESS, fields[12].GetUInt32()); setPowerType(POWER_FOCUS); break; default: @@ -241,23 +226,37 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool } else { - uint32 savedhealth = fields[11].GetUInt32(); - uint32 savedmana = fields[12].GetUInt32(); + uint32 savedhealth = fields[10].GetUInt32(); + uint32 savedmana = fields[11].GetUInt32(); SetHealth(savedhealth > GetMaxHealth() ? GetMaxHealth() : savedhealth); SetPower(POWER_MANA, savedmana > GetMaxPower(POWER_MANA) ? GetMaxPower(POWER_MANA) : savedmana); } + // set current pet as current + // 0=current + // 1..MAX_PET_STABLES in stable slot + // PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning)) + if(fields[7].GetUInt32() != 0) + { + CharacterDatabase.BeginTransaction(); + CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'", + PET_SAVE_NOT_IN_SLOT, ownerid, PET_SAVE_AS_CURRENT, m_charmInfo->GetPetNumber()); + CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'", + PET_SAVE_AS_CURRENT, ownerid, m_charmInfo->GetPetNumber()); + CharacterDatabase.CommitTransaction(); + } + owner->SetMinion(this, true); map->Add((Creature*)this); - m_resetTalentsCost = fields[16].GetUInt32(); - m_resetTalentsTime = fields[17].GetUInt64(); - InitTalentForLevel(); + m_resetTalentsCost = fields[15].GetUInt32(); + m_resetTalentsTime = fields[16].GetUInt64(); + InitTalentForLevel(); // set original talents points before spell loading - uint32 timediff = (time(NULL) - fields[15].GetUInt32()); + uint32 timediff = (time(NULL) - fields[14].GetUInt32()); _LoadAuras(timediff); - uint8 loadFlags = fields[20].GetUInt8(); + uint8 loadFlags = fields[19].GetUInt8(); owner->SetPetAtLoginFlag(loadFlags); if (loadFlags & AT_LOAD_RESET_SPELLS) { @@ -272,7 +271,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool // Load action bar data if (!is_temporary_summoned) { - if(!m_charmInfo->LoadActionBar(fields[14].GetCppString())) + if(!m_charmInfo->LoadActionBar(fields[13].GetCppString())) { delete result; return false; @@ -383,7 +382,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, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags) " + ss << "INSERT INTO character_pet ( id, entry, owner, modelid, level, exp, Reactstate, slot, name, renamed, curhealth, curmana, curhappiness, abdata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType, load_flags) " << "VALUES (" << m_charmInfo->GetPetNumber() << ", " << GetEntry() << ", " @@ -392,7 +391,6 @@ void Pet::SavePetToDB(PetSaveMode mode) << getLevel() << ", " << GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", " << uint32(GetReactState()) << ", " - << uint32(GetFreeTalentPoints()) << ", " << uint32(mode) << ", '" << name.c_str() << "', " << uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", " @@ -1053,7 +1051,17 @@ void Pet::_LoadSpells() { Field *fields = result->Fetch(); - addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt16()), PETSPELL_UNCHANGED); + uint32 spell_id = fields[0].GetUInt32(); + + // load only pet talents, other spell types auto-learned + if(GetTalentSpellCost(spell_id)==0) + { + CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE spell = '%u'",spell_id); + sLog.outError("Table `pet_spell` have non-talent spell %u , spell removed from table for all pets.",spell_id); + continue; + } + + addSpell(spell_id, ActiveStates(fields[1].GetUInt16()), PETSPELL_UNCHANGED,PETSPELL_TALENT); } while( result->NextRow() ); @@ -1067,8 +1075,8 @@ void Pet::_SaveSpells() { ++next; - // prevent saving family passives to DB - if (itr->second.type == PETSPELL_FAMILY) + // save only talent spells for pets, other spells auto-applied + if (itr->second.type != PETSPELL_TALENT) continue; switch(itr->second.state) @@ -1245,6 +1253,9 @@ bool Pet::addSpell(uint32 spell_id,ActiveStates active /*= ACT_DECIDE*/, PetSpel // talent: unlearn all other talent ranks (high and low) if(TalentSpellPos const* talentPos = GetTalentSpellPos(spell_id)) { + // propertly mark spell for allow save + newspell.type = PETSPELL_TALENT; + if(TalentEntry const *talentInfo = sTalentStore.LookupEntry( talentPos->talent_id )) { for(int i=0; i < MAX_TALENT_RANK; ++i) diff --git a/src/game/Pet.h b/src/game/Pet.h index 8ee83b9a4ec..b4d5b928e97 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -65,6 +65,7 @@ enum PetSpellType { PETSPELL_NORMAL = 0, PETSPELL_FAMILY = 1, + PETSPELL_TALENT = 2, }; struct PetSpell |