aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/extractor/libmpq/common.h6
-rw-r--r--contrib/extractor/libmpq/mpq.cpp2
-rw-r--r--sql/updates/176_world.sql32
-rw-r--r--src/game/CharacterHandler.cpp21
-rw-r--r--src/game/Chat.cpp1
-rw-r--r--src/game/Chat.h1
-rw-r--r--src/game/Creature.cpp58
-rw-r--r--src/game/Creature.h38
-rw-r--r--src/game/Level2.cpp17
-rw-r--r--src/game/NPCHandler.cpp14
-rw-r--r--src/game/ObjectMgr.cpp119
-rw-r--r--src/game/ObjectMgr.h15
-rw-r--r--src/game/OutdoorPvPEP.cpp6
-rw-r--r--src/game/OutdoorPvPZM.cpp4
-rw-r--r--src/game/Player.cpp26
-rw-r--r--src/game/QueryHandler.cpp2
-rw-r--r--src/game/QuestHandler.cpp4
-rw-r--r--src/game/SharedDefines.h7
-rw-r--r--src/game/Spell.cpp14
-rw-r--r--src/game/SpellEffects.cpp8
-rw-r--r--src/game/World.cpp7
-rw-r--r--src/game/WorldSession.cpp1
-rw-r--r--src/trinitycore/trinitycore.conf.dist4
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