diff options
-rw-r--r-- | contrib/extractor/libmpq/common.h | 6 | ||||
-rw-r--r-- | contrib/extractor/libmpq/mpq.cpp | 2 | ||||
-rw-r--r-- | sql/updates/176_world.sql | 32 | ||||
-rw-r--r-- | src/game/CharacterHandler.cpp | 21 | ||||
-rw-r--r-- | src/game/Chat.cpp | 1 | ||||
-rw-r--r-- | src/game/Chat.h | 1 | ||||
-rw-r--r-- | src/game/Creature.cpp | 58 | ||||
-rw-r--r-- | src/game/Creature.h | 38 | ||||
-rw-r--r-- | src/game/Level2.cpp | 17 | ||||
-rw-r--r-- | src/game/NPCHandler.cpp | 14 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 119 | ||||
-rw-r--r-- | src/game/ObjectMgr.h | 15 | ||||
-rw-r--r-- | src/game/OutdoorPvPEP.cpp | 6 | ||||
-rw-r--r-- | src/game/OutdoorPvPZM.cpp | 4 | ||||
-rw-r--r-- | src/game/Player.cpp | 26 | ||||
-rw-r--r-- | src/game/QueryHandler.cpp | 2 | ||||
-rw-r--r-- | src/game/QuestHandler.cpp | 4 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 7 | ||||
-rw-r--r-- | src/game/Spell.cpp | 14 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 8 | ||||
-rw-r--r-- | src/game/World.cpp | 7 | ||||
-rw-r--r-- | src/game/WorldSession.cpp | 1 | ||||
-rw-r--r-- | src/trinitycore/trinitycore.conf.dist | 4 |
23 files changed, 301 insertions, 106 deletions
diff --git a/contrib/extractor/libmpq/common.h b/contrib/extractor/libmpq/common.h index ad2c0f101fa..5794c162e10 100644 --- a/contrib/extractor/libmpq/common.h +++ b/contrib/extractor/libmpq/common.h @@ -49,6 +49,12 @@ #include <io.h> #endif +#ifdef O_LARGEFILE + #define MPQ_FILE_OPEN_FLAGS (O_RDONLY | O_BINARY | O_LARGEFILE) +#else + #define MPQ_FILE_OPEN_FLAGS (O_RDONLY | O_BINARY) +#endif + #ifndef min #define min(a, b) ((a < b) ? a : b) #endif diff --git a/contrib/extractor/libmpq/mpq.cpp b/contrib/extractor/libmpq/mpq.cpp index 0761d81caae..9582b72b560 100644 --- a/contrib/extractor/libmpq/mpq.cpp +++ b/contrib/extractor/libmpq/mpq.cpp @@ -59,7 +59,7 @@ int libmpq_archive_open(mpq_archive *mpq_a, unsigned char *mpq_filename) { memset(mpq_a->header, 0, sizeof(mpq_header)); /* Check if file exists and is readable */ - fd = _open((char *)mpq_filename, O_RDONLY | O_BINARY | O_LARGEFILE); + fd = _open((char *)mpq_filename, MPQ_FILE_OPEN_FLAGS); if (fd == LIBMPQ_EFILE) { return LIBMPQ_EFILE; } diff --git a/sql/updates/176_world.sql b/sql/updates/176_world.sql new file mode 100644 index 00000000000..03c720d7ef5 --- /dev/null +++ b/sql/updates/176_world.sql @@ -0,0 +1,32 @@ +ALTER TABLE `npc_option`
+ CHANGE COLUMN `id` `id` mediumint(8) unsigned NOT NULL default '0',
+ CHANGE COLUMN `gossip_id` `gossip_id` mediumint(8) unsigned NOT NULL default '0',
+ CHANGE COLUMN `action` `action` mediumint(8) unsigned NOT NULL default '0',
+ ADD COLUMN `box_money` int(10) unsigned NOT NULL default '0' AFTER `action`,
+ ADD COLUMN `coded` tinyint(3) unsigned NOT NULL default '0' AFTER `box_money`,
+ ADD COLUMN `box_text` text AFTER `option_text`;
+
+CREATE TABLE `locales_npc_option` (
+ `entry` mediumint(8) unsigned NOT NULL default '0',
+ `option_text_loc1` text,
+ `option_text_loc2` text,
+ `option_text_loc3` text,
+ `option_text_loc4` text,
+ `option_text_loc5` text,
+ `option_text_loc6` text,
+ `option_text_loc7` text,
+ `option_text_loc8` text,
+ `box_text_loc1` text,
+ `box_text_loc2` text,
+ `box_text_loc3` text,
+ `box_text_loc4` text,
+ `box_text_loc5` text,
+ `box_text_loc6` text,
+ `box_text_loc7` text,
+ `box_text_loc8` text,
+ PRIMARY KEY (`entry`)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
+
+ALTER TABLE `creature_template`
+ CHANGE COLUMN `flags` `unit_flags` int(10) unsigned NOT NULL default '0',
+ CHANGE COLUMN `flag1` `type_flags` int(10) unsigned NOT NULL default '0';
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 88677cbca07..bc897fd8fec 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -130,9 +130,10 @@ void WorldSession::HandleCharEnum(QueryResult * result) Player *plr = new Player(this); do { - sLog.outDetail("Loading char guid %u from account %u.",(*result)[0].GetUInt32(),GetAccountId()); + uint32 guidlow = (*result)[0].GetUInt32(); + sLog.outDetail("Loading char guid %u from account %u.",guidlow,GetAccountId()); - if(plr->MinimalLoadFromDB( result, (*result)[0].GetUInt32() )) + if(plr->MinimalLoadFromDB( result, guidlow )) { plr->BuildEnumData( result, &data ); ++num; @@ -155,18 +156,18 @@ void WorldSession::HandleCharEnumOpcode( WorldPacket & /*recv_data*/ ) CharacterDatabase.AsyncPQuery(&chrHandler, &CharacterHandler::HandleCharEnumCallback, GetAccountId(), !sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) ? // ------- Query Without Declined Names -------- - // 0 1 2 3 4 5 6 7 8 - "SELECT characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, characters.at_login, " - // 9 10 11 - "character_pet.entry, character_pet.modelid, character_pet.level " + // 0 1 2 3 4 5 6 7 8 + "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " + // 9 10 11 12 + "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level " "FROM characters LEFT JOIN character_pet ON characters.guid=character_pet.owner AND character_pet.slot='0' " "WHERE characters.account = '%u' ORDER BY characters.guid" : // --------- Query With Declined Names --------- - // 0 1 2 3 4 5 6 7 8 - "SELECT characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, characters.at_login, " - // 9 10 11 12 - "character_pet.entry, character_pet.modelid, character_pet.level, genitive " + // 0 1 2 3 4 5 6 7 8 + "SELECT characters.guid, characters.data, characters.name, characters.position_x, characters.position_y, characters.position_z, characters.map, characters.totaltime, characters.leveltime, " + // 9 10 11 12 13 + "characters.at_login, character_pet.entry, character_pet.modelid, character_pet.level, genitive " "FROM characters LEFT JOIN character_pet ON characters.guid = character_pet.owner AND character_pet.slot='0' " "LEFT JOIN character_declinedname ON characters.guid = character_declinedname.guid " "WHERE characters.account = '%u' ORDER BY characters.guid", diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index b72a02c3373..c2687563aa0 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -231,6 +231,7 @@ ChatCommand * ChatHandler::getCommandTable() { "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL }, { "trinity_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadTrinityStringCommand, "", NULL }, { "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL }, + { "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL }, { "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL }, { "npc_vendor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL }, { "page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadPageTextsCommand, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index f92e748bd8a..08e90f34414 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -191,6 +191,7 @@ class ChatHandler bool HandleReloadLootTemplatesSkinningCommand(const char* args); bool HandleReloadTrinityStringCommand(const char* args); bool HandleReloadNpcGossipCommand(const char* args); + bool HandleReloadNpcOptionCommand(const char* args); bool HandleReloadNpcTrainerCommand(const char* args); bool HandleReloadNpcVendorCommand(const char* args); bool HandleReloadQuestAreaTriggersCommand(const char* args); diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 3a1565d2a88..322a2aea95d 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -287,7 +287,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) SetAttackTime(OFF_ATTACK, GetCreatureInfo()->baseattacktime); SetAttackTime(RANGED_ATTACK,GetCreatureInfo()->rangeattacktime); - SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->Flags); + SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->unit_flags); SetUInt32Value(UNIT_DYNAMIC_FLAGS,GetCreatureInfo()->dynamicflags); SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(GetCreatureInfo()->armor)); @@ -697,12 +697,9 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid ) // lazy loading single time at use LoadGossipOptions(); - GossipOption* gso; - GossipOption* ingso; - for( GossipOptionList::iterator i = m_goptions.begin( ); i != m_goptions.end( ); i++ ) { - gso=&*i; + GossipOption* gso=&*i; if(gso->GossipId == gossipid) { bool cantalking=true; @@ -774,15 +771,29 @@ void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid ) cantalking = false; break; default: - sLog.outErrorDb("Creature %u (entry: %u) have unknown gossip option %u",GetGUIDLow(),GetEntry(),gso->Action); + sLog.outErrorDb("Creature %u (entry: %u) have unknown gossip option %u",GetDBTableGUIDLow(),GetEntry(),gso->Action); break; } } - if(!gso->Option.empty() && cantalking ) - { //note for future dev: should have database fields for BoxMessage & BoxMoney - pm->GetGossipMenu().AddMenuItem((uint8)gso->Icon,gso->Option, gossipid,gso->Action,"",0,false); - ingso=gso; + //note for future dev: should have database fields for BoxMessage & BoxMoney + if(!gso->OptionText.empty() && cantalking) + { + std::string OptionText = gso->OptionText; + std::string BoxText = gso->BoxText; + int loc_idx = pPlayer->GetSession()->GetSessionDbLocaleIndex(); + if (loc_idx >= 0) + { + NpcOptionLocale const *no = objmgr.GetNpcOptionLocale(gso->Id); + if (no) + { + if (no->OptionText.size() > loc_idx && !no->OptionText[loc_idx].empty()) + OptionText=no->OptionText[loc_idx]; + if (no->BoxText.size() > loc_idx && !no->BoxText[loc_idx].empty()) + BoxText=no->BoxText[loc_idx]; + } + } + pm->GetGossipMenu().AddMenuItem((uint8)gso->Icon,OptionText, gossipid,gso->Action,BoxText,gso->BoxMoney,gso->Coded); } } } @@ -835,7 +846,6 @@ void Creature::OnGossipSelect(Player* player, uint32 option) uint64 guid=GetGUID(); GossipOption const *gossip=GetGossipOption( action ); - uint32 textid; if(!gossip) { zoneid=0; @@ -843,7 +853,7 @@ void Creature::OnGossipSelect(Player* player, uint32 option) if(!gossip) return; } - textid=GetGossipTextId( action, zoneid); + uint32 textid=GetGossipTextId( action, zoneid); if(textid==0) textid=GetNpcTextId(); @@ -935,7 +945,7 @@ void Creature::OnPoiSelect(Player* player, GossipOption const *gossip) Map const* map=MapManager::Instance().GetBaseMap( mapid ); uint16 areaflag=map->GetAreaFlag(GetPositionX(),GetPositionY()); uint32 zoneid=Map::GetZoneId(areaflag,mapid); - std::string areaname= gossip->Option; + std::string areaname= gossip->OptionText; /* uint16 pflag; @@ -1040,24 +1050,10 @@ void Creature::LoadGossipOptions() uint32 npcflags=GetUInt32Value(UNIT_NPC_FLAGS); - QueryResult *result = WorldDatabase.PQuery( "SELECT id,gossip_id,npcflag,icon,action,option_text FROM npc_option WHERE (npcflag & %u)<>0", npcflags ); - - if(!result) - return; - - GossipOption go; - do - { - Field *fields = result->Fetch(); - go.Id= fields[0].GetUInt32(); - go.GossipId = fields[1].GetUInt32(); - go.NpcFlag=fields[2].GetUInt32(); - go.Icon=fields[3].GetUInt32(); - go.Action=fields[4].GetUInt32(); - go.Option=fields[5].GetCppString(); - addGossipOption(go); - }while( result->NextRow() ); - delete result; + CacheNpcOptionList const& noList = objmgr.GetNpcOptions (); + for (CacheNpcOptionList::const_iterator i = noList.begin (); i != noList.end (); ++i) + if(i->NpcFlag & npcflags) + addGossipOption(*i); m_gossipOptionLoaded = true; } diff --git a/src/game/Creature.h b/src/game/Creature.h index dcbe6a47b29..0ccc1ca3f9d 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -112,7 +112,10 @@ struct GossipOption uint32 NpcFlag; uint32 Icon; uint32 Action; - std::string Option; + uint32 BoxMoney; + bool Coded; + std::string OptionText; + std::string BoxText; }; enum CreatureFlagsExtra @@ -166,9 +169,9 @@ struct CreatureInfo uint32 attackpower; uint32 baseattacktime; uint32 rangeattacktime; - uint32 Flags; + uint32 unit_flags; // enum UnitFlags mask values uint32 dynamicflags; - uint32 family; + uint32 family; // enum CreatureFamily values for type==CREATURE_TYPE_BEAST, or 0 in another cases uint32 trainer_type; uint32 trainer_spell; uint32 classNum; @@ -176,8 +179,8 @@ struct CreatureInfo float minrangedmg; float maxrangedmg; uint32 rangedattackpower; - uint32 type; - uint32 flag1; + uint32 type; // enum CreatureType values + uint32 type_flags; // enum CreatureTypeFlags mask values uint32 lootid; uint32 pickpocketLootId; uint32 SkinLootId; @@ -205,6 +208,21 @@ struct CreatureInfo char const* ScriptName; uint32 GetRandomValidModelId() const; uint32 GetFirstValidModelId() const; + + SkillType GetRequiredLootSkill() const + { + if(type_flags & CREATURE_TYPEFLAGS_HERBLOOT) + return SKILL_HERBALISM; + else if(type_flags & CREATURE_TYPEFLAGS_MININGLOOT) + return SKILL_MINING; + else + return SKILL_SKINNING; // normal case + } + + bool isTameable() const + { + return type == CREATURE_TYPE_BEAST && family != 0 && (type_flags & CREATURE_TYPEFLAGS_TAMEBLE); + } }; struct CreatureLocale @@ -213,6 +231,12 @@ struct CreatureLocale std::vector<std::string> SubName; }; +struct NpcOptionLocale +{ + std::vector<std::string> OptionText; + std::vector<std::string> BoxText; +}; + struct EquipmentInfo { uint32 entry; @@ -473,8 +497,8 @@ class TRINITY_DLL_SPEC Creature : public Unit CreatureDataAddon const* GetCreatureAddon() const; char const* GetScriptName() const; - void prepareGossipMenu( Player *pPlayer,uint32 gossipid ); - void sendPreparedGossip( Player* player); + void prepareGossipMenu( Player *pPlayer, uint32 gossipid = 0 ); + void sendPreparedGossip( Player* player ); void OnGossipSelect(Player* player, uint32 option); void OnPoiSelect(Player* player, GossipOption const *gossip); diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index ec86797eacd..722ed64fb97 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1796,7 +1796,8 @@ bool ChatHandler::HandlePInfoCommand(const char* args) else { accId = objmgr.GetPlayerAccountIdByGUID(targetGUID); - Player plr(m_session); // use current session for temporary load + WorldSession session(0,NULL,SEC_PLAYER,0,0,LOCALE_enUS); + Player plr(&session); // use fake session for temporary load plr.MinimalLoadFromDB(NULL, targetGUID); money = plr.GetMoney(); total_player_time = plr.GetTotalPlayedTime(); @@ -4132,6 +4133,13 @@ bool ChatHandler::HandleCreatePetCommand(const char* args) { Player *player = m_session->GetPlayer(); Creature *creatureTarget = getSelectedCreature(); + + if(!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) + { + PSendSysMessage(LANG_SELECT_CREATURE); + SetSentErrorMessage(true); + return false; + } CreatureInfo const* cInfo = objmgr.GetCreatureTemplate(creatureTarget->GetEntry()); // Creatures with family 0 crashes the server @@ -4148,13 +4156,6 @@ bool ChatHandler::HandleCreatePetCommand(const char* args) SetSentErrorMessage(true); return false; } - - if(!creatureTarget || creatureTarget->isPet() || creatureTarget->GetTypeId() == TYPEID_PLAYER) - { - PSendSysMessage(LANG_SELECT_CREATURE); - SetSentErrorMessage(true); - return false; - } // Everything looks OK, create new pet Pet* pet = new Pet(HUNTER_PET); diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index f765a09dea4..bec37717239 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -297,8 +297,8 @@ void WorldSession::HandleGossipHelloOpcode( WorldPacket & recv_data ) if(!Script->GossipHello( _player, unit )) { _player->TalkedToCreature(unit->GetEntry(),unit->GetGUID()); - unit->prepareGossipMenu(_player,0); - unit->sendPreparedGossip( _player ); + unit->prepareGossipMenu(_player); + unit->sendPreparedGossip(_player); } } @@ -338,13 +338,15 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) if(!code.empty()) { - if(!Script->GossipSelectWithCode( _player, unit, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option ), code.c_str()) ) - unit->OnGossipSelect( _player, option ); + if (!Script->GossipSelectWithCode(_player, unit, _player->PlayerTalkClass->GossipOptionSender (option), _player->PlayerTalkClass->GossipOptionAction( option ), code.c_str())) + unit->OnGossipSelect (_player, option); } else - if(!Script->GossipSelect( _player, unit, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option )) ) - unit->OnGossipSelect( _player, option ); + { + if (!Script->GossipSelect (_player, unit, _player->PlayerTalkClass->GossipOptionSender (option), _player->PlayerTalkClass->GossipOptionAction (option))) + unit->OnGossipSelect (_player, option); + } } void WorldSession::HandleSpiritHealerActivateOpcode( WorldPacket & recv_data ) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 5715af51061..97a0ce0c9e8 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -624,6 +624,74 @@ void ObjectMgr::LoadCreatureLocales() sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() ); } +void ObjectMgr::LoadNpcOptionLocales() +{ + mNpcOptionLocaleMap.clear(); // need for reload case + + QueryResult *result = WorldDatabase.Query("SELECT entry," + "option_text_loc1,box_text_loc1,option_text_loc2,box_text_loc2," + "option_text_loc3,box_text_loc3,option_text_loc4,box_text_loc4," + "option_text_loc5,box_text_loc5,option_text_loc6,box_text_loc6," + "option_text_loc7,box_text_loc7,option_text_loc8,box_text_loc8 " + "FROM locales_npc_option"); + + if(!result) + { + barGoLink bar(1); + + bar.step(); + + sLog.outString(""); + sLog.outString(">> Loaded 0 npc_option locale strings. DB table `locales_npc_option` is empty."); + return; + } + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + + NpcOptionLocale& data = mNpcOptionLocaleMap[entry]; + + for(int i = 1; i < MAX_LOCALE; ++i) + { + std::string str = fields[1+2*(i-1)].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.OptionText.size() <= idx) + data.OptionText.resize(idx+1); + + data.OptionText[idx] = str; + } + } + str = fields[1+2*(i-1)+1].GetCppString(); + if(!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if(idx >= 0) + { + if(data.BoxText.size() <= idx) + data.BoxText.resize(idx+1); + + data.BoxText[idx] = str; + } + } + } + } while (result->NextRow()); + + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %u npc_option locale strings", mNpcOptionLocaleMap.size() ); +} + void ObjectMgr::LoadCreatureTemplates() { sCreatureStorage.Load(); @@ -7076,6 +7144,57 @@ void ObjectMgr::LoadNpcTextId() sLog.outString( ">> Loaded %d NpcTextId ", count ); } +void ObjectMgr::LoadNpcOptions() +{ + m_mCacheNpcOptionList.clear(); // For reload case + + QueryResult *result = WorldDatabase.Query( + // 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 ); + + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded `npc_option`, table is empty!"); + return; + } + + barGoLink bar( result->GetRowCount() ); + + uint32 count = 0; + + do + { + bar.step(); + + Field* fields = result->Fetch(); + + GossipOption go; + go.Id = fields[0].GetUInt32(); + go.GossipId = fields[1].GetUInt32(); + go.NpcFlag = fields[2].GetUInt32(); + go.Icon = fields[3].GetUInt32(); + go.Action = fields[4].GetUInt32(); + go.BoxMoney = fields[5].GetUInt32(); + go.Coded = fields[6].GetUInt8()!=0; + go.OptionText = fields[7].GetCppString(); + go.BoxText = fields[8].GetCppString(); + + m_mCacheNpcOptionList.push_back(go); + + ++count; + + } while (result->NextRow()); + delete result; + + sLog.outString(); + sLog.outString( ">> Loaded %d npc_option entries", count ); +} + void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost, bool savetodb) { VendorItemData& vList = m_mCacheVendorItemMap[entry]; diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 43e460ab94a..c40ba87d7f2 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -75,6 +75,7 @@ struct GameTele }; typedef HM_NAMESPACE::hash_map<uint32, GameTele > GameTeleMap; +typedef std::list<GossipOption> CacheNpcOptionList; struct ScriptInfo { @@ -141,6 +142,7 @@ typedef HM_NAMESPACE::hash_map<uint32,QuestLocale> QuestLocaleMap; typedef HM_NAMESPACE::hash_map<uint32,NpcTextLocale> NpcTextLocaleMap; typedef HM_NAMESPACE::hash_map<uint32,PageTextLocale> PageTextLocaleMap; typedef HM_NAMESPACE::hash_map<uint32,TrinityStringLocale> TrinityStringLocaleMap; +typedef HM_NAMESPACE::hash_map<uint32,NpcOptionLocale> NpcOptionLocaleMap; typedef std::multimap<uint32,uint32> QuestRelations; @@ -537,6 +539,7 @@ class ObjectMgr void LoadQuestLocales(); void LoadNpcTextLocales(); void LoadPageTextLocales(); + void LoadNpcOptionLocales(); void LoadInstanceTemplate(); void LoadGossipText(); @@ -567,6 +570,7 @@ class ObjectMgr void LoadWeatherZoneChances(); void LoadGameTele(); + void LoadNpcOptions(); void LoadNpcTextId(); void LoadVendors(); void LoadTrainerSpell(); @@ -664,6 +668,13 @@ class ObjectMgr if(itr==mPageTextLocaleMap.end()) return NULL; return &itr->second; } + + NpcOptionLocale const* GetNpcOptionLocale(uint32 entry) const + { + NpcOptionLocaleMap::const_iterator itr = mNpcOptionLocaleMap.find(entry); + if(itr==mNpcOptionLocaleMap.end()) return NULL; + return &itr->second; + } GameObjectData const* GetGOData(uint32 guid) const { @@ -742,6 +753,8 @@ 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 { @@ -874,6 +887,7 @@ class ObjectMgr NpcTextLocaleMap mNpcTextLocaleMap; PageTextLocaleMap mPageTextLocaleMap; TrinityStringLocaleMap mTrinityStringLocaleMap; + NpcOptionLocaleMap mNpcOptionLocaleMap; RespawnTimes mCreatureRespawnTimes; RespawnTimes mGORespawnTimes; @@ -884,6 +898,7 @@ class ObjectMgr typedef std::vector<PlayerCondition> ConditionStore; ConditionStore mConditions; + CacheNpcOptionList m_mCacheNpcOptionList; CacheNpcTextIdMap m_mCacheNpcTextIdMap; CacheVendorItemMap m_mCacheVendorItemMap; CacheTrainerSpellMap m_mCacheTrainerSpellMap; diff --git a/src/game/OutdoorPvPEP.cpp b/src/game/OutdoorPvPEP.cpp index 8ffcb4b1f62..d2d58ea00f3 100644 --- a/src/game/OutdoorPvPEP.cpp +++ b/src/game/OutdoorPvPEP.cpp @@ -703,7 +703,7 @@ void OutdoorPvPObjectiveEP_PWT::SummonFlightMaster(uint32 team) GossipOption gso; gso.Action = GOSSIP_OPTION_OUTDOORPVP; gso.GossipId = 0; - gso.Option.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_NPT)); + gso.OptionText.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_NPT)); gso.Id = 50; gso.Icon = 0; gso.NpcFlag = 0; @@ -711,7 +711,7 @@ void OutdoorPvPObjectiveEP_PWT::SummonFlightMaster(uint32 team) gso.Action = GOSSIP_OPTION_OUTDOORPVP; gso.GossipId = 0; - gso.Option.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_EWT)); + gso.OptionText.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_EWT)); gso.Id = 50; gso.Icon = 0; gso.NpcFlag = 0; @@ -719,7 +719,7 @@ void OutdoorPvPObjectiveEP_PWT::SummonFlightMaster(uint32 team) gso.Action = GOSSIP_OPTION_OUTDOORPVP; gso.GossipId = 0; - gso.Option.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_CGT)); + gso.OptionText.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_CGT)); gso.Id = 50; gso.Icon = 0; gso.NpcFlag = 0; diff --git a/src/game/OutdoorPvPZM.cpp b/src/game/OutdoorPvPZM.cpp index 94706f046f3..071a008225f 100644 --- a/src/game/OutdoorPvPZM.cpp +++ b/src/game/OutdoorPvPZM.cpp @@ -400,12 +400,12 @@ bool OutdoorPvPObjectiveZM_GraveYard::CanTalkTo(Player * plr, Creature * c, Goss { if(itr->second == ZM_ALLIANCE_FIELD_SCOUT && plr->GetTeam() == ALLIANCE && m_BothControllingFaction == ALLIANCE && !m_FlagCarrierGUID && m_GraveYardState != ZM_GRAVEYARD_A) { - gso.Option.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_GOSSIP_ALLIANCE)); + gso.OptionText.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_GOSSIP_ALLIANCE)); return true; } else if(itr->second == ZM_HORDE_FIELD_SCOUT && plr->GetTeam() == HORDE && m_BothControllingFaction == HORDE && !m_FlagCarrierGUID && m_GraveYardState != ZM_GRAVEYARD_H) { - gso.Option.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_GOSSIP_HORDE)); + gso.OptionText.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_GOSSIP_HORDE)); return true; } } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 8b2edce2895..dc4092540d9 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -1352,7 +1352,7 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) char_flags |= CHARACTER_FLAG_RENAME; // always send the flag if declined names aren't used // to let the client select a default method of declining the name - if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[12].GetCppString() != "")) + if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[13].GetCppString() != "")) char_flags |= CHARACTER_FLAG_DECLINED; *p_data << (uint32)char_flags; // character flags @@ -1370,12 +1370,12 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data ) { Field* fields = result->Fetch(); - uint32 entry = fields[9].GetUInt32(); + uint32 entry = fields[10].GetUInt32(); CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry); if(cInfo) { - petDisplayId = fields[10].GetUInt32(); - petLevel = fields[11].GetUInt32(); + petDisplayId = fields[11].GetUInt32(); + petLevel = fields[12].GetUInt32(); petFamily = cInfo->family; } } @@ -13495,15 +13495,15 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid ) bool delete_result = true; if(!result) { - // 0 1 2 3 4 5 6 7 8 - result = CharacterDatabase.PQuery("SELECT data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login FROM characters WHERE guid = '%u'",guid); + // 0 1 2 3 4 5 6 7 8 9 + result = CharacterDatabase.PQuery("SELECT guid, data, name, position_x, position_y, position_z, map, totaltime, leveltime, at_login FROM characters WHERE guid = '%u'",guid); if(!result) return false; } else delete_result = false; Field *fields = result->Fetch(); - if(!LoadValues( fields[0].GetString())) + if(!LoadValues( fields[1].GetString())) { sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid)); if(delete_result) delete result; @@ -13513,16 +13513,16 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid ) // overwrite possible wrong/corrupted guid SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER)); - m_name = fields[1].GetCppString(); + m_name = fields[2].GetCppString(); - Relocate(fields[2].GetFloat(),fields[3].GetFloat(),fields[4].GetFloat()); - SetMapId(fields[5].GetUInt32()); + Relocate(fields[3].GetFloat(),fields[4].GetFloat(),fields[5].GetFloat()); + SetMapId(fields[6].GetUInt32()); // the instance id is not needed at character enum - m_Played_time[0] = fields[6].GetUInt32(); - m_Played_time[1] = fields[7].GetUInt32(); + m_Played_time[0] = fields[7].GetUInt32(); + m_Played_time[1] = fields[8].GetUInt32(); - m_atLoginFlags = fields[8].GetUInt32(); + m_atLoginFlags = fields[9].GetUInt32(); // I don't see these used anywhere .. /*_LoadGroup(); diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp index fe38ac2bdc7..efd27281e29 100644 --- a/src/game/QueryHandler.cpp +++ b/src/game/QueryHandler.cpp @@ -181,7 +181,7 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data ) data << uint8(0) << uint8(0) << uint8(0); // name2, name3, name4, always empty data << SubName; data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 - data << (uint32)ci->flag1; // flags wdbFeild7=wad flags1 + data << (uint32)ci->type_flags; // flags wdbFeild7=wad flags1 data << (uint32)ci->type; data << (uint32)ci->family; // family wdbFeild9 data << (uint32)ci->rank; // rank wdbFeild10 diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index bac85b6b4b0..7215f5a6060 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -105,8 +105,8 @@ void WorldSession::HandleQuestgiverHelloOpcode( WorldPacket & recv_data ) if(Script->GossipHello( _player, pCreature ) ) return; - pCreature->prepareGossipMenu(_player,0); - pCreature->sendPreparedGossip( _player ); + pCreature->prepareGossipMenu(_player); + pCreature->sendPreparedGossip(_player); } void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data ) diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 756e03ecb0c..072c6947cdf 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -1600,6 +1600,13 @@ enum CreatureFamily CREATURE_FAMILY_SEA_LION = 36 }; +enum CreatureTypeFlags +{ + CREATURE_TYPEFLAGS_TAMEBLE = 0x0001, + CREATURE_TYPEFLAGS_HERBLOOT = 0x0100, + CREATURE_TYPEFLAGS_MININGLOOT = 0x0200, +}; + enum CreatureEliteType { CREATURE_ELITE_NORMAL = 0, diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 4795d64bfcc..7b4c855474c 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -3669,13 +3669,7 @@ uint8 Spell::CanCast(bool strict) return SPELL_FAILED_TARGET_NOT_LOOTED; } - uint32 skill; - if(creature->GetCreatureInfo()->flag1 & 256) - skill = SKILL_HERBALISM; // special case - else if(creature->GetCreatureInfo()->flag1 & 512) - skill = SKILL_MINING; // special case - else - skill = SKILL_SKINNING; // normal case + uint32 skill = creature->GetCreatureInfo()->GetRequiredLootSkill(); int32 skillValue = ((Player*)m_caster)->GetSkillValue(skill); int32 TargetLevel = m_targets.getUnitTarget()->getLevel(); @@ -3967,12 +3961,8 @@ uint8 Spell::CanCast(bool strict) if (m_targets.getUnitTarget()->getLevel() > m_caster->getLevel()) return SPELL_FAILED_HIGHLEVEL; - CreatureInfo const *cinfo = ((Creature*)m_targets.getUnitTarget())->GetCreatureInfo(); - if( cinfo->type != CREATURE_TYPE_BEAST ) - return SPELL_FAILED_BAD_TARGETS; - // use SMSG_PET_TAME_FAILURE? - if( !(cinfo->flag1 & 1) || !(cinfo->family) ) + if (!((Creature*)m_targets.getUnitTarget())->GetCreatureInfo()->isTameable ()) return SPELL_FAILED_BAD_TARGETS; if(m_caster->GetPetGUID()) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 6aa85b976d7..39329e58bfd 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -5555,13 +5555,7 @@ void Spell::EffectSkinning(uint32 /*i*/) Creature* creature = (Creature*) unitTarget; int32 targetLevel = creature->getLevel(); - uint32 skill; - if(creature->GetCreatureInfo()->flag1 & 256) - skill = SKILL_HERBALISM; // special case - else if(creature->GetCreatureInfo()->flag1 & 512) - skill = SKILL_MINING; // special case - else - skill = SKILL_SKINNING; // normal case + uint32 skill = creature->GetCreatureInfo()->GetRequiredLootSkill(); ((Player*)m_caster)->SendLoot(creature->GetGUID(),LOOT_SKINNING); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); diff --git a/src/game/World.cpp b/src/game/World.cpp index 0eefc688789..d02aa8a1f6f 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -982,6 +982,7 @@ void World::SetInitialWorldSettings() objmgr.LoadQuestLocales(); objmgr.LoadNpcTextLocales(); objmgr.LoadPageTextLocales(); + objmgr.LoadNpcOptionLocales(); objmgr.SetDBCLocaleIndex(GetDefaultDbcLocale()); // Get once for all the locale index of DBC language (console/broadcasts) sLog.outString( "Loading Page Texts..." ); @@ -1160,6 +1161,9 @@ 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(); sLog.outString( "Loading vendors..." ); objmgr.LoadVendors(); // must be after load CreatureTemplate and ItemTemplate @@ -2472,7 +2476,10 @@ void World::UpdateSessions( time_t diff ) ///- Delete kicked sessions at add new session for (std::set<WorldSession*>::iterator itr = m_kicked_sessions.begin(); itr != m_kicked_sessions.end(); ++itr) + { + RemoveQueuedPlayer (*itr); delete *itr; + } m_kicked_sessions.clear(); ///- Then send an update signal to remaining ones diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 0b37f5252b1..0e6dfedc162 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -79,7 +79,6 @@ WorldSession::~WorldSession() delete packet; } - sWorld.RemoveQueuedPlayer(this); } void WorldSession::SizeError(WorldPacket const& packet, uint32 size) const diff --git a/src/trinitycore/trinitycore.conf.dist b/src/trinitycore/trinitycore.conf.dist index 9bd69ec6c5e..d8ca0dcc172 100644 --- a/src/trinitycore/trinitycore.conf.dist +++ b/src/trinitycore/trinitycore.conf.dist @@ -244,7 +244,7 @@ AddonChannel = 1 # # WorldLogFile # Packet logging file for the worldserver -# Default: "world.log" +# Default: "" # # DBErrorLogFile # Log file of DB errors detected at server run @@ -301,7 +301,7 @@ LogFileLevel = 0 LogFilter_TransportMoves = 1 LogFilter_CreatureMoves = 1 LogFilter_VisibilityChanges = 1 -WorldLogFile = "world.log" +WorldLogFile = "" DBErrorLogFile = "db_errors.log" CharLogFile = "characters.log" CharLogTimestamp = 0 |