diff options
author | megamage <none@none> | 2008-11-28 11:38:28 -0600 |
---|---|---|
committer | megamage <none@none> | 2008-11-28 11:38:28 -0600 |
commit | e26beb36c2073bb35151aa0cfee7e95f1b5a3901 (patch) | |
tree | 0adc111c86d8a75c406889c231a3b6922ff9933c | |
parent | 1d6e33add4f41ba07d5bd9115b1fe8c52ebb6d21 (diff) |
*Update to Mangos 6856. Source: Mangos.
--HG--
branch : trunk
-rw-r--r-- | sql/updates/341_world.sql | 1 | ||||
-rw-r--r-- | src/framework/Utilities/LinkedList.h | 30 | ||||
-rw-r--r-- | src/framework/Utilities/LinkedReference/Reference.h | 12 | ||||
-rw-r--r-- | src/game/Map.cpp | 37 | ||||
-rw-r--r-- | src/game/Map.h | 1 | ||||
-rw-r--r-- | src/game/MapReference.h | 102 | ||||
-rw-r--r-- | src/game/MovementHandler.cpp | 15 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 5 | ||||
-rw-r--r-- | src/game/Pet.cpp | 2 | ||||
-rw-r--r-- | src/game/PetHandler.cpp | 5 | ||||
-rw-r--r-- | src/game/Player.cpp | 103 | ||||
-rw-r--r-- | src/game/Player.h | 1 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 96 | ||||
-rw-r--r-- | src/shared/Database/DBCStores.cpp | 3 | ||||
-rw-r--r-- | src/shared/Database/DBCStores.h | 1 | ||||
-rw-r--r-- | src/shared/Database/DBCStructure.h | 15 | ||||
-rw-r--r-- | src/shared/Database/DBCfmt.cpp | 3 |
17 files changed, 271 insertions, 161 deletions
diff --git a/sql/updates/341_world.sql b/sql/updates/341_world.sql new file mode 100644 index 00000000000..7d1eb4a0c8d --- /dev/null +++ b/sql/updates/341_world.sql @@ -0,0 +1 @@ +TRUNCATE TABLE playercreateinfo_item;
\ No newline at end of file diff --git a/src/framework/Utilities/LinkedList.h b/src/framework/Utilities/LinkedList.h index fe4d1b7dd8d..3f9c99b31ff 100644 --- a/src/framework/Utilities/LinkedList.h +++ b/src/framework/Utilities/LinkedList.h @@ -46,6 +46,11 @@ class LinkedListElement LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; } LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; } + LinkedListElement * nocheck_next() { return iNext; } + LinkedListElement const* nocheck_next() const { return iNext; } + LinkedListElement * nocheck_prev() { return iPrev; } + LinkedListElement const* nocheck_prev() const { return iPrev; } + void delink() { if(isInList()) @@ -136,7 +141,10 @@ class LinkedListHead typedef ptrdiff_t difference_type; typedef ptrdiff_t distance_type; typedef _Ty* pointer; + typedef _Ty const* const_pointer; typedef _Ty& reference; + typedef _Ty const & const_reference; + Iterator() : _Ptr(0) { // construct with null node pointer @@ -146,6 +154,17 @@ class LinkedListHead { // construct with node pointer _Pnode } + Iterator& operator=(Iterator const &_Right) + { + return (*this) = _Right._Ptr; + } + + Iterator& operator=(const_pointer const &_Right) + { + _Ptr = (pointer)_Right; + return (*this); + } + reference operator*() { // return designated value return *_Ptr; @@ -202,6 +221,17 @@ class LinkedListHead return (!(*this == _Right)); } + bool operator==(const_reference _Right) const + { // test for reference equality + return (_Ptr == &_Right); + } + + bool operator!=(const_reference _Right) const + { // test for reference equality + return (_Ptr != &_Right); + } + + pointer _Mynode() { // return node pointer return (_Ptr); diff --git a/src/framework/Utilities/LinkedReference/Reference.h b/src/framework/Utilities/LinkedReference/Reference.h index ca837c81f91..bce0e0f387c 100644 --- a/src/framework/Utilities/LinkedReference/Reference.h +++ b/src/framework/Utilities/LinkedReference/Reference.h @@ -73,9 +73,15 @@ template <class TO, class FROM> class Reference : public LinkedListElement return iRefTo != NULL; } - Reference<TO,FROM>* next() { return((Reference<TO,FROM>*)LinkedListElement::next()); } - Reference<TO,FROM>const* next() const { return((Reference<TO,FROM> const*)LinkedListElement::next()); } - Reference<TO,FROM>* prev() { return((Reference<TO,FROM>*)LinkedListElement::prev()); } + Reference<TO,FROM> * next() { return((Reference<TO,FROM> *) LinkedListElement::next()); } + Reference<TO,FROM> const * next() const { return((Reference<TO,FROM> const *) LinkedListElement::next()); } + Reference<TO,FROM> * prev() { return((Reference<TO,FROM> *) LinkedListElement::prev()); } + Reference<TO,FROM> const * prev() const { return((Reference<TO,FROM> const *) LinkedListElement::prev()); } + + Reference<TO,FROM> * nocheck_next() { return((Reference<TO,FROM> *) LinkedListElement::nocheck_next()); } + Reference<TO,FROM> const * nocheck_next() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_next()); } + Reference<TO,FROM> * nocheck_prev() { return((Reference<TO,FROM> *) LinkedListElement::nocheck_prev()); } + Reference<TO,FROM> const * nocheck_prev() const { return((Reference<TO,FROM> const *) LinkedListElement::nocheck_prev()); } inline TO* operator ->() const { return iRefTo; } inline TO* getTarget() const { return iRefTo; } diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 246af3792fb..b1f22a63e78 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -641,22 +641,18 @@ void Map::Update(const uint32 &t_diff) { resetMarkedCells(); - // update cells around players - /*for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) - { - Player* plr = iter->getSource(); - if(plr->IsInWorld()) - UpdateActiveCells(plr->GetPositionX(), plr->GetPositionY(), t_diff); - }*/ - - // update cells around active objects - // clone the active object list, because update might remove from it - std::set<WorldObject *> activeObjects(i_activeObjects); + //TODO: is there a better way to update activeobjects? + std::vector<WorldObject*> activeObjects; for(MapRefManager::iterator iter = m_mapRefManager.begin(); iter != m_mapRefManager.end(); ++iter) { Player* plr = iter->getSource(); if(plr->IsInWorld()) - activeObjects.insert(plr); + activeObjects.push_back(plr); + } + for(std::set<WorldObject *>::iterator iter = i_activeObjects.begin(); iter != i_activeObjects.end(); ++iter) + { + if((*iter)->IsInWorld()) + activeObjects.push_back(*iter); } Trinity::ObjectUpdater updater(t_diff); @@ -665,11 +661,8 @@ void Map::Update(const uint32 &t_diff) // for pets TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer > world_object_update(updater); - for(std::set<WorldObject *>::iterator iter = activeObjects.begin(); iter != activeObjects.end(); ++iter) + for(std::vector<WorldObject*>::iterator iter = activeObjects.begin(); iter != activeObjects.end(); ++iter) { - if(!(*iter)->IsInWorld()) - continue; - CellPair standing_cell(Trinity::ComputeCellPair((*iter)->GetPositionX(), (*iter)->GetPositionY())); // Check for correctness of standing_cell, it also avoids problems with update_cell @@ -723,6 +716,13 @@ void Map::Update(const uint32 &t_diff) void Map::Remove(Player *player, bool remove) { + // this may be called during Map::Update + // after decrement+unlink, ++m_mapRefIter will continue correctly + // when the first element of the list is being removed + // nocheck_prev will return the padding element of the RefManager + // instead of NULL in the case of prev + if(m_mapRefIter == player->GetMapRef()) + m_mapRefIter = m_mapRefIter->nocheck_prev(); player->GetMapRef().unlink(); CellPair p = Trinity::ComputeCellPair(player->GetPositionX(), player->GetPositionY()); if(p.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || p.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP) @@ -1754,6 +1754,8 @@ bool InstanceMap::Add(Player *player) } if(i_data) i_data->OnPlayerEnter(player); + // for normal instances cancel the reset schedule when the + // first player enters (no players yet) SetResetSchedule(false); player->SendInitWorldStates(); @@ -1780,11 +1782,12 @@ void InstanceMap::Update(const uint32& t_diff) void InstanceMap::Remove(Player *player, bool remove) { sLog.outDetail("MAP: Removing player '%s' from instance '%u' of map '%s' before relocating to other map", player->GetName(), GetInstanceId(), GetMapName()); - SetResetSchedule(true); //if last player set unload timer if(!m_unloadTimer && m_mapRefManager.getSize() == 1) m_unloadTimer = m_unloadWhenEmpty ? MIN_UNLOAD_DELAY : std::max(sWorld.getConfig(CONFIG_INSTANCE_UNLOAD_DELAY), (uint32)MIN_UNLOAD_DELAY); Map::Remove(player, remove); + // for normal instances schedule the reset after all players have left + SetResetSchedule(true); } Creature * Map::GetCreatureInMap(uint64 guid) diff --git a/src/game/Map.h b/src/game/Map.h index cd476f5e3c6..5f2212e53a7 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -302,6 +302,7 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O uint32 m_unloadTimer; MapRefManager m_mapRefManager; + MapRefManager::iterator m_mapRefIter; private: typedef GridReadGuard ReadGuard; typedef GridWriteGuard WriteGuard; diff --git a/src/game/MapReference.h b/src/game/MapReference.h index b41796ea91b..5300d1aa4a7 100644 --- a/src/game/MapReference.h +++ b/src/game/MapReference.h @@ -1,50 +1,52 @@ -/*
- * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _MAPREFERENCE_H
-#define _MAPREFERENCE_H
-
-#include "Utilities/LinkedReference/Reference.h"
-#include "Map.h"
-
-class TRINITY_DLL_SPEC MapReference : public Reference<Map, Player>
-{
- protected:
- void targetObjectBuildLink()
- {
- // called from link()
- getTarget()->m_mapRefManager.insertFirst(this);
- getTarget()->m_mapRefManager.incSize();
- }
- void targetObjectDestroyLink()
- {
- // called from unlink()
- if(isValid()) getTarget()->m_mapRefManager.decSize();
- }
- void sourceObjectDestroyLink()
- {
- // called from invalidate()
- getTarget()->m_mapRefManager.decSize();
- }
- public:
- MapReference() : Reference<Map, Player>() {}
- ~MapReference() { unlink(); }
- MapReference *next() { return (MapReference*)Reference<Map, Player>::next(); }
- MapReference const *next() const { return (MapReference const*)Reference<Map, Player>::next(); }
-};
-#endif
+/* + * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _MAPREFERENCE_H +#define _MAPREFERENCE_H + +#include "Utilities/LinkedReference/Reference.h" +#include "Map.h" + +class TRINITY_DLL_SPEC MapReference : public Reference<Map, Player> +{ + protected: + void targetObjectBuildLink() + { + // called from link() + getTarget()->m_mapRefManager.insertFirst(this); + getTarget()->m_mapRefManager.incSize(); + } + void targetObjectDestroyLink() + { + // called from unlink() + if(isValid()) getTarget()->m_mapRefManager.decSize(); + } + void sourceObjectDestroyLink() + { + // called from invalidate() + getTarget()->m_mapRefManager.decSize(); + } + public: + MapReference() : Reference<Map, Player>() {} + ~MapReference() { unlink(); } + MapReference *next() { return (MapReference*)Reference<Map, Player>::next(); } + MapReference const *next() const { return (MapReference const*)Reference<Map, Player>::next(); } + MapReference *nockeck_prev() { return (MapReference*)Reference<Map, Player>::nocheck_prev(); } + MapReference const *nocheck_prev() const { return (MapReference const*)Reference<Map, Player>::nocheck_prev(); } +}; +#endif diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 78cabe07bab..cdc922aa84c 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -10,12 +10,12 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "Common.h" @@ -50,15 +50,6 @@ void WorldSession::HandleMoveWorldportAckOpcode() return; } - if(!sWorld.IsAllowedMap(loc.mapid) && (GetSecurity() < SEC_GAMEMASTER)) - { - if(sWorld.IsAllowedMap(GetPlayer()->m_homebindMapId)) - GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); - else - LogoutPlayer(false); - return; - } - // get the destination map entry, not the current one, this will fix homebind and reset greeting MapEntry const* mEntry = sMapStore.LookupEntry(loc.mapid); InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(loc.mapid); @@ -83,7 +74,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() GetPlayer()->SendInitialPacketsBeforeAddToMap(); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full - if(!MapManager::Instance().GetMap(GetPlayer()->GetMapId(), GetPlayer())->Add(GetPlayer())) + if(!GetPlayer()->GetMap()->Add(GetPlayer())) { sLog.outDebug("WORLD: teleport of player %s (%d) to location %d,%f,%f,%f,%f failed", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow(), loc.mapid, loc.x, loc.y, loc.z, loc.o); // teleport the player home diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 16ef4a26a34..bdf9e0328f2 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -2183,8 +2183,7 @@ void ObjectMgr::LoadPlayerInfo() barGoLink bar( 1 ); sLog.outString(); - sLog.outString( ">> Loaded %u player create items", count ); - sLog.outErrorDb( "Error loading `playercreateinfo_item` table or empty table."); + sLog.outString( ">> Loaded %u custom player create items", count ); } else { @@ -2236,7 +2235,7 @@ void ObjectMgr::LoadPlayerInfo() delete result; sLog.outString(); - sLog.outString( ">> Loaded %u player create items", count ); + sLog.outString( ">> Loaded %u custom player create items", count ); } } diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 65d5fd73199..3ab892fd2fb 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -1015,7 +1015,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel) SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0); CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(cinfo->family); - if(cFamily && cFamily->minScale > 0.0f) + if(cFamily && cFamily->minScale > 0.0f && getPetType()==HUNTER_PET) { float scale; if (getLevel() >= cFamily->maxScaleLevel) diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index d912f42c22b..7950db27464 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -112,7 +112,10 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) return; // not let attack friendly units. - if( GetPlayer()->IsFriendlyTo(TargetUnit)) + if(GetPlayer()->IsFriendlyTo(TargetUnit)) + return; + // Not let attack through obstructions + if(!pet->IsWithinLOSInMap(TargetUnit)) return; if(pet->GetTypeId() != TYPEID_PLAYER) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 1a5775845b1..8b7bcdf8c06 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -566,7 +566,9 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_, setFactionForRace(m_race); - SetUInt32Value(UNIT_FIELD_BYTES_0, ( ( race ) | ( class_ << 8 ) | ( gender << 16 ) | ( powertype << 24 ) ) ); + uint32 RaceClassGender = ( race ) | ( class_ << 8 ) | ( gender << 16 ); + + SetUInt32Value(UNIT_FIELD_BYTES_0, ( RaceClassGender | ( powertype << 24 ) ) ); SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 ); SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); @@ -674,8 +676,10 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_, SetPower(POWER_MANA,GetMaxPower(POWER_MANA)); } + // original spells learnDefaultSpells(true); + // original action bar std::list<uint16>::const_iterator action_itr[4]; for(int i=0; i<4; i++) action_itr[i] = info->action[i].begin(); @@ -692,37 +696,59 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_, ++action_itr[i]; } - for (PlayerCreateInfoItems::const_iterator item_id_itr = info->item.begin(); item_id_itr!=info->item.end(); ++item_id_itr++) + // original items + CharStartOutfitEntry const* oEntry = NULL; + for (uint32 i = 1; i < sCharStartOutfitStore.GetNumRows(); ++i) { - uint32 titem_id = item_id_itr->item_id; - uint32 titem_amount = item_id_itr->item_amount; - - sLog.outDebug("STORAGE: Creating initial item, itemId = %u, count = %u",titem_id, titem_amount); - - // attempt equip - uint16 eDest; - uint8 msg = CanEquipNewItem( NULL_SLOT, eDest, titem_id, titem_amount, false ); - if( msg == EQUIP_ERR_OK ) + if(CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(i)) { - EquipNewItem( eDest, titem_id, titem_amount, true); - AutoUnequipOffhandIfNeed(); - continue; // equipped, to next + if(entry->RaceClassGender == RaceClassGender) + { + oEntry = entry; + break; + } } + } - // attempt store - ItemPosCountVec sDest; - // store in main bag to simplify second pass (special bags can be not equipped yet at this moment) - msg = CanStoreNewItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount ); - if( msg == EQUIP_ERR_OK ) + if(oEntry) + { + for(int j = 0; j < MAX_OUTFIT_ITEMS; ++j) { - StoreNewItem( sDest, titem_id, true, Item::GenerateItemRandomPropertyId(titem_id) ); - continue; // stored, to next - } + if(oEntry->ItemId[j] <= 0) + continue; + + uint32 item_id = oEntry->ItemId[j]; - // item can't be added - sLog.outError("STORAGE: Can't equip or store initial item %u for race %u class %u , error msg = %u",titem_id,race,class_,msg); + ItemPrototype const* iProto = objmgr.GetItemPrototype(item_id); + if(!iProto) + { + sLog.outErrorDb("Initial item id %u (race %u class %u) from CharStartOutfit.dbc not listed in `item_template`, ignoring.",item_id,getRace(),getClass()); + continue; + } + + uint32 count = iProto->Stackable; // max stack by default (mostly 1) + if(iProto->Class==ITEM_CLASS_CONSUMABLE && iProto->SubClass==ITEM_SUBCLASS_FOOD) + { + switch(iProto->Spells[0].SpellCategory) + { + case 11: // food + if(iProto->Stackable > 4) + count = 4; + break; + case 59: // drink + if(iProto->Stackable > 2) + count = 2; + break; + } + } + + StoreNewItemInBestSlot(item_id, count); + } } + for (PlayerCreateInfoItems::const_iterator item_id_itr = info->item.begin(); item_id_itr!=info->item.end(); ++item_id_itr++) + StoreNewItemInBestSlot(item_id_itr->item_id, item_id_itr->item_amount); + // bags and main-hand weapon must equipped at this moment // now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon) // or ammo not equipped in special bag @@ -761,6 +787,35 @@ bool Player::Create( uint32 guidlow, std::string name, uint8 race, uint8 class_, return true; } +bool Player::StoreNewItemInBestSlot(uint32 titem_id, uint32 titem_amount) +{ + sLog.outDebug("STORAGE: Creating initial item, itemId = %u, count = %u",titem_id, titem_amount); + + // attempt equip + uint16 eDest; + uint8 msg = CanEquipNewItem( NULL_SLOT, eDest, titem_id, titem_amount, false ); + if( msg == EQUIP_ERR_OK ) + { + EquipNewItem( eDest, titem_id, titem_amount, true); + AutoUnequipOffhandIfNeed(); + return true; // equipped + } + + // attempt store + ItemPosCountVec sDest; + // store in main bag to simplify second pass (special bags can be not equipped yet at this moment) + msg = CanStoreNewItem( INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount ); + if( msg == EQUIP_ERR_OK ) + { + StoreNewItem( sDest, titem_id, true, Item::GenerateItemRandomPropertyId(titem_id) ); + return true; // stored + } + + // item can't be added + sLog.outError("STORAGE: Can't equip or store initial item %u for race %u class %u , error msg = %u",titem_id,getRace(),getClass(),msg); + return false; +} + void Player::StartMirrorTimer(MirrorTimerType Type, uint32 MaxValue) { uint32 BreathRegen = (uint32)-1; diff --git a/src/game/Player.h b/src/game/Player.h index 2f98793f3d1..0f2b9fc0dd5 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1081,6 +1081,7 @@ class TRINITY_DLL_SPEC Player : public Unit Item* EquipNewItem( uint16 pos, uint32 item, uint32 count, bool update ); Item* EquipItem( uint16 pos, Item *pItem, bool update ); void AutoUnequipOffhandIfNeed(); + bool StoreNewItemInBestSlot(uint32 item_id, uint32 item_count); uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const; uint8 _CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL ) const; diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index e7e1302ab58..073e8b36a8b 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -572,58 +572,9 @@ void Spell::EffectDummy(uint32 i) switch(m_spellInfo->SpellFamilyName) { case SPELLFAMILY_GENERIC: - // Gnomish Poultryizer trinket + { switch(m_spellInfo->Id ) { - // Mingo's Fortune Giblets - case 40802: - { - if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - - Player *player = (Player*)m_caster; - uint32 newitemid; - - switch(urand(1,20)) - { - case 1: newitemid = 32688; break; - case 2: newitemid = 32689; break; - case 3: newitemid = 32690; break; - case 4: newitemid = 32691; break; - case 5: newitemid = 32692; break; - case 6: newitemid = 32693; break; - case 7: newitemid = 32700; break; - case 8: newitemid = 32701; break; - case 9: newitemid = 32702; break; - case 10: newitemid = 32703; break; - case 11: newitemid = 32704; break; - case 12: newitemid = 32705; break; - case 13: newitemid = 32706; break; - case 14: newitemid = 32707; break; - case 15: newitemid = 32708; break; - case 16: newitemid = 32709; break; - case 17: newitemid = 32710; break; - case 18: newitemid = 32711; break; - case 19: newitemid = 32712; break; - case 20: newitemid = 32713; break; - } - ItemPosCountVec dest; - uint8 msg = player->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, newitemid, 1, false); - if (msg != EQUIP_ERR_OK) - { - player->SendEquipError(msg, NULL, NULL); - return; - } - Item *pItem = player->StoreNewItem(dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid)); - - if (!pItem) - { - player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); - return; - } - player->SendNewItem(pItem, 1, true, true); - - return; - } // Encapsulate Voidwalker case 29364: { @@ -1035,6 +986,50 @@ void Spell::EffectDummy(uint32 i) if(unitTarget) m_caster->CastSpell(unitTarget,37675,true); return; + case 40802: // Mingo's Fortune Generator (Mingo's Fortune Giblets) + { + // selecting one from Bloodstained Fortune item + uint32 newitemid; + switch(urand(1,20)) + { + case 1: newitemid = 32688; break; + case 2: newitemid = 32689; break; + case 3: newitemid = 32690; break; + case 4: newitemid = 32691; break; + case 5: newitemid = 32692; break; + case 6: newitemid = 32693; break; + case 7: newitemid = 32700; break; + case 8: newitemid = 32701; break; + case 9: newitemid = 32702; break; + case 10: newitemid = 32703; break; + case 11: newitemid = 32704; break; + case 12: newitemid = 32705; break; + case 13: newitemid = 32706; break; + case 14: newitemid = 32707; break; + case 15: newitemid = 32708; break; + case 16: newitemid = 32709; break; + case 17: newitemid = 32710; break; + case 18: newitemid = 32711; break; + case 19: newitemid = 32712; break; + case 20: newitemid = 32713; break; + default: + return; + } + + DoCreateItem(i,newitemid); + return; + } + // Demon Broiled Surprise + /* FIX ME: Required for correct work implementing implicit target 7 (in pair (22,7)) + case 43723: + { + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return; + + ((Player*)m_caster)->CastSpell(unitTarget, 43753, true); + return; + } + */ case 44875: // Complete Raptor Capture { if(!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT) @@ -1182,6 +1177,7 @@ void Spell::EffectDummy(uint32 i) } } break; + } case SPELLFAMILY_MAGE: switch(m_spellInfo->Id ) { diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp index 71e3483a1ab..b337acb1bd7 100644 --- a/src/shared/Database/DBCStores.cpp +++ b/src/shared/Database/DBCStores.cpp @@ -38,6 +38,7 @@ static AreaFlagByMapID sAreaFlagByMapID; // for instances wit DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt); DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt); DBCStorage <BattlemasterListEntry> sBattlemasterListStore(BattlemasterListEntryfmt); +DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore(CharStartOutfitEntryfmt); DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt); DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt); DBCStorage <ChrClassesEntry> sChrClassesStore(ChrClassesEntryfmt); @@ -203,6 +204,8 @@ void LoadDBCStores(std::string dataPath) LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore, dbcPath,"AreaTrigger.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore, dbcPath,"BankBagSlotPrices.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore, dbcPath,"BattlemasterList.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore, dbcPath,"CharStartOutfit.dbc"); + LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore, dbcPath,"CharTitles.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore, dbcPath,"ChatChannels.dbc"); LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore, dbcPath,"ChrClasses.dbc"); diff --git a/src/shared/Database/DBCStores.h b/src/shared/Database/DBCStores.h index 0375f20c7eb..eb824e331cc 100644 --- a/src/shared/Database/DBCStores.h +++ b/src/shared/Database/DBCStores.h @@ -136,6 +136,7 @@ extern DBCStorage <AreaTriggerEntry> sAreaTriggerStore; extern DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore; extern DBCStorage <BattlemasterListEntry> sBattlemasterListStore; //extern DBCStorage <ChatChannelsEntry> sChatChannelsStore; -- accessed using function, no usable index +extern DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore; extern DBCStorage <CharTitlesEntry> sCharTitlesStore; extern DBCStorage <ChrClassesEntry> sChrClassesStore; extern DBCStorage <ChrRacesEntry> sChrRacesStore; diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index ce72661066b..dde32406b94 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -86,6 +86,21 @@ struct BattlemasterListEntry // 32 unused }; +#define MAX_OUTFIT_ITEMS 12 +// #define MAX_OUTFIT_ITEMS 24 // 12->24 in 3.0.x + +struct CharStartOutfitEntry +{ + //uint32 Id; // 0 + uint32 RaceClassGender; // 1 (UNIT_FIELD_BYTES_0 & 0x00FFFFFF) comparable (0 byte = race, 1 byte = class, 2 byte = gender) + int32 ItemId[MAX_OUTFIT_ITEMS]; // 2-13 + //int32 ItemDisplayId[MAX_OUTFIT_ITEMS]; // 14-25 not required at server side + //int32 ItemInventorySlot[MAX_OUTFIT_ITEMS]; // 26-37 not required at server side + //uint32 Unknown1; // 38, unique values (index-like with gaps ordered in other way as ids) + //uint32 Unknown2; // 39 + //uint32 Unknown3; // 40 +}; + struct CharTitlesEntry { uint32 ID; // 0, title ids, for example in Quest::GetCharTitleId() diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp index 64163664b49..fe8d3cdb400 100644 --- a/src/shared/Database/DBCfmt.cpp +++ b/src/shared/Database/DBCfmt.cpp @@ -22,6 +22,9 @@ const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxx"; const char AreaTriggerEntryfmt[]="niffffffff"; const char BankBagSlotPricesEntryfmt[]="ni"; const char BattlemasterListEntryfmt[]="niiixxxxxiiiixxssssssssssssssssxx"; +const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxx"; +// 3*12 new item fields in 3.0.x +//const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; const char CharTitlesEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx"; // ChatChannelsEntryfmt, index not used (more compact store) |