mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-16 01:01:30 +00:00
Added node pathing to the bot movement dilemma...
This commit is contained in:
parent
5c6492bc0f
commit
7a6d5d46f4
@ -1,5 +1,12 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 02/25/2017 ==
|
||||
Uleat: Implemented rule-based node pathing for bots
|
||||
- This currently applies to out-of-combat following movement and blocked los in-combat movement
|
||||
- The default is set to 'true' (use node pathing)
|
||||
- If you want to disable node pathing, apply the optional sql '2017_02_25_bots_use_pathing_rule.sql' file located in the utils/sql/git/bots/optional sub-directory. This will apply a 'false' rule..but, it can be changed as desired
|
||||
- This helps with bot movement..but, there are still issues...
|
||||
|
||||
== 02/23/2017 ==
|
||||
Uleat: Moved bot spell casting chance values into database - this will allow admins to tailor their bots without having to rebuild server code
|
||||
- Each entry uses a 4-dimensional identifier: [spell type index][class index][stance index][conditional index]
|
||||
|
||||
@ -558,6 +558,7 @@ RULE_BOOL(Bots, PreferNoManaCommandSpells, true) // Give sorting priority to new
|
||||
RULE_BOOL(Bots, QuestableSpawnLimit, false) // Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl
|
||||
RULE_BOOL(Bots, QuestableSpells, false) // Anita Thrall's (Anita_Thrall.pl) Bot Spell Scriber quests.
|
||||
RULE_INT(Bots, SpawnLimit, 71) // Number of bots a character can have spawned at one time, You + 71 bots is a 12 group pseudo-raid (bots are not raidable at this time)
|
||||
RULE_BOOL(Bots, UsePathing, true) // Bots will use node pathing when moving
|
||||
RULE_BOOL(Bots, BotGroupXP, false) // Determines whether client gets xp for bots outside their group.
|
||||
RULE_BOOL(Bots, BotBardUseOutOfCombatSongs, true) // Determines whether bard bots use additional out of combat songs (optional script)
|
||||
RULE_BOOL(Bots, BotLevelsWithOwner, false) // Auto-updates spawned bots as owner levels/de-levels (false is original behavior)
|
||||
|
||||
@ -0,0 +1 @@
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Bots:UsePathing', 'false', 'Bots will use node pathing when moving');
|
||||
92
zone/bot.cpp
92
zone/bot.cpp
@ -77,7 +77,7 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm
|
||||
SetShowHelm(true);
|
||||
SetPauseAI(false);
|
||||
rest_timer.Disable();
|
||||
SetFollowDistance(BOT_DEFAULT_FOLLOW_DISTANCE);
|
||||
SetFollowDistance(BOT_FOLLOW_DISTANCE_DEFAULT);
|
||||
// Do this once and only in this constructor
|
||||
GenerateAppearance();
|
||||
GenerateBaseStats();
|
||||
@ -151,7 +151,7 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
||||
SetPauseAI(false);
|
||||
|
||||
rest_timer.Disable();
|
||||
SetFollowDistance(BOT_DEFAULT_FOLLOW_DISTANCE);
|
||||
SetFollowDistance(BOT_FOLLOW_DISTANCE_DEFAULT);
|
||||
strcpy(this->name, this->GetCleanName());
|
||||
|
||||
memset(&_botInspectMessage, 0, sizeof(InspectMessage_Struct));
|
||||
@ -2065,6 +2065,8 @@ float Bot::GetMaxMeleeRangeToTarget(Mob* target) {
|
||||
|
||||
// AI Processing for the Bot object
|
||||
void Bot::AI_Process() {
|
||||
// TODO: Need to add root checks to all movement code
|
||||
|
||||
if (!IsAIControlled())
|
||||
return;
|
||||
if (GetPauseAI())
|
||||
@ -2229,13 +2231,23 @@ void Bot::AI_Process() {
|
||||
return;
|
||||
}
|
||||
else if (!CheckLosFN(GetTarget())) {
|
||||
if (!IsRooted()) {
|
||||
if (RuleB(Bots, UsePathing) && zone->pathing) {
|
||||
bool WaypointChanged, NodeReached;
|
||||
|
||||
glm::vec3 Goal = UpdatePath(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(),
|
||||
GetRunspeed(), WaypointChanged, NodeReached);
|
||||
|
||||
if (WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetRunspeed());
|
||||
}
|
||||
else {
|
||||
Mob* follow = entity_list.GetMob(GetFollowID());
|
||||
if (follow)
|
||||
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), GetRunspeed());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2516,33 +2528,52 @@ void Bot::AI_Process() {
|
||||
}
|
||||
}
|
||||
else if(AI_movement_timer->Check()) {
|
||||
// something is wrong with bot movement spell bonuses - based on logging..
|
||||
// ..this code won't need to be so complex once fixed...
|
||||
int speed = GetRunspeed();
|
||||
if (cur_dist < GetFollowDistance() + 2000) {
|
||||
speed = GetWalkspeed();
|
||||
}
|
||||
else if (cur_dist >= GetFollowDistance() + 10000) { // 100
|
||||
if (cur_dist >= 22500) { // 150
|
||||
auto leader = follow;
|
||||
while (leader->GetFollowID()) {
|
||||
leader = entity_list.GetMob(leader->GetFollowID());
|
||||
if (!leader || leader == this)
|
||||
break;
|
||||
if (leader->GetRunspeed() > speed)
|
||||
speed = leader->GetRunspeed();
|
||||
if (leader->IsClient())
|
||||
break;
|
||||
// Something is still wrong with bot following...
|
||||
// Shows up really bad over long distances when movement bonuses are involved
|
||||
if (cur_dist > GetFollowDistance()) {
|
||||
if (RuleB(Bots, UsePathing) && zone->pathing) {
|
||||
if (cur_dist <= GetFollowDistance() + BOT_FOLLOW_DISTANCE_WALK) {
|
||||
bool WaypointChanged, NodeReached;
|
||||
|
||||
glm::vec3 Goal = UpdatePath(follow->GetX(), follow->GetY(), follow->GetZ(),
|
||||
GetWalkspeed(), WaypointChanged, NodeReached);
|
||||
|
||||
if (WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, GetWalkspeed());
|
||||
}
|
||||
else {
|
||||
int speed = GetRunspeed();
|
||||
if (cur_dist > GetFollowDistance() + BOT_FOLLOW_DISTANCE_CRITICAL)
|
||||
speed = ((float)speed * 1.25f); // sprint mod (1/4 boost)
|
||||
|
||||
bool WaypointChanged, NodeReached;
|
||||
|
||||
glm::vec3 Goal = UpdatePath(follow->GetX(), follow->GetY(), follow->GetZ(),
|
||||
speed, WaypointChanged, NodeReached);
|
||||
|
||||
if (WaypointChanged)
|
||||
tar_ndx = 20;
|
||||
|
||||
CalculateNewPosition2(Goal.x, Goal.y, Goal.z, speed);
|
||||
}
|
||||
}
|
||||
speed = (float)speed * (1.0f + ((float)speed * 0.03125f)); // 1/32 - special bot sprint mod
|
||||
}
|
||||
else {
|
||||
if (cur_dist <= GetFollowDistance() + BOT_FOLLOW_DISTANCE_WALK) {
|
||||
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), GetWalkspeed());
|
||||
}
|
||||
else {
|
||||
int speed = GetRunspeed();
|
||||
if (cur_dist > GetFollowDistance() + BOT_FOLLOW_DISTANCE_CRITICAL)
|
||||
speed = ((float)speed * 1.25f); // sprint mod (1/4 boost)
|
||||
|
||||
if (cur_dist > GetFollowDistance()) {
|
||||
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), speed);
|
||||
CalculateNewPosition2(follow->GetX(), follow->GetY(), follow->GetZ(), speed);
|
||||
}
|
||||
}
|
||||
|
||||
if (rest_timer.Enabled())
|
||||
rest_timer.Disable();
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (moved) {
|
||||
@ -2550,9 +2581,14 @@ void Bot::AI_Process() {
|
||||
SetCurrentSpeed(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (GetClass() == BARD && GetBotStance() != BotStancePassive && !spellend_timer.Enabled() && AI_think_timer->Check())
|
||||
AI_IdleCastCheck();
|
||||
|
||||
return;
|
||||
}
|
||||
else if (IsMoving()) {
|
||||
if (GetBotStance() != BotStancePassive && GetClass() == BARD && !spellend_timer.Enabled() && AI_think_timer->Check()) {
|
||||
if (GetClass() == BARD && GetBotStance() != BotStancePassive && !spellend_timer.Enabled() && AI_think_timer->Check()) {
|
||||
AI_IdleCastCheck();
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,10 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#define BOT_DEFAULT_FOLLOW_DISTANCE 184
|
||||
#define BOT_FOLLOW_DISTANCE_DEFAULT 184 // as DSq value (~13.565 units)
|
||||
#define BOT_FOLLOW_DISTANCE_DEFAULT_MAX 2500 // as DSq value (50 units)
|
||||
#define BOT_FOLLOW_DISTANCE_WALK 625 // as DSq value (25 units)
|
||||
#define BOT_FOLLOW_DISTANCE_CRITICAL 22500 // as DSq value (150 units)
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
|
||||
@ -4550,7 +4550,7 @@ void bot_subcommand_bot_follow_distance(Client *c, const Seperator *sep)
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
|
||||
uint32 bfd = BOT_DEFAULT_FOLLOW_DISTANCE;
|
||||
uint32 bfd = BOT_FOLLOW_DISTANCE_DEFAULT;
|
||||
bool set_flag = false;
|
||||
int ab_arg = 2;
|
||||
|
||||
@ -4561,6 +4561,10 @@ void bot_subcommand_bot_follow_distance(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
bfd = atoi(sep->arg[2]);
|
||||
if (bfd < 1)
|
||||
bfd = 1;
|
||||
if (bfd > BOT_FOLLOW_DISTANCE_DEFAULT_MAX)
|
||||
bfd = BOT_FOLLOW_DISTANCE_DEFAULT_MAX;
|
||||
set_flag = true;
|
||||
ab_arg = 3;
|
||||
}
|
||||
|
||||
@ -378,7 +378,13 @@ bool BotDatabase::LoadBot(const uint32 bot_id, Bot*& loaded_bot)
|
||||
loaded_bot = new Bot(bot_id, atoi(row[0]), atoi(row[1]), atof(row[14]), atoi(row[6]), tempNPCStruct);
|
||||
if (loaded_bot) {
|
||||
loaded_bot->SetShowHelm((atoi(row[43]) > 0 ? true : false));
|
||||
loaded_bot->SetFollowDistance(atoi(row[44]));
|
||||
uint32 bfd = atoi(row[44]);
|
||||
if (bfd < 1)
|
||||
bfd = 1;
|
||||
if (bfd > BOT_FOLLOW_DISTANCE_DEFAULT_MAX)
|
||||
bfd = BOT_FOLLOW_DISTANCE_DEFAULT_MAX;
|
||||
loaded_bot->SetFollowDistance(bfd);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -515,7 +521,7 @@ bool BotDatabase::SaveNewBot(Bot* bot_inst, uint32& bot_id)
|
||||
bot_inst->GetPR(),
|
||||
bot_inst->GetDR(),
|
||||
bot_inst->GetCorrup(),
|
||||
BOT_DEFAULT_FOLLOW_DISTANCE
|
||||
BOT_FOLLOW_DISTANCE_DEFAULT
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user