diff options
Diffstat (limited to 'src/game')
36 files changed, 858 insertions, 546 deletions
diff --git a/src/game/AuctionHouse.cpp b/src/game/AuctionHouse.cpp index ca549f4d404..5526240528b 100644 --- a/src/game/AuctionHouse.cpp +++ b/src/game/AuctionHouse.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 "WorldPacket.h" @@ -89,8 +89,8 @@ bool WorldSession::SendAuctionInfo(WorldPacket & data, AuctionEntry* auction) sLog.outError("auction to item, that doesn't exist !!!!"); return false; } - data << auction->Id; - data << pItem->GetUInt32Value(OBJECT_FIELD_ENTRY); + data << (uint32) auction->Id; + data << (uint32) pItem->GetEntry(); for (uint8 i = 0; i < MAX_INSPECTED_ENCHANTMENT_SLOT; i++) { @@ -245,7 +245,7 @@ void WorldSession::HandleAuctionSellItem( WorldPacket & recv_data ) SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_INTERNAL_ERROR); return; } - // prevent sending bag with items (cheat: can be placed in bag after adding equipped empty bag to auction) + // prevent sending bag with items (cheat: can be placed in bag after adding equiped empty bag to auction) if(!it) { SendAuctionCommandResult(0, AUCTION_SELL_ITEM, AUCTION_ITEM_NOT_FOUND); @@ -716,7 +716,7 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data ) ItemLocale const *il = objmgr.GetItemLocale(proto->ItemId); if (il) { - if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) + if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty()) name = il->Name[loc_idx]; } } diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp index 4b8284c7c37..765d40f3962 100644 --- a/src/game/Bag.cpp +++ b/src/game/Bag.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" @@ -41,7 +41,7 @@ Bag::~Bag() { for(int i = 0; i < MAX_BAG_SIZE; ++i) if (m_bagslot[i]) - delete m_bagslot[i]; + delete m_bagslot[i]; } void Bag::AddToWorld() @@ -71,7 +71,7 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner) Object::_Create( guidlow, 0, HIGHGUID_CONTAINER ); - SetUInt32Value(OBJECT_FIELD_ENTRY, itemid); + SetEntry(itemid); SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0); @@ -85,7 +85,7 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner) // Setting the number of Slots the Container has SetUInt32Value(CONTAINER_FIELD_NUM_SLOTS, itemProto->ContainerSlots); - // Cleanning 20 slots + // Cleaning 20 slots for (uint8 i = 0; i < MAX_BAG_SIZE; i++) { SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0); @@ -213,6 +213,7 @@ uint8 Bag::GetSlotByItemGUID(uint64 guid) const if(m_bagslot[i] != 0) if(m_bagslot[i]->GetGUID() == guid) return i; + return NULL_SLOT; } @@ -220,6 +221,6 @@ Item* Bag::GetItemByPos( uint8 slot ) const { if( slot < GetBagSize() ) return m_bagslot[slot]; - + return NULL; } diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index bff970be3b7..862cfc638ca 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -63,16 +63,44 @@ ChatCommand * ChatHandler::getCommandTable() { NULL, 0, false, NULL, "", NULL } }; + static ChatCommand serverIdleRestartCommandTable[] = + { + { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL }, + { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleRestartCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand serverIdleShutdownCommandTable[] = + { + { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL }, + { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerIdleShutDownCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand serverRestartCommandTable[] = + { + { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL }, + { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerRestartCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + + static ChatCommand serverShutdownCommandTable[] = + { + { "cancel", SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCancelCommand,"", NULL }, + { "" , SEC_ADMINISTRATOR, true, &ChatHandler::HandleServerShutDownCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; + static ChatCommand serverCommandTable[] = { { "corpses", SEC_GAMEMASTER, true, &ChatHandler::HandleServerCorpsesCommand, "", NULL }, { "exit", SEC_CONSOLE, true, &ChatHandler::HandleServerExitCommand, "", NULL }, - { "idlerestart", SEC_ADMINISTRATOR, true, &ChatHandler::HandleIdleRestartCommand, "", NULL }, - { "idleshutdown", SEC_ADMINISTRATOR, true, &ChatHandler::HandleIdleShutDownCommand, "", NULL }, + { "idlerestart", SEC_ADMINISTRATOR, true, NULL, "", serverIdleRestartCommandTable }, + { "idleshutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable }, { "info", SEC_PLAYER, true, &ChatHandler::HandleServerInfoCommand, "", NULL }, { "motd", SEC_PLAYER, true, &ChatHandler::HandleServerMotdCommand, "", NULL }, - { "restart", SEC_ADMINISTRATOR, true, &ChatHandler::HandleRestartCommand, "", NULL }, - { "shutdown", SEC_ADMINISTRATOR, true, &ChatHandler::HandleShutDownCommand, "", NULL }, + { "restart", SEC_ADMINISTRATOR, true, NULL, "", serverRestartCommandTable }, + { "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable }, { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable }, { NULL, 0, false, NULL, "", NULL } }; diff --git a/src/game/Chat.h b/src/game/Chat.h index 0ba253defd9..b62bae39d17 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -175,6 +175,7 @@ class ChatHandler bool HandleModifyHonorCommand (const char* args); bool HandleModifyRepCommand(const char* args); bool HandleModifyArenaCommand(const char* args); + bool HandleModifyGenderCommand(const char* args); bool HandleNpcAddCommand(const char* args); bool HandleNpcAddMoveCommand(const char* args); @@ -191,6 +192,7 @@ class ChatHandler bool HandleNpcSetMoveTypeCommand(const char* args); bool HandleNpcSpawnDistCommand(const char* args); bool HandleNpcSpawnTimeCommand(const char* args); + bool HandleNpcTameCommand(const char* args); bool HandleNpcTextEmoteCommand(const char* args); bool HandleNpcUnFollowCommand(const char* args); bool HandleNpcWhisperCommand(const char* args); @@ -215,6 +217,7 @@ class ChatHandler bool HandleReloadCommandCommand(const char* args); bool HandleReloadCreatureQuestRelationsCommand(const char* args); bool HandleReloadCreatureQuestInvRelationsCommand(const char* args); + bool HandleReloadDbScriptStringCommand(const char* args); bool HandleReloadGameGraveyardZoneCommand(const char* args); bool HandleReloadGameObjectScriptsCommand(const char* args); bool HandleReloadGameTeleCommand(const char* args); @@ -270,10 +273,15 @@ class ChatHandler bool HandleServerCorpsesCommand(const char* args); bool HandleServerExitCommand(const char* args); + bool HandleServerIdleRestartCommand(const char* args); + bool HandleServerIdleShutDownCommand(const char* args); bool HandleServerInfoCommand(const char* args); bool HandleServerMotdCommand(const char* args); + bool HandleServerRestartCommand(const char* args); bool HandleServerSetMotdCommand(const char* args); bool HandleServerSetLogLevelCommand(const char* args); + bool HandleServerShutDownCommand(const char* args); + bool HandleServerShutDownCancelCommand(const char* args); bool HandleAddHonorCommand(const char* args); bool HandleHonorAddKillCommand(const char* args); @@ -327,11 +335,6 @@ class ChatHandler bool HandleBanListAccountCommand(const char* args); bool HandleBanListCharacterCommand(const char* args); bool HandleBanListIPCommand(const char* args); - bool HandleIdleRestartCommand(const char* args); - bool HandleIdleShutDownCommand(const char* args); - bool HandleShutDownCommand(const char* args); - bool HandleRestartCommand(const char* args); - bool HandleSecurityCommand(const char* args); bool HandleGoXYCommand(const char* args); bool HandleGoXYZCommand(const char* args); bool HandleGoZoneXYCommand(const char* args); @@ -365,7 +368,6 @@ class ChatHandler bool HandleHideAreaCommand(const char* args); bool HandleAddItemCommand(const char* args); bool HandleAddItemSetCommand(const char* args); - bool HandleModifyGenderCommand(const char* args); bool HandlePetTpCommand(const char* args); bool HandlePetUnlearnCommand(const char* args); bool HandlePetLearnCommand(const char* args); diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 5e3d3ac9f8e..8a58deb7f91 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -177,7 +177,7 @@ void Creature::RemoveCorpse() float x,y,z,o; GetRespawnCoord(x, y, z, &o); - MapManager::Instance().GetMap(GetMapId(), this)->CreatureRelocation(this,x,y,z,o); + GetMap()->CreatureRelocation(this,x,y,z,o); } /** @@ -209,7 +209,7 @@ bool Creature::InitEntry(uint32 Entry, uint32 team, const CreatureData *data ) } } - SetUInt32Value(OBJECT_FIELD_ENTRY, Entry); // normal entry always + SetEntry(Entry); // normal entry always m_creatureInfo = cinfo; // map mode related always // Cancel load if no model defined @@ -352,7 +352,7 @@ void Creature::Update(uint32 diff) lootForPickPocketed = false; lootForBody = false; - if(m_originalEntry != GetUInt32Value(OBJECT_FIELD_ENTRY)) + if(m_originalEntry != GetEntry()) UpdateEntry(m_originalEntry); CreatureInfo const *cinfo = GetCreatureInfo(); @@ -371,9 +371,9 @@ void Creature::Update(uint32 diff) setDeathState( JUST_ALIVED ); //Call AI respawn virtual function - AI()->JustRespawned(); + i_AI->JustRespawned(); - MapManager::Instance().GetMap(GetMapId(), this)->Add(this); + GetMap()->Add(this); } break; } @@ -435,7 +435,7 @@ void Creature::Update(uint32 diff) { // do not allow the AI to be changed during update m_AI_locked = true; - AI()->UpdateAI(diff); + i_AI->UpdateAI(diff); m_AI_locked = false; } @@ -2096,9 +2096,14 @@ uint32 Creature::getLevelForTarget( Unit const* target ) const return level; } -char const* Creature::GetScriptName() const +std::string Creature::GetScriptName() { - return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptName; + return objmgr.GetScriptName(GetScriptId()); +} + +uint32 Creature::GetScriptId() +{ + return ObjectMgr::GetCreatureTemplate(GetEntry())->ScriptID; } VendorItemData const* Creature::GetVendorItems() const diff --git a/src/game/Creature.h b/src/game/Creature.h index be421f26ad2..d5b6b23a025 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -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 */ #ifndef TRINITYCORE_CREATURE_H @@ -205,10 +205,11 @@ struct CreatureInfo uint32 equipmentId; uint32 MechanicImmuneMask; uint32 flags_extra; - char const* ScriptName; + uint32 ScriptID; uint32 GetRandomValidModelId() const; uint32 GetFirstValidModelId() const; - + + // helpers SkillType GetRequiredLootSkill() const { if(type_flags & CREATURE_TYPEFLAGS_HERBLOOT) @@ -218,7 +219,7 @@ struct CreatureInfo else return SKILL_SKINNING; // normal case } - + bool isTameable() const { return type == CREATURE_TYPE_BEAST && family != 0 && (type_flags & CREATURE_TYPEFLAGS_TAMEBLE); @@ -498,7 +499,9 @@ class TRINITY_DLL_SPEC Creature : public Unit CreatureInfo const *GetCreatureInfo() const { return m_creatureInfo; } CreatureDataAddon const* GetCreatureAddon() const; - char const* GetScriptName() const; + + std::string GetScriptName(); + uint32 GetScriptId(); void prepareGossipMenu( Player *pPlayer, uint32 gossipid = 0 ); void sendPreparedGossip( Player* player ); @@ -524,7 +527,7 @@ class TRINITY_DLL_SPEC Creature : public Unit // overwrite WorldObject function for proper name localization const char* GetNameForLocaleIdx(int32 locale_idx) const; - + void setDeathState(DeathState s); // overwrite virtual Unit::setDeathState bool LoadFromDB(uint32 guid, Map *map); diff --git a/src/game/CreatureAI.cpp b/src/game/CreatureAI.cpp index 3cb8db202fa..ad663d13b38 100644 --- a/src/game/CreatureAI.cpp +++ b/src/game/CreatureAI.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 "CreatureAI.h" diff --git a/src/game/CreatureAIImpl.h b/src/game/CreatureAIImpl.h index 877ed885152..76ba93a3cb5 100644 --- a/src/game/CreatureAIImpl.h +++ b/src/game/CreatureAIImpl.h @@ -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 */ #ifndef CREATUREAIIMPL_H #define CREATUREAIIMPL_H diff --git a/src/game/CreatureAIRegistry.cpp b/src/game/CreatureAIRegistry.cpp index 7219f71cd81..a4ee030c34e 100644 --- a/src/game/CreatureAIRegistry.cpp +++ b/src/game/CreatureAIRegistry.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 "CreatureAIRegistry.h" diff --git a/src/game/CreatureAISelector.cpp b/src/game/CreatureAISelector.cpp index 2e0d297305c..5e15efafe6f 100644 --- a/src/game/CreatureAISelector.cpp +++ b/src/game/CreatureAISelector.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 "Creature.h" diff --git a/src/game/Formulas.h b/src/game/Formulas.h index cef4fab9c7b..f9915a2001c 100644 --- a/src/game/Formulas.h +++ b/src/game/Formulas.h @@ -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 */ #ifndef TRINITY_FORMULAS_H @@ -29,7 +29,7 @@ namespace Trinity { inline uint32 hk_honor_at_level(uint32 level, uint32 count=1) { - return (uint32) ceil(count*(-0.53177f + 0.59357f * exp((level +23.54042f) / 26.07859f ))); + return (uint32)ceil(count*(-0.53177f + 0.59357f * exp((level +23.54042f) / 26.07859f ))); } } namespace XP @@ -80,6 +80,7 @@ namespace Trinity inline uint32 BaseGain(uint32 pl_level, uint32 mob_level, ContentLevels content) { + //TODO: need modifier for CONTENT_71_80 different from CONTENT_61_70? const uint32 nBaseExp = content == CONTENT_1_60 ? 45 : 235; if( mob_level >= pl_level ) { diff --git a/src/game/GMTicketHandler.cpp b/src/game/GMTicketHandler.cpp index 6d005c2806a..448730bd3ea 100644 --- a/src/game/GMTicketHandler.cpp +++ b/src/game/GMTicketHandler.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" @@ -66,8 +66,6 @@ void WorldSession::HandleGMTicketUpdateTextOpcode( WorldPacket & recv_data ) std::string ticketText; recv_data >> ticketText; - CharacterDatabase.escape_string(ticketText); - if(GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow())) ticket->SetText(ticketText.c_str()); else @@ -105,9 +103,7 @@ void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data ) sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2); - CharacterDatabase.escape_string(ticketText); - - if(GMTicket* ticket = ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow())) + if(ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow())) { WorldPacket data( SMSG_GMTICKET_CREATE, 4 ); data << uint32(1); diff --git a/src/game/GMTicketMgr.h b/src/game/GMTicketMgr.h index a7b7a02ea17..1fd4e4c3a8f 100644 --- a/src/game/GMTicketMgr.h +++ b/src/game/GMTicketMgr.h @@ -50,7 +50,10 @@ class GMTicket { m_text = text ? text : ""; m_lastUpdate = time(NULL); - CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", m_text.c_str(), m_guid); + + std::string escapedString = m_text; + CharacterDatabase.escape_string(escapedString); + CharacterDatabase.PExecute("UPDATE character_ticket SET ticket_text = '%s' WHERE guid = '%u'", escapedString.c_str(), m_guid); } void DeleteFromDB() const @@ -62,7 +65,11 @@ class GMTicket { CharacterDatabase.BeginTransaction(); DeleteFromDB(); - CharacterDatabase.PExecute("INSERT INTO character_ticket (guid, ticket_text) VALUES ('%u', '%s')", m_guid, GetText()); + + std::string escapedString = m_text; + CharacterDatabase.escape_string(escapedString); + + CharacterDatabase.PExecute("INSERT INTO character_ticket (guid, ticket_text) VALUES ('%u', '%s')", m_guid, escapedString.c_str()); CharacterDatabase.CommitTransaction(); } private: @@ -115,4 +122,4 @@ class GMTicketMgr }; #define ticketmgr Trinity::Singleton<GMTicketMgr>::Instance() -#endif
\ No newline at end of file +#endif diff --git a/src/game/GameObject.h b/src/game/GameObject.h index 7dc5a879913..afeaba98cc9 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -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 */ #ifndef TRINITYCORE_GAMEOBJECT_H @@ -357,7 +357,7 @@ struct GameObjectInfo uint32 data[24]; } raw; }; - char *ScriptName; + uint32 ScriptId; }; struct GameObjectLocale diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 2c4ebfb0a3e..0c264a76d8b 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.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" @@ -179,7 +179,7 @@ bool ItemCanGoIntoBag(ItemPrototype const *pProto, ItemPrototype const *pBagProt case ITEM_SUBCLASS_CONTAINER: return true; case ITEM_SUBCLASS_SOUL_CONTAINER: - if(!(pProto->BagFamily & BAG_FAMILY_MASK_SHARDS)) + if(!(pProto->BagFamily & BAG_FAMILY_MASK_SOUL_SHARDS)) return false; return true; case ITEM_SUBCLASS_HERB_CONTAINER: @@ -247,7 +247,7 @@ bool Item::Create( uint32 guidlow, uint32 itemid, Player const* owner) { Object::_Create( guidlow, 0, HIGHGUID_ITEM ); - SetUInt32Value(OBJECT_FIELD_ENTRY, itemid); + SetEntry(itemid); SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f); SetUInt64Value(ITEM_FIELD_OWNER, owner ? owner->GetGUID() : 0); @@ -429,7 +429,7 @@ void Item::DeleteFromInventoryDB() ItemPrototype const *Item::GetProto() const { - return objmgr.GetItemPrototype(GetUInt32Value(OBJECT_FIELD_ENTRY)); + return objmgr.GetItemPrototype(GetEntry()); } Player* Item::GetOwner()const @@ -762,9 +762,7 @@ bool Item::IsFitToSpellRequirements(SpellEntry const* spellInfo) const void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges) { // Better lost small time at check in comparison lost time at item save to DB. - if( GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET)==id && - GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET)==duration && - GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET)==charges ) + if((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges)) return; SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id); @@ -775,7 +773,7 @@ void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration) { - if(GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET)==duration) + if(GetEnchantmentDuration(slot) == duration) return; SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); @@ -784,17 +782,20 @@ void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration) void Item::SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges) { + if(GetEnchantmentCharges(slot) == charges) + return; + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); SetState(ITEM_CHANGED); } void Item::ClearEnchantment(EnchantmentSlot slot) { - if(!GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET)) + if(!GetEnchantmentId(slot)) return; - for(int x=0;x<3;x++) - SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x,0); + for(uint8 x = 0; x < 3; ++x) + SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x, 0); SetState(ITEM_CHANGED); } diff --git a/src/game/Item.h b/src/game/Item.h index 7b265b9cbf2..72c09b0c1da 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -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 */ #ifndef TRINITYCORE_ITEM_H @@ -228,7 +228,6 @@ class TRINITY_DLL_SPEC Item : public Object bool IsLimitedToAnotherMapOrZone( uint32 cur_mapId, uint32 cur_zoneId) const; bool GemsFitSockets() const; - uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); } uint32 GetCount() const { return GetUInt32Value (ITEM_FIELD_STACK_COUNT); } void SetCount(uint32 value) { SetUInt32Value (ITEM_FIELD_STACK_COUNT, value); } uint32 GetMaxStackCount() const { return GetProto()->Stackable; } diff --git a/src/game/ItemEnchantmentMgr.cpp b/src/game/ItemEnchantmentMgr.cpp index 6d4197b0335..52a2e5dc1eb 100644 --- a/src/game/ItemEnchantmentMgr.cpp +++ b/src/game/ItemEnchantmentMgr.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 <stdlib.h> diff --git a/src/game/ItemEnchantmentMgr.h b/src/game/ItemEnchantmentMgr.h index a6b84c17418..97053c1ec36 100644 --- a/src/game/ItemEnchantmentMgr.h +++ b/src/game/ItemEnchantmentMgr.h @@ -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 */ #ifndef _ITEM_ENCHANTMENT_MGR_H diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index 5f9daa44336..c074ac98d77 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.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" @@ -313,9 +313,9 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId); if (il) { - if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) + if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty()) Name = il->Name[loc_idx]; - if (il->Description.size() > loc_idx && !il->Description[loc_idx].empty()) + if (il->Description.size() > size_t(loc_idx) && !il->Description[loc_idx].empty()) Description = il->Description[loc_idx]; } } @@ -360,6 +360,8 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) data << pProto->Damage[i].DamageMax; data << pProto->Damage[i].DamageType; } + + // resistances (7) data << pProto->Armor; data << pProto->HolyRes; data << pProto->FireRes; @@ -367,10 +369,11 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data ) data << pProto->FrostRes; data << pProto->ShadowRes; data << pProto->ArcaneRes; + data << pProto->Delay; data << pProto->Ammo_type; + data << pProto->RangedModRange; - data << (float)pProto->RangedModRange; for(int s = 0; s < 5; s++) { // send DBC data for cooldowns in same way as it used in Spell::SendSpellCooldown @@ -976,7 +979,7 @@ void WorldSession::HandleItemNameQueryOpcode(WorldPacket & recv_data) ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId); if (il) { - if (il->Name.size() > loc_idx && !il->Name[loc_idx].empty()) + if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty()) Name = il->Name[loc_idx]; } } @@ -1027,7 +1030,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) return; } - if(item==gift) // not possible with pacjket from real client + if(item==gift) // not possable with pacjket from real client { _player->SendEquipError( EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL ); return; @@ -1072,16 +1075,16 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) CharacterDatabase.BeginTransaction(); CharacterDatabase.PExecute("INSERT INTO character_gifts VALUES ('%u', '%u', '%u', '%u')", GUID_LOPART(item->GetOwnerGUID()), item->GetGUIDLow(), item->GetEntry(), item->GetUInt32Value(ITEM_FIELD_FLAGS)); - item->SetUInt32Value(OBJECT_FIELD_ENTRY, gift->GetUInt32Value(OBJECT_FIELD_ENTRY)); + item->SetEntry(gift->GetEntry()); switch (item->GetEntry()) { - case 5042: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 5043); break; - case 5048: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 5044); break; - case 17303: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 17302); break; - case 17304: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 17305); break; - case 17307: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 17308); break; - case 21830: item->SetUInt32Value(OBJECT_FIELD_ENTRY, 21831); break; + case 5042: item->SetEntry( 5043); break; + case 5048: item->SetEntry( 5044); break; + case 17303: item->SetEntry(17302); break; + case 17304: item->SetEntry(17305); break; + case 17307: item->SetEntry(17308); break; + case 21830: item->SetEntry(21831); break; } item->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, _player->GetGUID()); item->SetUInt32Value(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED); diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index 4762bf1e26a..8a90ad49adb 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -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 */ #ifndef _ITEMPROTOTYPE_H @@ -99,16 +99,18 @@ enum ITEM_FLAGS ITEM_FLAGS_UNIQUE_EQUIPPED = 0x00080000, ITEM_FLAGS_USEABLE_IN_ARENA = 0x00200000, ITEM_FLAGS_THROWABLE = 0x00400000, // not used in game for check trow possibility, only for item in game tooltip - ITEM_FLAGS_SPECIALUSE = 0x00800000 // last used flag in 2.3.0 + ITEM_FLAGS_SPECIALUSE = 0x00800000, // last used flag in 2.3.0 + ITEM_FLAGS_BOA = 0x08000000, // bind on account + ITEM_FLAGS_MILLABLE = 0x20000000 }; enum BAG_FAMILY_MASK { BAG_FAMILY_MASK_ARROWS = 0x00000001, BAG_FAMILY_MASK_BULLETS = 0x00000002, - BAG_FAMILY_MASK_SHARDS = 0x00000004, + BAG_FAMILY_MASK_SOUL_SHARDS = 0x00000004, BAG_FAMILY_MASK_LEATHERWORKING_SUPP = 0x00000008, - BAG_FAMILY_MASK_UNUSED = 0x00000010, // not used currently + BAG_FAMILY_MASK_INSCRIPTION_SUPP = 0x00000010, BAG_FAMILY_MASK_HERBS = 0x00000020, BAG_FAMILY_MASK_ENCHANTING_SUPP = 0x00000040, BAG_FAMILY_MASK_ENGINEERING_SUPP = 0x00000080, @@ -116,13 +118,11 @@ enum BAG_FAMILY_MASK BAG_FAMILY_MASK_GEMS = 0x00000200, BAG_FAMILY_MASK_MINING_SUPP = 0x00000400, BAG_FAMILY_MASK_SOULBOUND_EQUIPMENT = 0x00000800, - BAG_FAMILY_MASK_VANITY_PETS = 0x00001000 + BAG_FAMILY_MASK_VANITY_PETS = 0x00001000, + BAG_FAMILY_MASK_CURRENCY_TOKENS = 0x00002000, + BAG_FAMILY_MASK_QUEST_ITEMS = 0x00004000 }; -/* TODO: Not entirely positive on need for this?? -enum SOCKET_CONTENT (); -*/ - enum SocketColor { SOCKET_COLOR_META = 1, @@ -275,7 +275,7 @@ enum ItemSubclassArmor ITEM_SUBCLASS_ARMOR_TOTEM = 9 }; -#define MAX_ITEM_SUBCLASS_ARMOR 10 +#define MAX_ITEM_SUBCLASS_ARMOR 10 enum ItemSubclassReagent { @@ -390,6 +390,22 @@ enum ItemSubclassJunk #define MAX_ITEM_SUBCLASS_JUNK 6 +enum ItemSubclassGlyph +{ + ITEM_SUBCLASS_GLYPH_WARRIOR = 1, + ITEM_SUBCLASS_GLYPH_PALADIN = 2, + ITEM_SUBCLASS_GLYPH_HUNTER = 3, + ITEM_SUBCLASS_GLYPH_ROGUE = 4, + ITEM_SUBCLASS_GLYPH_PRIEST = 5, + ITEM_SUBCLASS_GLYPH_DEATH_KNIGHT = 6, + ITEM_SUBCLASS_GLYPH_SHAMAN = 7, + ITEM_SUBCLASS_GLYPH_MAGE = 8, + ITEM_SUBCLASS_GLYPH_WARLOCK = 9, + ITEM_SUBCLASS_GLYPH_DRUID = 11 +}; + +#define MAX_ITEM_SUBCLASS_GLYPH 12 + const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] = { MAX_ITEM_SUBCLASS_CONSUMABLE, @@ -524,7 +540,7 @@ struct ItemPrototype uint32 GemProperties; // id from GemProperties.dbc uint32 RequiredDisenchantSkill; float ArmorDamageModifier; - char* ScriptName; + uint32 ScriptId; uint32 DisenchantID; uint32 FoodType; uint32 MinMoneyLoot; diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 643a5b6f819..bb6a4473e0b 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -2361,8 +2361,8 @@ bool ChatHandler::HandleWpModifyCommand(const char* args) std::string show = show_str; // Check // Remember: "show" must also be the name of a column! - if( (show != "emote") && (show != "spell") && (show != "text1") && (show != "text2") - && (show != "text3") && (show != "text4") && (show != "text5") + if( (show != "emote") && (show != "spell") && (show != "textid1") && (show != "textid2") + && (show != "textid3") && (show != "textid4") && (show != "textid5") && (show != "waittime") && (show != "del") && (show != "move") && (show != "add") && (show != "model1") && (show != "model2") && (show != "orientation")) { @@ -2705,6 +2705,13 @@ bool ChatHandler::HandleWpModifyCommand(const char* args) return false; } + // set in game textids not supported + if( show == "textid1" || show == "textid2" || show == "textid3" || + show == "textid4" || show == "textid5" ) + { + return false; + } + WaypointMgr.SetNodeText(lowguid, point, show_str, arg_str); Creature* npcCreature = ObjectAccessor::GetCreature(*m_session->GetPlayer(), MAKE_NEW_GUID(lowguid, data->id, HIGHGUID_UNIT)); @@ -2842,7 +2849,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args) //pCreature->GetPositionX(); QueryResult *result = - WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE wpguid = %u", + WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE wpguid = %u", target->GetGUIDLow() ); if(!result) { @@ -2854,7 +2861,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args) const char* maxDIFF = "0.01"; PSendSysMessage(LANG_WAYPOINT_NOTFOUNDSEARCH, target->GetGUID()); - result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, text1, text2, text3, text4, text5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )", + result = WorldDatabase.PQuery( "SELECT id, point, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, model1, model2 FROM creature_movement WHERE (abs(position_x - %f) <= %s ) and (abs(position_y - %f) <= %s ) and (abs(position_z - %f) <= %s )", target->GetPositionX(), maxDIFF, target->GetPositionY(), maxDIFF, target->GetPositionZ(), maxDIFF); if(!result) { @@ -2871,11 +2878,9 @@ bool ChatHandler::HandleWpShowCommand(const char* args) int waittime = fields[2].GetUInt32(); uint32 emote = fields[3].GetUInt32(); uint32 spell = fields[4].GetUInt32(); - const char * text1 = fields[5].GetString(); - const char * text2 = fields[6].GetString(); - const char * text3 = fields[7].GetString(); - const char * text4 = fields[8].GetString(); - const char * text5 = fields[9].GetString(); + uint32 textid[MAX_WAYPOINT_TEXT]; + for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i) + textid[i] = fields[5+i].GetUInt32(); uint32 model1 = fields[10].GetUInt32(); uint32 model2 = fields[11].GetUInt32(); @@ -2888,11 +2893,8 @@ bool ChatHandler::HandleWpShowCommand(const char* args) PSendSysMessage(LANG_WAYPOINT_INFO_MODEL, 2, model2); PSendSysMessage(LANG_WAYPOINT_INFO_EMOTE, emote); PSendSysMessage(LANG_WAYPOINT_INFO_SPELL, spell); - PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 1, text1); - PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 2, text2); - PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 3, text3); - PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 4, text4); - PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, 5, text5); + for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i) + PSendSysMessage(LANG_WAYPOINT_INFO_TEXT, i+1, textid[i], (textid[i] ? GetTrinityString(textid[i]) : "")); }while( result->NextRow() ); // Cleanup memory @@ -3213,8 +3215,8 @@ bool ChatHandler::HandleWpExportCommand(const char *args) PSendSysMessage("DEBUG: wp export, GUID: %u", lowguid); QueryResult *result = WorldDatabase.PQuery( - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid ); + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + "SELECT point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id FROM creature_movement WHERE id = '%u' ORDER BY point", lowguid ); if (!result) { @@ -3231,7 +3233,7 @@ bool ChatHandler::HandleWpExportCommand(const char *args) Field *fields = result->Fetch(); outfile << "INSERT INTO creature_movement "; - outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5 ) VALUES "; + outfile << "( id, point, position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5 ) VALUES "; outfile << "( "; outfile << fields[15].GetUInt32(); // id @@ -3256,65 +3258,15 @@ bool ChatHandler::HandleWpExportCommand(const char *args) outfile << ", "; outfile << fields[9].GetUInt32(); // spell outfile << ", "; - const char *tmpChar = fields[10].GetString(); - if( !tmpChar ) - { - outfile << "NULL"; // text1 - } - else - { - outfile << "'"; - outfile << tmpChar; // text1 - outfile << "'"; - } + outfile << fields[10].GetUInt32(); // textid1 outfile << ", "; - tmpChar = fields[11].GetString(); - if( !tmpChar ) - { - outfile << "NULL"; // text2 - } - else - { - outfile << "'"; - outfile << tmpChar; // text2 - outfile << "'"; - } + outfile << fields[11].GetUInt32(); // textid2 outfile << ", "; - tmpChar = fields[12].GetString(); - if( !tmpChar ) - { - outfile << "NULL"; // text3 - } - else - { - outfile << "'"; - outfile << tmpChar; // text3 - outfile << "'"; - } + outfile << fields[12].GetUInt32(); // textid3 outfile << ", "; - tmpChar = fields[13].GetString(); - if( !tmpChar ) - { - outfile << "NULL"; // text4 - } - else - { - outfile << "'"; - outfile << tmpChar; // text4 - outfile << "'"; - } + outfile << fields[13].GetUInt32(); // textid4 outfile << ", "; - tmpChar = fields[14].GetString(); - if( !tmpChar ) - { - outfile << "NULL"; // text5 - } - else - { - outfile << "'"; - outfile << tmpChar; // text5 - outfile << "'"; - } + outfile << fields[14].GetUInt32(); // textid5 outfile << ");\n "; } while( result->NextRow() ); diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index a2f68a4ce58..1fb799cde6b 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -135,6 +135,7 @@ bool ChatHandler::HandleReloadAllScriptsCommand(const char*) HandleReloadQuestStartScriptsCommand("a"); HandleReloadSpellScriptsCommand("a"); SendGlobalSysMessage("DB tables `*_scripts` reloaded."); + HandleReloadDbScriptStringCommand("a"); return true; } @@ -601,6 +602,14 @@ bool ChatHandler::HandleReloadSpellScriptsCommand(const char* arg) return true; } +bool ChatHandler::HandleReloadDbScriptStringCommand(const char* arg) +{ + sLog.outString( "Re-Loading Script strings from `db_script_string`..."); + objmgr.LoadDbScriptStrings(); + SendGlobalSysMessage("DB table `db_script_string` reloaded."); + return true; +} + bool ChatHandler::HandleReloadGameGraveyardZoneCommand(const char* /*arg*/) { sLog.outString( "Re-Loading Graveyard-zone links..."); @@ -1767,7 +1776,8 @@ bool ChatHandler::HandleLearnAllMyTalentsCommand(const char* /*args*/) // search highest talent rank uint32 spellid = 0; - for(int rank = 4; rank >= 0; --rank) + int rank = 4; + for(; rank >= 0; --rank) { if(talentInfo->RankID[rank]!=0) { @@ -4645,91 +4655,149 @@ bool ChatHandler::HandleResetAllCommand(const char * args) return true; } -bool ChatHandler::HandleShutDownCommand(const char* args) +bool ChatHandler::HandleServerShutDownCancelCommand(const char* args) +{ + sWorld.ShutdownCancel(); + return true; +} + +bool ChatHandler::HandleServerShutDownCommand(const char* args) { if(!*args) return false; - if(std::string(args)=="cancel") - { - sWorld.ShutdownCancel(); - } - else + char* time_str = strtok ((char*) args, " "); + char* exitcode_str = strtok (NULL, ""); + + int32 time = atoi (time_str); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) + return false; + + if (exitcode_str) { - int32 time = atoi(args); + int32 exitcode = atoi (exitcode_str); - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0) + // Handle atoi() errors + if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) return false; - sWorld.ShutdownServ(time); + // Exit code should be in range of 0-125, 126-255 is used + // in many shells for their own return codes and code > 255 + // is not supported in many others + if (exitcode < 0 || exitcode > 125) + return false; + + sWorld.ShutdownServ (time, 0, exitcode); } + else + sWorld.ShutdownServ(time,0,SHUTDOWN_EXIT_CODE); return true; } -bool ChatHandler::HandleRestartCommand(const char* args) +bool ChatHandler::HandleServerRestartCommand(const char* args) { if(!*args) return false; - if(std::string(args)=="cancel") - { - sWorld.ShutdownCancel(); - } - else + char* time_str = strtok ((char*) args, " "); + char* exitcode_str = strtok (NULL, ""); + + int32 time = atoi (time_str); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) + return false; + + if (exitcode_str) { - int32 time = atoi(args); + int32 exitcode = atoi (exitcode_str); + + // Handle atoi() errors + if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) + return false; - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0) + // Exit code should be in range of 0-125, 126-255 is used + // in many shells for their own return codes and code > 255 + // is not supported in many others + if (exitcode < 0 || exitcode > 125) return false; - sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART); + sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART, exitcode); } + else + sWorld.ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE); return true; } -bool ChatHandler::HandleIdleRestartCommand(const char* args) +bool ChatHandler::HandleServerIdleRestartCommand(const char* args) { if(!*args) return false; - if(std::string(args)=="cancel") - { - sWorld.ShutdownCancel(); - } - else + char* time_str = strtok ((char*) args, " "); + char* exitcode_str = strtok (NULL, ""); + + int32 time = atoi (time_str); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) + return false; + + if (exitcode_str) { - int32 time = atoi(args); + int32 exitcode = atoi (exitcode_str); + + // Handle atoi() errors + if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) + return false; - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0) + // Exit code should be in range of 0-125, 126-255 is used + // in many shells for their own return codes and code > 255 + // is not supported in many others + if (exitcode < 0 || exitcode > 125) return false; - sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART+SHUTDOWN_MASK_IDLE); + sWorld.ShutdownServ (time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode); } + else + sWorld.ShutdownServ(time,SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE,RESTART_EXIT_CODE); return true; } -bool ChatHandler::HandleIdleShutDownCommand(const char* args) +bool ChatHandler::HandleServerIdleShutDownCommand(const char* args) { if(!*args) return false; - if(std::string(args)=="cancel") - { - sWorld.ShutdownCancel(); - } - else + char* time_str = strtok ((char*) args, " "); + char* exitcode_str = strtok (NULL, ""); + + int32 time = atoi (time_str); + + ///- Prevent interpret wrong arg value as 0 secs shutdown time + if(time == 0 && (time_str[0]!='0' || time_str[1]!='\0') || time < 0) + return false; + + if (exitcode_str) { - int32 time = atoi(args); + int32 exitcode = atoi (exitcode_str); - ///- Prevent interpret wrong arg value as 0 secs shutdown time - if(time == 0 && (args[0]!='0' || args[1]!='\0') || time < 0) + // Handle atoi() errors + if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0')) return false; - sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE); + // Exit code should be in range of 0-125, 126-255 is used + // in many shells for their own return codes and code > 255 + // is not supported in many others + if (exitcode < 0 || exitcode > 125) + return false; + + sWorld.ShutdownServ (time, SHUTDOWN_MASK_IDLE, exitcode); } + else + sWorld.ShutdownServ(time,SHUTDOWN_MASK_IDLE,SHUTDOWN_EXIT_CODE); return true; } diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp index d91206bf6d9..6605cc78057 100644 --- a/src/game/Mail.cpp +++ b/src/game/Mail.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 "Mail.h" @@ -187,18 +187,17 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data ) pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR); return; } - if (mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_CONJURED) || mailItem.item->GetUInt32Value(ITEM_FIELD_DURATION)) { pl->SendMailResult(0, 0, MAIL_ERR_INTERNAL_ERROR); return; } - if(COD && mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED)) - { - pl->SendMailResult(0, 0, MAIL_ERR_CANT_SEND_WRAPPED_COD); - return; - } + if(COD && mailItem.item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED)) + { + pl->SendMailResult(0, 0, MAIL_ERR_CANT_SEND_WRAPPED_COD); + return; + } } } pl->SendMailResult(0, 0, MAIL_OK); diff --git a/src/game/Map.cpp b/src/game/Map.cpp index ba72775b5cf..3804560b662 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -1713,7 +1713,7 @@ void InstanceMap::CreateInstanceData(bool load) InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(GetId()); if (mInstance) { - i_script = mInstance->script; + i_script_id = mInstance->script_id; i_data = Script->CreateInstanceData(this); } @@ -1730,7 +1730,7 @@ void InstanceMap::CreateInstanceData(bool load) const char* data = fields[0].GetString(); if(data) { - sLog.outDebug("Loading instance data for `%s` with id %u", i_script.c_str(), i_InstanceId); + sLog.outDebug("Loading instance data for `%s` with id %u", objmgr.GetScriptName(i_script_id), i_InstanceId); i_data->Load(data); } delete result; @@ -1738,7 +1738,7 @@ void InstanceMap::CreateInstanceData(bool load) } else { - sLog.outDebug("New instance data, \"%s\" ,initialized!",i_script.c_str()); + sLog.outDebug("New instance data, \"%s\" ,initialized!", objmgr.GetScriptName(i_script_id)); i_data->Initialize(); } } diff --git a/src/game/Map.h b/src/game/Map.h index 1765d6d09fa..6e0e9cb37a9 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -105,7 +105,7 @@ struct InstanceTemplate float startLocY; float startLocZ; float startLocO; - char const* script; + uint32 script_id; }; enum LevelRequirementVsMode @@ -343,7 +343,7 @@ class TRINITY_DLL_SPEC InstanceMap : public Map void Update(const uint32&); void CreateInstanceData(bool load); bool Reset(uint8 method); - std::string GetScript() { return i_script; } + uint32 GetScriptId() { return i_script_id; } InstanceData* GetInstanceData() { return i_data; } void PermBindAllPlayers(Player *player); time_t GetResetTime(); @@ -355,10 +355,7 @@ class TRINITY_DLL_SPEC InstanceMap : public Map bool m_resetAfterUnload; bool m_unloadWhenEmpty; InstanceData* i_data; - std::string i_script; - // only online players that are inside the instance currently - // TODO ? - use the grid instead to access the players - PlayerList i_Players; + uint32 i_script_id; }; class TRINITY_DLL_SPEC BattleGroundMap : public Map diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 34aefdff074..26279cb76ec 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -222,7 +222,7 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player) return true; } -void MapManager::DeleteInstance(uint32 mapid, uint32 instanceId, uint8 mode) +void MapManager::DeleteInstance(uint32 mapid, uint32 instanceId) { Map *m = _GetBaseMap(mapid); if (m && m->Instanceable()) diff --git a/src/game/MapManager.h b/src/game/MapManager.h index 44197ccd84a..cba0a86d1a5 100644 --- a/src/game/MapManager.h +++ b/src/game/MapManager.h @@ -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 */ #ifndef TRINITY_MAPMANAGER_H @@ -27,6 +27,7 @@ #include "Common.h" #include "Map.h" #include "GridStates.h" + class Transport; class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinity::ClassLevelLockable<MapManager, ZThread::Mutex> > @@ -44,7 +45,7 @@ class TRINITY_DLL_DECL MapManager : public Trinity::Singleton<MapManager, Trinit // only const version for outer users Map const* GetBaseMap(uint32 id) const { return const_cast<MapManager*>(this)->_GetBaseMap(id); } - void DeleteInstance(uint32 mapid, uint32 instanceId, uint8 mode); + void DeleteInstance(uint32 mapid, uint32 instanceId); inline uint16 GetAreaFlag(uint32 mapid, float x, float y) const { diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 43d867d779d..751a3ca4fbc 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -10,17 +10,18 @@ * * 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" #include "Database/DatabaseEnv.h" #include "Database/SQLStorage.h" +#include "Database/SQLStorageImpl.h" #include "Log.h" #include "MapManager.h" @@ -116,8 +117,12 @@ ObjectMgr::ObjectMgr() m_hiGoGuid = 1; m_hiDoGuid = 1; m_hiCorpseGuid = 1; - m_hiPetNumber = 1; + m_ItemTextId = 1; + m_mailid = 1; + m_auctionid = 1; + m_guildId = 1; + m_arenaTeamId = 1; mGuildBankTabPrice.resize(GUILD_BANK_MAX_TABS); mGuildBankTabPrice[0] = 100; @@ -415,7 +420,7 @@ void ObjectMgr::SendAuctionWonMail( AuctionEntry *auction ) sLog.outDebug( "AuctionWon body string : %s", msgAuctionWonBody.str().c_str() ); //prepare mail data... : - uint32 itemTextId = this->CreateItemText( msgAuctionWonBody.str() ); + uint32 itemTextId = CreateItemText( msgAuctionWonBody.str() ); // set owner to bidder (to prevent delete item with sender char deleting) // owner in `data` will set at mail receive and item extracting @@ -466,7 +471,7 @@ void ObjectMgr::SendAuctionSalePendingMail( AuctionEntry * auction ) sLog.outDebug("AuctionSalePending body string : %s", msgAuctionSalePendingBody.str().c_str()); - uint32 itemTextId = this->CreateItemText( msgAuctionSalePendingBody.str() ); + uint32 itemTextId = CreateItemText( msgAuctionSalePendingBody.str() ); WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, auction->owner, msgAuctionSalePendingSubject.str(), itemTextId, NULL, 0, 0, MAIL_CHECK_MASK_AUCTION); } @@ -498,7 +503,7 @@ void ObjectMgr::SendAuctionSuccessfulMail( AuctionEntry * auction ) sLog.outDebug("AuctionSuccessful body string : %s", auctionSuccessfulBody.str().c_str()); - uint32 itemTextId = this->CreateItemText( auctionSuccessfulBody.str() ); + uint32 itemTextId = CreateItemText( auctionSuccessfulBody.str() ); uint32 profit = auction->bid + auction->deposit - auctionCut; @@ -545,7 +550,6 @@ void ObjectMgr::SendAuctionExpiredMail( AuctionEntry * auction ) // will delete item or place to receiver mail list WorldSession::SendMailTo(owner, MAIL_AUCTION, MAIL_STATIONERY_AUCTION, auction->location, GUID_LOPART(owner_guid), subject.str(), 0, &mi, 0, 0, MAIL_CHECK_MASK_NONE); - } // owner not found else @@ -563,8 +567,8 @@ CreatureInfo const* ObjectMgr::GetCreatureTemplate(uint32 id) void ObjectMgr::LoadCreatureLocales() { - mCreatureLocaleMap.clear(); - + mCreatureLocaleMap.clear(); // need for reload case + QueryResult *result = WorldDatabase.Query("SELECT entry,name_loc1,subname_loc1,name_loc2,subname_loc2,name_loc3,subname_loc3,name_loc4,subname_loc4,name_loc5,subname_loc5,name_loc6,subname_loc6,name_loc7,subname_loc7,name_loc8,subname_loc8 FROM locales_creature"); if(!result) @@ -623,7 +627,7 @@ void ObjectMgr::LoadCreatureLocales() sLog.outString(); sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() ); } - + void ObjectMgr::LoadNpcOptionLocales() { mNpcOptionLocaleMap.clear(); // need for reload case @@ -692,9 +696,19 @@ void ObjectMgr::LoadNpcOptionLocales() sLog.outString( ">> Loaded %u npc_option locale strings", mNpcOptionLocaleMap.size() ); } +struct SQLCreatureLoader : public SQLStorageLoaderBase<SQLCreatureLoader> +{ + template<class D> + void convert_from_str(uint32 field_pos, char *src, D &dst) + { + dst = D(objmgr.GetScriptId(src)); + } +}; + void ObjectMgr::LoadCreatureTemplates() { - sCreatureStorage.Load(); + SQLCreatureLoader loader; + loader.Load(sCreatureStorage); sLog.outString( ">> Loaded %u creature definitions", sCreatureStorage.RecordCount ); sLog.outString(); @@ -1512,7 +1526,7 @@ void ObjectMgr::LoadAuctions() aItem->deposit = fields[10].GetUInt32(); aItem->location = fields[11].GetUInt8(); //check if sold item exists - if ( this->GetAItem( aItem->item_guidlow ) ) + if ( GetAItem( aItem->item_guidlow ) ) { GetAuctionsMap( aItem->location )->AddAuction(aItem); } @@ -1532,8 +1546,8 @@ void ObjectMgr::LoadAuctions() void ObjectMgr::LoadItemLocales() { - mItemLocaleMap.clear(); - + mItemLocaleMap.clear(); // need for reload case + QueryResult *result = WorldDatabase.Query("SELECT entry,name_loc1,description_loc1,name_loc2,description_loc2,name_loc3,description_loc3,name_loc4,description_loc4,name_loc5,description_loc5,name_loc6,description_loc6,name_loc7,description_loc7,name_loc8,description_loc8 FROM locales_item"); if(!result) @@ -1594,9 +1608,19 @@ void ObjectMgr::LoadItemLocales() sLog.outString( ">> Loaded %u Item locale strings", mItemLocaleMap.size() ); } +struct SQLItemLoader : public SQLStorageLoaderBase<SQLItemLoader> +{ + template<class D> + void convert_from_str(uint32 field_pos, char *src, D &dst) + { + dst = D(objmgr.GetScriptId(src)); + } +}; + void ObjectMgr::LoadItemPrototypes() { - sItemStorage.Load (); + SQLItemLoader loader; + loader.Load(sItemStorage); sLog.outString( ">> Loaded %u item prototypes", sItemStorage.RecordCount ); sLog.outString(); @@ -2506,7 +2530,7 @@ void ObjectMgr::LoadPlayerInfo() // skip expansion races if not playing with expansion if (sWorld.getConfig(CONFIG_EXPANSION) < 1 && (race == RACE_BLOODELF || race == RACE_DRAENEI)) continue; - + // skip expansion classes if not playing with expansion if (sWorld.getConfig(CONFIG_EXPANSION) < 2 && class_ == CLASS_DEATH_KNIGHT) continue; @@ -3555,7 +3579,7 @@ void ObjectMgr::LoadQuests() void ObjectMgr::LoadQuestLocales() { - mQuestLocaleMap.clear(); + mQuestLocaleMap.clear(); // need for reload case QueryResult *result = WorldDatabase.Query("SELECT entry," "Title_loc1,Details_loc1,Objectives_loc1,OfferRewardText_loc1,RequestItemsText_loc1,EndText_loc1,ObjectiveText1_loc1,ObjectiveText2_loc1,ObjectiveText3_loc1,ObjectiveText4_loc1," @@ -3749,7 +3773,7 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename) scripts.clear(); // need for reload support - QueryResult *result = WorldDatabase.PQuery( "SELECT id,delay,command,datalong,datalong2,datatext, x, y, z, o FROM %s", tablename ); + QueryResult *result = WorldDatabase.PQuery( "SELECT id,delay,command,datalong,datalong2,dataint, x, y, z, o FROM %s", tablename ); uint32 count = 0; @@ -3771,16 +3795,16 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename) Field *fields = result->Fetch(); ScriptInfo tmp; - tmp.id = fields[0].GetUInt32(); - tmp.delay = fields[1].GetUInt32(); - tmp.command = fields[2].GetUInt32(); - tmp.datalong = fields[3].GetUInt32(); + tmp.id = fields[0].GetUInt32(); + tmp.delay = fields[1].GetUInt32(); + tmp.command = fields[2].GetUInt32(); + tmp.datalong = fields[3].GetUInt32(); tmp.datalong2 = fields[4].GetUInt32(); - tmp.datatext = fields[5].GetCppString(); - tmp.x = fields[6].GetFloat(); - tmp.y = fields[7].GetFloat(); - tmp.z = fields[8].GetFloat(); - tmp.o = fields[9].GetFloat(); + tmp.dataint = fields[5].GetInt32(); + tmp.x = fields[6].GetFloat(); + tmp.y = fields[7].GetFloat(); + tmp.z = fields[8].GetFloat(); + tmp.o = fields[9].GetFloat(); // generic command args check switch(tmp.command) @@ -3792,6 +3816,18 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename) sLog.outErrorDb("Table `%s` has invalid talk type (datalong = %u) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.datalong,tmp.id); continue; } + if(tmp.dataint==0) + { + sLog.outErrorDb("Table `%s` has invalid talk text id (dataint = %i) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.dataint,tmp.id); + continue; + } + if(tmp.dataint < MIN_DB_SCRIPT_STRING_ID || tmp.dataint >= MAX_DB_SCRIPT_STRING_ID) + { + sLog.outErrorDb("Table `%s` has out of range text id (dataint = %i expected %u-%u) in SCRIPT_COMMAND_TALK for script id %u",tablename,tmp.dataint,MIN_DB_SCRIPT_STRING_ID,MAX_DB_SCRIPT_STRING_ID,tmp.id); + continue; + } + + // if(!objmgr.GetMangosStringLocale(tmp.dataint)) will checked after db_script_string loading break; } @@ -4156,8 +4192,8 @@ void ObjectMgr::LoadPageTexts() void ObjectMgr::LoadPageTextLocales() { - mPageTextLocaleMap.clear(); - + mPageTextLocaleMap.clear(); // need for reload case + QueryResult *result = WorldDatabase.Query("SELECT entry,text_loc1,text_loc2,text_loc3,text_loc4,text_loc5,text_loc6,text_loc7,text_loc8 FROM locales_page_text"); if(!result) @@ -4206,9 +4242,19 @@ void ObjectMgr::LoadPageTextLocales() sLog.outString( ">> Loaded %u PageText locale strings", mPageTextLocaleMap.size() ); } +struct SQLInstanceLoader : public SQLStorageLoaderBase<SQLInstanceLoader> +{ + template<class D> + void convert_from_str(uint32 field_pos, char *src, D &dst) + { + dst = D(objmgr.GetScriptId(src)); + } +}; + void ObjectMgr::LoadInstanceTemplate() { - sInstanceTemplate.Load(); + SQLInstanceLoader loader; + loader.Load(sInstanceTemplate); for(uint32 i = 0; i < sInstanceTemplate.MaxEntry; i++) { @@ -4324,8 +4370,8 @@ void ObjectMgr::LoadGossipText() void ObjectMgr::LoadNpcTextLocales() { - mNpcTextLocaleMap.clear(); - + mNpcTextLocaleMap.clear(); // need for reload case + QueryResult *result = WorldDatabase.Query("SELECT entry," "Text0_0_loc1,Text0_1_loc1,Text1_0_loc1,Text1_1_loc1,Text2_0_loc1,Text2_1_loc1,Text3_0_loc1,Text3_1_loc1,Text4_0_loc1,Text4_1_loc1,Text5_0_loc1,Text5_1_loc1,Text6_0_loc1,Text6_1_loc1,Text7_0_loc1,Text7_1_loc1," "Text0_0_loc2,Text0_1_loc2,Text1_0_loc2,Text1_1_loc2,Text2_0_loc2,Text2_1_loc2,Text3_0_loc2,Text3_1_loc1,Text4_0_loc2,Text4_1_loc2,Text5_0_loc2,Text5_1_loc2,Text6_0_loc2,Text6_1_loc2,Text7_0_loc2,Text7_1_loc2," @@ -4622,7 +4668,7 @@ void ObjectMgr::LoadAreaTriggerScripts() Field *fields = result->Fetch(); uint32 Trigger_ID = fields[0].GetUInt32(); - std::string scriptName = fields[1].GetCppString(); + const char *scriptName = fields[1].GetString(); AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(Trigger_ID); if(!atEntry) @@ -4630,7 +4676,7 @@ void ObjectMgr::LoadAreaTriggerScripts() sLog.outErrorDb("Area trigger (ID:%u) does not exist in `AreaTrigger.dbc`.",Trigger_ID); continue; } - mAreaTriggerScripts[Trigger_ID] = scriptName; + mAreaTriggerScripts[Trigger_ID] = GetScriptId(scriptName); } while( result->NextRow() ); delete result; @@ -4638,6 +4684,7 @@ void ObjectMgr::LoadAreaTriggerScripts() sLog.outString(); sLog.outString( ">> Loaded %u areatrigger scripts", count ); } + uint32 ObjectMgr::GetNearestTaxiNode( float x, float y, float z, uint32 mapid ) { bool found = false; @@ -4696,11 +4743,11 @@ void ObjectMgr::GetTaxiPath( uint32 source, uint32 destination, uint32 &path, ui uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team ) { - uint32 mount_entry = 0; - uint32 mount_id = 0; + uint16 mount_entry = 0; + uint16 mount_id = 0; TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id); - if (node) + if(node) { if (team == ALLIANCE) mount_entry = node->alliance_mount_type; else mount_entry = node->horde_mount_type; @@ -4939,7 +4986,6 @@ WorldSafeLocsEntry const *ObjectMgr::GetClosestGraveYard(float x, float y, float } } - // find now nearest graveyard at same map if(entryNear) return entryNear; @@ -5180,7 +5226,6 @@ void ObjectMgr::SetHighestGuids() if( result ) { m_hiCharGuid = (*result)[0].GetUInt32()+1; - delete result; } @@ -5188,23 +5233,16 @@ void ObjectMgr::SetHighestGuids() if( result ) { m_hiCreatureGuid = (*result)[0].GetUInt32()+1; - delete result; } - result = CharacterDatabase.Query( "SELECT MAX(id) FROM character_pet" ); - if( result ) - { - m_hiPetGuid = (*result)[0].GetUInt32()+1; - - delete result; - } + // pet guids are not saved to DB, set to 0 (pet guid != pet id) + m_hiPetGuid = 0; result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" ); if( result ) { m_hiItemGuid = (*result)[0].GetUInt32()+1; - delete result; } @@ -5218,7 +5256,6 @@ void ObjectMgr::SetHighestGuids() if( result ) { m_hiGoGuid = (*result)[0].GetUInt32()+1; - delete result; } @@ -5226,74 +5263,93 @@ void ObjectMgr::SetHighestGuids() if( result ) { m_auctionid = (*result)[0].GetUInt32()+1; - delete result; } - else - { - m_auctionid = 0; - } + result = CharacterDatabase.Query( "SELECT MAX(id) FROM mail" ); if( result ) { m_mailid = (*result)[0].GetUInt32()+1; - delete result; } - else - { - m_mailid = 0; - } + result = CharacterDatabase.Query( "SELECT MAX(id) FROM item_text" ); if( result ) { - m_ItemTextId = (*result)[0].GetUInt32(); - + m_ItemTextId = (*result)[0].GetUInt32()+1; delete result; } - else - m_ItemTextId = 0; result = CharacterDatabase.Query( "SELECT MAX(guid) FROM corpse" ); if( result ) { m_hiCorpseGuid = (*result)[0].GetUInt32()+1; + delete result; + } + result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team"); + if (result) + { + m_arenaTeamId = (*result)[0].GetUInt32()+1; + delete result; + } + + result = CharacterDatabase.Query( "SELECT MAX(guildid) FROM guild" ); + if (result) + { + m_guildId = (*result)[0].GetUInt32()+1; delete result; } } +uint32 ObjectMgr::GenerateArenaTeamId() +{ + if(m_arenaTeamId>=0xFFFFFFFE) + { + sLog.outError("Arena team ids overflow!! Can't continue, shutting down server. "); + World::StopNow(ERROR_EXIT_CODE); + } + return m_arenaTeamId++; +} + +uint32 ObjectMgr::GenerateGuildId() +{ + if(m_guildId>=0xFFFFFFFE) + { + sLog.outError("Guild ids overflow!! Can't continue, shutting down server. "); + World::StopNow(ERROR_EXIT_CODE); + } + return m_guildId++; +} + uint32 ObjectMgr::GenerateAuctionID() { - ++m_auctionid; - if(m_auctionid>=0xFFFFFFFF) + if(m_auctionid>=0xFFFFFFFE) { sLog.outError("Auctions ids overflow!! Can't continue, shutting down server. "); - sWorld.m_stopEvent = true; + World::StopNow(ERROR_EXIT_CODE); } - return m_auctionid; + return m_auctionid++; } uint32 ObjectMgr::GenerateMailID() { - ++m_mailid; - if(m_mailid>=0xFFFFFFFF) + if(m_mailid>=0xFFFFFFFE) { sLog.outError("Mail ids overflow!! Can't continue, shutting down server. "); - sWorld.m_stopEvent = true; + World::StopNow(ERROR_EXIT_CODE); } - return m_mailid; + return m_mailid++; } uint32 ObjectMgr::GenerateItemTextID() { - ++m_ItemTextId; - if(m_ItemTextId>=0xFFFFFFFF) + if(m_ItemTextId>=0xFFFFFFFE) { sLog.outError("Item text ids overflow!! Can't continue, shutting down server. "); - sWorld.m_stopEvent = true; + World::StopNow(ERROR_EXIT_CODE); } - return m_ItemTextId; + return m_ItemTextId++; } uint32 ObjectMgr::CreateItemText(std::string text) @@ -5315,61 +5371,54 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) switch(guidhigh) { case HIGHGUID_ITEM: - ++m_hiItemGuid; - if(m_hiItemGuid>=0xFFFFFFFF) + if(m_hiItemGuid>=0xFFFFFFFE) { sLog.outError("Item guid overflow!! Can't continue, shutting down server. "); - sWorld.m_stopEvent = true; + World::StopNow(ERROR_EXIT_CODE); } - return m_hiItemGuid; + return m_hiItemGuid++; case HIGHGUID_UNIT: - ++m_hiCreatureGuid; - if(m_hiCreatureGuid>=0x00FFFFFF) + if(m_hiCreatureGuid>=0x00FFFFFE) { sLog.outError("Creature guid overflow!! Can't continue, shutting down server. "); - sWorld.m_stopEvent = true; + World::StopNow(ERROR_EXIT_CODE); } - return m_hiCreatureGuid; + return m_hiCreatureGuid++; case HIGHGUID_PET: - ++m_hiPetGuid; - if(m_hiPetGuid>=0x00FFFFFF) + if(m_hiPetGuid>=0x00FFFFFE) { sLog.outError("Pet guid overflow!! Can't continue, shutting down server. "); - sWorld.m_stopEvent = true; + World::StopNow(ERROR_EXIT_CODE); } - return m_hiPetGuid; + return m_hiPetGuid++; case HIGHGUID_PLAYER: - ++m_hiCharGuid; - if(m_hiCharGuid>=0xFFFFFFFF) + if(m_hiCharGuid>=0xFFFFFFFE) { sLog.outError("Players guid overflow!! Can't continue, shutting down server. "); - sWorld.m_stopEvent = true; + World::StopNow(ERROR_EXIT_CODE); } - return m_hiCharGuid; + return m_hiCharGuid++; case HIGHGUID_GAMEOBJECT: - ++m_hiGoGuid; - if(m_hiGoGuid>=0x00FFFFFF) + if(m_hiGoGuid>=0x00FFFFFE) { sLog.outError("Gameobject guid overflow!! Can't continue, shutting down server. "); - sWorld.m_stopEvent = true; + World::StopNow(ERROR_EXIT_CODE); } - return m_hiGoGuid; + return m_hiGoGuid++; case HIGHGUID_CORPSE: - ++m_hiCorpseGuid; - if(m_hiCorpseGuid>=0xFFFFFFFF) + if(m_hiCorpseGuid>=0xFFFFFFFE) { sLog.outError("Corpse guid overflow!! Can't continue, shutting down server. "); - sWorld.m_stopEvent = true; + World::StopNow(ERROR_EXIT_CODE); } - return m_hiCorpseGuid; + return m_hiCorpseGuid++; case HIGHGUID_DYNAMICOBJECT: - ++m_hiDoGuid; - if(m_hiDoGuid>=0xFFFFFFFF) + if(m_hiDoGuid>=0xFFFFFFFE) { sLog.outError("DynamicObject guid overflow!! Can't continue, shutting down server. "); - sWorld.m_stopEvent = true; + World::StopNow(ERROR_EXIT_CODE); } - return m_hiDoGuid; + return m_hiDoGuid++; default: ASSERT(0); } @@ -5380,8 +5429,8 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) void ObjectMgr::LoadGameObjectLocales() { - mGameObjectLocaleMap.clear(); - + mGameObjectLocaleMap.clear(); // need for reload case + QueryResult *result = WorldDatabase.Query("SELECT entry," "name_loc1,name_loc2,name_loc3,name_loc4,name_loc5,name_loc6,name_loc7,name_loc8," "castbarcaption_loc1,castbarcaption_loc2,castbarcaption_loc3,castbarcaption_loc4," @@ -5449,9 +5498,19 @@ void ObjectMgr::LoadGameObjectLocales() sLog.outString( ">> Loaded %u gameobject locale strings", mGameObjectLocaleMap.size() ); } +struct SQLGameObjectLoader : public SQLStorageLoaderBase<SQLGameObjectLoader> +{ + template<class D> + void convert_from_str(uint32 field_pos, char *src, D &dst) + { + dst = D(objmgr.GetScriptId(src)); + } +}; + void ObjectMgr::LoadGameobjectInfo() { - sGOStorage.Load(); + SQLGameObjectLoader loader; + loader.Load(sGOStorage); // some checks for(uint32 id = 1; id < sGOStorage.MaxEntry; id++) @@ -6624,12 +6683,12 @@ bool ObjectMgr::CheckDeclinedNames( std::wstring mainpart, DeclinedName const& n return true; } -const char* ObjectMgr::GetAreaTriggerScriptName(uint32 id) +uint32 ObjectMgr::GetAreaTriggerScriptId(uint32 trigger_id) { - AreaTriggerScriptMap::const_iterator i = mAreaTriggerScripts.find(id); + AreaTriggerScriptMap::const_iterator i = mAreaTriggerScripts.find(trigger_id); if(i!= mAreaTriggerScripts.end()) - return i->second.c_str(); - return ""; + return i->second; + return 0; } // Checks if player meets the condition @@ -6674,10 +6733,10 @@ bool PlayerCondition::Meets(Player const * player) const return true; return false; } - case CONDITION_NO_AURA: - return !player->HasAura(value1, value2); - case CONDITION_ACTIVE_EVENT: - return gameeventmgr.IsActiveEvent(value1); + case CONDITION_NO_AURA: + return !player->HasAura(value1, value2); + case CONDITION_ACTIVE_EVENT: + return gameeventmgr.IsActiveEvent(value1); default: return false; } @@ -6798,30 +6857,30 @@ bool PlayerCondition::IsValid(ConditionType condition, uint32 value1, uint32 val sLog.outErrorDb("Quest condition has useless data in value2 (%u)!", value2); break; } - case CONDITION_NO_AURA: - { - if(!sSpellStore.LookupEntry(value1)) - { - sLog.outErrorDb("Aura condition requires to have non existing spell (Id: %d), skipped", value1); - return false; - } - if(value2 > 2) - { - sLog.outErrorDb("Aura condition requires to have non existing effect index (%u) (must be 0..2), skipped", value2); - return false; - } - break; - } - case CONDITION_ACTIVE_EVENT: - { - GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); - if(value1 >=events.size() || !events[value1].isValid()) - { - sLog.outErrorDb("Active event condition requires existed event id (%u), skipped", value1); - return false; - } - break; - } + case CONDITION_NO_AURA: + { + if(!sSpellStore.LookupEntry(value1)) + { + sLog.outErrorDb("Aura condition requires to have non existing spell (Id: %d), skipped", value1); + return false; + } + if(value2 > 2) + { + sLog.outErrorDb("Aura condition requires to have non existing effect index (%u) (must be 0..2), skipped", value2); + return false; + } + break; + } + case CONDITION_ACTIVE_EVENT: + { + GameEvent::GameEventDataMap const& events = gameeventmgr.GetEventMap(); + if(value1 >=events.size() || !events[value1].isValid()) + { + sLog.outErrorDb("Active event condition requires existed event id (%u), skipped", value1); + return false; + } + break; + } } return true; } @@ -6951,7 +7010,7 @@ bool ObjectMgr::AddGameTele(GameTele& tele) for(GameTeleMap::const_iterator itr = m_GameTeleMap.begin(); itr != m_GameTeleMap.end(); ++itr) if(itr->first > new_id) new_id = itr->first; - + // use next ++new_id; @@ -6991,7 +7050,7 @@ bool ObjectMgr::DeleteGameTele(std::string name) void ObjectMgr::LoadTrainerSpell() { - // For reload case + // For reload case for (CacheTrainerSpellMap::iterator itr = m_mCacheTrainerSpellMap.begin(); itr != m_mCacheTrainerSpellMap.end(); ++itr) itr->second.Clear(); m_mCacheTrainerSpellMap.clear(); @@ -7082,7 +7141,7 @@ void ObjectMgr::LoadTrainerSpell() void ObjectMgr::LoadVendors() { - // For reload case + // For reload case for (CacheVendorItemMap::iterator itr = m_mCacheVendorItemMap.begin(); itr != m_mCacheVendorItemMap.end(); ++itr) itr->second.Clear(); m_mCacheVendorItemMap.clear(); @@ -7189,6 +7248,7 @@ void ObjectMgr::LoadNpcOptions() // 0 1 2 3 4 5 6 7 8 "SELECT id,gossip_id,npcflag,icon,action,box_money,coded,option_text,box_text " "FROM npc_option"); + if( !result ) { barGoLink bar( 1 ); @@ -7341,10 +7401,84 @@ bool ObjectMgr::IsVendorItemValid( uint32 vendor_entry, uint32 item_id, uint32 m return true; } +void ObjectMgr::LoadScriptNames() +{ + m_scriptNames.push_back(""); + QueryResult *result = WorldDatabase.Query( + "SELECT DISTINCT(ScriptName) FROM creature_template WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM gameobject_template WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM item_template WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(ScriptName) FROM areatrigger_scripts WHERE ScriptName <> '' " + "UNION " + "SELECT DISTINCT(script) FROM instance_template WHERE script <> ''"); + if(result) + { + do + { + m_scriptNames.push_back((*result)[0].GetString()); + } while (result->NextRow()); + delete result; + } + + std::sort(m_scriptNames.begin(), m_scriptNames.end()); +} + +uint32 ObjectMgr::GetScriptId(const char *name) +{ + // use binary search to find the script name in the sorted vector + // assume "" is the first element + if(!name) return 0; + ScriptNameMap::const_iterator itr = + std::lower_bound(m_scriptNames.begin(), m_scriptNames.end(), name); + if(itr == m_scriptNames.end()) return 0; + return itr - m_scriptNames.begin(); +} + +void ObjectMgr::CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids) +{ + for(ScriptMapMap::const_iterator itrMM = scripts.begin(); itrMM != scripts.end(); ++itrMM) + { + for(ScriptMap::const_iterator itrM = itrMM->second.begin(); itrM != itrMM->second.end(); ++itrM) + { + if(itrM->second.dataint) + { + if(!GetTrinityStringLocale (itrM->second.dataint)) + sLog.outErrorDb( "Table `db_script_string` has not existed string id %u", *itrM); + + if(ids.count(itrM->second.dataint)) + ids.erase(itrM->second.dataint); + } + } + } +} + +void ObjectMgr::LoadDbScriptStrings() +{ + LoadTrinityStrings(WorldDatabase,"db_script_string",MIN_DB_SCRIPT_STRING_ID,MAX_DB_SCRIPT_STRING_ID); + + std::set<int32> ids; + + for(int32 i = MIN_DB_SCRIPT_STRING_ID; i < MAX_DB_SCRIPT_STRING_ID; ++i) + if(GetTrinityStringLocale(i)) + ids.insert(i); + + CheckScripts(sQuestEndScripts,ids); + CheckScripts(sQuestStartScripts,ids); + CheckScripts(sSpellScripts,ids); + CheckScripts(sGameObjectScripts,ids); + CheckScripts(sEventScripts,ids); + + for(std::set<int32>::const_iterator itr = ids.begin(); itr != ids.end(); ++itr) + sLog.outErrorDb( "Table `db_script_string` has unused string id %u", *itr); +} + // Functions for scripting access -const char* GetAreaTriggerScriptNameById(uint32 id) +uint32 GetAreaTriggerScriptId(uint32 trigger_id) { - return objmgr.GetAreaTriggerScriptName(id); + return objmgr.GetAreaTriggerScriptId(trigger_id); } bool LoadTrinityStrings(DatabaseType& db, char const* table,int32 start_value, int32 end_value) @@ -7359,3 +7493,13 @@ bool LoadTrinityStrings(DatabaseType& db, char const* table,int32 start_value, i // for scripting localized strings allowed use _only_ negative entries return objmgr.LoadTrinityStrings(db,table,end_value,start_value); } + +uint32 TRINITY_DLL_SPEC GetScriptId(const char *name) +{ + return objmgr.GetScriptId(name); +} + +ObjectMgr::ScriptNameMap & GetScriptNames() +{ + return objmgr.GetScriptNames(); +} diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index a5d8a679fdd..9595418ed22 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -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 */ #ifndef _OBJECTMGR_H @@ -84,7 +84,7 @@ struct ScriptInfo uint32 command; uint32 datalong; uint32 datalong2; - std::string datatext; + int32 dataint; float x; float y; float z; @@ -128,6 +128,13 @@ typedef UNORDERED_MAP<uint32/*(mapid,spawnMode) pair*/,CellObjectGuidsMap> MapOb typedef UNORDERED_MAP<uint64/*(instance,guid) pair*/,time_t> RespawnTimes; + +// mangos string ranges +#define MIN_TRINITY_STRING_ID 1 +#define MAX_TRINITY_STRING_ID 2000000000 +#define MIN_DB_SCRIPT_STRING_ID MAX_TRINITY_STRING_ID +#define MAX_DB_SCRIPT_STRING_ID 2000010000 + struct TrinityStringLocale { std::vector<std::string> Content; // 0 -> default, i -> i-1 locale index @@ -207,8 +214,8 @@ enum ConditionType CONDITION_QUESTREWARDED = 8, // quest_id 0 CONDITION_QUESTTAKEN = 9, // quest_id 0, for condition true while quest active. CONDITION_AD_COMMISSION_AURA = 10, // 0 0, for condition true while one from AD ñommission aura active - CONDITION_NO_AURA = 11, // spell_id effindex - CONDITION_ACTIVE_EVENT = 12, // event_id + CONDITION_NO_AURA = 11, // spell_id effindex + CONDITION_ACTIVE_EVENT = 12, // event_id }; #define MAX_CONDITION 13 // maximum value in ConditionType enum @@ -250,7 +257,7 @@ struct PlayerCondition // NPC gossip text id typedef UNORDERED_MAP<uint32, uint32> CacheNpcTextIdMap; - +typedef std::list<GossipOption> CacheNpcOptionList; typedef UNORDERED_MAP<uint32, VendorItemData> CacheVendorItemMap; typedef UNORDERED_MAP<uint32, TrainerSpellData> CacheTrainerSpellMap; @@ -299,9 +306,10 @@ class ObjectMgr typedef UNORDERED_MAP<uint32, Quest*> QuestMap; + typedef UNORDERED_MAP<uint32, AreaTrigger> AreaTriggerMap; - typedef UNORDERED_MAP<uint32, std::string> AreaTriggerScriptMap; + typedef UNORDERED_MAP<uint32, uint32> AreaTriggerScriptMap; typedef UNORDERED_MAP<uint32, ReputationOnKillEntry> RepOnKillMap; @@ -309,6 +317,8 @@ class ObjectMgr typedef UNORDERED_MAP<uint32, PetCreateSpellEntry> PetCreateSpellMap; + typedef std::vector<std::string> ScriptNameMap; + Player* GetPlayer(const char* name) const { return ObjectAccessor::Instance().FindPlayerByName(name);} Player* GetPlayer(uint64 guid) const { return ObjectAccessor::FindPlayer(guid); } @@ -476,7 +486,7 @@ class ObjectMgr AreaTrigger const* GetGoBackTrigger(uint32 Map) const; - const char* GetAreaTriggerScriptName(uint32 id); + uint32 GetAreaTriggerScriptId(uint32 trigger_id); ReputationOnKillEntry const* GetReputationOnKilEntry(uint32 id) const { @@ -522,7 +532,8 @@ class ObjectMgr void LoadSpellScripts(); bool LoadTrinityStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value); - bool LoadTrinityStrings() { return LoadTrinityStrings(WorldDatabase,"trinity_string",1,std::numeric_limits<int32>::max()); } + bool LoadTrinityStrings() { return LoadTrinityStrings(WorldDatabase,"trinity_string",MIN_TRINITY_STRING_ID,MAX_TRINITY_STRING_ID); } + void LoadDbScriptStrings(); void LoadPetCreateSpells(); void LoadCreatureLocales(); void LoadCreatureTemplates(); @@ -592,6 +603,8 @@ class ObjectMgr uint32 GenerateMailID(); uint32 GenerateItemTextID(); uint32 GeneratePetNumber(); + uint32 GenerateArenaTeamId(); + uint32 GenerateGuildId(); void LoadPlayerInfoInCache(); PCachePlayerInfo GetPlayerInfoFromCache(uint32 unPlayerGuid) const; @@ -668,7 +681,6 @@ class ObjectMgr if(itr==mPageTextLocaleMap.end()) return NULL; return &itr->second; } - NpcOptionLocale const* GetNpcOptionLocale(uint32 entry) const { NpcOptionLocaleMap::const_iterator itr = mNpcOptionLocaleMap.find(entry); @@ -693,7 +705,7 @@ class ObjectMgr } const char *GetTrinityString(int32 entry, int locale_idx) const; const char *GetTrinityStringForDBCLocale(int32 entry) const { return GetTrinityString(entry,DBCLocaleIndex); } - int32 GetDBCLocaleIndex() const { return DBCLocaleIndex; } + int32 GetDBCLocaleIndex() const { return DBCLocaleIndex; } void SetDBCLocaleIndex(uint32 lang) { DBCLocaleIndex = GetIndexForLocale(LocaleConstant(lang)); } void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance); @@ -732,7 +744,7 @@ class ObjectMgr int GetIndexForLocale(LocaleConstant loc); LocaleConstant GetLocaleForIndex(int i); // guild bank tabs - const uint32 GetGuildBankTabPrice(uint8 Index) { return Index < GUILD_BANK_MAX_TABS ? mGuildBankTabPrice[Index] : 0; } + uint32 GetGuildBankTabPrice(uint8 Index) const { return Index < GUILD_BANK_MAX_TABS ? mGuildBankTabPrice[Index] : 0; } uint16 GetConditionId(ConditionType condition, uint32 value1, uint32 value2); bool IsPlayerMeetToCondition(Player const* player, uint16 condition_id) const @@ -753,7 +765,7 @@ class ObjectMgr GameTeleMap const& GetGameTeleMap() const { return m_GameTeleMap; } bool AddGameTele(GameTele& data); bool DeleteGameTele(std::string name); - + CacheNpcOptionList const& GetNpcOptions() const { return m_mCacheNpcOptionList; } uint32 GetNpcGossip(uint32 entry) const @@ -761,7 +773,7 @@ class ObjectMgr CacheNpcTextIdMap::const_iterator iter = m_mCacheNpcTextIdMap.find(entry); if(iter == m_mCacheNpcTextIdMap.end()) return 0; - + return iter->second; } @@ -782,15 +794,25 @@ class ObjectMgr return &iter->second; } - void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, bool savetodb = true); - bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true); - bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const; + void AddVendorItem(uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 ExtendedCost, bool savetodb = true); // for event + bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true); // for event + bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0 ) const; + void LoadScriptNames(); + ScriptNameMap &GetScriptNames() { return m_scriptNames; } + const char * GetScriptName(uint32 id) { return id < m_scriptNames.size() ? m_scriptNames[id].c_str() : ""; } + uint32 GetScriptId(const char *name); protected: + + // first free id for selected id type uint32 m_auctionid; uint32 m_mailid; uint32 m_ItemTextId; + uint32 m_arenaTeamId; + uint32 m_guildId; + uint32 m_hiPetNumber; + // first free low guid for seelcted guid type uint32 m_hiCharGuid; uint32 m_hiCreatureGuid; uint32 m_hiPetGuid; @@ -799,9 +821,7 @@ class ObjectMgr uint32 m_hiDoGuid; uint32 m_hiCorpseGuid; - uint32 m_hiPetNumber; - - QuestMap mQuestTemplates; + QuestMap mQuestTemplates; typedef UNORDERED_MAP<uint32, GossipText*> GossipTextMap; typedef UNORDERED_MAP<uint32, uint32> QuestAreaTriggerMap; @@ -848,6 +868,8 @@ class ObjectMgr GameTeleMap m_GameTeleMap; + ScriptNameMap m_scriptNames; + typedef std::vector<LocaleConstant> LocalForIndex; LocalForIndex m_LocalForIndex; int GetOrNewIndexForLocale(LocaleConstant loc); @@ -855,6 +877,7 @@ class ObjectMgr int DBCLocaleIndex; private: void LoadScripts(ScriptMapMap& scripts, char const* tablename); + void CheckScripts(ScriptMapMap const& scripts,std::set<int32>& ids); void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr); void LoadQuestRelationsHelper(QuestRelations& map,char const* table); @@ -907,7 +930,9 @@ class ObjectMgr #define objmgr Trinity::Singleton<ObjectMgr>::Instance() // scripting access functions -bool TRINITY_DLL_SPEC LoadTrinityStrings(DatabaseType& db, char const* table,int32 start_value = -1, int32 end_value = std::numeric_limits<int32>::min()); -TRINITY_DLL_SPEC const char* GetAreaTriggerScriptNameById(uint32 id); +TRINITY_DLL_SPEC bool LoadTrinityStrings(DatabaseType& db, char const* table,int32 start_value = -1, int32 end_value = std::numeric_limits<int32>::min()); +TRINITY_DLL_SPEC uint32 GetAreaTriggerScriptId(uint32 trigger_id); +TRINITY_DLL_SPEC uint32 GetScriptId(const char *name); +TRINITY_DLL_SPEC ObjectMgr::ScriptNameMap& GetScriptNames(); #endif diff --git a/src/game/PlayerDump.cpp b/src/game/PlayerDump.cpp index 78f90bc9c9e..7b32f547bff 100644 --- a/src/game/PlayerDump.cpp +++ b/src/game/PlayerDump.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" @@ -277,7 +277,7 @@ void PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tabl // for guid set stop if set is empty if(guids && guids->empty()) - return; // nothing to do + return; // nothing to do // setup for guids case start position GUIDs::const_iterator guids_itr; @@ -343,7 +343,7 @@ DumpReturn PlayerDumpWriter::WriteDump(std::string file, uint32 guid) { FILE *fout = fopen(file.c_str(), "w"); if (!fout) - return DUMP_FILE_OPEN_ERROR; + return DUMP_FILE_OPEN_ERROR; std::string dump = GetDump(guid); @@ -371,9 +371,10 @@ DumpReturn PlayerDumpReader::LoadDump(std::string file, uint32 account, std::str return DUMP_TOO_MANY_CHARS; } } + FILE *fin = fopen(file.c_str(), "r"); if(!fin) - return DUMP_FILE_OPEN_ERROR; + return DUMP_FILE_OPEN_ERROR; QueryResult * result = NULL; char newguid[20], chraccount[20], newpetid[20], currpetid[20], lastpetid[20]; @@ -390,7 +391,8 @@ DumpReturn PlayerDumpReader::LoadDump(std::string file, uint32 account, std::str } else incHighest = false; } - else guid = objmgr.m_hiCharGuid; + else + guid = objmgr.m_hiCharGuid; // normalize the name if specified and check if it exists if(!normalizePlayerName(name)) @@ -468,29 +470,25 @@ DumpReturn PlayerDumpReader::LoadDump(std::string file, uint32 account, std::str { case DTT_CHAR_TABLE: if(!changenth(line, 1, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); break; case DTT_CHARACTER: // character t. { if(!changenth(line, 1, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); // guid, data field:guid, items if(!changenth(line, 2, chraccount)) - ROLLBACK(DUMP_FILE_BROKEN); - + ROLLBACK(DUMP_FILE_BROKEN); std::string vals = getnth(line, 3); if(!changetoknth(vals, OBJECT_FIELD_GUID+1, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); - + ROLLBACK(DUMP_FILE_BROKEN); for(uint16 field = PLAYER_FIELD_INV_SLOT_HEAD; field < PLAYER_FARSIGHT; field++) if(!changetokGuid(vals, field+1, items, objmgr.m_hiItemGuid, true)) - ROLLBACK(DUMP_FILE_BROKEN); - + ROLLBACK(DUMP_FILE_BROKEN); if(!changenth(line, 3, vals.c_str())) - ROLLBACK(DUMP_FILE_BROKEN); - + ROLLBACK(DUMP_FILE_BROKEN); if (name == "") { // check if the original name already exists @@ -503,50 +501,49 @@ DumpReturn PlayerDumpReader::LoadDump(std::string file, uint32 account, std::str delete result; // rename on login: `at_login` field 30 in raw field list if(!changenth(line, 30, "1")) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); } } else if(!changenth(line, 4, name.c_str())) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_INVENTORY: // character_inventory t. { if(!changenth(line, 1, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); // bag, item if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid, true)) - ROLLBACK(DUMP_FILE_BROKEN); - if(!changeGuid(line, 4, items, objmgr.m_hiItemGuid)) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); + if(!changeGuid(line, 4, items, objmgr.m_hiItemGuid)) + ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_ITEM: // item_instance t. { // item, owner, data field:item, owner guid if(!changeGuid(line, 1, items, objmgr.m_hiItemGuid)) - ROLLBACK(DUMP_FILE_BROKEN); - if(!changenth(line, 2, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); - + ROLLBACK(DUMP_FILE_BROKEN); + if(!changenth(line, 2, newguid)) + ROLLBACK(DUMP_FILE_BROKEN); std::string vals = getnth(line,3); if(!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, objmgr.m_hiItemGuid)) - ROLLBACK(DUMP_FILE_BROKEN); - if(!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); - if(!changenth(line, 3, vals.c_str())) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); + if(!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid)) + ROLLBACK(DUMP_FILE_BROKEN); + if(!changenth(line, 3, vals.c_str())) + ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_ITEM_GIFT: // character_gift { // guid,item_guid, if(!changenth(line, 1, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); - if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid)) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); + if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid)) + ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_PET: // character_pet t @@ -569,9 +566,9 @@ DumpReturn PlayerDumpReader::LoadDump(std::string file, uint32 account, std::str // item, entry, owner, ... if(!changenth(line, 1, newpetid)) - ROLLBACK(DUMP_FILE_BROKEN); - if(!changenth(line, 3, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); + if(!changenth(line, 3, newguid)) + ROLLBACK(DUMP_FILE_BROKEN); break; } @@ -582,12 +579,12 @@ DumpReturn PlayerDumpReader::LoadDump(std::string file, uint32 account, std::str // lookup currpetid and match to new inserted pet id std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid)); if(petids_iter == petids.end()) // couldn't find new inserted id - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); snprintf(newpetid, 20, "%d", petids_iter->second); if(!changenth(line, 1, newpetid)) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); break; } @@ -595,20 +592,20 @@ DumpReturn PlayerDumpReader::LoadDump(std::string file, uint32 account, std::str { // id,messageType,stationery,sender,receiver if(!changeGuid(line, 1, mails, objmgr.m_mailid)) - ROLLBACK(DUMP_FILE_BROKEN); - if(!changenth(line, 5, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); + if(!changenth(line, 5, newguid)) + ROLLBACK(DUMP_FILE_BROKEN); break; } case DTT_MAIL_ITEM: // mail_items { // mail_id,item_guid,item_template,receiver if(!changeGuid(line, 1, mails, objmgr.m_mailid)) - ROLLBACK(DUMP_FILE_BROKEN); - if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid)) - ROLLBACK(DUMP_FILE_BROKEN); - if(!changenth(line, 4, newguid)) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); + if(!changeGuid(line, 2, items, objmgr.m_hiItemGuid)) + ROLLBACK(DUMP_FILE_BROKEN); + if(!changenth(line, 4, newguid)) + ROLLBACK(DUMP_FILE_BROKEN); break; } default: @@ -617,7 +614,7 @@ DumpReturn PlayerDumpReader::LoadDump(std::string file, uint32 account, std::str } if(!CharacterDatabase.Execute(line.c_str())) - ROLLBACK(DUMP_FILE_BROKEN); + ROLLBACK(DUMP_FILE_BROKEN); } CharacterDatabase.CommitTransaction(); diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 3ed9c04a259..0e318eb5ddc 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.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" @@ -54,6 +54,12 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) return; } + if(pItem->GetGUID() != item_guid) + { + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); + return; + } + sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, spell_count: %u , cast_count: %u, Item: %u, data length = %i", bagIndex, slot, spell_count, cast_count, pItem->GetEntry(), recvPacket.size()); ItemPrototype const *proto = pItem->GetProto(); @@ -237,7 +243,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) uint32 flags = fields[1].GetUInt32(); pItem->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, 0); - pItem->SetUInt32Value(OBJECT_FIELD_ENTRY, entry); + pItem->SetEntry(entry); pItem->SetUInt32Value(ITEM_FIELD_FLAGS, flags); pItem->SetState(ITEM_CHANGED, pUser); delete result; @@ -259,7 +265,6 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data ) CHECK_PACKET_SIZE(recv_data,8); uint64 guid; - uint32 spellId = OPEN_CHEST; recv_data >> guid; @@ -322,7 +327,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) } Spell *spell = new Spell(_player, spellInfo, false); - spell->m_cast_count = cast_count; //set count of casts + spell->m_cast_count = cast_count; // set count of casts spell->prepare(&targets); } diff --git a/src/game/WaypointManager.cpp b/src/game/WaypointManager.cpp index d72ac1e266e..a6dda2477ff 100644 --- a/src/game/WaypointManager.cpp +++ b/src/game/WaypointManager.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 "Database/DatabaseEnv.h" @@ -24,20 +24,30 @@ #include "WaypointManager.h" #include "ProgressBar.h" #include "MapManager.h" +#include "ObjectMgr.h" INSTANTIATE_SINGLETON_1(WaypointManager); bool WaypointBehavior::isEmpty() { - return emote == 0 && spell == 0 && model1 == 0 && model2 == 0 && text[0].empty() && - text[1].empty() && text[2].empty() && text[3].empty() && text[4].empty(); + if (emote || spell || model1 || model2) + return false; + + for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i) + if(textid[i]) + return false; + + return true; } WaypointBehavior::WaypointBehavior(const WaypointBehavior &b) { - emote = b.emote; spell = b.spell; model1 = b.model1; model2 = b.model2; - text[0] = b.text[0]; text[1] = b.text[1]; text[2] = b.text[2]; - text[3] = b.text[3]; text[4] = b.text[4]; + emote = b.emote; + spell = b.spell; + model1 = b.model1; + model2 = b.model2; + for(int i=0; i < MAX_WAYPOINT_TEXT; ++i) + textid[i] = b.textid[i]; } void WaypointManager::Load() @@ -66,7 +76,7 @@ void WaypointManager::Load() delete result; } - result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, text1, text2, text3, text4, text5, id, point FROM creature_movement"); + result = WorldDatabase.Query("SELECT position_x, position_y, position_z, orientation, model1, model2, waittime, emote, spell, textid1, textid2, textid3, textid4, textid5, id, point FROM creature_movement"); if(result) { barGoLink bar( result->GetRowCount() ); @@ -113,11 +123,33 @@ void WaypointManager::Load() be.model2 = fields[5].GetUInt32(); be.emote = fields[7].GetUInt32(); be.spell = fields[8].GetUInt32(); - be.text[0] = fields[9].GetCppString(); - be.text[1] = fields[10].GetCppString(); - be.text[2] = fields[11].GetCppString(); - be.text[3] = fields[12].GetCppString(); - be.text[4] = fields[13].GetCppString(); + + // load and store without holes in array + int j = 0; + for(int i = 0; i < MAX_WAYPOINT_TEXT; ++i) + { + be.textid[j] = fields[9+i].GetUInt32(); + if(be.textid[j]) + { + if (be.textid[j] < MIN_DB_SCRIPT_STRING_ID || be.textid[j] >= MAX_DB_SCRIPT_STRING_ID) + { + sLog.outErrorDb( "Table `db_script_string` not have string id %u", be.textid[j]); + continue; + } + + if (!objmgr.GetTrinityStringLocale (be.textid[j])) + { + sLog.outErrorDb("ERROR: Waypoint path %d (point %d), have invalid text id (%i) in `textid%d, ignored.", + id, point, be.textid[j], i+1); + continue; + } + + ++j; // to next internal field + } + } + // fill array tail + for(; j < MAX_WAYPOINT_TEXT; ++j) + be.textid[j] = 0; // save memory by not storing empty behaviors if(!be.isEmpty()) @@ -265,11 +297,11 @@ void WaypointManager::SetNodeText(uint32 id, uint32 point, const char *text_fiel WaypointNode &node = itr->second[point-1]; if(!node.behavior) node.behavior = new WaypointBehavior(); - if(field == "text1") node.behavior->text[0] = text ? text : ""; - if(field == "text2") node.behavior->text[1] = text ? text : ""; - if(field == "text3") node.behavior->text[2] = text ? text : ""; - if(field == "text4") node.behavior->text[3] = text ? text : ""; - if(field == "text5") node.behavior->text[4] = text ? text : ""; +// if(field == "text1") node.behavior->text[0] = text ? text : ""; +// if(field == "text2") node.behavior->text[1] = text ? text : ""; +// if(field == "text3") node.behavior->text[2] = text ? text : ""; +// if(field == "text4") node.behavior->text[3] = text ? text : ""; +// if(field == "text5") node.behavior->text[4] = text ? text : ""; if(field == "emote") node.behavior->emote = text ? atoi(text) : 0; if(field == "spell") node.behavior->spell = text ? atoi(text) : 0; if(field == "model1") node.behavior->model1 = text ? atoi(text) : 0; diff --git a/src/game/WaypointManager.h b/src/game/WaypointManager.h index 2fdf5622c2e..75f01cc82f3 100644 --- a/src/game/WaypointManager.h +++ b/src/game/WaypointManager.h @@ -25,11 +25,12 @@ #include <string> #include "Utilities/UnorderedMap.h" +#define MAX_WAYPOINT_TEXT 5 struct WaypointBehavior { uint32 emote; uint32 spell; - std::string text[5]; + int32 textid[MAX_WAYPOINT_TEXT]; uint32 model1; uint32 model2; diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index ef3a8a04ef3..7969c375e81 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -21,11 +21,11 @@ /* creature_movement Table -alter table creature_movement add `text1` varchar(255) default NULL; -alter table creature_movement add `text2` varchar(255) default NULL; -alter table creature_movement add `text3` varchar(255) default NULL; -alter table creature_movement add `text4` varchar(255) default NULL; -alter table creature_movement add `text5` varchar(255) default NULL; +alter table creature_movement add `textid1` int(11) NOT NULL default '0'; +alter table creature_movement add `textid2` int(11) NOT NULL default '0'; +alter table creature_movement add `textid3` int(11) NOT NULL default '0'; +alter table creature_movement add `textid4` int(11) NOT NULL default '0'; +alter table creature_movement add `textid5` int(11) NOT NULL default '0'; alter table creature_movement add `emote` int(10) unsigned default '0'; alter table creature_movement add `spell` int(5) unsigned default '0'; alter table creature_movement add `wpguid` int(11) default '0'; @@ -148,22 +148,21 @@ WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &di creature.CastSpell(&creature,behavior->spell, false); if(behavior->model1 != 0) creature.SetDisplayId(behavior->model1); - if(!behavior->text[0].empty()) + if(behavior->textid[0]) { - // Only one text is set - if( !behavior->text[1].empty() ) + // Not only one text is set + if( behavior->textid[1] ) { // Select one from max 5 texts (0 and 1 already checked) int i = 2; - for( ; i < 5; ++i ) - if( behavior->text[i].empty() ) + for( ; i < MAX_WAYPOINT_TEXT; ++i ) + if( !behavior->textid[i] ) break; - creature.Say(behavior->text[rand() % i].c_str(), 0, 0); - + creature.Say(behavior->textid[rand() % i], 0, 0); } else - creature.Say(behavior->text[0].c_str(), 0, 0); + creature.Say(behavior->textid[0], 0, 0); } } // wpBehaviour found i_hasDone[idx] = true; diff --git a/src/game/World.cpp b/src/game/World.cpp index d6017ac0669..64c2bd49099 100644 --- a/src/game/World.cpp +++ b/src/game/World.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 */ /** \file @@ -66,6 +66,7 @@ INSTANTIATE_SINGLETON_1( World ); volatile bool World::m_stopEvent = false; +uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; volatile uint32 World::m_worldLoopCounter = 0; float World::m_MaxVisibleDistanceForCreature = DEFAULT_VISIBILITY_DISTANCE; @@ -542,7 +543,6 @@ void World::LoadConfigSettings(bool reload) else m_configs[CONFIG_SOCKET_SELECTTIME] = sConfig.GetIntDefault("SocketSelectTime", DEFAULT_SOCKET_SELECT_TIME); - m_configs[CONFIG_GROUP_XP_DISTANCE] = sConfig.GetIntDefault("MaxGroupXPDistance", 74); /// \todo Add MonsterSight and GuarderSight (with meaning) in Trinityd.conf or put them as define m_configs[CONFIG_SIGHT_MONSTER] = sConfig.GetIntDefault("MonsterSight", 50); @@ -605,7 +605,6 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_SKIP_CINEMATICS] = 0; } - if(reload) { uint32 val = sConfig.GetIntDefault("MaxPlayerLevel", 60); @@ -769,8 +768,8 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_THREAT_RADIUS] = sConfig.GetIntDefault("ThreatRadius", 100); - // always use declined names in the Russian client - m_configs[CONFIG_DECLINED_NAMES_USED] = + // always use declined names in the russian client + m_configs[CONFIG_DECLINED_NAMES_USED] = (m_configs[CONFIG_REALM_ZONE] == REALM_ZONE_RUSSIAN) ? true : sConfig.GetBoolDefault("DeclinedNames", false); m_configs[CONFIG_LISTEN_RANGE_SAY] = sConfig.GetIntDefault("ListenRange.Say", 25); @@ -965,6 +964,9 @@ void World::SetInitialWorldSettings() LoadDBCStores(m_dataPath); DetectDBCLang(); + sLog.outString( "Loading Script Names..."); + objmgr.LoadScriptNames(); + sLog.outString( "Loading InstanceTemplate" ); objmgr.LoadInstanceTemplate(); @@ -1080,11 +1082,10 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Tavern Area Triggers..." ); objmgr.LoadTavernAreaTriggers(); - + sLog.outString( "Loading AreaTrigger script names..." ); objmgr.LoadAreaTriggerScripts(); - sLog.outString( "Loading Graveyard-zone links..."); objmgr.LoadGraveyardZones(); @@ -1164,7 +1165,7 @@ void World::SetInitialWorldSettings() sLog.outString( "Loading Npc Text Id..." ); objmgr.LoadNpcTextId(); // must be after load Creature and NpcText - + sLog.outString( "Loading Npc Options..." ); objmgr.LoadNpcOptions(); @@ -1192,6 +1193,9 @@ void World::SetInitialWorldSettings() objmgr.LoadGameObjectScripts(); // must be after load Creature/Gameobject(Template/Data) objmgr.LoadEventScripts(); // must be after load Creature/Gameobject(Template/Data) + sLog.outString( "Loading Scripts text locales..." ); // must be after Load*Scripts calls + objmgr.LoadDbScriptStrings(); + sLog.outString( "Initializing Scripts..." ); if(!LoadScriptingModule()) exit(1); @@ -1262,6 +1266,7 @@ void World::SetInitialWorldSettings() sLog.outString( "WORLD: World initialized" ); } + void World::DetectDBCLang() { uint32 m_lang_confid = sConfig.GetIntDefault("DBC.Locale", 255); @@ -1462,7 +1467,9 @@ void World::Update(time_t diff) m_timers[WUPDATE_EVENTS].Reset(); } - MapManager::Instance().DoDelayedMovesAndRemoves(); ///- Move all creatures with "delayed move" and remove and delete all objects with "delayed remove" + /// </ul> + ///- Move all creatures with "delayed move" and remove and delete all objects with "delayed remove" + MapManager::Instance().DoDelayedMovesAndRemoves(); // update the instance reset times sInstanceSaveManager.Update(); @@ -1582,6 +1589,8 @@ void World::ScriptsProcess() } } + //if(source && !source->IsInWorld()) source = NULL; + Object* target = NULL; if(step.targetGUID) @@ -1609,6 +1618,8 @@ void World::ScriptsProcess() } } + //if(target && !target->IsInWorld()) target = NULL; + switch (step.script->command) { case SCRIPT_COMMAND_TALK: @@ -1636,7 +1647,7 @@ void World::ScriptsProcess() switch(step.script->datalong) { case 0: // Say - ((Creature *)source)->Say(step.script->datatext.c_str(), LANG_UNIVERSAL, unit_target); + ((Creature *)source)->Say(step.script->dataint, LANG_UNIVERSAL, unit_target); break; case 1: // Whisper if(!unit_target) @@ -1644,13 +1655,13 @@ void World::ScriptsProcess() sLog.outError("SCRIPT_COMMAND_TALK attempt to whisper (%u) NULL, skipping.",step.script->datalong); break; } - ((Creature *)source)->Whisper(step.script->datatext.c_str(),unit_target); + ((Creature *)source)->Whisper(step.script->dataint,unit_target); break; case 2: // Yell - ((Creature *)source)->Yell(step.script->datatext.c_str(), LANG_UNIVERSAL, unit_target); + ((Creature *)source)->Yell(step.script->dataint, LANG_UNIVERSAL, unit_target); break; case 3: // Emote text - ((Creature *)source)->TextEmote(step.script->datatext.c_str(), unit_target); + ((Creature *)source)->TextEmote(step.script->dataint, unit_target); break; default: break; // must be already checked at load @@ -1701,7 +1712,7 @@ void World::ScriptsProcess() break; } ((Unit *)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, ((Unit *)source)->GetUnitMovementFlags(), step.script->datalong2 ); - MapManager::Instance().GetMap(((Unit *)source)->GetMapId(), ((Unit *)source))->CreatureRelocation(((Creature *)source), step.script->x, step.script->y, step.script->z, 0); + ((Unit *)source)->GetMap()->CreatureRelocation(((Creature *)source), step.script->x, step.script->y, step.script->z, 0); break; case SCRIPT_COMMAND_FLAG_SET: if(!source) @@ -1851,7 +1862,7 @@ void World::ScriptsProcess() go->SetLootState(GO_READY); go->SetRespawnTime(time_to_despawn); //despawn object in ? seconds - MapManager::Instance().GetMap(go->GetMapId(), go)->Add(go); + go->GetMap()->Add(go); break; } case SCRIPT_COMMAND_OPEN_DOOR: @@ -2373,13 +2384,13 @@ void World::_UpdateGameTime() m_gameTime = thisTime; ///- if there is a shutdown timer - if(m_ShutdownTimer > 0 && elapsed > 0) + if(!m_stopEvent && m_ShutdownTimer > 0 && elapsed > 0) { ///- ... and it is overdue, stop the world (set m_stopEvent) if( m_ShutdownTimer <= elapsed ) { if(!(m_ShutdownMask & SHUTDOWN_MASK_IDLE) || GetActiveAndQueuedSessionCount()==0) - m_stopEvent = true; + m_stopEvent = true; // exist code already set else m_ShutdownTimer = 1; // minimum timer value to wait idle state } @@ -2394,15 +2405,20 @@ void World::_UpdateGameTime() } /// Shutdown the server -void World::ShutdownServ(uint32 time, uint32 options) +void World::ShutdownServ(uint32 time, uint32 options, uint8 exitcode) { + // ignore if server shutdown at next tick + if(m_stopEvent) + return; + m_ShutdownMask = options; + m_ExitCode = exitcode; ///- If the shutdown time is 0, set m_stopEvent (except if shutdown is 'idle' with remaining sessions) if(time==0) { if(!(options & SHUTDOWN_MASK_IDLE) || GetActiveAndQueuedSessionCount()==0) - m_stopEvent = true; + m_stopEvent = true; // exist code already set else m_ShutdownTimer = 1; //So that the session count is re-evaluated at next world tick } @@ -2447,16 +2463,18 @@ void World::ShutdownMsg(bool show, Player* player) /// Cancel a planned server shutdown void World::ShutdownCancel() { - if(!m_ShutdownTimer) + // nothing cancel or too later + if(!m_ShutdownTimer || m_stopEvent) return; uint32 msgid = (m_ShutdownMask & SHUTDOWN_MASK_RESTART) ? SERVER_MSG_RESTART_CANCELLED : SERVER_MSG_SHUTDOWN_CANCELLED; m_ShutdownMask = 0; m_ShutdownTimer = 0; + m_ExitCode = SHUTDOWN_EXIT_CODE; // to default value SendServerMessage(msgid); - DEBUG_LOG("Server %s canceled.",(m_ShutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shuttingdown")); + DEBUG_LOG("Server %s cancelled.",(m_ShutdownMask & SHUTDOWN_MASK_RESTART ? "restart" : "shuttingdown")); } /// Send a server message to the user(s) @@ -2501,6 +2519,7 @@ void World::UpdateSessions( time_t diff ) ///- and remove not active sessions from the list if(!itr->second->Update(diff)) // As interval = 0 { + RemoveQueuedPlayer (itr->second); delete itr->second; m_sessions.erase(itr); } diff --git a/src/game/World.h b/src/game/World.h index c1ceb6891a5..50065b360dd 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -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 */ /// \addtogroup world The World @@ -51,6 +51,13 @@ enum ShutdownMask SHUTDOWN_MASK_IDLE = 2, }; +enum ShutdownExitCode +{ + SHUTDOWN_EXIT_CODE = 0, + ERROR_EXIT_CODE = 1, + RESTART_EXIT_CODE = 2, +}; + /// Timers for different object refresh rates enum WorldTimers { @@ -61,8 +68,7 @@ enum WorldTimers WUPDATE_UPTIME = 4, WUPDATE_CORPSES = 5, WUPDATE_EVENTS = 6, - WUPDATE_COUNT = 7, - + WUPDATE_COUNT = 7 }; /// Configuration elements @@ -105,6 +111,8 @@ enum WorldConfigs CONFIG_INSTANCE_IGNORE_LEVEL, CONFIG_INSTANCE_IGNORE_RAID, CONFIG_BATTLEGROUND_CAST_DESERTER, + CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE, + CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY, CONFIG_INSTANCE_RESET_TIME_HOUR, CONFIG_INSTANCE_UNLOAD_DELAY, CONFIG_CAST_UNSTUCK, @@ -143,6 +151,7 @@ enum WorldConfigs CONFIG_WORLD_BOSS_LEVEL_DIFF, CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF, CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF, + CONFIG_DETECT_POS_COLLISION, CONFIG_RESTRICTED_LFG_CHANNEL, CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL, CONFIG_TALENTS_INSPECTING, @@ -316,27 +325,26 @@ enum RealmZone /// Storage class for commands issued for delayed execution struct CliCommandHolder { - typedef void Print(const char*); + typedef void Print(const char*); - char *m_command; - Print* m_print; + char *m_command; + Print* m_print; - CliCommandHolder(const char *command, Print* zprint) - : m_print(zprint) - { - size_t len = strlen(command)+1; - m_command = new char[len]; - memcpy(m_command, command, len); - } + CliCommandHolder(const char *command, Print* zprint) + : m_print(zprint) + { + size_t len = strlen(command)+1; + m_command = new char[len]; + memcpy(m_command, command, len); + } - ~CliCommandHolder() { delete[] m_command; } + ~CliCommandHolder() { delete[] m_command; } }; /// The World class World { public: - static volatile bool m_stopEvent; static volatile uint32 m_worldLoopCounter; World(); @@ -344,7 +352,6 @@ class World WorldSession* FindSession(uint32 id) const; void AddSession(WorldSession *s); - bool RemoveSession(uint32 id); /// Get the number of current active sessions void UpdateMaxSessionCounters(); @@ -407,18 +414,20 @@ class World void SetInitialWorldSettings(); void LoadConfigSettings(bool reload = false); - void SendWorldText(int32 string_id, ...); + void SendWorldText(int32 string_id, ...); void SendGlobalMessage(WorldPacket *packet, WorldSession *self = 0, uint32 team = 0); void SendZoneMessage(uint32 zone, WorldPacket *packet, WorldSession *self = 0, uint32 team = 0); void SendZoneText(uint32 zone, const char *text, WorldSession *self = 0, uint32 team = 0); void SendServerMessage(uint32 type, const char *text = "", Player* player = NULL); /// Are we in the middle of a shutdown? - uint32 GetShutdownMask() const { return m_ShutdownMask; } bool IsShutdowning() const { return m_ShutdownTimer > 0; } - void ShutdownServ(uint32 time, uint32 options = 0); + void ShutdownServ(uint32 time, uint32 options, uint8 exitcode); void ShutdownCancel(); void ShutdownMsg(bool show = false, Player* player = NULL); + static uint8 GetExitCode() { return m_ExitCode; } + static void StopNow(uint8 exitcode) { m_stopEvent = true; m_ExitCode = exitcode; } + static bool IsStopped() { return m_stopEvent; } void Update(time_t diff); @@ -453,7 +462,7 @@ class World void KickAllLess(AccountTypes sec); void KickAllQueued(); BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author); - bool RemoveBanAccount(BanMode mode, std::string nameOrIP); + bool RemoveBanAccount(BanMode mode, std::string nameOrIP); void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo> > const& scripts, uint32 id, Object* source, Object* target); void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target); @@ -481,13 +490,13 @@ class World LocaleConstant GetAvailableDbcLocale(LocaleConstant locale) const { if(m_availableDbcLocaleMask & (1 << locale)) return locale; else return m_defaultDbcLocale; } - //used World DB version - void LoadDBVersion(); - char const* GetDBVersion() { return m_DBVersion.c_str(); } + //used World DB version + void LoadDBVersion(); + char const* GetDBVersion() { return m_DBVersion.c_str(); } - //used Script version - void SetScriptsVersion(char const* version) { m_ScriptsVersion = version ? version : "unknown scripting library"; } - char const* GetScriptsVersion() { return m_ScriptsVersion.c_str(); } + //used Script version + void SetScriptsVersion(char const* version) { m_ScriptsVersion = version ? version : "unknown scripting library"; } + char const* GetScriptsVersion() { return m_ScriptsVersion.c_str(); } protected: void _UpdateGameTime(); @@ -498,6 +507,11 @@ class World void InitDailyQuestResetTime(); void ResetDailyQuests(); private: + static volatile bool m_stopEvent; + static uint8 m_ExitCode; + uint32 m_ShutdownTimer; + uint32 m_ShutdownMask; + time_t m_startTime; time_t m_gameTime; IntervalTimer m_timers[WUPDATE_COUNT]; @@ -525,9 +539,6 @@ class World std::string m_dataPath; std::set<uint32> m_forbiddenMapIds; - uint32 m_ShutdownTimer; - uint32 m_ShutdownMask; - // for max speed access static float m_MaxVisibleDistanceForCreature; static float m_MaxVisibleDistanceForPlayer; @@ -545,14 +556,14 @@ class World //Player Queue Queue m_QueuedPlayer; - + //sessions that are added async void AddSession_(WorldSession* s); ZThread::LockedQueue<WorldSession*, ZThread::FastMutex> addSessQueue; - //used versions - std::string m_DBVersion; - std::string m_ScriptsVersion; + //used versions + std::string m_DBVersion; + std::string m_ScriptsVersion; }; extern uint32 realmID; |