Core/Scripts/SmartAI: removed test code

Core/CreatureTextMgr: added reload command
handle text from DB
handle grouped texts
handle repeatable/single texts based on probability
todo: sound/emote, code cleanup

--HG--
branch : trunk
This commit is contained in:
Rat
2010-09-26 20:48:25 +02:00
parent 133ab88f8c
commit bbf86641a1
9 changed files with 162 additions and 14 deletions
+1
View File
@@ -643,6 +643,7 @@ INSERT INTO `command` VALUES
('reload creature_template','3','Syntax: .reload creature_template $entry\r\nReload the specified creature''s template.'),
('reload trinity_string',3,'Syntax: .reload trinity_string\nReload trinity_string table.'),
('reload waypoint_scripts',3,'Syntax: .reload waypoint_scripts\nReload waypoint_scripts table.'),
('reload creature_text',3,'Syntax: .reload creature_text\r\nReload creature_text table.'),
('repairitems',2,'Syntax: .repairitems\r\n\r\nRepair all selected player''s items.'),
('reset',3,'Syntax: .reset $subcommand\nType .reset to see the list of possible subcommands or .help reset $subcommand to see info on subcommands'),
('reset achievements',3,'Syntax: .reset achievements [$playername]\r\n\r\nReset achievements data for selected or named (online or offline) character. Achievements for persistance progress data like completed quests/etc re-filled at reset. Achievements for events like kills/casts/etc will lost.'),
+3
View File
@@ -0,0 +1,3 @@
DELETE FROM `command` WHERE `name` LIKE 'reload creature_text';
INSERT INTO `command` (`name`,`security`,`help`) VALUES
('reload creature_text',3,'Syntax: .reload creature_text\r\nReload creature_text table.');
-6
View File
@@ -35,7 +35,6 @@ void SmartAIMgr::LoadSmartAIFromDB()
SmartAI::SmartAI(Creature *c) : CreatureAI(c)
{
// copy script to local (pretection for table reload)
mTestTimer = 0;
}
int SmartAI::Permissible(const Creature *creature)
@@ -47,11 +46,6 @@ int SmartAI::Permissible(const Creature *creature)
void SmartAI::UpdateAI(const uint32 diff)
{
if (mTestTimer < diff)
{
mTestTimer = 60000;
sCreatureTextMgr.SendChat(me,"CHAT_TYPE_SAY", CHAT_TYPE_SAY);
} else mTestTimer -= diff;
}
void SmartAI::JustRespawned()
-1
View File
@@ -362,7 +362,6 @@ class SmartAI : public CreatureAI
void SetMovePathEndAction(SMARTAI_ACTION action = SMART_ACTION_FORCE_DESPAWN);
private:
uint32 mTestTimer;
};
#define sSmartAIMgr (*ACE_Singleton<SmartAIMgr, ACE_Null_Mutex>::instance())
+1
View File
@@ -469,6 +469,7 @@ ChatCommand * ChatHandler::getCommandTable()
{ "autobroadcast", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadAutobroadcastCommand, "", NULL },
{ "command", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCommandCommand, "", NULL },
{ "conditions", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadConditions, "", NULL },
{ "creature_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureText, "", NULL },
{ "creature_ai_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAIScriptsCommand, "", NULL },
{ "creature_ai_summons", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAISummonsCommand, "", NULL },
{ "creature_ai_texts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadEventAITextsCommand, "", NULL },
+1
View File
@@ -450,6 +450,7 @@ class ChatHandler
bool HandleReloadAuctionsCommand(const char* args);
bool HandleReloadWpScriptsCommand(const char* args);
bool HandleReloadConditions(const char* args);
bool HandleReloadCreatureText(const char* args);
bool HandleResetAchievementsCommand(const char * args);
bool HandleResetAllCommand(const char * args);
+9
View File
@@ -60,6 +60,7 @@
#include "WeatherMgr.h"
#include "ScriptMgr.h"
#include "LFGMgr.h"
#include "CreatureTextMgr.h"
//reload commands
bool ChatHandler::HandleReloadAllCommand(const char*)
@@ -1170,6 +1171,14 @@ bool ChatHandler::HandleReloadConditions(const char* /*args*/)
return true;
}
bool ChatHandler::HandleReloadCreatureText(const char* /*args*/)
{
sLog.outString("Re-Loading Creature Texts...");
sCreatureTextMgr.LoadCreatureTexts();
SendGlobalGMSysMessage("Creature Texts reloaded.");
return true;
}
bool ChatHandler::HandleAccountSetGmLevelCommand(const char *args)
{
if (!*args)
+131 -1
View File
@@ -26,6 +26,7 @@
void CreatureTextMgr::LoadCreatureTexts()
{
mTextMap.clear(); // for reload case
mTextRepeatMap.clear(); //reset all currently used temp texts
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_LOAD_CRETEXT);
PreparedQueryResult result = WorldDatabase.Query(stmt);
@@ -108,8 +109,131 @@ void CreatureTextMgr::LoadCreatureTexts()
sLog.outString(">> Loaded %u Creature Texts for %u Creatures.", TextCount, CreatureCount);
}
void CreatureTextMgr::SendChat(WorldObject* source, char const* text, ChatType msgtype, Language language, uint64 whisperGuid, TextRange range) const
void CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, uint64 whisperGuid, ChatType msgtype, Language language, TextRange range)
{
if (!source)
return;
CreatureTextMap::const_iterator sList = mTextMap.find(source->GetEntry());
if (sList == mTextMap.end())
{
sLog.outErrorDb("CreatureTextMgr: Could not find Text for Creature(%s) Entry %u in 'creature_text' table. Ignoring.",source->GetName(), source->GetEntry());
return;
}
CreatureTextHolder TextHolder = (*sList).second;
CreatureTextHolder::const_iterator itr = TextHolder.find(textGroup);
if (itr == TextHolder.end())
{
sLog.outErrorDb("CreatureTextMgr: Could not find TextGroup %u for Creature(%s) GuidLow %u Entry %u. Ignoring.",uint32(textGroup), source->GetName(), source->GetGUIDLow(), source->GetEntry());
return;
}
CreatureTextGroup TextGroup = (*itr).second;//has all texts in the group
CreatureTextRepeatIds repeatGroup = GetRepeatGroup(source,textGroup);//has all textIDs from the group that were already said
CreatureTextGroup tempGroup;//will use this to talk after sorting repeatGroup
for (CreatureTextGroup::const_iterator giter = TextGroup.begin(); giter != TextGroup.end(); ++giter)
{
if (std::find(repeatGroup.begin(), repeatGroup.end(), (*giter).id) == repeatGroup.end())
tempGroup.push_back((*giter));
}
if (tempGroup.empty())
{
//mTextRepeatMap[source->GetGUID()][textGroup].clear();
CreatureTextRepeatMap::iterator mapItr = mTextRepeatMap.find(source->GetGUID());
if (mapItr != mTextRepeatMap.end())
{
CreatureTextRepeatGroup::iterator groupItr = (*mapItr).second.find(textGroup);
(*groupItr).second.clear();
}
tempGroup = TextGroup;
}
uint8 count = 0;
float lastChance = -1;
bool isEqualChanced = true;
float totalChance = 0;
for (CreatureTextGroup::const_iterator iter = tempGroup.begin(); iter != tempGroup.end(); ++iter)
{
if (lastChance >= 0 && lastChance != (*iter).probability)
isEqualChanced = false;
lastChance = (*iter).probability;
totalChance += (*iter).probability;
count++;
}
if (isEqualChanced)
{
uint32 pos = urand(0,count - 1);
CreatureTextGroup::const_iterator iter = tempGroup.begin() + pos;
SendChatString(source, (*iter).text.c_str(), (*iter).type, (*iter).lang, whisperGuid);
SetRepeatId(source, textGroup, (*iter).id);
}else
{
for (CreatureTextGroup::const_iterator iter = tempGroup.begin(); iter != tempGroup.end(); ++iter)
{
uint32 chance = uint32((*iter).probability);
uint32 r = urand(0, 100);
if (r <= chance)
{
SendChatString(source, (*iter).text.c_str(), (*iter).type, (*iter).lang, whisperGuid);
if (totalChance == 100.0f)// only if total chances are 100 do not repeat
SetRepeatId(source, textGroup, (*iter).id);
return;
}
}
uint32 pos = urand(0,count - 1);
CreatureTextGroup::const_iterator iter = tempGroup.begin() + pos;
SendChatString(source, (*iter).text.c_str(), (*iter).type, (*iter).lang, whisperGuid);
SetRepeatId(source, textGroup, (*iter).id);
}
}
void CreatureTextMgr::SetRepeatId(Creature* source, uint8 textGroup, uint8 id)
{
if (!source)
return;
if (mTextRepeatMap.find(source->GetGUID()) == mTextRepeatMap.end())
{
CreatureTextRepeatGroup TextGroup;
mTextRepeatMap[source->GetGUID()] = TextGroup;
}
if (mTextRepeatMap[source->GetGUID()].find(textGroup) == mTextRepeatMap[source->GetGUID()].end())
{
CreatureTextRepeatIds ids;
mTextRepeatMap[source->GetGUID()][textGroup] = ids;
}
if (std::find(mTextRepeatMap[source->GetGUID()][textGroup].begin(), mTextRepeatMap[source->GetGUID()][textGroup].end(), id) == mTextRepeatMap[source->GetGUID()][textGroup].end())
{
mTextRepeatMap[source->GetGUID()][textGroup].push_back(id);
}
else
sLog.outErrorDb("CreatureTextMgr: TextGroup %u for Creature(%s) GuidLow %u Entry %u, id %u already added",uint32(textGroup), source->GetName(), source->GetGUIDLow(), source->GetEntry(), uint32(id));
}
CreatureTextRepeatIds CreatureTextMgr::GetRepeatGroup(Creature* source, uint8 textGroup)
{
ASSERT(source);//should never happen
CreatureTextRepeatIds ids;
CreatureTextRepeatMap::const_iterator mapItr = mTextRepeatMap.find(source->GetGUID());
if (mapItr != mTextRepeatMap.end())
{
CreatureTextRepeatGroup::const_iterator groupItr = (*mapItr).second.find(textGroup);
if (groupItr != (*mapItr).second.end())
{
ids = (*groupItr).second;
}
}
return ids;
}
void CreatureTextMgr::SendChatString(WorldObject* source, char const* text, ChatType msgtype, Language language, uint64 whisperGuid, TextRange range) const
{
if (!source)
return;
WorldPacket data(SMSG_MESSAGECHAT, 200);
BuildMonsterChat(&data, source, msgtype, text, language, whisperGuid);//build our packet
SendChatPacket(&data, source, msgtype, whisperGuid, range);//send our packet
@@ -117,6 +241,9 @@ void CreatureTextMgr::SendChat(WorldObject* source, char const* text, ChatType m
void CreatureTextMgr::BuildMonsterChat(WorldPacket *data, WorldObject* source, ChatType msgtype, char const* text, Language language, uint64 whisperGuid) const
{
if (!source)
return;
ChatMsg sendType = CHAT_MSG_MONSTER_SAY;
switch (msgtype)
{
@@ -172,6 +299,9 @@ void CreatureTextMgr::BuildMonsterChat(WorldPacket *data, WorldObject* source, C
void CreatureTextMgr::SendChatPacket(WorldPacket *data, WorldObject* source, ChatType msgtype, uint64 whisperGuid, TextRange range) const
{
if (!source)
return;
float dist = sWorld.getFloatConfig(CONFIG_LISTEN_RANGE_SAY);
switch (msgtype)
+16 -6
View File
@@ -52,9 +52,14 @@ enum TextRange
typedef std::vector<CreatureTextEntry> CreatureTextGroup; //texts in a group
typedef UNORDERED_MAP<uint32, CreatureTextGroup> CreatureTextHolder; //groups for a creature
typedef UNORDERED_MAP<uint32, CreatureTextHolder> CreatureTextMap; //all creatures
typedef std::vector<CreatureTextEntry> CreatureTextGroup; //texts in a group
typedef UNORDERED_MAP<uint8, CreatureTextGroup> CreatureTextHolder; //groups for a creature by groupid
typedef UNORDERED_MAP<uint32, CreatureTextHolder> CreatureTextMap; //all creatures by entry
//used for handling non-repeatable random texts
typedef std::vector<uint8> CreatureTextRepeatIds;
typedef UNORDERED_MAP<uint8, CreatureTextRepeatIds> CreatureTextRepeatGroup;
typedef UNORDERED_MAP<uint64, CreatureTextRepeatGroup> CreatureTextRepeatMap;//guid based
class CreatureTextMgr
{
@@ -65,12 +70,17 @@ class CreatureTextMgr
void LoadCreatureTexts();
CreatureTextMap const& GetTextMap() const { return mTextMap; }
void SendChat(WorldObject* source, char const* text, ChatType msgtype = CHAT_TYPE_SAY, Language language = LANG_UNIVERSAL, uint64 whisperGuid = 0, TextRange range = TEXT_RANGE_NORMAL) const;
void SendChat(Creature* source, uint8 textGroup, uint64 whisperGuid = 0, ChatType msgtype = CHAT_TYPE_SAY, Language language = LANG_UNIVERSAL, TextRange range = TEXT_RANGE_NORMAL);
void SendChatString(WorldObject* source, char const* text, ChatType msgtype = CHAT_TYPE_SAY, Language language = LANG_UNIVERSAL, uint64 whisperGuid = 0, TextRange range = TEXT_RANGE_NORMAL) const;
private:
CreatureTextMap mTextMap;
CreatureTextRepeatIds GetRepeatGroup(Creature* source, uint8 textGroup);
void SetRepeatId(Creature* source, uint8 textGroup, uint8 id);
void BuildMonsterChat(WorldPacket *data, WorldObject* source, ChatType msgtype, char const* text, Language language, uint64 whisperGuid) const;
void SendChatPacket(WorldPacket *data, WorldObject* source, ChatType msgtype, uint64 whisperGuid, TextRange range) const;
CreatureTextMap mTextMap;
CreatureTextRepeatMap mTextRepeatMap;
};
#define sCreatureTextMgr (*ACE_Singleton<CreatureTextMgr, ACE_Null_Mutex>::instance())