mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-25 10:28:23 +00:00
Remove bcspells, fix helper_send_usage_required_bots
This commit is contained in:
@@ -3607,6 +3607,8 @@ bool Bot::Spawn(Client* botCharacterOwner) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MapSpellTypeLevels();
|
||||||
|
|
||||||
if (RuleB(Bots, RunSpellTypeChecksOnSpawn)) {
|
if (RuleB(Bots, RunSpellTypeChecksOnSpawn)) {
|
||||||
OwnerMessage("Running SpellType checks. There may be some spells that are mislabeled as incorrect. Use this as a loose guideline.");
|
OwnerMessage("Running SpellType checks. There may be some spells that are mislabeled as incorrect. Use this as a loose guideline.");
|
||||||
CheckBotSpells(); //This runs through a serious of checks and outputs any spells that are set to the wrong spell type in the database
|
CheckBotSpells(); //This runs through a serious of checks and outputs any spells that are set to the wrong spell type in the database
|
||||||
|
|||||||
@@ -609,6 +609,7 @@ public:
|
|||||||
bool HasValidAETarget(Bot* caster, uint16 spell_id, uint16 spell_type, Mob* tar);
|
bool HasValidAETarget(Bot* caster, uint16 spell_id, uint16 spell_type, Mob* tar);
|
||||||
|
|
||||||
void CheckBotSpells();
|
void CheckBotSpells();
|
||||||
|
void MapSpellTypeLevels();
|
||||||
|
|
||||||
[[nodiscard]] int GetMaxBuffSlots() const final { return EQ::spells::LONG_BUFFS; }
|
[[nodiscard]] int GetMaxBuffSlots() const final { return EQ::spells::LONG_BUFFS; }
|
||||||
[[nodiscard]] int GetMaxSongSlots() const final { return EQ::spells::SHORT_BUFFS; }
|
[[nodiscard]] int GetMaxSongSlots() const final { return EQ::spells::SHORT_BUFFS; }
|
||||||
@@ -951,6 +952,7 @@ public:
|
|||||||
void SetBotTimers(std::vector<BotTimer_Struct> timers) { bot_timers = timers; }
|
void SetBotTimers(std::vector<BotTimer_Struct> timers) { bot_timers = timers; }
|
||||||
std::vector<BotBlockedBuffs_Struct> GetBotBlockedBuffs() { return bot_blocked_buffs; }
|
std::vector<BotBlockedBuffs_Struct> GetBotBlockedBuffs() { return bot_blocked_buffs; }
|
||||||
void SetBotBlockedBuffs(std::vector<BotBlockedBuffs_Struct> blocked_buffs) { bot_blocked_buffs = blocked_buffs; }
|
void SetBotBlockedBuffs(std::vector<BotBlockedBuffs_Struct> blocked_buffs) { bot_blocked_buffs = blocked_buffs; }
|
||||||
|
const CommandedSpellTypesMinLevelMap& GetCommandedSpellTypesMinLevels() { return commanded_spells_min_level; }
|
||||||
uint32 GetLastZoneID() const { return _lastZoneId; }
|
uint32 GetLastZoneID() const { return _lastZoneId; }
|
||||||
int32 GetBaseAC() const { return _baseAC; }
|
int32 GetBaseAC() const { return _baseAC; }
|
||||||
int32 GetBaseATK() const { return _baseATK; }
|
int32 GetBaseATK() const { return _baseATK; }
|
||||||
@@ -1079,6 +1081,9 @@ protected:
|
|||||||
std::vector<BotSpells_Struct> AIBot_spells;
|
std::vector<BotSpells_Struct> AIBot_spells;
|
||||||
std::vector<BotSpells_Struct> AIBot_spells_enforced;
|
std::vector<BotSpells_Struct> AIBot_spells_enforced;
|
||||||
std::unordered_map<uint16, std::vector<BotSpells_Struct_wIndex>> AIBot_spells_by_type;
|
std::unordered_map<uint16, std::vector<BotSpells_Struct_wIndex>> AIBot_spells_by_type;
|
||||||
|
|
||||||
|
CommandedSpellTypesMinLevelMap commanded_spells_min_level;
|
||||||
|
|
||||||
std::vector<BotTimer_Struct> bot_timers;
|
std::vector<BotTimer_Struct> bot_timers;
|
||||||
std::vector<BotBlockedBuffs_Struct> bot_blocked_buffs;
|
std::vector<BotBlockedBuffs_Struct> bot_blocked_buffs;
|
||||||
|
|
||||||
|
|||||||
+49
-1307
File diff suppressed because it is too large
Load Diff
+13
-633
@@ -27,194 +27,6 @@ class Seperator;
|
|||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
#include "dialogue_window.h"
|
#include "dialogue_window.h"
|
||||||
|
|
||||||
class BCEnum
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef enum SpellType {
|
|
||||||
SpT_None = 0,
|
|
||||||
SpT_BindAffinity,
|
|
||||||
SpT_Charm,
|
|
||||||
SpT_Cure,
|
|
||||||
SpT_Depart,
|
|
||||||
SpT_Escape,
|
|
||||||
SpT_Identify,
|
|
||||||
SpT_Invisibility,
|
|
||||||
SpT_Levitation,
|
|
||||||
SpT_Lull,
|
|
||||||
SpT_Mesmerize,
|
|
||||||
SpT_MovementSpeed,
|
|
||||||
SpT_Resistance,
|
|
||||||
SpT_Resurrect,
|
|
||||||
SpT_Rune,
|
|
||||||
SpT_SendHome,
|
|
||||||
SpT_Size,
|
|
||||||
SpT_Stance,
|
|
||||||
SpT_SummonCorpse,
|
|
||||||
SpT_WaterBreathing
|
|
||||||
} SpType;
|
|
||||||
static const int SpellTypeFirst = SpT_BindAffinity;
|
|
||||||
static const int SpellTypeLast = SpT_WaterBreathing;
|
|
||||||
|
|
||||||
typedef enum TargetType {
|
|
||||||
TT_None = 0,
|
|
||||||
TT_Corpse,
|
|
||||||
TT_Self,
|
|
||||||
TT_Animal,
|
|
||||||
TT_Undead,
|
|
||||||
TT_Summoned,
|
|
||||||
TT_Plant,
|
|
||||||
TT_Single,
|
|
||||||
TT_GroupV1,
|
|
||||||
TT_GroupV2,
|
|
||||||
TT_AECaster,
|
|
||||||
TT_AEBard,
|
|
||||||
TT_AETarget
|
|
||||||
} TType;
|
|
||||||
static const int TargetTypeFirst = TT_Corpse;
|
|
||||||
static const int TargetTypeLast = TT_AETarget;
|
|
||||||
static const int TargetTypeCount = 13;
|
|
||||||
|
|
||||||
typedef enum TargetMask {
|
|
||||||
TM_None = 0,
|
|
||||||
TM_Corpse = 1,
|
|
||||||
TM_Self = 2,
|
|
||||||
TM_Animal = 4,
|
|
||||||
TM_Undead = 8,
|
|
||||||
TM_Summoned = 16,
|
|
||||||
TM_Plant = 32,
|
|
||||||
TM_Single = 124, // currently, 2^6 + 2^{2..5}) -or- (64+32+16+8+4)
|
|
||||||
TM_GroupV1 = 128,
|
|
||||||
TM_GroupV2 = 256,
|
|
||||||
TM_AECaster = 512,
|
|
||||||
TM_AEBard = 1024,
|
|
||||||
TM_AETarget = 2048
|
|
||||||
} TMask;
|
|
||||||
|
|
||||||
typedef enum AppearanceFailType {
|
|
||||||
AFT_None = 0,
|
|
||||||
AFT_Value,
|
|
||||||
AFT_GenderRace,
|
|
||||||
AFT_Race
|
|
||||||
} AFType;
|
|
||||||
|
|
||||||
typedef enum AilmentType {
|
|
||||||
AT_None = 0,
|
|
||||||
AT_Blindness, // SE: 20
|
|
||||||
AT_Disease, // SE: 35
|
|
||||||
AT_Poison, // SE: 36
|
|
||||||
AT_Curse, // SE: 116
|
|
||||||
AT_Corruption // SE: 369
|
|
||||||
} AType;
|
|
||||||
static const int AilmentTypeCount = 5;
|
|
||||||
|
|
||||||
typedef enum InvisType {
|
|
||||||
IT_None = 0,
|
|
||||||
IT_Animal,
|
|
||||||
IT_Undead,
|
|
||||||
IT_Living,
|
|
||||||
IT_See
|
|
||||||
} IType;
|
|
||||||
|
|
||||||
typedef enum ResistanceType {
|
|
||||||
RT_None = 0,
|
|
||||||
RT_Fire, // SE: 46
|
|
||||||
RT_Cold, // SE: 47
|
|
||||||
RT_Poison, // SE: 48
|
|
||||||
RT_Disease, // SE: 49
|
|
||||||
RT_Magic, // SE: 50
|
|
||||||
RT_Corruption // SE: 370
|
|
||||||
} RType;
|
|
||||||
static const int ResistanceTypeCount = 6;
|
|
||||||
|
|
||||||
typedef enum SizeType {
|
|
||||||
SzT_None = 0,
|
|
||||||
SzT_Enlarge,
|
|
||||||
SzT_Reduce
|
|
||||||
} SzType;
|
|
||||||
|
|
||||||
typedef enum StanceType {
|
|
||||||
StT_None = 0,
|
|
||||||
StT_Aggressive,
|
|
||||||
StT_Defensive
|
|
||||||
} StType;
|
|
||||||
|
|
||||||
static std::string SpellTypeEnumToString(BCEnum::SpType spell_type) {
|
|
||||||
switch (spell_type) {
|
|
||||||
case SpT_BindAffinity:
|
|
||||||
return "SpT_BindAffinity";
|
|
||||||
case SpT_Charm:
|
|
||||||
return "SpT_Charm";
|
|
||||||
case SpT_Cure:
|
|
||||||
return "SpT_Cure";
|
|
||||||
case SpT_Depart:
|
|
||||||
return "SpT_Depart";
|
|
||||||
case SpT_Escape:
|
|
||||||
return "SpT_Escape";
|
|
||||||
case SpT_Identify:
|
|
||||||
return "SpT_Identify";
|
|
||||||
case SpT_Invisibility:
|
|
||||||
return "SpT_Invisibility";
|
|
||||||
case SpT_Levitation:
|
|
||||||
return "SpT_Levitation";
|
|
||||||
case SpT_Lull:
|
|
||||||
return "SpT_Lull";
|
|
||||||
case SpT_Mesmerize:
|
|
||||||
return "SpT_Mesmerize";
|
|
||||||
case SpT_MovementSpeed:
|
|
||||||
return "SpT_MovementSpeed";
|
|
||||||
case SpT_Resistance:
|
|
||||||
return "SpT_Resistance";
|
|
||||||
case SpT_Resurrect:
|
|
||||||
return "SpT_Resurrect";
|
|
||||||
case SpT_Rune:
|
|
||||||
return "SpT_Rune";
|
|
||||||
case SpT_SendHome:
|
|
||||||
return "SpT_SendHome";
|
|
||||||
case SpT_Size:
|
|
||||||
return "SpT_Size";
|
|
||||||
case SpT_Stance:
|
|
||||||
return "SpT_Stance";
|
|
||||||
case SpT_SummonCorpse:
|
|
||||||
return "SpT_SummonCorpse";
|
|
||||||
case SpT_WaterBreathing:
|
|
||||||
return "SpT_WaterBreathing";
|
|
||||||
default:
|
|
||||||
return "SpT_None";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string TargetTypeEnumToString(BCEnum::TType target_type) {
|
|
||||||
switch (target_type) {
|
|
||||||
case TT_Self:
|
|
||||||
return "TT_Self";
|
|
||||||
case TT_Animal:
|
|
||||||
return "TT_Animal";
|
|
||||||
case TT_Undead:
|
|
||||||
return "TT_Undead";
|
|
||||||
case TT_Summoned:
|
|
||||||
return "TT_Summoned";
|
|
||||||
case TT_Plant:
|
|
||||||
return "TT_Plant";
|
|
||||||
case TT_Single:
|
|
||||||
return "TT_Single";
|
|
||||||
case TT_GroupV1:
|
|
||||||
return "TT_GroupV1";
|
|
||||||
case TT_GroupV2:
|
|
||||||
return "TT_GroupV2";
|
|
||||||
case TT_AECaster:
|
|
||||||
return "TT_AECaster";
|
|
||||||
case TT_AEBard:
|
|
||||||
return "TT_AEBard";
|
|
||||||
case TT_AETarget:
|
|
||||||
return "TT_AETarget";
|
|
||||||
case TT_Corpse:
|
|
||||||
return "TT_Corpse";
|
|
||||||
default:
|
|
||||||
return "TT_None";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
#define HP_RATIO_DELTA 5.0f
|
#define HP_RATIO_DELTA 5.0f
|
||||||
@@ -222,14 +34,17 @@ namespace
|
|||||||
enum { EffectIDFirst = 1, EffectIDLast = 12 };
|
enum { EffectIDFirst = 1, EffectIDLast = 12 };
|
||||||
|
|
||||||
#define VALIDATECLASSID(x) ((x >= Class::Warrior && x <= Class::Berserker) ? (x) : (0))
|
#define VALIDATECLASSID(x) ((x >= Class::Warrior && x <= Class::Berserker) ? (x) : (0))
|
||||||
#define CLASSIDTOINDEX(x) ((x >= Class::Warrior && x <= Class::Berserker) ? (x - 1) : (0))
|
|
||||||
#define EFFECTIDTOINDEX(x) ((x >= EffectIDFirst && x <= EffectIDLast) ? (x - 1) : (0))
|
|
||||||
#define AILMENTIDTOINDEX(x) ((x >= BCEnum::AT_Blindness && x <= BCEnum::AT_Corruption) ? (x - 1) : (0))
|
|
||||||
#define RESISTANCEIDTOINDEX(x) ((x >= BCEnum::RT_Fire && x <= BCEnum::RT_Corruption) ? (x - 1) : (0))
|
|
||||||
|
|
||||||
// ActionableTarget action_type
|
// ActionableTarget action_type
|
||||||
#define FRIENDLY true
|
#define FRIENDLY true
|
||||||
#define ENEMY false
|
#define ENEMY false
|
||||||
|
|
||||||
|
enum {
|
||||||
|
AFT_None = 0,
|
||||||
|
AFT_Value,
|
||||||
|
AFT_GenderRace,
|
||||||
|
AFT_Race
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MyBots
|
namespace MyBots
|
||||||
@@ -759,128 +574,6 @@ namespace ActionableTarget
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Mob* VerifyFriendly(Client* bot_owner, BCEnum::TType target_type, bool return_me_on_null_target = true) {
|
|
||||||
if (IsAttackable(bot_owner, bot_owner->GetTarget()) || target_type == BCEnum::TT_None)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
auto target_mob = bot_owner->GetTarget();
|
|
||||||
Mob* verified_friendly = nullptr;
|
|
||||||
switch (target_type) {
|
|
||||||
case BCEnum::TT_Single:
|
|
||||||
case BCEnum::TT_GroupV1:
|
|
||||||
case BCEnum::TT_GroupV2:
|
|
||||||
case BCEnum::TT_AETarget:
|
|
||||||
verified_friendly = target_mob;
|
|
||||||
break;
|
|
||||||
case BCEnum::TT_Animal:
|
|
||||||
if (target_mob && target_mob->GetBodyType() == BodyType::Animal)
|
|
||||||
verified_friendly = target_mob;
|
|
||||||
break;
|
|
||||||
case BCEnum::TT_Undead:
|
|
||||||
if (target_mob && target_mob->GetBodyType() == BodyType::Undead)
|
|
||||||
verified_friendly = target_mob;
|
|
||||||
break;
|
|
||||||
case BCEnum::TT_Summoned:
|
|
||||||
if (target_mob && target_mob->GetBodyType() == BodyType::Summoned)
|
|
||||||
verified_friendly = target_mob;
|
|
||||||
break;
|
|
||||||
case BCEnum::TT_Plant:
|
|
||||||
if (target_mob && target_mob->GetBodyType() == BodyType::Plant)
|
|
||||||
verified_friendly = target_mob;
|
|
||||||
break;
|
|
||||||
case BCEnum::TT_Corpse:
|
|
||||||
if (target_mob && target_mob->IsCorpse())
|
|
||||||
verified_friendly = target_mob;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (return_me_on_null_target && !target_mob && !verified_friendly) {
|
|
||||||
switch (target_type) {
|
|
||||||
case BCEnum::TT_Single:
|
|
||||||
case BCEnum::TT_GroupV1:
|
|
||||||
case BCEnum::TT_GroupV2:
|
|
||||||
case BCEnum::TT_AETarget:
|
|
||||||
verified_friendly = bot_owner;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return verified_friendly;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Mob* VerifyEnemy(Client* bot_owner, BCEnum::TType target_type) {
|
|
||||||
if (!IsAttackable(bot_owner, bot_owner->GetTarget()) || target_type == BCEnum::TT_None)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
auto target_mob = bot_owner->GetTarget();
|
|
||||||
Mob* verified_enemy = nullptr;
|
|
||||||
switch (target_type) {
|
|
||||||
case BCEnum::TT_Animal:
|
|
||||||
if (target_mob->GetBodyType() == BodyType::Animal)
|
|
||||||
verified_enemy = target_mob;
|
|
||||||
break;
|
|
||||||
case BCEnum::TT_Undead:
|
|
||||||
if (target_mob->GetBodyType() == BodyType::Undead)
|
|
||||||
verified_enemy = target_mob;
|
|
||||||
break;
|
|
||||||
case BCEnum::TT_Summoned:
|
|
||||||
if (target_mob->GetBodyType() == BodyType::Summoned)
|
|
||||||
verified_enemy = target_mob;
|
|
||||||
break;
|
|
||||||
case BCEnum::TT_Plant:
|
|
||||||
if (target_mob->GetBodyType() == BodyType::Plant)
|
|
||||||
verified_enemy = target_mob;
|
|
||||||
break;
|
|
||||||
case BCEnum::TT_Single:
|
|
||||||
case BCEnum::TT_GroupV1:
|
|
||||||
case BCEnum::TT_GroupV2:
|
|
||||||
case BCEnum::TT_AETarget:
|
|
||||||
verified_enemy = target_mob;
|
|
||||||
break;
|
|
||||||
case BCEnum::TT_Corpse:
|
|
||||||
if (target_mob->IsCorpse())
|
|
||||||
verified_enemy = target_mob;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return verified_enemy;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Types {
|
|
||||||
Mob* target[BCEnum::TargetTypeCount];
|
|
||||||
bool target_set[BCEnum::TargetTypeCount];
|
|
||||||
|
|
||||||
public:
|
|
||||||
Types() { Clear(); }
|
|
||||||
|
|
||||||
void Clear() {
|
|
||||||
for (int i = BCEnum::TT_None; i <= BCEnum::TargetTypeLast; ++i) {
|
|
||||||
target[i] = nullptr;
|
|
||||||
target_set[i] = false;
|
|
||||||
}
|
|
||||||
target_set[BCEnum::TT_None] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mob* Select(Client* bot_owner, BCEnum::TType target_type, bool action_type, bool return_me_on_null_target = true) {
|
|
||||||
if (target_set[target_type])
|
|
||||||
return target[target_type];
|
|
||||||
|
|
||||||
if (action_type == FRIENDLY)
|
|
||||||
target[target_type] = VerifyFriendly(bot_owner, target_type, return_me_on_null_target);
|
|
||||||
else
|
|
||||||
target[target_type] = VerifyEnemy(bot_owner, target_type);
|
|
||||||
target_set[target_type] = true;
|
|
||||||
|
|
||||||
return target[target_type];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ActionableBots
|
namespace ActionableBots
|
||||||
@@ -1228,7 +921,7 @@ namespace ActionableBots
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bot* Select_ByClass(Client* bot_owner, BCEnum::TType target_type, std::vector<Bot*>& sbl, uint8 cls, Mob* target_mob = nullptr, bool petless = false) {
|
static Bot* Select_ByClass(Client* bot_owner, int target_type, std::vector<Bot*>& sbl, uint8 cls, Mob* target_mob = nullptr, bool petless = false) {
|
||||||
if (!bot_owner || sbl.empty())
|
if (!bot_owner || sbl.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -1239,7 +932,7 @@ namespace ActionableBots
|
|||||||
continue;
|
continue;
|
||||||
if (petless && bot_iter->GetPet())
|
if (petless && bot_iter->GetPet())
|
||||||
continue;
|
continue;
|
||||||
if (target_type == BCEnum::TT_GroupV1) {
|
if (target_type == ST_GroupTeleport) {
|
||||||
if (!target_mob)
|
if (!target_mob)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else if (bot_iter->GetGroup() != target_mob->GetGroup())
|
else if (bot_iter->GetGroup() != target_mob->GetGroup())
|
||||||
@@ -1252,7 +945,7 @@ namespace ActionableBots
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bot* Select_ByMinLevelAndClass(Client* bot_owner, BCEnum::TType target_type, std::vector<Bot*>& sbl, uint8 minlvl, uint8 cls, Mob* target_mob = nullptr, bool petless = false) {
|
static Bot* Select_ByMinLevelAndClass(Client* bot_owner, int target_type, std::vector<Bot*>& sbl, uint8 minlvl, uint8 cls, Mob* target_mob = nullptr, bool petless = false) {
|
||||||
if (!bot_owner || sbl.empty())
|
if (!bot_owner || sbl.empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -1263,7 +956,7 @@ namespace ActionableBots
|
|||||||
continue;
|
continue;
|
||||||
if (petless && bot_iter->GetPet())
|
if (petless && bot_iter->GetPet())
|
||||||
continue;
|
continue;
|
||||||
if (target_type == BCEnum::TT_GroupV1) {
|
if (target_type == ST_GroupTeleport) {
|
||||||
if (!target_mob)
|
if (!target_mob)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else if (bot_iter->GetGroup() != target_mob->GetGroup())
|
else if (bot_iter->GetGroup() != target_mob->GetGroup())
|
||||||
@@ -1332,315 +1025,6 @@ namespace ActionableBots
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class STBaseEntry;
|
|
||||||
class STCharmEntry;
|
|
||||||
class STCureEntry;
|
|
||||||
class STDepartEntry;
|
|
||||||
class STEscapeEntry;
|
|
||||||
class STInvisibilityEntry;
|
|
||||||
class STMovementSpeedEntry;
|
|
||||||
class STResistanceEntry;
|
|
||||||
class STResurrectEntry;
|
|
||||||
class STSendHomeEntry;
|
|
||||||
class STSizeEntry;
|
|
||||||
class STStanceEntry;
|
|
||||||
|
|
||||||
class STBaseEntry
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
BCEnum::SpType m_bcst;
|
|
||||||
|
|
||||||
public:
|
|
||||||
int spell_id;
|
|
||||||
uint8 spell_level;
|
|
||||||
uint8 caster_class;
|
|
||||||
BCEnum::TType target_type;
|
|
||||||
|
|
||||||
// A non-polymorphic constructor requires an appropriate, non-'ST_None' BCEnum::SType
|
|
||||||
STBaseEntry(BCEnum::SpType init_bcst = BCEnum::SpT_None) {
|
|
||||||
spell_id = 0;
|
|
||||||
spell_level = 255;
|
|
||||||
caster_class = 255;
|
|
||||||
target_type = BCEnum::TT_None;
|
|
||||||
m_bcst = init_bcst;
|
|
||||||
}
|
|
||||||
STBaseEntry(STBaseEntry* prototype) {
|
|
||||||
spell_id = prototype->spell_id;
|
|
||||||
spell_level = 255;
|
|
||||||
caster_class = 255;
|
|
||||||
target_type = prototype->target_type;
|
|
||||||
m_bcst = prototype->BCST();
|
|
||||||
}
|
|
||||||
virtual ~STBaseEntry() { return; };
|
|
||||||
|
|
||||||
BCEnum::SpType BCST() { return m_bcst; }
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return false; }
|
|
||||||
|
|
||||||
bool IsCharm() const { return (m_bcst == BCEnum::SpT_Charm); }
|
|
||||||
bool IsCure() const { return (m_bcst == BCEnum::SpT_Cure); }
|
|
||||||
bool IsDepart() const { return (m_bcst == BCEnum::SpT_Depart); }
|
|
||||||
bool IsEscape() const { return (m_bcst == BCEnum::SpT_Escape); }
|
|
||||||
bool IsInvisibility() const { return (m_bcst == BCEnum::SpT_Invisibility); }
|
|
||||||
bool IsMovementSpeed() const { return (m_bcst == BCEnum::SpT_MovementSpeed); }
|
|
||||||
bool IsResistance() const { return (m_bcst == BCEnum::SpT_Resistance); }
|
|
||||||
bool IsResurrect() const { return (m_bcst == BCEnum::SpT_Resurrect); }
|
|
||||||
bool IsSendHome() const { return (m_bcst == BCEnum::SpT_SendHome); }
|
|
||||||
bool IsSize() const { return (m_bcst == BCEnum::SpT_Size); }
|
|
||||||
bool IsStance() const { return (m_bcst == BCEnum::SpT_Stance); }
|
|
||||||
|
|
||||||
virtual STCharmEntry* SafeCastToCharm() { return nullptr; }
|
|
||||||
virtual STCureEntry* SafeCastToCure() { return nullptr; }
|
|
||||||
virtual STDepartEntry* SafeCastToDepart() { return nullptr; }
|
|
||||||
virtual STEscapeEntry* SafeCastToEscape() { return nullptr; }
|
|
||||||
virtual STInvisibilityEntry* SafeCastToInvisibility() { return nullptr; }
|
|
||||||
virtual STMovementSpeedEntry* SafeCastToMovementSpeed() { return nullptr; }
|
|
||||||
virtual STResistanceEntry* SafeCastToResistance() { return nullptr; }
|
|
||||||
virtual STResurrectEntry* SafeCastToResurrect() { return nullptr; }
|
|
||||||
virtual STSendHomeEntry* SafeCastToSendHome() { return nullptr; }
|
|
||||||
virtual STSizeEntry* SafeCastToSize() { return nullptr; }
|
|
||||||
virtual STStanceEntry* SafeCastToStance() { return nullptr; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STCharmEntry : public STBaseEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool dire;
|
|
||||||
|
|
||||||
STCharmEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_Charm;
|
|
||||||
dire = false;
|
|
||||||
}
|
|
||||||
STCharmEntry(STCharmEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_Charm;
|
|
||||||
dire = prototype->dire;
|
|
||||||
}
|
|
||||||
virtual ~STCharmEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STCharmEntry* SafeCastToCharm() { return ((m_bcst == BCEnum::SpT_Charm) ? (static_cast<STCharmEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STCureEntry : public STBaseEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int cure_value[BCEnum::AilmentTypeCount];
|
|
||||||
int cure_total;
|
|
||||||
|
|
||||||
STCureEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_Cure;
|
|
||||||
memset(&cure_value, 0, (sizeof(int) * BCEnum::AilmentTypeCount));
|
|
||||||
cure_total = 0;
|
|
||||||
}
|
|
||||||
STCureEntry(STCureEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_Cure;
|
|
||||||
memcpy(&cure_value, prototype->cure_value, (sizeof(int) * BCEnum::AilmentTypeCount));
|
|
||||||
cure_total = prototype->cure_total;
|
|
||||||
}
|
|
||||||
virtual ~STCureEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STCureEntry* SafeCastToCure() { return ((m_bcst == BCEnum::SpT_Cure) ? (static_cast<STCureEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STDepartEntry : public STBaseEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool single;
|
|
||||||
std::string long_name;
|
|
||||||
|
|
||||||
STDepartEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_Depart;
|
|
||||||
single = false;
|
|
||||||
long_name.clear();
|
|
||||||
}
|
|
||||||
STDepartEntry(STDepartEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_Depart;
|
|
||||||
single = prototype->single;
|
|
||||||
long_name = prototype->long_name;
|
|
||||||
}
|
|
||||||
virtual ~STDepartEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STDepartEntry* SafeCastToDepart() { return ((m_bcst == BCEnum::SpT_Depart) ? (static_cast<STDepartEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STEscapeEntry : public STBaseEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool lesser;
|
|
||||||
|
|
||||||
STEscapeEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_Escape;
|
|
||||||
lesser = false;
|
|
||||||
}
|
|
||||||
STEscapeEntry(STEscapeEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_Escape;
|
|
||||||
lesser = prototype->lesser;
|
|
||||||
}
|
|
||||||
virtual ~STEscapeEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STEscapeEntry* SafeCastToEscape() { return ((m_bcst == BCEnum::SpT_Escape) ? (static_cast<STEscapeEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STInvisibilityEntry : public STBaseEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BCEnum::IType invis_type;
|
|
||||||
|
|
||||||
STInvisibilityEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_Invisibility;
|
|
||||||
invis_type = BCEnum::IT_None;
|
|
||||||
}
|
|
||||||
STInvisibilityEntry(STInvisibilityEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_Invisibility;
|
|
||||||
invis_type = prototype->invis_type;
|
|
||||||
}
|
|
||||||
virtual ~STInvisibilityEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STInvisibilityEntry* SafeCastToInvisibility() { return ((m_bcst == BCEnum::SpT_Invisibility) ? (static_cast<STInvisibilityEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STMovementSpeedEntry : public STBaseEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool group;
|
|
||||||
|
|
||||||
STMovementSpeedEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_MovementSpeed;
|
|
||||||
group = false;
|
|
||||||
}
|
|
||||||
STMovementSpeedEntry(STMovementSpeedEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_MovementSpeed;
|
|
||||||
group = prototype->group;
|
|
||||||
}
|
|
||||||
virtual ~STMovementSpeedEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STMovementSpeedEntry* SafeCastToMovementSpeed() { return ((m_bcst == BCEnum::SpT_MovementSpeed) ? (static_cast<STMovementSpeedEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STResistanceEntry : public STBaseEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int resist_value[BCEnum::ResistanceTypeCount];
|
|
||||||
int resist_total;
|
|
||||||
|
|
||||||
STResistanceEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_Resistance;
|
|
||||||
memset(&resist_value, 0, (sizeof(int) * BCEnum::ResistanceTypeCount));
|
|
||||||
resist_total = 0;
|
|
||||||
}
|
|
||||||
STResistanceEntry(STResistanceEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_Resistance;
|
|
||||||
memcpy(&resist_value, prototype->resist_value, (sizeof(int) * BCEnum::ResistanceTypeCount));
|
|
||||||
resist_total = prototype->resist_total;
|
|
||||||
}
|
|
||||||
virtual ~STResistanceEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STResistanceEntry* SafeCastToResistance() { return ((m_bcst == BCEnum::SpT_Resistance) ? (static_cast<STResistanceEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STResurrectEntry : public STBaseEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool aoe;
|
|
||||||
|
|
||||||
STResurrectEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_Resurrect;
|
|
||||||
aoe = false;
|
|
||||||
}
|
|
||||||
STResurrectEntry(STResurrectEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_Resurrect;
|
|
||||||
aoe = prototype->aoe;
|
|
||||||
}
|
|
||||||
virtual ~STResurrectEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STResurrectEntry* SafeCastToResurrect() { return ((m_bcst == BCEnum::SpT_Resurrect) ? (static_cast<STResurrectEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STSendHomeEntry : public STBaseEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool group;
|
|
||||||
|
|
||||||
STSendHomeEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_SendHome;
|
|
||||||
group = false;
|
|
||||||
}
|
|
||||||
STSendHomeEntry(STSendHomeEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_SendHome;
|
|
||||||
group = prototype->group;
|
|
||||||
}
|
|
||||||
virtual ~STSendHomeEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STSendHomeEntry* SafeCastToSendHome() { return ((m_bcst == BCEnum::SpT_SendHome) ? (static_cast<STSendHomeEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STSizeEntry : public STBaseEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
BCEnum::SzType size_type;
|
|
||||||
|
|
||||||
STSizeEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_Size;
|
|
||||||
size_type = BCEnum::SzT_None;
|
|
||||||
}
|
|
||||||
STSizeEntry(STSizeEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_Size;
|
|
||||||
size_type = prototype->size_type;
|
|
||||||
}
|
|
||||||
virtual ~STSizeEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STSizeEntry* SafeCastToSize() { return ((m_bcst == BCEnum::SpT_Size) ? (static_cast<STSizeEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class STStanceEntry : public STBaseEntry {
|
|
||||||
public:
|
|
||||||
BCEnum::StType stance_type;
|
|
||||||
|
|
||||||
STStanceEntry() {
|
|
||||||
m_bcst = BCEnum::SpT_Stance;
|
|
||||||
stance_type = BCEnum::StT_None;
|
|
||||||
}
|
|
||||||
STStanceEntry(STStanceEntry* prototype) : STBaseEntry(prototype) {
|
|
||||||
m_bcst = BCEnum::SpT_Stance;
|
|
||||||
stance_type = prototype->stance_type;
|
|
||||||
}
|
|
||||||
virtual ~STStanceEntry() { return; };
|
|
||||||
|
|
||||||
virtual bool IsDerived() { return true; }
|
|
||||||
|
|
||||||
virtual STStanceEntry* SafeCastToStance() { return ((m_bcst == BCEnum::SpT_Stance) ? (static_cast<STStanceEntry*>(this)) : (nullptr)); }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef std::list<STBaseEntry*> bcst_list;
|
|
||||||
typedef std::map<BCEnum::SpType, bcst_list> bcst_map;
|
|
||||||
|
|
||||||
typedef std::map<BCEnum::SpType, std::string> bcst_required_bot_classes_map;
|
|
||||||
typedef std::map<BCEnum::SpType, std::map<uint8, std::string>> bcst_required_bot_classes_map_by_class;
|
|
||||||
|
|
||||||
typedef std::map<uint8, uint8> bcst_levels;
|
|
||||||
typedef std::map<BCEnum::SpType, bcst_levels> bcst_levels_map;
|
|
||||||
|
|
||||||
#define BOT_COMMAND_CHAR '^'
|
#define BOT_COMMAND_CHAR '^'
|
||||||
|
|
||||||
typedef void (*BotCmdFuncPtr)(Client *,const Seperator *);
|
typedef void (*BotCmdFuncPtr)(Client *,const Seperator *);
|
||||||
@@ -1791,21 +1175,17 @@ void bot_command_pet_set_type(Client *c, const Seperator *sep);
|
|||||||
|
|
||||||
|
|
||||||
// bot command helpers
|
// bot command helpers
|
||||||
bool helper_bot_appearance_fail(Client *bot_owner, Bot *my_bot, BCEnum::AFType fail_type, const char* type_desc);
|
bool helper_bot_appearance_fail(Client *bot_owner, Bot *my_bot, uint8 fail_type, const char* type_desc);
|
||||||
void helper_bot_appearance_form_final(Client *bot_owner, Bot *my_bot);
|
void helper_bot_appearance_form_final(Client *bot_owner, Bot *my_bot);
|
||||||
void helper_bot_appearance_form_update(Bot *my_bot);
|
void helper_bot_appearance_form_update(Bot *my_bot);
|
||||||
uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_class, uint16 bot_race, uint8 bot_gender);
|
uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_class, uint16 bot_race, uint8 bot_gender);
|
||||||
int helper_bot_follow_option_chain(Client *bot_owner);
|
int helper_bot_follow_option_chain(Client *bot_owner);
|
||||||
bool helper_cast_standard_spell(Bot* casting_bot, Mob* target_mob, int spell_id, bool annouce_cast = true, uint32* dont_root_before = nullptr);
|
|
||||||
bool helper_command_disabled(Client *bot_owner, bool rule_value, const char *command);
|
bool helper_command_disabled(Client *bot_owner, bool rule_value, const char *command);
|
||||||
bool helper_command_alias_fail(Client *bot_owner, const char* command_handler, const char *alias, const char *command);
|
bool helper_command_alias_fail(Client *bot_owner, const char* command_handler, const char *alias, const char *command);
|
||||||
void helper_command_depart_list(Client* bot_owner, Bot* druid_bot, Bot* wizard_bot, bcst_list* local_list, bool single_flag = false);
|
|
||||||
bool helper_is_help_or_usage(const char* arg);
|
bool helper_is_help_or_usage(const char* arg);
|
||||||
bool helper_no_available_bots(Client *bot_owner, Bot *my_bot = nullptr);
|
bool helper_no_available_bots(Client *bot_owner, Bot *my_bot = nullptr);
|
||||||
void helper_send_available_subcommands(Client *bot_owner, const char* command_simile, std::vector<const char*> subcommand_list);
|
void helper_send_available_subcommands(Client *bot_owner, const char* command_simile, std::vector<const char*> subcommand_list);
|
||||||
void helper_send_usage_required_bots(Client *bot_owner, BCEnum::SpType spell_type, uint8 bot_class = Class::None);
|
void helper_send_usage_required_bots(Client *bot_owner, uint16 spell_type);
|
||||||
bool helper_spell_check_fail(STBaseEntry* local_entry);
|
|
||||||
bool helper_spell_list_fail(Client *bot_owner, bcst_list* spell_list, BCEnum::SpType spell_type);
|
|
||||||
void SendSpellTypeWindow(Client* c, const Seperator* sep);
|
void SendSpellTypeWindow(Client* c, const Seperator* sep);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ void bot_command_beard_color(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = AFT_None;
|
||||||
if (my_bot->GetGender() != Gender::Male && my_bot->GetRace() != DWARF)
|
if (my_bot->GetGender() != Gender::Male && my_bot->GetRace() != DWARF)
|
||||||
fail_type = BCEnum::AFT_GenderRace;
|
fail_type = AFT_GenderRace;
|
||||||
else if (!PlayerAppearance::IsValidBeardColor(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
else if (!PlayerAppearance::IsValidBeardColor(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = AFT_Value;
|
||||||
else
|
else
|
||||||
my_bot->SetBeardColor(uvalue);
|
my_bot->SetBeardColor(uvalue);
|
||||||
|
|
||||||
@@ -82,11 +82,11 @@ void bot_command_beard_style(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = AFT_None;
|
||||||
if (my_bot->GetGender() != Gender::Male && my_bot->GetRace() != DWARF)
|
if (my_bot->GetGender() != Gender::Male && my_bot->GetRace() != DWARF)
|
||||||
fail_type = BCEnum::AFT_GenderRace;
|
fail_type = AFT_GenderRace;
|
||||||
else if (!PlayerAppearance::IsValidBeard(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
else if (!PlayerAppearance::IsValidBeard(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = AFT_Value;
|
||||||
else
|
else
|
||||||
my_bot->SetBeard(uvalue);
|
my_bot->SetBeard(uvalue);
|
||||||
|
|
||||||
@@ -121,11 +121,11 @@ void bot_command_details(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
uint32 uvalue = Strings::ToInt(sep->arg[1]);
|
uint32 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = AFT_None;
|
||||||
if (my_bot->GetRace() != DRAKKIN)
|
if (my_bot->GetRace() != DRAKKIN)
|
||||||
fail_type = BCEnum::AFT_Race;
|
fail_type = AFT_Race;
|
||||||
else if (!PlayerAppearance::IsValidDetail(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
else if (!PlayerAppearance::IsValidDetail(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = AFT_Value;
|
||||||
else
|
else
|
||||||
my_bot->SetDrakkinDetails(uvalue);
|
my_bot->SetDrakkinDetails(uvalue);
|
||||||
|
|
||||||
@@ -280,9 +280,9 @@ void bot_command_eyes(Client *c, const Seperator *sep)
|
|||||||
//else if (!arg2.compare("right"))
|
//else if (!arg2.compare("right"))
|
||||||
// eye_bias = 2;
|
// eye_bias = 2;
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = AFT_None;
|
||||||
if (!PlayerAppearance::IsValidEyeColor(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
if (!PlayerAppearance::IsValidEyeColor(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = AFT_Value;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//if (eye_bias == 1) {
|
//if (eye_bias == 1) {
|
||||||
@@ -327,9 +327,9 @@ void bot_command_face(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = AFT_None;
|
||||||
if (!PlayerAppearance::IsValidFace(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
if (!PlayerAppearance::IsValidFace(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = AFT_Value;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint8 old_woad = 0;
|
uint8 old_woad = 0;
|
||||||
@@ -367,9 +367,9 @@ void bot_command_hair_color(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = AFT_None;
|
||||||
if (!PlayerAppearance::IsValidHairColor(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
if (!PlayerAppearance::IsValidHairColor(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = AFT_Value;
|
||||||
else
|
else
|
||||||
my_bot->SetHairColor(uvalue);
|
my_bot->SetHairColor(uvalue);
|
||||||
|
|
||||||
@@ -402,9 +402,9 @@ void bot_command_hairstyle(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = AFT_None;
|
||||||
if (!PlayerAppearance::IsValidHair(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
if (!PlayerAppearance::IsValidHair(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = AFT_Value;
|
||||||
else
|
else
|
||||||
my_bot->SetHairStyle(uvalue);
|
my_bot->SetHairStyle(uvalue);
|
||||||
|
|
||||||
@@ -439,11 +439,11 @@ void bot_command_heritage(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
uint32 uvalue = Strings::ToInt(sep->arg[1]);
|
uint32 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = AFT_None;
|
||||||
if (my_bot->GetRace() != DRAKKIN)
|
if (my_bot->GetRace() != DRAKKIN)
|
||||||
fail_type = BCEnum::AFT_Race;
|
fail_type = AFT_Race;
|
||||||
else if (!PlayerAppearance::IsValidHeritage(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
else if (!PlayerAppearance::IsValidHeritage(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = AFT_Value;
|
||||||
else
|
else
|
||||||
my_bot->SetDrakkinHeritage(uvalue);
|
my_bot->SetDrakkinHeritage(uvalue);
|
||||||
|
|
||||||
@@ -478,11 +478,11 @@ void bot_command_tattoo(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
uint32 uvalue = Strings::ToInt(sep->arg[1]);
|
uint32 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = AFT_None;
|
||||||
if (my_bot->GetRace() != DRAKKIN)
|
if (my_bot->GetRace() != DRAKKIN)
|
||||||
fail_type = BCEnum::AFT_Race;
|
fail_type = AFT_Race;
|
||||||
else if (!PlayerAppearance::IsValidTattoo(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
else if (!PlayerAppearance::IsValidTattoo(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = AFT_Value;
|
||||||
else
|
else
|
||||||
my_bot->SetDrakkinTattoo(uvalue);
|
my_bot->SetDrakkinTattoo(uvalue);
|
||||||
|
|
||||||
@@ -515,12 +515,12 @@ void bot_command_woad(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = AFT_None;
|
||||||
if (my_bot->GetRace() != BARBARIAN) {
|
if (my_bot->GetRace() != BARBARIAN) {
|
||||||
fail_type = BCEnum::AFT_Race;
|
fail_type = AFT_Race;
|
||||||
}
|
}
|
||||||
else if (!PlayerAppearance::IsValidWoad(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
else if (!PlayerAppearance::IsValidWoad(my_bot->GetRace(), my_bot->GetGender(), uvalue)) {
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = AFT_Value;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint8 old_face = (my_bot->GetLuclinFace() % 10);
|
uint8 old_face = (my_bot->GetLuclinFace() % 10);
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ void bot_command_cast(Client* c, const Seperator* sep)
|
|||||||
if (sep->IsNumber(1)) {
|
if (sep->IsNumber(1)) {
|
||||||
spell_type = atoi(sep->arg[1]);
|
spell_type = atoi(sep->arg[1]);
|
||||||
|
|
||||||
if (spell_type < BotSpellTypes::START || (spell_type > BotSpellTypes::END && spell_type < BotSpellTypes::COMMANDED_START) || spell_type > BotSpellTypes::COMMANDED_END) {
|
if (!c->IsValidSpellType(spell_type)) {
|
||||||
c->Message(
|
c->Message(
|
||||||
Chat::Yellow,
|
Chat::Yellow,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -621,6 +621,10 @@ void bot_command_cast(Client* c, const Seperator* sep)
|
|||||||
tar ? tar->GetCleanName() : "your target"
|
tar ? tar->GetCleanName() : "your target"
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!aa_type && !by_spell_id) {
|
||||||
|
helper_send_usage_required_bots(c, spell_type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c->Message(
|
c->Message(
|
||||||
|
|||||||
@@ -36,10 +36,15 @@ void bot_command_pull(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
sbl.erase(std::remove(sbl.begin(), sbl.end(), nullptr), sbl.end());
|
sbl.erase(std::remove(sbl.begin(), sbl.end(), nullptr), sbl.end());
|
||||||
|
|
||||||
auto target_mob = ActionableTarget::VerifyEnemy(c, BCEnum::TT_Single);
|
auto target_mob = c->GetTarget();
|
||||||
if (!target_mob) {
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
!target_mob ||
|
||||||
|
target_mob == c ||
|
||||||
|
!c->IsAttackAllowed(target_mob)
|
||||||
|
) {
|
||||||
c->Message(Chat::White, "Your current target is not attackable!");
|
c->Message(Chat::White, "Your current target is not attackable!");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -122,4 +122,11 @@ struct BotBlockedBuffs_Struct {
|
|||||||
uint8_t blocked_pet;
|
uint8_t blocked_pet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BotSpellTypesByClass_Struct {
|
||||||
|
uint8_t min_level = 255;
|
||||||
|
std::string description;
|
||||||
|
};
|
||||||
|
|
||||||
|
using CommandedSpellTypesMinLevelMap = std::map<int32_t, std::map<int32_t, BotSpellTypesByClass_Struct>>;
|
||||||
|
|
||||||
#endif // BOT_STRUCTS
|
#endif // BOT_STRUCTS
|
||||||
|
|||||||
+96
-46
@@ -2821,6 +2821,63 @@ BotSpell Bot::GetBestBotSpellForNukeByBodyType(Bot* caster, uint8 body_type, uin
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BotSpell Bot::GetBestBotSpellForRez(Bot* caster, Mob* target, uint16 spell_type) {
|
||||||
|
BotSpell result;
|
||||||
|
|
||||||
|
result.SpellId = 0;
|
||||||
|
result.SpellIndex = 0;
|
||||||
|
result.ManaCost = 0;
|
||||||
|
|
||||||
|
if (caster) {
|
||||||
|
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_Revive);
|
||||||
|
|
||||||
|
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||||
|
// Assuming all the spells have been loaded into this list by level and in descending order
|
||||||
|
if (
|
||||||
|
IsResurrectSpell(bot_spell_list_itr->SpellId) &&
|
||||||
|
caster->CheckSpellRecastTimer(bot_spell_list_itr->SpellId)
|
||||||
|
) {
|
||||||
|
result.SpellId = bot_spell_list_itr->SpellId;
|
||||||
|
result.SpellIndex = bot_spell_list_itr->SpellIndex;
|
||||||
|
result.ManaCost = bot_spell_list_itr->ManaCost;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
BotSpell Bot::GetBestBotSpellForCharm(Bot* caster, Mob* target, uint16 spell_type) {
|
||||||
|
BotSpell result;
|
||||||
|
|
||||||
|
result.SpellId = 0;
|
||||||
|
result.SpellIndex = 0;
|
||||||
|
result.ManaCost = 0;
|
||||||
|
|
||||||
|
if (caster) {
|
||||||
|
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_Charm);
|
||||||
|
|
||||||
|
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
||||||
|
// Assuming all the spells have been loaded into this list by level and in descending order
|
||||||
|
if (
|
||||||
|
IsCharmSpell(bot_spell_list_itr->SpellId) &&
|
||||||
|
caster->CastChecks(bot_spell_list_itr->SpellId, target, spell_type)
|
||||||
|
) {
|
||||||
|
result.SpellId = bot_spell_list_itr->SpellId;
|
||||||
|
result.SpellIndex = bot_spell_list_itr->SpellIndex;
|
||||||
|
result.ManaCost = bot_spell_list_itr->ManaCost;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Bot::CheckBotSpells() {
|
void Bot::CheckBotSpells() {
|
||||||
auto spell_list = BotSpellsEntriesRepository::All(content_db);
|
auto spell_list = BotSpellsEntriesRepository::All(content_db);
|
||||||
uint16 spell_id;
|
uint16 spell_id;
|
||||||
@@ -2949,58 +3006,51 @@ void Bot::CheckBotSpells() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BotSpell Bot::GetBestBotSpellForRez(Bot* caster, Mob* target, uint16 spell_type) {
|
void Bot::MapSpellTypeLevels() {
|
||||||
BotSpell result;
|
commanded_spells_min_level.clear();
|
||||||
|
|
||||||
result.SpellId = 0;
|
auto start = std::min({ BotSpellTypes::START, BotSpellTypes::COMMANDED_START, BotSpellTypes::DISCIPLINE_START });
|
||||||
result.SpellIndex = 0;
|
auto end = std::max({ BotSpellTypes::END, BotSpellTypes::COMMANDED_END, BotSpellTypes::DISCIPLINE_END });
|
||||||
result.ManaCost = 0;
|
|
||||||
|
|
||||||
if (caster) {
|
for (int i = start; i <= end; ++i) {
|
||||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_Revive);
|
if (!Bot::IsValidSpellType(i)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int x = Class::Warrior; x <= Class::Berserker; ++x) {
|
||||||
|
commanded_spells_min_level[i][x] = { UINT8_MAX, "" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto spell_list = BotSpellsEntriesRepository::All(content_db);
|
||||||
|
|
||||||
|
for (const auto& s : spell_list) {
|
||||||
|
if (!IsValidSpell(s.spell_id)) {
|
||||||
|
LogBotSpellTypeChecks("{} is an invalid spell", s.spell_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t spell_type = s.type;
|
||||||
|
int32_t bot_class = s.npc_spells_id - BOT_CLASS_BASE_ID_PREFIX;
|
||||||
|
uint8_t min_level = s.minlevel;
|
||||||
|
|
||||||
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
|
||||||
// Assuming all the spells have been loaded into this list by level and in descending order
|
|
||||||
if (
|
if (
|
||||||
IsResurrectSpell(bot_spell_list_itr->SpellId) &&
|
!EQ::ValueWithin(bot_class, Class::Warrior, Class::Berserker) ||
|
||||||
caster->CheckSpellRecastTimer(bot_spell_list_itr->SpellId)
|
!Bot::IsValidSpellType(spell_type)
|
||||||
) {
|
) {
|
||||||
result.SpellId = bot_spell_list_itr->SpellId;
|
continue;
|
||||||
result.SpellIndex = bot_spell_list_itr->SpellIndex;
|
}
|
||||||
result.ManaCost = bot_spell_list_itr->ManaCost;
|
|
||||||
|
|
||||||
break;
|
auto& spell_info = commanded_spells_min_level[spell_type][bot_class];
|
||||||
|
|
||||||
|
if (min_level < spell_info.min_level) {
|
||||||
|
spell_info.min_level = min_level;
|
||||||
|
spell_info.description = StringFormat(
|
||||||
|
"%s [#%u]: Level %u",
|
||||||
|
GetClassIDName(bot_class),
|
||||||
|
bot_class,
|
||||||
|
min_level
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
BotSpell Bot::GetBestBotSpellForCharm(Bot* caster, Mob* target, uint16 spell_type) {
|
|
||||||
BotSpell result;
|
|
||||||
|
|
||||||
result.SpellId = 0;
|
|
||||||
result.SpellIndex = 0;
|
|
||||||
result.ManaCost = 0;
|
|
||||||
|
|
||||||
if (caster) {
|
|
||||||
std::list<BotSpell> bot_spell_list = GetBotSpellsForSpellEffect(caster, spell_type, SE_Charm);
|
|
||||||
|
|
||||||
for (std::list<BotSpell>::iterator bot_spell_list_itr = bot_spell_list.begin(); bot_spell_list_itr != bot_spell_list.end(); ++bot_spell_list_itr) {
|
|
||||||
// Assuming all the spells have been loaded into this list by level and in descending order
|
|
||||||
if (
|
|
||||||
IsCharmSpell(bot_spell_list_itr->SpellId) &&
|
|
||||||
caster->CastChecks(bot_spell_list_itr->SpellId, target, spell_type)
|
|
||||||
) {
|
|
||||||
result.SpellId = bot_spell_list_itr->SpellId;
|
|
||||||
result.SpellIndex = bot_spell_list_itr->SpellIndex;
|
|
||||||
result.ManaCost = bot_spell_list_itr->ManaCost;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user