diff options
author | n0n4m3 <none@none> | 2009-12-17 11:18:07 +0100 |
---|---|---|
committer | n0n4m3 <none@none> | 2009-12-17 11:18:07 +0100 |
commit | 360edd11df3911567000d5e150f3ede22af112f5 (patch) | |
tree | b06a0244a2f24b2a5322e8f61437cae8f9fb6706 | |
parent | 085bc555d73ebc1e28304c4dbfdb9542bb78f21e (diff) |
Update InstanceSaveMgr for new instance system
--HG--
branch : trunk
-rw-r--r-- | src/game/InstanceSaveMgr.cpp | 147 | ||||
-rw-r--r-- | src/game/InstanceSaveMgr.h | 40 | ||||
-rw-r--r-- | src/game/Item.cpp | 6 | ||||
-rw-r--r-- | src/game/Item.h | 1 | ||||
-rw-r--r-- | src/game/ItemHandler.cpp | 35 | ||||
-rw-r--r-- | src/game/ItemPrototype.h | 17 |
6 files changed, 158 insertions, 88 deletions
diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index 8c1aab1b60b..128674d978a 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -77,15 +77,27 @@ InstanceSaveManager::~InstanceSaveManager() - adding instance into manager - called from InstanceMap::Add, _LoadBoundInstances, LoadGroups */ -InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instanceId, uint8 difficulty, time_t resetTime, bool canReset, bool load) +InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load) { - InstanceSave *save = GetInstanceSave(instanceId); - if(save) return save; + if(InstanceSave *old_save = GetInstanceSave(instanceId)) + return old_save; const MapEntry* entry = sMapStore.LookupEntry(mapId); - if(!entry || instanceId == 0) + if (!entry) { - sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d!", mapId, instanceId); + sLog.outError("InstanceSaveManager::AddInstanceSave: wrong mapid = %d!", mapId, instanceId); + return NULL; + } + + if (instanceId == 0) + { + sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, wrong instanceid = %d!", mapId, instanceId); + return NULL; + } + + if (difficulty >= (entry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY)) + { + sLog.outError("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, wrong dificalty %u!", mapId, instanceId, difficulty); return NULL; } @@ -93,19 +105,19 @@ InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instance { // initialize reset time // for normal instances if no creatures are killed the instance will reset in two hours - if(entry->map_type == MAP_RAID || difficulty == DIFFICULTY_HEROIC) - resetTime = GetResetTimeFor(mapId); + if(entry->map_type == MAP_RAID || difficulty > DUNGEON_DIFFICULTY_NORMAL) + resetTime = GetResetTimeFor(mapId,difficulty); else { resetTime = time(NULL) + 2 * HOUR; // normally this will be removed soon after in InstanceMap::Add, prevent error - ScheduleReset(true, resetTime, InstResetEvent(0, mapId, instanceId)); + ScheduleReset(true, resetTime, InstResetEvent(0, mapId, difficulty, instanceId)); } } sLog.outDebug("InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d", mapId, instanceId); - save = new InstanceSave(mapId, instanceId, difficulty, resetTime, canReset); + InstanceSave *save = new InstanceSave(mapId, instanceId, difficulty, resetTime, canReset); if(!load) save->SaveToDB(); m_instanceSaveById[instanceId] = save; @@ -141,7 +153,7 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId) } } -InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty, time_t resetTime, bool canReset) +InstanceSave::InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, bool canReset) : m_resetTime(resetTime), m_instanceid(InstanceId), m_mapid(MapId), m_difficulty(difficulty), m_canReset(canReset) { @@ -180,7 +192,7 @@ time_t InstanceSave::GetResetTimeForDB() { // only save the reset time for normal instances const MapEntry *entry = sMapStore.LookupEntry(GetMapId()); - if(!entry || entry->map_type == MAP_RAID || GetDifficulty() == DIFFICULTY_HEROIC) + if(!entry || entry->map_type == MAP_RAID || GetDifficulty() == DUNGEON_DIFFICULTY_HEROIC) return 0; else return GetResetTime(); @@ -402,18 +414,26 @@ void InstanceSaveManager::LoadResetTimes() // get the current reset times for normal instances (these may need to be updated) // these are only kept in memory for InstanceSaves that are loaded later // resettime = 0 in the DB for raid/heroic instances so those are skipped - typedef std::map<uint32, std::pair<uint32, time_t> > ResetTimeMapType; - ResetTimeMapType InstResetTime; - QueryResult *result = CharacterDatabase.Query("SELECT id, map, resettime FROM instance WHERE resettime > 0"); + typedef std::pair<uint32 /*PAIR32(map,difficulty)*/, time_t> ResetTimeMapDiffType; + typedef std::map<uint32, ResetTimeMapDiffType> InstResetTimeMapDiffType; + InstResetTimeMapDiffType instResetTime; + + // index instance ids by map/difficulty pairs for fast reset warning send + typedef std::multimap<uint32 /*PAIR32(map,difficulty)*/, uint32 /*instanceid*/ > ResetTimeMapDiffInstances; + ResetTimeMapDiffInstances mapDiffResetInstances; + + QueryResult *result = CharacterDatabase.Query("SELECT id, map, difficulty, resettime FROM instance WHERE resettime > 0"); if( result ) { do { - if(time_t resettime = time_t((*result)[2].GetUInt64())) + if(time_t resettime = time_t((*result)[3].GetUInt64())) { uint32 id = (*result)[0].GetUInt32(); uint32 mapid = (*result)[1].GetUInt32(); - InstResetTime[id] = std::pair<uint32, uint64>(mapid, resettime); + uint32 difficulty = (*result)[2].GetUInt32(); + instResetTime[id] = ResetTimeMapDiffType(MAKE_PAIR32(mapid,difficulty), resettime); + mapDiffResetInstances.insert(ResetTimeMapDiffInstances::value_type(MAKE_PAIR32(mapid,difficulty),id)); } } while (result->NextRow()); @@ -428,8 +448,8 @@ void InstanceSaveManager::LoadResetTimes() Field *fields = result->Fetch(); uint32 instance = fields[1].GetUInt32(); time_t resettime = time_t(fields[0].GetUInt64() + 2 * HOUR); - ResetTimeMapType::iterator itr = InstResetTime.find(instance); - if(itr != InstResetTime.end() && itr->second.second != resettime) + InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance); + if(itr != instResetTime.end() && itr->second.second != resettime) { CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; @@ -440,62 +460,65 @@ void InstanceSaveManager::LoadResetTimes() } // schedule the reset times - for (ResetTimeMapType::iterator itr = InstResetTime.begin(); itr != InstResetTime.end(); ++itr) + for(InstResetTimeMapDiffType::iterator itr = instResetTime.begin(); itr != instResetTime.end(); ++itr) if(itr->second.second > now) - ScheduleReset(true, itr->second.second, InstResetEvent(0, itr->second.first, itr->first)); + ScheduleReset(true, itr->second.second, InstResetEvent(0, PAIR32_LOPART(itr->second.first),Difficulty(PAIR32_HIPART(itr->second.first)),itr->first)); } // load the global respawn times for raid/heroic instances uint32 diff = sWorld.getConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; - m_resetTimeByMapId.resize(sMapStore.GetNumRows()+1); - result = CharacterDatabase.Query("SELECT mapid, resettime FROM instance_reset"); + result = CharacterDatabase.Query("SELECT mapid, difficulty, resettime FROM instance_reset"); if(result) { do { Field *fields = result->Fetch(); uint32 mapid = fields[0].GetUInt32(); - if(!objmgr.GetInstanceTemplate(mapid)) + Difficulty difficulty = Difficulty(fields[1].GetUInt32()); + uint64 oldresettime = fields[2].GetUInt64(); + + MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty); + if(!mapDiff) { - sLog.outError("InstanceSaveManager::LoadResetTimes: invalid mapid %u in instance_reset!", mapid); - CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u'", mapid); + sLog.outError("InstanceSaveManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, difficulty); + CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid,difficulty); continue; } // update the reset time if the hour in the configs changes - uint64 oldresettime = fields[1].GetUInt64(); uint64 newresettime = (oldresettime / DAY) * DAY + diff; if(oldresettime != newresettime) - CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u'", newresettime, mapid); + CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty = '%u'", newresettime, mapid, difficulty); - m_resetTimeByMapId[mapid] = newresettime; + SetResetTimeFor(mapid,difficulty,newresettime); } while(result->NextRow()); delete result; } // clean expired instances, references to them will be deleted in CleanupInstances // must be done before calculating new reset times - _DelHelper(CharacterDatabase, "id, map, difficulty", "instance", "LEFT JOIN instance_reset ON mapid = map WHERE (instance.resettime < '"UI64FMTD"' AND instance.resettime > '0') OR (NOT instance_reset.resettime IS NULL AND instance_reset.resettime < '"UI64FMTD"')", (uint64)now, (uint64)now); + _DelHelper(CharacterDatabase, "id, map, instance.difficulty", "instance", "LEFT JOIN instance_reset ON mapid = map AND instance.difficulty = instance_reset.difficulty WHERE (instance.resettime < '"UI64FMTD"' AND instance.resettime > '0') OR (NOT instance_reset.resettime IS NULL AND instance_reset.resettime < '"UI64FMTD"')", (uint64)now, (uint64)now); // calculate new global reset times for expired instances and those that have never been reset yet // add the global reset times to the priority queue - for (uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++) + for(MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr) { - InstanceTemplate const* temp = objmgr.GetInstanceTemplate(i); - if(!temp) continue; - // only raid/heroic maps have a global reset time - const MapEntry* entry = sMapStore.LookupEntry(temp->map); - if(!entry || !entry->HasResetTime()) + uint32 map_diff_pair = itr->first; + uint32 mapid = PAIR32_LOPART(map_diff_pair); + Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair)); + MapDifficulty const* mapDiff = &itr->second; + if (!mapDiff->resetTime) continue; - uint32 period = temp->reset_delay * DAY; - assert(period != 0); - time_t t = m_resetTimeByMapId[temp->map]; + // the reset_delay must be at least one day + uint32 period = (mapDiff->resetTime / DAY * sWorld.getRate(RATE_INSTANCE_RESET_TIME)) * DAY; + + time_t t = GetResetTimeFor(mapid,difficulty); if(!t) { // initialize the reset time t = today + period + diff; - CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u','"UI64FMTD"')", i, (uint64)t); + CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u','%u','"UI64FMTD"')", mapid, difficulty, (uint64)t); } if(t < now) @@ -504,17 +527,23 @@ void InstanceSaveManager::LoadResetTimes() // calculate the next reset time t = (t / DAY) * DAY; t += ((today - t) / period + 1) * period + diff; - CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u'", (uint64)t, i); + CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); } - m_resetTimeByMapId[temp->map] = t; + SetResetTimeFor(mapid,difficulty,t); // schedule the global reset/warning uint8 type = 1; static int tim[4] = {3600, 900, 300, 60}; for (; type < 4; type++) - if(t - tim[type-1] > now) break; - ScheduleReset(true, t - tim[type-1], InstResetEvent(type, i)); + if(t - tim[type-1] > now) + break; + + for(ResetTimeMapDiffInstances::const_iterator in_itr = mapDiffResetInstances.lower_bound(map_diff_pair); + in_itr != mapDiffResetInstances.upper_bound(map_diff_pair); ++in_itr) + { + ScheduleReset(true, t - tim[type-1], InstResetEvent(type, mapid, difficulty, in_itr->second)); + } } } @@ -555,8 +584,8 @@ void InstanceSaveManager::Update() else { // global reset/warning for a certain map - time_t resetTime = GetResetTimeFor(event.mapid); - _ResetOrWarnAll(event.mapid, event.type != 4, resetTime - now); + time_t resetTime = GetResetTimeFor(event.mapid,event.difficulty); + _ResetOrWarnAll(event.mapid, event.difficulty, event.type != 4, resetTime - now); if(event.type != 4) { // schedule the next warning/reset @@ -607,29 +636,28 @@ void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId) else objmgr.DeleteRespawnTimeForInstance(instanceId); // even if map is not loaded } -void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLeft) +void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, uint32 timeLeft) { // global reset for all instances of the given map - // note: this isn't fast but it's meant to be executed very rarely - Map const *map = MapManager::Instance().CreateBaseMap(mapid); - if(!map->Instanceable()) + MapEntry const *mapEntry = sMapStore.LookupEntry(mapid); + if (!mapEntry->Instanceable()) return; + uint64 now = (uint64)time(NULL); if(!warn) { - // this is called one minute before the reset time - InstanceTemplate const* temp = objmgr.GetInstanceTemplate(mapid); - if(!temp || !temp->reset_delay) + MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty); + if (!mapDiff || !mapDiff->resetTime) { - sLog.outError("InstanceSaveManager::ResetOrWarnAll: no instance template or reset delay for map %d", mapid); + sLog.outError("InstanceSaveManager::ResetOrWarnAll: not valid difficulty or no reset delay for map %d", mapid); return; } // remove all binds to instances of the given map for (InstanceSaveHashMap::iterator itr = m_instanceSaveById.begin(); itr != m_instanceSaveById.end();) { - if(itr->second->GetMapId() == mapid) + if (itr->second->GetMapId() == mapid && itr->second->GetDifficulty() == difficulty) _ResetSave(itr); else ++itr; @@ -644,16 +672,14 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeLe // calculate the next reset time uint32 diff = sWorld.getConfig(CONFIG_INSTANCE_RESET_TIME_HOUR) * HOUR; - uint32 period = temp->reset_delay * DAY; + uint32 period = mapDiff->resetTime * DAY; uint64 next_reset = ((now + timeLeft + MINUTE) / DAY * DAY) + period + diff; // update it in the DB - CharacterDatabase.PExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%d'", next_reset, mapid); - - // schedule next reset. - m_resetTimeByMapId[mapid] = (time_t) next_reset; - ScheduleReset(true, (time_t) (next_reset-3600), InstResetEvent(1, mapid)); + CharacterDatabase.PExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%d' AND difficulty = '%d'", next_reset, mapid, difficulty); } + // note: this isn't fast but it's meant to be executed very rarely + Map const *map = MapManager::Instance().CreateBaseMap(mapid); // _not_ include difficulty MapInstanced::InstancedMaps &instMaps = ((MapInstanced*)map)->GetInstancedMaps(); MapInstanced::InstancedMaps::iterator mitr; for (mitr = instMaps.begin(); mitr != instMaps.end(); ++mitr) @@ -682,4 +708,3 @@ uint32 InstanceSaveManager::GetNumBoundGroupsTotal() ret += itr->second->GetGroupCount(); return ret; } - diff --git a/src/game/InstanceSaveMgr.h b/src/game/InstanceSaveMgr.h index 29972210f3d..6d031af752d 100644 --- a/src/game/InstanceSaveMgr.h +++ b/src/game/InstanceSaveMgr.h @@ -29,6 +29,8 @@ #include <map> #include "Utilities/UnorderedMap.h" #include "Database/DatabaseEnv.h" +#include "DBCEnums.h" +#include "ObjectDefines.h" struct InstanceTemplate; struct MapEntry; @@ -50,7 +52,7 @@ class InstanceSave - any new instance is being generated - the first time a player bound to InstanceId logs in - when a group bound to the instance is loaded */ - InstanceSave(uint16 MapId, uint32 InstanceId, uint8 difficulty, time_t resetTime, bool canReset); + InstanceSave(uint16 MapId, uint32 InstanceId, Difficulty difficulty, time_t resetTime, bool canReset); /* Unloaded when m_playerList and m_groupList become empty or when the instance is reset */ @@ -95,7 +97,7 @@ class InstanceSave /* currently it is possible to omit this information from this structure but that would depend on a lot of things that can easily change in future */ - uint8 GetDifficulty() { return m_difficulty; } + Difficulty GetDifficulty() { return m_difficulty; } typedef std::list<Player*> PlayerListType; typedef std::list<Group*> GroupListType; @@ -108,8 +110,8 @@ class InstanceSave GroupListType m_groupList; time_t m_resetTime; uint32 m_instanceid; - uint16 m_mapid; - uint8 m_difficulty; + uint32 m_mapid; + Difficulty m_difficulty; bool m_canReset; }; @@ -120,33 +122,44 @@ class MANGOS_DLL_DECL InstanceSaveManager : public MaNGOS::Singleton<InstanceSav InstanceSaveManager(); ~InstanceSaveManager(); - typedef std::map<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveMap; typedef UNORDERED_MAP<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveHashMap; - typedef std::map<uint32 /*mapId*/, InstanceSaveMap> InstanceSaveMapMap; + typedef UNORDERED_MAP<uint32 /*mapId*/, InstanceSaveHashMap> InstanceSaveMapMap; /* resetTime is a global propery of each (raid/heroic) map all instances of that map reset at the same time */ struct InstResetEvent { uint8 type; + Difficulty difficulty:8; uint16 mapid; uint16 instanceId; - InstResetEvent(uint8 t = 0, uint16 m = 0, uint16 i = 0) : type(t), mapid(m), instanceId(i) {} + + InstResetEvent() : type(0), difficulty(DUNGEON_DIFFICULTY_NORMAL), mapid(0), instanceId(0) {} + InstResetEvent(uint8 t, uint32 _mapid, Difficulty d, uint16 _instanceid) + : type(t), difficulty(d), mapid(_mapid), instanceId(_instanceid) {} bool operator == (const InstResetEvent& e) { return e.instanceId == instanceId; } }; typedef std::multimap<time_t /*resetTime*/, InstResetEvent> ResetTimeQueue; - typedef std::vector<time_t /*resetTime*/> ResetTimeVector; + typedef UNORDERED_MAP<uint32 /*PAIR32(map,difficulty)*/,time_t /*resetTime*/> ResetTimeByMapDifficultyMap; void CleanupInstances(); void PackInstances(); void LoadResetTimes(); - time_t GetResetTimeFor(uint32 mapid) { return m_resetTimeByMapId[mapid]; } + time_t GetResetTimeFor(uint32 mapid, Difficulty d) const + { + ResetTimeByMapDifficultyMap::const_iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR32(mapid,d)); + return itr != m_resetTimeByMapDifficulty.end() ? itr->second : 0; + } + void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t) + { + m_resetTimeByMapDifficulty[MAKE_PAIR32(mapid,d)] = t; + } void ScheduleReset(bool add, time_t time, InstResetEvent event); void Update(); - InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, uint8 difficulty, time_t resetTime, bool canReset, bool load = false); + InstanceSave* AddInstanceSave(uint32 mapId, uint32 instanceId, Difficulty difficulty, time_t resetTime, bool canReset, bool load = false); void RemoveInstanceSave(uint32 InstanceId); static void DeleteInstanceFromDB(uint32 instanceid); @@ -158,7 +171,7 @@ class MANGOS_DLL_DECL InstanceSaveManager : public MaNGOS::Singleton<InstanceSav uint32 GetNumBoundGroupsTotal(); private: - void _ResetOrWarnAll(uint32 mapid, bool warn, uint32 timeleft); + void _ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, uint32 timeleft); void _ResetInstance(uint32 mapid, uint32 instanceId); void _ResetSave(InstanceSaveHashMap::iterator &itr); void _DelHelper(DatabaseType &db, const char *fields, const char *table, const char *queryTail,...); @@ -166,11 +179,10 @@ class MANGOS_DLL_DECL InstanceSaveManager : public MaNGOS::Singleton<InstanceSav bool lock_instLists; // fast lookup by instance id InstanceSaveHashMap m_instanceSaveById; - // fast lookup for reset times - ResetTimeVector m_resetTimeByMapId; + // fast lookup for reset times (always use existed functions for access/set) + ResetTimeByMapDifficultyMap m_resetTimeByMapDifficulty; ResetTimeQueue m_resetTimeQueue; }; #define sInstanceSaveManager Trinity::Singleton<InstanceSaveManager>::Instance() #endif - diff --git a/src/game/Item.cpp b/src/game/Item.cpp index f26106cb452..05c1adec795 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -751,15 +751,15 @@ uint32 Item::GetEnchantRequiredLevel() const for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot) if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot))) if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id)) - if (enchantEntry->RequiredLevel > level) - level = enchantEntry->RequiredLevel; + if (enchantEntry->requiredLevel > level) + level = enchantEntry->requiredLevel; return level; } bool Item::IsBoundByEnchant() const { // Check all enchants for soulbound - for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot) + for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot) if (uint32 enchant_id = GetEnchantmentId(EnchantmentSlot(enchant_slot))) if (SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(enchant_id)) if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND) diff --git a/src/game/Item.h b/src/game/Item.h index a26b9148f21..0adf60bb57d 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -328,4 +328,3 @@ class TRINITY_DLL_SPEC Item : public Object bool mb_in_trade; // true if item is currently in trade-window }; #endif - diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index ad9b1a7de4b..f7f7ba9a9a5 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -67,7 +67,7 @@ void WorldSession::HandleSwapInvItemOpcode( WorldPacket & recv_data ) //sLog.outDebug("WORLD: CMSG_SWAP_INV_ITEM"); uint8 srcslot, dstslot; - recv_data >> srcslot >> dstslot; + recv_data >> dstslot >> srcslot; //sLog.outDebug("STORAGE: receive srcslot = %u, dstslot = %u", srcslot, dstslot); // prevent attempt swap same item to current position generated by client at special checting sequence @@ -319,6 +319,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) data << pProto->DisplayInfoID; data << pProto->Quality; data << pProto->Flags; + data << pProto->Faction; // 3.2 faction? data << pProto->BuyPrice; data << pProto->SellPrice; data << pProto->InventoryType; @@ -947,10 +948,10 @@ void WorldSession::HandleSetAmmoOpcode(WorldPacket & recv_data) void WorldSession::SendEnchantmentLog(uint64 Target, uint64 Caster,uint32 ItemID,uint32 SpellID) { WorldPacket data(SMSG_ENCHANTMENTLOG, (8+8+4+4+1)); // last check 2.0.10 - data << Target; - data << Caster; - data << ItemID; - data << SpellID; + data << uint64(Target); + data << uint64(Caster); + data << uint32(ItemID); + data << uint32(SpellID); data << uint8(0); SendPacket(&data); } @@ -1336,3 +1337,27 @@ void WorldSession::HandleCancelTempEnchantmentOpcode(WorldPacket& recv_data) item->ClearEnchantment(TEMP_ENCHANTMENT_SLOT); } +void WorldSession::HandleItemRefundInfoRequest(WorldPacket& recv_data) +{ + sLog.outDebug("WORLD: CMSG_ITEM_REFUND_INFO_REQUEST"); + + uint64 guid; + + recv_data >> guid; // item guid + + Item *item = _player->GetItemByGuid(guid); + + if(!item) + { + sLog.outDebug("Item refund: item not found!"); + return; + } + + if(!item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_REFUNDABLE)) + { + sLog.outDebug("Item refund: item not refundable!"); + return; + } + + // item refund system not implemented yet +} diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index a6daf47cb48..4a2ab112538 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -65,10 +65,13 @@ enum ItemModType ITEM_MOD_SPELL_DAMAGE_DONE = 42, // deprecated ITEM_MOD_MANA_REGENERATION = 43, ITEM_MOD_ARMOR_PENETRATION_RATING = 44, - ITEM_MOD_SPELL_POWER = 45 + ITEM_MOD_SPELL_POWER = 45, + ITEM_MOD_HEALTH_REGEN = 46, + ITEM_MOD_SPELL_PENETRATION = 47, + ITEM_MOD_BLOCK_VALUE = 48 }; -#define MAX_ITEM_MOD 46 +#define MAX_ITEM_MOD 49 enum ItemSpelltriggerType { @@ -108,9 +111,13 @@ enum ITEM_FLAGS ITEM_FLAGS_OPENABLE = 0x00000004, ITEM_FLAGS_WRAPPED = 0x00000008, ITEM_FLAGS_BROKEN = 0x00000010, // appears red icon (like when item durability==0) + ITEM_FLAGS_TOTEM = 0x00000020, // ? + ITEM_FLAGS_USABLE = 0x00000040, // ? ITEM_FLAGS_WRAPPER = 0x00000200, // used or not used wrapper ITEM_FLAGS_PARTY_LOOT = 0x00000800, // determines if item is party loot or not + ITEM_FLAGS_REFUNDABLE = 0x00001000, // item cost can be refunded within 2 hours after purchase ITEM_FLAGS_CHARTER = 0x00002000, // arena/guild charter + ITEM_FLAGS_REFUNDABLE_2 = 0x00008000, ITEM_FLAGS_PROSPECTABLE = 0x00040000, ITEM_FLAGS_UNIQUE_EQUIPPED = 0x00080000, ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000, @@ -118,7 +125,9 @@ enum ITEM_FLAGS ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0 ITEM_FLAGS_BOA = 0x08000000, // bind on account (set in template for items that can binded in like way) ITEM_FLAGS_TRIGGERED_CAST = 0x10000000, // used by enchanting scrolls made with vellum - ITEM_FLAGS_MILLABLE = 0x20000000 + ITEM_FLAGS_ENCHANT_SCROLL = 0x10000000, // for enchant scrolls + ITEM_FLAGS_MILLABLE = 0x20000000, + ITEM_FLAGS_BOP_TRADEABLE = 0x80000000 }; enum BAG_FAMILY_MASK @@ -515,6 +524,7 @@ struct ItemPrototype uint32 DisplayInfoID; // id from ItemDisplayInfo.dbc uint32 Quality; uint32 Flags; + uint32 Faction; uint32 BuyCount; uint32 BuyPrice; uint32 SellPrice; @@ -649,4 +659,3 @@ struct ItemLocale #pragma pack(pop) #endif #endif - |