diff --git a/zone/bot.cpp b/zone/bot.cpp index e1d0e0652..fcf3669d7 100644 --- a/zone/bot.cpp +++ b/zone/bot.cpp @@ -26,6 +26,7 @@ #include "../common/strings.h" #include "../common/say_link.h" #include "../common/repositories/bot_spell_settings_repository.h" +#include "../common/data_verification.h" extern volatile bool is_zone_loaded; @@ -10915,6 +10916,169 @@ void Bot::SetBotArcherySetting(bool bot_archer_setting, bool save) } } +std::vector Bot::GetApplySpellList( + ApplySpellType apply_type, + bool allow_pets, + bool is_raid_group_only +) { + std::vector l; + + if (apply_type == ApplySpellType::Raid && IsRaidGrouped()) { + auto* r = GetRaid(); + auto group_id = r->GetGroup(this->GetCleanName()); + if (r && EQ::ValueWithin(group_id, 0, (MAX_RAID_GROUPS - 1))) { + for (auto i = 0; i < MAX_RAID_MEMBERS; i++) { + auto* m = r->members[i].member; + if (m && m->IsClient() && (!is_raid_group_only || r->GetGroup(m) == group_id)) { + l.push_back(m); + + if (allow_pets && m->HasPet()) { + l.push_back(m->GetPet()); + } + + const auto& sbl = entity_list.GetBotListByCharacterID(m->CharacterID()); + for (const auto& b : sbl) { + l.push_back(b); + } + } + } + } + } else if (apply_type == ApplySpellType::Group && IsGrouped()) { + auto* g = GetGroup(); + if (g) { + for (auto i = 0; i < MAX_GROUP_MEMBERS; i++) { + auto* m = g->members[i]; + if (m && m->IsClient()) { + l.push_back(m->CastToClient()); + + if (allow_pets && m->HasPet()) { + l.push_back(m->GetPet()); + } + const auto& sbl = entity_list.GetBotListByCharacterID(m->CastToClient()->CharacterID()); + for (const auto& b : sbl) { + l.push_back(b); + } + } + } + } + } else { + l.push_back(this); + + if (allow_pets && HasPet()) { + l.push_back(GetPet()); + } + const auto& sbl = entity_list.GetBotListByCharacterID(CharacterID()); + for (const auto& b : sbl) { + l.push_back(b); + } + } + + return l; +} + +void Bot::ApplySpell( + int spell_id, + int duration, + ApplySpellType apply_type, + bool allow_pets, + bool is_raid_group_only +) { + const auto& l = GetApplySpellList(apply_type, allow_pets, is_raid_group_only); + + for (const auto& m : l) { + m->ApplySpellBuff(spell_id, duration); + } +} + +void Bot::SetSpellDuration( + int spell_id, + int duration, + ApplySpellType apply_type, + bool allow_pets, + bool is_raid_group_only +) { + const auto& l = GetApplySpellList(apply_type, allow_pets, is_raid_group_only); + + for (const auto& m : l) { + m->SetBuffDuration(spell_id, duration); + } +} + +void Bot::Escape() +{ + entity_list.RemoveFromTargets(this, true); + SetInvisible(Invisibility::Invisible); +} + +void Bot::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls, bool calculate_speed) { + BuffFadeByEffect(SE_Levitate); + if (CheckLosFN(target_x, target_y, target_z, 6.0f) || ignore_los) { + auto p = new EQApplicationPacket(OP_Fling, sizeof(fling_struct)); + auto* f = (fling_struct*) p->pBuffer; + + if (!calculate_speed) { + f->speed_z = value; + } else { + auto speed = 1.0f; + const auto distance = CalculateDistance(target_x, target_y, target_z); + + auto z_diff = target_z - GetZ(); + if (z_diff != 0.0f) { + speed += std::abs(z_diff) / 12.0f; + } + + speed += distance / 200.0f; + + speed++; + + speed = std::abs(speed); + + f->speed_z = speed; + } + + f->collision = clip_through_walls ? 0 : -1; + f->travel_time = -1; + f->unk3 = 1; + f->disable_fall_damage = 1; + f->new_y = target_y; + f->new_x = target_x; + f->new_z = target_z; + p->priority = 6; + GetBotOwner()->CastToClient()->FastQueuePacket(&p); + } +} + +// This should return the combined AC of all the items the Bot is wearing. +int32 Bot::GetRawItemAC() +{ + int32 Total = 0; + // this skips MainAmmo..add an '=' conditional if that slot is required (original behavior) + for (int16 slot_id = EQ::invslot::BONUS_BEGIN; slot_id <= EQ::invslot::BONUS_STAT_END; slot_id++) { + const EQ::ItemInstance* inst = m_inv[slot_id]; + if (inst && inst->IsClassCommon()) { + Total += inst->GetItem()->AC; + } + } + return Total; +} + +void Bot::SendSpellAnim(uint16 targetid, uint16 spell_id) +{ + if (!targetid || !IsValidSpell(spell_id)) + return; + + EQApplicationPacket app(OP_Action, sizeof(Action_Struct)); + Action_Struct* a = (Action_Struct*)app.pBuffer; + a->target = targetid; + a->source = GetID(); + a->type = 231; + a->spell = spell_id; + a->hit_heading = GetHeading(); + + app.priority = 1; + entity_list.QueueCloseClients(this, &app, false, RuleI(Range, SpellParticles)); +} + uint8 Bot::spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND] = { 0 }; #endif diff --git a/zone/bot.h b/zone/bot.h index 2f4718f85..7113879f8 100644 --- a/zone/bot.h +++ b/zone/bot.h @@ -389,7 +389,7 @@ public: void EquipBot(std::string* error_message); bool CheckLoreConflict(const EQ::ItemData* item); virtual void UpdateEquipmentLight() { m_Light.Type[EQ::lightsource::LightEquipment] = m_inv.FindBrightestLightType(); m_Light.Level[EQ::lightsource::LightEquipment] = EQ::lightsource::TypeToLevel(m_Light.Type[EQ::lightsource::LightEquipment]); } - const EQ::InventoryProfile& GetBotInv() const { return m_inv; } + inline EQ::InventoryProfile& GetBotInv() { return m_inv; } // Static Class Methods //static void DestroyBotRaidObjects(Client* client); // Can be removed after bot raids are dumped @@ -581,6 +581,16 @@ public: // "Quest API" Methods bool HasBotSpellEntry(uint16 spellid); + void ApplySpell(int spell_id, int duration = 0, ApplySpellType apply_type = ApplySpellType::Solo, bool allow_pets = false, bool is_raid_group_only = true); + void BreakInvis(); + void Escape(); + void Fling(float value, float target_x, float target_y, float target_z, bool ignore_los = false, bool clip_through_walls = false, bool calculate_speed = false); + std::vector GetApplySpellList(ApplySpellType apply_type, bool allow_pets, bool is_raid_group_only); + int32 GetItemIDAt(int16 slot_id); + int32 GetAugmentIDAt(int16 slot_id, uint8 augslot); + int32 GetRawItemAC(); + void SendSpellAnim(uint16 targetid, uint16 spell_id); + void SetSpellDuration(int spell_id, int duration = 0, ApplySpellType apply_type = ApplySpellType::Solo, bool allow_pets = false, bool is_raid_group_only = true); // "SET" Class Methods void SetBotSpellID(uint32 newSpellID); diff --git a/zone/inventory.cpp b/zone/inventory.cpp index 8376b9f9f..c1115cdbb 100644 --- a/zone/inventory.cpp +++ b/zone/inventory.cpp @@ -25,6 +25,10 @@ #include "zonedb.h" #include "../common/zone_store.h" +#ifdef BOTS +#include "bot.h" +#endif + extern WorldServer worldserver; // @merth: this needs to be touched up @@ -4204,3 +4208,66 @@ int EQ::InventoryProfile::GetItemStatValue(uint32 item_id, const char* identifie safe_delete(inst); return stat; } + +#ifdef BOTS +// Returns a slot's item ID (returns INVALID_ID if not found) +int32 Bot::GetItemIDAt(int16 slot_id) { + if (slot_id <= EQ::invslot::POSSESSIONS_END && slot_id >= EQ::invslot::POSSESSIONS_BEGIN) { + if ((((uint64)1 << slot_id) & GetBotInv().GetLookup()->PossessionsBitmask) == 0) + return INVALID_ID; + } + else if (slot_id <= EQ::invbag::GENERAL_BAGS_END && slot_id >= EQ::invbag::GENERAL_BAGS_BEGIN) { + auto temp_slot = EQ::invslot::GENERAL_BEGIN + ((slot_id - EQ::invbag::GENERAL_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT); + if ((((uint64)1 << temp_slot) & GetBotInv().GetLookup()->PossessionsBitmask) == 0) + return INVALID_ID; + } + else if (slot_id <= EQ::invslot::BANK_END && slot_id >= EQ::invslot::BANK_BEGIN) { + if ((slot_id - EQ::invslot::BANK_BEGIN) >= GetBotInv().GetLookup()->InventoryTypeSize.Bank) + return INVALID_ID; + } + else if (slot_id <= EQ::invbag::BANK_BAGS_END && slot_id >= EQ::invbag::BANK_BAGS_BEGIN) { + auto temp_slot = (slot_id - EQ::invbag::BANK_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT; + if (temp_slot >= GetBotInv().GetLookup()->InventoryTypeSize.Bank) + return INVALID_ID; + } + + const EQ::ItemInstance* inst = m_inv[slot_id]; + if (inst) + return inst->GetItem()->ID; + + // None found + return INVALID_ID; +} + +// Returns an augment's ID that's in an item (returns INVALID_ID if not found) +// Pass in the slot ID of the item and which augslot you want to check (0-5) +int32 Bot::GetAugmentIDAt(int16 slot_id, uint8 augslot) { + if (slot_id <= EQ::invslot::POSSESSIONS_END && slot_id >= EQ::invslot::POSSESSIONS_BEGIN) { + if ((((uint64)1 << slot_id) & GetBotInv().GetLookup()->PossessionsBitmask) == 0) + return INVALID_ID; + } + else if (slot_id <= EQ::invbag::GENERAL_BAGS_END && slot_id >= EQ::invbag::GENERAL_BAGS_BEGIN) { + auto temp_slot = EQ::invslot::GENERAL_BEGIN + ((slot_id - EQ::invbag::GENERAL_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT); + if ((((uint64)1 << temp_slot) & GetBotInv().GetLookup()->PossessionsBitmask) == 0) + return INVALID_ID; + } + else if (slot_id <= EQ::invslot::BANK_END && slot_id >= EQ::invslot::BANK_BEGIN) { + if ((slot_id - EQ::invslot::BANK_BEGIN) >= GetBotInv().GetLookup()->InventoryTypeSize.Bank) + return INVALID_ID; + } + else if (slot_id <= EQ::invbag::BANK_BAGS_END && slot_id >= EQ::invbag::BANK_BAGS_BEGIN) { + auto temp_slot = (slot_id - EQ::invbag::BANK_BAGS_BEGIN) / EQ::invbag::SLOT_COUNT; + if (temp_slot >= GetBotInv().GetLookup()->InventoryTypeSize.Bank) + return INVALID_ID; + } + + const EQ::ItemInstance* inst = m_inv[slot_id]; + if (inst && inst->GetAugmentItemID(augslot)) { + return inst->GetAugmentItemID(augslot); + } + + // None found + return INVALID_ID; +} + +#endif diff --git a/zone/lua_bot.cpp b/zone/lua_bot.cpp index 442a2058f..7d9396a81 100644 --- a/zone/lua_bot.cpp +++ b/zone/lua_bot.cpp @@ -8,6 +8,7 @@ #include "lua_bot.h" #include "lua_iteminst.h" #include "lua_mob.h" +#include "lua_group.h" void Lua_Bot::AddBotItem(uint16 slot_id, uint32 item_id) { Lua_Safe_Call_Void(); @@ -144,6 +145,216 @@ void Lua_Bot::SendPayload(int payload_id, std::string payload_value) { self->SendPayload(payload_id, payload_value); } +void Lua_Bot::ApplySpell(int spell_id) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id); +} + +void Lua_Bot::ApplySpell(int spell_id, int duration) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration); +} + +void Lua_Bot::ApplySpell(int spell_id, int duration, bool allow_pets) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets); +} + +void Lua_Bot::ApplySpellGroup(int spell_id) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, 0, ApplySpellType::Group); +} + +void Lua_Bot::ApplySpellGroup(int spell_id, int duration) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Group); +} + +void Lua_Bot::ApplySpellGroup(int spell_id, int duration, bool allow_pets) { + Lua_Safe_Call_Void(); + self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets); +} + +void Lua_Bot::SetSpellDuration(int spell_id) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id); +} + +void Lua_Bot::SetSpellDuration(int spell_id, int duration) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration); +} + +void Lua_Bot::SetSpellDuration(int spell_id, int duration, bool allow_pets) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets); +} + +void Lua_Bot::SetSpellDurationGroup(int spell_id) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, 0, ApplySpellType::Group); +} + +void Lua_Bot::SetSpellDurationGroup(int spell_id, int duration) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group); +} + +void Lua_Bot::SetSpellDurationGroup(int spell_id, int duration, bool allow_pets) { + Lua_Safe_Call_Void(); + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets); +} + +int Lua_Bot::CountAugmentEquippedByID(uint32 item_id) { + Lua_Safe_Call_Int(); + return self->GetBotInv().CountAugmentEquippedByID(item_id); +} + +bool Lua_Bot::HasAugmentEquippedByID(uint32 item_id) { + Lua_Safe_Call_Bool(); + return self->GetBotInv().HasAugmentEquippedByID(item_id); +} + +int Lua_Bot::CountItemEquippedByID(uint32 item_id) { + Lua_Safe_Call_Int(); + return self->GetBotInv().CountItemEquippedByID(item_id); +} + +bool Lua_Bot::HasItemEquippedByID(uint32 item_id) { + Lua_Safe_Call_Bool(); + return self->GetBotInv().HasItemEquippedByID(item_id); +} + +void Lua_Bot::Escape() { + Lua_Safe_Call_Void(); + self->Escape(); +} + +void Lua_Bot::Fling(float target_x, float target_y, float target_z) { + Lua_Safe_Call_Void(); + self->Fling(0, target_x, target_y, target_z, false, false, true); +} + +void Lua_Bot::Fling(float target_x, float target_y, float target_z, bool ignore_los) { + Lua_Safe_Call_Void(); + self->Fling(0, target_x, target_y, target_z, ignore_los, false, true); +} + +void Lua_Bot::Fling(float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls) { + Lua_Safe_Call_Void(); + self->Fling(0, target_x, target_y, target_z, ignore_los, clip_through_walls, true); +} + +void Lua_Bot::Fling(float value, float target_x, float target_y, float target_z) { + Lua_Safe_Call_Void(); + self->Fling(value, target_x, target_y, target_z); +} + +void Lua_Bot::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los) { + Lua_Safe_Call_Void(); + self->Fling(value, target_x, target_y, target_z, ignore_los); +} + +void Lua_Bot::Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls) { + Lua_Safe_Call_Void(); + self->Fling(value, target_x, target_y, target_z, ignore_los, clip_through_walls); +} + +int Lua_Bot::GetItemIDAt(int slot_id) { + Lua_Safe_Call_Int(); + return self->GetItemIDAt(slot_id); +} + +int Lua_Bot::GetAugmentIDAt(int slot_id, int aug_slot) { + Lua_Safe_Call_Int(); + return self->GetAugmentIDAt(slot_id, aug_slot); +} + +int Lua_Bot::GetBaseSTR() { + Lua_Safe_Call_Int(); + return self->GetBaseSTR(); +} + +int Lua_Bot::GetBaseSTA() { + Lua_Safe_Call_Int(); + return self->GetBaseSTA(); +} + +int Lua_Bot::GetBaseCHA() { + Lua_Safe_Call_Int(); + return self->GetBaseCHA(); +} + +int Lua_Bot::GetBaseDEX() { + Lua_Safe_Call_Int(); + return self->GetBaseDEX(); +} + +int Lua_Bot::GetBaseINT() { + Lua_Safe_Call_Int(); + return self->GetBaseINT(); +} + +int Lua_Bot::GetBaseAGI() { + Lua_Safe_Call_Int(); + return self->GetBaseAGI(); +} + +int Lua_Bot::GetBaseWIS() { + Lua_Safe_Call_Int(); + return self->GetBaseWIS(); +} + +Lua_Group Lua_Bot::GetGroup() { + Lua_Safe_Call_Class(Lua_Group); + return self->GetGroup(); +} + +int Lua_Bot::GetHealAmount() { + Lua_Safe_Call_Int(); + return self->GetHealAmt(); +} + +int Lua_Bot::GetSpellDamage() { + Lua_Safe_Call_Int(); + return self->GetSpellDmg(); +} + +int Lua_Bot::GetInstrumentMod(int spell_id) { + Lua_Safe_Call_Int(); + return self->GetInstrumentMod(spell_id); +} + +int Lua_Bot::GetRawItemAC() { + Lua_Safe_Call_Int(); + return self->GetRawItemAC(); +} + +bool Lua_Bot::IsGrouped() { + Lua_Safe_Call_Bool(); + return self->IsGrouped(); +} + +bool Lua_Bot::IsStanding() { + Lua_Safe_Call_Bool(); + return self->IsStanding(); +} + +bool Lua_Bot::IsSitting() { + Lua_Safe_Call_Bool(); + return self->IsSitting(); +} + +void Lua_Bot::Sit() { + Lua_Safe_Call_Void(); + self->Sit(); +} + +void Lua_Bot::Stand() { + Lua_Safe_Call_Void(); + self->Stand(); +} + luabind::scope lua_register_bot() { return luabind::class_("Bot") .def(luabind::constructor<>()) @@ -156,13 +367,45 @@ luabind::scope lua_register_bot() { .def("AddBotItem", (void(Lua_Bot::*)(uint16,uint32,int16,bool,uint32,uint32,uint32,uint32))&Lua_Bot::AddBotItem) .def("AddBotItem", (void(Lua_Bot::*)(uint16,uint32,int16,bool,uint32,uint32,uint32,uint32,uint32))&Lua_Bot::AddBotItem) .def("AddBotItem", (void(Lua_Bot::*)(uint16,uint32,int16,bool,uint32,uint32,uint32,uint32,uint32,uint32))&Lua_Bot::AddBotItem) + .def("ApplySpell", (void(Lua_Bot::*)(int))&Lua_Bot::ApplySpell) + .def("ApplySpell", (void(Lua_Bot::*)(int,int))&Lua_Bot::ApplySpell) + .def("ApplySpell", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::ApplySpell) + .def("ApplySpellGroup", (void(Lua_Bot::*)(int))&Lua_Bot::ApplySpellGroup) + .def("ApplySpellGroup", (void(Lua_Bot::*)(int,int))&Lua_Bot::ApplySpellGroup) + .def("ApplySpellGroup", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::ApplySpellGroup) .def("CountBotItem", (uint32(Lua_Bot::*)(uint32))&Lua_Bot::CountBotItem) + .def("CountItemEquippedByID", (int(Lua_Bot::*)(uint32))&Lua_Bot::CountItemEquippedByID) + .def("Escape", (void(Lua_Bot::*)(void))&Lua_Bot::Escape) + .def("Fling", (void(Lua_Bot::*)(float,float,float))&Lua_Bot::Fling) + .def("Fling", (void(Lua_Bot::*)(float,float,float,bool))&Lua_Bot::Fling) + .def("Fling", (void(Lua_Bot::*)(float,float,float,bool,bool))&Lua_Bot::Fling) + .def("Fling", (void(Lua_Bot::*)(float,float,float,float))&Lua_Bot::Fling) + .def("Fling", (void(Lua_Bot::*)(float,float,float,float,bool))&Lua_Bot::Fling) + .def("Fling", (void(Lua_Bot::*)(float,float,float,float,bool,bool))&Lua_Bot::Fling) + .def("GetAugmentIDAt", (int(Lua_Bot::*)(int,int))&Lua_Bot::GetAugmentIDAt) + .def("GetBaseAGI", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseAGI) + .def("GetBaseCHA", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseCHA) + .def("GetBaseDEX", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseDEX) + .def("GetBaseINT", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseINT) + .def("GetBaseSTA", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseSTA) + .def("GetBaseSTR", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseSTR) + .def("GetBaseWIS", (int(Lua_Bot::*)(void))&Lua_Bot::GetBaseWIS) .def("GetBotItem", (Lua_ItemInst(Lua_Bot::*)(uint16))&Lua_Bot::GetBotItem) .def("GetBotItemIDBySlot", (uint32(Lua_Bot::*)(uint16))&Lua_Bot::GetBotItemIDBySlot) .def("GetExpansionBitmask", (int(Lua_Bot::*)(void))&Lua_Bot::GetExpansionBitmask) + .def("GetGroup", (Lua_Group(Lua_Bot::*)(void))&Lua_Bot::GetGroup) + .def("GetHealAmount", (int(Lua_Bot::*)(void))&Lua_Bot::GetHealAmount) + .def("GetInstrumentMod", (int(Lua_Bot::*)(int))&Lua_Bot::GetInstrumentMod) .def("GetOwner", (Lua_Mob(Lua_Bot::*)(void))&Lua_Bot::GetOwner) + .def("GetRawItemAC", (int(Lua_Bot::*)(void))&Lua_Bot::GetRawItemAC) + .def("GetSpellDamage", (int(Lua_Bot::*)(void))&Lua_Bot::GetSpellDamage) + .def("HasAugmentEquippedByID", (bool(Lua_Bot::*)(uint32))&Lua_Bot::HasAugmentEquippedByID) .def("HasBotItem", (bool(Lua_Bot::*)(uint32))&Lua_Bot::HasBotItem) .def("HasBotSpellEntry", (bool(Lua_Bot::*)(uint16)) & Lua_Bot::HasBotSpellEntry) + .def("HasItemEquippedByID", (bool(Lua_Bot::*)(uint32))&Lua_Bot::HasItemEquippedByID) + .def("IsGrouped", (bool(Lua_Bot::*)(void))&Lua_Bot::IsGrouped) + .def("IsSitting", (bool(Lua_Bot::*)(void))&Lua_Bot::IsSitting) + .def("IsStanding", (bool(Lua_Bot::*)(void))&Lua_Bot::IsStanding) .def("OwnerMessage", (void(Lua_Bot::*)(std::string))&Lua_Bot::OwnerMessage) .def("ReloadBotDataBuckets", (bool(Lua_Bot::*)(void))&Lua_Bot::ReloadBotDataBuckets) .def("ReloadBotOwnerDataBuckets", (bool(Lua_Bot::*)(void))&Lua_Bot::ReloadBotOwnerDataBuckets) @@ -171,9 +414,17 @@ luabind::scope lua_register_bot() { .def("RemoveBotItem", (void(Lua_Bot::*)(uint32))&Lua_Bot::RemoveBotItem) .def("SetExpansionBitmask", (void(Lua_Bot::*)(int))&Lua_Bot::SetExpansionBitmask) .def("SetExpansionBitmask", (void(Lua_Bot::*)(int,bool))&Lua_Bot::SetExpansionBitmask) + .def("SetSpellDuration", (void(Lua_Bot::*)(int))&Lua_Bot::SetSpellDuration) + .def("SetSpellDuration", (void(Lua_Bot::*)(int,int))&Lua_Bot::SetSpellDuration) + .def("SetSpellDuration", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::SetSpellDuration) + .def("SetSpellDurationGroup", (void(Lua_Bot::*)(int))&Lua_Bot::SetSpellDurationGroup) + .def("SetSpellDurationGroup", (void(Lua_Bot::*)(int,int))&Lua_Bot::SetSpellDurationGroup) + .def("SetSpellDurationGroup", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::SetSpellDurationGroup) .def("SendPayload", (void(Lua_Bot::*)(int))&Lua_Bot::SendPayload) .def("SendPayload", (void(Lua_Bot::*)(int,std::string))&Lua_Bot::SendPayload) - .def("Signal", (void(Lua_Bot::*)(int))&Lua_Bot::Signal); + .def("Signal", (void(Lua_Bot::*)(int))&Lua_Bot::Signal) + .def("Sit", (void(Lua_Bot::*)(void))&Lua_Bot::Sit) + .def("Stand", (void(Lua_Bot::*)(void))&Lua_Bot::Stand); } #endif diff --git a/zone/lua_bot.h b/zone/lua_bot.h index 4776e0193..01b364149 100644 --- a/zone/lua_bot.h +++ b/zone/lua_bot.h @@ -8,6 +8,7 @@ class Bot; class Lua_Bot; class Lua_Mob; +class Lua_Group; namespace luabind { struct scope; @@ -54,6 +55,64 @@ public: bool HasBotSpellEntry(uint16 spellid); void SendPayload(int payload_id); void SendPayload(int payload_id, std::string payload_value); + + void ApplySpell(int spell_id); + void ApplySpell(int spell_id, int duration); + void ApplySpell(int spell_id, int duration, bool allow_pets); + + void ApplySpellGroup(int spell_id); + void ApplySpellGroup(int spell_id, int duration); + void ApplySpellGroup(int spell_id, int duration, bool allow_pets); + + void SetSpellDuration(int spell_id); + void SetSpellDuration(int spell_id, int duration); + void SetSpellDuration(int spell_id, int duration, bool allow_pets); + + void SetSpellDurationGroup(int spell_id); + void SetSpellDurationGroup(int spell_id, int duration); + void SetSpellDurationGroup(int spell_id, int duration, bool allow_pets); + + void SetSpellDurationRaid(int spell_id); + void SetSpellDurationRaid(int spell_id, int duration); + void SetSpellDurationRaid(int spell_id, int duration, bool allow_pets); + void SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only); + + int CountAugmentEquippedByID(uint32 item_id); + int CountItemEquippedByID(uint32 item_id); + bool HasAugmentEquippedByID(uint32 item_id); + bool HasItemEquippedByID(uint32 item_id); + int GetHealAmount(); + int GetSpellDamage(); + + void Escape(); + int GetInstrumentMod(int spell_id); + + int GetItemIDAt(int slot_id); + int GetAugmentIDAt(int slot_id, int aug_slot); + + int GetBaseSTR(); + int GetBaseSTA(); + int GetBaseCHA(); + int GetBaseDEX(); + int GetBaseINT(); + int GetBaseAGI(); + int GetBaseWIS(); + + Lua_Group GetGroup(); + int GetRawItemAC(); + + bool IsGrouped(); + bool IsStanding(); + bool IsSitting(); + void Sit(); + void Stand(); + + void Fling(float target_x, float target_y, float target_z); + void Fling(float target_x, float target_y, float target_z, bool ignore_los); + void Fling(float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls); + void Fling(float value, float target_x, float target_y, float target_z); + void Fling(float value, float target_x, float target_y, float target_z, bool ignore_los); + void Fling(float value, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls); }; #endif diff --git a/zone/lua_group.h b/zone/lua_group.h index 1b7b93346..0f6c87ba3 100644 --- a/zone/lua_group.h +++ b/zone/lua_group.h @@ -8,6 +8,10 @@ class Group; class Lua_Mob; class Lua_Client; +#ifdef BOTS +class Lua_Bot; +#endif + namespace luabind { struct scope; } diff --git a/zone/perl_bot.cpp b/zone/perl_bot.cpp index 0e01e42a0..de5e2ee2e 100644 --- a/zone/perl_bot.cpp +++ b/zone/perl_bot.cpp @@ -56,6 +56,36 @@ void Perl_Bot_AddBotItem(Bot* self, uint16 slot_id, uint32 item_id, uint16 charg self->AddBotItem(slot_id, item_id, charges, attuned, aug1, aug2, aug3, aug4, aug5, aug6); } +void Perl_Bot_ApplySpell(Bot* self, int spell_id) +{ + self->ApplySpell(spell_id); +} + +void Perl_Bot_ApplySpell(Bot* self, int spell_id, int duration) +{ + self->ApplySpell(spell_id, duration); +} + +void Perl_Bot_ApplySpell(Bot* self, int spell_id, int duration, bool allow_pets) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets); +} + +void Perl_Bot_ApplySpellGroup(Bot* self, int spell_id) +{ + self->ApplySpell(spell_id, 0, ApplySpellType::Group); +} + +void Perl_Bot_ApplySpellGroup(Bot* self, int spell_id, int duration) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Group); +} + +void Perl_Bot_ApplySpellGroup(Bot* self, int spell_id, int duration, bool allow_pets) +{ + self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets); +} + uint32 Perl_Bot_CountBotItem(Bot* self, uint32 item_id) { return self->CountBotItem(item_id); @@ -71,6 +101,41 @@ void Perl_Bot_RemoveBotItem(Bot* self, uint32 item_id) return self->RemoveBotItem(item_id); } +EQ::ItemInstance* Perl_Bot_GetAugmentAt(Bot* self, uint32 slot, uint32 aug_slot) +{ + EQ::ItemInstance* inst = self->GetBotInv().GetItem(slot); + if (inst) + { + return inst->GetAugment(aug_slot); + } + return nullptr; +} + +int Perl_Bot_CountAugmentEquippedByID(Bot* self, uint32 item_id) +{ + return self->GetBotInv().CountAugmentEquippedByID(item_id); +} + +bool Perl_Bot_HasAugmentEquippedByID(Bot* self, uint32 item_id) +{ + return self->GetBotInv().HasAugmentEquippedByID(item_id); +} + +int Perl_Bot_CountItemEquippedByID(Bot* self, uint32 item_id) +{ + return self->GetBotInv().CountItemEquippedByID(item_id); +} + +bool Perl_Bot_HasItemEquippedByID(Bot* self, uint32 item_id) +{ + return self->GetBotInv().HasItemEquippedByID(item_id); +} + +int Perl_Bot_GetRawItemAC(Bot* self) // @categories Inventory and Items +{ + return self->GetRawItemAC(); +} + EQ::ItemInstance* Perl_Bot_GetBotItem(Bot* self, uint16 slot_id) { return self->GetBotItem(slot_id); @@ -81,6 +146,26 @@ uint32 Perl_Bot_GetBotItemIDBySlot(Bot* self, uint16 slot_id) return self->GetBotItemBySlot(slot_id); } +bool Perl_Bot_IsStanding(Bot* self) // @categories Account and Character +{ + return self->IsStanding(); +} + +void Perl_Bot_Sit(Bot* self) +{ + self->Sit(); +} + +bool Perl_Bot_IsSitting(Bot* self) // @categories Account and Character +{ + return self->IsSitting(); +} + +void Perl_Bot_SendSpellAnim(Bot* self, uint16 targetid, uint16 spell_id) +{ + self->SendSpellAnim(targetid, spell_id); +} + void Perl_Bot_Signal(Bot* self, int signal_id) { self->Signal(signal_id); @@ -96,6 +181,121 @@ int Perl_Bot_GetExpansionBitmask(Bot* self) return self->GetExpansionBitmask(); } +void Perl_Bot_Escape(Bot* self) // @categories Account and Character, Skills and Recipes +{ + self->Escape(); +} + +void Perl_Bot_Fling(Bot* self, float target_x, float target_y, float target_z) +{ + self->Fling(0, target_x, target_y, target_z, false, false, true); +} + +void Perl_Bot_Fling(Bot* self, float target_x, float target_y, float target_z, bool ignore_los) +{ + self->Fling(0, target_x, target_y, target_z, ignore_los, false, true); +} + +void Perl_Bot_Fling(Bot* self, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls) +{ + self->Fling(0, target_x, target_y, target_z, ignore_los, clip_through_walls, true); +} + +void Perl_Bot_Fling(Bot* self, float value, float target_x, float target_y, float target_z) +{ + self->Fling(value, target_x, target_y, target_z); +} + +void Perl_Bot_Fling(Bot* self, float value, float target_x, float target_y, float target_z, bool ignore_los) +{ + self->Fling(value, target_x, target_y, target_z, ignore_los); +} + +void Perl_Bot_Fling(Bot* self, float value, float target_x, float target_y, float target_z, bool ignore_los, bool clip_through_walls) +{ + self->Fling(value, target_x, target_y, target_z, ignore_los, clip_through_walls); +} + +void Perl_Bot_Stand(Bot* self) // @categories Script Utility +{ + self->Stand(); +} + +int Perl_Bot_GetItemIDAt(Bot* self, int16 slot_id) // @categories Inventory and Items +{ + return self->GetItemIDAt(slot_id); +} + +int Perl_Bot_GetAugmentIDAt(Bot* self, int16 slot_id, uint8 aug_slot) // @categories Inventory and Items +{ + return self->GetAugmentIDAt(slot_id, aug_slot); +} + +int Perl_Bot_GetBaseSTR(Bot* self) // @categories Stats and Attributes +{ + return self->GetBaseSTR(); +} + +int Perl_Bot_GetBaseSTA(Bot* self) // @categories Stats and Attributes +{ + return self->GetBaseSTA(); +} + +int Perl_Bot_GetBaseCHA(Bot* self) // @categories Stats and Attributes +{ + return self->GetBaseCHA(); +} + +int Perl_Bot_GetBaseDEX(Bot* self) // @categories Stats and Attributes +{ + return self->GetBaseDEX(); +} + +int Perl_Bot_GetBaseINT(Bot* self) // @categories Stats and Attributes +{ + return self->GetBaseINT(); +} + +int Perl_Bot_GetBaseAGI(Bot* self) // @categories Stats and Attributes +{ + return self->GetBaseAGI(); +} + +int Perl_Bot_GetBaseWIS(Bot* self) // @categories Stats and Attributes +{ + return self->GetBaseWIS(); +} + +Group* Perl_Bot_GetGroup(Bot* self) // @categories Account and Character, Group +{ + return self->GetGroup(); +} + +int Perl_Bot_GetHealAmount(Bot* self) +{ + return self->GetHealAmt(); +} + +int Perl_Bot_GetSpellDamage(Bot* self) +{ + return self->GetSpellDmg(); +} + +int Perl_Bot_GetInstrumentMod(Bot* self, uint16 spell_id) // @categories Spells and Disciplines +{ + return self->GetInstrumentMod(spell_id); +} + +EQ::ItemInstance* Perl_Bot_GetItemAt(Bot* self, uint32 slot) // @categories Inventory and Items +{ + return self->GetBotInv().GetItem(slot); +} + +bool Perl_Bot_IsGrouped(Bot* self) // @categories Account and Character, Group +{ + return self->IsGrouped(); +} + void Perl_Bot_SetExpansionBitmask(Bot* self, int expansion_bitmask) { self->SetExpansionBitmask(expansion_bitmask); @@ -106,6 +306,36 @@ void Perl_Bot_SetExpansionBitmask(Bot* self, int expansion_bitmask, bool save) self->SetExpansionBitmask(expansion_bitmask, save); } +void Perl_Bot_SetSpellDuration(Bot* self, int spell_id) +{ + self->SetSpellDuration(spell_id); +} + +void Perl_Bot_SetSpellDuration(Bot* self, int spell_id, int duration) +{ + self->SetSpellDuration(spell_id, duration); +} + +void Perl_Bot_SetSpellDuration(Bot* self, int spell_id, int duration, bool allow_pets) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets); +} + +void Perl_Bot_SetSpellDurationGroup(Bot* self, int spell_id) +{ + self->SetSpellDuration(spell_id, 0, ApplySpellType::Group); +} + +void Perl_Bot_SetSpellDurationGroup(Bot* self, int spell_id, int duration) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group); +} + +void Perl_Bot_SetSpellDurationGroup(Bot* self, int spell_id, int duration, bool allow_pets) +{ + self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets); +} + bool Perl_Bot_ReloadBotDataBuckets(Bot* self) { return self->GetBotDataBuckets(); @@ -156,13 +386,49 @@ void perl_register_bot() package.add("AddBotItem", (void(*)(Bot*, uint16, uint32, uint16, bool, uint32, uint32, uint32, uint32))&Perl_Bot_AddBotItem); package.add("AddBotItem", (void(*)(Bot*, uint16, uint32, uint16, bool, uint32, uint32, uint32, uint32, uint32))&Perl_Bot_AddBotItem); package.add("AddBotItem", (void(*)(Bot*, uint16, uint32, uint16, bool, uint32, uint32, uint32, uint32, uint32, uint32))&Perl_Bot_AddBotItem); - package.add("CountBotItem", &Perl_Bot_CountBotItem); + package.add("ApplySpell", (void(*)(Bot*, int))&Perl_Bot_ApplySpell); + package.add("ApplySpell", (void(*)(Bot*, int, int))&Perl_Bot_ApplySpell); + package.add("ApplySpell", (void(*)(Bot*, int, int, bool))&Perl_Bot_ApplySpell); + package.add("ApplySpellGroup", (void(*)(Bot*, int))&Perl_Bot_ApplySpellGroup); + package.add("ApplySpellGroup", (void(*)(Bot*, int, int))&Perl_Bot_ApplySpellGroup); + package.add("ApplySpellGroup", (void(*)(Bot*, int, int, bool))&Perl_Bot_ApplySpellGroup); + package.add("CountAugmentEquippedByID", &Perl_Bot_CountAugmentEquippedByID); + package.add("CountBotItem", &Perl_Bot_CountBotItem); + package.add("CountItemEquippedByID", &Perl_Bot_CountItemEquippedByID); + package.add("Escape", &Perl_Bot_Escape); + package.add("Fling", (void(*)(Bot*, float, float, float))&Perl_Bot_Fling); + package.add("Fling", (void(*)(Bot*, float, float, float, bool))&Perl_Bot_Fling); + package.add("Fling", (void(*)(Bot*, float, float, float, bool, bool))&Perl_Bot_Fling); + package.add("Fling", (void(*)(Bot*, float, float, float, float))&Perl_Bot_Fling); + package.add("Fling", (void(*)(Bot*, float, float, float, float, bool))&Perl_Bot_Fling); + package.add("Fling", (void(*)(Bot*, float, float, float, float, bool, bool))&Perl_Bot_Fling); + package.add("GetAugmentAt", &Perl_Bot_GetAugmentAt); + package.add("GetAugmentIDAt", &Perl_Bot_GetAugmentIDAt); + package.add("GetBaseAGI", &Perl_Bot_GetBaseAGI); + package.add("GetBaseCHA", &Perl_Bot_GetBaseCHA); + package.add("GetBaseDEX", &Perl_Bot_GetBaseDEX); + package.add("GetBaseINT", &Perl_Bot_GetBaseINT); + package.add("GetBaseSTA", &Perl_Bot_GetBaseSTA); + package.add("GetBaseSTR", &Perl_Bot_GetBaseSTR); + package.add("GetBaseWIS", &Perl_Bot_GetBaseWIS); package.add("GetBotItem", &Perl_Bot_GetBotItem); package.add("GetBotItemIDBySlot", &Perl_Bot_GetBotItemIDBySlot); package.add("GetExpansionBitmask", &Perl_Bot_GetExpansionBitmask); + package.add("GetGroup", &Perl_Bot_GetGroup); + package.add("GetHealAmount", &Perl_Bot_GetHealAmount); + package.add("GetInstrumentMod", &Perl_Bot_GetInstrumentMod); + package.add("GetItemAt", &Perl_Bot_GetItemAt); + package.add("GetItemIDAt", &Perl_Bot_GetItemIDAt); package.add("GetOwner", &Perl_Bot_GetOwner); + package.add("GetRawItemAC", &Perl_Bot_GetRawItemAC); + package.add("GetSpellDamage", &Perl_Bot_GetSpellDamage); + package.add("HasAugmentEquippedByID", &Perl_Bot_HasAugmentEquippedByID); package.add("HasBotItem", &Perl_Bot_HasBotItem); package.add("HasBotSpellEntry", &Perl_Bot_HasBotSpellEntry); + package.add("HasItemEquippedByID", &Perl_Bot_HasItemEquippedByID); + package.add("IsGrouped", &Perl_Bot_IsGrouped); + package.add("IsSitting", &Perl_Bot_IsSitting); + package.add("IsStanding", &Perl_Bot_IsStanding); package.add("OwnerMessage", &Perl_Bot_OwnerMessage); package.add("ReloadBotDataBuckets", &Perl_Bot_ReloadBotDataBuckets); package.add("ReloadBotOwnerDataBuckets", &Perl_Bot_ReloadBotOwnerDataBuckets); @@ -171,9 +437,18 @@ void perl_register_bot() package.add("RemoveBotItem", &Perl_Bot_RemoveBotItem); package.add("SendPayload", (void(*)(Bot*, int))&Perl_Bot_SendPayload); package.add("SendPayload", (void(*)(Bot*, int, std::string))&Perl_Bot_SendPayload); + package.add("SendSpellAnim", &Perl_Bot_SendSpellAnim); package.add("SetExpansionBitmask", (void(*)(Bot*, int))&Perl_Bot_SetExpansionBitmask); package.add("SetExpansionBitmask", (void(*)(Bot*, int, bool))&Perl_Bot_SetExpansionBitmask); + package.add("SetSpellDuration", (void(*)(Bot*, int))&Perl_Bot_SetSpellDuration); + package.add("SetSpellDuration", (void(*)(Bot*, int, int))&Perl_Bot_SetSpellDuration); + package.add("SetSpellDuration", (void(*)(Bot*, int, int, bool))&Perl_Bot_SetSpellDuration); + package.add("SetSpellDurationGroup", (void(*)(Bot*, int))&Perl_Bot_SetSpellDurationGroup); + package.add("SetSpellDurationGroup", (void(*)(Bot*, int, int))&Perl_Bot_SetSpellDurationGroup); + package.add("SetSpellDurationGroup", (void(*)(Bot*, int, int, bool))&Perl_Bot_SetSpellDurationGroup); package.add("Signal", &Perl_Bot_Signal); + package.add("Sit", &Perl_Bot_Sit); + package.add("Stand", &Perl_Bot_Stand); } #endif //EMBPERL_XS_CLASSES