Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions server/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ set(tfs_SRC
${CMAKE_CURRENT_LIST_DIR}/playerbotcombat.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotcombatruntime.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotcontroller.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotdepotworkflow.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotdepotsession.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotdeparture.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotequipment.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotequipmentpolicy.cpp
${CMAKE_CURRENT_LIST_DIR}/playerboteconomy.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotgoalarbiter.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbothuntpolicy.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbothuntplanningsession.cpp
Expand All @@ -71,6 +73,7 @@ set(tfs_SRC
${CMAKE_CURRENT_LIST_DIR}/playerbottestpolicy.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotservice.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotservicesession.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotserviceworkflow.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbothuntregions.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotnavigation.cpp
${CMAKE_CURRENT_LIST_DIR}/playerbotnavigationruntime.cpp
Expand Down
12 changes: 6 additions & 6 deletions server/src/playerbotcombat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ PlayerBotSurvivalSnapshot PlayerBotController::survivalSnapshot(const Player& pl
}
}
snapshot.canDoAction = player.canDoAction();
snapshot.buyingPotions = serviceStage == ServiceStage::BuyPotions;
snapshot.buyingPotions = serviceWorkflow.stage() == PlayerBotServiceStage::BuyPotions;
snapshot.lootMovePending = lootWorkflow.hasPendingLootMove();
snapshot.progressionActive = progressionSession.active() != PlayerBotProgressionProcedure::None;
snapshot.progressionDeparture = progressionSession.active(PlayerBotProgressionProcedure::OracleDeparture);
Expand Down Expand Up @@ -1099,9 +1099,9 @@ void PlayerBotController::processTraversal(Player* player, const Position& curre
if (pauseDepotFixtureForRestart(*player, DepotRestartCheckpoint::Approach, currentPosition)) {
return;
}
if (!processNavigation(player, currentPosition, depotSession.approachPosition())) {
if (!processNavigation(player, currentPosition, depotWorkflow.approachPosition())) {
if (fixedTargetRouteFailureCount != 0) {
depotSession.rejectApproach(depotSession.approachPosition(), std::chrono::steady_clock::now() + depotApproachSuppression);
depotWorkflow.rejectApproach(depotWorkflow.approachPosition(), std::chrono::steady_clock::now() + depotApproachSuppression);
clearDepotDiscovery();
clearNavigation();
}
Expand All @@ -1125,12 +1125,12 @@ void PlayerBotController::processTraversal(Player* player, const Position& curre
if (!discoverDepot(*player, currentPosition)) {
return;
}
if (!Position::areInRange<1, 1, 0>(currentPosition, depotSession.lockerPosition())) {
if (!Position::areInRange<1, 1, 0>(currentPosition, depotWorkflow.lockerPosition())) {
setCyclePhase(CyclePhase::ReturnToDepot, currentPosition, "displaced_during_deposit");
clearNavigation();
if (!processNavigation(player, currentPosition, depotSession.approachPosition())) {
if (!processNavigation(player, currentPosition, depotWorkflow.approachPosition())) {
if (fixedTargetRouteFailureCount != 0) {
depotSession.rejectApproach(depotSession.approachPosition(), std::chrono::steady_clock::now() + depotApproachSuppression);
depotWorkflow.rejectApproach(depotWorkflow.approachPosition(), std::chrono::steady_clock::now() + depotApproachSuppression);
clearDepotDiscovery();
clearNavigation();
}
Expand Down
5 changes: 2 additions & 3 deletions server/src/playerbotcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ PlayerBotController::PlayerBotController(const Player& player,
playerId(player.getID()), playerGuid(player.getGUID()), playerName(player.getName()), fixtureRuntime(playerBotTestPolicyFromEnvironment()),
telemetry(player.getName(), player.getGUID()),
equipmentPolicy(oracleVocationId),
inventoryPolicy(itemSellValues, [this](const Player& candidatePlayer, const Item& item) {
inventoryPolicy(economyCatalog.sellValues(), [this](const Player& candidatePlayer, const Item& item) {
return equipmentPolicy.evaluateUpgrade(candidatePlayer, item).has_value();
}), huntRegionCooldowns(sharedHuntRegionCooldowns)
{}
Expand Down Expand Up @@ -143,8 +143,7 @@ Item* PlayerBotController::findActionableSlottedItem(const Player& player, uint1
if (!item || !inventoryPolicy.isActionableSlottedItem(player, *item, candidateSlot, itemId)) {
continue;
}
auto suppressed = unavailableSlottedSales.find({item->getID(), candidateSlot});
if (suppressed != unavailableSlottedSales.end() && suppressed->second > now) {
if (serviceWorkflow.slottedSaleUnavailable(item->getID(), candidateSlot, now)) {
continue;
}
slot = candidateSlot;
Expand Down
51 changes: 16 additions & 35 deletions server/src/playerbotcontroller.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

#include "playerbot.h"
#include "playerbotcombatruntime.h"
#include "playerbotdepotsession.h"
#include "playerbotdepotworkflow.h"
#include "playerboteconomy.h"
#include "playerbotequipmentpolicy.h"
#include "playerbotgoalarbiter.h"
#include "playerbothuntregions.h"
Expand All @@ -24,12 +25,11 @@
#include "playerbotinventorypolicy.h"
#include "playerbotlootworkflow.h"
#include "playerbotnavigationruntime.h"
#include "playerbotnpcsession.h"
#include "playerbotprogressionsession.h"
#include "playerbotsurvivalruntime.h"
#include "playerbottestpolicy.h"
#include "playerbottelemetry.h"
#include "playerbotservicesession.h"
#include "playerbotserviceworkflow.h"

#include "container.h"
#include "condition.h"
Expand Down Expand Up @@ -176,16 +176,9 @@ class PlayerBotController : public std::enable_shared_from_this<PlayerBotControl
Hunt,
};

enum class ServiceStage : uint8_t {
Discover,
SellLoot,
BuyPotions,
Bank,
Complete,
};

using TopLevelGoal = PlayerBotGoalArbiter::TopLevelGoal;
using GoalCandidate = PlayerBotGoalArbiter::GoalCandidate;
using ServiceStage = PlayerBotServiceStage;

using EquipmentUpgrade = PlayerBotEquipmentUpgrade;
using EquipmentLoadout = PlayerBotEquipmentLoadout;
Expand Down Expand Up @@ -232,10 +225,7 @@ class PlayerBotController : public std::enable_shared_from_this<PlayerBotControl
int32_t knownUtility = 0;
};

struct ServiceNpc {
uint32_t id;
Position position;
};
using ServiceNpc = PlayerBotEconomyProvider;

enum class ScenarioStage : uint8_t {
LootCorpse,
Expand Down Expand Up @@ -454,28 +444,28 @@ class PlayerBotController : public std::enable_shared_from_this<PlayerBotControl

void discoverServices(const Position& position);

bool approachServiceNpc(Player* player, ServiceNpc& service, const Position& currentPosition);
bool approachServiceNpc(Player* player, const ServiceNpc& service, const Position& currentPosition);

void refreshItemValues();

const ShopInfo* findOffer(const ServiceNpc& service, uint16_t itemId, bool buying) const;

uint32_t serviceDistance(const Position& from, const ServiceNpc& service) const;

ServiceNpc* findNearestService(std::vector<ServiceNpc>& services, const Position& position);
const ServiceNpc* findNearestService(const std::vector<ServiceNpc>& services, const Position& position) const;

ServiceNpc* findShopFor(uint16_t itemId, bool buying, const Position& position);
const ServiceNpc* findShopFor(uint16_t itemId, bool buying, const Position& position) const;

ServiceNpc* findLootSeller(Player* player, const Position& position, uint16_t& itemId);
const ServiceNpc* findLootSeller(Player* player, const Position& position, uint16_t& itemId) const;
bool prepareSlottedSaleItem(Player* player, uint16_t itemId, const Position& position);

void completeServiceAction(Player* player, const char* action, const PlayerBotServiceTransaction& transaction,
const Position& position);

void processServiceShop(Player* player, const Position& currentPosition, ServiceNpc& service, const char* action,
void processServiceShop(Player* player, const Position& currentPosition, const ServiceNpc& service, const char* action,
uint16_t itemId, uint32_t amount, bool purchase);

void processBank(Player* player, const Position& currentPosition, ServiceNpc& banker);
void processBank(Player* player, const Position& currentPosition, const ServiceNpc& banker);

void processService(Player* player, const Position& currentPosition);

Expand Down Expand Up @@ -553,11 +543,12 @@ class PlayerBotController : public std::enable_shared_from_this<PlayerBotControl
std::chrono::steady_clock::time_point patrolRouteFailureStarted;
uint64_t lastNavigationExpandedNodes = 0;
PlayerBotNavigationResult lastNavigationPlanResult = PlayerBotNavigationResult::Reached;
std::map<uint16_t, uint32_t> itemSellValues;
PlayerBotEconomyCatalog economyCatalog;
PlayerBotDispositionPolicy dispositionPolicy;
PlayerBotEquipmentPolicy equipmentPolicy;
playerbot::PlayerBotInventoryPolicy inventoryPolicy;
PlayerBotSurvivalRuntime survivalRuntime;
PlayerBotDepotSession depotSession;
PlayerBotDepotWorkflow depotWorkflow;
PlayerBotCombatRuntime combatRuntime{PlayerBotCombatRuntimeConfig{
playerbot::traversalCombatTimeout, playerbot::traversalTargetSuppression,
playerbot::lostTargetPursuitTimeout, playerbot::lostTargetSuppression,
Expand All @@ -569,7 +560,6 @@ class PlayerBotController : public std::enable_shared_from_this<PlayerBotControl
playerbot::corpseLootTimeout, playerbot::preferredFoodCount,
}};
CyclePhase cyclePhase = CyclePhase::ReturnToDepot;
ServiceStage serviceStage = ServiceStage::Discover;
PlayerBotProgressionSession progressionSession;
PlayerBotRewardSession rewardSession;
PlayerBotOracleDepartureSession departureSession;
Expand All @@ -582,17 +572,7 @@ class PlayerBotController : public std::enable_shared_from_this<PlayerBotControl
uint32_t pendingReadinessAttempts = 0;
bool readinessEquipmentPending = false;
bool readinessResumeService = false;
std::vector<ServiceNpc> serviceShops;
std::vector<ServiceNpc> serviceBankers;
Position serviceApproachTarget;
std::set<Position> serviceRejectedApproaches;
uint16_t pendingSlottedSaleItemId = 0;
slots_t pendingSlottedSaleSourceSlot = CONST_SLOT_WHEREEVER;
uint32_t pendingSlottedSaleBackpackCount = 0;
uint32_t slottedSaleMoveAttempts = 0;
std::map<std::pair<uint16_t, slots_t>, std::chrono::steady_clock::time_point> unavailableSlottedSales;
PlayerBotNpcSession npcSession;
PlayerBotServiceSession serviceSession;
PlayerBotServiceWorkflow serviceWorkflow;
size_t huntRouteIndex = 0;
uint32_t completedCycles = 0;
std::chrono::steady_clock::time_point huntDeadline;
Expand All @@ -609,4 +589,5 @@ class PlayerBotController : public std::enable_shared_from_this<PlayerBotControl
uint32_t huntRegionStartLevel = 0;
bool deathObserved = false;
};

#endif
10 changes: 5 additions & 5 deletions server/src/playerbotdeparture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ bool PlayerBotController::forceOracleDeparture(Player& player, const Position& p
player.closeContainer(corpseContainerId);
setStage(ScenarioStage::Traverse, position);
progressionSession.reset();
serviceStage = ServiceStage::Discover;
serviceWorkflow.setStage(PlayerBotServiceStage::Discover);

PlayerBotOracleDeparturePlan plan;
std::deque<PlayerBotNavigationStep> route;
Expand Down Expand Up @@ -153,7 +153,7 @@ void PlayerBotController::beginOracleDeparture(Player& player, const Position& p
departureSession.begin(std::move(plan));
progressionSession.begin(PlayerBotProgressionProcedure::OracleDeparture);
const auto& departure = departureSession.plan();
npcSession.reset(departure.npcId);
serviceWorkflow.resetNpc(departure.npcId);
navigationRuntime.adopt(departure.approachPosition, std::move(steps));
emit("strategy_selection", position,
"\"goal\":\"oracle_departure\",\"npc_id\":" + std::to_string(departure.npcId) +
Expand All @@ -171,7 +171,7 @@ void PlayerBotController::finishOracleDeparture(Player* player, const Position&
",\"reason\":" + jsonString(reason));
progressionSession.reset();
departureSession.reset();
npcSession.reset();
serviceWorkflow.resetNpc();
clearNavigation();
if (std::strcmp(result, "success") == 0) {
if (player) {
Expand Down Expand Up @@ -226,15 +226,15 @@ void PlayerBotController::processOracleDeparture(Player* player, const Position&
}

if (departureSession.stage() == PlayerBotOracleDepartureStage::Greet) {
npcSession.resetGreetingAcknowledgement();
serviceWorkflow.resetGreetingAcknowledgement();
telemetry.recordActionAttempt();
oracle->receiveSpeech(player, TALKTYPE_PRIVATE_PN, "hi");
departureSession.setStage(PlayerBotOracleDepartureStage::ConfirmReady);
schedule(1000);
return;
}
if (departureSession.stage() == PlayerBotOracleDepartureStage::ConfirmReady) {
if (!npcSession.isGreetingAcknowledged()) {
if (!serviceWorkflow.isGreetingAcknowledged()) {
if (departureSession.incrementRetries() >= maximumProgressionAttempts) {
finishOracleDeparture(player, currentPosition, "failed", "oracle_focus_unconfirmed");
return;
Expand Down
5 changes: 0 additions & 5 deletions server/src/playerbotdepotsession.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,11 @@ class PlayerBotDepotSession
bool candidatesPrepared() const { return candidatesReady; }
void prepareCandidates(const Position& anchor);
const Position& discoveryAnchor() const { return anchorPosition; }
std::vector<PlayerBotDepotCandidate>& candidates() { return depotCandidates; }
const std::vector<PlayerBotDepotCandidate>& candidates() const { return depotCandidates; }
size_t nextCandidate() const { return nextCandidateIndex; }
void advanceCandidate() { ++nextCandidateIndex; }
void resetCandidates();

uint32_t& indexedCandidateCount() { return indexedCandidates; }
uint32_t& inScopeCandidateCount() { return inScopeCandidates; }
uint32_t& standableCandidateCount() { return standableCandidates; }
uint32_t& suppressedApproachCount() { return suppressedApproaches; }
uint32_t indexedCandidateCount() const { return indexedCandidates; }
uint32_t inScopeCandidateCount() const { return inScopeCandidates; }
uint32_t standableCandidateCount() const { return standableCandidates; }
Expand Down
66 changes: 66 additions & 0 deletions server/src/playerbotdepotworkflow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#include "otpch.h"

#include "playerbotdepotworkflow.h"

void PlayerBotDepotWorkflow::reset()
{
session.reset();
discoveryCandidates.clear();
nextCandidateOffset = 0;
indexedCandidates = 0;
inScopeCandidates = 0;
standableCandidates = 0;
suppressedApproaches = 0;
}

void PlayerBotDepotWorkflow::clearDiscovery()
{
session.clearDiscovery();
discoveryCandidates.clear();
nextCandidateOffset = 0;
indexedCandidates = 0;
inScopeCandidates = 0;
standableCandidates = 0;
suppressedApproaches = 0;
}

void PlayerBotDepotWorkflow::recordCandidate(PlayerBotDepotCandidate candidate)
{
discoveryCandidates.push_back(candidate);
}

void PlayerBotDepotWorkflow::sortCandidates()
{
std::sort(discoveryCandidates.begin(), discoveryCandidates.end(), [](const auto& left, const auto& right) {
return left.distance != right.distance ? left.distance < right.distance :
left.depotId != right.depotId ? left.depotId < right.depotId :
left.lockerPosition != right.lockerPosition ? left.lockerPosition < right.lockerPosition :
left.approachPosition < right.approachPosition;
});
}

bool PlayerBotDepotWorkflow::hasNextCandidate() const
{
return nextCandidateOffset < discoveryCandidates.size();
}

std::optional<PlayerBotDepotCandidate> PlayerBotDepotWorkflow::takeNextCandidate()
{
if (!hasNextCandidate()) {
return std::nullopt;
}
return discoveryCandidates[nextCandidateOffset++];
}

std::optional<std::chrono::steady_clock::time_point> PlayerBotDepotWorkflow::earliestRejectedApproachExpiry() const
{
const auto& rejected = session.rejectedApproaches();
if (rejected.empty()) {
return std::nullopt;
}
auto earliest = rejected.begin()->second;
for (const auto& entry : rejected) {
earliest = std::min(earliest, entry.second);
}
return earliest;
}
Loading