mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 07:18:37 +00:00
[Bots] Add support for Bot scripting. (#2515)
* [Bots] Add support for Bot scripting. # Perl - Add support for `zone/bot.pl` and `zone/bot_v#.pl`. - Add support for `global/global_bot.pl`. - Add `$bot->SignalBot(signal_id)` to Perl. - Add `$bot->OwnerMessage(message)` to Perl. - Add `$entity_list->SignalAllBotsByOwnerCharacterID(character_id, signal_id)` to Perl. - Add `$entity_list->SignalBotByBotID(bot_id, signal_id)` to Perl. - Add `$entity_list->SignalBotByBotName(bot_name, signal_id)` to Perl. - Add `EVENT_SPELL_EFFECT_BOT` to Perl. - Add `EVENT_SPELL_EFFECT_BUFF_TIC_BOT` to Perl. # Lua - Add support for `zone/bot.lua` and `zone/bot_v#.lua`. - Add support for `global/global_bot.lua`. - Add `bot:SignalBot(signal_id)` to Lua. - Add `bot:OwnerMessage(message)` to Lua. - Add `entity_list:SignalAllBotsByOwnerCharacterID(character_id, signal_id)` to Lua. - Add `entity_list:SignalBotByBotID(bot_id, signal_id)` to Lua. - Add `entity_list:SignalBotByBotName(bot_name, signal_id)` to Lua. - Add `EVENT_SPELL_EFFECT_BOT` to Lua. - Add `EVENT_SPELL_EFFECT_BUFF_TIC_BOT` to Lua. # Supported Bot Events 1. `EVENT_CAST` 2. `EVENT_CAST_BEGIN` 3. `EVENT_CAST_ON` 4. `EVENT_COMBAT` 5. `EVENT_DEATH` 6. `EVENT_DEATH_COMPLETE` 7. `EVENT_SAY` 8. `EVENT_SIGNAL` 9. `EVENT_SLAY` 10. `EVENT_SLAY_NPC` 11. `EVENT_SPAWN` 12. `EVENT_TARGET_CHANGE` 13. `EVENT_TIMER` 14. `EVENT_USE_SKILL` # Common - Convert NPC pointers in common events to Mob pointers so bots are supported. - Convert signal IDs to `int` where it wasn't already, allowing negative signals to be sent properly. * Add EVENT_POPUP_RESPONSE. * Cleanup and fix EVENT_COMBAT/EVENT_SLAY/EVENT_NPC_SLAY. * Fix DoNPCEmote calls. * Update attack.cpp * Update event_codes.h * Update bot_command.cpp
This commit is contained in:
+414
-113
@@ -163,6 +163,11 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
||||
"EVENT_TASK_BEFORE_UPDATE",
|
||||
"EVENT_AA_BUY",
|
||||
"EVENT_AA_GAIN"
|
||||
#ifdef BOTS
|
||||
,
|
||||
"EVENT_SPELL_EFFECT_BOT",
|
||||
"EVENT_SPELL_EFFECT_BUFF_TIC_BOT"
|
||||
#endif
|
||||
};
|
||||
|
||||
PerlembParser::PerlembParser() : perl(nullptr)
|
||||
@@ -170,6 +175,11 @@ PerlembParser::PerlembParser() : perl(nullptr)
|
||||
global_npc_quest_status_ = questUnloaded;
|
||||
player_quest_status_ = questUnloaded;
|
||||
global_player_quest_status_ = questUnloaded;
|
||||
|
||||
#ifdef BOTS
|
||||
bot_quest_status_ = questUnloaded;
|
||||
global_bot_quest_status_ = questUnloaded;
|
||||
#endif
|
||||
}
|
||||
|
||||
PerlembParser::~PerlembParser()
|
||||
@@ -203,15 +213,28 @@ void PerlembParser::ReloadQuests()
|
||||
global_npc_quest_status_ = questUnloaded;
|
||||
player_quest_status_ = questUnloaded;
|
||||
global_player_quest_status_ = questUnloaded;
|
||||
|
||||
#ifdef BOTS
|
||||
bot_quest_status_ = questUnloaded;
|
||||
global_bot_quest_status_ = questUnloaded;
|
||||
#endif
|
||||
|
||||
item_quest_status_.clear();
|
||||
spell_quest_status_.clear();
|
||||
}
|
||||
|
||||
int PerlembParser::EventCommon(
|
||||
QuestEventID event, uint32 objid, const char *data, NPC *npcmob, EQ::ItemInstance *item_inst, const SPDat_Spell_Struct* spell, Mob *mob,
|
||||
uint32 extradata, bool global, std::vector<std::any> *extra_pointers
|
||||
)
|
||||
{
|
||||
QuestEventID event,
|
||||
uint32 objid,
|
||||
const char *data,
|
||||
Mob *npcmob,
|
||||
EQ::ItemInstance *item_inst,
|
||||
const SPDat_Spell_Struct* spell,
|
||||
Mob *mob,
|
||||
uint32 extradata,
|
||||
bool global,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
if (!perl) {
|
||||
return 0;
|
||||
}
|
||||
@@ -220,20 +243,46 @@ int PerlembParser::EventCommon(
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool isPlayerQuest = false;
|
||||
bool isGlobalPlayerQuest = false;
|
||||
bool isGlobalNPC = false;
|
||||
bool isItemQuest = false;
|
||||
bool isSpellQuest = false;
|
||||
bool isPlayerQuest = false;
|
||||
bool isGlobalPlayerQuest = false;
|
||||
bool isGlobalNPC = false;
|
||||
bool isBotQuest = false;
|
||||
bool isGlobalBotQuest = false;
|
||||
bool isItemQuest = false;
|
||||
bool isSpellQuest = false;
|
||||
|
||||
std::string package_name;
|
||||
|
||||
GetQuestTypes(
|
||||
isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
|
||||
event, npcmob, item_inst, mob, global
|
||||
isPlayerQuest,
|
||||
isGlobalPlayerQuest,
|
||||
isBotQuest,
|
||||
isGlobalBotQuest,
|
||||
isGlobalNPC,
|
||||
isItemQuest,
|
||||
isSpellQuest,
|
||||
event,
|
||||
npcmob,
|
||||
item_inst,
|
||||
mob,
|
||||
global
|
||||
);
|
||||
|
||||
GetQuestPackageName(
|
||||
isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
|
||||
package_name, event, objid, data, npcmob, item_inst, global
|
||||
isPlayerQuest,
|
||||
isGlobalPlayerQuest,
|
||||
isBotQuest,
|
||||
isGlobalBotQuest,
|
||||
isGlobalNPC,
|
||||
isItemQuest,
|
||||
isSpellQuest,
|
||||
package_name,
|
||||
event,
|
||||
objid,
|
||||
data,
|
||||
npcmob,
|
||||
item_inst,
|
||||
global
|
||||
);
|
||||
|
||||
const char *sub_name = QuestEventSubroutines[event];
|
||||
@@ -249,6 +298,8 @@ int PerlembParser::EventCommon(
|
||||
ExportQGlobals(
|
||||
isPlayerQuest,
|
||||
isGlobalPlayerQuest,
|
||||
isBotQuest,
|
||||
isGlobalBotQuest,
|
||||
isGlobalNPC,
|
||||
isItemQuest,
|
||||
isSpellQuest,
|
||||
@@ -264,6 +315,8 @@ int PerlembParser::EventCommon(
|
||||
ExportMobVariables(
|
||||
isPlayerQuest,
|
||||
isGlobalPlayerQuest,
|
||||
isBotQuest,
|
||||
isGlobalBotQuest,
|
||||
isGlobalNPC,
|
||||
isItemQuest,
|
||||
isSpellQuest,
|
||||
@@ -290,6 +343,8 @@ int PerlembParser::EventCommon(
|
||||
|
||||
if (isPlayerQuest || isGlobalPlayerQuest) {
|
||||
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr, nullptr);
|
||||
} else if (isBotQuest || isGlobalBotQuest) {
|
||||
return SendCommands(package_name.c_str(), sub_name, 0, npcmob, mob, nullptr, nullptr);
|
||||
} else if (isItemQuest) {
|
||||
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, item_inst, nullptr);
|
||||
} else if (isSpellQuest) {
|
||||
@@ -304,19 +359,19 @@ int PerlembParser::EventCommon(
|
||||
}
|
||||
|
||||
int PerlembParser::EventNPC(
|
||||
QuestEventID evt, NPC *npc, Mob *init, std::string data, uint32 extra_data,
|
||||
QuestEventID evt, NPC *npc, Mob *mob, std::string data, uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
)
|
||||
{
|
||||
return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, nullptr, init, extra_data, false, extra_pointers);
|
||||
return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, nullptr, mob, extra_data, false, extra_pointers);
|
||||
}
|
||||
|
||||
int PerlembParser::EventGlobalNPC(
|
||||
QuestEventID evt, NPC *npc, Mob *init, std::string data, uint32 extra_data,
|
||||
QuestEventID evt, NPC *npc, Mob *mob, std::string data, uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
)
|
||||
{
|
||||
return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, nullptr, init, extra_data, true, extra_pointers);
|
||||
return EventCommon(evt, npc->GetNPCTypeID(), data.c_str(), npc, nullptr, nullptr, mob, extra_data, true, extra_pointers);
|
||||
}
|
||||
|
||||
int PerlembParser::EventPlayer(
|
||||
@@ -345,11 +400,11 @@ int PerlembParser::EventItem(
|
||||
}
|
||||
|
||||
int PerlembParser::EventSpell(
|
||||
QuestEventID evt, NPC *npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||
QuestEventID evt, Mob *mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
)
|
||||
{
|
||||
return EventCommon(evt, spell_id, data.c_str(), npc, nullptr, &spells[spell_id], client, extra_data, false, extra_pointers);
|
||||
return EventCommon(evt, spell_id, data.c_str(), mob, nullptr, &spells[spell_id], client, extra_data, false, extra_pointers);
|
||||
}
|
||||
|
||||
bool PerlembParser::HasQuestSub(uint32 npcid, QuestEventID evt)
|
||||
@@ -860,77 +915,93 @@ int PerlembParser::SendCommands(
|
||||
std::string qi = (std::string) "$" + (std::string) pkgprefix + (std::string) "::questitem";
|
||||
std::string sp = (std::string) "$" + (std::string) pkgprefix + (std::string) "::spell";
|
||||
std::string enl = (std::string) "$" + (std::string) pkgprefix + (std::string) "::entity_list";
|
||||
|
||||
#ifdef BOTS
|
||||
std::string bot = (std::string) "$" + (std::string) pkgprefix + (std::string) "::bot";
|
||||
#endif
|
||||
|
||||
if (clear_vars_.find(cl) != clear_vars_.end()) {
|
||||
std::string eval_str = cl;
|
||||
eval_str += " = undef;";
|
||||
perl->eval(eval_str.c_str());
|
||||
auto e = fmt::format("{} = undef;", cl);
|
||||
perl->eval(e.c_str());
|
||||
}
|
||||
|
||||
if (clear_vars_.find(np) != clear_vars_.end()) {
|
||||
std::string eval_str = np;
|
||||
eval_str += " = undef;";
|
||||
perl->eval(eval_str.c_str());
|
||||
auto e = fmt::format("{} = undef;", np);
|
||||
perl->eval(e.c_str());
|
||||
}
|
||||
|
||||
if (clear_vars_.find(qi) != clear_vars_.end()) {
|
||||
std::string eval_str = qi;
|
||||
eval_str += " = undef;";
|
||||
perl->eval(eval_str.c_str());
|
||||
auto e = fmt::format("{} = undef;", qi);
|
||||
perl->eval(e.c_str());
|
||||
}
|
||||
|
||||
if (clear_vars_.find(sp) != clear_vars_.end()) {
|
||||
std::string eval_str = sp;
|
||||
eval_str += " = undef;";
|
||||
perl->eval(eval_str.c_str());
|
||||
auto e = fmt::format("{} = undef;", sp);
|
||||
perl->eval(e.c_str());
|
||||
}
|
||||
|
||||
if (clear_vars_.find(enl) != clear_vars_.end()) {
|
||||
std::string eval_str = enl;
|
||||
eval_str += " = undef;";
|
||||
perl->eval(eval_str.c_str());
|
||||
auto e = fmt::format("{} = undef;", enl);
|
||||
perl->eval(e.c_str());
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
if (clear_vars_.find(bot) != clear_vars_.end()) {
|
||||
auto e = fmt::format("{} = undef;", bot);
|
||||
perl->eval(e.c_str());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
char namebuf[64];
|
||||
std::string buf;
|
||||
|
||||
//init a couple special vars: client, npc, entity_list
|
||||
Client *curc = quest_manager.GetInitiator();
|
||||
snprintf(namebuf, 64, "%s::client", pkgprefix);
|
||||
SV *client = get_sv(namebuf, true);
|
||||
if (curc != nullptr) {
|
||||
buf = fmt::format("{}::client", pkgprefix);
|
||||
SV *client = get_sv(buf.c_str(), true);
|
||||
if (curc) {
|
||||
sv_setref_pv(client, "Client", curc);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
//clear out the value, mainly to get rid of blessedness
|
||||
sv_setsv(client, _empty_sv);
|
||||
}
|
||||
|
||||
//only export NPC if it's a npc quest
|
||||
if (!other->IsClient()) {
|
||||
if (!other->IsClient() && other->IsNPC()) {
|
||||
NPC *curn = quest_manager.GetNPC();
|
||||
snprintf(namebuf, 64, "%s::npc", pkgprefix);
|
||||
SV *npc = get_sv(namebuf, true);
|
||||
buf = fmt::format("{}::npc", pkgprefix);
|
||||
SV *npc = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(npc, "NPC", curn);
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
if (!other->IsClient() && other->IsBot()) {
|
||||
Bot *curb = quest_manager.GetBot();
|
||||
buf = fmt::format("{}::bot", pkgprefix);
|
||||
SV *bot = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(bot, "Bot", curb);
|
||||
}
|
||||
#endif
|
||||
|
||||
//only export QuestItem if it's an item quest
|
||||
if (item_inst) {
|
||||
EQ::ItemInstance *curi = quest_manager.GetQuestItem();
|
||||
snprintf(namebuf, 64, "%s::questitem", pkgprefix);
|
||||
SV *questitem = get_sv(namebuf, true);
|
||||
buf = fmt::format("{}::questitem", pkgprefix);
|
||||
SV *questitem = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(questitem, "QuestItem", curi);
|
||||
}
|
||||
|
||||
if (spell) {
|
||||
const SPDat_Spell_Struct* current_spell = quest_manager.GetQuestSpell();
|
||||
SPDat_Spell_Struct* real_spell = const_cast<SPDat_Spell_Struct*>(current_spell);
|
||||
snprintf(namebuf, 64, "%s::spell", pkgprefix);
|
||||
SV *spell = get_sv(namebuf, true);
|
||||
buf = fmt::format("{}::spell", pkgprefix);
|
||||
SV *spell = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(spell, "Spell", (void *) real_spell);
|
||||
}
|
||||
|
||||
snprintf(namebuf, 64, "%s::entity_list", pkgprefix);
|
||||
SV *el = get_sv(namebuf, true);
|
||||
|
||||
buf = fmt::format("{}::entity_list", pkgprefix);
|
||||
SV *el = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(el, "EntityList", &entity_list);
|
||||
#endif
|
||||
|
||||
@@ -944,11 +1015,20 @@ int PerlembParser::SendCommands(
|
||||
std::string qi = (std::string) "$" + (std::string) pkgprefix + (std::string) "::questitem";
|
||||
std::string sp = (std::string) "$" + (std::string) pkgprefix + (std::string) "::spell";
|
||||
std::string enl = (std::string) "$" + (std::string) pkgprefix + (std::string) "::entity_list";
|
||||
|
||||
#ifdef BOTS
|
||||
std::string bot = (std::string) "$" + (std::string) pkgprefix + (std::string) "::bot";
|
||||
#endif
|
||||
|
||||
clear_vars_[cl] = 1;
|
||||
clear_vars_[np] = 1;
|
||||
clear_vars_[qi] = 1;
|
||||
clear_vars_[sp] = 1;
|
||||
clear_vars_[enl] = 1;
|
||||
|
||||
#ifdef BOTS
|
||||
clear_vars_[bot] = 1;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -967,19 +1047,16 @@ int PerlembParser::SendCommands(
|
||||
|
||||
#ifdef EMBPERL_XS_CLASSES
|
||||
if (!quest_manager.QuestsRunning()) {
|
||||
auto iter = clear_vars_.begin();
|
||||
std::string eval_str;
|
||||
while (iter != clear_vars_.end()) {
|
||||
eval_str += iter->first;
|
||||
eval_str += " = undef;";
|
||||
++iter;
|
||||
for (const auto &v : clear_vars_) {
|
||||
eval_str += fmt::format("{} = undef;", v.first);
|
||||
}
|
||||
|
||||
clear_vars_.clear();
|
||||
|
||||
try {
|
||||
perl->eval(eval_str.c_str());
|
||||
}
|
||||
catch (std::string e) {
|
||||
} catch (std::string e) {
|
||||
AddError(
|
||||
fmt::format(
|
||||
"Script Clear Error | Error [{}]",
|
||||
@@ -1023,29 +1100,61 @@ void PerlembParser::MapFunctions()
|
||||
}
|
||||
|
||||
void PerlembParser::GetQuestTypes(
|
||||
bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
||||
bool &isSpellQuest, QuestEventID event, NPC *npcmob, EQ::ItemInstance *item_inst, Mob *mob, bool global
|
||||
)
|
||||
{
|
||||
if (event == EVENT_SPELL_EFFECT_CLIENT ||
|
||||
bool &isPlayerQuest,
|
||||
bool &isGlobalPlayerQuest,
|
||||
bool &isBotQuest,
|
||||
bool &isGlobalBotQuest,
|
||||
bool &isGlobalNPC,
|
||||
bool &isItemQuest,
|
||||
bool &isSpellQuest,
|
||||
QuestEventID event,
|
||||
Mob *npcmob,
|
||||
EQ::ItemInstance *item_inst,
|
||||
Mob *mob,
|
||||
bool global
|
||||
) {
|
||||
if (
|
||||
event == EVENT_SPELL_EFFECT_CLIENT ||
|
||||
event == EVENT_SPELL_EFFECT_NPC ||
|
||||
#ifdef BOTS
|
||||
event == EVENT_SPELL_EFFECT_BOT ||
|
||||
#endif
|
||||
event == EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT ||
|
||||
event == EVENT_SPELL_EFFECT_BUFF_TIC_NPC ||
|
||||
#ifdef BOTS
|
||||
event == EVENT_SPELL_EFFECT_BUFF_TIC_BOT ||
|
||||
#endif
|
||||
event == EVENT_SPELL_FADE ||
|
||||
event == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE) {
|
||||
event == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE
|
||||
) {
|
||||
isSpellQuest = true;
|
||||
}
|
||||
else {
|
||||
if (!npcmob && mob) {
|
||||
} else {
|
||||
if (npcmob) {
|
||||
if (!item_inst) {
|
||||
if (global) {
|
||||
isGlobalPlayerQuest = true;
|
||||
}
|
||||
else {
|
||||
isPlayerQuest = true;
|
||||
if (npcmob->IsBot()) {
|
||||
isGlobalBotQuest = true;
|
||||
}
|
||||
} else {
|
||||
if (npcmob->IsBot()) {
|
||||
isBotQuest = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
isItemQuest = true;
|
||||
}
|
||||
else {
|
||||
} else if (!npcmob && mob) {
|
||||
if (!item_inst) {
|
||||
if (global) {
|
||||
if (mob->IsClient()) {
|
||||
isGlobalPlayerQuest = true;
|
||||
}
|
||||
} else {
|
||||
if (mob->IsClient()) {
|
||||
isPlayerQuest = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
isItemQuest = true;
|
||||
}
|
||||
}
|
||||
@@ -1055,6 +1164,8 @@ void PerlembParser::GetQuestTypes(
|
||||
void PerlembParser::GetQuestPackageName(
|
||||
bool &isPlayerQuest,
|
||||
bool &isGlobalPlayerQuest,
|
||||
bool &isBotQuest,
|
||||
bool &isGlobalBotQuest,
|
||||
bool &isGlobalNPC,
|
||||
bool &isItemQuest,
|
||||
bool &isSpellQuest,
|
||||
@@ -1062,7 +1173,7 @@ void PerlembParser::GetQuestPackageName(
|
||||
QuestEventID event,
|
||||
uint32 objid,
|
||||
const char *data,
|
||||
NPC *npcmob,
|
||||
Mob *npcmob,
|
||||
EQ::ItemInstance *item_inst,
|
||||
bool global
|
||||
)
|
||||
@@ -1070,6 +1181,8 @@ void PerlembParser::GetQuestPackageName(
|
||||
if (
|
||||
!isPlayerQuest &&
|
||||
!isGlobalPlayerQuest &&
|
||||
!isBotQuest &&
|
||||
!isGlobalBotQuest &&
|
||||
!isItemQuest &&
|
||||
!isSpellQuest
|
||||
) {
|
||||
@@ -1077,30 +1190,30 @@ void PerlembParser::GetQuestPackageName(
|
||||
isGlobalNPC = true;
|
||||
package_name = "qst_global_npc";
|
||||
} else {
|
||||
package_name = "qst_npc_";
|
||||
package_name += std::to_string(npcmob->GetNPCTypeID());
|
||||
package_name = fmt::format("qst_npc_{}", npcmob->GetNPCTypeID());
|
||||
}
|
||||
} else if (isItemQuest) {
|
||||
// need a valid EQ::ItemInstance pointer check here..unsure how to cancel this process
|
||||
const EQ::ItemData *item = item_inst->GetItem();
|
||||
package_name = "qst_item_";
|
||||
package_name += std::to_string(item->ID);
|
||||
package_name = fmt::format("qst_item_{}", item->ID);
|
||||
} else if (isPlayerQuest) {
|
||||
package_name = "qst_player";
|
||||
} else if (isGlobalPlayerQuest) {
|
||||
package_name = "qst_global_player";
|
||||
} else if (isBotQuest) {
|
||||
package_name = "qst_bot";
|
||||
} else if (isGlobalBotQuest) {
|
||||
package_name = "qst_global_bot";
|
||||
} else {
|
||||
package_name = "qst_spell_";
|
||||
package_name += std::to_string(objid);
|
||||
package_name = fmt::format("qst_spell_{}", objid);
|
||||
}
|
||||
}
|
||||
|
||||
void PerlembParser::ExportCharID(const std::string &package_name, int &char_id, NPC *npcmob, Mob *mob)
|
||||
void PerlembParser::ExportCharID(const std::string &package_name, int &char_id, Mob *npcmob, Mob *mob)
|
||||
{
|
||||
if (mob && mob->IsClient()) { // some events like waypoint and spawn don't have a player involved
|
||||
char_id = mob->CastToClient()->CharacterID();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (npcmob) {
|
||||
char_id = -static_cast<int>(npcmob->GetNPCTypeID()); // make char id negative npc id as a fudge
|
||||
}
|
||||
@@ -1112,29 +1225,54 @@ void PerlembParser::ExportCharID(const std::string &package_name, int &char_id,
|
||||
}
|
||||
|
||||
void PerlembParser::ExportQGlobals(
|
||||
bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
||||
bool isSpellQuest, std::string &package_name, NPC *npcmob, Mob *mob, int char_id
|
||||
)
|
||||
{
|
||||
bool isPlayerQuest,
|
||||
bool isGlobalPlayerQuest,
|
||||
bool isBotQuest,
|
||||
bool isGlobalBotQuest,
|
||||
bool isGlobalNPC,
|
||||
bool isItemQuest,
|
||||
bool isSpellQuest,
|
||||
std::string &package_name,
|
||||
Mob *npcmob,
|
||||
Mob *mob,
|
||||
int char_id
|
||||
) {
|
||||
//NPC quest
|
||||
if (!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest && !isSpellQuest) {
|
||||
if (
|
||||
!isPlayerQuest &&
|
||||
!isGlobalPlayerQuest &&
|
||||
!isBotQuest &&
|
||||
!isGlobalBotQuest &&
|
||||
!isItemQuest &&
|
||||
!isSpellQuest
|
||||
) {
|
||||
//only export for npcs that are global enabled.
|
||||
if (npcmob && npcmob->GetQglobal()) {
|
||||
std::map<std::string, std::string> globhash;
|
||||
QGlobalCache *npc_c = nullptr;
|
||||
QGlobalCache *char_c = nullptr;
|
||||
QGlobalCache *zone_c = nullptr;
|
||||
QGlobalCache *npc_c = nullptr;
|
||||
QGlobalCache *char_c = nullptr;
|
||||
QGlobalCache *zone_c = nullptr;
|
||||
|
||||
//retrieve our globals
|
||||
npc_c = npcmob->GetQGlobals();
|
||||
if (npcmob) {
|
||||
if (npcmob->IsNPC()) {
|
||||
npc_c = npcmob->CastToNPC()->GetQGlobals();
|
||||
} else if (npcmob->IsClient()) {
|
||||
char_c = npcmob->CastToClient()->GetQGlobals();
|
||||
}
|
||||
}
|
||||
|
||||
if (mob && mob->IsClient()) {
|
||||
char_c = mob->CastToClient()->GetQGlobals();
|
||||
}
|
||||
|
||||
zone_c = zone->GetQGlobals();
|
||||
|
||||
if (!npc_c) {
|
||||
npc_c = npcmob->CreateQGlobals();
|
||||
npc_c->LoadByNPCID(npcmob->GetNPCTypeID());
|
||||
if (npcmob && npcmob->IsNPC()) {
|
||||
npc_c = npcmob->CastToNPC()->CreateQGlobals();
|
||||
npc_c->LoadByNPCID(npcmob->GetNPCTypeID());
|
||||
}
|
||||
}
|
||||
|
||||
if (!char_c) {
|
||||
@@ -1157,7 +1295,8 @@ void PerlembParser::ExportQGlobals(
|
||||
npc_c->GetBucket(),
|
||||
npcmob->GetNPCTypeID(),
|
||||
char_id,
|
||||
zone->GetZoneID());
|
||||
zone->GetZoneID())
|
||||
;
|
||||
}
|
||||
|
||||
if (char_c) {
|
||||
@@ -1166,7 +1305,8 @@ void PerlembParser::ExportQGlobals(
|
||||
char_c->GetBucket(),
|
||||
npcmob->GetNPCTypeID(),
|
||||
char_id,
|
||||
zone->GetZoneID());
|
||||
zone->GetZoneID()
|
||||
);
|
||||
}
|
||||
|
||||
if (zone_c) {
|
||||
@@ -1175,7 +1315,8 @@ void PerlembParser::ExportQGlobals(
|
||||
zone_c->GetBucket(),
|
||||
npcmob->GetNPCTypeID(),
|
||||
char_id,
|
||||
zone->GetZoneID());
|
||||
zone->GetZoneID()
|
||||
);
|
||||
}
|
||||
|
||||
auto iter = globalMap.begin();
|
||||
@@ -1184,19 +1325,20 @@ void PerlembParser::ExportQGlobals(
|
||||
ExportVar(package_name.c_str(), (*iter).name.c_str(), (*iter).value.c_str());
|
||||
++iter;
|
||||
}
|
||||
|
||||
ExportHash(package_name.c_str(), "qglobals", globhash);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
std::map<std::string, std::string> globhash;
|
||||
QGlobalCache *char_c = nullptr;
|
||||
QGlobalCache *zone_c = nullptr;
|
||||
QGlobalCache *char_c = nullptr;
|
||||
QGlobalCache *zone_c = nullptr;
|
||||
|
||||
//retrieve our globals
|
||||
if (mob && mob->IsClient()) {
|
||||
char_c = mob->CastToClient()->GetQGlobals();
|
||||
}
|
||||
zone_c = zone->GetQGlobals();
|
||||
|
||||
zone_c = zone->GetQGlobals();
|
||||
|
||||
if (!char_c) {
|
||||
if (mob && mob->IsClient()) {
|
||||
@@ -1226,15 +1368,23 @@ void PerlembParser::ExportQGlobals(
|
||||
ExportVar(package_name.c_str(), (*iter).name.c_str(), (*iter).value.c_str());
|
||||
++iter;
|
||||
}
|
||||
|
||||
ExportHash(package_name.c_str(), "qglobals", globhash);
|
||||
}
|
||||
}
|
||||
|
||||
void PerlembParser::ExportMobVariables(
|
||||
bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
||||
bool isSpellQuest, std::string &package_name, Mob *mob, NPC *npcmob
|
||||
)
|
||||
{
|
||||
bool isPlayerQuest,
|
||||
bool isGlobalPlayerQuest,
|
||||
bool isBotQuest,
|
||||
bool isGlobalBotQuest,
|
||||
bool isGlobalNPC,
|
||||
bool isItemQuest,
|
||||
bool isSpellQuest,
|
||||
std::string &package_name,
|
||||
Mob *mob,
|
||||
Mob *npcmob
|
||||
) {
|
||||
uint8 fac = 0;
|
||||
if (mob && mob->IsClient()) {
|
||||
ExportVar(package_name.c_str(), "uguild_id", mob->CastToClient()->GuildID());
|
||||
@@ -1242,8 +1392,21 @@ void PerlembParser::ExportMobVariables(
|
||||
ExportVar(package_name.c_str(), "status", mob->CastToClient()->Admin());
|
||||
}
|
||||
|
||||
if (!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest) {
|
||||
if (mob && npcmob && mob->IsClient()) {
|
||||
#ifdef BOTS
|
||||
if (mob && mob->IsBot()) {
|
||||
ExportVar(package_name.c_str(), "bot_id", mob->CastToBot()->GetBotID());
|
||||
ExportVar(package_name.c_str(), "bot_owner_char_id", mob->CastToBot()->GetBotOwnerCharacterID());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (
|
||||
!isPlayerQuest &&
|
||||
!isGlobalPlayerQuest &&
|
||||
!isBotQuest &&
|
||||
!isGlobalBotQuest &&
|
||||
!isItemQuest
|
||||
) {
|
||||
if (mob && mob->IsClient() && npcmob && npcmob->IsNPC()) {
|
||||
Client *client = mob->CastToClient();
|
||||
|
||||
fac = client->GetFactionLevel(
|
||||
@@ -1261,8 +1424,15 @@ void PerlembParser::ExportMobVariables(
|
||||
ExportVar(package_name.c_str(), "userid", mob->GetID());
|
||||
}
|
||||
|
||||
if (!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest && !isSpellQuest) {
|
||||
if (npcmob) {
|
||||
if (
|
||||
!isPlayerQuest &&
|
||||
!isGlobalPlayerQuest &&
|
||||
!isBotQuest &&
|
||||
!isGlobalBotQuest &&
|
||||
!isItemQuest &&
|
||||
!isSpellQuest
|
||||
) {
|
||||
if (npcmob->IsNPC()) {
|
||||
ExportVar(package_name.c_str(), "mname", npcmob->GetName());
|
||||
ExportVar(package_name.c_str(), "mobid", npcmob->GetID());
|
||||
ExportVar(package_name.c_str(), "mlevel", npcmob->GetLevel());
|
||||
@@ -1331,14 +1501,20 @@ void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob)
|
||||
}
|
||||
|
||||
void PerlembParser::ExportEventVariables(
|
||||
std::string &package_name, QuestEventID event, uint32 objid, const char *data,
|
||||
NPC *npcmob, EQ::ItemInstance *item_inst, Mob *mob, uint32 extradata, std::vector<std::any> *extra_pointers
|
||||
)
|
||||
{
|
||||
std::string &package_name,
|
||||
QuestEventID event,
|
||||
uint32 objid,
|
||||
const char *data,
|
||||
Mob *npcmob,
|
||||
EQ::ItemInstance *item_inst,
|
||||
Mob *mob,
|
||||
uint32 extradata,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
switch (event) {
|
||||
case EVENT_SAY: {
|
||||
if (npcmob && mob) {
|
||||
npcmob->DoQuestPause(mob);
|
||||
if (npcmob && npcmob->IsNPC() && mob) {
|
||||
npcmob->CastToNPC()->DoQuestPause(mob);
|
||||
}
|
||||
|
||||
ExportVar(package_name.c_str(), "data", objid);
|
||||
@@ -1568,8 +1744,15 @@ void PerlembParser::ExportEventVariables(
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
#ifdef BOTS
|
||||
case EVENT_SPELL_EFFECT_BUFF_TIC_BOT:
|
||||
#endif
|
||||
case EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT:
|
||||
case EVENT_SPELL_EFFECT_BUFF_TIC_NPC:
|
||||
#ifdef BOTS
|
||||
case EVENT_SPELL_EFFECT_BOT:
|
||||
#endif
|
||||
case EVENT_SPELL_EFFECT_CLIENT:
|
||||
case EVENT_SPELL_EFFECT_NPC:
|
||||
case EVENT_SPELL_FADE: {
|
||||
@@ -1799,4 +1982,122 @@ void PerlembParser::ExportEventVariables(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
void PerlembParser::LoadBotScript(std::string filename)
|
||||
{
|
||||
if (!perl) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bot_quest_status_ != questUnloaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
perl->eval_file("qst_bot", filename.c_str());
|
||||
} catch (std::string e) {
|
||||
AddError(
|
||||
fmt::format(
|
||||
"Error Compiling Bot Quest File [{}] Error [{}]",
|
||||
filename,
|
||||
e
|
||||
)
|
||||
);
|
||||
|
||||
bot_quest_status_ = questFailedToLoad;
|
||||
return;
|
||||
}
|
||||
|
||||
bot_quest_status_ = questLoaded;
|
||||
}
|
||||
|
||||
void PerlembParser::LoadGlobalBotScript(std::string filename)
|
||||
{
|
||||
if (!perl) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (global_bot_quest_status_ != questUnloaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
perl->eval_file("qst_global_bot", filename.c_str());
|
||||
} catch (std::string e) {
|
||||
AddError(
|
||||
fmt::format(
|
||||
"Error Compiling Global Bot Quest File [{}] Error [{}]",
|
||||
filename,
|
||||
e
|
||||
)
|
||||
);
|
||||
|
||||
global_bot_quest_status_ = questFailedToLoad;
|
||||
return;
|
||||
}
|
||||
|
||||
global_bot_quest_status_ = questLoaded;
|
||||
}
|
||||
|
||||
bool PerlembParser::BotHasQuestSub(QuestEventID evt)
|
||||
{
|
||||
if (!perl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bot_quest_status_ != questLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (evt >= _LargestEventID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *subname = QuestEventSubroutines[evt];
|
||||
|
||||
return (perl->SubExists("qst_bot", subname));
|
||||
}
|
||||
|
||||
bool PerlembParser::GlobalBotHasQuestSub(QuestEventID evt)
|
||||
{
|
||||
if (!perl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (global_bot_quest_status_ != questLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (evt >= _LargestEventID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *subname = QuestEventSubroutines[evt];
|
||||
|
||||
return (perl->SubExists("qst_global_bot", subname));
|
||||
}
|
||||
|
||||
int PerlembParser::EventBot(
|
||||
QuestEventID evt,
|
||||
Bot *bot,
|
||||
Mob *mob,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
return EventCommon(evt, 0, data.c_str(), bot, nullptr, nullptr, mob, extra_data, false, extra_pointers);
|
||||
}
|
||||
|
||||
int PerlembParser::EventGlobalBot(
|
||||
QuestEventID evt,
|
||||
Bot *bot,
|
||||
Mob *mob,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
return EventCommon(evt, 0, data.c_str(), bot, nullptr, nullptr, mob, extra_data, true, extra_pointers);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user