diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp index c2a873a1b..1523fe673 100644 --- a/src/game/Corpse.cpp +++ b/src/game/Corpse.cpp @@ -34,7 +34,7 @@ Corpse::Corpse(CorpseType type) : WorldObject() m_objectType |= TYPEMASK_CORPSE; m_objectTypeId = TYPEID_CORPSE; // 2.3.2 - 0x58 - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); + m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION); m_valuesCount = CORPSE_END; diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index 86d621905..970209d7a 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -36,7 +36,7 @@ DynamicObject::DynamicObject() : WorldObject() m_objectType |= TYPEMASK_DYNAMICOBJECT; m_objectTypeId = TYPEID_DYNAMICOBJECT; // 2.3.2 - 0x58 - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); + m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION); m_valuesCount = DYNAMICOBJECT_END; } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 2544640c5..e9841e4fc 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -42,7 +42,7 @@ GameObject::GameObject() : WorldObject() m_objectType |= TYPEMASK_GAMEOBJECT; m_objectTypeId = TYPEID_GAMEOBJECT; // 2.3.2 - 0x58 - m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); + m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION); m_valuesCount = GAMEOBJECT_END; m_respawnTime = 0; diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 29bb37bc1..10c6f1f8a 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -547,12 +547,12 @@ void WorldSession::HandleTogglePvP( WorldPacket & recv_data ) bool newPvPStatus; recv_data >> newPvPStatus; GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus); - GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP, !newPvPStatus); + GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER, !newPvPStatus); } else { GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP); - GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP); + GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER); } if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index f2c9e168a..444930632 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -146,15 +146,9 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c /** lower flag1 **/ if(target == this) // building packet for oneself - { flags |= UPDATEFLAG_SELF; - /*** temporary reverted - until real source of stack corruption will not found - updatetype = UPDATETYPE_CREATE_OBJECT2; - ****/ - } - - if(flags & UPDATEFLAG_HASPOSITION) + if(flags & UPDATEFLAG_HAS_POSITION) { // UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses... if(isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER)) @@ -180,6 +174,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c break; } } + + if(isType(TYPEMASK_UNIT)) + { + if(((Unit*)this)->getVictim()) + flags |= UPDATEFLAG_HAS_TARGET; + } } //sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2); @@ -255,7 +255,7 @@ void Object::DestroyForPlayer(Player *target) const target->GetSession()->SendPacket( &data ); } -void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const +void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) const { uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0); @@ -298,7 +298,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 } // 0x40 - if (flags & UPDATEFLAG_HASPOSITION) + if (flags & UPDATEFLAG_HAS_POSITION) { // 0x02 if(flags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT) @@ -512,13 +512,13 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 *data << uint32(GetGUIDHigh()); // GetGUIDHigh() break; case TYPEID_UNIT: - *data << uint32(-1); + *data << uint32(0x0000000B); // unk, can be 0xB or 0xC break; case TYPEID_PLAYER: if(flags & UPDATEFLAG_SELF) *data << uint32(0x0000002F); // unk, can be 0x15 or 0x22 else - *data << uint32(-1); // unk, can be 0x7 or 0x8 + *data << uint32(0x00000008); // unk, can be 0x7 or 0x8 break; default: *data << uint32(0x00000000); // unk @@ -527,9 +527,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 } // 0x4 - if(flags & UPDATEFLAG_FULLGUID) + if(flags & UPDATEFLAG_HAS_TARGET) // packed guid (current target guid) { - *data << uint8(0); // packed guid (probably target guid) + if(Unit *victim = ((Unit*)this)->getVictim()) + data->append(victim->GetPackGUID()); + else + *data << uint8(0); } // 0x2 @@ -542,7 +545,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 if(flags & UPDATEFLAG_VEHICLE) // unused for now { *data << uint32(0); // vehicle id - *data << float(0); + *data << float(0); // facing adjustment } } @@ -646,7 +649,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *data << uint32(1); break; default: - *data << uint32(0); //unknown. not happen. + *data << uint32(0); // unknown. not happen. break; } } diff --git a/src/game/Object.h b/src/game/Object.h index d71da5622..45d86efaa 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -317,7 +317,7 @@ class MANGOS_DLL_SPEC Object { int32 *m_int32Values; uint32 *m_uint32Values; - float *m_floatValues; + float *m_floatValues; }; uint32 *m_uint32Values_mirror; diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 9c16b2fca..d18cccda7 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -904,7 +904,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel) case HUNTER_PET: { SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((MaNGOS::XP::xp_to_level(petlevel))/4)); - + learnLevelupSpells(); //these formula may not be correct; however, it is designed to be close to what it should be //this makes dps 0.5 of pets level SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) ); @@ -1331,6 +1331,21 @@ bool Pet::learnSpell(uint16 spell_id) return true; } +void Pet::learnLevelupSpells() +{ + PetLevelupSpellList const *levelupSpells = spellmgr.GetPetLevelupSpellList(GetCreatureInfo()->family); + if(!levelupSpells) + return; + + for(PetLevelupSpellList::const_iterator itr = levelupSpells->begin(); itr != levelupSpells->end(); ++itr) + { + if(itr->ReqLevel <= getLevel()) + learnSpell(itr->SpellId); + else + removeSpell(itr->SpellId); + } +} + void Pet::removeSpell(uint16 spell_id) { PetSpellMap::iterator itr = m_spells.find(spell_id); diff --git a/src/game/Pet.h b/src/game/Pet.h index ab349fc72..cbabb3985 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -190,6 +190,7 @@ 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 learnSpell(uint16 spell_id); + void learnLevelupSpells(); void removeSpell(uint16 spell_id); bool _removeSpell(uint16 spell_id); diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index e0acefd16..511544afe 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -731,6 +731,9 @@ void WorldSession::HandlePetLearnTalent( WorldPacket & recv_data ) if(!pet_family) return; + if(pet_family->petTalentType < 0) // not hunter pet + return; + // prevent learn talent for different family (cheating) if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)) return; diff --git a/src/game/Player.h b/src/game/Player.h index 50b464293..3473f58c8 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -390,7 +390,7 @@ enum PlayerFlags PLAYER_FLAGS_UNK3 = 0x00008000, // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag PLAYER_FLAGS_SANCTUARY = 0x00010000, // player entered sanctuary PLAYER_FLAGS_UNK4 = 0x00020000, // taxi benchmark mode (on/off) (2.0.1) - PLAYER_FLAGS_PVP = 0x00040000, // 3.0.2... + PLAYER_FLAGS_PVP_TIMER = 0x00040000, // 3.0.2, pvp timer active (after you disable pvp manually) }; // used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<> Loaded %u spell pet auras", count ); } -/// Some checks for spells, to prevent adding depricated/broken spells for trainers, spell book, etc +void SpellMgr::LoadPetLevelupSpellMap() +{ + PetLevelupSpell petSpell; + CreatureFamilyEntry const *creatureFamily; + SpellEntry const *spell; + uint32 count = 0; + uint32 startTime = getMSTime(); + + for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i) + { + creatureFamily = sCreatureFamilyStore.LookupEntry(i); + + if(!creatureFamily) // not exist + continue; + + if(creatureFamily->petTalentType < 0) // not hunter pet family + continue; + + for(uint32 j = 0; j < sSpellStore.GetNumRows(); ++j) + { + spell = sSpellStore.LookupEntry(j); + + // not exist + if(!spell) + continue; + + // not hunter spell + if(spell->SpellFamilyName != SPELLFAMILY_HUNTER) + continue; + + // not pet spell + if(!(spell->SpellFamilyFlags & 0x1000000000000000LL)) + continue; + + // not Growl or Cower (generics) + if(spell->SpellIconID != 201 && spell->SpellIconID != 958) + { + switch(creatureFamily->ID) + { + case CREATURE_FAMILY_BAT: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 1577) // Bite and Sonic Blast + continue; + break; + case CREATURE_FAMILY_BEAR: + if(spell->SpellIconID != 262 && spell->SpellIconID != 1562) // Claw and Swipe + continue; + break; + case CREATURE_FAMILY_BIRD_OF_PREY: + if(spell->SpellIconID != 262 && spell->SpellIconID != 168) // Claw and Snatch + continue; + case CREATURE_FAMILY_BOAR: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 1578) // Bite and Gore + continue; + break; + case CREATURE_FAMILY_CARRION_BIRD: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 1579) // Bite and Demoralizing Screech + continue; + break; + case CREATURE_FAMILY_CAT: + if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 494) // Claw and Prowl and Rake + continue; + break; + case CREATURE_FAMILY_CHIMAERA: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 62) // Bite and Froststorm Breath + continue; + break; + case CREATURE_FAMILY_CORE_HOUND: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 1197) // Bite and Lava Breath + continue; + break; + case CREATURE_FAMILY_CRAB: + if(spell->SpellIconID != 262 && spell->SpellIconID != 2679) // Claw and Pin + continue; + break; + case CREATURE_FAMILY_CROCOLISK: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 1581) // Bite and Bad Attitude + continue; + break; + case CREATURE_FAMILY_DEVILSAUR: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 599) // Bite and Monstrous Bite + continue; + break; + case CREATURE_FAMILY_DRAGONHAWK: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 2128) // Bite and Fire Breath + continue; + break; + case CREATURE_FAMILY_GORILLA: + if(spell->SpellIconID != 473 && spell->SpellIconID != 148) // Smack and Thunderstomp + continue; + break; + case CREATURE_FAMILY_HYENA: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 138) // Bite and Tendon Rip + continue; + break; + case CREATURE_FAMILY_MOTH: + if(spell->SpellIconID != 1714 && spell->SpellIconID != 473) // Serenity Dust and Smack + continue; + break; + case CREATURE_FAMILY_NETHER_RAY: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 2027) // Bite and Nether Shock + continue; + break; + case CREATURE_FAMILY_RAPTOR: + if(spell->SpellIconID != 262 && spell->SpellIconID != 245) // Claw and Savage Rend + continue; + break; + case CREATURE_FAMILY_RAVAGER: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 2253) // Bite and Ravage + continue; + break; + case CREATURE_FAMILY_RHINO: + if(spell->SpellIconID != 473 && spell->SpellIconID != 3066) // Smack and Stampede + continue; + break; + case CREATURE_FAMILY_SCORPID: + if(spell->SpellIconID != 262 && spell->SpellIconID != 163) // Claw and Scorpid Poison + continue; + break; + case CREATURE_FAMILY_SERPENT: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 68) // Bite and Poison Spit + continue; + break; + case CREATURE_FAMILY_SILITHID: + if(spell->SpellIconID != 262 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 12013)) // Claw and Venom Web Spray + continue; + break; + case CREATURE_FAMILY_SPIDER: + if(spell->SpellIconID != 1680 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 684)) // Bite and Web + continue; + break; + case CREATURE_FAMILY_SPIRIT_BEAST: + if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 255) // Claw and Prowl and Spirit Strike + continue; + break; + case CREATURE_FAMILY_SPOREBAT: + if(spell->SpellIconID != 473 && spell->SpellIconID != 2681) // Smack and Spore Cloud + continue; + break; + case CREATURE_FAMILY_TALLSTRIDER: + if(spell->SpellIconID != 262 (spell->SpellIconID != 157 && (spell->Attributes & 0x4000000))) // Claw and Dust Cloud + continue; + break; + case CREATURE_FAMILY_TURTLE: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 1588) // Bite and Shell Shield + continue; + break; + case CREATURE_FAMILY_WARP_STALKER: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 1952) // Bite and Warp + continue; + break; + case CREATURE_FAMILY_WASP: + if(spell->SpellIconID != 473 && spell->SpellIconID != 110) // Smack and Sting + continue; + break; + case CREATURE_FAMILY_WIND_SERPENT: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 62) // Bite and Lightning Breath + continue; + break; + case CREATURE_FAMILY_WOLF: + if(spell->SpellIconID != 1680 && spell->SpellIconID != 1573) // Bite and Furious Howl + continue; + break; + case CREATURE_FAMILY_WORM: + if(spell->SpellIconID != 636 && spell->SpellIconID != 1680) // Acid Spit and Bite + continue; + break; + default: + sLog.outError("LoadPetLevelupSpellMap: Unhandled creature family %u", creatureFamily->ID); + continue; + } + } + + petSpell.SpellId = spell->Id; + petSpell.ReqLevel = spell->spellLevel; + + mPetLevelupSpellMap[creatureFamily->ID].push_back(petSpell); + count++; + } + } + + uint32 diffTime = getMSTimeDiff(startTime, getMSTime()); + sLog.outDebug("took %u ms", diffTime); + + sLog.outString(); + sLog.outString( ">> Loaded %u pet levelup spells", count ); +} + +/// Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg) { // not exist diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 9c739a589..6ae7aac1e 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -626,6 +626,15 @@ typedef std::multimap SpellLearnSpellMap; typedef std::multimap SkillLineAbilityMap; +struct PetLevelupSpell +{ + uint32 SpellId; + uint32 ReqLevel; +}; + +typedef std::list PetLevelupSpellList; +typedef std::map PetLevelupSpellMap; + inline bool IsPrimaryProfessionSkill(uint32 skill) { SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill); @@ -841,6 +850,15 @@ class SpellMgr return NULL; } + PetLevelupSpellList const* GetPetLevelupSpellList(uint32 petFamily) const + { + PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily); + if(itr != mPetLevelupSpellMap.end()) + return &itr->second; + else + return NULL; + } + // Modifiers public: static SpellMgr& Instance(); @@ -857,6 +875,7 @@ class SpellMgr void LoadSpellThreats(); void LoadSkillLineAbilityMap(); void LoadSpellPetAuras(); + void LoadPetLevelupSpellMap(); private: SpellScriptTarget mSpellScriptTarget; @@ -870,6 +889,7 @@ class SpellMgr SpellProcEventMap mSpellProcEventMap; SkillLineAbilityMap mSkillLineAbilityMap; SpellPetAuraMap mSpellPetAuraMap; + PetLevelupSpellMap mPetLevelupSpellMap; }; #define spellmgr SpellMgr::Instance() diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp index 375bcc1ad..26faa9350 100644 --- a/src/game/Transports.cpp +++ b/src/game/Transports.cpp @@ -135,7 +135,7 @@ void MapManager::LoadTransports() Transport::Transport() : GameObject() { // 2.3.2 - 0x5A - m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); + m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION); } bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 95ac8ffc1..8b894bb87 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -146,7 +146,7 @@ Unit::Unit() m_objectType |= TYPEMASK_UNIT; m_objectTypeId = TYPEID_UNIT; // 2.3.2 - 0x70 - m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HASPOSITION); + m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION); m_attackTimer[BASE_ATTACK] = 0; m_attackTimer[OFF_ATTACK] = 0; diff --git a/src/game/UpdateData.h b/src/game/UpdateData.h index b4ddc1c9b..aff6d47e5 100644 --- a/src/game/UpdateData.h +++ b/src/game/UpdateData.h @@ -36,11 +36,11 @@ enum OBJECT_UPDATE_FLAGS UPDATEFLAG_NONE = 0x00, UPDATEFLAG_SELF = 0x01, UPDATEFLAG_TRANSPORT = 0x02, - UPDATEFLAG_FULLGUID = 0x04, + UPDATEFLAG_HAS_TARGET = 0x04, UPDATEFLAG_LOWGUID = 0x08, UPDATEFLAG_HIGHGUID = 0x10, UPDATEFLAG_LIVING = 0x20, - UPDATEFLAG_HASPOSITION = 0x40, + UPDATEFLAG_HAS_POSITION = 0x40, UPDATEFLAG_VEHICLE = 0x80 }; diff --git a/src/game/World.cpp b/src/game/World.cpp index 1e29ffc55..f177b86f0 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1060,6 +1060,9 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading spell pet auras..." ); spellmgr.LoadSpellPetAuras(); + sLog.outString( "Loading pet levelup spells..." ); + spellmgr.LoadPetLevelupSpellMap(); + sLog.outString( "Loading player Create Info & Level Stats..." ); objmgr.LoadPlayerInfo(); diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index 4aa97397c..be9214209 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -613,7 +613,7 @@ struct CreatureFamilyEntry uint32 maxScaleLevel; // 4 m_maxScaleLevel uint32 skillLine[2]; // 5-6 m_skillLine uint32 petFoodMask; // 7 m_petFoodMask - uint32 petTalentType; // 8 m_petTalentType + int32 petTalentType; // 8 m_petTalentType // 9 m_categoryEnumID char* Name[16]; // 10-25 m_name_lang // 26 string flags, unused