implement commanded cast types

This commit is contained in:
nytmyr
2024-11-26 13:17:36 -06:00
parent 3d67009de5
commit ee9651b4f1
27 changed files with 1394 additions and 993 deletions
+181
View File
@@ -9527,6 +9527,17 @@ bool Bot::CanCastSpellType(uint16 spellType, uint16 spell_id, Mob* tar) {
case BotSpellTypes::PetDamageShields:
case BotSpellTypes::ResistBuffs:
case BotSpellTypes::PetResistBuffs:
case BotSpellTypes::Teleport:
case BotSpellTypes::Succor:
case BotSpellTypes::BindAffinity:
case BotSpellTypes::Identify:
case BotSpellTypes::Levitate:
case BotSpellTypes::Rune:
case BotSpellTypes::WaterBreathing:
case BotSpellTypes::Size:
case BotSpellTypes::Invisibility:
case BotSpellTypes::MovementSpeed:
case BotSpellTypes::SendHome:
if (
!(
spells[spell_id].target_type == ST_Target ||
@@ -10893,6 +10904,18 @@ uint16 Bot::GetSpellListSpellType(uint16 spellType) {
case BotSpellTypes::PetDamageShields:
case BotSpellTypes::ResistBuffs:
case BotSpellTypes::PetResistBuffs:
case BotSpellTypes::Teleport:
case BotSpellTypes::Succor:
case BotSpellTypes::BindAffinity:
case BotSpellTypes::Identify:
case BotSpellTypes::Levitate:
case BotSpellTypes::Rune:
case BotSpellTypes::WaterBreathing:
case BotSpellTypes::Size:
case BotSpellTypes::Invisibility:
case BotSpellTypes::MovementSpeed:
case BotSpellTypes::SendHome:
case BotSpellTypes::SummonCorpse:
return BotSpellTypes::Buff;
case BotSpellTypes::AEMez:
case BotSpellTypes::Mez:
@@ -10934,6 +10957,7 @@ uint16 Bot::GetSpellListSpellType(uint16 spellType) {
case BotSpellTypes::PreCombatBuff:
case BotSpellTypes::PreCombatBuffSong:
case BotSpellTypes::Resurrect:
case BotSpellTypes::Lull:
default:
return spellType;
}
@@ -10996,6 +11020,84 @@ bool Bot::IsValidSpellTypeBySpellID(uint16 spellType, uint16 spell_id) {
return true;
}
return false;
case BotSpellTypes::Lull:
if (!IsHarmonySpell(spell_id)) {
return true;
}
return false;
case BotSpellTypes::Teleport:
if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_Teleport) || IsEffectInSpell(spell_id, SE_Translocate))) {
return true;
}
return false;
case BotSpellTypes::Succor:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_Succor)) {
return true;
}
return false;
case BotSpellTypes::BindAffinity:
if (IsEffectInSpell(spell_id, SE_BindAffinity)) {
return true;
}
return false;
case BotSpellTypes::Identify:
if (IsEffectInSpell(spell_id, SE_Identify)) {
return true;
}
return false;
case BotSpellTypes::Levitate:
if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_Levitate))) {
return true;
}
return false;
case BotSpellTypes::Rune:
if (IsEffectInSpell(spell_id, SE_AbsorbMagicAtt) || IsEffectInSpell(spell_id, SE_Rune)) {
return true;
}
return false;
case BotSpellTypes::WaterBreathing:
if (IsEffectInSpell(spell_id, SE_WaterBreathing)) {
return true;
}
return false;
case BotSpellTypes::Size:
if (IsBeneficialSpell(spell_id) && (IsEffectInSpell(spell_id, SE_ModelSize) || IsEffectInSpell(spell_id, SE_ChangeHeight))) {
return true;
}
return false;
case BotSpellTypes::Invisibility:
if (IsEffectInSpell(spell_id, SE_SeeInvis) || IsInvisibleSpell(spell_id)) {
return true;
}
return false;
case BotSpellTypes::MovementSpeed:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_MovementSpeed)) {
return true;
}
return false;
case BotSpellTypes::SendHome:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_GateToHomeCity)) {
return true;
}
return false;
case BotSpellTypes::SummonCorpse:
if (IsEffectInSpell(spell_id, SE_SummonCorpse)) {
return true;
}
return false;
default:
return true;
@@ -11491,3 +11593,82 @@ bool Bot::BotPassiveCheck() {
return false;
}
bool Bot::IsValidSpellTypeSubType(uint16 spellType, uint16 subType, uint16 spell_id) {
if (subType == UINT16_MAX) {
return true;
}
switch (subType) {
case CommandedSubTypes::SingleTarget:
if (!IsAnyAESpell(spell_id) && !IsGroupSpell(spell_id)) {
return true;
}
break;
case CommandedSubTypes::GroupTarget:
if (IsGroupSpell(spell_id)) {
return true;
}
break;
case CommandedSubTypes::AETarget:
if (IsAnyAESpell(spell_id)) {
return true;
}
break;
case CommandedSubTypes::SeeInvis:
if (IsEffectInSpell(spell_id, SE_SeeInvis)) {
return true;
}
break;
case CommandedSubTypes::Invis:
if (IsEffectInSpell(spell_id, SE_Invisibility) || IsEffectInSpell(spell_id, SE_Invisibility2)) {
return true;
}
break;
case CommandedSubTypes::InvisUndead:
if (IsEffectInSpell(spell_id, SE_InvisVsUndead) || IsEffectInSpell(spell_id, SE_InvisVsUndead2)) {
return true;
}
break;
case CommandedSubTypes::InvisAnimals:
if (IsEffectInSpell(spell_id, SE_InvisVsAnimals) || IsEffectInSpell(spell_id, SE_ImprovedInvisAnimals)) {
return true;
}
break;
case CommandedSubTypes::Shrink:
if (
(IsEffectInSpell(spell_id, SE_ModelSize) && CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SE_ModelSize), GetLevel()) < 100) ||
(IsEffectInSpell(spell_id, SE_ChangeHeight) && CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SE_ChangeHeight), GetLevel()) < 100)
) {
return true;
}
break;
case CommandedSubTypes::Grow:
if (
(IsEffectInSpell(spell_id, SE_ModelSize) && CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SE_ModelSize), GetLevel()) > 100) ||
(IsEffectInSpell(spell_id, SE_ChangeHeight) && CalcSpellEffectValue(spell_id, GetSpellEffectIndex(spell_id, SE_ChangeHeight), GetLevel()) > 100)
) {
return true;
}
break;
case CommandedSubTypes::Selo:
if (IsBeneficialSpell(spell_id) && IsEffectInSpell(spell_id, SE_MovementSpeed) && IsBardSong(spell_id)) {
return true;
}
break;
default:
break;
}
return false;
}
+16 -2
View File
@@ -147,6 +147,19 @@ namespace BotBaseSettings {
constexpr uint16 END = BotBaseSettings::ManaWhenToMed; // Increment as needed
};
namespace CommandedSubTypes {
constexpr uint16 SingleTarget = 1;
constexpr uint16 GroupTarget = 2;
constexpr uint16 AETarget = 3;
constexpr uint16 SeeInvis = 4;
constexpr uint16 Invis = 5;
constexpr uint16 InvisUndead = 6;
constexpr uint16 InvisAnimals = 7;
constexpr uint16 Shrink = 8;
constexpr uint16 Grow = 9;
constexpr uint16 Selo = 10;
};
class Bot : public NPC {
friend class Mob;
public:
@@ -387,7 +400,7 @@ public:
void AI_Bot_Event_SpellCastFinished(bool iCastSucceeded, uint16 slot);
// AI Methods
bool AICastSpell(Mob* tar, uint8 iChance, uint16 spellType);
bool AICastSpell(Mob* tar, uint8 iChance, uint16 spellType, uint16 subTargetType = UINT16_MAX, uint16 subType = UINT16_MAX);
bool AttemptAICastSpell(uint16 spellType);
bool AI_EngagedCastCheck() override;
bool AI_PursueCastCheck() override;
@@ -523,6 +536,7 @@ public:
bool IsValidSpellTypeBySpellID(uint16 spellType, uint16 spell_id);
inline uint16 GetCastedSpellType() const { return _castedSpellType; }
void SetCastedSpellType(uint16 spellType);
bool IsValidSpellTypeSubType(uint16 spellType, uint16 subType, uint16 spell_id);
bool HasValidAETarget(Bot* botCaster, uint16 spell_id, uint16 spellType, Mob* tar);
@@ -577,7 +591,7 @@ public:
static std::list<BotSpell> GetBotSpellsForSpellEffect(Bot* botCaster, uint16 spellType, int spellEffect);
static std::list<BotSpell> GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, uint16 spellType, int spellEffect, SpellTargetType targetType);
static std::list<BotSpell> GetBotSpellsBySpellType(Bot* botCaster, uint16 spellType);
static std::list<BotSpell_wPriority> GetPrioritizedBotSpellsBySpellType(Bot* botCaster, uint16 spellType, Mob* tar, bool AE = false);
static std::list<BotSpell_wPriority> GetPrioritizedBotSpellsBySpellType(Bot* botCaster, uint16 spellType, Mob* tar, bool AE = false, uint16 subTargetType = UINT16_MAX, uint16 subType = UINT16_MAX);
static BotSpell GetFirstBotSpellBySpellType(Bot* botCaster, uint16 spellType);
static BotSpell GetBestBotSpellForVeryFastHeal(Bot* botCaster, Mob* tar, uint16 spellType = BotSpellTypes::RegularHeal);
+4 -34
View File
@@ -1251,7 +1251,6 @@ int bot_command_init(void)
bot_command_add("applypoison", "Applies cursor-held poison to a rogue bot's weapon", AccountStatus::Player, bot_command_apply_poison) ||
bot_command_add("attack", "Orders bots to attack a designated target", AccountStatus::Player, bot_command_attack) ||
bot_command_add("behindmob", "Toggles whether or not your bot tries to stay behind a mob", AccountStatus::Player, bot_command_behind_mob) ||
bot_command_add("bindaffinity", "Orders a bot to attempt an affinity binding", AccountStatus::Player, bot_command_bind_affinity) ||
bot_command_add("bot", "Lists the available bot management [subcommands]", AccountStatus::Player, bot_command_bot) ||
bot_command_add("botappearance", "Lists the available bot appearance [subcommands]", AccountStatus::Player, bot_command_appearance) ||
bot_command_add("botbeardcolor", "Changes the beard color of a bot", AccountStatus::Player, bot_command_beard_color) ||
@@ -1286,16 +1285,13 @@ int bot_command_init(void)
bot_command_add("botwoad", "Changes the Barbarian woad of a bot", AccountStatus::Player, bot_command_woad) ||
bot_command_add("cast", "Tells the first found specified bot to cast the given spell type", AccountStatus::Player, bot_command_cast) ||
bot_command_add("distanceranged", "Controls the range casters and ranged will try to stay away from a mob", AccountStatus::Player, bot_command_distance_ranged) ||
bot_command_add("charm", "Attempts to have a bot charm your target", AccountStatus::Player, bot_command_charm) ||
bot_command_add("classracelist", "Lists the classes and races and their appropriate IDs", AccountStatus::Player, bot_command_class_race_list) ||
bot_command_add("clickitem", "Orders your targeted bot to click the item in the provided inventory slot.", AccountStatus::Player, bot_command_click_item) ||
bot_command_add("copysettings", "Copies settings from one bot to another", AccountStatus::Player, bot_command_copy_settings) ||
bot_command_add("cure", "Orders a bot to remove any ailments", AccountStatus::Player, bot_command_cure) ||
bot_command_add("defaultsettings", "Restores a bot back to default settings", AccountStatus::Player, bot_command_default_settings) ||
bot_command_add("defensive", "Orders a bot to use a defensive discipline", AccountStatus::Player, bot_command_defensive) ||
bot_command_add("depart", "Orders a bot to open a magical doorway to a specified destination", AccountStatus::Player, bot_command_depart) ||
bot_command_add("depart", "Orders a bot to open a magical doorway to a specified destination", AccountStatus::Player, bot_command_depart) || //TODO bot rewrite - deleteme
bot_command_add("enforcespellsettings", "Toggles your Bot to cast only spells in their spell settings list.", AccountStatus::Player, bot_command_enforce_spell_list) ||
bot_command_add("escape", "Orders a bot to send a target group to a safe location within the zone", AccountStatus::Player, bot_command_escape) ||
bot_command_add("findaliases", "Find available aliases for a bot command", AccountStatus::Player, bot_command_find_aliases) ||
bot_command_add("follow", "Orders bots to follow a designated target (option 'chain' auto-links eligible spawned bots)", AccountStatus::Player, bot_command_follow) ||
bot_command_add("guard", "Orders bots to guard their current positions", AccountStatus::Player, bot_command_guard) ||
@@ -1322,20 +1318,15 @@ int bot_command_init(void)
bot_command_add("healrotationstop", "Stops a heal rotation", AccountStatus::Player, bot_command_heal_rotation_stop) ||
bot_command_add("help", "List available commands and their description - specify partial command as argument to search", AccountStatus::Player, bot_command_help) ||
bot_command_add("hold", "Prevents a bot from attacking until released", AccountStatus::Player, bot_command_hold) ||
bot_command_add("identify", "Orders a bot to cast an item identification spell", AccountStatus::Player, bot_command_identify) ||
bot_command_add("illusionblock", "Control whether or not illusion effects will land on the bot if casted by another player or bot", AccountStatus::Player, bot_command_illusion_block) ||
bot_command_add("inventory", "Lists the available bot inventory [subcommands]", AccountStatus::Player, bot_command_inventory) ||
bot_command_add("inventorygive", "Gives the item on your cursor to a bot", AccountStatus::Player, bot_command_inventory_give) ||
bot_command_add("inventorylist", "Lists all items in a bot's inventory", AccountStatus::Player, bot_command_inventory_list) ||
bot_command_add("inventoryremove", "Removes an item from a bot's inventory", AccountStatus::Player, bot_command_inventory_remove) ||
bot_command_add("inventorywindow", "Displays all items in a bot's inventory in a pop-up window", AccountStatus::Player, bot_command_inventory_window) ||
bot_command_add("invisibility", "Orders a bot to cast a cloak of invisibility, or allow them to be seen", AccountStatus::Player, bot_command_invisibility) ||
bot_command_add("itemuse", "Elicits a report from spawned bots that can use the item on your cursor (option 'empty' yields only empty slots)", AccountStatus::Player, bot_command_item_use) ||
bot_command_add("levitation", "Orders a bot to cast a levitation spell", AccountStatus::Player, bot_command_levitation) ||
bot_command_add("lull", "Orders a bot to cast a pacification spell", AccountStatus::Player, bot_command_lull) ||
bot_command_add("lull", "Orders a bot to cast a pacification spell", AccountStatus::Player, bot_command_lull) || //TODO bot rewrite - IMPLEMENT
bot_command_add("maxmeleerange", "Toggles whether your bot is at max melee range or not. This will disable all special abilities, including taunt.", AccountStatus::Player, bot_command_max_melee_range) ||
bot_command_add("mesmerize", "Orders a bot to cast a mesmerization spell", AccountStatus::Player, bot_command_mesmerize) ||
bot_command_add("movementspeed", "Orders a bot to cast a movement speed enhancement spell", AccountStatus::Player, bot_command_movement_speed) ||
bot_command_add("owneroption", "Sets options available to bot owners", AccountStatus::Player, bot_command_owner_option) ||
bot_command_add("pet", "Lists the available bot pet [subcommands]", AccountStatus::Player, bot_command_pet) ||
bot_command_add("petgetlost", "Orders a bot to remove its summoned pet", AccountStatus::Player, bot_command_pet_get_lost) ||
@@ -1346,14 +1337,9 @@ int bot_command_init(void)
bot_command_add("precombat", "Sets flag used to determine pre-combat behavior", AccountStatus::Player, bot_command_precombat) ||
bot_command_add("pull", "Orders a designated bot to 'pull' an enemy", AccountStatus::Player, bot_command_pull) ||
bot_command_add("release", "Releases a suspended bot's AI processing (with hate list wipe)", AccountStatus::Player, bot_command_release) ||
bot_command_add("resistance", "Orders a bot to cast a specified resistance buff", AccountStatus::Player, bot_command_resistance) ||
bot_command_add("resurrect", "Orders a bot to resurrect a player's (players') corpse(s)", AccountStatus::Player, bot_command_resurrect) ||
bot_command_add("rune", "Orders a bot to cast a rune of protection", AccountStatus::Player, bot_command_rune) ||
bot_command_add("sendhome", "Orders a bot to open a magical doorway home", AccountStatus::Player, bot_command_send_home) ||
bot_command_add("sithppercent", "HP threshold for a bot to start sitting in combat if allowed", AccountStatus::Player, bot_command_sit_hp_percent) ||
bot_command_add("sitincombat", "Toggles whether or a not a bot will attempt to med or sit to heal in combat", AccountStatus::Player, bot_command_sit_in_combat) ||
bot_command_add("sitmanapercent", "Mana threshold for a bot to start sitting in combat if allowed", AccountStatus::Player, bot_command_sit_mana_percent) ||
bot_command_add("size", "Orders a bot to change a player's size", AccountStatus::Player, bot_command_size) ||
bot_command_add("spellaggrochecks", "Toggles whether or not bots will cast a spell type if they think it will get them aggro", AccountStatus::Player, bot_command_spell_aggro_checks) ||
bot_command_add("spellengagedpriority", "Controls the order of casts by spell type when engaged in combat", AccountStatus::Player, bot_command_spell_engaged_priority) ||
bot_command_add("spelldelays", "Controls the delay between casts for a specific spell type", AccountStatus::Player, bot_command_spell_delays) ||
@@ -1374,15 +1360,14 @@ int bot_command_init(void)
bot_command_add("spellsettingsdelete", "Delete a bot spell setting entry", AccountStatus::Player, bot_command_spell_settings_delete) ||
bot_command_add("spellsettingstoggle", "Toggle a bot spell use", AccountStatus::Player, bot_command_spell_settings_toggle) ||
bot_command_add("spellsettingsupdate", "Update a bot spell setting entry", AccountStatus::Player, bot_command_spell_settings_update) ||
bot_command_add("summoncorpse", "Orders a bot to summon a corpse to its feet", AccountStatus::Player, bot_command_summon_corpse) ||
bot_command_add("spelltypeids", "Lists spelltypes by ID", AccountStatus::Player, bot_command_spelltype_ids) ||
bot_command_add("spelltypenames", "Lists spelltypes by shortname", AccountStatus::Player, bot_command_spelltype_names) ||
bot_command_add("summoncorpse", "Orders a bot to summon a corpse to its feet", AccountStatus::Player, bot_command_summon_corpse) || //TODO bot rewrite - IMPLEMENT
bot_command_add("suspend", "Suspends a bot's AI processing until released", AccountStatus::Player, bot_command_suspend) ||
bot_command_add("taunt", "Toggles taunt use by a bot", AccountStatus::Player, bot_command_taunt) ||
bot_command_add("timer", "Checks or clears timers of the chosen type.", AccountStatus::GMMgmt, bot_command_timer) ||
bot_command_add("track", "Orders a capable bot to track enemies", AccountStatus::Player, bot_command_track) ||
bot_command_add("viewcombos", "Views bot race class combinations", AccountStatus::Player, bot_command_view_combos) ||
bot_command_add("waterbreathing", "Orders a bot to cast a water breathing spell", AccountStatus::Player, bot_command_water_breathing)
bot_command_add("viewcombos", "Views bot race class combinations", AccountStatus::Player, bot_command_view_combos)
) {
bot_command_deinit();
return -1;
@@ -2266,36 +2251,27 @@ void SendSpellTypeWindow(Client *c, const Seperator* sep) {
#include "bot_commands/apply_potion.cpp"
#include "bot_commands/attack.cpp"
#include "bot_commands/behind_mob.cpp"
#include "bot_commands/bind_affinity.cpp"
#include "bot_commands/bot.cpp"
#include "bot_commands/bot_settings.cpp"
#include "bot_commands/cast.cpp"
#include "bot_commands/charm.cpp"
#include "bot_commands/class_race_list.cpp"
#include "bot_commands/click_item.cpp"
#include "bot_commands/copy_settings.cpp"
#include "bot_commands/cure.cpp"
#include "bot_commands/default_settings.cpp"
#include "bot_commands/defensive.cpp"
#include "bot_commands/depart.cpp"
#include "bot_commands/distance_ranged.cpp"
#include "bot_commands/escape.cpp"
#include "bot_commands/find_aliases.cpp"
#include "bot_commands/follow.cpp"
#include "bot_commands/guard.cpp"
#include "bot_commands/heal_rotation.cpp"
#include "bot_commands/help.cpp"
#include "bot_commands/hold.cpp"
#include "bot_commands/identify.cpp"
#include "bot_commands/illusion_block.cpp"
#include "bot_commands/inventory.cpp"
#include "bot_commands/invisibility.cpp"
#include "bot_commands/item_use.cpp"
#include "bot_commands/levitation.cpp"
#include "bot_commands/lull.cpp"
#include "bot_commands/max_melee_range.cpp"
#include "bot_commands/mesmerize.cpp"
#include "bot_commands/movement_speed.cpp"
#include "bot_commands/name.cpp"
#include "bot_commands/owner_option.cpp"
#include "bot_commands/pet.cpp"
@@ -2304,14 +2280,9 @@ void SendSpellTypeWindow(Client *c, const Seperator* sep) {
#include "bot_commands/precombat.cpp"
#include "bot_commands/pull.cpp"
#include "bot_commands/release.cpp"
#include "bot_commands/resistance.cpp"
#include "bot_commands/resurrect.cpp"
#include "bot_commands/rune.cpp"
#include "bot_commands/send_home.cpp"
#include "bot_commands/sit_hp_percent.cpp"
#include "bot_commands/sit_in_combat.cpp"
#include "bot_commands/sit_mana_percent.cpp"
#include "bot_commands/size.cpp"
#include "bot_commands/spell.cpp"
#include "bot_commands/spell_aggro_checks.cpp"
#include "bot_commands/spell_delays.cpp"
@@ -2334,4 +2305,3 @@ void SendSpellTypeWindow(Client *c, const Seperator* sep) {
#include "bot_commands/timer.cpp"
#include "bot_commands/track.cpp"
#include "bot_commands/view_combos.cpp"
#include "bot_commands/water_breathing.cpp"
-15
View File
@@ -1669,36 +1669,27 @@ void bot_command_apply_poison(Client *c, const Seperator *sep);
void bot_command_apply_potion(Client* c, const Seperator* sep);
void bot_command_attack(Client *c, const Seperator *sep);
void bot_command_behind_mob(Client* c, const Seperator* sep);
void bot_command_bind_affinity(Client *c, const Seperator *sep);
void bot_command_bot(Client *c, const Seperator *sep);
void bot_command_bot_settings(Client* c, const Seperator* sep);
void bot_command_cast(Client* c, const Seperator* sep);
void bot_command_distance_ranged(Client* c, const Seperator* sep);
void bot_command_charm(Client *c, const Seperator *sep);
void bot_command_class_race_list(Client* c, const Seperator* sep);
void bot_command_click_item(Client* c, const Seperator* sep);
void bot_command_copy_settings(Client* c, const Seperator* sep);
void bot_command_cure(Client *c, const Seperator *sep);
void bot_command_default_settings(Client* c, const Seperator* sep);
void bot_command_defensive(Client *c, const Seperator *sep);
void bot_command_depart(Client *c, const Seperator *sep);
void bot_command_escape(Client *c, const Seperator *sep);
void bot_command_find_aliases(Client *c, const Seperator *sep);
void bot_command_follow(Client *c, const Seperator *sep);
void bot_command_guard(Client *c, const Seperator *sep);
void bot_command_heal_rotation(Client *c, const Seperator *sep);
void bot_command_help(Client *c, const Seperator *sep);
void bot_command_hold(Client *c, const Seperator *sep);
void bot_command_identify(Client *c, const Seperator *sep);
void bot_command_illusion_block(Client* c, const Seperator* sep);
void bot_command_inventory(Client *c, const Seperator *sep);
void bot_command_invisibility(Client *c, const Seperator *sep);
void bot_command_item_use(Client *c, const Seperator *sep);
void bot_command_levitation(Client *c, const Seperator *sep);
void bot_command_lull(Client *c, const Seperator *sep);
void bot_command_max_melee_range(Client* c, const Seperator* sep);
void bot_command_mesmerize(Client *c, const Seperator *sep);
void bot_command_movement_speed(Client *c, const Seperator *sep);
void bot_command_owner_option(Client *c, const Seperator *sep);
void bot_command_pet(Client *c, const Seperator *sep);
void bot_command_pick_lock(Client *c, const Seperator *sep);
@@ -1706,14 +1697,9 @@ void bot_command_pickpocket(Client* c, const Seperator* sep);
void bot_command_precombat(Client* c, const Seperator* sep);
void bot_command_pull(Client *c, const Seperator *sep);
void bot_command_release(Client *c, const Seperator *sep);
void bot_command_resistance(Client *c, const Seperator *sep);
void bot_command_resurrect(Client *c, const Seperator *sep);
void bot_command_rune(Client *c, const Seperator *sep);
void bot_command_send_home(Client *c, const Seperator *sep);
void bot_command_sit_hp_percent(Client* c, const Seperator* sep);
void bot_command_sit_in_combat(Client* c, const Seperator* sep);
void bot_command_sit_mana_percent(Client* c, const Seperator* sep);
void bot_command_size(Client *c, const Seperator *sep);
void bot_command_spell_aggro_checks(Client* c, const Seperator* sep);
void bot_command_spell_delays(Client* c, const Seperator* sep);
void bot_command_spell_engaged_priority(Client* c, const Seperator* sep);
@@ -1743,7 +1729,6 @@ void bot_command_taunt(Client *c, const Seperator *sep);
void bot_command_timer(Client* c, const Seperator* sep);
void bot_command_track(Client *c, const Seperator *sep);
void bot_command_view_combos(Client *c, const Seperator *sep);
void bot_command_water_breathing(Client *c, const Seperator *sep);
// Bot Subcommands
void bot_command_appearance(Client *c, const Seperator *sep);
-42
View File
@@ -1,42 +0,0 @@
#include "../bot_command.h"
void bot_command_bind_affinity(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_BindAffinity];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_BindAffinity) || helper_command_alias_fail(c, "bot_command_bind_affinity", sep->arg[0], "bindaffinity"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s", sep->arg[0]);
c->Message(Chat::White, "note: Orders a bot to attempt an affinity binding", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_BindAffinity);
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
for (auto list_iter : *local_list) {
auto local_entry = list_iter;
if (helper_spell_check_fail(local_entry))
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
// Cast effect message is not being generated
if (helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id))
c->Message(Chat::White, "Successfully bound %s to this location", target_mob->GetCleanName());
else
c->Message(Chat::White, "Failed to bind %s to this location", target_mob->GetCleanName());
break;
}
helper_no_available_bots(c, my_bot);
}
+193 -37
View File
@@ -99,8 +99,8 @@ void bot_command_cast(Client* c, const Seperator* sep)
c->Message(
Chat::Yellow,
fmt::format(
"Use {} for information about race/class IDs.",
Saylink::Silent("^classracelist")
"Use help after any command type for more subtypes to use, for example: {}.",
Saylink::Silent("^cast invisibility help")
).c_str()
);
@@ -118,9 +118,58 @@ void bot_command_cast(Client* c, const Seperator* sep)
}
std::string arg1 = sep->arg[1];
std::string arg2 = sep->arg[2];
if (!arg1.compare("listid") || !arg1.compare("listname")) {
c->CastToBot()->SendSpellTypesWindow(c, sep->arg[0], sep->arg[1], sep->arg[2]);
//Commanded type help prompts
if (!arg2.compare("help")) {
c->Message(Chat::Yellow, "You can also use [single], [group], [ae]. Ex: ^cast movementspeed group.", sep->arg[0]);
}
if (!arg1.compare("invisibility") && !arg2.compare("help")) {
c->Message(
Chat::Yellow,
fmt::format(
"Available options for {} are: {}, {}, {}, {}.",
sep->arg[0],
Saylink::Silent("^cast invisibility see", "see"),
Saylink::Silent("^cast invisibility invis", "invis"),
Saylink::Silent("^cast invisibility undead", "undead"),
Saylink::Silent("^cast invisibility animals", "animals")
).c_str()
);
return;
}
if (!arg1.compare("size") && !arg2.compare("help")) {
c->Message(
Chat::Yellow,
fmt::format(
"Available options for {} are: {}, {}.",
sep->arg[0],
Saylink::Silent("^cast size grow", "grow"),
Saylink::Silent("^cast size shrink", "shrink")
).c_str()
);
return;
}
if (!arg1.compare("movementspeed") && !arg2.compare("help")) {
c->Message(
Chat::Yellow,
fmt::format(
"Available options for {} are: {}, {}.",
sep->arg[0],
Saylink::Silent("^cast movementspeed selo"), "selo"
).c_str()
);
return;
}
if (!arg2.compare("help")) {
c->Message(Chat::Yellow, "There are no additional options for {}.", sep->arg[0]);
return;
}
@@ -131,8 +180,16 @@ void bot_command_cast(Client* c, const Seperator* sep)
if (sep->IsNumber(1)) {
spellType = atoi(sep->arg[1]);
if (spellType < BotSpellTypes::START || spellType > BotSpellTypes::END) {
c->Message(Chat::Yellow, "You must choose a valid spell type. Spell types range from %i to %i", BotSpellTypes::START, BotSpellTypes::END);
if (spellType < BotSpellTypes::START || (spellType > BotSpellTypes::END && spellType < BotSpellTypes::COMMANDED_START) || spellType > BotSpellTypes::COMMANDED_END) {
c->Message(
Chat::Yellow,
fmt::format(
"You must choose a valid spell type. Use {} for information regarding this command.",
Saylink::Silent(
fmt::format("{} help", sep->arg[0])
)
).c_str()
);
return;
}
@@ -156,6 +213,88 @@ void bot_command_cast(Client* c, const Seperator* sep)
}
}
switch (spellType) { //Allowed command checks
case BotSpellTypes::Charm:
if (!RuleB(Bots, AllowCommandedCharm)) {
c->Message(Chat::Yellow, "This commanded type is currently disabled.");
return;
}
break;
case BotSpellTypes::AEMez:
case BotSpellTypes::Mez:
if (!RuleB(Bots, AllowCommandedMez)) {
c->Message(Chat::Yellow, "This commanded type is currently disabled.");
return;
}
break;
case BotSpellTypes::Resurrect:
if (!RuleB(Bots, AllowCommandedResurrect)) {
c->Message(Chat::Yellow, "This commanded type is currently disabled.");
return;
}
break;
case BotSpellTypes::SummonCorpse:
if (!RuleB(Bots, AllowCommandedSummonCorpse)) {
c->Message(Chat::Yellow, "This commanded type is currently disabled.");
return;
}
break;
default:
break;
}
std::string argString = sep->arg[ab_arg];
uint16 subType = UINT16_MAX;
uint16 subTargetType = UINT16_MAX;
if (!argString.compare("shrink")) {
subType = CommandedSubTypes::Shrink;
++ab_arg;
}
else if (!argString.compare("grow")) {
subType = CommandedSubTypes::Grow;
++ab_arg;
}
else if (!argString.compare("see")) {
subType = CommandedSubTypes::SeeInvis;
++ab_arg;
}
else if (!argString.compare("invis")) {
subType = CommandedSubTypes::Invis;
++ab_arg;
}
else if (!argString.compare("undead")) {
subType = CommandedSubTypes::InvisUndead;
++ab_arg;
}
else if (!argString.compare("animals")) {
subType = CommandedSubTypes::InvisAnimals;
++ab_arg;
}
else if (!argString.compare("selo")) {
subType = CommandedSubTypes::Selo;
++ab_arg;
}
argString = sep->arg[ab_arg];
if (!argString.compare("single")) {
subTargetType = CommandedSubTypes::SingleTarget;
++ab_arg;
}
else if (!argString.compare("group")) {
subTargetType = CommandedSubTypes::GroupTarget;
++ab_arg;
}
else if (!argString.compare("ae")) {
subTargetType = CommandedSubTypes::AETarget;
++ab_arg;
}
if (
spellType == BotSpellTypes::PetBuffs ||
spellType == BotSpellTypes::PetCompleteHeals ||
@@ -169,47 +308,63 @@ void bot_command_cast(Client* c, const Seperator* sep)
}
Mob* tar = c->GetTarget();
LogTestDebug("{}: Attempting {} on {}", __LINE__, c->GetSpellTypeNameByID(spellType), (tar ? tar->GetCleanName() : "NOBODY")); //deleteme
if (spellType != BotSpellTypes::Escape && spellType != BotSpellTypes::Pet) {
if (!tar) {
LogTestDebug("{}: 'Attempting {} [{}] on {}'", __LINE__, c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (tar ? tar->GetCleanName() : "NOBODY")); //deleteme
if (!tar) {
if (spellType != BotSpellTypes::Escape && spellType != BotSpellTypes::Pet) {
c->Message(Chat::Yellow, "You need a target for that.");
return;
}
if (BOT_SPELL_TYPES_DETRIMENTAL(spellType) && !c->IsAttackAllowed(tar)) {
c->Message(Chat::Yellow, "You cannot attack [%s].", tar->GetCleanName());
return;
}
if (BOT_SPELL_TYPES_BENEFICIAL(spellType)) {
if (!tar->IsOfClientBot() && !(tar->IsPet() && tar->GetOwner() && tar->GetOwner()->IsOfClientBot())) {
c->Message(Chat::Yellow, "[%s] is an invalid target.", tar->GetCleanName());
return;
}
}
}
LogTestDebug("{}: Attempting {} on {}", __LINE__, c->GetSpellTypeNameByID(spellType), (tar ? tar->GetCleanName() : "NOBODY")); //deleteme
switch (spellType) {
case BotSpellTypes::Stun:
case BotSpellTypes::AEStun:
if (tar->GetSpecialAbility(SpecialAbility::StunImmunity)) {
c->Message(Chat::Yellow, "[%s] is immune to stuns.", tar->GetCleanName());
return;
}
break;
switch (spellType) { //Target Checks
case BotSpellTypes::Resurrect:
if (!tar->IsCorpse() || !tar->CastToCorpse()->IsPlayerCorpse()) {
c->Message(Chat::Yellow, "[%s] is an invalid target. I can only resurrect player corpses.", tar->GetCleanName());
c->Message(Chat::Yellow, "[%s] is not a player's corpse.", tar->GetCleanName());
return;
}
break;
case BotSpellTypes::Identify:
case BotSpellTypes::SendHome:
case BotSpellTypes::BindAffinity:
case BotSpellTypes::SummonCorpse:
if (!tar->IsClient() || !c->IsInGroupOrRaid(tar)) {
c->Message(Chat::Yellow, "[%s] is an invalid target. Only players in your group or raid are eligible targets.", tar->GetCleanName());
return;
}
break;
default:
if (BOT_SPELL_TYPES_DETRIMENTAL(spellType) && !c->IsAttackAllowed(tar)) {
c->Message(Chat::Yellow, "You cannot attack [%s].", tar->GetCleanName());
return;
}
if (BOT_SPELL_TYPES_BENEFICIAL(spellType)) {
if (
(!tar->IsOfClientBot() && !(tar->IsPet() && tar->GetOwner() && tar->GetOwner()->IsOfClientBot())) ||
((tar->IsOfClientBot() && !c->IsInGroupOrRaid(tar)) || (tar->GetOwner() && tar->GetOwner()->IsOfClientBot() && !c->IsInGroupOrRaid(tar->GetOwner())))
) {
c->Message(Chat::Yellow, "[%s] is an invalid target. Only players in your group or raid are eligible targets.", tar->GetCleanName());
return;
}
}
break;
}
const int ab_mask = ActionableBots::ABM_Type1;
std::string actionableArg = sep->arg[ab_arg];
if (actionableArg.empty()) {
actionableArg = "spawned";
}
std::string class_race_arg = sep->arg[ab_arg];
bool class_race_check = false;
@@ -219,7 +374,7 @@ void bot_command_cast(Client* c, const Seperator* sep)
std::list<Bot*> sbl;
if (ActionableBots::PopulateSBL(c, sep->arg[ab_arg], sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
if (ActionableBots::PopulateSBL(c, actionableArg, sbl, ab_mask, !class_race_check ? sep->arg[ab_arg + 1] : nullptr, class_race_check ? atoi(sep->arg[ab_arg + 1]) : 0) == ActionableBots::ABT_None) {
return;
}
@@ -240,7 +395,8 @@ void bot_command_cast(Client* c, const Seperator* sep)
/*
TODO bot rewrite -
FIX: Snares, Group Cures, OOC Song, Precombat, HateRedux, Fear/AE Fear
FIX: Depart, SummonCorpse, Lull,
Group Cures, Precombat, Fear/AE Fear
ICB (SK) casting hate on friendly but not hostile?
NEED TO CHECK: precombat, AE Dispel, AE Lifetap
DO I NEED A PBAE CHECK???
@@ -250,7 +406,7 @@ void bot_command_cast(Client* c, const Seperator* sep)
}
Mob* newTar = tar;
LogTestDebug("{}: Attempting {} on {}", __LINE__, c->GetSpellTypeNameByID(spellType), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
LogTestDebug("{}: {} says, 'Attempting {} [{}] on {}'", __LINE__, bot_iter->GetCleanName(), c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
if (!SpellTypeRequiresTarget(spellType, bot_iter->GetClass())) {
newTar = bot_iter;
}
@@ -279,11 +435,11 @@ void bot_command_cast(Client* c, const Seperator* sep)
continue;
}
LogTestDebug("{}: Attempting {} on {}", __LINE__, c->GetSpellTypeNameByID(spellType), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
LogTestDebug("{}: {} says, 'Attempting {} [{}] on {}'", __LINE__, bot_iter->GetCleanName(), c->GetSpellTypeNameByID(spellType), (subType != UINT16_MAX ? c->GetSubTypeNameByID(subType) : "Standard"), (newTar ? newTar->GetCleanName() : "NOBODY")); //deleteme
bot_iter->SetCommandedSpell(true);
if (bot_iter->AICastSpell(newTar, 100, spellType)) {
if (bot_iter->AICastSpell(newTar, 100, spellType, subTargetType, subType)) {
if (!firstFound) {
firstFound = bot_iter;
}
-54
View File
@@ -1,54 +0,0 @@
#include "../bot_command.h"
void bot_command_charm(Client *c, const Seperator *sep)
{
auto local_list = &bot_command_spells[BCEnum::SpT_Charm];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Charm) || helper_command_alias_fail(c, "bot_command_charm", sep->arg[0], "charm"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: <enemy_target> %s ([option: dire])", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Charm);
return;
}
bool dire = false;
std::string dire_arg = sep->arg[1];
if (!dire_arg.compare("dire"))
dire = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToCharm();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->dire != dire)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, ENEMY);
if (!target_mob)
continue;
if (target_mob->IsCharmed()) {
c->Message(Chat::White, "Your <target> is already charmed");
return;
}
if (spells[local_entry->spell_id].max_value[EFFECTIDTOINDEX(1)] < target_mob->GetLevel())
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob, true);
if (!my_bot)
continue;
uint32 dont_root_before = 0;
if (helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id, true, &dont_root_before))
target_mob->SetDontRootMeBefore(dont_root_before);
break;
}
helper_no_available_bots(c, my_bot);
}
-71
View File
@@ -1,71 +0,0 @@
#include "../bot_command.h"
void bot_command_cure(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Cure];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Cure) || helper_command_alias_fail(c, "bot_command_cure", sep->arg[0], "cure"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s [ailment: blindness | disease | poison | curse | corruption]", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Cure);
return;
}
std::string ailment_arg = sep->arg[1];
auto ailment_type = BCEnum::AT_None;
if (!ailment_arg.compare("blindness"))
ailment_type = BCEnum::AT_Blindness;
else if (!ailment_arg.compare("disease"))
ailment_type = BCEnum::AT_Disease;
else if (!ailment_arg.compare("poison"))
ailment_type = BCEnum::AT_Poison;
else if (!ailment_arg.compare("curse"))
ailment_type = BCEnum::AT_Curse;
else if (!ailment_arg.compare("corruption"))
ailment_type = BCEnum::AT_Corruption;
if (ailment_type == BCEnum::AT_None) {
c->Message(Chat::White, "You must specify a cure [ailment] to use this command");
return;
}
local_list->sort([ailment_type](STBaseEntry* l, STBaseEntry* r) {
auto _l = l->SafeCastToCure(), _r = r->SafeCastToCure();
if (_l->cure_value[AILMENTIDTOINDEX(ailment_type)] < _r->cure_value[AILMENTIDTOINDEX(ailment_type)])
return true;
if (_l->cure_value[AILMENTIDTOINDEX(ailment_type)] == _r->cure_value[AILMENTIDTOINDEX(ailment_type)] && spells[_l->spell_id].mana < spells[_r->spell_id].mana)
return true;
if (_l->cure_value[AILMENTIDTOINDEX(ailment_type)] == _r->cure_value[AILMENTIDTOINDEX(ailment_type)] && spells[_l->spell_id].mana == spells[_r->spell_id].mana && _l->cure_total < _r->cure_total)
return true;
return false;
});
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToCure();
if (helper_spell_check_fail(local_entry))
continue;
if (!local_entry->cure_value[AILMENTIDTOINDEX(ailment_type)])
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-44
View File
@@ -1,44 +0,0 @@
#include "../bot_command.h"
void bot_command_escape(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Escape];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Escape) || helper_command_alias_fail(c, "bot_command_escape", sep->arg[0], "escape"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s ([option: lesser])", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Escape);
return;
}
bool use_lesser = false;
if (!strcasecmp(sep->arg[1], "lesser"))
use_lesser = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToEscape();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->lesser != use_lesser)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-38
View File
@@ -1,38 +0,0 @@
#include "../bot_command.h"
void bot_command_identify(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Identify];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Identify) || helper_command_alias_fail(c, "bot_command_identify", sep->arg[0], "identify"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Identify);
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter;
if (helper_spell_check_fail(local_entry))
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-57
View File
@@ -1,57 +0,0 @@
#include "../bot_command.h"
void bot_command_invisibility(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Invisibility];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Invisibility) || helper_command_alias_fail(c, "bot_command_invisibility", sep->arg[0], "invisibility"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s [invisibility: living | undead | animal | see]", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Invisibility);
return;
}
std::string invisibility = sep->arg[1];
BCEnum::IType invisibility_type = BCEnum::IT_None;
if (!invisibility.compare("living"))
invisibility_type = BCEnum::IT_Living;
else if (!invisibility.compare("undead"))
invisibility_type = BCEnum::IT_Undead;
else if (!invisibility.compare("animal"))
invisibility_type = BCEnum::IT_Animal;
else if (!invisibility.compare("see"))
invisibility_type = BCEnum::IT_See;
if (invisibility_type == BCEnum::IT_None) {
c->Message(Chat::White, "You must specify an [invisibility]");
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToInvisibility();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->invis_type != invisibility_type)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-38
View File
@@ -1,38 +0,0 @@
#include "../bot_command.h"
void bot_command_levitation(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Levitation];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Levitation) || helper_command_alias_fail(c, "bot_command_levitation", sep->arg[0], "levitation"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Levitation);
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter;
if (helper_spell_check_fail(local_entry))
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-41
View File
@@ -1,41 +0,0 @@
#include "../bot_command.h"
void bot_command_mesmerize(Client *c, const Seperator *sep)
{
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: <enemy_target> %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Mesmerize);
return;
}
bool isSuccess = false;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
for (auto bot_iter : sbl) {
std::list<BotSpell_wPriority> botSpellList = bot_iter->GetPrioritizedBotSpellsBySpellType(bot_iter, BotSpellTypes::Mez, c->GetTarget(), IsAEBotSpellType(BotSpellTypes::Mez));
for (const auto& s : botSpellList) {
if (!IsValidSpell(s.SpellId)) {
continue;
}
if (!bot_iter->IsInGroupOrRaid(c)) {
continue;
}
if (!bot_iter->CastChecks(s.SpellId, c->GetTarget(), BotSpellTypes::Mez, false, false)) {
continue;
}
if (bot_iter->CommandedDoSpellCast(s.SpellIndex, c->GetTarget(), s.ManaCost)) {
bot_iter->BotGroupSay(bot_iter, "Casting %s [%s] on %s.", GetSpellName(s.SpellId), bot_iter->GetSpellTypeNameByID(BotSpellTypes::Mez), c->GetTarget()->GetCleanName());
isSuccess = true;
}
}
}
if (!isSuccess) {
helper_no_available_bots(c);
}
}
-50
View File
@@ -1,50 +0,0 @@
#include "../bot_command.h"
void bot_command_movement_speed(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_MovementSpeed];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_MovementSpeed) || helper_command_alias_fail(c, "bot_command_movement_speed", sep->arg[0], "movementspeed"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s ([group | sow])", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_MovementSpeed);
return;
}
bool group = false;
bool sow = false;
std::string arg1 = sep->arg[1];
if (!arg1.compare("group"))
group = true;
else if (!arg1.compare("sow"))
sow = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToMovementSpeed();
if (helper_spell_check_fail(local_entry))
continue;
if (!sow && (local_entry->group != group))
continue;
if (sow && (local_entry->spell_id != 278)) // '278' = single-target "Spirit of Wolf"
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-73
View File
@@ -1,73 +0,0 @@
#include "../bot_command.h"
void bot_command_resistance(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Resistance];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Resistance) || helper_command_alias_fail(c, "bot_command_resistance", sep->arg[0], "resistance"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s [resistance: fire | cold | poison | disease | magic | corruption]", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Resistance);
return;
}
std::string resistance_arg = sep->arg[1];
auto resistance_type = BCEnum::RT_None;
if (!resistance_arg.compare("fire"))
resistance_type = BCEnum::RT_Fire;
else if (!resistance_arg.compare("cold"))
resistance_type = BCEnum::RT_Cold;
else if (!resistance_arg.compare("poison"))
resistance_type = BCEnum::RT_Poison;
else if (!resistance_arg.compare("disease"))
resistance_type = BCEnum::RT_Disease;
else if (!resistance_arg.compare("magic"))
resistance_type = BCEnum::RT_Magic;
else if (!resistance_arg.compare("corruption"))
resistance_type = BCEnum::RT_Corruption;
if (resistance_type == BCEnum::RT_None) {
c->Message(Chat::White, "You must specify a [resistance]");
return;
}
local_list->sort([resistance_type](STBaseEntry* l, STBaseEntry* r) {
auto _l = l->SafeCastToResistance(), _r = r->SafeCastToResistance();
if (_l->resist_value[RESISTANCEIDTOINDEX(resistance_type)] > _r->resist_value[RESISTANCEIDTOINDEX(resistance_type)])
return true;
if (_l->resist_value[RESISTANCEIDTOINDEX(resistance_type)] == _r->resist_value[RESISTANCEIDTOINDEX(resistance_type)] && spells[_l->spell_id].mana < spells[_r->spell_id].mana)
return true;
if (_l->resist_value[RESISTANCEIDTOINDEX(resistance_type)] == _r->resist_value[RESISTANCEIDTOINDEX(resistance_type)] && spells[_l->spell_id].mana == spells[_r->spell_id].mana && _l->resist_total > _r->resist_total)
return true;
return false;
});
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToResistance();
if (helper_spell_check_fail(local_entry))
continue;
if (!local_entry->resist_value[RESISTANCEIDTOINDEX(resistance_type)])
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-57
View File
@@ -1,57 +0,0 @@
#include "../bot_command.h"
void bot_command_resurrect(Client *c, const Seperator *sep)
{
// Obscure bot spell code prohibits the aoe portion from working correctly...
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Resurrect];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Resurrect) || helper_command_alias_fail(c, "bot_command_resurrect", sep->arg[0], "resurrect"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
//c->Message(Chat::White, "usage: <corpse_target> %s ([option: aoe])", sep->arg[0]);
c->Message(Chat::White, "usage: <corpse_target> %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Resurrect);
return;
}
bool aoe = false;
//std::string aoe_arg = sep->arg[1];
//if (!aoe_arg.compare("aoe"))
// aoe = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToResurrect();
if (helper_spell_check_fail(local_entry))
continue;
//if (local_entry->aoe != aoe)
// continue;
if (local_entry->aoe)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
//if (!target_mob && !local_entry->aoe)
// continue;
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
//if (local_entry->aoe)
// target_mob = my_bot;
uint32 dont_root_before = 0;
if (helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id, true, &dont_root_before))
target_mob->SetDontRootMeBefore(dont_root_before);
break;
}
helper_no_available_bots(c, my_bot);
}
-38
View File
@@ -1,38 +0,0 @@
#include "../bot_command.h"
void bot_command_rune(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Rune];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Rune) || helper_command_alias_fail(c, "bot_command_rune", sep->arg[0], "rune"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Rune);
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter;
if (helper_spell_check_fail(local_entry))
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-47
View File
@@ -1,47 +0,0 @@
#include "../bot_command.h"
void bot_command_send_home(Client *c, const Seperator *sep)
{
// Obscure bot spell code prohibits the aoe portion from working correctly...
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_SendHome];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_SendHome) || helper_command_alias_fail(c, "bot_command_send_home", sep->arg[0], "sendhome"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s ([option: group])", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_SendHome);
return;
}
bool group = false;
std::string group_arg = sep->arg[1];
if (!group_arg.compare("group"))
group = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToSendHome();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->group != group)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-50
View File
@@ -1,50 +0,0 @@
#include "../bot_command.h"
void bot_command_size(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_Size];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Size) || helper_command_alias_fail(c, "bot_command_size", sep->arg[0], "size"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s [grow | shrink]", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_Size);
return;
}
std::string size_arg = sep->arg[1];
auto size_type = BCEnum::SzT_Reduce;
if (!size_arg.compare("grow")) {
size_type = BCEnum::SzT_Enlarge;
}
else if (size_arg.compare("shrink")) {
c->Message(Chat::White, "This command requires a [grow | shrink] argument");
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter->SafeCastToSize();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->size_type != size_type)
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
-38
View File
@@ -1,38 +0,0 @@
#include "../bot_command.h"
void bot_command_water_breathing(Client *c, const Seperator *sep)
{
bcst_list* local_list = &bot_command_spells[BCEnum::SpT_WaterBreathing];
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_WaterBreathing) || helper_command_alias_fail(c, "bot_command_water_breathing", sep->arg[0], "waterbreathing"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(Chat::White, "usage: (<friendly_target>) %s", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_WaterBreathing);
return;
}
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
std::list<Bot*> sbl;
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
bool cast_success = false;
for (auto list_iter : *local_list) {
auto local_entry = list_iter;
if (helper_spell_check_fail(local_entry))
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
if (!target_mob)
continue;
my_bot = ActionableBots::Select_ByMinLevelAndClass(c, local_entry->target_type, sbl, local_entry->spell_level, local_entry->caster_class, target_mob);
if (!my_bot)
continue;
cast_success = helper_cast_standard_spell(my_bot, target_mob, local_entry->spell_id);
break;
}
helper_no_available_bots(c, my_bot);
}
+50 -9
View File
@@ -21,7 +21,7 @@
#include "../common/repositories/bot_spells_entries_repository.h"
#include "../common/repositories/npc_spells_repository.h"
bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType) {
bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType, uint16 subTargetType, uint16 subType) {
if (!tar) {
return false;
}
@@ -48,7 +48,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType) {
return false;
}
if (spellType != BotSpellTypes::Resurrect && tar->GetAppearance() == eaDead) {
if ((spellType != BotSpellTypes::Resurrect && spellType != BotSpellTypes::SummonCorpse) && tar->GetAppearance() == eaDead) {
if (!((tar->IsClient() && tar->CastToClient()->GetFeigned()) || tar->IsBot())) {
return false;
}
@@ -83,7 +83,12 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType) {
}
break;
//SpecialAbility::PacifyImmunity -- TODO bot rewrite
case BotSpellTypes::Lull:
if (tar->GetSpecialAbility(SpecialAbility::PacifyImmunity)) {
return false;
}
break;
case BotSpellTypes::Fear:
if (tar->GetSpecialAbility(SpecialAbility::FearImmunity)) {
return false;
@@ -128,6 +133,17 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType) {
case BotSpellTypes::PetDamageShields:
case BotSpellTypes::ResistBuffs:
case BotSpellTypes::PetResistBuffs:
case BotSpellTypes::Teleport:
case BotSpellTypes::Succor:
case BotSpellTypes::BindAffinity:
case BotSpellTypes::Identify:
case BotSpellTypes::Levitate:
case BotSpellTypes::Rune:
case BotSpellTypes::WaterBreathing:
case BotSpellTypes::Size:
case BotSpellTypes::Invisibility:
case BotSpellTypes::MovementSpeed:
case BotSpellTypes::SendHome:
if (!tar->IsOfClientBot() && !(tar->IsPet() && tar->GetOwner() && tar->GetOwner()->IsOfClientBot())) {
return false;
}
@@ -182,6 +198,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType) {
return BotCastPet(tar, botClass, botSpell, spellType);
case BotSpellTypes::Resurrect:
case BotSpellTypes::SummonCorpse:
if (!tar->IsCorpse() || !tar->CastToCorpse()->IsPlayerCorpse()) {
return false;
}
@@ -197,7 +214,7 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint16 spellType) {
break;
}
std::list<BotSpell_wPriority> botSpellList = GetPrioritizedBotSpellsBySpellType(this, spellType, tar, IsAEBotSpellType(spellType));
std::list<BotSpell_wPriority> botSpellList = GetPrioritizedBotSpellsBySpellType(this, spellType, tar, IsAEBotSpellType(spellType), subTargetType, subType);
for (const auto& s : botSpellList) {
@@ -643,7 +660,7 @@ bool Bot::AI_PursueCastCheck() {
continue;
}
if (currentCast.spellType == BotSpellTypes::Resurrect || currentCast.spellType == BotSpellTypes::Charm) { // Unsupported by AI currently.
if (IsCommandedSpellType(currentCast.spellType) || currentCast.spellType == BotSpellTypes::Resurrect || currentCast.spellType == BotSpellTypes::Charm) { // Unsupported by AI currently.
continue;
}
@@ -706,7 +723,7 @@ bool Bot::AI_IdleCastCheck() {
continue;
}
if (currentCast.spellType == BotSpellTypes::Resurrect || currentCast.spellType == BotSpellTypes::Charm) { // Unsupported by AI currently.
if (IsCommandedSpellType(currentCast.spellType) || currentCast.spellType == BotSpellTypes::Resurrect || currentCast.spellType == BotSpellTypes::Charm) { // Unsupported by AI currently.
continue;
}
@@ -756,7 +773,7 @@ bool Bot::AI_EngagedCastCheck() {
continue;
}
if (currentCast.spellType == BotSpellTypes::Resurrect || currentCast.spellType == BotSpellTypes::Charm) { // Unsupported by AI currently.
if (IsCommandedSpellType(currentCast.spellType) || currentCast.spellType == BotSpellTypes::Resurrect || currentCast.spellType == BotSpellTypes::Charm) { // Unsupported by AI currently.
continue;
}
@@ -979,7 +996,7 @@ std::list<BotSpell> Bot::GetBotSpellsBySpellType(Bot* botCaster, uint16 spellTyp
return result;
}
std::list<BotSpell_wPriority> Bot::GetPrioritizedBotSpellsBySpellType(Bot* botCaster, uint16 spellType, Mob* tar, bool AE) {
std::list<BotSpell_wPriority> Bot::GetPrioritizedBotSpellsBySpellType(Bot* botCaster, uint16 spellType, Mob* tar, bool AE, uint16 subTargetType, uint16 subType) {
std::list<BotSpell_wPriority> result;
if (botCaster && botCaster->AI_HasSpells()) {
@@ -1001,6 +1018,16 @@ std::list<BotSpell_wPriority> Bot::GetPrioritizedBotSpellsBySpellType(Bot* botCa
(botSpellList[i].type == spellType || botSpellList[i].type == botCaster->GetSpellListSpellType(spellType)) &&
botCaster->IsValidSpellTypeBySpellID(spellType, botSpellList[i].spellid)
) {
if (
botCaster->IsCommandedSpell() &&
(
!botCaster->IsValidSpellTypeSubType(spellType, subTargetType, botSpellList[i].spellid) ||
!botCaster->IsValidSpellTypeSubType(spellType, subType, botSpellList[i].spellid)
)
) {
continue;
}
if (!AE && IsAnyAESpell(botSpellList[i].spellid) && !IsGroupSpell(botSpellList[i].spellid)) {
continue;
}
@@ -2040,7 +2067,7 @@ BotSpell Bot::GetBestBotSpellForCure(Bot* botCaster, Mob* tar, uint16 spellType)
return result;
}
uint8 Bot::GetChanceToCastBySpellType(uint16 spellType) //TODO bot rewrite - adjust, move AEs to own rule?
uint8 Bot::GetChanceToCastBySpellType(uint16 spellType)
{
switch (spellType) {
case BotSpellTypes::AENukes:
@@ -2072,6 +2099,18 @@ uint8 Bot::GetChanceToCastBySpellType(uint16 spellType) //TODO bot rewrite - adj
case BotSpellTypes::PetResistBuffs:
case BotSpellTypes::DamageShields:
case BotSpellTypes::PetDamageShields:
case BotSpellTypes::Teleport:
case BotSpellTypes::Succor:
case BotSpellTypes::BindAffinity:
case BotSpellTypes::Identify:
case BotSpellTypes::Levitate:
case BotSpellTypes::Rune:
case BotSpellTypes::WaterBreathing:
case BotSpellTypes::Size:
case BotSpellTypes::Invisibility:
case BotSpellTypes::MovementSpeed:
case BotSpellTypes::SendHome:
case BotSpellTypes::SummonCorpse:
return RuleI(Bots, PercentChanceToCastBuff);
case BotSpellTypes::Escape:
return RuleI(Bots, PercentChanceToCastEscape);
@@ -2949,6 +2988,7 @@ void Bot::CheckBotSpells() {
break;
}
break;
//TODO bot rewrite - add commanded types
default:
break;
@@ -3044,6 +3084,7 @@ void Bot::CheckBotSpells() {
else if (IsEffectInSpell(spell_id, SE_Revive)) {
correctType = BotSpellTypes::Resurrect;
}
//TODO bot rewrite - add commanded types
if (!valid || (correctType == UINT16_MAX) || (s.type != correctType)) {
LogBotSpellTypeChecks("{} [#{}] is incorrect. It is currently set as {} [#{}] and should be {} [#{}]"
+125
View File
@@ -8703,6 +8703,12 @@ uint16 Mob::GetSpellTypeIDByShortName(std::string spellTypeString) {
}
}
for (int i = BotSpellTypes::COMMANDED_START; i <= BotSpellTypes::COMMANDED_END; ++i) {
if (!Strings::ToLower(spellTypeString).compare(GetSpellTypeShortNameByID(i))) {
return i;
}
}
return UINT16_MAX;
}
@@ -8875,6 +8881,45 @@ std::string Mob::GetSpellTypeNameByID(uint16 spellType) {
case BotSpellTypes::PetResistBuffs:
spellTypeName = "Pet Resist Buff";
break;
case BotSpellTypes::Lull:
spellTypeName = "Lull";
break;
case BotSpellTypes::Teleport:
spellTypeName = "Teleport";
break;
case BotSpellTypes::Succor:
spellTypeName = "Succor";
break;
case BotSpellTypes::BindAffinity:
spellTypeName = "Bind Affinity";
break;
case BotSpellTypes::Identify:
spellTypeName = "Identify";
break;
case BotSpellTypes::Levitate:
spellTypeName = "Levitate";
break;
case BotSpellTypes::Rune:
spellTypeName = "Rune";
break;
case BotSpellTypes::WaterBreathing:
spellTypeName = "Water Breathing";
break;
case BotSpellTypes::Size:
spellTypeName = "Size";
break;
case BotSpellTypes::Invisibility:
spellTypeName = "Invisibility";
break;
case BotSpellTypes::MovementSpeed:
spellTypeName = "Movement Speed";
break;
case BotSpellTypes::SendHome:
spellTypeName = "Send Home";
break;
case BotSpellTypes::SummonCorpse:
spellTypeName = "Summon Corpse";
break;
default:
break;
}
@@ -9051,6 +9096,45 @@ std::string Mob::GetSpellTypeShortNameByID(uint16 spellType) {
case BotSpellTypes::PetResistBuffs:
spellTypeName = "petresistbuffs";
break;
case BotSpellTypes::Lull:
spellTypeName = "lull";
break;
case BotSpellTypes::Teleport:
spellTypeName = "teleport";
break;
case BotSpellTypes::Succor:
spellTypeName = "succor";
break;
case BotSpellTypes::BindAffinity:
spellTypeName = "bindaffinity";
break;
case BotSpellTypes::Identify:
spellTypeName = "identify";
break;
case BotSpellTypes::Levitate:
spellTypeName = "levitate";
break;
case BotSpellTypes::Rune:
spellTypeName = "rune";
break;
case BotSpellTypes::WaterBreathing:
spellTypeName = "waterbreathing";
break;
case BotSpellTypes::Size:
spellTypeName = "size";
break;
case BotSpellTypes::Invisibility:
spellTypeName = "invisibility";
break;
case BotSpellTypes::MovementSpeed:
spellTypeName = "movementspeed";
break;
case BotSpellTypes::SendHome:
spellTypeName = "sendhome";
break;
case BotSpellTypes::SummonCorpse:
spellTypeName = "summoncorpse";
break;
default:
break;
}
@@ -9058,6 +9142,47 @@ std::string Mob::GetSpellTypeShortNameByID(uint16 spellType) {
return spellTypeName;
}
std::string Mob::GetSubTypeNameByID(uint16 subType) {
std::string subTypeName = "null";
switch (subType) {
case CommandedSubTypes::SingleTarget:
subTypeName = "SingleTarget";
break;
case CommandedSubTypes::GroupTarget:
subTypeName = "GroupTarget";
break;
case CommandedSubTypes::AETarget:
subTypeName = "AETarget";
break;
case CommandedSubTypes::SeeInvis:
subTypeName = "SeeInvis";
break;
case CommandedSubTypes::Invis:
subTypeName = "Invis";
break;
case CommandedSubTypes::InvisUndead:
subTypeName = "InvisUndead";
break;
case CommandedSubTypes::InvisAnimals:
subTypeName = "InvisAnimals";
break;
case CommandedSubTypes::Shrink:
subTypeName = "Shrink";
break;
case CommandedSubTypes::Grow:
subTypeName = "Grow";
break;
case CommandedSubTypes::Selo:
subTypeName = "Selo";
break;
default:
break;
}
return subTypeName;
}
bool Mob::GetDefaultSpellHold(uint16 spellType, uint8 stance) {
switch (spellType) {
case BotSpellTypes::Nuke:
+2 -1
View File
@@ -435,7 +435,8 @@ public:
uint16 GetSpellTypeIDByShortName(std::string spellTypeString);
std::string GetSpellTypeNameByID(uint16 spellType);
std::string GetSpellTypeShortNameByID(uint16 spellType);
std::string GetSpellTypeShortNameByID(uint16 spellType);
std::string GetSubTypeNameByID(uint16 subType);
bool GetDefaultSpellHold(uint16 spellType, uint8 stance = Stance::Balanced);
uint16 GetDefaultSpellDelay(uint16 spellType, uint8 stance = Stance::Balanced);