Permalink
Browse files

Add full 'botguy' patch, with config controls

  • Loading branch information...
1 parent dad2c30 commit f7fa6745c0f6cde25aae06d30f3ea8b67cfd52e1 @blueboy blueboy committed Jul 6, 2010
View
@@ -0,0 +1,12 @@
+What it is:
+===========
+
+The new revised'botguy' utilizes NPCs already distributed throughout the world, to allow players to
+summon and dismiss bots at will, from their own account.
+
+This is a revised (more stable) version that utilizes the new 'GOSSIP MENU SYSTEM' to modify the menus of existing NPCs
+(e.g Trainers etc) to include the bot Recruit/Dismiss menu. (No GameMaster account necessary).
+
+Install (Server administrators only)
+=======
+Please apply 'mangos_botguy.sql' once to the world database to update the 'gossip_menu_option' table.
View
@@ -0,0 +1 @@
+INSERT INTO `gossip_menu_option` VALUES('0','16','0','GOSSIP_OPTION_BOT','99','1','0','0','0','0','0',NULL,'0','0','0','0','0','0','0','0','0');
View
@@ -406,6 +406,9 @@ class MANGOS_DLL_SPEC Creature : public Unit
bool isTotem() const { return m_subtype == CREATURE_SUBTYPE_TOTEM; }
bool isTemporarySummon() const { return m_subtype == CREATURE_SUBTYPE_TEMPORARY_SUMMON; }
+ // Playerbot mod - adds functionality to load/unload bots from NPC, also need to apply SQL scripts
+ void LoadBotMenu(Player *pPlayer);
+
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; }
bool isCivilian() const { return GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_CIVILIAN; }
@@ -48,6 +48,8 @@ enum Gossip_Option
GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER (4096)
GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER)
GOSSIP_OPTION_UNLEARNPETSKILLS = 17, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER)
+ // Playerbot mod
+ GOSSIP_OPTION_BOT = 99, //UNIT_NPC_FLAG_GOSSIP (1) UNUSED (just for bot system)
GOSSIP_OPTION_MAX
};
View
@@ -65,6 +65,7 @@
// Playerbot mod:
#include "playerbot/PlayerbotAI.h"
#include "playerbot/PlayerbotMgr.h"
+#include "Config/Config.h"
#include <cmath>
@@ -82,6 +83,8 @@
#define SKILL_PERM_BONUS(x) int16(PAIR32_HIPART(x))
#define MAKE_SKILL_BONUS(t, p) MAKE_PAIR32(t,p)
+extern Config botConfig;
+
enum CharacterFlags
{
CHARACTER_FLAG_NONE = 0x00000000,
@@ -12748,6 +12751,15 @@ void Player::PrepareGossipMenu(WorldObject *pSource, uint32 menuId)
case GOSSIP_OPTION_TABARDDESIGNER:
case GOSSIP_OPTION_AUCTIONEER:
break; // no checks
+ case GOSSIP_OPTION_BOT:
+ {
+ std::string reqQuestIds = botConfig.GetStringDefault("PlayerbotAI.BotguyQuests","");
+ uint32 cost = botConfig.GetIntDefault("PlayerbotAI.BotguyCost",0);
+ if((reqQuestIds == "" || requiredQuests(reqQuestIds.c_str())) && !pCreature->isInnkeeper() && this->GetMoney() >= cost)
+ pCreature->LoadBotMenu(this);
+ hasMenuItem = false;
+ break;
+ }
default:
sLog.outErrorDb("Creature entry %u have unknown gossip option %u for menu %u", pCreature->GetEntry(), itr->second.option_id, itr->second.menu_id);
hasMenuItem = false;
@@ -12894,12 +12906,12 @@ void Player::OnGossipSelect(WorldObject* pSource, uint32 gossipListId, uint32 me
}
}
- GossipMenuItemData pMenuData = gossipmenu.GetItemData(gossipListId);
-
switch(gossipOptionId)
{
case GOSSIP_OPTION_GOSSIP:
{
+ GossipMenuItemData pMenuData = gossipmenu.GetItemData(gossipListId);
+
if (pMenuData.m_gAction_poi)
PlayerTalkClass->SendPointOfInterest(pMenuData.m_gAction_poi);
@@ -12983,6 +12995,27 @@ void Player::OnGossipSelect(WorldObject* pSource, uint32 gossipListId, uint32 me
GetSession()->SendBattlegGroundList(guid, bgTypeId);
break;
}
+ case GOSSIP_OPTION_BOT:
+ {
+ // DEBUG_LOG("GOSSIP_OPTION_BOT");
+ PlayerTalkClass->CloseGossip();
+ uint32 cost = botConfig.GetIntDefault("PlayerbotAI.BotguyCost",0);
+
+ if (!GetPlayerbotMgr())
+ SetPlayerbotMgr(new PlayerbotMgr(this));
+
+ uint64 guidlo = PlayerTalkClass->GossipOptionSender(gossipListId);
+ if(GetPlayerbotMgr()->GetPlayerBot(guidlo) != NULL)
+ {
+ GetPlayerbotMgr()->LogoutPlayerBot(guidlo);
+ }
+ else if(GetPlayerbotMgr()->GetPlayerBot(guidlo) == NULL)
+ {
+ GetPlayerbotMgr()->AddPlayerBot(guidlo);
+ this->ModifyMoney(-(int32)cost);
+ }
+ break;
+ }
}
}
View
@@ -1491,6 +1491,10 @@ class MANGOS_DLL_SPEC Player : public Unit
void AddTimedQuest( uint32 quest_id ) { m_timedquests.insert(quest_id); }
void RemoveTimedQuest( uint32 quest_id ) { m_timedquests.erase(quest_id); }
+ void chompAndTrim(std::string& str);
+ bool getNextQuestId(const std::string& pString, unsigned int& pStartPos, unsigned int& pId);
+ bool requiredQuests(const char* pQuestIdString);
+
/*********************************************************/
/*** LOAD SYSTEM ***/
/*********************************************************/
@@ -542,6 +542,108 @@ void PlayerbotMgr::RemoveAllBotsFromGroup()
}
}
+void Creature::LoadBotMenu(Player *pPlayer)
+{
+
+ if (pPlayer->GetPlayerbotAI()) return;
+ uint64 guid = pPlayer->GetGUID();
+ uint32 accountId = sObjectMgr.GetPlayerAccountIdByGUID(guid);
+ QueryResult *result = CharacterDatabase.PQuery("SELECT guid, name FROM characters WHERE account='%d'",accountId);
+ do
+ {
+ Field *fields = result->Fetch();
+ uint64 guidlo = fields[0].GetUInt64();
+ std::string name = fields[1].GetString();
+ std::string word = "";
+
+ if( (guid == 0) || (guid == guidlo) )
+ {
+ //not found or himself
+ }
+ else
+ {
+ // if(sConfig.GetBoolDefault("PlayerbotAI.DisableBots", false)) return;
+ // create the manager if it doesn't already exist
+ if (! pPlayer->GetPlayerbotMgr())
+ pPlayer->SetPlayerbotMgr(new PlayerbotMgr(pPlayer));
+ if(pPlayer->GetPlayerbotMgr()->GetPlayerBot(guidlo) == NULL) // add (if not already in game)
+ {
+ word += "Recruit ";
+ word += name;
+ word += " as a Bot.";
+ pPlayer->PlayerTalkClass->GetGossipMenu().AddMenuItem((uint8)9, word, guidlo, GOSSIP_OPTION_BOT, word, false);
+ }
+ else if(pPlayer->GetPlayerbotMgr()->GetPlayerBot(guidlo) != NULL) // remove (if in game)
+ {
+ word += "Dismiss ";
+ word += name;
+ word += " from duty.";
+ pPlayer->PlayerTalkClass->GetGossipMenu().AddMenuItem((uint8)0, word, guidlo, GOSSIP_OPTION_BOT, word, false);
+ }
+ }
+ }
+ while (result->NextRow());
+ delete result;
+}
+
+void Player::chompAndTrim(std::string& str)
+{
+ while(str.length() >0)
+ {
+ char lc = str[str.length()-1];
+ if(lc == '\r' || lc == '\n' || lc == ' ' || lc == '"' || lc == '\'')
+ str = str.substr(0,str.length()-1);
+ else
+ break;
+ while(str.length() >0)
+ {
+ char lc = str[0];
+ if(lc == ' ' || lc == '"' || lc == '\'')
+ str = str.substr(1,str.length()-1);
+ else
+ break;
+ }
+ }
+}
+
+bool Player::getNextQuestId(const std::string& pString, unsigned int& pStartPos, unsigned int& pId)
+{
+ bool result = false;
+ unsigned int i;
+ for(i=pStartPos;i<pString.size(); ++i)
+ {
+ if(pString[i] == ',')
+ break;
+ }
+ if(i>pStartPos)
+ {
+ std::string idString = pString.substr(pStartPos, i-pStartPos);
+ pStartPos = i+1;
+ chompAndTrim(idString);
+ pId = atoi(idString.c_str());
+ result = true;
+ }
+ return(result);
+}
+
+bool Player::requiredQuests(const char* pQuestIdString)
+{
+ if(pQuestIdString != NULL)
+ {
+ unsigned int pos = 0;
+ unsigned int id;
+ std::string confString(pQuestIdString);
+ chompAndTrim(confString);
+ while(getNextQuestId(confString, pos, id))
+ {
+ QuestStatus status = GetQuestStatus( id );
+ if ( status == QUEST_STATUS_COMPLETE )
+ return true;
+ }
+ }
+ return false;
+}
+
bool ChatHandler::HandlePlayerbotCommand(const char* args)
{
if(!(m_session->GetSecurity() > SEC_PLAYER))
@@ -31,6 +31,17 @@ ConfVersion=2010062001
# Restrict the allowed bot level (Current Max 80)
# Default: 80
#
+# PlayerbotAI.BotguyQuests
+# List of Quest ids, any of which, once completed will enable botguy menu on NPCs
+# List must be enclosed in double quotes ("") and multiple Quest Ids separated by a delimiter(,)
+# Example: "805,54,2160"
+# Default: "" no quest restriction, memu always displayed by NPCs
+#
+# PlayerbotAI.BotguyCost
+# Cost (Copper coins) levied on summoning a bot
+# If player has the cost, botguy menu will be displayed by NPCs
+# Default: 0 - no cost, menu always displayed by NPCs
+#
###################################################################################################################
PlayerbotAI.DisableBots = 0
@@ -39,3 +50,5 @@ PlayerbotAI.FollowDistanceMin = 0.5
PlayerbotAI.FollowDistanceMax = 1.0
PlayerbotAI.MaxNumBots = 9
PlayerbotAI.RestrictBotLevel = 80
+PlayerbotAI.BotguyQuests = ""
+PlayerbotAI.BotguyCost = 0

0 comments on commit f7fa674

Please sign in to comment.