mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +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:
parent
7ea77ee027
commit
856aa51cb8
@ -1528,7 +1528,7 @@ struct CZSetEntityVariable_Struct {
|
|||||||
struct CZSignal_Struct {
|
struct CZSignal_Struct {
|
||||||
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name, 6 - NPC
|
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name, 6 - NPC
|
||||||
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
|
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
|
||||||
uint32 signal;
|
int signal;
|
||||||
char client_name[64]; // Only used by Character Name Type, else empty
|
char client_name[64]; // Only used by Character Name Type, else empty
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1601,7 +1601,7 @@ struct WWSetEntityVariable_Struct {
|
|||||||
|
|
||||||
struct WWSignal_Struct {
|
struct WWSignal_Struct {
|
||||||
uint8 update_type; // 0 - Character, 1 - NPC
|
uint8 update_type; // 0 - Character, 1 - NPC
|
||||||
uint32 signal;
|
int signal;
|
||||||
uint8 min_status;
|
uint8 min_status;
|
||||||
uint8 max_status;
|
uint8 max_status;
|
||||||
};
|
};
|
||||||
|
|||||||
252
zone/attack.cpp
252
zone/attack.cpp
@ -1454,6 +1454,17 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, boo
|
|||||||
LogCombat("Attack missed. Damage set to 0");
|
LogCombat("Attack missed. Damage set to 0");
|
||||||
hit.damage_done = 0;
|
hit.damage_done = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
if (IsBot()) {
|
||||||
|
const auto export_string = fmt::format(
|
||||||
|
"{} {}",
|
||||||
|
hit.skill,
|
||||||
|
GetSkill(hit.skill)
|
||||||
|
);
|
||||||
|
parse->EventBot(EVENT_USE_SKILL, CastToBot(), nullptr, export_string, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1707,22 +1718,26 @@ void Client::Damage(Mob* other, int64 damage, uint16 spell_id, EQ::skills::Skill
|
|||||||
|
|
||||||
bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::SkillType attack_skill)
|
bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::SkillType attack_skill)
|
||||||
{
|
{
|
||||||
if (!ClientFinishedLoading())
|
if (!ClientFinishedLoading()) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (dead)
|
if (dead) {
|
||||||
return false; //cant die more than once...
|
return false; //cant die more than once...
|
||||||
|
}
|
||||||
|
|
||||||
if (!spell)
|
if (!spell) {
|
||||||
spell = SPELL_UNKNOWN;
|
spell = SPELL_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
std::string export_string = fmt::format(
|
auto export_string = fmt::format(
|
||||||
"{} {} {} {}",
|
"{} {} {} {}",
|
||||||
killerMob ? killerMob->GetID() : 0,
|
killerMob ? killerMob->GetID() : 0,
|
||||||
damage,
|
damage,
|
||||||
spell,
|
spell,
|
||||||
static_cast<int>(attack_skill)
|
static_cast<int>(attack_skill)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (parse->EventPlayer(EVENT_DEATH, this, export_string, 0) != 0) {
|
if (parse->EventPlayer(EVENT_DEATH, this, export_string, 0) != 0) {
|
||||||
if (GetHP() < 0) {
|
if (GetHP() < 0) {
|
||||||
SetHP(0);
|
SetHP(0);
|
||||||
@ -1793,24 +1808,36 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
|||||||
GetMerc()->Suspend();
|
GetMerc()->Suspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (killerMob != nullptr)
|
if (killerMob) {
|
||||||
{
|
|
||||||
if (killerMob->IsNPC()) {
|
if (killerMob->IsNPC()) {
|
||||||
parse->EventNPC(EVENT_SLAY, killerMob->CastToNPC(), this, "", 0);
|
parse->EventNPC(EVENT_SLAY, killerMob->CastToNPC(), this, "", 0);
|
||||||
|
|
||||||
mod_client_death_npc(killerMob);
|
mod_client_death_npc(killerMob);
|
||||||
|
|
||||||
uint32 emoteid = killerMob->GetEmoteID();
|
auto emote_id = killerMob->GetEmoteID();
|
||||||
if (emoteid != 0)
|
if (emote_id) {
|
||||||
killerMob->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledPC, emoteid);
|
killerMob->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledPC, emoteid);
|
||||||
|
}
|
||||||
|
|
||||||
killerMob->TrySpellOnKill(killed_level, spell);
|
killerMob->TrySpellOnKill(killed_level, spell);
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (killerMob->IsBot()) {
|
||||||
|
parse->EventBot(EVENT_SLAY, killerMob->CastToBot(), this, "", 0);
|
||||||
|
killerMob->TrySpellOnKill(killed_level, spell);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (killerMob->IsClient() && (IsDueling() || killerMob->CastToClient()->IsDueling())) {
|
if (
|
||||||
|
killerMob->IsClient() &&
|
||||||
|
(IsDueling() || killerMob->CastToClient()->IsDueling())
|
||||||
|
) {
|
||||||
SetDueling(false);
|
SetDueling(false);
|
||||||
SetDuelTarget(0);
|
SetDuelTarget(0);
|
||||||
if (killerMob->IsClient() && killerMob->CastToClient()->IsDueling() && killerMob->CastToClient()->GetDuelTarget() == GetID())
|
if (
|
||||||
{
|
killerMob->IsClient() &&
|
||||||
|
killerMob->CastToClient()->IsDueling() &&
|
||||||
|
killerMob->CastToClient()->GetDuelTarget() == GetID()
|
||||||
|
) {
|
||||||
//if duel opponent killed us...
|
//if duel opponent killed us...
|
||||||
killerMob->CastToClient()->SetDueling(false);
|
killerMob->CastToClient()->SetDueling(false);
|
||||||
killerMob->CastToClient()->SetDuelTarget(0);
|
killerMob->CastToClient()->SetDuelTarget(0);
|
||||||
@ -1843,16 +1870,19 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
|||||||
|
|
||||||
// figure out if they should lose exp
|
// figure out if they should lose exp
|
||||||
if (RuleB(Character, UseDeathExpLossMult)) {
|
if (RuleB(Character, UseDeathExpLossMult)) {
|
||||||
float GetNum[] = { 0.005f,0.015f,0.025f,0.035f,0.045f,0.055f,0.065f,0.075f,0.085f,0.095f,0.110f };
|
float exp_losses[] = { 0.005f, 0.015f, 0.025f, 0.035f, 0.045f, 0.055f, 0.065f, 0.075f, 0.085f, 0.095f, 0.110f };
|
||||||
int Num = RuleI(Character, DeathExpLossMultiplier);
|
int exp_loss = RuleI(Character, DeathExpLossMultiplier);
|
||||||
if ((Num < 0) || (Num > 10))
|
if (!EQ::ValueWithin(exp_loss, 0, 10)) {
|
||||||
Num = 3;
|
exp_loss = 3;
|
||||||
float loss = GetNum[Num];
|
}
|
||||||
exploss = (int)((float)GetEXP() * (loss)); //loose % of total XP pending rule (choose 0-10)
|
|
||||||
|
auto current_exp_loss = exp_losses[exp_loss];
|
||||||
|
|
||||||
|
exploss = static_cast<int>(static_cast<float>(GetEXP()) * current_exp_loss); //loose % of total XP pending rule (choose 0-10)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RuleB(Character, UseDeathExpLossMult)) {
|
if (!RuleB(Character, UseDeathExpLossMult)) {
|
||||||
exploss = (int)(GetLevel() * (GetLevel() / 18.0) * 12000);
|
exploss = static_cast<int>(GetLevel() * (GetLevel() / 18.0) * 12000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RuleB(Zone, LevelBasedEXPMods)) {
|
if (RuleB(Zone, LevelBasedEXPMods)) {
|
||||||
@ -1873,56 +1903,49 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((GetLevel() < RuleI(Character, DeathExpLossLevel)) || (GetLevel() > RuleI(Character, DeathExpLossMaxLevel)) || IsBecomeNPC())
|
if ((GetLevel() < RuleI(Character, DeathExpLossLevel)) || (GetLevel() > RuleI(Character, DeathExpLossMaxLevel)) || IsBecomeNPC()) {
|
||||||
{
|
|
||||||
exploss = 0;
|
exploss = 0;
|
||||||
}
|
} else if (killerMob) {
|
||||||
else if (killerMob)
|
if (killerMob->IsClient()) {
|
||||||
{
|
|
||||||
if (killerMob->IsClient())
|
|
||||||
{
|
|
||||||
exploss = 0;
|
exploss = 0;
|
||||||
}
|
} else if (killerMob->GetOwner() && killerMob->GetOwner()->IsClient()) {
|
||||||
else if (killerMob->GetOwner() && killerMob->GetOwner()->IsClient())
|
|
||||||
{
|
|
||||||
exploss = 0;
|
exploss = 0;
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (killerMob->IsBot()) {
|
||||||
|
exploss = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spell != SPELL_UNKNOWN)
|
if (spell != SPELL_UNKNOWN) {
|
||||||
{
|
|
||||||
uint32 buff_count = GetMaxTotalSlots();
|
uint32 buff_count = GetMaxTotalSlots();
|
||||||
for (uint16 buffIt = 0; buffIt < buff_count; buffIt++)
|
for (uint16 buffIt = 0; buffIt < buff_count; buffIt++) {
|
||||||
{
|
if (buffs[buffIt].spellid == spell && buffs[buffIt].client) {
|
||||||
if (buffs[buffIt].spellid == spell && buffs[buffIt].client)
|
|
||||||
{
|
|
||||||
exploss = 0; // no exp loss for pvp dot
|
exploss = 0; // no exp loss for pvp dot
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LeftCorpse = false;
|
bool leave_corpse = false;
|
||||||
Corpse* new_corpse = nullptr;
|
Corpse* new_corpse = nullptr;
|
||||||
|
|
||||||
// now we apply the exp loss, unmem their spells, and make a corpse
|
// now we apply the exp loss, unmem their spells, and make a corpse
|
||||||
// unless they're a GM (or less than lvl 10
|
// unless they're a GM (or less than lvl 10
|
||||||
if (!GetGM())
|
if (!GetGM()) {
|
||||||
{
|
|
||||||
if (exploss > 0) {
|
if (exploss > 0) {
|
||||||
int32 newexp = GetEXP();
|
int32 newexp = GetEXP();
|
||||||
if (exploss > newexp) {
|
if (exploss > newexp) {
|
||||||
//lost more than we have... wtf..
|
//lost more than we have... wtf..
|
||||||
newexp = 1;
|
newexp = 1;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
newexp -= exploss;
|
newexp -= exploss;
|
||||||
}
|
}
|
||||||
SetEXP(newexp, GetAAXP());
|
SetEXP(newexp, GetAAXP());
|
||||||
//m_epp.perAA = 0; //reset to no AA exp on death.
|
//m_epp.perAA = 0; //reset to no AA exp on death.
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 illusion_spell_id = spellbonuses.Illusion;
|
auto illusion_spell_id = spellbonuses.Illusion;
|
||||||
|
|
||||||
//this generates a lot of 'updates' to the client that the client does not need
|
//this generates a lot of 'updates' to the client that the client does not need
|
||||||
if (RuleB(Spells, BuffsFadeOnDeath)) {
|
if (RuleB(Spells, BuffsFadeOnDeath)) {
|
||||||
@ -1930,58 +1953,61 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (RuleB(Character, UnmemSpellsOnDeath)) {
|
if (RuleB(Character, UnmemSpellsOnDeath)) {
|
||||||
if ((ClientVersionBit() & EQ::versions::maskSoFAndLater) && RuleB(Character, RespawnFromHover))
|
if ((ClientVersionBit() & EQ::versions::maskSoFAndLater) && RuleB(Character, RespawnFromHover)) {
|
||||||
UnmemSpellAll(true);
|
UnmemSpellAll(true);
|
||||||
else
|
} else {
|
||||||
UnmemSpellAll(false);
|
UnmemSpellAll(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((RuleB(Character, LeaveCorpses) && GetLevel() >= RuleI(Character, DeathItemLossLevel)) || RuleB(Character, LeaveNakedCorpses))
|
if (
|
||||||
{
|
(RuleB(Character, LeaveCorpses) && GetLevel() >= RuleI(Character, DeathItemLossLevel)) ||
|
||||||
|
RuleB(Character, LeaveNakedCorpses)
|
||||||
|
) {
|
||||||
// creating the corpse takes the cash/items off the player too
|
// creating the corpse takes the cash/items off the player too
|
||||||
new_corpse = new Corpse(this, exploss);
|
new_corpse = new Corpse(this, exploss);
|
||||||
|
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
database.GetVariable("ServerType", tmp);
|
database.GetVariable("ServerType", tmp);
|
||||||
if (tmp[0] == '1' && tmp[1] == '\0' && killerMob != nullptr && killerMob->IsClient()) {
|
if (tmp[0] == '1' && tmp[1] == '\0' && killerMob && killerMob->IsClient()) {
|
||||||
database.GetVariable("PvPreward", tmp);
|
database.GetVariable("PvPreward", tmp);
|
||||||
int reward = atoi(tmp.c_str());
|
auto reward = atoi(tmp.c_str());
|
||||||
if (reward == 3) {
|
if (reward == 3) {
|
||||||
database.GetVariable("PvPitem", tmp);
|
database.GetVariable("PvPitem", tmp);
|
||||||
int pvpitem = atoi(tmp.c_str());
|
auto pvp_item_id = atoi(tmp.c_str());
|
||||||
if (pvpitem>0 && pvpitem<200000)
|
const auto* item = database.GetItem(pvp_item_id);
|
||||||
new_corpse->SetPlayerKillItemID(pvpitem);
|
if (item) {
|
||||||
}
|
new_corpse->SetPlayerKillItemID(pvp_item_id);
|
||||||
else if (reward == 2)
|
}
|
||||||
|
} else if (reward == 2) {
|
||||||
new_corpse->SetPlayerKillItemID(-1);
|
new_corpse->SetPlayerKillItemID(-1);
|
||||||
else if (reward == 1)
|
} else if (reward == 1) {
|
||||||
new_corpse->SetPlayerKillItemID(1);
|
new_corpse->SetPlayerKillItemID(1);
|
||||||
else
|
} else {
|
||||||
new_corpse->SetPlayerKillItemID(0);
|
new_corpse->SetPlayerKillItemID(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (killerMob->CastToClient()->isgrouped) {
|
if (killerMob->CastToClient()->isgrouped) {
|
||||||
Group* group = entity_list.GetGroupByClient(killerMob->CastToClient());
|
auto* group = entity_list.GetGroupByClient(killerMob->CastToClient());
|
||||||
if (group != 0)
|
if (group) {
|
||||||
{
|
for (int i = 0; i < 6; i++) {
|
||||||
for (int i = 0; i<6; i++)
|
if (group->members[i]) {
|
||||||
{
|
|
||||||
if (group->members[i] != nullptr)
|
|
||||||
{
|
|
||||||
new_corpse->AllowPlayerLoot(group->members[i], i);
|
new_corpse->AllowPlayerLoot(group->members[i], i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entity_list.AddCorpse(new_corpse, GetID());
|
entity_list.AddCorpse(new_corpse, GetID());
|
||||||
SetID(0);
|
SetID(0);
|
||||||
|
|
||||||
//send the become corpse packet to everybody else in the zone.
|
//send the become corpse packet to everybody else in the zone.
|
||||||
entity_list.QueueClients(this, &app2, true);
|
entity_list.QueueClients(this, &app2, true);
|
||||||
ApplyIllusionToCorpse(illusion_spell_id, new_corpse);
|
ApplyIllusionToCorpse(illusion_spell_id, new_corpse);
|
||||||
LeftCorpse = true;
|
leave_corpse = true;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
BuffFadeDetrimental();
|
BuffFadeDetrimental();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1993,8 +2019,9 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
|||||||
/*
|
/*
|
||||||
Reset reuse timer for classic skill based Lay on Hands (For tit I guess)
|
Reset reuse timer for classic skill based Lay on Hands (For tit I guess)
|
||||||
*/
|
*/
|
||||||
if (GetClass() == PALADIN) // we could check if it's not expired I guess, but should be fine not to
|
if (GetClass() == PALADIN) { // we could check if it's not expired I guess, but should be fine not to
|
||||||
p_timers.Clear(&database, pTimerLayHands);
|
p_timers.Clear(&database, pTimerLayHands);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Finally, send em home
|
Finally, send em home
|
||||||
@ -2003,25 +2030,23 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
|
|||||||
from these and overwrite what we set in pp anyway
|
from these and overwrite what we set in pp anyway
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (LeftCorpse && (ClientVersionBit() & EQ::versions::maskSoFAndLater) && RuleB(Character, RespawnFromHover))
|
if (leave_corpse && (ClientVersionBit() & EQ::versions::maskSoFAndLater) && RuleB(Character, RespawnFromHover)) {
|
||||||
{
|
|
||||||
ClearDraggedCorpses();
|
ClearDraggedCorpses();
|
||||||
RespawnFromHoverTimer.Start(RuleI(Character, RespawnFromHoverTimer) * 1000);
|
RespawnFromHoverTimer.Start(RuleI(Character, RespawnFromHoverTimer) * 1000);
|
||||||
SendRespawnBinds();
|
SendRespawnBinds();
|
||||||
}
|
} else {
|
||||||
else
|
if (isgrouped) {
|
||||||
{
|
auto* g = GetGroup();
|
||||||
if (isgrouped)
|
if (g) {
|
||||||
{
|
|
||||||
Group *g = GetGroup();
|
|
||||||
if (g)
|
|
||||||
g->MemberZoned(this);
|
g->MemberZoned(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Raid* r = entity_list.GetRaidByClient(this);
|
auto* r = entity_list.GetRaidByClient(this);
|
||||||
|
|
||||||
if (r)
|
if (r) {
|
||||||
r->MemberZoned(this);
|
r->MemberZoned(this);
|
||||||
|
}
|
||||||
|
|
||||||
dead_timer.Start(5000, true);
|
dead_timer.Start(5000, true);
|
||||||
m_pp.zone_id = m_pp.binds[0].zone_id;
|
m_pp.zone_id = m_pp.binds[0].zone_id;
|
||||||
@ -2320,9 +2345,8 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
LogCombat("Fatal blow dealt by [{}] with [{}] damage, spell [{}], skill [{}]",
|
LogCombat("Fatal blow dealt by [{}] with [{}] damage, spell [{}], skill [{}]",
|
||||||
((killer_mob) ? (killer_mob->GetName()) : ("[nullptr]")), damage, spell, attack_skill);
|
((killer_mob) ? (killer_mob->GetName()) : ("[nullptr]")), damage, spell, attack_skill);
|
||||||
|
|
||||||
Mob* oos = killer_mob ? killer_mob->GetOwnerOrSelf() : nullptr;
|
Mob *oos = killer_mob ? killer_mob->GetOwnerOrSelf() : nullptr;
|
||||||
|
auto export_string = fmt::format(
|
||||||
std::string export_string = fmt::format(
|
|
||||||
"{} {} {} {}",
|
"{} {} {} {}",
|
||||||
killer_mob ? killer_mob->GetID() : 0,
|
killer_mob ? killer_mob->GetID() : 0,
|
||||||
damage,
|
damage,
|
||||||
@ -2330,12 +2354,24 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
static_cast<int>(attack_skill)
|
static_cast<int>(attack_skill)
|
||||||
);
|
);
|
||||||
|
|
||||||
// todo: multiple attacks causes this to fire multiple times (DoAttackRounds, DoMain/OffHandAttackRounds, DoRiposte, spells?)
|
if (IsNPC()) {
|
||||||
if (parse->EventNPC(EVENT_DEATH, this, oos, export_string, 0) != 0) {
|
if (parse->EventNPC(EVENT_DEATH, this, oos, export_string, 0) != 0) {
|
||||||
if (GetHP() < 0) {
|
if (GetHP() < 0) {
|
||||||
SetHP(0);
|
SetHP(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
#ifdef BOTS
|
||||||
|
} else if (IsBot()) {
|
||||||
|
if (parse->EventBot(EVENT_DEATH, CastToBot(), oos, export_string, 0) != 0) {
|
||||||
|
if (GetHP() < 0) {
|
||||||
|
SetHP(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (killer_mob && (killer_mob->IsClient() || killer_mob->IsBot()) && (spell != SPELL_UNKNOWN) && damage > 0) {
|
if (killer_mob && (killer_mob->IsClient() || killer_mob->IsBot()) && (spell != SPELL_UNKNOWN) && damage > 0) {
|
||||||
@ -2364,23 +2400,25 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
SetPet(0);
|
SetPet(0);
|
||||||
|
|
||||||
if (GetSwarmOwner()) {
|
if (GetSwarmOwner()) {
|
||||||
Mob* owner = entity_list.GetMobID(GetSwarmOwner());
|
auto* owner = entity_list.GetMobID(GetSwarmOwner());
|
||||||
if (owner)
|
if (owner) {
|
||||||
owner->SetTempPetCount(owner->GetTempPetCount() - 1);
|
owner->SetTempPetCount(owner->GetTempPetCount() - 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mob* killer = GetHateDamageTop(this);
|
auto* killer = GetHateDamageTop(this);
|
||||||
|
|
||||||
entity_list.RemoveFromTargets(this, p_depop);
|
entity_list.RemoveFromTargets(this, p_depop);
|
||||||
|
|
||||||
if (p_depop == true)
|
if (p_depop) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int32 illusion_spell_id = spellbonuses.Illusion;
|
const auto illusion_spell_id = spellbonuses.Illusion;
|
||||||
|
|
||||||
HasAISpellEffects = false;
|
HasAISpellEffects = false;
|
||||||
BuffFadeAll();
|
BuffFadeAll();
|
||||||
uint8 killed_level = GetLevel();
|
const auto killed_level = GetLevel();
|
||||||
|
|
||||||
if (GetClass() == LDON_TREASURE) { // open chest
|
if (GetClass() == LDON_TREASURE) { // open chest
|
||||||
auto outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct));
|
auto outapp = new EQApplicationPacket(OP_Animation, sizeof(Animation_Struct));
|
||||||
@ -2393,7 +2431,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto app = new EQApplicationPacket(OP_Death, sizeof(Death_Struct));
|
auto app = new EQApplicationPacket(OP_Death, sizeof(Death_Struct));
|
||||||
Death_Struct* d = (Death_Struct*)app->pBuffer;
|
auto* d = (Death_Struct*) app->pBuffer;
|
||||||
d->spawn_id = GetID();
|
d->spawn_id = GetID();
|
||||||
d->killer_id = killer_mob ? killer_mob->GetID() : 0;
|
d->killer_id = killer_mob ? killer_mob->GetID() : 0;
|
||||||
d->bindzoneid = 0;
|
d->bindzoneid = 0;
|
||||||
@ -2409,16 +2447,17 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
respawn2->DeathReset(1);
|
respawn2->DeathReset(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (killer_mob && GetClass() != LDON_TREASURE)
|
if (killer_mob && GetClass() != LDON_TREASURE) {
|
||||||
hate_list.AddEntToHateList(killer_mob, damage);
|
hate_list.AddEntToHateList(killer_mob, damage);
|
||||||
|
}
|
||||||
|
|
||||||
Mob *give_exp = hate_list.GetDamageTopOnHateList(this);
|
Mob *give_exp = hate_list.GetDamageTopOnHateList(this);
|
||||||
|
|
||||||
if (give_exp == nullptr)
|
if (give_exp) {
|
||||||
give_exp = killer;
|
give_exp = killer;
|
||||||
|
}
|
||||||
|
|
||||||
if (give_exp && give_exp->HasOwner()) {
|
if (give_exp && give_exp->HasOwner()) {
|
||||||
|
|
||||||
bool ownerInGroup = false;
|
bool ownerInGroup = false;
|
||||||
if ((give_exp->HasGroup() && give_exp->GetGroup()->IsGroupMember(give_exp->GetUltimateOwner()))
|
if ((give_exp->HasGroup() && give_exp->GetGroup()->IsGroupMember(give_exp->GetUltimateOwner()))
|
||||||
|| (give_exp->IsPet() && (give_exp->GetOwner()->IsClient()
|
|| (give_exp->IsPet() && (give_exp->GetOwner()->IsClient()
|
||||||
@ -2721,18 +2760,33 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
if (oos) {
|
if (oos) {
|
||||||
mod_npc_killed(oos);
|
mod_npc_killed(oos);
|
||||||
|
|
||||||
uint32 emoteid = GetEmoteID();
|
if (IsNPC()) {
|
||||||
if (emoteid != 0)
|
auto emote_id = GetEmoteID();
|
||||||
DoNPCEmote(EQ::constants::EmoteEventTypes::OnDeath, emoteid);
|
if (emote_id) {
|
||||||
|
DoNPCEmote(EQ::constants::EmoteEventTypes::OnDeath, emoteid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (oos->IsNPC()) {
|
if (oos->IsNPC()) {
|
||||||
parse->EventNPC(EVENT_NPC_SLAY, oos->CastToNPC(), this, "", 0);
|
parse->EventNPC(EVENT_NPC_SLAY, oos->CastToNPC(), this, "", 0);
|
||||||
uint32 emoteid = oos->GetEmoteID();
|
auto emote_id = oos->GetEmoteID();
|
||||||
if (emoteid != 0)
|
if (emote_id) {
|
||||||
oos->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledNPC, emoteid);
|
oos->CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::KilledNPC, emote_id);
|
||||||
|
}
|
||||||
|
|
||||||
killer_mob->TrySpellOnKill(killed_level, spell);
|
killer_mob->TrySpellOnKill(killed_level, spell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
if (killer_mob->IsBot()) {
|
||||||
|
parse->EventBot(EVENT_NPC_SLAY, killer_mob->CastToBot(), this, "", 0);
|
||||||
|
killer_mob->TrySpellOnKill(killed_level, spell);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LogInfo("[Attack] Should have attempted to do OOS check");
|
||||||
|
|
||||||
WipeHateList();
|
WipeHateList();
|
||||||
p_depop = true;
|
p_depop = true;
|
||||||
|
|
||||||
|
|||||||
225
zone/bot.cpp
225
zone/bot.cpp
@ -2663,7 +2663,13 @@ void Bot::AI_Process()
|
|||||||
auto pull_target = bot_owner->GetTarget();
|
auto pull_target = bot_owner->GetTarget();
|
||||||
if (pull_target) {
|
if (pull_target) {
|
||||||
|
|
||||||
Bot::BotGroupSay(this, "Pulling %s to the group..", pull_target->GetCleanName());
|
BotGroupSay(
|
||||||
|
this,
|
||||||
|
fmt::format(
|
||||||
|
"Pulling {}.",
|
||||||
|
pull_target->GetCleanName()
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
InterruptSpell();
|
InterruptSpell();
|
||||||
WipeHateList();
|
WipeHateList();
|
||||||
AddToHateList(pull_target, 1);
|
AddToHateList(pull_target, 1);
|
||||||
@ -2822,14 +2828,20 @@ void Bot::AI_Process()
|
|||||||
bool find_target = true;
|
bool find_target = true;
|
||||||
|
|
||||||
if (assist_mob) {
|
if (assist_mob) {
|
||||||
|
|
||||||
if (assist_mob->GetTarget()) {
|
if (assist_mob->GetTarget()) {
|
||||||
|
|
||||||
if (assist_mob != this) {
|
if (assist_mob != this) {
|
||||||
|
if (GetTarget() != assist_mob->GetTarget()) {
|
||||||
|
SetTarget(assist_mob->GetTarget());
|
||||||
|
}
|
||||||
|
|
||||||
SetTarget(assist_mob->GetTarget());
|
if (
|
||||||
if (HasPet() && (GetClass() != ENCHANTER || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 2)) {
|
HasPet() &&
|
||||||
|
(
|
||||||
|
GetClass() != ENCHANTER ||
|
||||||
|
GetPet()->GetPetType() != petAnimation ||
|
||||||
|
GetAA(aaAnimationEmpathy) >= 2
|
||||||
|
)
|
||||||
|
) {
|
||||||
// This artificially inflates pet's target aggro..but, less expensive than checking hate each AI process
|
// This artificially inflates pet's target aggro..but, less expensive than checking hate each AI process
|
||||||
GetPet()->AddToHateList(assist_mob->GetTarget(), 1);
|
GetPet()->AddToHateList(assist_mob->GetTarget(), 1);
|
||||||
GetPet()->SetTarget(assist_mob->GetTarget());
|
GetPet()->SetTarget(assist_mob->GetTarget());
|
||||||
@ -2837,12 +2849,19 @@ void Bot::AI_Process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
find_target = false;
|
find_target = false;
|
||||||
}
|
} else if (assist_mob != this) {
|
||||||
else if (assist_mob != this) {
|
if (GetTarget()) {
|
||||||
|
SetTarget(nullptr);
|
||||||
SetTarget(nullptr);
|
}
|
||||||
if (HasPet() && (GetClass() != ENCHANTER || GetPet()->GetPetType() != petAnimation || GetAA(aaAnimationEmpathy) >= 1)) {
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
HasPet() &&
|
||||||
|
(
|
||||||
|
GetClass() != ENCHANTER ||
|
||||||
|
GetPet()->GetPetType() != petAnimation ||
|
||||||
|
GetAA(aaAnimationEmpathy) >= 1
|
||||||
|
)
|
||||||
|
) {
|
||||||
GetPet()->WipeHateList();
|
GetPet()->WipeHateList();
|
||||||
GetPet()->SetTarget(nullptr);
|
GetPet()->SetTarget(nullptr);
|
||||||
}
|
}
|
||||||
@ -2852,16 +2871,23 @@ void Bot::AI_Process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (find_target) {
|
if (find_target) {
|
||||||
|
|
||||||
if (IsRooted()) {
|
if (IsRooted()) {
|
||||||
SetTarget(hate_list.GetClosestEntOnHateList(this, true));
|
auto closest = hate_list.GetClosestEntOnHateList(this, true);
|
||||||
}
|
if (closest) {
|
||||||
else {
|
SetTarget(closest);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// This will keep bots on target for now..but, future updates will allow for rooting/stunning
|
// This will keep bots on target for now..but, future updates will allow for rooting/stunning
|
||||||
SetTarget(hate_list.GetEscapingEntOnHateList(leash_owner, leash_distance));
|
auto escaping = hate_list.GetEscapingEntOnHateList(leash_owner, leash_distance);
|
||||||
|
if (escaping) {
|
||||||
|
SetTarget(escaping);
|
||||||
|
}
|
||||||
|
|
||||||
if (!GetTarget()) {
|
if (!GetTarget()) {
|
||||||
SetTarget(hate_list.GetEntWithMostHateOnList(this, nullptr, true));
|
auto most_hate = hate_list.GetEntWithMostHateOnList(this, nullptr, true);
|
||||||
|
if (most_hate) {
|
||||||
|
SetTarget(most_hate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2884,8 +2910,10 @@ void Bot::AI_Process()
|
|||||||
|
|
||||||
Mob* tar = GetTarget(); // We should have a target..if not, we're awaiting new orders
|
Mob* tar = GetTarget(); // We should have a target..if not, we're awaiting new orders
|
||||||
if (!tar || PASSIVE) {
|
if (!tar || PASSIVE) {
|
||||||
|
if (GetTarget()) {
|
||||||
|
SetTarget(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
SetTarget(nullptr);
|
|
||||||
WipeHateList();
|
WipeHateList();
|
||||||
SetAttackFlag(false);
|
SetAttackFlag(false);
|
||||||
SetAttackingFlag(false);
|
SetAttackingFlag(false);
|
||||||
@ -4929,12 +4957,10 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
if (!database.botdb.DeleteItemBySlot(GetBotID(), return_iterator.from_bot_slot)) {
|
if (!database.botdb.DeleteItemBySlot(GetBotID(), return_iterator.from_bot_slot)) {
|
||||||
client->Message(
|
OwnerMessage(
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Failed to delete item by slot from slot {} for {}.",
|
"Failed to delete item by slot from slot {}.",
|
||||||
return_iterator.from_bot_slot,
|
return_iterator.from_bot_slot
|
||||||
GetCleanName()
|
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -4947,13 +4973,11 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
|||||||
linker.SetItemInst(return_instance);
|
linker.SetItemInst(return_instance);
|
||||||
auto item_link = linker.GenerateLink();
|
auto item_link = linker.GenerateLink();
|
||||||
|
|
||||||
client->Message(
|
OwnerMessage(
|
||||||
Chat::Tell,
|
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} tells you, 'I have returned {}.'",
|
"I have returned {}.",
|
||||||
GetCleanName(),
|
|
||||||
item_link
|
item_link
|
||||||
).c_str()
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
client->PutItemInInventory(return_iterator.to_client_slot, *return_instance, true);
|
client->PutItemInInventory(return_iterator.to_client_slot, *return_instance, true);
|
||||||
@ -4969,12 +4993,10 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
|||||||
// TODO: code for stackables
|
// TODO: code for stackables
|
||||||
|
|
||||||
if (!database.botdb.SaveItemBySlot(this, trade_iterator.to_bot_slot, trade_iterator.trade_item_instance)) {
|
if (!database.botdb.SaveItemBySlot(this, trade_iterator.to_bot_slot, trade_iterator.trade_item_instance)) {
|
||||||
client->Message(
|
OwnerMessage(
|
||||||
Chat::White,
|
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Failed to save item by slot to slot {} for {}.",
|
"Failed to save item by slot to slot {}.",
|
||||||
trade_iterator.to_bot_slot,
|
trade_iterator.to_bot_slot
|
||||||
GetCleanName()
|
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -4984,13 +5006,11 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
|||||||
linker.SetItemInst(trade_iterator.trade_item_instance);
|
linker.SetItemInst(trade_iterator.trade_item_instance);
|
||||||
auto item_link = linker.GenerateLink();
|
auto item_link = linker.GenerateLink();
|
||||||
|
|
||||||
client->Message(
|
OwnerMessage(
|
||||||
Chat::Tell,
|
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} tells you, 'I have accepted {}.'",
|
"I have accepted {}.",
|
||||||
GetCleanName(),
|
|
||||||
item_link
|
item_link
|
||||||
).c_str()
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
m_inv.PutItem(trade_iterator.to_bot_slot, *trade_iterator.trade_item_instance);
|
m_inv.PutItem(trade_iterator.to_bot_slot, *trade_iterator.trade_item_instance);
|
||||||
@ -5101,6 +5121,16 @@ bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::Skill
|
|||||||
my_owner->CastToClient()->SetBotPulling(false);
|
my_owner->CastToClient()->SetBotPulling(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto export_string = fmt::format(
|
||||||
|
"{} {} {} {}",
|
||||||
|
killerMob ? killerMob->GetID() : 0,
|
||||||
|
damage,
|
||||||
|
spell_id,
|
||||||
|
static_cast<int>(attack_skill)
|
||||||
|
);
|
||||||
|
|
||||||
|
parse->EventBot(EVENT_DEATH_COMPLETE, this, killerMob, export_string, 0);
|
||||||
|
|
||||||
entity_list.RemoveBot(GetID());
|
entity_list.RemoveBot(GetID());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -5112,7 +5142,7 @@ void Bot::Damage(Mob *from, int64 damage, uint16 spell_id, EQ::skills::SkillType
|
|||||||
//handle EVENT_ATTACK. Resets after we have not been attacked for 12 seconds
|
//handle EVENT_ATTACK. Resets after we have not been attacked for 12 seconds
|
||||||
if(attacked_timer.Check()) {
|
if(attacked_timer.Check()) {
|
||||||
LogCombat("Triggering EVENT_ATTACK due to attack by [{}]", from->GetName());
|
LogCombat("Triggering EVENT_ATTACK due to attack by [{}]", from->GetName());
|
||||||
parse->EventNPC(EVENT_ATTACK, this, from, "", 0);
|
parse->EventBot(EVENT_ATTACK, this, from, "", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
attacked_timer.Start(CombatEventTimer_expire);
|
attacked_timer.Start(CombatEventTimer_expire);
|
||||||
@ -6554,7 +6584,13 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
|
|||||||
|
|
||||||
if(taunting && target && target->IsNPC() && taunt_time) {
|
if(taunting && target && target->IsNPC() && taunt_time) {
|
||||||
if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this) {
|
if(GetTarget() && GetTarget()->GetHateTop() && GetTarget()->GetHateTop() != this) {
|
||||||
BotGroupSay(this, "Taunting %s", target->GetCleanName());
|
BotGroupSay(
|
||||||
|
this,
|
||||||
|
fmt::format(
|
||||||
|
"Taunting {}.",
|
||||||
|
target->GetCleanName()
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
Taunt(target->CastToNPC(), false);
|
Taunt(target->CastToNPC(), false);
|
||||||
taunt_timer.Start(TauntReuseTime * 1000);
|
taunt_timer.Start(TauntReuseTime * 1000);
|
||||||
}
|
}
|
||||||
@ -7512,27 +7548,49 @@ void Bot::DoBuffTic(const Buffs_Struct &buff, int slot, Mob* caster) {
|
|||||||
Mob::DoBuffTic(buff, slot, caster);
|
Mob::DoBuffTic(buff, slot, caster);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Bot::CastSpell(uint16 spell_id, uint16 target_id, EQ::spells::CastingSlot slot, int32 cast_time, int32 mana_cost,
|
bool Bot::CastSpell(
|
||||||
uint32* oSpellWillFinish, uint32 item_slot, int16 *resist_adjust, uint32 aa_id) {
|
uint16 spell_id,
|
||||||
|
uint16 target_id,
|
||||||
|
EQ::spells::CastingSlot slot,
|
||||||
|
int32 cast_time,
|
||||||
|
int32 mana_cost,
|
||||||
|
uint32* oSpellWillFinish,
|
||||||
|
uint32 item_slot,
|
||||||
|
int16 *resist_adjust,
|
||||||
|
uint32 aa_id
|
||||||
|
) {
|
||||||
bool Result = false;
|
bool Result = false;
|
||||||
if(zone && !zone->IsSpellBlocked(spell_id, glm::vec3(GetPosition()))) {
|
if (zone && !zone->IsSpellBlocked(spell_id, glm::vec3(GetPosition()))) {
|
||||||
// LogSpells("CastSpell called for spell [{}] ([{}]) on entity [{}], slot [{}], time [{}], mana [{}], from item slot [{}]", spells[spell_id].name, spell_id, target_id, slot, cast_time, mana_cost, (item_slot==0xFFFFFFFF)?999:item_slot);
|
// LogSpells("CastSpell called for spell [{}] ([{}]) on entity [{}], slot [{}], time [{}], mana [{}], from item slot [{}]", spells[spell_id].name, spell_id, target_id, slot, cast_time, mana_cost, (item_slot==0xFFFFFFFF)?999:item_slot);
|
||||||
|
|
||||||
if(casting_spell_id == spell_id)
|
if (casting_spell_id == spell_id) {
|
||||||
ZeroCastingVars();
|
ZeroCastingVars();
|
||||||
|
}
|
||||||
|
|
||||||
if(GetClass() != BARD) {
|
if (GetClass() != BARD) {
|
||||||
if(!IsValidSpell(spell_id) || casting_spell_id || delaytimer || spellend_timer.Enabled() || IsStunned() || IsFeared() || IsMezzed() || (IsSilenced() && !IsDiscipline(spell_id)) || (IsAmnesiad() && IsDiscipline(spell_id))) {
|
if (
|
||||||
|
!IsValidSpell(spell_id) ||
|
||||||
|
casting_spell_id ||
|
||||||
|
delaytimer ||
|
||||||
|
spellend_timer.Enabled() ||
|
||||||
|
IsStunned() ||
|
||||||
|
IsFeared() ||
|
||||||
|
IsMezzed() ||
|
||||||
|
(IsSilenced() && !IsDiscipline(spell_id)) ||
|
||||||
|
(IsAmnesiad() && IsDiscipline(spell_id))
|
||||||
|
) {
|
||||||
LogSpells("Spell casting canceled: not able to cast now. Valid? [{}], casting [{}], waiting? [{}], spellend? [{}], stunned? [{}], feared? [{}], mezed? [{}], silenced? [{}]", IsValidSpell(spell_id), casting_spell_id, delaytimer, spellend_timer.Enabled(), IsStunned(), IsFeared(), IsMezzed(), IsSilenced() );
|
LogSpells("Spell casting canceled: not able to cast now. Valid? [{}], casting [{}], waiting? [{}], spellend? [{}], stunned? [{}], feared? [{}], mezed? [{}], silenced? [{}]", IsValidSpell(spell_id), casting_spell_id, delaytimer, spellend_timer.Enabled(), IsStunned(), IsFeared(), IsMezzed(), IsSilenced() );
|
||||||
if(IsSilenced() && !IsDiscipline(spell_id))
|
if (IsSilenced() && !IsDiscipline(spell_id)) {
|
||||||
MessageString(Chat::White, SILENCED_STRING);
|
MessageString(Chat::White, SILENCED_STRING);
|
||||||
|
}
|
||||||
|
|
||||||
if(IsAmnesiad() && IsDiscipline(spell_id))
|
if (IsAmnesiad() && IsDiscipline(spell_id)) {
|
||||||
|
|
||||||
MessageString(Chat::White, MELEE_SILENCE);
|
MessageString(Chat::White, MELEE_SILENCE);
|
||||||
|
}
|
||||||
|
|
||||||
if(casting_spell_id)
|
if (casting_spell_id) {
|
||||||
AI_Bot_Event_SpellCastFinished(false, static_cast<uint16>(casting_spell_slot));
|
AI_Bot_Event_SpellCastFinished(false, static_cast<uint16>(casting_spell_slot));
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -7540,19 +7598,20 @@ bool Bot::CastSpell(uint16 spell_id, uint16 target_id, EQ::spells::CastingSlot s
|
|||||||
|
|
||||||
if (IsDetrimentalSpell(spell_id) && !zone->CanDoCombat()) {
|
if (IsDetrimentalSpell(spell_id) && !zone->CanDoCombat()) {
|
||||||
MessageString(Chat::White, SPELL_WOULDNT_HOLD);
|
MessageString(Chat::White, SPELL_WOULDNT_HOLD);
|
||||||
if(casting_spell_id)
|
if (casting_spell_id) {
|
||||||
AI_Bot_Event_SpellCastFinished(false, static_cast<uint16>(casting_spell_slot));
|
AI_Bot_Event_SpellCastFinished(false, static_cast<uint16>(casting_spell_slot));
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DivineAura()) {
|
if (DivineAura()) {
|
||||||
LogSpells("Spell casting canceled: cannot cast while Divine Aura is in effect");
|
LogSpells("Spell casting canceled: cannot cast while Divine Aura is in effect");
|
||||||
InterruptSpell(173, 0x121, false);
|
InterruptSpell(173, 0x121, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(slot < EQ::spells::CastingSlot::MaxGems && !CheckFizzle(spell_id)) {
|
if (slot < EQ::spells::CastingSlot::MaxGems && !CheckFizzle(spell_id)) {
|
||||||
int fizzle_msg = IsBardSong(spell_id) ? MISS_NOTE : SPELL_FIZZLE;
|
int fizzle_msg = IsBardSong(spell_id) ? MISS_NOTE : SPELL_FIZZLE;
|
||||||
InterruptSpell(fizzle_msg, 0x121, spell_id);
|
InterruptSpell(fizzle_msg, 0x121, spell_id);
|
||||||
|
|
||||||
@ -7878,7 +7937,13 @@ bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spe
|
|||||||
bool Bot::DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
|
bool Bot::DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
|
||||||
bool isMainGroupMGB = false;
|
bool isMainGroupMGB = false;
|
||||||
if(isMainGroupMGB && (GetClass() != BARD)) {
|
if(isMainGroupMGB && (GetClass() != BARD)) {
|
||||||
BotGroupSay(this, "MGB %s", spells[spell_id].name);
|
BotGroupSay(
|
||||||
|
this,
|
||||||
|
fmt::format(
|
||||||
|
"Casting {} as a Mass Group Buff.",
|
||||||
|
spells[spell_id].name
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
SpellOnTarget(spell_id, this);
|
SpellOnTarget(spell_id, this);
|
||||||
entity_list.AESpell(this, this, spell_id, true);
|
entity_list.AESpell(this, this, spell_id, true);
|
||||||
} else {
|
} else {
|
||||||
@ -9564,28 +9629,30 @@ Client* EntityList::GetBotOwnerByBotEntityID(uint16 entityID) {
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityList::AddBot(Bot *newBot, bool SendSpawnPacket, bool dontqueue) {
|
void EntityList::AddBot(Bot *new_bot, bool send_spawn_packet, bool dont_queue) {
|
||||||
if(newBot) {
|
if (new_bot) {
|
||||||
newBot->SetID(GetFreeID());
|
new_bot->SetID(GetFreeID());
|
||||||
newBot->SetSpawned();
|
new_bot->SetSpawned();
|
||||||
if(SendSpawnPacket) {
|
if (send_spawn_packet) {
|
||||||
if(dontqueue) {
|
if (dont_queue) {
|
||||||
EQApplicationPacket* outapp = new EQApplicationPacket();
|
EQApplicationPacket* outapp = new EQApplicationPacket();
|
||||||
newBot->CreateSpawnPacket(outapp);
|
new_bot->CreateSpawnPacket(outapp);
|
||||||
outapp->priority = 6;
|
outapp->priority = 6;
|
||||||
QueueClients(newBot, outapp, true);
|
QueueClients(new_bot, outapp, true);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
} else {
|
} else {
|
||||||
NewSpawn_Struct* ns = new NewSpawn_Struct;
|
NewSpawn_Struct* ns = new NewSpawn_Struct;
|
||||||
memset(ns, 0, sizeof(NewSpawn_Struct));
|
memset(ns, 0, sizeof(NewSpawn_Struct));
|
||||||
newBot->FillSpawnStruct(ns, newBot);
|
new_bot->FillSpawnStruct(ns, new_bot);
|
||||||
AddToSpawnQueue(newBot->GetID(), &ns);
|
AddToSpawnQueue(new_bot->GetID(), &ns);
|
||||||
safe_delete(ns);
|
safe_delete(ns);
|
||||||
}
|
}
|
||||||
parse->EventNPC(EVENT_SPAWN, newBot, nullptr, "", 0);
|
|
||||||
|
parse->EventBot(EVENT_SPAWN, new_bot, nullptr, "", 0);
|
||||||
}
|
}
|
||||||
bot_list.push_back(newBot);
|
|
||||||
mob_list.insert(std::pair<uint16, Mob*>(newBot->GetID(), newBot));
|
bot_list.push_back(new_bot);
|
||||||
|
mob_list.insert(std::pair<uint16, Mob*>(new_bot->GetID(), new_bot));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10379,6 +10446,28 @@ void Bot::SpawnBotGroupByName(Client* c, std::string botgroup_name, uint32 leade
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Bot::SignalBot(int signal_id)
|
||||||
|
{
|
||||||
|
const auto export_string = fmt::format("{}", signal_id);
|
||||||
|
parse->EventBot(EVENT_SIGNAL, this, nullptr, export_string, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Bot::OwnerMessage(std::string message)
|
||||||
|
{
|
||||||
|
if (!GetBotOwner() || !GetBotOwner()->IsClient()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetBotOwner()->Message(
|
||||||
|
Chat::Tell,
|
||||||
|
fmt::format(
|
||||||
|
"{} tells you, '{}'",
|
||||||
|
GetCleanName(),
|
||||||
|
message
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
bool Bot::GetBotOwnerDataBuckets()
|
bool Bot::GetBotOwnerDataBuckets()
|
||||||
{
|
{
|
||||||
auto bot_owner = GetBotOwner();
|
auto bot_owner = GetBotOwner();
|
||||||
|
|||||||
@ -681,6 +681,9 @@ public:
|
|||||||
int32 GetBaseDR() { return _baseDR; }
|
int32 GetBaseDR() { return _baseDR; }
|
||||||
int32 GetBaseCorrup() { return _baseCorrup; }
|
int32 GetBaseCorrup() { return _baseCorrup; }
|
||||||
|
|
||||||
|
void SignalBot(int signal_id);
|
||||||
|
void OwnerMessage(std::string message);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void PetAIProcess();
|
virtual void PetAIProcess();
|
||||||
virtual void BotMeditate(bool isSitting);
|
virtual void BotMeditate(bool isSitting);
|
||||||
@ -700,6 +703,7 @@ protected:
|
|||||||
//void SetRaidSlower(bool flag = true) { m_CastingRoles.RaidSlower = flag; }
|
//void SetRaidSlower(bool flag = true) { m_CastingRoles.RaidSlower = flag; }
|
||||||
//void SetRaidNuker(bool flag = true) { m_CastingRoles.RaidNuker = flag; }
|
//void SetRaidNuker(bool flag = true) { m_CastingRoles.RaidNuker = flag; }
|
||||||
//void SetRaidDoter(bool flag = true) { m_CastingRoles.RaidDoter = flag; }
|
//void SetRaidDoter(bool flag = true) { m_CastingRoles.RaidDoter = flag; }
|
||||||
|
std::deque<int> bot_signal_q;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Class Members
|
// Class Members
|
||||||
|
|||||||
@ -2585,8 +2585,16 @@ void bot_command_aggressive(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
my_bot->InterruptSpell();
|
my_bot->InterruptSpell();
|
||||||
if (candidate_count == 1)
|
if (candidate_count == 1) {
|
||||||
Bot::BotGroupSay(my_bot, "Using '%s'", spells[local_entry->spell_id].name);
|
Bot::BotGroupSay(
|
||||||
|
my_bot,
|
||||||
|
fmt::format(
|
||||||
|
"Using {}.",
|
||||||
|
spells[local_entry->spell_id].name
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
my_bot->UseDiscipline(local_entry->spell_id, my_bot->GetID());
|
my_bot->UseDiscipline(local_entry->spell_id, my_bot->GetID());
|
||||||
++success_count;
|
++success_count;
|
||||||
|
|
||||||
@ -2803,10 +2811,22 @@ void bot_command_attack(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (attacker_count == 1 && first_attacker) {
|
if (attacker_count == 1 && first_attacker) {
|
||||||
Bot::BotGroupSay(first_attacker, "Attacking %s!", target_mob->GetCleanName());
|
Bot::BotGroupSay(
|
||||||
}
|
first_attacker,
|
||||||
else {
|
fmt::format(
|
||||||
c->Message(Chat::White, "%i of your bots are attacking %s!", sbl.size(), target_mob->GetCleanName());
|
"Attacking {}.",
|
||||||
|
target_mob->GetCleanName()
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"{} of your bots are attacking {}.",
|
||||||
|
sbl.size(),
|
||||||
|
target_mob->GetCleanName()
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3065,8 +3085,16 @@ void bot_command_defensive(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
my_bot->InterruptSpell();
|
my_bot->InterruptSpell();
|
||||||
if (candidate_count == 1)
|
if (candidate_count == 1) {
|
||||||
Bot::BotGroupSay(my_bot, "Using '%s'", spells[local_entry->spell_id].name);
|
Bot::BotGroupSay(
|
||||||
|
my_bot,
|
||||||
|
fmt::format(
|
||||||
|
"Using {}.",
|
||||||
|
spells[local_entry->spell_id].name
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
my_bot->UseDiscipline(local_entry->spell_id, my_bot->GetID());
|
my_bot->UseDiscipline(local_entry->spell_id, my_bot->GetID());
|
||||||
++success_count;
|
++success_count;
|
||||||
|
|
||||||
@ -3285,15 +3313,35 @@ void bot_command_follow(Client *c, const Seperator *sep)
|
|||||||
bot_iter->GetPet()->WipeHateList();
|
bot_iter->GetPet()->WipeHateList();
|
||||||
bot_iter->GetPet()->SetFollowID(bot_iter->GetID());
|
bot_iter->GetPet()->SetFollowID(bot_iter->GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sbl.size() == 1) {
|
if (sbl.size() == 1) {
|
||||||
Mob* follow_mob = entity_list.GetMob(sbl.front()->GetFollowID());
|
Mob* follow_mob = entity_list.GetMob(sbl.front()->GetFollowID());
|
||||||
Bot::BotGroupSay(sbl.front(), "Following %s", ((follow_mob) ? (follow_mob->GetCleanName()) : ("'nullptr'")));
|
Bot::BotGroupSay(
|
||||||
}
|
sbl.front(),
|
||||||
else {
|
fmt::format(
|
||||||
if (reset)
|
"Following {}.",
|
||||||
c->Message(Chat::White, "%i of your bots are following their default assignments", sbl.size());
|
follow_mob ? follow_mob->GetCleanName() : "no one"
|
||||||
else
|
).c_str()
|
||||||
c->Message(Chat::White, "%i of your bots are following %s", sbl.size(), target_mob->GetCleanName());
|
);
|
||||||
|
} else {
|
||||||
|
if (reset) {
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"{} of your bots are following their default assignments.",
|
||||||
|
sbl.size()
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"{} of your bots are following {}.",
|
||||||
|
sbl.size(),
|
||||||
|
target_mob->GetCleanName()
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3338,9 +3386,14 @@ void bot_command_guard(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sbl.size() == 1) {
|
if (sbl.size() == 1) {
|
||||||
Bot::BotGroupSay(sbl.front(), "%suarding this position.", (clear ? "No longer g" : "G"));
|
Bot::BotGroupSay(
|
||||||
}
|
sbl.front(),
|
||||||
else {
|
fmt::format(
|
||||||
|
"{}uarding this position.",
|
||||||
|
clear ? "No longer g" : "G"
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
c->Message(Chat::White, "%i of your bots are %sguarding their positions.", sbl.size(), (clear ? "no longer " : ""));
|
c->Message(Chat::White, "%i of your bots are %sguarding their positions.", sbl.size(), (clear ? "no longer " : ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3469,10 +3522,22 @@ void bot_command_hold(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sbl.size() == 1) {
|
if (sbl.size() == 1) {
|
||||||
Bot::BotGroupSay(sbl.front(), "%solding my attacks.", (clear ? "No longer h" : "H"));
|
Bot::BotGroupSay(
|
||||||
}
|
sbl.front(),
|
||||||
else {
|
fmt::format(
|
||||||
c->Message(Chat::White, "%i of your bots are %sholding their attacks.", sbl.size(), (clear ? "no longer " : ""));
|
"{}olding my attacks.",
|
||||||
|
clear ? "No longer h" : "H"
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"{} of your bots are {}holding their attacks.",
|
||||||
|
sbl.size(),
|
||||||
|
clear ? "no longer " : ""
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4224,7 +4289,7 @@ void bot_command_pick_lock(Client *c, const Seperator *sep)
|
|||||||
Bot* my_bot = sbl.front();
|
Bot* my_bot = sbl.front();
|
||||||
|
|
||||||
my_bot->InterruptSpell();
|
my_bot->InterruptSpell();
|
||||||
Bot::BotGroupSay(my_bot, "Attempting to pick the lock..");
|
Bot::BotGroupSay(my_bot, "Attempting to pick the lock.");
|
||||||
|
|
||||||
std::list<Doors*> door_list;
|
std::list<Doors*> door_list;
|
||||||
entity_list.GetDoorsList(door_list);
|
entity_list.GetDoorsList(door_list);
|
||||||
@ -4251,7 +4316,7 @@ void bot_command_pick_lock(Client *c, const Seperator *sep)
|
|||||||
++open_count;
|
++open_count;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Bot::BotGroupSay(my_bot, "I am not skilled enough for this lock...");
|
Bot::BotGroupSay(my_bot, "I am not skilled enough for this lock.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c->Message(Chat::White, "%i door%s attempted - %i door%s successful", door_count, ((door_count != 1) ? ("s") : ("")), open_count, ((open_count != 1) ? ("s") : ("")));
|
c->Message(Chat::White, "%i door%s attempted - %i door%s successful", door_count, ((door_count != 1) ? ("s") : ("")), open_count, ((open_count != 1) ? ("s") : ("")));
|
||||||
@ -4791,38 +4856,78 @@ void bot_command_taunt(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
int taunting_count = 0;
|
int taunting_count = 0;
|
||||||
for (auto bot_iter : sbl) {
|
for (auto bot_iter : sbl) {
|
||||||
if (!bot_iter->GetSkill(EQ::skills::SkillTaunt))
|
if (!bot_iter->GetSkill(EQ::skills::SkillTaunt)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (toggle_taunt)
|
if (toggle_taunt) {
|
||||||
bot_iter->SetTaunting(!bot_iter->IsTaunting());
|
bot_iter->SetTaunting(!bot_iter->IsTaunting());
|
||||||
else
|
} else {
|
||||||
bot_iter->SetTaunting(taunt_state);
|
bot_iter->SetTaunting(taunt_state);
|
||||||
|
}
|
||||||
|
|
||||||
if (sbl.size() == 1)
|
if (sbl.size() == 1) {
|
||||||
Bot::BotGroupSay(bot_iter, "I am %s taunting", bot_iter->IsTaunting() ? "now" : "no longer");
|
Bot::BotGroupSay(
|
||||||
|
bot_iter,
|
||||||
|
fmt::format(
|
||||||
|
"I am {} taunting.",
|
||||||
|
bot_iter->IsTaunting() ? "now" : "no longer"
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
++taunting_count;
|
++taunting_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto bot_iter : sbl) {
|
for (auto bot_iter : sbl) {
|
||||||
if (!bot_iter->HasPet())
|
if (!bot_iter->HasPet()) {
|
||||||
continue;
|
continue;
|
||||||
if (!bot_iter->GetPet()->GetSkill(EQ::skills::SkillTaunt))
|
}
|
||||||
|
|
||||||
|
if (!bot_iter->GetPet()->GetSkill(EQ::skills::SkillTaunt)) {
|
||||||
continue;
|
continue;
|
||||||
if (toggle_taunt)
|
}
|
||||||
|
|
||||||
|
if (toggle_taunt) {
|
||||||
bot_iter->GetPet()->CastToNPC()->SetTaunting(!bot_iter->GetPet()->CastToNPC()->IsTaunting());
|
bot_iter->GetPet()->CastToNPC()->SetTaunting(!bot_iter->GetPet()->CastToNPC()->IsTaunting());
|
||||||
else
|
} else {
|
||||||
bot_iter->GetPet()->CastToNPC()->SetTaunting(taunt_state);
|
bot_iter->GetPet()->CastToNPC()->SetTaunting(taunt_state);
|
||||||
if (sbl.size() == 1)
|
}
|
||||||
Bot::BotGroupSay(bot_iter, "My Pet is %s taunting", bot_iter->GetPet()->CastToNPC()->IsTaunting() ? "now" : "no longer");
|
|
||||||
|
if (sbl.size() == 1) {
|
||||||
|
Bot::BotGroupSay(
|
||||||
|
bot_iter,
|
||||||
|
fmt::format(
|
||||||
|
"My Pet is {} taunting.",
|
||||||
|
bot_iter->GetPet()->CastToNPC()->IsTaunting() ? "now" : "no longer"
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
++taunting_count;
|
++taunting_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (taunting_count) {
|
if (taunting_count) {
|
||||||
if (toggle_taunt)
|
if (toggle_taunt) {
|
||||||
c->Message(Chat::White, "%i of your bots and their pets %s toggled their taunting state", taunting_count, ((taunting_count != 1) ? ("have") : ("has")));
|
c->Message(
|
||||||
else
|
Chat::White,
|
||||||
c->Message(Chat::White, "%i of your bots and their pets %s %s taunting", taunting_count, ((taunting_count != 1) ? ("have") : ("has")), ((taunt_state) ? ("started") : ("stopped")));
|
fmt::format(
|
||||||
|
"{} of your bots and their pets {} toggled their taunting state",
|
||||||
|
taunting_count,
|
||||||
|
taunting_count != 1 ? "have" : "has"
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"{} of your bots and their pets {} {} taunting.",
|
||||||
|
taunting_count,
|
||||||
|
taunting_count != 1 ? "have" : "has",
|
||||||
|
taunt_state ? "started" : "stopped"
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c->Message(Chat::White, "None of your bots are capable of taunting");
|
c->Message(Chat::White, "None of your bots are capable of taunting");
|
||||||
@ -6600,14 +6705,7 @@ void bot_subcommand_bot_spawn(Client *c, const Seperator *sep)
|
|||||||
if (c->GetBotOption(Client::booSpawnMessageSay)) {
|
if (c->GetBotOption(Client::booSpawnMessageSay)) {
|
||||||
Bot::BotGroupSay(my_bot, bot_spawn_message[message_index].c_str());
|
Bot::BotGroupSay(my_bot, bot_spawn_message[message_index].c_str());
|
||||||
} else if (c->GetBotOption(Client::booSpawnMessageTell)) {
|
} else if (c->GetBotOption(Client::booSpawnMessageTell)) {
|
||||||
c->Message(
|
my_bot->OwnerMessage(bot_spawn_message[message_index]);
|
||||||
Chat::Tell,
|
|
||||||
fmt::format(
|
|
||||||
"{} tells you, \"{}\"",
|
|
||||||
my_bot->GetCleanName(),
|
|
||||||
bot_spawn_message[message_index]
|
|
||||||
).c_str()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6663,9 +6761,11 @@ void bot_subcommand_bot_stance(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
Bot::BotGroupSay(
|
Bot::BotGroupSay(
|
||||||
bot_iter,
|
bot_iter,
|
||||||
"My current stance is '%s' (%i)",
|
fmt::format(
|
||||||
EQ::constants::GetStanceName(bot_iter->GetBotStance()),
|
"My current stance is {} ({}).",
|
||||||
bot_iter->GetBotStance()
|
EQ::constants::GetStanceName(bot_iter->GetBotStance()),
|
||||||
|
bot_iter->GetBotStance()
|
||||||
|
).c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6719,41 +6819,63 @@ void bot_subcommand_bot_stop_melee_level(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
void bot_subcommand_bot_summon(Client *c, const Seperator *sep)
|
void bot_subcommand_bot_summon(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
if (helper_command_alias_fail(c, "bot_subcommand_bot_summon", sep->arg[0], "botsummon"))
|
if (helper_command_alias_fail(c, "bot_subcommand_bot_summon", sep->arg[0], "botsummon")) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"Usage: {} ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))",
|
||||||
|
sep->arg[0]
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||||
|
|
||||||
std::list<Bot*> sbl;
|
std::list<Bot*> sbl;
|
||||||
if (ActionableBots::PopulateSBL(c, sep->arg[1], sbl, ab_mask, sep->arg[2]) == ActionableBots::ABT_None)
|
if (ActionableBots::PopulateSBL(c, sep->arg[1], sbl, ab_mask, sep->arg[2]) == ActionableBots::ABT_None) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (auto bot_iter : sbl) {
|
for (auto bot_iter : sbl) {
|
||||||
if (!bot_iter)
|
if (!bot_iter) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
//Bot::BotGroupSay(bot_iter, "Whee!");
|
|
||||||
|
|
||||||
bot_iter->WipeHateList();
|
bot_iter->WipeHateList();
|
||||||
bot_iter->SetTarget(nullptr);
|
bot_iter->SetTarget(nullptr);
|
||||||
bot_iter->Teleport(c->GetPosition());
|
bot_iter->Teleport(c->GetPosition());
|
||||||
bot_iter->DoAnim(0);
|
bot_iter->DoAnim(0);
|
||||||
|
|
||||||
if (!bot_iter->HasPet())
|
if (!bot_iter->HasPet()) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
bot_iter->GetPet()->WipeHateList();
|
bot_iter->GetPet()->WipeHateList();
|
||||||
bot_iter->GetPet()->SetTarget(nullptr);
|
bot_iter->GetPet()->SetTarget(nullptr);
|
||||||
bot_iter->GetPet()->Teleport(c->GetPosition());
|
bot_iter->GetPet()->Teleport(c->GetPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sbl.size() == 1)
|
if (sbl.size() == 1) {
|
||||||
c->Message(Chat::White, "Summoned %s to you", ((sbl.front()) ? (sbl.front()->GetCleanName()) : ("'nullptr'")));
|
c->Message(
|
||||||
else
|
Chat::White,
|
||||||
c->Message(Chat::White, "Summoned %i bots to you", sbl.size());
|
fmt::format(
|
||||||
|
"Summoned {} to you.",
|
||||||
|
sbl.front() ? sbl.front()->GetCleanName() : "no one"
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"Summoned {} bots to you.",
|
||||||
|
sbl.size()
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bot_subcommand_bot_tattoo(Client *c, const Seperator *sep)
|
void bot_subcommand_bot_tattoo(Client *c, const Seperator *sep)
|
||||||
@ -9182,15 +9304,13 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
c->Message(
|
my_bot->OwnerMessage(
|
||||||
Chat::Tell,
|
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} tells you, 'My {} (Slot {}) {} already unequipped.'",
|
"My {} (Slot {}) {} already unequipped.",
|
||||||
my_bot->GetCleanName(),
|
|
||||||
EQ::invslot::GetInvPossessionsSlotName(slot_id),
|
EQ::invslot::GetInvPossessionsSlotName(slot_id),
|
||||||
slot_id,
|
slot_id,
|
||||||
slot_message
|
slot_message
|
||||||
).c_str()
|
)
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -9247,15 +9367,13 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
|
|||||||
my_bot->BotRemoveEquipItem(slot_id);
|
my_bot->BotRemoveEquipItem(slot_id);
|
||||||
my_bot->CalcBotStats(c->GetBotOption(Client::booStatsUpdate));
|
my_bot->CalcBotStats(c->GetBotOption(Client::booStatsUpdate));
|
||||||
|
|
||||||
c->Message(
|
my_bot->OwnerMessage(
|
||||||
Chat::Tell,
|
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} tells you, 'I have unequipped {} from my {} (Slot {}).'",
|
"I have unequipped {} from my {} (Slot {}).",
|
||||||
my_bot->GetCleanName(),
|
|
||||||
linker.GenerateLink(),
|
linker.GenerateLink(),
|
||||||
EQ::invslot::GetInvPossessionsSlotName(slot_id),
|
EQ::invslot::GetInvPossessionsSlotName(slot_id),
|
||||||
slot_id
|
slot_id
|
||||||
).c_str()
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9890,8 +10008,16 @@ bool helper_cast_standard_spell(Bot* casting_bot, Mob* target_mob, int spell_id,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
casting_bot->InterruptSpell();
|
casting_bot->InterruptSpell();
|
||||||
if (annouce_cast)
|
if (annouce_cast) {
|
||||||
Bot::BotGroupSay(casting_bot, "Attempting to cast '%s' on %s", spells[spell_id].name, target_mob->GetCleanName());
|
Bot::BotGroupSay(
|
||||||
|
casting_bot,
|
||||||
|
fmt::format(
|
||||||
|
"Attempting to cast {} on {}.",
|
||||||
|
spells[spell_id].name,
|
||||||
|
target_mob->GetCleanName()
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return casting_bot->CastSpell(spell_id, target_mob->GetID(), EQ::spells::CastingSlot::Gem2, -1, -1, dont_root_before);
|
return casting_bot->CastSpell(spell_id, target_mob->GetID(), EQ::spells::CastingSlot::Gem2, -1, -1, dont_root_before);
|
||||||
}
|
}
|
||||||
@ -9919,54 +10045,115 @@ bool helper_command_alias_fail(Client *bot_owner, const char* command_handler, c
|
|||||||
|
|
||||||
void helper_command_depart_list(Client* bot_owner, Bot* druid_bot, Bot* wizard_bot, bcst_list* local_list, bool single_flag)
|
void helper_command_depart_list(Client* bot_owner, Bot* druid_bot, Bot* wizard_bot, bcst_list* local_list, bool single_flag)
|
||||||
{
|
{
|
||||||
if (!bot_owner)
|
if (!bot_owner) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!MyBots::IsMyBot(bot_owner, druid_bot))
|
if (!MyBots::IsMyBot(bot_owner, druid_bot)) {
|
||||||
druid_bot = nullptr;
|
druid_bot = nullptr;
|
||||||
if (!MyBots::IsMyBot(bot_owner, wizard_bot))
|
}
|
||||||
|
|
||||||
|
if (!MyBots::IsMyBot(bot_owner, wizard_bot)) {
|
||||||
wizard_bot = nullptr;
|
wizard_bot = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
if (!druid_bot && !wizard_bot) {
|
if (!druid_bot && !wizard_bot) {
|
||||||
bot_owner->Message(Chat::White, "No bots are capable of performing this action");
|
bot_owner->Message(Chat::White, "No bots are capable of performing this action");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bot_owner->Message(Chat::White, "The following destinations are available:");
|
|
||||||
if (!local_list) {
|
if (!local_list) {
|
||||||
bot_owner->Message(Chat::White, "None");
|
bot_owner->Message(Chat::White, "There are no destinations you can be taken to.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string msg;
|
std::string msg;
|
||||||
std::string text_link;
|
std::string text_link;
|
||||||
|
|
||||||
int destinations = 0;
|
auto destination_count = 0;
|
||||||
|
auto destination_number = 1;
|
||||||
for (auto list_iter : *local_list) {
|
for (auto list_iter : *local_list) {
|
||||||
auto local_entry = list_iter->SafeCastToDepart();
|
auto local_entry = list_iter->SafeCastToDepart();
|
||||||
if (!local_entry)
|
if (!local_entry) {
|
||||||
continue;
|
|
||||||
|
|
||||||
if (druid_bot && druid_bot->GetClass() == local_entry->caster_class && druid_bot->GetLevel() >= local_entry->spell_level) {
|
|
||||||
if (local_entry->single != single_flag)
|
|
||||||
continue;
|
|
||||||
msg = StringFormat("%ccircle %s%s", BOT_COMMAND_CHAR, spells[local_entry->spell_id].teleport_zone, ((single_flag) ? (" single") : ("")));
|
|
||||||
text_link = druid_bot->CreateSayLink(bot_owner, msg.c_str(), local_entry->long_name.c_str());
|
|
||||||
Bot::BotGroupSay(druid_bot, "dest: '%s' click: %s", spells[local_entry->spell_id].teleport_zone, text_link.c_str());
|
|
||||||
++destinations;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (wizard_bot && wizard_bot->GetClass() == local_entry->caster_class && wizard_bot->GetLevel() >= local_entry->spell_level) {
|
|
||||||
if (local_entry->single != single_flag)
|
if (
|
||||||
|
druid_bot &&
|
||||||
|
druid_bot->GetClass() == local_entry->caster_class &&
|
||||||
|
druid_bot->GetLevel() >= local_entry->spell_level
|
||||||
|
) {
|
||||||
|
if (local_entry->single != single_flag) {
|
||||||
continue;
|
continue;
|
||||||
msg = StringFormat("%cportal %s%s", BOT_COMMAND_CHAR, spells[local_entry->spell_id].teleport_zone, ((single_flag) ? (" single") : ("")));
|
}
|
||||||
text_link = wizard_bot->CreateSayLink(bot_owner, msg.c_str(), local_entry->long_name.c_str());
|
|
||||||
Bot::BotGroupSay(wizard_bot, "dest: '%s' click: %s", spells[local_entry->spell_id].teleport_zone, text_link.c_str());
|
msg = fmt::format(
|
||||||
++destinations;
|
"{}circle {}{}",
|
||||||
|
std::to_string(BOT_COMMAND_CHAR),
|
||||||
|
spells[local_entry->spell_id].teleport_zone,
|
||||||
|
single_flag ? " single" : ""
|
||||||
|
);
|
||||||
|
|
||||||
|
text_link = druid_bot->CreateSayLink(
|
||||||
|
bot_owner,
|
||||||
|
msg.c_str(),
|
||||||
|
"Goto"
|
||||||
|
);
|
||||||
|
|
||||||
|
druid_bot->OwnerMessage(
|
||||||
|
fmt::format(
|
||||||
|
"Destination {} | {} | {}",
|
||||||
|
destination_number,
|
||||||
|
local_entry->long_name,
|
||||||
|
text_link
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
destination_count++;
|
||||||
|
destination_number++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
wizard_bot &&
|
||||||
|
wizard_bot->GetClass() == local_entry->caster_class &&
|
||||||
|
wizard_bot->GetLevel() >= local_entry->spell_level
|
||||||
|
) {
|
||||||
|
if (local_entry->single != single_flag) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = fmt::format(
|
||||||
|
"{}portal {}{}",
|
||||||
|
std::to_string(BOT_COMMAND_CHAR),
|
||||||
|
spells[local_entry->spell_id].teleport_zone,
|
||||||
|
single_flag ? " single" : ""
|
||||||
|
);
|
||||||
|
|
||||||
|
text_link = wizard_bot->CreateSayLink(
|
||||||
|
bot_owner,
|
||||||
|
msg.c_str(),
|
||||||
|
"Goto"
|
||||||
|
);
|
||||||
|
|
||||||
|
wizard_bot->OwnerMessage(
|
||||||
|
fmt::format(
|
||||||
|
"Destination {} | {} | {}",
|
||||||
|
destination_number,
|
||||||
|
local_entry->long_name,
|
||||||
|
text_link
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
destination_count++;
|
||||||
|
destination_number++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!destinations)
|
|
||||||
bot_owner->Message(Chat::White, "None");
|
if (!destination_count) {
|
||||||
|
bot_owner->Message(Chat::White, "There are no destinations you can be taken to.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool helper_is_help_or_usage(const char* arg)
|
bool helper_is_help_or_usage(const char* arg)
|
||||||
|
|||||||
@ -98,8 +98,16 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
|||||||
}
|
}
|
||||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, addMob, botSpell.ManaCost);
|
castedSpell = AIDoSpellCast(botSpell.SpellIndex, addMob, botSpell.ManaCost);
|
||||||
|
|
||||||
if(castedSpell)
|
if (castedSpell) {
|
||||||
BotGroupSay(this, "Attempting to mez %s.", addMob->GetCleanName());
|
BotGroupSay(
|
||||||
|
this,
|
||||||
|
fmt::format(
|
||||||
|
"Attempting to mesmerize {} with {}.",
|
||||||
|
addMob->GetCleanName(),
|
||||||
|
spells[botSpell.SpellId].name
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -272,7 +280,13 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
|||||||
Group *g = GetGroup();
|
Group *g = GetGroup();
|
||||||
|
|
||||||
if(g) {
|
if(g) {
|
||||||
BotGroupSay(this, "Casting %s.", spells[botSpell.SpellId].name);
|
BotGroupSay(
|
||||||
|
this,
|
||||||
|
fmt::format(
|
||||||
|
"Casting {}.",
|
||||||
|
spells[botSpell.SpellId].name
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
|
||||||
for( int i = 0; i<MAX_GROUP_MEMBERS; i++) {
|
for( int i = 0; i<MAX_GROUP_MEMBERS; i++) {
|
||||||
if(g->members[i] && !g->members[i]->qglobal) {
|
if(g->members[i] && !g->members[i]->qglobal) {
|
||||||
@ -281,10 +295,17 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
if (tar != this) { //we don't need spam of bots healing themselves
|
||||||
if(tar != this) //we don't need spam of bots healing themselves
|
BotGroupSay(
|
||||||
BotGroupSay(this, "Casting %s on %s", spells[botSpell.SpellId].name, tar->GetCleanName());
|
this,
|
||||||
|
fmt::format(
|
||||||
|
"Casting {} on {}.",
|
||||||
|
spells[botSpell.SpellId].name,
|
||||||
|
tar->GetCleanName()
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
tar->SetDontHealMeBefore(Timer::GetCurrentTime() + 2000);
|
tar->SetDontHealMeBefore(Timer::GetCurrentTime() + 2000);
|
||||||
}
|
}
|
||||||
@ -892,8 +913,16 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
|||||||
|
|
||||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost);
|
||||||
|
|
||||||
if(castedSpell && GetClass() != BARD)
|
if (castedSpell && GetClass() != BARD) {
|
||||||
BotGroupSay(this, "Attempting to slow %s.", tar->GetCleanName());
|
BotGroupSay(
|
||||||
|
this,
|
||||||
|
fmt::format(
|
||||||
|
"Attempting to slow {} with {}.",
|
||||||
|
tar->GetCleanName(),
|
||||||
|
spells[botSpell.SpellId].name
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -982,7 +1011,14 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
|||||||
|
|
||||||
castedSpell = AIDoSpellCast(iter.SpellIndex, tar, iter.ManaCost);
|
castedSpell = AIDoSpellCast(iter.SpellIndex, tar, iter.ManaCost);
|
||||||
if (castedSpell) {
|
if (castedSpell) {
|
||||||
BotGroupSay(this, "Attempting to reduce hate on %s.", tar->GetCleanName());
|
BotGroupSay(
|
||||||
|
this,
|
||||||
|
fmt::format(
|
||||||
|
"Attempting to reduce hate on {} with {}.",
|
||||||
|
tar->GetCleanName(),
|
||||||
|
spells[iter.SpellId].name
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1596,8 +1632,16 @@ bool Bot::AIHealRotation(Mob* tar, bool useFastHeals) {
|
|||||||
|
|
||||||
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontHealMeBeforeTime);
|
castedSpell = AIDoSpellCast(botSpell.SpellIndex, tar, botSpell.ManaCost, &TempDontHealMeBeforeTime);
|
||||||
|
|
||||||
if(castedSpell)
|
if (castedSpell) {
|
||||||
Say("Casting %s on %s, please stay in range!", spells[botSpell.SpellId].name, tar->GetCleanName());
|
BotGroupSay(
|
||||||
|
this,
|
||||||
|
fmt::format(
|
||||||
|
"Casting {} on {}, please stay in range!",
|
||||||
|
spells[botSpell.SpellId].name,
|
||||||
|
tar->GetCleanName()
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return castedSpell;
|
return castedSpell;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1170,8 +1170,9 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
}
|
}
|
||||||
|
|
||||||
Mob* sender = this;
|
Mob* sender = this;
|
||||||
if (GetPet() && GetTarget() == GetPet() && GetPet()->FindType(SE_VoiceGraft))
|
if (GetPet() && GetTarget() == GetPet() && GetPet()->FindType(SE_VoiceGraft)) {
|
||||||
sender = GetPet();
|
sender = GetPet();
|
||||||
|
}
|
||||||
|
|
||||||
if (!is_silent) {
|
if (!is_silent) {
|
||||||
entity_list.ChannelMessage(sender, chan_num, language, lang_skill, message);
|
entity_list.ChannelMessage(sender, chan_num, language, lang_skill, message);
|
||||||
@ -1179,36 +1180,51 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
|
|
||||||
parse->EventPlayer(EVENT_SAY, this, message, language);
|
parse->EventPlayer(EVENT_SAY, this, message, language);
|
||||||
|
|
||||||
if (sender != this)
|
if (sender != this) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if(quest_manager.ProximitySayInUse())
|
if (quest_manager.ProximitySayInUse()) {
|
||||||
entity_list.ProcessProximitySay(message, this, language);
|
entity_list.ProcessProximitySay(message, this, language);
|
||||||
|
}
|
||||||
|
|
||||||
if (GetTarget() != 0 && GetTarget()->IsNPC() &&
|
if (
|
||||||
!IsInvisible(GetTarget())) {
|
GetTarget() &&
|
||||||
if(!GetTarget()->CastToNPC()->IsEngaged()) {
|
GetTarget()->IsNPC() &&
|
||||||
CheckLDoNHail(GetTarget());
|
!IsInvisible(GetTarget())
|
||||||
CheckEmoteHail(GetTarget(), message);
|
) {
|
||||||
|
auto* t = GetTarget()->CastToNPC();
|
||||||
|
if (!t->IsEngaged()) {
|
||||||
|
CheckLDoNHail(t);
|
||||||
|
CheckEmoteHail(t, message);
|
||||||
|
|
||||||
if(DistanceNoZ(m_Position, GetTarget()->GetPosition()) <= RuleI(Range, Say)) {
|
if (DistanceNoZ(m_Position, t->GetPosition()) <= RuleI(Range, Say)) {
|
||||||
NPC *tar = GetTarget()->CastToNPC();
|
|
||||||
parse->EventNPC(EVENT_SAY, tar->CastToNPC(), this, message, language);
|
|
||||||
|
|
||||||
if(RuleB(TaskSystem, EnableTaskSystem)) {
|
parse->EventNPC(EVENT_SAY, t, this, message, language);
|
||||||
if (UpdateTasksOnSpeakWith(tar)) {
|
|
||||||
tar->DoQuestPause(this);
|
if (RuleB(TaskSystem, EnableTaskSystem)) {
|
||||||
|
if (UpdateTasksOnSpeakWith(t)) {
|
||||||
|
t->DoQuestPause(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
if (DistanceSquaredNoZ(m_Position, t->GetPosition()) <= RuleI(Range, Say)) {
|
||||||
if (DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= RuleI(Range, Say)) {
|
parse->EventNPC(EVENT_AGGRO_SAY, t, this, message, language);
|
||||||
parse->EventNPC(EVENT_AGGRO_SAY, GetTarget()->CastToNPC(), this, message, language);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
else if (GetTarget() && GetTarget()->IsBot() && !IsInvisible(GetTarget())) {
|
||||||
|
if (DistanceNoZ(m_Position, GetTarget()->GetPosition()) <= RuleI(Range, Say)) {
|
||||||
|
parse->EventBot(GetTarget()->IsEngaged() ? EVENT_AGGRO_SAY : EVENT_SAY, GetTarget()->CastToBot(), this, message, language);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ChatChannel_UCSRelay:
|
case ChatChannel_UCSRelay:
|
||||||
@ -5470,9 +5486,9 @@ void Client::ShowSkillsWindow()
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::Signal(uint32 data)
|
void Client::Signal(int signal_id)
|
||||||
{
|
{
|
||||||
std::string export_string = fmt::format("{}", data);
|
const auto export_string = fmt::format("{}", signal_id);
|
||||||
parse->EventPlayer(EVENT_SIGNAL, this, export_string, 0);
|
parse->EventPlayer(EVENT_SIGNAL, this, export_string, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1408,7 +1408,7 @@ public:
|
|||||||
void SuspendMinion(int value);
|
void SuspendMinion(int value);
|
||||||
void Doppelganger(uint16 spell_id, Mob *target, const char *name_override, int pet_count, int pet_duration);
|
void Doppelganger(uint16 spell_id, Mob *target, const char *name_override, int pet_count, int pet_duration);
|
||||||
void NotifyNewTitlesAvailable();
|
void NotifyNewTitlesAvailable();
|
||||||
void Signal(uint32 data);
|
void Signal(int signal_id);
|
||||||
Mob *GetBindSightTarget() { return bind_sight_target; }
|
Mob *GetBindSightTarget() { return bind_sight_target; }
|
||||||
void SetBindSightTarget(Mob *n) { bind_sight_target = n; }
|
void SetBindSightTarget(Mob *n) { bind_sight_target = n; }
|
||||||
const uint16 GetBoatID() const { return controlling_boat_id; }
|
const uint16 GetBoatID() const { return controlling_boat_id; }
|
||||||
|
|||||||
@ -11200,13 +11200,19 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string export_string = fmt::format("{}", popup_response->popupid);
|
const auto export_string = fmt::format("{}", popup_response->popupid);
|
||||||
|
|
||||||
parse->EventPlayer(EVENT_POPUP_RESPONSE, this, export_string, 0);
|
parse->EventPlayer(EVENT_POPUP_RESPONSE, this, export_string, 0);
|
||||||
|
|
||||||
Mob *Target = GetTarget();
|
auto t = GetTarget();
|
||||||
if (Target && Target->IsNPC()) {
|
if (t) {
|
||||||
parse->EventNPC(EVENT_POPUP_RESPONSE, Target->CastToNPC(), this, export_string, 0);
|
if (t->IsNPC()) {
|
||||||
|
parse->EventNPC(EVENT_POPUP_RESPONSE, t->CastToNPC(), this, export_string, 0);
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (t->IsBot()) {
|
||||||
|
parse->EventBot(EVENT_POPUP_RESPONSE, t->CastToBot(), this, export_string, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -163,6 +163,11 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
|||||||
"EVENT_TASK_BEFORE_UPDATE",
|
"EVENT_TASK_BEFORE_UPDATE",
|
||||||
"EVENT_AA_BUY",
|
"EVENT_AA_BUY",
|
||||||
"EVENT_AA_GAIN"
|
"EVENT_AA_GAIN"
|
||||||
|
#ifdef BOTS
|
||||||
|
,
|
||||||
|
"EVENT_SPELL_EFFECT_BOT",
|
||||||
|
"EVENT_SPELL_EFFECT_BUFF_TIC_BOT"
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
PerlembParser::PerlembParser() : perl(nullptr)
|
PerlembParser::PerlembParser() : perl(nullptr)
|
||||||
@ -170,6 +175,11 @@ PerlembParser::PerlembParser() : perl(nullptr)
|
|||||||
global_npc_quest_status_ = questUnloaded;
|
global_npc_quest_status_ = questUnloaded;
|
||||||
player_quest_status_ = questUnloaded;
|
player_quest_status_ = questUnloaded;
|
||||||
global_player_quest_status_ = questUnloaded;
|
global_player_quest_status_ = questUnloaded;
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
bot_quest_status_ = questUnloaded;
|
||||||
|
global_bot_quest_status_ = questUnloaded;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
PerlembParser::~PerlembParser()
|
PerlembParser::~PerlembParser()
|
||||||
@ -203,15 +213,28 @@ void PerlembParser::ReloadQuests()
|
|||||||
global_npc_quest_status_ = questUnloaded;
|
global_npc_quest_status_ = questUnloaded;
|
||||||
player_quest_status_ = questUnloaded;
|
player_quest_status_ = questUnloaded;
|
||||||
global_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();
|
item_quest_status_.clear();
|
||||||
spell_quest_status_.clear();
|
spell_quest_status_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int PerlembParser::EventCommon(
|
int PerlembParser::EventCommon(
|
||||||
QuestEventID event, uint32 objid, const char *data, NPC *npcmob, EQ::ItemInstance *item_inst, const SPDat_Spell_Struct* spell, Mob *mob,
|
QuestEventID event,
|
||||||
uint32 extradata, bool global, std::vector<std::any> *extra_pointers
|
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) {
|
if (!perl) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -220,20 +243,46 @@ int PerlembParser::EventCommon(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isPlayerQuest = false;
|
bool isPlayerQuest = false;
|
||||||
bool isGlobalPlayerQuest = false;
|
bool isGlobalPlayerQuest = false;
|
||||||
bool isGlobalNPC = false;
|
bool isGlobalNPC = false;
|
||||||
bool isItemQuest = false;
|
bool isBotQuest = false;
|
||||||
bool isSpellQuest = false;
|
bool isGlobalBotQuest = false;
|
||||||
|
bool isItemQuest = false;
|
||||||
|
bool isSpellQuest = false;
|
||||||
|
|
||||||
std::string package_name;
|
std::string package_name;
|
||||||
|
|
||||||
GetQuestTypes(
|
GetQuestTypes(
|
||||||
isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
|
isPlayerQuest,
|
||||||
event, npcmob, item_inst, mob, global
|
isGlobalPlayerQuest,
|
||||||
|
isBotQuest,
|
||||||
|
isGlobalBotQuest,
|
||||||
|
isGlobalNPC,
|
||||||
|
isItemQuest,
|
||||||
|
isSpellQuest,
|
||||||
|
event,
|
||||||
|
npcmob,
|
||||||
|
item_inst,
|
||||||
|
mob,
|
||||||
|
global
|
||||||
);
|
);
|
||||||
|
|
||||||
GetQuestPackageName(
|
GetQuestPackageName(
|
||||||
isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
|
isPlayerQuest,
|
||||||
package_name, event, objid, data, npcmob, item_inst, global
|
isGlobalPlayerQuest,
|
||||||
|
isBotQuest,
|
||||||
|
isGlobalBotQuest,
|
||||||
|
isGlobalNPC,
|
||||||
|
isItemQuest,
|
||||||
|
isSpellQuest,
|
||||||
|
package_name,
|
||||||
|
event,
|
||||||
|
objid,
|
||||||
|
data,
|
||||||
|
npcmob,
|
||||||
|
item_inst,
|
||||||
|
global
|
||||||
);
|
);
|
||||||
|
|
||||||
const char *sub_name = QuestEventSubroutines[event];
|
const char *sub_name = QuestEventSubroutines[event];
|
||||||
@ -249,6 +298,8 @@ int PerlembParser::EventCommon(
|
|||||||
ExportQGlobals(
|
ExportQGlobals(
|
||||||
isPlayerQuest,
|
isPlayerQuest,
|
||||||
isGlobalPlayerQuest,
|
isGlobalPlayerQuest,
|
||||||
|
isBotQuest,
|
||||||
|
isGlobalBotQuest,
|
||||||
isGlobalNPC,
|
isGlobalNPC,
|
||||||
isItemQuest,
|
isItemQuest,
|
||||||
isSpellQuest,
|
isSpellQuest,
|
||||||
@ -264,6 +315,8 @@ int PerlembParser::EventCommon(
|
|||||||
ExportMobVariables(
|
ExportMobVariables(
|
||||||
isPlayerQuest,
|
isPlayerQuest,
|
||||||
isGlobalPlayerQuest,
|
isGlobalPlayerQuest,
|
||||||
|
isBotQuest,
|
||||||
|
isGlobalBotQuest,
|
||||||
isGlobalNPC,
|
isGlobalNPC,
|
||||||
isItemQuest,
|
isItemQuest,
|
||||||
isSpellQuest,
|
isSpellQuest,
|
||||||
@ -290,6 +343,8 @@ int PerlembParser::EventCommon(
|
|||||||
|
|
||||||
if (isPlayerQuest || isGlobalPlayerQuest) {
|
if (isPlayerQuest || isGlobalPlayerQuest) {
|
||||||
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr, nullptr);
|
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) {
|
} else if (isItemQuest) {
|
||||||
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, item_inst, nullptr);
|
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, item_inst, nullptr);
|
||||||
} else if (isSpellQuest) {
|
} else if (isSpellQuest) {
|
||||||
@ -304,19 +359,19 @@ int PerlembParser::EventCommon(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PerlembParser::EventNPC(
|
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
|
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(
|
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
|
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(
|
int PerlembParser::EventPlayer(
|
||||||
@ -345,11 +400,11 @@ int PerlembParser::EventItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
int PerlembParser::EventSpell(
|
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
|
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)
|
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 qi = (std::string) "$" + (std::string) pkgprefix + (std::string) "::questitem";
|
||||||
std::string sp = (std::string) "$" + (std::string) pkgprefix + (std::string) "::spell";
|
std::string sp = (std::string) "$" + (std::string) pkgprefix + (std::string) "::spell";
|
||||||
std::string enl = (std::string) "$" + (std::string) pkgprefix + (std::string) "::entity_list";
|
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()) {
|
if (clear_vars_.find(cl) != clear_vars_.end()) {
|
||||||
std::string eval_str = cl;
|
auto e = fmt::format("{} = undef;", cl);
|
||||||
eval_str += " = undef;";
|
perl->eval(e.c_str());
|
||||||
perl->eval(eval_str.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clear_vars_.find(np) != clear_vars_.end()) {
|
if (clear_vars_.find(np) != clear_vars_.end()) {
|
||||||
std::string eval_str = np;
|
auto e = fmt::format("{} = undef;", np);
|
||||||
eval_str += " = undef;";
|
perl->eval(e.c_str());
|
||||||
perl->eval(eval_str.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clear_vars_.find(qi) != clear_vars_.end()) {
|
if (clear_vars_.find(qi) != clear_vars_.end()) {
|
||||||
std::string eval_str = qi;
|
auto e = fmt::format("{} = undef;", qi);
|
||||||
eval_str += " = undef;";
|
perl->eval(e.c_str());
|
||||||
perl->eval(eval_str.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clear_vars_.find(sp) != clear_vars_.end()) {
|
if (clear_vars_.find(sp) != clear_vars_.end()) {
|
||||||
std::string eval_str = sp;
|
auto e = fmt::format("{} = undef;", sp);
|
||||||
eval_str += " = undef;";
|
perl->eval(e.c_str());
|
||||||
perl->eval(eval_str.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clear_vars_.find(enl) != clear_vars_.end()) {
|
if (clear_vars_.find(enl) != clear_vars_.end()) {
|
||||||
std::string eval_str = enl;
|
auto e = fmt::format("{} = undef;", enl);
|
||||||
eval_str += " = undef;";
|
perl->eval(e.c_str());
|
||||||
perl->eval(eval_str.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
|
//init a couple special vars: client, npc, entity_list
|
||||||
Client *curc = quest_manager.GetInitiator();
|
Client *curc = quest_manager.GetInitiator();
|
||||||
snprintf(namebuf, 64, "%s::client", pkgprefix);
|
buf = fmt::format("{}::client", pkgprefix);
|
||||||
SV *client = get_sv(namebuf, true);
|
SV *client = get_sv(buf.c_str(), true);
|
||||||
if (curc != nullptr) {
|
if (curc) {
|
||||||
sv_setref_pv(client, "Client", curc);
|
sv_setref_pv(client, "Client", curc);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//clear out the value, mainly to get rid of blessedness
|
//clear out the value, mainly to get rid of blessedness
|
||||||
sv_setsv(client, _empty_sv);
|
sv_setsv(client, _empty_sv);
|
||||||
}
|
}
|
||||||
|
|
||||||
//only export NPC if it's a npc quest
|
//only export NPC if it's a npc quest
|
||||||
if (!other->IsClient()) {
|
if (!other->IsClient() && other->IsNPC()) {
|
||||||
NPC *curn = quest_manager.GetNPC();
|
NPC *curn = quest_manager.GetNPC();
|
||||||
snprintf(namebuf, 64, "%s::npc", pkgprefix);
|
buf = fmt::format("{}::npc", pkgprefix);
|
||||||
SV *npc = get_sv(namebuf, true);
|
SV *npc = get_sv(buf.c_str(), true);
|
||||||
sv_setref_pv(npc, "NPC", curn);
|
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
|
//only export QuestItem if it's an item quest
|
||||||
if (item_inst) {
|
if (item_inst) {
|
||||||
EQ::ItemInstance *curi = quest_manager.GetQuestItem();
|
EQ::ItemInstance *curi = quest_manager.GetQuestItem();
|
||||||
snprintf(namebuf, 64, "%s::questitem", pkgprefix);
|
buf = fmt::format("{}::questitem", pkgprefix);
|
||||||
SV *questitem = get_sv(namebuf, true);
|
SV *questitem = get_sv(buf.c_str(), true);
|
||||||
sv_setref_pv(questitem, "QuestItem", curi);
|
sv_setref_pv(questitem, "QuestItem", curi);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spell) {
|
if (spell) {
|
||||||
const SPDat_Spell_Struct* current_spell = quest_manager.GetQuestSpell();
|
const SPDat_Spell_Struct* current_spell = quest_manager.GetQuestSpell();
|
||||||
SPDat_Spell_Struct* real_spell = const_cast<SPDat_Spell_Struct*>(current_spell);
|
SPDat_Spell_Struct* real_spell = const_cast<SPDat_Spell_Struct*>(current_spell);
|
||||||
snprintf(namebuf, 64, "%s::spell", pkgprefix);
|
buf = fmt::format("{}::spell", pkgprefix);
|
||||||
SV *spell = get_sv(namebuf, true);
|
SV *spell = get_sv(buf.c_str(), true);
|
||||||
sv_setref_pv(spell, "Spell", (void *) real_spell);
|
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);
|
sv_setref_pv(el, "EntityList", &entity_list);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -944,11 +1015,20 @@ int PerlembParser::SendCommands(
|
|||||||
std::string qi = (std::string) "$" + (std::string) pkgprefix + (std::string) "::questitem";
|
std::string qi = (std::string) "$" + (std::string) pkgprefix + (std::string) "::questitem";
|
||||||
std::string sp = (std::string) "$" + (std::string) pkgprefix + (std::string) "::spell";
|
std::string sp = (std::string) "$" + (std::string) pkgprefix + (std::string) "::spell";
|
||||||
std::string enl = (std::string) "$" + (std::string) pkgprefix + (std::string) "::entity_list";
|
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_[cl] = 1;
|
||||||
clear_vars_[np] = 1;
|
clear_vars_[np] = 1;
|
||||||
clear_vars_[qi] = 1;
|
clear_vars_[qi] = 1;
|
||||||
clear_vars_[sp] = 1;
|
clear_vars_[sp] = 1;
|
||||||
clear_vars_[enl] = 1;
|
clear_vars_[enl] = 1;
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
clear_vars_[bot] = 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -967,19 +1047,16 @@ int PerlembParser::SendCommands(
|
|||||||
|
|
||||||
#ifdef EMBPERL_XS_CLASSES
|
#ifdef EMBPERL_XS_CLASSES
|
||||||
if (!quest_manager.QuestsRunning()) {
|
if (!quest_manager.QuestsRunning()) {
|
||||||
auto iter = clear_vars_.begin();
|
|
||||||
std::string eval_str;
|
std::string eval_str;
|
||||||
while (iter != clear_vars_.end()) {
|
for (const auto &v : clear_vars_) {
|
||||||
eval_str += iter->first;
|
eval_str += fmt::format("{} = undef;", v.first);
|
||||||
eval_str += " = undef;";
|
|
||||||
++iter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_vars_.clear();
|
clear_vars_.clear();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
perl->eval(eval_str.c_str());
|
perl->eval(eval_str.c_str());
|
||||||
}
|
} catch (std::string e) {
|
||||||
catch (std::string e) {
|
|
||||||
AddError(
|
AddError(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Script Clear Error | Error [{}]",
|
"Script Clear Error | Error [{}]",
|
||||||
@ -1023,29 +1100,61 @@ void PerlembParser::MapFunctions()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PerlembParser::GetQuestTypes(
|
void PerlembParser::GetQuestTypes(
|
||||||
bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
bool &isPlayerQuest,
|
||||||
bool &isSpellQuest, QuestEventID event, NPC *npcmob, EQ::ItemInstance *item_inst, Mob *mob, bool global
|
bool &isGlobalPlayerQuest,
|
||||||
)
|
bool &isBotQuest,
|
||||||
{
|
bool &isGlobalBotQuest,
|
||||||
if (event == EVENT_SPELL_EFFECT_CLIENT ||
|
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 ||
|
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_CLIENT ||
|
||||||
event == EVENT_SPELL_EFFECT_BUFF_TIC_NPC ||
|
event == EVENT_SPELL_EFFECT_BUFF_TIC_NPC ||
|
||||||
|
#ifdef BOTS
|
||||||
|
event == EVENT_SPELL_EFFECT_BUFF_TIC_BOT ||
|
||||||
|
#endif
|
||||||
event == EVENT_SPELL_FADE ||
|
event == EVENT_SPELL_FADE ||
|
||||||
event == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE) {
|
event == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE
|
||||||
|
) {
|
||||||
isSpellQuest = true;
|
isSpellQuest = true;
|
||||||
}
|
} else {
|
||||||
else {
|
if (npcmob) {
|
||||||
if (!npcmob && mob) {
|
|
||||||
if (!item_inst) {
|
if (!item_inst) {
|
||||||
if (global) {
|
if (global) {
|
||||||
isGlobalPlayerQuest = true;
|
if (npcmob->IsBot()) {
|
||||||
}
|
isGlobalBotQuest = true;
|
||||||
else {
|
}
|
||||||
isPlayerQuest = 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;
|
isItemQuest = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1055,6 +1164,8 @@ void PerlembParser::GetQuestTypes(
|
|||||||
void PerlembParser::GetQuestPackageName(
|
void PerlembParser::GetQuestPackageName(
|
||||||
bool &isPlayerQuest,
|
bool &isPlayerQuest,
|
||||||
bool &isGlobalPlayerQuest,
|
bool &isGlobalPlayerQuest,
|
||||||
|
bool &isBotQuest,
|
||||||
|
bool &isGlobalBotQuest,
|
||||||
bool &isGlobalNPC,
|
bool &isGlobalNPC,
|
||||||
bool &isItemQuest,
|
bool &isItemQuest,
|
||||||
bool &isSpellQuest,
|
bool &isSpellQuest,
|
||||||
@ -1062,7 +1173,7 @@ void PerlembParser::GetQuestPackageName(
|
|||||||
QuestEventID event,
|
QuestEventID event,
|
||||||
uint32 objid,
|
uint32 objid,
|
||||||
const char *data,
|
const char *data,
|
||||||
NPC *npcmob,
|
Mob *npcmob,
|
||||||
EQ::ItemInstance *item_inst,
|
EQ::ItemInstance *item_inst,
|
||||||
bool global
|
bool global
|
||||||
)
|
)
|
||||||
@ -1070,6 +1181,8 @@ void PerlembParser::GetQuestPackageName(
|
|||||||
if (
|
if (
|
||||||
!isPlayerQuest &&
|
!isPlayerQuest &&
|
||||||
!isGlobalPlayerQuest &&
|
!isGlobalPlayerQuest &&
|
||||||
|
!isBotQuest &&
|
||||||
|
!isGlobalBotQuest &&
|
||||||
!isItemQuest &&
|
!isItemQuest &&
|
||||||
!isSpellQuest
|
!isSpellQuest
|
||||||
) {
|
) {
|
||||||
@ -1077,30 +1190,30 @@ void PerlembParser::GetQuestPackageName(
|
|||||||
isGlobalNPC = true;
|
isGlobalNPC = true;
|
||||||
package_name = "qst_global_npc";
|
package_name = "qst_global_npc";
|
||||||
} else {
|
} else {
|
||||||
package_name = "qst_npc_";
|
package_name = fmt::format("qst_npc_{}", npcmob->GetNPCTypeID());
|
||||||
package_name += std::to_string(npcmob->GetNPCTypeID());
|
|
||||||
}
|
}
|
||||||
} else if (isItemQuest) {
|
} else if (isItemQuest) {
|
||||||
// need a valid EQ::ItemInstance pointer check here..unsure how to cancel this process
|
// need a valid EQ::ItemInstance pointer check here..unsure how to cancel this process
|
||||||
const EQ::ItemData *item = item_inst->GetItem();
|
const EQ::ItemData *item = item_inst->GetItem();
|
||||||
package_name = "qst_item_";
|
package_name = fmt::format("qst_item_{}", item->ID);
|
||||||
package_name += std::to_string(item->ID);
|
|
||||||
} else if (isPlayerQuest) {
|
} else if (isPlayerQuest) {
|
||||||
package_name = "qst_player";
|
package_name = "qst_player";
|
||||||
} else if (isGlobalPlayerQuest) {
|
} else if (isGlobalPlayerQuest) {
|
||||||
package_name = "qst_global_player";
|
package_name = "qst_global_player";
|
||||||
|
} else if (isBotQuest) {
|
||||||
|
package_name = "qst_bot";
|
||||||
|
} else if (isGlobalBotQuest) {
|
||||||
|
package_name = "qst_global_bot";
|
||||||
} else {
|
} else {
|
||||||
package_name = "qst_spell_";
|
package_name = fmt::format("qst_spell_{}", objid);
|
||||||
package_name += std::to_string(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
|
if (mob && mob->IsClient()) { // some events like waypoint and spawn don't have a player involved
|
||||||
char_id = mob->CastToClient()->CharacterID();
|
char_id = mob->CastToClient()->CharacterID();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (npcmob) {
|
if (npcmob) {
|
||||||
char_id = -static_cast<int>(npcmob->GetNPCTypeID()); // make char id negative npc id as a fudge
|
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(
|
void PerlembParser::ExportQGlobals(
|
||||||
bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
bool isPlayerQuest,
|
||||||
bool isSpellQuest, std::string &package_name, NPC *npcmob, Mob *mob, int char_id
|
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
|
//NPC quest
|
||||||
if (!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest && !isSpellQuest) {
|
if (
|
||||||
|
!isPlayerQuest &&
|
||||||
|
!isGlobalPlayerQuest &&
|
||||||
|
!isBotQuest &&
|
||||||
|
!isGlobalBotQuest &&
|
||||||
|
!isItemQuest &&
|
||||||
|
!isSpellQuest
|
||||||
|
) {
|
||||||
//only export for npcs that are global enabled.
|
//only export for npcs that are global enabled.
|
||||||
if (npcmob && npcmob->GetQglobal()) {
|
if (npcmob && npcmob->GetQglobal()) {
|
||||||
std::map<std::string, std::string> globhash;
|
std::map<std::string, std::string> globhash;
|
||||||
QGlobalCache *npc_c = nullptr;
|
QGlobalCache *npc_c = nullptr;
|
||||||
QGlobalCache *char_c = nullptr;
|
QGlobalCache *char_c = nullptr;
|
||||||
QGlobalCache *zone_c = nullptr;
|
QGlobalCache *zone_c = nullptr;
|
||||||
|
|
||||||
//retrieve our globals
|
//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()) {
|
if (mob && mob->IsClient()) {
|
||||||
char_c = mob->CastToClient()->GetQGlobals();
|
char_c = mob->CastToClient()->GetQGlobals();
|
||||||
}
|
}
|
||||||
|
|
||||||
zone_c = zone->GetQGlobals();
|
zone_c = zone->GetQGlobals();
|
||||||
|
|
||||||
if (!npc_c) {
|
if (!npc_c) {
|
||||||
npc_c = npcmob->CreateQGlobals();
|
if (npcmob && npcmob->IsNPC()) {
|
||||||
npc_c->LoadByNPCID(npcmob->GetNPCTypeID());
|
npc_c = npcmob->CastToNPC()->CreateQGlobals();
|
||||||
|
npc_c->LoadByNPCID(npcmob->GetNPCTypeID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!char_c) {
|
if (!char_c) {
|
||||||
@ -1157,7 +1295,8 @@ void PerlembParser::ExportQGlobals(
|
|||||||
npc_c->GetBucket(),
|
npc_c->GetBucket(),
|
||||||
npcmob->GetNPCTypeID(),
|
npcmob->GetNPCTypeID(),
|
||||||
char_id,
|
char_id,
|
||||||
zone->GetZoneID());
|
zone->GetZoneID())
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (char_c) {
|
if (char_c) {
|
||||||
@ -1166,7 +1305,8 @@ void PerlembParser::ExportQGlobals(
|
|||||||
char_c->GetBucket(),
|
char_c->GetBucket(),
|
||||||
npcmob->GetNPCTypeID(),
|
npcmob->GetNPCTypeID(),
|
||||||
char_id,
|
char_id,
|
||||||
zone->GetZoneID());
|
zone->GetZoneID()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zone_c) {
|
if (zone_c) {
|
||||||
@ -1175,7 +1315,8 @@ void PerlembParser::ExportQGlobals(
|
|||||||
zone_c->GetBucket(),
|
zone_c->GetBucket(),
|
||||||
npcmob->GetNPCTypeID(),
|
npcmob->GetNPCTypeID(),
|
||||||
char_id,
|
char_id,
|
||||||
zone->GetZoneID());
|
zone->GetZoneID()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto iter = globalMap.begin();
|
auto iter = globalMap.begin();
|
||||||
@ -1184,19 +1325,20 @@ void PerlembParser::ExportQGlobals(
|
|||||||
ExportVar(package_name.c_str(), (*iter).name.c_str(), (*iter).value.c_str());
|
ExportVar(package_name.c_str(), (*iter).name.c_str(), (*iter).value.c_str());
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportHash(package_name.c_str(), "qglobals", globhash);
|
ExportHash(package_name.c_str(), "qglobals", globhash);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
std::map<std::string, std::string> globhash;
|
std::map<std::string, std::string> globhash;
|
||||||
QGlobalCache *char_c = nullptr;
|
QGlobalCache *char_c = nullptr;
|
||||||
QGlobalCache *zone_c = nullptr;
|
QGlobalCache *zone_c = nullptr;
|
||||||
|
|
||||||
//retrieve our globals
|
//retrieve our globals
|
||||||
if (mob && mob->IsClient()) {
|
if (mob && mob->IsClient()) {
|
||||||
char_c = mob->CastToClient()->GetQGlobals();
|
char_c = mob->CastToClient()->GetQGlobals();
|
||||||
}
|
}
|
||||||
zone_c = zone->GetQGlobals();
|
|
||||||
|
zone_c = zone->GetQGlobals();
|
||||||
|
|
||||||
if (!char_c) {
|
if (!char_c) {
|
||||||
if (mob && mob->IsClient()) {
|
if (mob && mob->IsClient()) {
|
||||||
@ -1226,15 +1368,23 @@ void PerlembParser::ExportQGlobals(
|
|||||||
ExportVar(package_name.c_str(), (*iter).name.c_str(), (*iter).value.c_str());
|
ExportVar(package_name.c_str(), (*iter).name.c_str(), (*iter).value.c_str());
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportHash(package_name.c_str(), "qglobals", globhash);
|
ExportHash(package_name.c_str(), "qglobals", globhash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerlembParser::ExportMobVariables(
|
void PerlembParser::ExportMobVariables(
|
||||||
bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
bool isPlayerQuest,
|
||||||
bool isSpellQuest, std::string &package_name, Mob *mob, NPC *npcmob
|
bool isGlobalPlayerQuest,
|
||||||
)
|
bool isBotQuest,
|
||||||
{
|
bool isGlobalBotQuest,
|
||||||
|
bool isGlobalNPC,
|
||||||
|
bool isItemQuest,
|
||||||
|
bool isSpellQuest,
|
||||||
|
std::string &package_name,
|
||||||
|
Mob *mob,
|
||||||
|
Mob *npcmob
|
||||||
|
) {
|
||||||
uint8 fac = 0;
|
uint8 fac = 0;
|
||||||
if (mob && mob->IsClient()) {
|
if (mob && mob->IsClient()) {
|
||||||
ExportVar(package_name.c_str(), "uguild_id", mob->CastToClient()->GuildID());
|
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());
|
ExportVar(package_name.c_str(), "status", mob->CastToClient()->Admin());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest) {
|
#ifdef BOTS
|
||||||
if (mob && npcmob && mob->IsClient()) {
|
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();
|
Client *client = mob->CastToClient();
|
||||||
|
|
||||||
fac = client->GetFactionLevel(
|
fac = client->GetFactionLevel(
|
||||||
@ -1261,8 +1424,15 @@ void PerlembParser::ExportMobVariables(
|
|||||||
ExportVar(package_name.c_str(), "userid", mob->GetID());
|
ExportVar(package_name.c_str(), "userid", mob->GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest && !isSpellQuest) {
|
if (
|
||||||
if (npcmob) {
|
!isPlayerQuest &&
|
||||||
|
!isGlobalPlayerQuest &&
|
||||||
|
!isBotQuest &&
|
||||||
|
!isGlobalBotQuest &&
|
||||||
|
!isItemQuest &&
|
||||||
|
!isSpellQuest
|
||||||
|
) {
|
||||||
|
if (npcmob->IsNPC()) {
|
||||||
ExportVar(package_name.c_str(), "mname", npcmob->GetName());
|
ExportVar(package_name.c_str(), "mname", npcmob->GetName());
|
||||||
ExportVar(package_name.c_str(), "mobid", npcmob->GetID());
|
ExportVar(package_name.c_str(), "mobid", npcmob->GetID());
|
||||||
ExportVar(package_name.c_str(), "mlevel", npcmob->GetLevel());
|
ExportVar(package_name.c_str(), "mlevel", npcmob->GetLevel());
|
||||||
@ -1331,14 +1501,20 @@ void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PerlembParser::ExportEventVariables(
|
void PerlembParser::ExportEventVariables(
|
||||||
std::string &package_name, QuestEventID event, uint32 objid, const char *data,
|
std::string &package_name,
|
||||||
NPC *npcmob, EQ::ItemInstance *item_inst, Mob *mob, uint32 extradata, std::vector<std::any> *extra_pointers
|
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) {
|
switch (event) {
|
||||||
case EVENT_SAY: {
|
case EVENT_SAY: {
|
||||||
if (npcmob && mob) {
|
if (npcmob && npcmob->IsNPC() && mob) {
|
||||||
npcmob->DoQuestPause(mob);
|
npcmob->CastToNPC()->DoQuestPause(mob);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExportVar(package_name.c_str(), "data", objid);
|
ExportVar(package_name.c_str(), "data", objid);
|
||||||
@ -1568,8 +1744,15 @@ void PerlembParser::ExportEventVariables(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
case EVENT_SPELL_EFFECT_BUFF_TIC_BOT:
|
||||||
|
#endif
|
||||||
case EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT:
|
case EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT:
|
||||||
case EVENT_SPELL_EFFECT_BUFF_TIC_NPC:
|
case EVENT_SPELL_EFFECT_BUFF_TIC_NPC:
|
||||||
|
#ifdef BOTS
|
||||||
|
case EVENT_SPELL_EFFECT_BOT:
|
||||||
|
#endif
|
||||||
case EVENT_SPELL_EFFECT_CLIENT:
|
case EVENT_SPELL_EFFECT_CLIENT:
|
||||||
case EVENT_SPELL_EFFECT_NPC:
|
case EVENT_SPELL_EFFECT_NPC:
|
||||||
case EVENT_SPELL_FADE: {
|
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
|
#endif
|
||||||
|
|||||||
197
zone/embparser.h
197
zone/embparser.h
@ -48,18 +48,73 @@ public:
|
|||||||
PerlembParser();
|
PerlembParser();
|
||||||
~PerlembParser();
|
~PerlembParser();
|
||||||
|
|
||||||
virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int EventNPC(
|
||||||
std::vector<std::any> *extra_pointers);
|
QuestEventID evt,
|
||||||
virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
NPC* npc,
|
||||||
std::vector<std::any> *extra_pointers);
|
Mob *init,
|
||||||
virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
std::string data,
|
||||||
std::vector<std::any> *extra_pointers);
|
uint32 extra_data,
|
||||||
virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
std::vector<std::any> *extra_pointers
|
||||||
std::vector<std::any> *extra_pointers);
|
);
|
||||||
virtual int EventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
virtual int EventGlobalNPC(
|
||||||
std::vector<std::any> *extra_pointers);
|
QuestEventID evt,
|
||||||
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
NPC* npc,
|
||||||
std::vector<std::any> *extra_pointers);
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventPlayer(
|
||||||
|
QuestEventID evt,
|
||||||
|
Client *client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventGlobalPlayer(
|
||||||
|
QuestEventID evt,
|
||||||
|
Client *client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventItem(
|
||||||
|
QuestEventID evt,
|
||||||
|
Client *client,
|
||||||
|
EQ::ItemInstance *item,
|
||||||
|
Mob *mob,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventSpell(
|
||||||
|
QuestEventID evt,
|
||||||
|
Mob* mob,
|
||||||
|
Client *client,
|
||||||
|
uint32 spell_id,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual int EventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventGlobalBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual bool HasQuestSub(uint32 npcid, QuestEventID evt);
|
virtual bool HasQuestSub(uint32 npcid, QuestEventID evt);
|
||||||
virtual bool HasGlobalQuestSub(QuestEventID evt);
|
virtual bool HasGlobalQuestSub(QuestEventID evt);
|
||||||
@ -68,6 +123,11 @@ public:
|
|||||||
virtual bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt);
|
virtual bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt);
|
||||||
virtual bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt);
|
virtual bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual bool BotHasQuestSub(QuestEventID evt);
|
||||||
|
virtual bool GlobalBotHasQuestSub(QuestEventID evt);
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual void LoadNPCScript(std::string filename, int npc_id);
|
virtual void LoadNPCScript(std::string filename, int npc_id);
|
||||||
virtual void LoadGlobalNPCScript(std::string filename);
|
virtual void LoadGlobalNPCScript(std::string filename);
|
||||||
virtual void LoadPlayerScript(std::string filename);
|
virtual void LoadPlayerScript(std::string filename);
|
||||||
@ -75,6 +135,11 @@ public:
|
|||||||
virtual void LoadItemScript(std::string filename, EQ::ItemInstance *item);
|
virtual void LoadItemScript(std::string filename, EQ::ItemInstance *item);
|
||||||
virtual void LoadSpellScript(std::string filename, uint32 spell_id);
|
virtual void LoadSpellScript(std::string filename, uint32 spell_id);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual void LoadBotScript(std::string filename);
|
||||||
|
virtual void LoadGlobalBotScript(std::string filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual void AddVar(std::string name, std::string val);
|
virtual void AddVar(std::string name, std::string val);
|
||||||
virtual std::string GetVar(std::string name);
|
virtual std::string GetVar(std::string name);
|
||||||
virtual void ReloadQuests();
|
virtual void ReloadQuests();
|
||||||
@ -91,25 +156,98 @@ private:
|
|||||||
void ExportVar(const char* pkgprefix, const char* varname, const char* classname, void* value);
|
void ExportVar(const char* pkgprefix, const char* varname, const char* classname, void* value);
|
||||||
void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value);
|
void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value);
|
||||||
|
|
||||||
int EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, EQ::ItemInstance* item_inst, const SPDat_Spell_Struct* spell, Mob* mob,
|
int EventCommon(
|
||||||
uint32 extradata, bool global, std::vector<std::any> *extra_pointers);
|
QuestEventID event,
|
||||||
int SendCommands(const char *pkgprefix, const char *event, uint32 spell_id, Mob* other, Mob* mob, EQ::ItemInstance *item_inst, const SPDat_Spell_Struct *spell);
|
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
|
||||||
|
);
|
||||||
|
int SendCommands(
|
||||||
|
const char *pkgprefix,
|
||||||
|
const char *event,
|
||||||
|
uint32 spell_id,
|
||||||
|
Mob* other,
|
||||||
|
Mob* mob,
|
||||||
|
EQ::ItemInstance *item_inst,
|
||||||
|
const SPDat_Spell_Struct *spell
|
||||||
|
);
|
||||||
void MapFunctions();
|
void MapFunctions();
|
||||||
|
|
||||||
void GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
void GetQuestTypes(
|
||||||
bool &isSpellQuest, QuestEventID event, NPC* npcmob, EQ::ItemInstance* item_inst, Mob* mob, bool global);
|
bool &isPlayerQuest,
|
||||||
void GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
|
bool &isGlobalPlayerQuest,
|
||||||
bool &isSpellQuest, std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
bool &isBotQuest,
|
||||||
NPC* npcmob, EQ::ItemInstance* item_inst, bool global);
|
bool &isGlobalBotQuest,
|
||||||
void ExportCharID(const std::string &package_name, int &char_id, NPC *npcmob, Mob *mob);
|
bool &isGlobalNPC,
|
||||||
void ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
bool &isItemQuest,
|
||||||
bool isSpellQuest, std::string &package_name, NPC *npcmob, Mob *mob, int char_id);
|
bool &isSpellQuest,
|
||||||
void ExportMobVariables(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
|
QuestEventID event,
|
||||||
bool isSpellQuest, std::string &package_name, Mob *mob, NPC *npcmob);
|
Mob* npcmob,
|
||||||
|
EQ::ItemInstance* item_inst,
|
||||||
|
Mob* mob,
|
||||||
|
bool global
|
||||||
|
);
|
||||||
|
void GetQuestPackageName(
|
||||||
|
bool &isPlayerQuest,
|
||||||
|
bool &isGlobalPlayerQuest,
|
||||||
|
bool &isBotQuest,
|
||||||
|
bool &isGlobalBotQuest,
|
||||||
|
bool &isGlobalNPC,
|
||||||
|
bool &isItemQuest,
|
||||||
|
bool &isSpellQuest,
|
||||||
|
std::string &package_name,
|
||||||
|
QuestEventID event,
|
||||||
|
uint32 objid,
|
||||||
|
const char * data,
|
||||||
|
Mob* npcmob,
|
||||||
|
EQ::ItemInstance* item_inst,
|
||||||
|
bool global
|
||||||
|
);
|
||||||
|
void ExportCharID(const std::string &package_name, int &char_id, Mob *npcmob, Mob *mob);
|
||||||
|
void ExportQGlobals(
|
||||||
|
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
|
||||||
|
);
|
||||||
|
void ExportMobVariables(
|
||||||
|
bool isPlayerQuest,
|
||||||
|
bool isGlobalPlayerQuest,
|
||||||
|
bool isBotQuest,
|
||||||
|
bool isGlobalBotQuest,
|
||||||
|
bool isGlobalNPC,
|
||||||
|
bool isItemQuest,
|
||||||
|
bool isSpellQuest,
|
||||||
|
std::string &package_name,
|
||||||
|
Mob *mob,
|
||||||
|
Mob *npcmob
|
||||||
|
);
|
||||||
void ExportZoneVariables(std::string &package_name);
|
void ExportZoneVariables(std::string &package_name);
|
||||||
void ExportItemVariables(std::string &package_name, Mob *mob);
|
void ExportItemVariables(std::string &package_name, Mob *mob);
|
||||||
void ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
|
void ExportEventVariables(
|
||||||
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
|
||||||
|
);
|
||||||
|
|
||||||
std::map<uint32, PerlQuestStatus> npc_quest_status_;
|
std::map<uint32, PerlQuestStatus> npc_quest_status_;
|
||||||
PerlQuestStatus global_npc_quest_status_;
|
PerlQuestStatus global_npc_quest_status_;
|
||||||
@ -118,6 +256,11 @@ private:
|
|||||||
std::map<uint32, PerlQuestStatus> item_quest_status_;
|
std::map<uint32, PerlQuestStatus> item_quest_status_;
|
||||||
std::map<uint32, PerlQuestStatus> spell_quest_status_;
|
std::map<uint32, PerlQuestStatus> spell_quest_status_;
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
PerlQuestStatus bot_quest_status_;
|
||||||
|
PerlQuestStatus global_bot_quest_status_;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::map<std::string, std::string> vars_;
|
std::map<std::string, std::string> vars_;
|
||||||
SV *_empty_sv;
|
SV *_empty_sv;
|
||||||
std::map<std::string, int> clear_vars_;
|
std::map<std::string, int> clear_vars_;
|
||||||
|
|||||||
@ -3134,38 +3134,38 @@ void Perl__crosszonesetentityvariablebynpctypeid(int npc_id, const char* variabl
|
|||||||
quest_manager.CrossZoneSetEntityVariable(CZUpdateType_NPC, npc_id, variable_name, variable_value);
|
quest_manager.CrossZoneSetEntityVariable(CZUpdateType_NPC, npc_id, variable_name, variable_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__crosszonesignalclientbycharid(int character_id, uint32 signal)
|
void Perl__crosszonesignalclientbycharid(int character_id, int signal)
|
||||||
{
|
{
|
||||||
quest_manager.CrossZoneSignal(CZUpdateType_Character, character_id, signal);
|
quest_manager.CrossZoneSignal(CZUpdateType_Character, character_id, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__crosszonesignalclientbygroupid(int group_id, uint32 signal)
|
void Perl__crosszonesignalclientbygroupid(int group_id, int signal)
|
||||||
{
|
{
|
||||||
quest_manager.CrossZoneSignal(CZUpdateType_Group, group_id, signal);
|
quest_manager.CrossZoneSignal(CZUpdateType_Group, group_id, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__crosszonesignalclientbyraidid(int raid_id, uint32 signal)
|
void Perl__crosszonesignalclientbyraidid(int raid_id, int signal)
|
||||||
{
|
{
|
||||||
quest_manager.CrossZoneSignal(CZUpdateType_Raid, raid_id, signal);
|
quest_manager.CrossZoneSignal(CZUpdateType_Raid, raid_id, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__crosszonesignalclientbyguildid(int guild_id, uint32 signal)
|
void Perl__crosszonesignalclientbyguildid(int guild_id, int signal)
|
||||||
{
|
{
|
||||||
quest_manager.CrossZoneSignal(CZUpdateType_Guild, guild_id, signal);
|
quest_manager.CrossZoneSignal(CZUpdateType_Guild, guild_id, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__crosszonesignalclientbyexpeditionid(uint32 expedition_id, uint32 signal)
|
void Perl__crosszonesignalclientbyexpeditionid(uint32 expedition_id, int signal)
|
||||||
{
|
{
|
||||||
quest_manager.CrossZoneSignal(CZUpdateType_Expedition, expedition_id, signal);
|
quest_manager.CrossZoneSignal(CZUpdateType_Expedition, expedition_id, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__crosszonesignalclientbyname(const char* client_name, uint32 signal)
|
void Perl__crosszonesignalclientbyname(const char* client_name, int signal)
|
||||||
{
|
{
|
||||||
int update_identifier = 0;
|
int update_identifier = 0;
|
||||||
quest_manager.CrossZoneSignal(CZUpdateType_Expedition, update_identifier, signal, client_name);
|
quest_manager.CrossZoneSignal(CZUpdateType_Expedition, update_identifier, signal, client_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__crosszonesignalnpcbynpctypeid(uint32 npc_id, uint32 signal)
|
void Perl__crosszonesignalnpcbynpctypeid(uint32 npc_id, int signal)
|
||||||
{
|
{
|
||||||
quest_manager.CrossZoneSignal(CZUpdateType_NPC, npc_id, signal);
|
quest_manager.CrossZoneSignal(CZUpdateType_NPC, npc_id, signal);
|
||||||
}
|
}
|
||||||
@ -3599,22 +3599,22 @@ void Perl__worldwidesetentityvariablenpc(const char* variable_name, const char*
|
|||||||
quest_manager.WorldWideSetEntityVariable(WWSetEntityVariableUpdateType_NPC, variable_name, variable_value);
|
quest_manager.WorldWideSetEntityVariable(WWSetEntityVariableUpdateType_NPC, variable_name, variable_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__worldwidesignalnpc(uint32 signal)
|
void Perl__worldwidesignalnpc(int signal)
|
||||||
{
|
{
|
||||||
quest_manager.WorldWideSignal(WWSignalUpdateType_NPC, signal);
|
quest_manager.WorldWideSignal(WWSignalUpdateType_NPC, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__worldwidesignalclient(uint32 signal)
|
void Perl__worldwidesignalclient(int signal)
|
||||||
{
|
{
|
||||||
quest_manager.WorldWideSignal(WWSignalUpdateType_Character, signal);
|
quest_manager.WorldWideSignal(WWSignalUpdateType_Character, signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__worldwidesignalclient(uint32 signal, uint8 min_status)
|
void Perl__worldwidesignalclient(int signal, uint8 min_status)
|
||||||
{
|
{
|
||||||
quest_manager.WorldWideSignal(WWSignalUpdateType_Character, signal, min_status);
|
quest_manager.WorldWideSignal(WWSignalUpdateType_Character, signal, min_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__worldwidesignalclient(uint32 signal, uint8 min_status, uint8 max_status)
|
void Perl__worldwidesignalclient(int signal, uint8 min_status, uint8 max_status)
|
||||||
{
|
{
|
||||||
quest_manager.WorldWideSignal(WWSignalUpdateType_Character, signal, min_status, max_status);
|
quest_manager.WorldWideSignal(WWSignalUpdateType_Character, signal, min_status, max_status);
|
||||||
}
|
}
|
||||||
@ -4163,9 +4163,9 @@ void perl_register_quest()
|
|||||||
package.add("worldwidesetentityvariableclient", (void(*)(const char*, const char*, uint8))&Perl__worldwidesetentityvariableclient);
|
package.add("worldwidesetentityvariableclient", (void(*)(const char*, const char*, uint8))&Perl__worldwidesetentityvariableclient);
|
||||||
package.add("worldwidesetentityvariableclient", (void(*)(const char*, const char*, uint8, uint8))&Perl__worldwidesetentityvariableclient);
|
package.add("worldwidesetentityvariableclient", (void(*)(const char*, const char*, uint8, uint8))&Perl__worldwidesetentityvariableclient);
|
||||||
package.add("worldwidesetentityvariablenpc", &Perl__worldwidesetentityvariablenpc);
|
package.add("worldwidesetentityvariablenpc", &Perl__worldwidesetentityvariablenpc);
|
||||||
package.add("worldwidesignalclient", (void(*)(uint32))&Perl__worldwidesignalclient);
|
package.add("worldwidesignalclient", (void(*)(int))&Perl__worldwidesignalclient);
|
||||||
package.add("worldwidesignalclient", (void(*)(uint32, uint8))&Perl__worldwidesignalclient);
|
package.add("worldwidesignalclient", (void(*)(int, uint8))&Perl__worldwidesignalclient);
|
||||||
package.add("worldwidesignalclient", (void(*)(uint32, uint8, uint8))&Perl__worldwidesignalclient);
|
package.add("worldwidesignalclient", (void(*)(int, uint8, uint8))&Perl__worldwidesignalclient);
|
||||||
package.add("worldwidesignalnpc", &Perl__worldwidesignalnpc);
|
package.add("worldwidesignalnpc", &Perl__worldwidesignalnpc);
|
||||||
package.add("worldwideupdateactivity", (void(*)(uint32, int))&Perl__worldwideupdateactivity);
|
package.add("worldwideupdateactivity", (void(*)(uint32, int))&Perl__worldwideupdateactivity);
|
||||||
package.add("worldwideupdateactivity", (void(*)(uint32, int, int))&Perl__worldwideupdateactivity);
|
package.add("worldwideupdateactivity", (void(*)(uint32, int, int))&Perl__worldwideupdateactivity);
|
||||||
|
|||||||
@ -5100,14 +5100,12 @@ void EntityList::GateAllClients()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityList::SignalAllClients(uint32 data)
|
void EntityList::SignalAllClients(int signal_id)
|
||||||
{
|
{
|
||||||
auto it = client_list.begin();
|
for (const auto& c : client_list) {
|
||||||
while (it != client_list.end()) {
|
if (c.second) {
|
||||||
Client *ent = it->second;
|
c.second->Signal(signal_id);
|
||||||
if (ent)
|
}
|
||||||
ent->Signal(data);
|
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5159,8 +5157,9 @@ void EntityList::GetClientList(std::list<Client *> &c_list)
|
|||||||
void EntityList::GetBotList(std::list<Bot *> &b_list)
|
void EntityList::GetBotList(std::list<Bot *> &b_list)
|
||||||
{
|
{
|
||||||
b_list.clear();
|
b_list.clear();
|
||||||
for (auto bot : bot_list) {
|
|
||||||
b_list.push_back(bot);
|
for (const auto& b : bot_list) {
|
||||||
|
b_list.push_back(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5172,16 +5171,12 @@ std::vector<Bot *> EntityList::GetBotListByCharacterID(uint32 character_id, uint
|
|||||||
return client_bot_list;
|
return client_bot_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto bot : bot_list) {
|
for (const auto& b : bot_list) {
|
||||||
if (
|
if (
|
||||||
bot->GetOwner() &&
|
b->GetOwner() &&
|
||||||
bot->GetBotOwnerCharacterID() == character_id &&
|
b->GetBotOwnerCharacterID() == character_id
|
||||||
(
|
|
||||||
!class_id ||
|
|
||||||
bot->GetClass() == class_id
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
client_bot_list.push_back(bot);
|
client_bot_list.push_back(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5196,14 +5191,45 @@ std::vector<Bot *> EntityList::GetBotListByClientName(std::string client_name)
|
|||||||
return client_bot_list;
|
return client_bot_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto bot : bot_list) {
|
for (const auto& b : bot_list) {
|
||||||
if (bot->GetOwner() && Strings::ToLower(bot->GetOwner()->GetCleanName()) == Strings::ToLower(client_name)) {
|
if (
|
||||||
client_bot_list.push_back(bot);
|
b->GetOwner() &&
|
||||||
|
Strings::ToLower(b->GetOwner()->GetCleanName()) == Strings::ToLower(client_name)
|
||||||
|
) {
|
||||||
|
client_bot_list.push_back(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return client_bot_list;
|
return client_bot_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityList::SignalAllBotsByOwnerCharacterID(uint32 character_id, int signal_id)
|
||||||
|
{
|
||||||
|
auto client_bot_list = GetBotListByCharacterID(character_id);
|
||||||
|
if (client_bot_list.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& b : client_bot_list) {
|
||||||
|
b->SignalBot(signal_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityList::SignalBotByBotID(uint32 bot_id, int signal_id)
|
||||||
|
{
|
||||||
|
auto b = GetBotByBotID(bot_id);
|
||||||
|
if (b) {
|
||||||
|
b->SignalBot(signal_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityList::SignalBotByBotName(std::string bot_name, int signal_id)
|
||||||
|
{
|
||||||
|
auto b = GetBotByBotName(bot_name);
|
||||||
|
if (b) {
|
||||||
|
b->SignalBot(signal_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void EntityList::GetCorpseList(std::list<Corpse *> &c_list)
|
void EntityList::GetCorpseList(std::list<Corpse *> &c_list)
|
||||||
|
|||||||
@ -508,7 +508,7 @@ public:
|
|||||||
void UnMarkNPC(uint16 ID);
|
void UnMarkNPC(uint16 ID);
|
||||||
|
|
||||||
void GateAllClients();
|
void GateAllClients();
|
||||||
void SignalAllClients(uint32 data);
|
void SignalAllClients(int signal_id);
|
||||||
void UpdateQGlobal(uint32 qid, QGlobal newGlobal);
|
void UpdateQGlobal(uint32 qid, QGlobal newGlobal);
|
||||||
void DeleteQGlobal(std::string name, uint32 npcID, uint32 charID, uint32 zoneID);
|
void DeleteQGlobal(std::string name, uint32 npcID, uint32 charID, uint32 zoneID);
|
||||||
void SendFindableNPCList(Client *c);
|
void SendFindableNPCList(Client *c);
|
||||||
@ -537,6 +537,9 @@ public:
|
|||||||
inline const std::list<Bot *> &GetBotList() { return bot_list; }
|
inline const std::list<Bot *> &GetBotList() { return bot_list; }
|
||||||
std::vector<Bot *> GetBotListByCharacterID(uint32 character_id, uint8 class_id = 0);
|
std::vector<Bot *> GetBotListByCharacterID(uint32 character_id, uint8 class_id = 0);
|
||||||
std::vector<Bot *> GetBotListByClientName(std::string client_name);
|
std::vector<Bot *> GetBotListByClientName(std::string client_name);
|
||||||
|
void SignalAllBotsByOwnerCharacterID(uint32 character_id, int signal_id);
|
||||||
|
void SignalBotByBotID(uint32 bot_id, int signal_id);
|
||||||
|
void SignalBotByBotName(std::string bot_name, int signal_id);
|
||||||
#endif
|
#endif
|
||||||
inline const std::unordered_map<uint16, Corpse *> &GetCorpseList() { return corpse_list; }
|
inline const std::unordered_map<uint16, Corpse *> &GetCorpseList() { return corpse_list; }
|
||||||
inline const std::unordered_map<uint16, Object *> &GetObjectList() { return object_list; }
|
inline const std::unordered_map<uint16, Object *> &GetObjectList() { return object_list; }
|
||||||
@ -605,7 +608,7 @@ private:
|
|||||||
// Please Do Not Declare Any EntityList Class Members After This Comment
|
// Please Do Not Declare Any EntityList Class Members After This Comment
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
public:
|
public:
|
||||||
void AddBot(Bot* newBot, bool SendSpawnPacket = true, bool dontqueue = false);
|
void AddBot(Bot* new_bot, bool send_spawn_packet = true, bool dont_queue = false);
|
||||||
bool RemoveBot(uint16 entityID);
|
bool RemoveBot(uint16 entityID);
|
||||||
Mob* GetMobByBotID(uint32 botID);
|
Mob* GetMobByBotID(uint32 botID);
|
||||||
Bot* GetBotByBotID(uint32 botID);
|
Bot* GetBotByBotID(uint32 botID);
|
||||||
|
|||||||
@ -106,6 +106,10 @@ typedef enum {
|
|||||||
EVENT_TASK_BEFORE_UPDATE,
|
EVENT_TASK_BEFORE_UPDATE,
|
||||||
EVENT_AA_BUY,
|
EVENT_AA_BUY,
|
||||||
EVENT_AA_GAIN,
|
EVENT_AA_GAIN,
|
||||||
|
#ifdef BOTS
|
||||||
|
EVENT_SPELL_EFFECT_BOT,
|
||||||
|
EVENT_SPELL_EFFECT_BUFF_TIC_BOT,
|
||||||
|
#endif
|
||||||
_LargestEventID
|
_LargestEventID
|
||||||
} QuestEventID;
|
} QuestEventID;
|
||||||
|
|
||||||
|
|||||||
@ -84,6 +84,16 @@ uint32 Lua_Bot::GetBotItemIDBySlot(uint16 slot_id) {
|
|||||||
return self->GetBotItemBySlot(slot_id);
|
return self->GetBotItemBySlot(slot_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lua_Bot::SignalBot(int signal_id) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SignalBot(signal_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Bot::OwnerMessage(std::string message) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->OwnerMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
int Lua_Bot::GetExpansionBitmask() {
|
int Lua_Bot::GetExpansionBitmask() {
|
||||||
Lua_Safe_Call_Int();
|
Lua_Safe_Call_Int();
|
||||||
return self->GetExpansionBitmask();
|
return self->GetExpansionBitmask();
|
||||||
@ -117,9 +127,11 @@ luabind::scope lua_register_bot() {
|
|||||||
.def("GetExpansionBitmask", (int(Lua_Bot::*)(void))&Lua_Bot::GetExpansionBitmask)
|
.def("GetExpansionBitmask", (int(Lua_Bot::*)(void))&Lua_Bot::GetExpansionBitmask)
|
||||||
.def("GetOwner", (Lua_Mob(Lua_Bot::*)(void))&Lua_Bot::GetOwner)
|
.def("GetOwner", (Lua_Mob(Lua_Bot::*)(void))&Lua_Bot::GetOwner)
|
||||||
.def("HasBotItem", (bool(Lua_Bot::*)(uint32))&Lua_Bot::HasBotItem)
|
.def("HasBotItem", (bool(Lua_Bot::*)(uint32))&Lua_Bot::HasBotItem)
|
||||||
|
.def("OwnerMessage", (void(Lua_Bot::*)(std::string))&Lua_Bot::OwnerMessage)
|
||||||
.def("RemoveBotItem", (void(Lua_Bot::*)(uint32))&Lua_Bot::RemoveBotItem)
|
.def("RemoveBotItem", (void(Lua_Bot::*)(uint32))&Lua_Bot::RemoveBotItem)
|
||||||
.def("SetExpansionBitmask", (void(Lua_Bot::*)(int))&Lua_Bot::SetExpansionBitmask)
|
.def("SetExpansionBitmask", (void(Lua_Bot::*)(int))&Lua_Bot::SetExpansionBitmask)
|
||||||
.def("SetExpansionBitmask", (void(Lua_Bot::*)(int,bool))&Lua_Bot::SetExpansionBitmask);
|
.def("SetExpansionBitmask", (void(Lua_Bot::*)(int,bool))&Lua_Bot::SetExpansionBitmask)
|
||||||
|
.def("SignalBot", (void(Lua_Bot::*)(int))&Lua_Bot::SignalBot);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -42,9 +42,11 @@ public:
|
|||||||
int GetExpansionBitmask();
|
int GetExpansionBitmask();
|
||||||
Lua_Mob GetOwner();
|
Lua_Mob GetOwner();
|
||||||
bool HasBotItem(uint32 item_id);
|
bool HasBotItem(uint32 item_id);
|
||||||
|
void OwnerMessage(std::string message);
|
||||||
void RemoveBotItem(uint32 item_id);
|
void RemoveBotItem(uint32 item_id);
|
||||||
void SetExpansionBitmask(int expansion_bitmask);
|
void SetExpansionBitmask(int expansion_bitmask);
|
||||||
void SetExpansionBitmask(int expansion_bitmask, bool save);
|
void SetExpansionBitmask(int expansion_bitmask, bool save);
|
||||||
|
void SignalBot(int signal_id);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -1515,9 +1515,9 @@ void Lua_Client::NotifyNewTitlesAvailable() {
|
|||||||
self->NotifyNewTitlesAvailable();
|
self->NotifyNewTitlesAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lua_Client::Signal(uint32 id) {
|
void Lua_Client::Signal(int signal_id) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->Signal(id);
|
self->Signal(signal_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lua_Client::AddAlternateCurrencyValue(uint32 currency, int amount) {
|
void Lua_Client::AddAlternateCurrencyValue(uint32 currency, int amount) {
|
||||||
@ -3108,7 +3108,7 @@ luabind::scope lua_register_client() {
|
|||||||
.def("SetTint", (void(Lua_Client::*)(int,uint32))&Lua_Client::SetTint)
|
.def("SetTint", (void(Lua_Client::*)(int,uint32))&Lua_Client::SetTint)
|
||||||
.def("SetTitleSuffix", (void(Lua_Client::*)(const char *))&Lua_Client::SetTitleSuffix)
|
.def("SetTitleSuffix", (void(Lua_Client::*)(const char *))&Lua_Client::SetTitleSuffix)
|
||||||
.def("SetZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::SetZoneFlag)
|
.def("SetZoneFlag", (void(Lua_Client::*)(uint32))&Lua_Client::SetZoneFlag)
|
||||||
.def("Signal", (void(Lua_Client::*)(uint32))&Lua_Client::Signal)
|
.def("Signal", (void(Lua_Client::*)(int))&Lua_Client::Signal)
|
||||||
.def("Sit", (void(Lua_Client::*)(void))&Lua_Client::Sit)
|
.def("Sit", (void(Lua_Client::*)(void))&Lua_Client::Sit)
|
||||||
.def("Stand", (void(Lua_Client::*)(void))&Lua_Client::Stand)
|
.def("Stand", (void(Lua_Client::*)(void))&Lua_Client::Stand)
|
||||||
.def("SummonBaggedItems", (void(Lua_Client::*)(uint32,luabind::adl::object))&Lua_Client::SummonBaggedItems)
|
.def("SummonBaggedItems", (void(Lua_Client::*)(uint32,luabind::adl::object))&Lua_Client::SummonBaggedItems)
|
||||||
|
|||||||
@ -363,7 +363,7 @@ public:
|
|||||||
uint32 GetMoney(uint8 type, uint8 subtype);
|
uint32 GetMoney(uint8 type, uint8 subtype);
|
||||||
void OpenLFGuildWindow();
|
void OpenLFGuildWindow();
|
||||||
void NotifyNewTitlesAvailable();
|
void NotifyNewTitlesAvailable();
|
||||||
void Signal(uint32 id);
|
void Signal(int signal_id);
|
||||||
void AddAlternateCurrencyValue(uint32 currency, int amount);
|
void AddAlternateCurrencyValue(uint32 currency, int amount);
|
||||||
void SetAlternateCurrencyValue(uint32 currency, int amount);
|
void SetAlternateCurrencyValue(uint32 currency, int amount);
|
||||||
int GetAlternateCurrencyValue(uint32 currency);
|
int GetAlternateCurrencyValue(uint32 currency);
|
||||||
|
|||||||
@ -440,6 +440,21 @@ Lua_Bot_List Lua_EntityList::GetBotListByClientName(std::string client_name) {
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lua_EntityList::SignalAllBotsByOwnerCharacterID(uint32 character_id, int signal_id) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SignalAllBotsByOwnerCharacterID(character_id, signal_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_EntityList::SignalBotByBotID(uint32 bot_id, int signal_id) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SignalBotByBotID(bot_id, signal_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_EntityList::SignalBotByBotName(std::string bot_name, int signal_id) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SignalBotByBotName(bot_name, signal_id);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Lua_Client_List Lua_EntityList::GetShuffledClientList() {
|
Lua_Client_List Lua_EntityList::GetShuffledClientList() {
|
||||||
@ -690,7 +705,14 @@ luabind::scope lua_register_entity_list() {
|
|||||||
.def("RemoveFromTargets", (void(Lua_EntityList::*)(Lua_Mob, bool))&Lua_EntityList::RemoveFromTargets)
|
.def("RemoveFromTargets", (void(Lua_EntityList::*)(Lua_Mob, bool))&Lua_EntityList::RemoveFromTargets)
|
||||||
.def("RemoveNumbers", (std::string(Lua_EntityList::*)(const char*))&Lua_EntityList::RemoveNumbers)
|
.def("RemoveNumbers", (std::string(Lua_EntityList::*)(const char*))&Lua_EntityList::RemoveNumbers)
|
||||||
.def("ReplaceWithTarget", (void(Lua_EntityList::*)(Lua_Mob, Lua_Mob))&Lua_EntityList::ReplaceWithTarget)
|
.def("ReplaceWithTarget", (void(Lua_EntityList::*)(Lua_Mob, Lua_Mob))&Lua_EntityList::ReplaceWithTarget)
|
||||||
|
#ifdef BOTS
|
||||||
|
.def("SignalAllBotsByOwnerCharacterID", (void(Lua_EntityList::*)(uint32, int))&Lua_EntityList::SignalAllBotsByOwnerCharacterID)
|
||||||
|
#endif
|
||||||
.def("SignalAllClients", (void(Lua_EntityList::*)(int))&Lua_EntityList::SignalAllClients)
|
.def("SignalAllClients", (void(Lua_EntityList::*)(int))&Lua_EntityList::SignalAllClients)
|
||||||
|
#ifdef BOTS
|
||||||
|
.def("SignalBotByBotID", (void(Lua_EntityList::*)(uint32, int))&Lua_EntityList::SignalBotByBotID)
|
||||||
|
.def("SignalBotByBotName", (void(Lua_EntityList::*)(std::string, int))&Lua_EntityList::SignalBotByBotName)
|
||||||
|
#endif
|
||||||
.def("SignalMobsByNPCID", (void(Lua_EntityList::*)(uint32, int))&Lua_EntityList::SignalMobsByNPCID);
|
.def("SignalMobsByNPCID", (void(Lua_EntityList::*)(uint32, int))&Lua_EntityList::SignalMobsByNPCID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -140,6 +140,9 @@ public:
|
|||||||
Lua_Bot GetRandomBot();
|
Lua_Bot GetRandomBot();
|
||||||
Lua_Bot GetRandomBot(float x, float y, float z, float distance);
|
Lua_Bot GetRandomBot(float x, float y, float z, float distance);
|
||||||
Lua_Bot GetRandomBot(float x, float y, float z, float distance, Lua_Bot exclude_bot);
|
Lua_Bot GetRandomBot(float x, float y, float z, float distance, Lua_Bot exclude_bot);
|
||||||
|
void SignalAllBotsByOwnerCharacterID(uint32 character_id, int signal_id);
|
||||||
|
void SignalBotByBotID(uint32 bot_id, int signal_id);
|
||||||
|
void SignalBotByBotName(std::string bot_name, int signal_id);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "npc.h"
|
#include "npc.h"
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
|
#include "bot.h"
|
||||||
#include "lua_bot.h"
|
#include "lua_bot.h"
|
||||||
#endif
|
#endif
|
||||||
#include "lua_item.h"
|
#include "lua_item.h"
|
||||||
@ -1371,13 +1372,17 @@ bool Lua_Mob::EntityVariableExists(const char *name) {
|
|||||||
return self->EntityVariableExists(name);
|
return self->EntityVariableExists(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lua_Mob::Signal(uint32 id) {
|
void Lua_Mob::Signal(int signal_id) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
|
|
||||||
if(self->IsClient()) {
|
if (self->IsClient()) {
|
||||||
self->CastToClient()->Signal(id);
|
self->CastToClient()->Signal(signal_id);
|
||||||
} else if(self->IsNPC()) {
|
} else if (self->IsNPC()) {
|
||||||
self->CastToNPC()->SignalNPC(id);
|
self->CastToNPC()->SignalNPC(signal_id);
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (self->IsBot()) {
|
||||||
|
self->CastToBot()->SignalBot(signal_id);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3100,7 +3105,7 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("SetTexture", (void(Lua_Mob::*)(int))&Lua_Mob::SetTexture)
|
.def("SetTexture", (void(Lua_Mob::*)(int))&Lua_Mob::SetTexture)
|
||||||
.def("Shout", (void(Lua_Mob::*)(const char*))& Lua_Mob::Shout)
|
.def("Shout", (void(Lua_Mob::*)(const char*))& Lua_Mob::Shout)
|
||||||
.def("Shout", (void(Lua_Mob::*)(const char*, int))& Lua_Mob::Shout)
|
.def("Shout", (void(Lua_Mob::*)(const char*, int))& Lua_Mob::Shout)
|
||||||
.def("Signal", (void(Lua_Mob::*)(uint32))&Lua_Mob::Signal)
|
.def("Signal", (void(Lua_Mob::*)(int))&Lua_Mob::Signal)
|
||||||
.def("SpellEffect", &Lua_Mob::SpellEffect)
|
.def("SpellEffect", &Lua_Mob::SpellEffect)
|
||||||
.def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob))&Lua_Mob::SpellFinished)
|
.def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob))&Lua_Mob::SpellFinished)
|
||||||
.def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob,int))&Lua_Mob::SpellFinished)
|
.def("SpellFinished", (bool(Lua_Mob::*)(int,Lua_Mob,int))&Lua_Mob::SpellFinished)
|
||||||
|
|||||||
@ -304,7 +304,7 @@ public:
|
|||||||
const char* GetEntityVariable(const char *name);
|
const char* GetEntityVariable(const char *name);
|
||||||
void SetEntityVariable(const char *name, const char *value);
|
void SetEntityVariable(const char *name, const char *value);
|
||||||
bool EntityVariableExists(const char *name);
|
bool EntityVariableExists(const char *name);
|
||||||
void Signal(uint32 id);
|
void Signal(int signal_id);
|
||||||
bool CombatRange(Lua_Mob other);
|
bool CombatRange(Lua_Mob other);
|
||||||
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage);
|
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage);
|
||||||
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage);
|
void DoSpecialAttackDamage(Lua_Mob other, int skill, int max_damage, int min_damage);
|
||||||
|
|||||||
@ -12,9 +12,9 @@ struct Lua_NPC_Loot_List {
|
|||||||
std::vector<uint32> entries;
|
std::vector<uint32> entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Lua_NPC::Signal(int id) {
|
void Lua_NPC::Signal(int signal_id) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->SignalNPC(id);
|
self->SignalNPC(signal_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Lua_NPC::CheckNPCFactionAlly(int faction) {
|
int Lua_NPC::CheckNPCFactionAlly(int faction) {
|
||||||
|
|||||||
@ -29,7 +29,7 @@ public:
|
|||||||
return reinterpret_cast<NPC*>(GetLuaPtrData());
|
return reinterpret_cast<NPC*>(GetLuaPtrData());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Signal(int id);
|
void Signal(int signal_id);
|
||||||
int CheckNPCFactionAlly(int faction);
|
int CheckNPCFactionAlly(int faction);
|
||||||
void AddItem(int item_id, int charges);
|
void AddItem(int item_id, int charges);
|
||||||
void AddItem(int item_id, int charges, bool equip);
|
void AddItem(int item_id, int charges, bool equip);
|
||||||
|
|||||||
@ -171,6 +171,10 @@ LuaParser::LuaParser() {
|
|||||||
ItemArgumentDispatch[i] = handle_item_null;
|
ItemArgumentDispatch[i] = handle_item_null;
|
||||||
SpellArgumentDispatch[i] = handle_spell_null;
|
SpellArgumentDispatch[i] = handle_spell_null;
|
||||||
EncounterArgumentDispatch[i] = handle_encounter_null;
|
EncounterArgumentDispatch[i] = handle_encounter_null;
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
BotArgumentDispatch[i] = handle_bot_null;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
NPCArgumentDispatch[EVENT_SAY] = handle_npc_event_say;
|
NPCArgumentDispatch[EVENT_SAY] = handle_npc_event_say;
|
||||||
@ -277,6 +281,22 @@ LuaParser::LuaParser() {
|
|||||||
EncounterArgumentDispatch[EVENT_ENCOUNTER_LOAD] = handle_encounter_load;
|
EncounterArgumentDispatch[EVENT_ENCOUNTER_LOAD] = handle_encounter_load;
|
||||||
EncounterArgumentDispatch[EVENT_ENCOUNTER_UNLOAD] = handle_encounter_unload;
|
EncounterArgumentDispatch[EVENT_ENCOUNTER_UNLOAD] = handle_encounter_unload;
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
BotArgumentDispatch[EVENT_CAST] = handle_bot_cast;
|
||||||
|
BotArgumentDispatch[EVENT_CAST_BEGIN] = handle_bot_cast;
|
||||||
|
BotArgumentDispatch[EVENT_CAST_ON] = handle_bot_cast;
|
||||||
|
BotArgumentDispatch[EVENT_COMBAT] = handle_bot_combat;
|
||||||
|
BotArgumentDispatch[EVENT_DEATH] = handle_bot_death;
|
||||||
|
BotArgumentDispatch[EVENT_DEATH_COMPLETE] = handle_bot_death;
|
||||||
|
BotArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_bot_popup_response;
|
||||||
|
BotArgumentDispatch[EVENT_SAY] = handle_bot_say;
|
||||||
|
BotArgumentDispatch[EVENT_SIGNAL] = handle_bot_signal;
|
||||||
|
BotArgumentDispatch[EVENT_SLAY] = handle_bot_slay;
|
||||||
|
BotArgumentDispatch[EVENT_TARGET_CHANGE] = handle_bot_target_change;
|
||||||
|
BotArgumentDispatch[EVENT_TIMER] = handle_bot_timer;
|
||||||
|
BotArgumentDispatch[EVENT_USE_SKILL] = handle_bot_use_skill;
|
||||||
|
#endif
|
||||||
|
|
||||||
L = nullptr;
|
L = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -566,7 +586,7 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
int LuaParser::EventSpell(QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) {
|
std::vector<std::any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
@ -579,10 +599,10 @@ int LuaParser::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spe
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _EventSpell(package_name, evt, npc, client, spell_id, data, extra_data, extra_pointers);
|
return _EventSpell(package_name, evt, mob, client, spell_id, data, extra_data, extra_pointers);
|
||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers, luabind::adl::object *l_func) {
|
std::vector<std::any> *extra_pointers, luabind::adl::object *l_func) {
|
||||||
const char *sub_name = LuaEvents[evt];
|
const char *sub_name = LuaEvents[evt];
|
||||||
|
|
||||||
@ -613,9 +633,9 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc,
|
|||||||
lua_setfield(L, -2, "self");
|
lua_setfield(L, -2, "self");
|
||||||
|
|
||||||
auto arg_function = SpellArgumentDispatch[evt];
|
auto arg_function = SpellArgumentDispatch[evt];
|
||||||
arg_function(this, L, npc, client, spell_id, data, extra_data, extra_pointers);
|
arg_function(this, L, mob, client, spell_id, data, extra_data, extra_pointers);
|
||||||
|
|
||||||
quest_manager.StartQuest(npc, client, nullptr, const_cast<SPDat_Spell_Struct*>(&spells[spell_id]));
|
quest_manager.StartQuest(mob, client, nullptr, const_cast<SPDat_Spell_Struct*>(&spells[spell_id]));
|
||||||
if(lua_pcall(L, 1, 1, 0)) {
|
if(lua_pcall(L, 1, 1, 0)) {
|
||||||
std::string error = lua_tostring(L, -1);
|
std::string error = lua_tostring(L, -1);
|
||||||
AddError(error);
|
AddError(error);
|
||||||
@ -1318,7 +1338,7 @@ int LuaParser::DispatchEventItem(QuestEventID evt, Client *client, EQ::ItemInsta
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
int LuaParser::DispatchEventSpell(QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) {
|
std::vector<std::any> *extra_pointers) {
|
||||||
evt = ConvertLuaEvent(evt);
|
evt = ConvertLuaEvent(evt);
|
||||||
if(evt >= _LargestEventID) {
|
if(evt >= _LargestEventID) {
|
||||||
@ -1334,7 +1354,7 @@ int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, ui
|
|||||||
while(riter != iter->second.end()) {
|
while(riter != iter->second.end()) {
|
||||||
if(riter->event_id == evt) {
|
if(riter->event_id == evt) {
|
||||||
std::string package_name = "encounter_" + riter->encounter_name;
|
std::string package_name = "encounter_" + riter->encounter_name;
|
||||||
int i = _EventSpell(package_name, evt, npc, client, spell_id, data, extra_data, extra_pointers, &riter->lua_reference);
|
int i = _EventSpell(package_name, evt, mob, client, spell_id, data, extra_data, extra_pointers, &riter->lua_reference);
|
||||||
if(i != 0) {
|
if(i != 0) {
|
||||||
ret = i;
|
ret = i;
|
||||||
}
|
}
|
||||||
@ -1352,7 +1372,7 @@ int LuaParser::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, ui
|
|||||||
while(riter != iter->second.end()) {
|
while(riter != iter->second.end()) {
|
||||||
if(riter->event_id == evt) {
|
if(riter->event_id == evt) {
|
||||||
std::string package_name = "encounter_" + riter->encounter_name;
|
std::string package_name = "encounter_" + riter->encounter_name;
|
||||||
int i = _EventSpell(package_name, evt, npc, client, spell_id, data, extra_data, extra_pointers, &riter->lua_reference);
|
int i = _EventSpell(package_name, evt, mob, client, spell_id, data, extra_data, extra_pointers, &riter->lua_reference);
|
||||||
if(i != 0)
|
if(i != 0)
|
||||||
ret = i;
|
ret = i;
|
||||||
}
|
}
|
||||||
@ -1367,10 +1387,16 @@ QuestEventID LuaParser::ConvertLuaEvent(QuestEventID evt) {
|
|||||||
case EVENT_NPC_SLAY:
|
case EVENT_NPC_SLAY:
|
||||||
return EVENT_SLAY;
|
return EVENT_SLAY;
|
||||||
break;
|
break;
|
||||||
|
#ifdef BOTS
|
||||||
|
case EVENT_SPELL_EFFECT_BOT:
|
||||||
|
#endif
|
||||||
case EVENT_SPELL_EFFECT_CLIENT:
|
case EVENT_SPELL_EFFECT_CLIENT:
|
||||||
case EVENT_SPELL_EFFECT_NPC:
|
case EVENT_SPELL_EFFECT_NPC:
|
||||||
return EVENT_SPELL_EFFECT_CLIENT;
|
return EVENT_SPELL_EFFECT_CLIENT;
|
||||||
break;
|
break;
|
||||||
|
#ifdef BOTS
|
||||||
|
case EVENT_SPELL_EFFECT_BUFF_TIC_BOT:
|
||||||
|
#endif
|
||||||
case EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT:
|
case EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT:
|
||||||
case EVENT_SPELL_EFFECT_BUFF_TIC_NPC:
|
case EVENT_SPELL_EFFECT_BUFF_TIC_NPC:
|
||||||
return EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT;
|
return EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT;
|
||||||
@ -1457,4 +1483,186 @@ uint32 LuaParser::GetExperienceForKill(Client *self, Mob *against, bool &ignoreD
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
int LuaParser::EventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
evt = ConvertLuaEvent(evt);
|
||||||
|
if (evt >= _LargestEventID) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bot) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!BotHasQuestSub(evt)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _EventBot("bot", evt, bot, init, data, extra_data, extra_pointers);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaParser::EventGlobalBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
evt = ConvertLuaEvent(evt);
|
||||||
|
if (evt >= _LargestEventID) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bot) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GlobalBotHasQuestSub(evt)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _EventBot("global_bot", evt, bot, init, data, extra_data, extra_pointers);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaParser::_EventBot(
|
||||||
|
std::string package_name,
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers,
|
||||||
|
luabind::adl::object *l_func
|
||||||
|
) {
|
||||||
|
const char *sub_name = LuaEvents[evt];
|
||||||
|
int start = lua_gettop(L);
|
||||||
|
|
||||||
|
try {
|
||||||
|
int npop = 1;
|
||||||
|
if(l_func != nullptr) {
|
||||||
|
l_func->push(L);
|
||||||
|
} else {
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str());
|
||||||
|
lua_getfield(L, -1, sub_name);
|
||||||
|
npop = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_createtable(L, 0, 0);
|
||||||
|
//push self
|
||||||
|
Lua_Bot l_bot(bot);
|
||||||
|
luabind::adl::object l_bot_o = luabind::adl::object(L, l_bot);
|
||||||
|
l_bot_o.push(L);
|
||||||
|
lua_setfield(L, -2, "self");
|
||||||
|
|
||||||
|
auto arg_function = BotArgumentDispatch[evt];
|
||||||
|
arg_function(this, L, bot, init, data, extra_data, extra_pointers);
|
||||||
|
auto* c = (init && init->IsClient()) ? init->CastToClient() : nullptr;
|
||||||
|
|
||||||
|
quest_manager.StartQuest(bot, c);
|
||||||
|
if(lua_pcall(L, 1, 1, 0)) {
|
||||||
|
std::string error = lua_tostring(L, -1);
|
||||||
|
AddError(error);
|
||||||
|
quest_manager.EndQuest();
|
||||||
|
lua_pop(L, npop);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
quest_manager.EndQuest();
|
||||||
|
|
||||||
|
if(lua_isnumber(L, -1)) {
|
||||||
|
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||||
|
lua_pop(L, npop);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, npop);
|
||||||
|
} catch(std::exception &ex) {
|
||||||
|
std::string error = "Lua Exception: ";
|
||||||
|
error += std::string(ex.what());
|
||||||
|
AddError(error);
|
||||||
|
|
||||||
|
//Restore our stack to the best of our ability
|
||||||
|
int end = lua_gettop(L);
|
||||||
|
int n = end - start;
|
||||||
|
if(n > 0) {
|
||||||
|
lua_pop(L, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int LuaParser::DispatchEventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
evt = ConvertLuaEvent(evt);
|
||||||
|
if (evt >= _LargestEventID) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string package_name = "bot";
|
||||||
|
|
||||||
|
auto iter = lua_encounter_events_registered.find(package_name);
|
||||||
|
if (iter == lua_encounter_events_registered.end()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
auto riter = iter->second.begin();
|
||||||
|
while (riter != iter->second.end()) {
|
||||||
|
if (riter->event_id == evt) {
|
||||||
|
package_name = fmt::format("encounter_{}", riter->encounter_name);
|
||||||
|
int i = _EventBot(package_name, evt, bot, init, data, extra_data, extra_pointers, &riter->lua_reference);
|
||||||
|
if (i != 0) {
|
||||||
|
ret = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++riter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaParser::BotHasQuestSub(QuestEventID evt) {
|
||||||
|
evt = ConvertLuaEvent(evt);
|
||||||
|
if (evt >= _LargestEventID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *subname = LuaEvents[evt];
|
||||||
|
return HasFunction(subname, "bot");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LuaParser::GlobalBotHasQuestSub(QuestEventID evt) {
|
||||||
|
evt = ConvertLuaEvent(evt);
|
||||||
|
if (evt >= _LargestEventID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *subname = LuaEvents[evt];
|
||||||
|
return HasFunction(subname, "global_bot");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaParser::LoadBotScript(std::string filename) {
|
||||||
|
LoadScript(filename, "bot");
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaParser::LoadGlobalBotScript(std::string filename) {
|
||||||
|
LoadScript(filename, "global_bot");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -36,20 +36,80 @@ class LuaParser : public QuestInterface {
|
|||||||
public:
|
public:
|
||||||
~LuaParser();
|
~LuaParser();
|
||||||
|
|
||||||
virtual int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int EventNPC(
|
||||||
std::vector<std::any> *extra_pointers);
|
QuestEventID evt,
|
||||||
virtual int EventGlobalNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
NPC* npc,
|
||||||
std::vector<std::any> *extra_pointers);
|
Mob *init,
|
||||||
virtual int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
std::string data,
|
||||||
std::vector<std::any> *extra_pointers);
|
uint32 extra_data,
|
||||||
virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
std::vector<std::any> *extra_pointers
|
||||||
std::vector<std::any> *extra_pointers);
|
);
|
||||||
virtual int EventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
virtual int EventGlobalNPC(
|
||||||
std::vector<std::any> *extra_pointers);
|
QuestEventID evt,
|
||||||
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
NPC* npc,
|
||||||
std::vector<std::any> *extra_pointers);
|
Mob *init,
|
||||||
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
std::string data,
|
||||||
std::vector<std::any> *extra_pointers);
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventPlayer(
|
||||||
|
QuestEventID evt,
|
||||||
|
Client *client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventGlobalPlayer(
|
||||||
|
QuestEventID evt,
|
||||||
|
Client *client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventItem(
|
||||||
|
QuestEventID evt,
|
||||||
|
Client *client,
|
||||||
|
EQ::ItemInstance *item,
|
||||||
|
Mob *mob,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventSpell(
|
||||||
|
QuestEventID evt,
|
||||||
|
Mob* mob,
|
||||||
|
Client *client,
|
||||||
|
uint32 spell_id,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventEncounter(
|
||||||
|
QuestEventID evt,
|
||||||
|
std::string encounter_name,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual int EventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int EventGlobalBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt);
|
virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt);
|
||||||
virtual bool HasGlobalQuestSub(QuestEventID evt);
|
virtual bool HasGlobalQuestSub(QuestEventID evt);
|
||||||
@ -60,6 +120,11 @@ public:
|
|||||||
virtual bool EncounterHasQuestSub(std::string encounter_name, QuestEventID evt);
|
virtual bool EncounterHasQuestSub(std::string encounter_name, QuestEventID evt);
|
||||||
virtual bool HasEncounterSub(const std::string& package_name, QuestEventID evt);
|
virtual bool HasEncounterSub(const std::string& package_name, QuestEventID evt);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual bool BotHasQuestSub(QuestEventID evt);
|
||||||
|
virtual bool GlobalBotHasQuestSub(QuestEventID evt);
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual void LoadNPCScript(std::string filename, int npc_id);
|
virtual void LoadNPCScript(std::string filename, int npc_id);
|
||||||
virtual void LoadGlobalNPCScript(std::string filename);
|
virtual void LoadGlobalNPCScript(std::string filename);
|
||||||
virtual void LoadPlayerScript(std::string filename);
|
virtual void LoadPlayerScript(std::string filename);
|
||||||
@ -68,6 +133,11 @@ public:
|
|||||||
virtual void LoadSpellScript(std::string filename, uint32 spell_id);
|
virtual void LoadSpellScript(std::string filename, uint32 spell_id);
|
||||||
virtual void LoadEncounterScript(std::string filename, std::string encounter_name);
|
virtual void LoadEncounterScript(std::string filename, std::string encounter_name);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual void LoadBotScript(std::string filename);
|
||||||
|
virtual void LoadGlobalBotScript(std::string filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual void AddVar(std::string name, std::string val);
|
virtual void AddVar(std::string name, std::string val);
|
||||||
virtual std::string GetVar(std::string name);
|
virtual std::string GetVar(std::string name);
|
||||||
virtual void Init();
|
virtual void Init();
|
||||||
@ -75,14 +145,50 @@ public:
|
|||||||
virtual void RemoveEncounter(const std::string &name);
|
virtual void RemoveEncounter(const std::string &name);
|
||||||
virtual uint32 GetIdentifier() { return 0xb0712acc; }
|
virtual uint32 GetIdentifier() { return 0xb0712acc; }
|
||||||
|
|
||||||
virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int DispatchEventNPC(
|
||||||
std::vector<std::any> *extra_pointers);
|
QuestEventID evt,
|
||||||
virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
NPC* npc,
|
||||||
std::vector<std::any> *extra_pointers);
|
Mob *init,
|
||||||
virtual int DispatchEventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
std::string data,
|
||||||
std::vector<std::any> *extra_pointers);
|
uint32 extra_data,
|
||||||
virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
std::vector<std::any> *extra_pointers
|
||||||
std::vector<std::any> *extra_pointers);
|
);
|
||||||
|
virtual int DispatchEventPlayer(
|
||||||
|
QuestEventID evt,
|
||||||
|
Client *client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int DispatchEventItem(
|
||||||
|
QuestEventID evt,
|
||||||
|
Client *client,
|
||||||
|
EQ::ItemInstance *item,
|
||||||
|
Mob *mob,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
virtual int DispatchEventSpell(
|
||||||
|
QuestEventID evt,
|
||||||
|
Mob* mob,
|
||||||
|
Client *client,
|
||||||
|
uint32 spell_id,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual int DispatchEventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
static LuaParser* Instance() {
|
static LuaParser* Instance() {
|
||||||
static LuaParser inst;
|
static LuaParser inst;
|
||||||
@ -107,16 +213,68 @@ private:
|
|||||||
LuaParser(const LuaParser&);
|
LuaParser(const LuaParser&);
|
||||||
LuaParser& operator=(const LuaParser&);
|
LuaParser& operator=(const LuaParser&);
|
||||||
|
|
||||||
int _EventNPC(std::string package_name, QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int _EventNPC(
|
||||||
std::vector<std::any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
std::string package_name,
|
||||||
int _EventPlayer(std::string package_name, QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
QuestEventID evt,
|
||||||
std::vector<std::any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
NPC* npc,
|
||||||
int _EventItem(std::string package_name, QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data,
|
Mob *init,
|
||||||
uint32 extra_data, std::vector<std::any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
std::string data,
|
||||||
int _EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers, luabind::adl::object *l_func = nullptr);
|
std::vector<std::any> *extra_pointers,
|
||||||
int _EventEncounter(std::string package_name, QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
luabind::adl::object *l_func = nullptr
|
||||||
std::vector<std::any> *extra_pointers);
|
);
|
||||||
|
int _EventPlayer(
|
||||||
|
std::string package_name,
|
||||||
|
QuestEventID evt,
|
||||||
|
Client *client,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers,
|
||||||
|
luabind::adl::object *l_func = nullptr
|
||||||
|
);
|
||||||
|
int _EventItem(
|
||||||
|
std::string package_name,
|
||||||
|
QuestEventID evt,
|
||||||
|
Client *client,
|
||||||
|
EQ::ItemInstance *item,
|
||||||
|
Mob *mob,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers,
|
||||||
|
luabind::adl::object *l_func = nullptr
|
||||||
|
);
|
||||||
|
int _EventSpell(
|
||||||
|
std::string package_name,
|
||||||
|
QuestEventID evt,
|
||||||
|
Mob* mob,
|
||||||
|
Client *client,
|
||||||
|
uint32 spell_id,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers,
|
||||||
|
luabind::adl::object *l_func = nullptr
|
||||||
|
);
|
||||||
|
int _EventEncounter(
|
||||||
|
std::string package_name,
|
||||||
|
QuestEventID evt,
|
||||||
|
std::string encounter_name,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
int _EventBot(
|
||||||
|
std::string package_name,
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers,
|
||||||
|
luabind::adl::object *l_func = nullptr
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
void LoadScript(std::string filename, std::string package_name);
|
void LoadScript(std::string filename, std::string package_name);
|
||||||
void MapFunctions(lua_State *L);
|
void MapFunctions(lua_State *L);
|
||||||
@ -133,6 +291,10 @@ private:
|
|||||||
SpellArgumentHandler SpellArgumentDispatch[_LargestEventID];
|
SpellArgumentHandler SpellArgumentDispatch[_LargestEventID];
|
||||||
EncounterArgumentHandler EncounterArgumentDispatch[_LargestEventID];
|
EncounterArgumentHandler EncounterArgumentDispatch[_LargestEventID];
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
BotArgumentHandler BotArgumentDispatch[_LargestEventID];
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -668,6 +668,26 @@ void handle_player_inspect(QuestInterface* parse, lua_State* L, Client* client,
|
|||||||
lua_setfield(L, -2, "other");
|
lua_setfield(L, -2, "other");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handle_player_aa_buy(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector<std::any>* extra_pointers) {
|
||||||
|
Seperator sep(data.c_str());
|
||||||
|
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
||||||
|
lua_setfield(L, -2, "aa_cost");
|
||||||
|
|
||||||
|
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
||||||
|
lua_setfield(L, -2, "aa_id");
|
||||||
|
|
||||||
|
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
||||||
|
lua_setfield(L, -2, "aa_previous_id");
|
||||||
|
|
||||||
|
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
||||||
|
lua_setfield(L, -2, "aa_next_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_player_aa_gain(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector<std::any>* extra_pointers) {
|
||||||
|
lua_pushinteger(L, std::stoi(data));
|
||||||
|
lua_setfield(L, -2, "aa_gained");
|
||||||
|
}
|
||||||
|
|
||||||
//Item
|
//Item
|
||||||
void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, EQ::ItemInstance* item, Mob *mob, std::string data, uint32 extra_data,
|
void handle_item_click(QuestInterface *parse, lua_State* L, Client* client, EQ::ItemInstance* item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) {
|
std::vector<std::any> *extra_pointers) {
|
||||||
@ -764,11 +784,11 @@ void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, EQ::I
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Spell
|
//Spell
|
||||||
void handle_spell_event(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers) {
|
void handle_spell_event(QuestInterface *parse, lua_State* L, Mob* mob, Client* client, uint32 spell_id, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers) {
|
||||||
if(npc) {
|
if (mob) {
|
||||||
Lua_Mob l_npc(npc);
|
Lua_Mob l_mob(mob);
|
||||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
l_npc_o.push(L);
|
l_mob_o.push(L);
|
||||||
} else if(client) {
|
} else if(client) {
|
||||||
Lua_Mob l_client(client);
|
Lua_Mob l_client(client);
|
||||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||||
@ -804,11 +824,11 @@ void handle_spell_event(QuestInterface *parse, lua_State* L, NPC* npc, Client* c
|
|||||||
lua_setfield(L, -2, "spell");
|
lua_setfield(L, -2, "spell");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers) {
|
void handle_translocate_finish(QuestInterface *parse, lua_State* L, Mob* mob, Client* client, uint32 spell_id, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers) {
|
||||||
if(npc) {
|
if (mob) {
|
||||||
Lua_Mob l_npc(npc);
|
Lua_Mob l_mob(mob);
|
||||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
l_npc_o.push(L);
|
l_mob_o.push(L);
|
||||||
} else if(client) {
|
} else if(client) {
|
||||||
Lua_Mob l_client(client);
|
Lua_Mob l_client(client);
|
||||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||||
@ -840,7 +860,7 @@ void handle_player_equip_item(QuestInterface *parse, lua_State* L, Client* clien
|
|||||||
lua_setfield(L, -2, "item");
|
lua_setfield(L, -2, "item");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers) { }
|
void handle_spell_null(QuestInterface *parse, lua_State* L, Mob* mob, Client* client, uint32 spell_id, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers) { }
|
||||||
|
|
||||||
void handle_encounter_timer(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
void handle_encounter_timer(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) {
|
std::vector<std::any> *extra_pointers) {
|
||||||
@ -940,24 +960,216 @@ void handle_player_merchant(QuestInterface* parse, lua_State* L, Client* client,
|
|||||||
lua_setfield(L, -2, "item_cost");
|
lua_setfield(L, -2, "item_cost");
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_aa_buy(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector<std::any>* extra_pointers) {
|
#ifdef BOTS
|
||||||
Seperator sep(data.c_str());
|
void handle_bot_null(
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
QuestInterface *parse,
|
||||||
lua_setfield(L, -2, "aa_cost");
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
Mob* init,
|
||||||
lua_setfield(L, -2, "aa_id");
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
std::vector<std::any> *extra_pointers
|
||||||
lua_setfield(L, -2, "aa_previous_id");
|
) {
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
|
||||||
lua_setfield(L, -2, "aa_next_id");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_player_aa_gain(QuestInterface* parse, lua_State* L, Client* client, std::string data, uint32 extra_data, std::vector<std::any>* extra_pointers) {
|
void handle_bot_cast(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
|
int spell_id = std::stoi(sep.arg[0]);
|
||||||
|
if (IsValidSpell(spell_id)) {
|
||||||
|
Lua_Spell l_spell(&spells[spell_id]);
|
||||||
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
|
l_spell_o.push(L);
|
||||||
|
} else {
|
||||||
|
Lua_Spell l_spell(nullptr);
|
||||||
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
|
l_spell_o.push(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_setfield(L, -2, "spell");
|
||||||
|
|
||||||
|
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
||||||
|
lua_setfield(L, -2, "caster_id");
|
||||||
|
|
||||||
|
lua_pushinteger(L, std::stoi(sep.arg[2]));
|
||||||
|
lua_setfield(L, -2, "caster_level");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_bot_combat(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Lua_Mob l_mob(init);
|
||||||
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
|
l_mob_o.push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
|
lua_pushboolean(L, std::stoi(data) == 0 ? false : true);
|
||||||
|
lua_setfield(L, -2, "joined");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_bot_death(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Seperator sep(data.c_str());
|
||||||
|
|
||||||
|
Mob *o = entity_list.GetMobID(std::stoi(sep.arg[0]));
|
||||||
|
Lua_Mob l_mob(o);
|
||||||
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
|
l_mob_o.push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
|
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
||||||
|
lua_setfield(L, -2, "damage");
|
||||||
|
|
||||||
|
int spell_id = std::stoi(sep.arg[2]);
|
||||||
|
if (IsValidSpell(spell_id)) {
|
||||||
|
Lua_Spell l_spell(&spells[spell_id]);
|
||||||
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
|
l_spell_o.push(L);
|
||||||
|
lua_setfield(L, -2, "spell");
|
||||||
|
} else {
|
||||||
|
Lua_Spell l_spell(nullptr);
|
||||||
|
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||||
|
l_spell_o.push(L);
|
||||||
|
lua_setfield(L, -2, "spell");
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushinteger(L, std::stoi(sep.arg[3]));
|
||||||
|
lua_setfield(L, -2, "skill");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_bot_popup_response(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Lua_Mob l_mob(init);
|
||||||
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
|
l_mob_o.push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
lua_pushinteger(L, std::stoi(data));
|
lua_pushinteger(L, std::stoi(data));
|
||||||
lua_setfield(L, -2, "aa_gained");
|
lua_setfield(L, -2, "popup_id");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_bot_say(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Lua_Client l_client(reinterpret_cast<Client*>(init));
|
||||||
|
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||||
|
l_client_o.push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
|
||||||
|
lua_pushstring(L, data.c_str());
|
||||||
|
lua_setfield(L, -2, "message");
|
||||||
|
|
||||||
|
lua_pushinteger(L, extra_data);
|
||||||
|
lua_setfield(L, -2, "language");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_bot_signal(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
lua_pushinteger(L, std::stoi(data));
|
||||||
|
lua_setfield(L, -2, "signal");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_bot_slay(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Lua_Mob l_mob(init);
|
||||||
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
|
l_mob_o.push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_bot_target_change(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Lua_Mob l_mob(init);
|
||||||
|
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||||
|
l_mob_o.push(L);
|
||||||
|
lua_setfield(L, -2, "other");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_bot_timer(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
lua_pushstring(L, data.c_str());
|
||||||
|
lua_setfield(L, -2, "timer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_bot_use_skill(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
Seperator sep(data.c_str());
|
||||||
|
lua_pushinteger(L, std::stoi(sep.arg[0]));
|
||||||
|
lua_setfield(L, -2, "skill_id");
|
||||||
|
|
||||||
|
lua_pushinteger(L, std::stoi(sep.arg[1]));
|
||||||
|
lua_setfield(L, -2, "skill_level");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@ -5,9 +5,13 @@
|
|||||||
typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32, std::vector<std::any>*);
|
typedef void(*NPCArgumentHandler)(QuestInterface*, lua_State*, NPC*, Mob*, std::string, uint32, std::vector<std::any>*);
|
||||||
typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector<std::any>*);
|
typedef void(*PlayerArgumentHandler)(QuestInterface*, lua_State*, Client*, std::string, uint32, std::vector<std::any>*);
|
||||||
typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, EQ::ItemInstance*, Mob*, std::string, uint32, std::vector<std::any>*);
|
typedef void(*ItemArgumentHandler)(QuestInterface*, lua_State*, Client*, EQ::ItemInstance*, Mob*, std::string, uint32, std::vector<std::any>*);
|
||||||
typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, NPC*, Client*, uint32, std::string, uint32, std::vector<std::any>*);
|
typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, Mob*, Client*, uint32, std::string, uint32, std::vector<std::any>*);
|
||||||
typedef void(*EncounterArgumentHandler)(QuestInterface*, lua_State*, Encounter* encounter, std::string, uint32, std::vector<std::any>*);
|
typedef void(*EncounterArgumentHandler)(QuestInterface*, lua_State*, Encounter* encounter, std::string, uint32, std::vector<std::any>*);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
typedef void(*BotArgumentHandler)(QuestInterface*, lua_State*, Bot*, Mob*, std::string, uint32, std::vector<std::any>*);
|
||||||
|
#endif
|
||||||
|
|
||||||
//NPC
|
//NPC
|
||||||
void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
void handle_npc_event_say(QuestInterface *parse, lua_State* L, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers);
|
std::vector<std::any> *extra_pointers);
|
||||||
@ -153,11 +157,11 @@ void handle_item_null(QuestInterface *parse, lua_State* L, Client* client, EQ::I
|
|||||||
std::vector<std::any> *extra_pointers);
|
std::vector<std::any> *extra_pointers);
|
||||||
|
|
||||||
//Spell
|
//Spell
|
||||||
void handle_spell_event(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, std::string data, uint32 extra_data,
|
void handle_spell_event(QuestInterface *parse, lua_State* L, Mob* mob, Client* client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers);
|
std::vector<std::any> *extra_pointers);
|
||||||
void handle_translocate_finish(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, std::string data, uint32 extra_data,
|
void handle_translocate_finish(QuestInterface *parse, lua_State* L, Mob* mob, Client* client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers);
|
std::vector<std::any> *extra_pointers);
|
||||||
void handle_spell_null(QuestInterface *parse, lua_State* L, NPC* npc, Client* client, uint32 spell_id, std::string data, uint32 extra_data,
|
void handle_spell_null(QuestInterface *parse, lua_State* L, Mob* mob, Client* client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers);
|
std::vector<std::any> *extra_pointers);
|
||||||
|
|
||||||
|
|
||||||
@ -171,5 +175,118 @@ void handle_encounter_unload(QuestInterface *parse, lua_State* L, Encounter* enc
|
|||||||
void handle_encounter_null(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
void handle_encounter_null(QuestInterface *parse, lua_State* L, Encounter* encounter, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers);
|
std::vector<std::any> *extra_pointers);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
void handle_bot_null(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_cast(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_combat(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_death(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_popup_response(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_say(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_signal(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_slay(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_target_change(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_timer(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
void handle_bot_use_skill(
|
||||||
|
QuestInterface *parse,
|
||||||
|
lua_State* L,
|
||||||
|
Bot* bot,
|
||||||
|
Mob* init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -4300,6 +4300,8 @@ void Mob::SetTarget(Mob *mob)
|
|||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
CastToClient()->SetBotPrecombat(false); // Any change in target will nullify this flag (target == mob checked above)
|
CastToClient()->SetBotPrecombat(false); // Any change in target will nullify this flag (target == mob checked above)
|
||||||
|
} else if (IsBot()) {
|
||||||
|
parse->EventBot(EVENT_TARGET_CHANGE, CastToBot(), mob, "", 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,10 @@
|
|||||||
#include "fastmath.h"
|
#include "fastmath.h"
|
||||||
#include "../common/data_verification.h"
|
#include "../common/data_verification.h"
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
#include "bot.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <glm/gtx/projection.hpp>
|
#include <glm/gtx/projection.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -1923,10 +1927,11 @@ void Mob::AI_Event_Engaged(Mob *attacker, bool yell_for_help)
|
|||||||
if (attacker->GetHP() > 0) {
|
if (attacker->GetHP() > 0) {
|
||||||
if (!CastToNPC()->GetCombatEvent() && GetHP() > 0) {
|
if (!CastToNPC()->GetCombatEvent() && GetHP() > 0) {
|
||||||
parse->EventNPC(EVENT_COMBAT, CastToNPC(), attacker, "1", 0);
|
parse->EventNPC(EVENT_COMBAT, CastToNPC(), attacker, "1", 0);
|
||||||
uint32 emoteid = GetEmoteID();
|
auto emote_id = GetEmoteID();
|
||||||
if (emoteid != 0) {
|
if (emote_id) {
|
||||||
CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::EnterCombat, emoteid);
|
CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::EnterCombat, emoteid);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string mob_name = GetCleanName();
|
std::string mob_name = GetCleanName();
|
||||||
combat_record.Start(mob_name);
|
combat_record.Start(mob_name);
|
||||||
CastToNPC()->SetCombatEvent(true);
|
CastToNPC()->SetCombatEvent(true);
|
||||||
@ -1934,18 +1939,28 @@ void Mob::AI_Event_Engaged(Mob *attacker, bool yell_for_help)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
if (IsBot()) {
|
||||||
|
parse->EventBot(EVENT_COMBAT, CastToBot(), attacker, "1", 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: Hate list may not be actually clear until after this function call completes
|
// Note: Hate list may not be actually clear until after this function call completes
|
||||||
void Mob::AI_Event_NoLongerEngaged() {
|
void Mob::AI_Event_NoLongerEngaged() {
|
||||||
if (!IsAIControlled())
|
if (!IsAIControlled()) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
AI_walking_timer->Start(RandomTimer(3000,20000));
|
AI_walking_timer->Start(RandomTimer(3000,20000));
|
||||||
time_until_can_move = Timer::GetCurrentTime();
|
time_until_can_move = Timer::GetCurrentTime();
|
||||||
if (minLastFightingDelayMoving == maxLastFightingDelayMoving)
|
|
||||||
|
if (minLastFightingDelayMoving == maxLastFightingDelayMoving) {
|
||||||
time_until_can_move += minLastFightingDelayMoving;
|
time_until_can_move += minLastFightingDelayMoving;
|
||||||
else
|
} else {
|
||||||
time_until_can_move += zone->random.Int(minLastFightingDelayMoving, maxLastFightingDelayMoving);
|
time_until_can_move += zone->random.Int(minLastFightingDelayMoving, maxLastFightingDelayMoving);
|
||||||
|
}
|
||||||
|
|
||||||
StopNavigation();
|
StopNavigation();
|
||||||
ClearRampage();
|
ClearRampage();
|
||||||
@ -1954,16 +1969,21 @@ void Mob::AI_Event_NoLongerEngaged() {
|
|||||||
SetPrimaryAggro(false);
|
SetPrimaryAggro(false);
|
||||||
SetAssistAggro(false);
|
SetAssistAggro(false);
|
||||||
if (CastToNPC()->GetCombatEvent() && GetHP() > 0) {
|
if (CastToNPC()->GetCombatEvent() && GetHP() > 0) {
|
||||||
if (entity_list.GetNPCByID(this->GetID())) {
|
if (entity_list.GetNPCByID(GetID())) {
|
||||||
uint32 emoteid = CastToNPC()->GetEmoteID();
|
auto emote_id = CastToNPC()->GetEmoteID();
|
||||||
parse->EventNPC(EVENT_COMBAT, CastToNPC(), nullptr, "0", 0);
|
parse->EventNPC(EVENT_COMBAT, CastToNPC(), nullptr, "0", 0);
|
||||||
if (emoteid != 0) {
|
if (emote_id) {
|
||||||
CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::LeaveCombat, emoteid);
|
CastToNPC()->DoNPCEmote(EQ::constants::EmoteEventTypes::LeaveCombat, emoteid);
|
||||||
}
|
}
|
||||||
|
|
||||||
combat_record.Stop();
|
combat_record.Stop();
|
||||||
CastToNPC()->SetCombatEvent(false);
|
CastToNPC()->SetCombatEvent(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (IsBot()) {
|
||||||
|
parse->EventBot(EVENT_COMBAT, CastToBot(), nullptr, "0", 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -81,6 +81,16 @@ uint32 Perl_Bot_GetBotItemIDBySlot(Bot* self, uint16 slot_id)
|
|||||||
return self->GetBotItemBySlot(slot_id);
|
return self->GetBotItemBySlot(slot_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Perl_Bot_SignalBot(Bot* self, int signal_id)
|
||||||
|
{
|
||||||
|
self->SignalBot(signal_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Perl_Bot_OwnerMessage(Bot* self, std::string message)
|
||||||
|
{
|
||||||
|
self->OwnerMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
int Perl_Bot_GetExpansionBitmask(Bot* self)
|
int Perl_Bot_GetExpansionBitmask(Bot* self)
|
||||||
{
|
{
|
||||||
return self->GetExpansionBitmask();
|
return self->GetExpansionBitmask();
|
||||||
@ -117,9 +127,11 @@ void perl_register_bot()
|
|||||||
package.add("GetExpansionBitmask", &Perl_Bot_GetExpansionBitmask);
|
package.add("GetExpansionBitmask", &Perl_Bot_GetExpansionBitmask);
|
||||||
package.add("GetOwner", &Perl_Bot_GetOwner);
|
package.add("GetOwner", &Perl_Bot_GetOwner);
|
||||||
package.add("HasBotItem", &Perl_Bot_HasBotItem);
|
package.add("HasBotItem", &Perl_Bot_HasBotItem);
|
||||||
|
package.add("OwnerMessage", &Perl_Bot_OwnerMessage);
|
||||||
package.add("RemoveBotItem", &Perl_Bot_RemoveBotItem);
|
package.add("RemoveBotItem", &Perl_Bot_RemoveBotItem);
|
||||||
package.add("SetExpansionBitmask", (void(*)(Bot*, int))&Perl_Bot_SetExpansionBitmask);
|
package.add("SetExpansionBitmask", (void(*)(Bot*, int))&Perl_Bot_SetExpansionBitmask);
|
||||||
package.add("SetExpansionBitmask", (void(*)(Bot*, int, bool))&Perl_Bot_SetExpansionBitmask);
|
package.add("SetExpansionBitmask", (void(*)(Bot*, int, bool))&Perl_Bot_SetExpansionBitmask);
|
||||||
|
package.add("SignalBot", &Perl_Bot_SignalBot);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //EMBPERL_XS_CLASSES
|
#endif //EMBPERL_XS_CLASSES
|
||||||
|
|||||||
@ -449,6 +449,21 @@ perl::array Perl_EntityList_GetBotListByClientName(EntityList* self, std::string
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Perl_EntityList_SignalAllBotsByOwnerCharacterID(EntityList* self, uint32_t character_id, int signal_id) // @categories Script Utility
|
||||||
|
{
|
||||||
|
entity_list.SignalAllBotsByOwnerCharacterID(character_id, signal_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Perl_EntityList_SignalBotByBotID(EntityList* self, uint32_t bot_id, int signal_id) // @categories Script Utility
|
||||||
|
{
|
||||||
|
entity_list.SignalBotByBotID(bot_id, signal_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Perl_EntityList_SignalBotByBotName(EntityList* self, std::string bot_name, int signal_id) // @categories Script Utility
|
||||||
|
{
|
||||||
|
entity_list.SignalBotByBotName(bot_name, signal_id);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
perl::array Perl_EntityList_GetNPCList(EntityList* self) // @categories Script Utility
|
perl::array Perl_EntityList_GetNPCList(EntityList* self) // @categories Script Utility
|
||||||
@ -675,7 +690,14 @@ void perl_register_entitylist()
|
|||||||
package.add("RemoveObject", &Perl_EntityList_RemoveObject);
|
package.add("RemoveObject", &Perl_EntityList_RemoveObject);
|
||||||
package.add("RemoveTrap", &Perl_EntityList_RemoveTrap);
|
package.add("RemoveTrap", &Perl_EntityList_RemoveTrap);
|
||||||
package.add("ReplaceWithTarget", &Perl_EntityList_ReplaceWithTarget);
|
package.add("ReplaceWithTarget", &Perl_EntityList_ReplaceWithTarget);
|
||||||
|
#ifdef BOTS
|
||||||
|
package.add("SignalAllBotsByOwnerCharacterID", &Perl_EntityList_SignalAllBotsByOwnerCharacterID);
|
||||||
|
#endif
|
||||||
package.add("SignalAllClients", &Perl_EntityList_SignalAllClients);
|
package.add("SignalAllClients", &Perl_EntityList_SignalAllClients);
|
||||||
|
#ifdef BOTS
|
||||||
|
package.add("SignalBotByBotID", &Perl_EntityList_SignalBotByBotID);
|
||||||
|
package.add("SignalBotByBotName", &Perl_EntityList_SignalBotByBotName);
|
||||||
|
#endif
|
||||||
package.add("SignalMobsByNPCID", &Perl_EntityList_SignalMobsByNPCID);
|
package.add("SignalMobsByNPCID", &Perl_EntityList_SignalMobsByNPCID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1492,9 +1492,9 @@ perl::array Perl_Mob_GetHateList(Mob* self)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl_Mob_SignalClient(Mob* self, Client* client, uint32 data) // @categories Script Utility
|
void Perl_Mob_SignalClient(Mob* self, Client* client, int signal_id) // @categories Script Utility
|
||||||
{
|
{
|
||||||
client->Signal(data);
|
client->Signal(signal_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Perl_Mob_CombatRange(Mob* self, Mob* target) // @categories Script Utility
|
bool Perl_Mob_CombatRange(Mob* self, Mob* target) // @categories Script Utility
|
||||||
|
|||||||
@ -43,11 +43,35 @@ public:
|
|||||||
std::vector<std::any> *extra_pointers) { return 0; }
|
std::vector<std::any> *extra_pointers) { return 0; }
|
||||||
virtual int EventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
virtual int EventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) { return 0; }
|
std::vector<std::any> *extra_pointers) { return 0; }
|
||||||
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
virtual int EventSpell(QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) { return 0; }
|
std::vector<std::any> *extra_pointers) { return 0; }
|
||||||
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
virtual int EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) { return 0; }
|
std::vector<std::any> *extra_pointers) { return 0; }
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual int EventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointer
|
||||||
|
) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int EventGlobalBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual bool HasQuestSub(uint32 npcid, QuestEventID evt) { return false; }
|
virtual bool HasQuestSub(uint32 npcid, QuestEventID evt) { return false; }
|
||||||
virtual bool HasGlobalQuestSub(QuestEventID evt) { return false; }
|
virtual bool HasGlobalQuestSub(QuestEventID evt) { return false; }
|
||||||
virtual bool PlayerHasQuestSub(QuestEventID evt) { return false; }
|
virtual bool PlayerHasQuestSub(QuestEventID evt) { return false; }
|
||||||
@ -57,6 +81,11 @@ public:
|
|||||||
virtual bool EncounterHasQuestSub(std::string encounter_name, QuestEventID evt) { return false; }
|
virtual bool EncounterHasQuestSub(std::string encounter_name, QuestEventID evt) { return false; }
|
||||||
virtual bool HasEncounterSub(const std::string& package_name, QuestEventID evt) { return false; }
|
virtual bool HasEncounterSub(const std::string& package_name, QuestEventID evt) { return false; }
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual bool BotHasQuestSub(QuestEventID evt) { return false; }
|
||||||
|
virtual bool GlobalBotHasQuestSub(QuestEventID evt) { return false; }
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual void LoadNPCScript(std::string filename, int npc_id) { }
|
virtual void LoadNPCScript(std::string filename, int npc_id) { }
|
||||||
virtual void LoadGlobalNPCScript(std::string filename) { }
|
virtual void LoadGlobalNPCScript(std::string filename) { }
|
||||||
virtual void LoadPlayerScript(std::string filename) { }
|
virtual void LoadPlayerScript(std::string filename) { }
|
||||||
@ -65,15 +94,33 @@ public:
|
|||||||
virtual void LoadSpellScript(std::string filename, uint32 spell_id) { }
|
virtual void LoadSpellScript(std::string filename, uint32 spell_id) { }
|
||||||
virtual void LoadEncounterScript(std::string filename, std::string encounter_name) { }
|
virtual void LoadEncounterScript(std::string filename, std::string encounter_name) { }
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual void LoadBotScript(std::string filename) { }
|
||||||
|
virtual void LoadGlobalBotScript(std::string filename) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
virtual int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) { return 0; }
|
std::vector<std::any> *extra_pointers) { return 0; }
|
||||||
virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
virtual int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) { return 0; }
|
std::vector<std::any> *extra_pointers) { return 0; }
|
||||||
virtual int DispatchEventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
virtual int DispatchEventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) { return 0; }
|
std::vector<std::any> *extra_pointers) { return 0; }
|
||||||
virtual int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
virtual int DispatchEventSpell(QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers) { return 0; }
|
std::vector<std::any> *extra_pointers) { return 0; }
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
virtual int DispatchEventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual void AddVar(std::string name, std::string val) { }
|
virtual void AddVar(std::string name, std::string val) { }
|
||||||
virtual std::string GetVar(std::string name) { return std::string(); }
|
virtual std::string GetVar(std::string name) { return std::string(); }
|
||||||
virtual void Init() { }
|
virtual void Init() { }
|
||||||
|
|||||||
@ -36,6 +36,11 @@ QuestParserCollection::QuestParserCollection() {
|
|||||||
_player_quest_status = QuestUnloaded;
|
_player_quest_status = QuestUnloaded;
|
||||||
_global_player_quest_status = QuestUnloaded;
|
_global_player_quest_status = QuestUnloaded;
|
||||||
_global_npc_quest_status = QuestUnloaded;
|
_global_npc_quest_status = QuestUnloaded;
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
_bot_quest_status = QuestUnloaded;
|
||||||
|
_global_bot_quest_status = QuestUnloaded;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QuestParserCollection::~QuestParserCollection() {
|
QuestParserCollection::~QuestParserCollection() {
|
||||||
@ -70,7 +75,7 @@ void QuestParserCollection::Init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QuestParserCollection::ReloadQuests(bool reset_timers) {
|
void QuestParserCollection::ReloadQuests(bool reset_timers) {
|
||||||
if(reset_timers) {
|
if (reset_timers) {
|
||||||
quest_manager.ClearAllTimers();
|
quest_manager.ClearAllTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,11 +84,17 @@ void QuestParserCollection::ReloadQuests(bool reset_timers) {
|
|||||||
_player_quest_status = QuestUnloaded;
|
_player_quest_status = QuestUnloaded;
|
||||||
_global_player_quest_status = QuestUnloaded;
|
_global_player_quest_status = QuestUnloaded;
|
||||||
_global_npc_quest_status = QuestUnloaded;
|
_global_npc_quest_status = QuestUnloaded;
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
_bot_quest_status = QuestUnloaded;
|
||||||
|
_global_bot_quest_status = QuestUnloaded;
|
||||||
|
#endif
|
||||||
|
|
||||||
_spell_quest_status.clear();
|
_spell_quest_status.clear();
|
||||||
_item_quest_status.clear();
|
_item_quest_status.clear();
|
||||||
_encounter_quest_status.clear();
|
_encounter_quest_status.clear();
|
||||||
auto iter = _load_precedence.begin();
|
auto iter = _load_precedence.begin();
|
||||||
while(iter != _load_precedence.end()) {
|
while (iter != _load_precedence.end()) {
|
||||||
(*iter)->ReloadQuests();
|
(*iter)->ReloadQuests();
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
@ -452,38 +463,46 @@ int QuestParserCollection::EventItem(QuestEventID evt, Client *client, EQ::ItemI
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
int QuestParserCollection::EventSpell(
|
||||||
std::vector<std::any> *extra_pointers) {
|
QuestEventID evt,
|
||||||
|
Mob* mob,
|
||||||
|
Client *client,
|
||||||
|
uint32 spell_id,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
auto iter = _spell_quest_status.find(spell_id);
|
auto iter = _spell_quest_status.find(spell_id);
|
||||||
if(iter != _spell_quest_status.end()) {
|
if (iter != _spell_quest_status.end()) {
|
||||||
//loaded or failed to load
|
//loaded or failed to load
|
||||||
if(iter->second != QuestFailedToLoad) {
|
if (iter->second != QuestFailedToLoad) {
|
||||||
auto qiter = _interfaces.find(iter->second);
|
auto qi = _interfaces.find(iter->second);
|
||||||
int ret = DispatchEventSpell(evt, npc, client, spell_id, data, extra_data, extra_pointers);
|
int ret = DispatchEventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers);
|
||||||
int i = qiter->second->EventSpell(evt, npc, client, spell_id, data, extra_data, extra_pointers);
|
int i = qi->second->EventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers);
|
||||||
if(i != 0) {
|
if (i != 0) {
|
||||||
ret = i;
|
ret = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return DispatchEventSpell(evt, npc, client, spell_id, data, extra_data, extra_pointers);
|
|
||||||
}
|
return DispatchEventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers);
|
||||||
else if (_spell_quest_status[spell_id] != QuestFailedToLoad) {
|
} else if (_spell_quest_status[spell_id] != QuestFailedToLoad) {
|
||||||
std::string filename;
|
std::string filename;
|
||||||
QuestInterface *qi = GetQIBySpellQuest(spell_id, filename);
|
QuestInterface *qi = GetQIBySpellQuest(spell_id, filename);
|
||||||
if (qi) {
|
if (qi) {
|
||||||
_spell_quest_status[spell_id] = qi->GetIdentifier();
|
_spell_quest_status[spell_id] = qi->GetIdentifier();
|
||||||
qi->LoadSpellScript(filename, spell_id);
|
qi->LoadSpellScript(filename, spell_id);
|
||||||
int ret = DispatchEventSpell(evt, npc, client, spell_id, data, extra_data, extra_pointers);
|
int ret = DispatchEventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers);
|
||||||
int i = qi->EventSpell(evt, npc, client, spell_id, data, extra_data, extra_pointers);
|
int i = qi->EventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers);
|
||||||
if (i != 0) {
|
if (i != 0) {
|
||||||
ret = i;
|
ret = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
_spell_quest_status[spell_id] = QuestFailedToLoad;
|
_spell_quest_status[spell_id] = QuestFailedToLoad;
|
||||||
return DispatchEventSpell(evt, npc, client, spell_id, data, extra_data, extra_pointers);
|
return DispatchEventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -1022,18 +1041,25 @@ int QuestParserCollection::DispatchEventItem(QuestEventID evt, Client *client, E
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int QuestParserCollection::DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
int QuestParserCollection::DispatchEventSpell(
|
||||||
std::vector<std::any> *extra_pointers) {
|
QuestEventID evt,
|
||||||
int ret = 0;
|
Mob* mob,
|
||||||
|
Client *client,
|
||||||
|
uint32 spell_id,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
int ret = 0;
|
||||||
auto iter = _load_precedence.begin();
|
auto iter = _load_precedence.begin();
|
||||||
while(iter != _load_precedence.end()) {
|
while(iter != _load_precedence.end()) {
|
||||||
int i = (*iter)->DispatchEventSpell(evt, npc, client, spell_id, data, extra_data, extra_pointers);
|
int i = (*iter)->DispatchEventSpell(evt, mob, client, spell_id, data, extra_data, extra_pointers);
|
||||||
if(i != 0) {
|
if(i != 0) {
|
||||||
ret = i;
|
ret = i;
|
||||||
}
|
}
|
||||||
++iter;
|
++iter;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings* perl_event_export_settings) {
|
void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings* perl_event_export_settings) {
|
||||||
@ -1074,3 +1100,228 @@ void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings*
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
int QuestParserCollection::DispatchEventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
int ret = 0;
|
||||||
|
auto iter = _load_precedence.begin();
|
||||||
|
while (iter != _load_precedence.end()) {
|
||||||
|
int i = (*iter)->DispatchEventBot(evt, bot, init, data, extra_data, extra_pointers);
|
||||||
|
if (i != 0) {
|
||||||
|
ret = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QuestParserCollection::EventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
auto rd = DispatchEventBot(evt, bot, init, data, extra_data, extra_pointers);
|
||||||
|
auto rl = EventBotLocal(evt, bot, init, data, extra_data, extra_pointers);
|
||||||
|
auto rg = EventBotGlobal(evt, bot, init, data, extra_data, extra_pointers);
|
||||||
|
|
||||||
|
//Local quests returning non-default values have priority over global quests
|
||||||
|
if (rl != 0) {
|
||||||
|
return rl;
|
||||||
|
} else if (rg != 0) {
|
||||||
|
return rg;
|
||||||
|
} else if (rd != 0) {
|
||||||
|
return rd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QuestParserCollection::EventBotLocal(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
if (_bot_quest_status == QuestUnloaded) {
|
||||||
|
std::string filename;
|
||||||
|
QuestInterface *qi = GetQIByBotQuest(filename);
|
||||||
|
if (qi) {
|
||||||
|
_bot_quest_status = qi->GetIdentifier();
|
||||||
|
qi->LoadBotScript(filename);
|
||||||
|
return qi->EventBot(evt, bot, init, data, extra_data, extra_pointers);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_bot_quest_status != QuestFailedToLoad) {
|
||||||
|
auto iter = _interfaces.find(_bot_quest_status);
|
||||||
|
return iter->second->EventBot(evt, bot, init, data, extra_data, extra_pointers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QuestParserCollection::EventBotGlobal(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
) {
|
||||||
|
if (_global_bot_quest_status == QuestUnloaded) {
|
||||||
|
std::string filename;
|
||||||
|
QuestInterface *qi = GetQIByGlobalBotQuest(filename);
|
||||||
|
if (qi) {
|
||||||
|
_global_bot_quest_status = qi->GetIdentifier();
|
||||||
|
qi->LoadGlobalBotScript(filename);
|
||||||
|
return qi->EventGlobalBot(evt, bot, init, data, extra_data, extra_pointers);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_global_bot_quest_status != QuestFailedToLoad) {
|
||||||
|
auto iter = _interfaces.find(_global_bot_quest_status);
|
||||||
|
return iter->second->EventGlobalBot(evt, bot, init, data, extra_data, extra_pointers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QuestParserCollection::BotHasQuestSubLocal(QuestEventID evt) {
|
||||||
|
if (_bot_quest_status == QuestUnloaded) {
|
||||||
|
std::string filename;
|
||||||
|
QuestInterface *qi = GetQIByBotQuest(filename);
|
||||||
|
if (qi) {
|
||||||
|
_bot_quest_status = qi->GetIdentifier();
|
||||||
|
qi->LoadBotScript(filename);
|
||||||
|
return qi->BotHasQuestSub(evt);
|
||||||
|
}
|
||||||
|
} else if (_bot_quest_status != QuestFailedToLoad) {
|
||||||
|
auto iter = _interfaces.find(_bot_quest_status);
|
||||||
|
return iter->second->BotHasQuestSub(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QuestParserCollection::BotHasQuestSubGlobal(QuestEventID evt) {
|
||||||
|
if (_global_bot_quest_status == QuestUnloaded) {
|
||||||
|
std::string filename;
|
||||||
|
QuestInterface *qi = GetQIByGlobalBotQuest(filename);
|
||||||
|
if (qi) {
|
||||||
|
_global_bot_quest_status = qi->GetIdentifier();
|
||||||
|
qi->LoadGlobalBotScript(filename);
|
||||||
|
return qi->GlobalBotHasQuestSub(evt);
|
||||||
|
}
|
||||||
|
} else if (_global_bot_quest_status != QuestFailedToLoad) {
|
||||||
|
auto iter = _interfaces.find(_global_bot_quest_status);
|
||||||
|
return iter->second->GlobalBotHasQuestSub(evt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestInterface *QuestParserCollection::GetQIByBotQuest(std::string &filename) {
|
||||||
|
if (!zone || !zone->IsLoaded()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first look for /quests/zone/bot_v[instance_version].ext (precedence)
|
||||||
|
filename = fmt::format("{}/{}/bot_v{}", path.GetQuestsPath(), zone->GetShortName(), zone->GetInstanceVersion());
|
||||||
|
std::string tmp;
|
||||||
|
FILE *f = nullptr;
|
||||||
|
|
||||||
|
auto iter = _load_precedence.begin();
|
||||||
|
while (iter != _load_precedence.end()) {
|
||||||
|
auto ext = _extensions.find((*iter)->GetIdentifier());
|
||||||
|
|
||||||
|
tmp = fmt::format("{}.{}", filename, ext->second);
|
||||||
|
|
||||||
|
f = fopen(tmp.c_str(), "r");
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
filename = tmp;
|
||||||
|
return (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// second look for /quests/zone/bot.ext (precedence)
|
||||||
|
filename = fmt::format("{}/{}/bot", path.GetQuestsPath(), zone->GetShortName());
|
||||||
|
|
||||||
|
iter = _load_precedence.begin();
|
||||||
|
while(iter != _load_precedence.end()) {
|
||||||
|
auto ext = _extensions.find((*iter)->GetIdentifier());
|
||||||
|
|
||||||
|
tmp = fmt::format("{}.{}", filename, ext->second);
|
||||||
|
|
||||||
|
f = fopen(tmp.c_str(), "r");
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
filename = tmp;
|
||||||
|
return (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// third look for /quests/global/bot.ext (precedence)
|
||||||
|
filename = fmt::format("{}/{}/bot", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY);
|
||||||
|
iter = _load_precedence.begin();
|
||||||
|
while (iter != _load_precedence.end()) {
|
||||||
|
auto ext = _extensions.find((*iter)->GetIdentifier());
|
||||||
|
|
||||||
|
tmp = fmt::format("{}.{}", filename, ext->second);
|
||||||
|
|
||||||
|
f = fopen(tmp.c_str(), "r");
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
filename = tmp;
|
||||||
|
return (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestInterface *QuestParserCollection::GetQIByGlobalBotQuest(std::string &filename) {
|
||||||
|
// first look for /quests/global/global_bot.ext (precedence)
|
||||||
|
filename = fmt::format("{}/{}/global_bot", path.GetQuestsPath(), QUEST_GLOBAL_DIRECTORY);
|
||||||
|
std::string tmp;
|
||||||
|
FILE *f = nullptr;
|
||||||
|
|
||||||
|
auto iter = _load_precedence.begin();
|
||||||
|
while (iter != _load_precedence.end()) {
|
||||||
|
auto ext = _extensions.find((*iter)->GetIdentifier());
|
||||||
|
|
||||||
|
tmp = fmt::format("{}.{}", filename, ext->second);
|
||||||
|
|
||||||
|
f = fopen(tmp.c_str(), "r");
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
filename = tmp;
|
||||||
|
return (*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@ -72,17 +72,32 @@ public:
|
|||||||
bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt, bool check_encounters = false);
|
bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt, bool check_encounters = false);
|
||||||
bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt, bool check_encounters = false);
|
bool ItemHasQuestSub(EQ::ItemInstance *itm, QuestEventID evt, bool check_encounters = false);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
bool BotHasQuestSub(QuestEventID evt);
|
||||||
|
#endif
|
||||||
|
|
||||||
int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int EventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers = nullptr);
|
std::vector<std::any> *extra_pointers = nullptr);
|
||||||
int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int EventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers = nullptr);
|
std::vector<std::any> *extra_pointers = nullptr);
|
||||||
int EventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
int EventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers = nullptr);
|
std::vector<std::any> *extra_pointers = nullptr);
|
||||||
int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
int EventSpell(QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers = nullptr);
|
std::vector<std::any> *extra_pointers = nullptr);
|
||||||
int EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
int EventEncounter(QuestEventID evt, std::string encounter_name, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers = nullptr);
|
std::vector<std::any> *extra_pointers = nullptr);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
int EventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers = nullptr
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
void GetErrors(std::list<std::string> &quest_errors);
|
void GetErrors(std::list<std::string> &quest_errors);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -117,11 +132,35 @@ private:
|
|||||||
bool ItemHasEncounterSub(EQ::ItemInstance* item, QuestEventID evt);
|
bool ItemHasEncounterSub(EQ::ItemInstance* item, QuestEventID evt);
|
||||||
bool HasEncounterSub(QuestEventID evt, const std::string& package_name);
|
bool HasEncounterSub(QuestEventID evt, const std::string& package_name);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
bool BotHasQuestSubLocal(QuestEventID evt);
|
||||||
|
bool BotHasQuestSubGlobal(QuestEventID evt);
|
||||||
|
#endif
|
||||||
|
|
||||||
int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers);
|
int EventNPCLocal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers);
|
||||||
int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers);
|
int EventNPCGlobal(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers);
|
||||||
int EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers);
|
int EventPlayerLocal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers);
|
||||||
int EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers);
|
int EventPlayerGlobal(QuestEventID evt, Client *client, std::string data, uint32 extra_data, std::vector<std::any> *extra_pointers);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
int EventBotLocal(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
int EventBotGlobal(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
QuestInterface *GetQIByNPCQuest(uint32 npcid, std::string &filename);
|
QuestInterface *GetQIByNPCQuest(uint32 npcid, std::string &filename);
|
||||||
QuestInterface *GetQIByGlobalNPCQuest(std::string &filename);
|
QuestInterface *GetQIByGlobalNPCQuest(std::string &filename);
|
||||||
QuestInterface *GetQIByPlayerQuest(std::string &filename);
|
QuestInterface *GetQIByPlayerQuest(std::string &filename);
|
||||||
@ -130,15 +169,31 @@ private:
|
|||||||
QuestInterface *GetQIByItemQuest(std::string item_script, std::string &filename);
|
QuestInterface *GetQIByItemQuest(std::string item_script, std::string &filename);
|
||||||
QuestInterface *GetQIByEncounterQuest(std::string encounter_name, std::string &filename);
|
QuestInterface *GetQIByEncounterQuest(std::string encounter_name, std::string &filename);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
QuestInterface *GetQIByBotQuest(std::string &filename);
|
||||||
|
QuestInterface *GetQIByGlobalBotQuest(std::string &filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
int DispatchEventNPC(QuestEventID evt, NPC* npc, Mob *init, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers);
|
std::vector<std::any> *extra_pointers);
|
||||||
int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
int DispatchEventPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers);
|
std::vector<std::any> *extra_pointers);
|
||||||
int DispatchEventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
int DispatchEventItem(QuestEventID evt, Client *client, EQ::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers);
|
std::vector<std::any> *extra_pointers);
|
||||||
int DispatchEventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
int DispatchEventSpell(QuestEventID evt, Mob* mob, Client *client, uint32 spell_id, std::string data, uint32 extra_data,
|
||||||
std::vector<std::any> *extra_pointers);
|
std::vector<std::any> *extra_pointers);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
int DispatchEventBot(
|
||||||
|
QuestEventID evt,
|
||||||
|
Bot *bot,
|
||||||
|
Mob *init,
|
||||||
|
std::string data,
|
||||||
|
uint32 extra_data,
|
||||||
|
std::vector<std::any> *extra_pointers
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
std::map<uint32, QuestInterface*> _interfaces;
|
std::map<uint32, QuestInterface*> _interfaces;
|
||||||
std::map<uint32, std::string> _extensions;
|
std::map<uint32, std::string> _extensions;
|
||||||
std::list<QuestInterface*> _load_precedence;
|
std::list<QuestInterface*> _load_precedence;
|
||||||
@ -149,6 +204,13 @@ private:
|
|||||||
uint32 _global_npc_quest_status;
|
uint32 _global_npc_quest_status;
|
||||||
uint32 _player_quest_status;
|
uint32 _player_quest_status;
|
||||||
uint32 _global_player_quest_status;
|
uint32 _global_player_quest_status;
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
uint32 _bot_quest_status;
|
||||||
|
uint32 _global_bot_quest_status;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
std::map<uint32, uint32> _spell_quest_status;
|
std::map<uint32, uint32> _spell_quest_status;
|
||||||
std::map<uint32, uint32> _item_quest_status;
|
std::map<uint32, uint32> _item_quest_status;
|
||||||
std::map<std::string, uint32> _encounter_quest_status;
|
std::map<std::string, uint32> _encounter_quest_status;
|
||||||
|
|||||||
@ -94,10 +94,15 @@ void QuestManager::Process() {
|
|||||||
parse->EventNPC(EVENT_TIMER, cur->mob->CastToNPC(), nullptr, cur->name, 0);
|
parse->EventNPC(EVENT_TIMER, cur->mob->CastToNPC(), nullptr, cur->name, 0);
|
||||||
} else if (cur->mob->IsEncounter()) {
|
} else if (cur->mob->IsEncounter()) {
|
||||||
parse->EventEncounter(EVENT_TIMER, cur->mob->CastToEncounter()->GetEncounterName(), cur->name, 0, nullptr);
|
parse->EventEncounter(EVENT_TIMER, cur->mob->CastToEncounter()->GetEncounterName(), cur->name, 0, nullptr);
|
||||||
} else {
|
} else if (cur->mob->IsClient()) {
|
||||||
//this is inheriently unsafe if we ever make it so more than npc/client start timers
|
//this is inheriently unsafe if we ever make it so more than npc/client start timers
|
||||||
parse->EventPlayer(EVENT_TIMER, cur->mob->CastToClient(), cur->name, 0);
|
parse->EventPlayer(EVENT_TIMER, cur->mob->CastToClient(), cur->name, 0);
|
||||||
}
|
}
|
||||||
|
#ifdef BOTS
|
||||||
|
else if (cur->mob->IsBot()) {
|
||||||
|
parse->EventBot(EVENT_TIMER, cur->mob->CastToBot(), nullptr, cur->name, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//we MUST reset our iterator since the quest could have removed/added any
|
//we MUST reset our iterator since the quest could have removed/added any
|
||||||
//number of timers... worst case we have to check a bunch of timers twice
|
//number of timers... worst case we have to check a bunch of timers twice
|
||||||
@ -3395,6 +3400,17 @@ NPC *QuestManager::GetNPC() const {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
Bot *QuestManager::GetBot() const {
|
||||||
|
if (!quests_running_.empty()) {
|
||||||
|
running_quest e = quests_running_.top();
|
||||||
|
return (e.owner && e.owner->IsBot()) ? e.owner->CastToBot() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Mob *QuestManager::GetOwner() const {
|
Mob *QuestManager::GetOwner() const {
|
||||||
if(!quests_running_.empty()) {
|
if(!quests_running_.empty()) {
|
||||||
running_quest e = quests_running_.top();
|
running_quest e = quests_running_.top();
|
||||||
@ -3653,7 +3669,7 @@ void QuestManager::CrossZoneSetEntityVariable(uint8 update_type, int update_iden
|
|||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuestManager::CrossZoneSignal(uint8 update_type, int update_identifier, uint32 signal, const char* client_name) {
|
void QuestManager::CrossZoneSignal(uint8 update_type, int update_identifier, int signal, const char* client_name) {
|
||||||
auto pack = new ServerPacket(ServerOP_CZSignal, sizeof(CZSignal_Struct));
|
auto pack = new ServerPacket(ServerOP_CZSignal, sizeof(CZSignal_Struct));
|
||||||
CZSignal_Struct* CZS = (CZSignal_Struct*)pack->pBuffer;
|
CZSignal_Struct* CZS = (CZSignal_Struct*)pack->pBuffer;
|
||||||
CZS->update_type = update_type;
|
CZS->update_type = update_type;
|
||||||
@ -3763,7 +3779,7 @@ void QuestManager::WorldWideSetEntityVariable(uint8 update_type, const char* var
|
|||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuestManager::WorldWideSignal(uint8 update_type, uint32 signal, uint8 min_status, uint8 max_status) {
|
void QuestManager::WorldWideSignal(uint8 update_type, int signal, uint8 min_status, uint8 max_status) {
|
||||||
auto pack = new ServerPacket(ServerOP_WWSignal, sizeof(WWSignal_Struct));
|
auto pack = new ServerPacket(ServerOP_WWSignal, sizeof(WWSignal_Struct));
|
||||||
WWSignal_Struct* WWS = (WWSignal_Struct*)pack->pBuffer;
|
WWSignal_Struct* WWS = (WWSignal_Struct*)pack->pBuffer;
|
||||||
WWS->update_type = update_type;
|
WWS->update_type = update_type;
|
||||||
|
|||||||
@ -311,7 +311,7 @@ public:
|
|||||||
void CrossZoneMessage(uint8 update_type, int update_identifier, uint32 type, const char* message, const char* client_name = "");
|
void CrossZoneMessage(uint8 update_type, int update_identifier, uint32 type, const char* message, const char* client_name = "");
|
||||||
void CrossZoneMove(uint8 update_type, uint8 update_subtype, int update_identifier, const char* zone_short_name, uint16 instance_id, const char* client_name = "");
|
void CrossZoneMove(uint8 update_type, uint8 update_subtype, int update_identifier, const char* zone_short_name, uint16 instance_id, const char* client_name = "");
|
||||||
void CrossZoneSetEntityVariable(uint8 update_type, int update_identifier, const char* variable_name, const char* variable_value, const char* client_name = "");
|
void CrossZoneSetEntityVariable(uint8 update_type, int update_identifier, const char* variable_name, const char* variable_value, const char* client_name = "");
|
||||||
void CrossZoneSignal(uint8 update_type, int update_identifier, uint32 signal, const char* client_name = "");
|
void CrossZoneSignal(uint8 update_type, int update_identifier, int signal, const char* client_name = "");
|
||||||
void CrossZoneSpell(uint8 update_type, uint8 update_subtype, int update_identifier, uint32 spell_id, const char* client_name = "");
|
void CrossZoneSpell(uint8 update_type, uint8 update_subtype, int update_identifier, uint32 spell_id, const char* client_name = "");
|
||||||
void CrossZoneTaskUpdate(uint8 update_type, uint8 update_subtype, int update_identifier, uint32 task_identifier, int task_subidentifier = -1, int update_count = 1, bool enforce_level_requirement = false, const char* client_name = "");
|
void CrossZoneTaskUpdate(uint8 update_type, uint8 update_subtype, int update_identifier, uint32 task_identifier, int task_subidentifier = -1, int update_count = 1, bool enforce_level_requirement = false, const char* client_name = "");
|
||||||
void WorldWideDialogueWindow(const char* message, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
void WorldWideDialogueWindow(const char* message, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
||||||
@ -320,7 +320,7 @@ public:
|
|||||||
void WorldWideMessage(uint32 type, const char* message, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
void WorldWideMessage(uint32 type, const char* message, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
||||||
void WorldWideMove(uint8 update_type, const char* zone_short_name, uint16 instance_id = 0, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
void WorldWideMove(uint8 update_type, const char* zone_short_name, uint16 instance_id = 0, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
||||||
void WorldWideSetEntityVariable(uint8 update_type, const char* variable_name, const char* variable_value, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
void WorldWideSetEntityVariable(uint8 update_type, const char* variable_name, const char* variable_value, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
||||||
void WorldWideSignal(uint8 update_type, uint32 signal, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
void WorldWideSignal(uint8 update_type, int signal, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
||||||
void WorldWideSpell(uint8 update_type, uint32 spell_id, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
void WorldWideSpell(uint8 update_type, uint32 spell_id, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
||||||
void WorldWideTaskUpdate(uint8 update_type, uint32 task_identifier, int task_subidentifier = -1, int update_count = 1, bool enforce_level_requirement = false, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
void WorldWideTaskUpdate(uint8 update_type, uint32 task_identifier, int task_subidentifier = -1, int update_count = 1, bool enforce_level_requirement = false, uint8 min_status = AccountStatus::Player, uint8 max_status = AccountStatus::Player);
|
||||||
bool EnableRecipe(uint32 recipe_id);
|
bool EnableRecipe(uint32 recipe_id);
|
||||||
@ -345,6 +345,10 @@ public:
|
|||||||
std::string GetRecipeName(uint32 recipe_id);
|
std::string GetRecipeName(uint32 recipe_id);
|
||||||
bool HasRecipeLearned(uint32 recipe_id);
|
bool HasRecipeLearned(uint32 recipe_id);
|
||||||
|
|
||||||
|
#ifdef BOTS
|
||||||
|
Bot *GetBot() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
Client *GetInitiator() const;
|
Client *GetInitiator() const;
|
||||||
NPC *GetNPC() const;
|
NPC *GetNPC() const;
|
||||||
Mob *GetOwner() const;
|
Mob *GetOwner() const;
|
||||||
|
|||||||
@ -175,10 +175,17 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (IsNPC()) {
|
} else if (IsNPC()) {
|
||||||
if (parse->EventSpell(EVENT_SPELL_EFFECT_NPC, CastToNPC(), nullptr, spell_id, export_string, 0) != 0) {
|
if (parse->EventSpell(EVENT_SPELL_EFFECT_NPC, this, nullptr, spell_id, export_string, 0) != 0) {
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (IsBot()) {
|
||||||
|
if (parse->EventSpell(EVENT_SPELL_EFFECT_BOT, this, nullptr, spell_id, export_string, 0) != 0) {
|
||||||
|
CalcBonuses();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsVirusSpell(spell_id)) {
|
if(IsVirusSpell(spell_id)) {
|
||||||
@ -3782,9 +3789,15 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (IsNPC()) {
|
} else if (IsNPC()) {
|
||||||
if (parse->EventSpell(EVENT_SPELL_EFFECT_BUFF_TIC_NPC, CastToNPC(), nullptr, buff.spellid, export_string, 0) != 0) {
|
if (parse->EventSpell(EVENT_SPELL_EFFECT_BUFF_TIC_NPC, this, nullptr, buff.spellid, export_string, 0) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (IsBot()) {
|
||||||
|
if (parse->EventSpell(EVENT_SPELL_EFFECT_BUFF_TIC_BOT, this, nullptr, buff.spellid, export_string, 0) != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < EFFECT_COUNT; i++) {
|
for (int i = 0; i < EFFECT_COUNT; i++) {
|
||||||
@ -4129,9 +4142,15 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (IsNPC()) {
|
} else if (IsNPC()) {
|
||||||
if (parse->EventSpell(EVENT_SPELL_FADE, CastToNPC(), nullptr, buffs[slot].spellid, export_string, 0) != 0) {
|
if (parse->EventSpell(EVENT_SPELL_FADE, this, nullptr, buffs[slot].spellid, export_string, 0) != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (IsBot()) {
|
||||||
|
if (parse->EventSpell(EVENT_SPELL_FADE, this, nullptr, buffs[slot].spellid, export_string, 0) != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i < EFFECT_COUNT; i++)
|
for (int i=0; i < EFFECT_COUNT; i++)
|
||||||
|
|||||||
@ -245,17 +245,21 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
|
|||||||
GetID(),
|
GetID(),
|
||||||
GetCasterLevel(spell_id)
|
GetCasterLevel(spell_id)
|
||||||
);
|
);
|
||||||
if(IsClient()) {
|
if (IsClient()) {
|
||||||
if (parse->EventPlayer(EVENT_CAST_BEGIN, CastToClient(), export_string, 0) != 0) {
|
if (parse->EventPlayer(EVENT_CAST_BEGIN, CastToClient(), export_string, 0) != 0) {
|
||||||
if (IsDiscipline(spell_id)) {
|
if (IsDiscipline(spell_id)) {
|
||||||
CastToClient()->SendDisciplineTimer(spells[spell_id].timer_id, 0);
|
CastToClient()->SendDisciplineTimer(spells[spell_id].timer_id, 0);
|
||||||
} else {
|
} else {
|
||||||
CastToClient()->SendSpellBarEnable(spell_id);
|
CastToClient()->SendSpellBarEnable(spell_id);
|
||||||
}
|
}
|
||||||
return(false);
|
return false;
|
||||||
}
|
}
|
||||||
} else if(IsNPC()) {
|
} else if (IsNPC()) {
|
||||||
parse->EventNPC(EVENT_CAST_BEGIN, CastToNPC(), nullptr, export_string, 0);
|
parse->EventNPC(EVENT_CAST_BEGIN, CastToNPC(), nullptr, export_string, 0);
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (IsBot()) {
|
||||||
|
parse->EventBot(EVENT_CAST_BEGIN, CastToBot(), nullptr, export_string, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//To prevent NPC ghosting when spells are cast from scripts
|
//To prevent NPC ghosting when spells are cast from scripts
|
||||||
@ -1666,10 +1670,14 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo
|
|||||||
GetID(),
|
GetID(),
|
||||||
GetCasterLevel(spell_id)
|
GetCasterLevel(spell_id)
|
||||||
);
|
);
|
||||||
if(IsClient()) {
|
if (IsClient()) {
|
||||||
parse->EventPlayer(EVENT_CAST, CastToClient(), export_string, 0);
|
parse->EventPlayer(EVENT_CAST, CastToClient(), export_string, 0);
|
||||||
} else if(IsNPC()) {
|
} else if (IsNPC()) {
|
||||||
parse->EventNPC(EVENT_CAST, CastToNPC(), nullptr, export_string, 0);
|
parse->EventNPC(EVENT_CAST, CastToNPC(), nullptr, export_string, 0);
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (IsBot()) {
|
||||||
|
parse->EventBot(EVENT_CAST, CastToBot(), nullptr, export_string, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bard_song_mode)
|
if(bard_song_mode)
|
||||||
@ -3628,8 +3636,13 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, int reflect_effectivenes
|
|||||||
parse->EventNPC(EVENT_CAST_ON, spelltar->CastToNPC(), this, export_string, 0);
|
parse->EventNPC(EVENT_CAST_ON, spelltar->CastToNPC(), this, export_string, 0);
|
||||||
} else if (spelltar->IsClient()) {
|
} else if (spelltar->IsClient()) {
|
||||||
parse->EventPlayer(EVENT_CAST_ON, spelltar->CastToClient(), export_string, 0);
|
parse->EventPlayer(EVENT_CAST_ON, spelltar->CastToClient(), export_string, 0);
|
||||||
|
#ifdef BOTS
|
||||||
|
} else if (spelltar->IsBot()) {
|
||||||
|
parse->EventBot(EVENT_CAST_ON, spelltar->CastToBot(), this, export_string, 0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mod_spell_cast(spell_id, spelltar, reflect_effectiveness, use_resist_adjust, resist_adjust, isproc);
|
mod_spell_cast(spell_id, spelltar, reflect_effectiveness, use_resist_adjust, resist_adjust, isproc);
|
||||||
|
|
||||||
if (!DoCastingChecksOnTarget(false, spell_id, spelltar)) {
|
if (!DoCastingChecksOnTarget(false, spell_id, spelltar)) {
|
||||||
|
|||||||
@ -2614,7 +2614,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
CZSignal_Struct* CZS = (CZSignal_Struct*) pack->pBuffer;
|
CZSignal_Struct* CZS = (CZSignal_Struct*) pack->pBuffer;
|
||||||
uint8 update_type = CZS->update_type;
|
uint8 update_type = CZS->update_type;
|
||||||
int update_identifier = CZS->update_identifier;
|
int update_identifier = CZS->update_identifier;
|
||||||
uint32 signal = CZS->signal;
|
int signal = CZS->signal;
|
||||||
const char* client_name = CZS->client_name;
|
const char* client_name = CZS->client_name;
|
||||||
if (update_type == CZUpdateType_Character) {
|
if (update_type == CZUpdateType_Character) {
|
||||||
auto client = entity_list.GetClientByCharID(update_identifier);
|
auto client = entity_list.GetClientByCharID(update_identifier);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user