mirror of
https://github.com/mod-playerbots/mod-playerbots.git
synced 2026-02-27 05:45:55 +00:00
# Pull Request
As I began modifying the newrpginfo to change the types of data it
stored, or add new data I found myself with the issue of ending up
either with garbage memory if the information wasnt properly stored on
status change, or needing complicated destructor patterns for non
trivial data sets.
---
## Design Philosophy
Make rpginfo able to handle more complicated information in a strongly
---
## Feature Evaluation
No Feature changes
---
## How to Test the Changes
- Server should be stable for an extended period of time.
- Bots should be able to complete quests, fly, etc as they did before.
## Complexity & Impact
- Does this change add new decision branches?
- [X ] No
- [ ] Yes (**explain below**)
- Does this change increase per-bot or per-tick processing?
- [ ] No
- [ X] Yes (**describe and justify impact**)
Potentially as there can be more memory involved in the object.
- Could this logic scale poorly under load?
- [X ] No
- [ ] Yes (**explain why**)
---
## Defaults & Configuration
- Does this change modify default bot behavior?
- [ X] No
- [ ] Yes (**explain why**)
If this introduces more advanced or AI-heavy logic:
- [ ] Lightweight mode remains the default
- [ ] More complex behavior is optional and thereby configurable
---
## AI Assistance
- Was AI assistance (e.g. ChatGPT or similar tools) used while working
on this change?
- [ ] No
- [ X] Yes (**explain below**)
If yes, please specify:
- Gemini suggested the use of std::variant as an alternative data
structure. I found additinal external references that correlated with
the same suggestion of moving away from a union.
- Implementation was performed manually with Co-pilot auto-complete
---
## Final Checklist
In progress.
- [ ] Stability is not compromised
- [ ] Performance impact is understood, tested, and acceptable
- [ ] Added logic complexity is justified and explained
- [ ] Documentation updated if needed
---
## Notes for Reviewers
Im not 100% sure if this is a good design choice. There are some things
I didnt quite like by the end of this, specifically having to double
check whenever accessing data whether exists or not even though an
action has already been triggered. But I have a PR in the works where I
want to store a full flight path vector, and the union was giving me
issues. (It appears that state changes may be occuring in the same tick
between RPG status update and the stated action, leading to incorrect
data gathering.
I ended up solving it by first checking a pointer to the object, and
then getting the reference.
```c++
auto* dataPtr = std::get_if<NewRpgInfo::DoQuest>(&info.data);
if (!dataPtr)
return false;
auto& data = *dataPtr;
```
---------
Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
107 lines
2.9 KiB
C++
107 lines
2.9 KiB
C++
#ifndef _PLAYERBOT_NEWRPGACTION_H
|
|
#define _PLAYERBOT_NEWRPGACTION_H
|
|
|
|
#include "Duration.h"
|
|
#include "MovementActions.h"
|
|
#include "NewRpgBaseAction.h"
|
|
#include "NewRpgInfo.h"
|
|
#include "NewRpgStrategy.h"
|
|
#include "Object.h"
|
|
#include "ObjectDefines.h"
|
|
#include "ObjectGuid.h"
|
|
#include "PlayerbotAI.h"
|
|
#include "QuestDef.h"
|
|
#include "TravelMgr.h"
|
|
|
|
class TellRpgStatusAction : public Action
|
|
{
|
|
public:
|
|
TellRpgStatusAction(PlayerbotAI* botAI) : Action(botAI, "rpg status") {}
|
|
|
|
bool Execute(Event event) override;
|
|
};
|
|
|
|
class StartRpgDoQuestAction : public Action
|
|
{
|
|
public:
|
|
StartRpgDoQuestAction(PlayerbotAI* botAI) : Action(botAI, "start rpg do quest") {}
|
|
|
|
bool Execute(Event event) override;
|
|
};
|
|
|
|
class NewRpgStatusUpdateAction : public NewRpgBaseAction
|
|
{
|
|
public:
|
|
NewRpgStatusUpdateAction(PlayerbotAI* botAI) : NewRpgBaseAction(botAI, "new rpg status update")
|
|
{
|
|
// int statusCount = RPG_STATUS_END - 1;
|
|
|
|
// transitionMat.resize(statusCount, std::vector<int>(statusCount, 0));
|
|
|
|
// transitionMat[RPG_IDLE][RPG_GO_GRIND] = 20;
|
|
// transitionMat[RPG_IDLE][RPG_GO_CAMP] = 15;
|
|
// transitionMat[RPG_IDLE][RPG_WANDER_NPC] = 30;
|
|
// transitionMat[RPG_IDLE][RPG_DO_QUEST] = 35;
|
|
}
|
|
bool Execute(Event event) override;
|
|
|
|
protected:
|
|
// static NewRpgStatusTransitionProb transitionMat;
|
|
const int32 statusWanderNpcDuration = 5 * 60 * 1000;
|
|
const int32 statusWanderRandomDuration = 5 * 60 * 1000;
|
|
const int32 statusRestDuration = 30 * 1000;
|
|
const int32 statusDoQuestDuration = 30 * 60 * 1000;
|
|
};
|
|
|
|
class NewRpgGoGrindAction : public NewRpgBaseAction
|
|
{
|
|
public:
|
|
NewRpgGoGrindAction(PlayerbotAI* botAI) : NewRpgBaseAction(botAI, "new rpg go grind") {}
|
|
bool Execute(Event event) override;
|
|
};
|
|
|
|
class NewRpgGoCampAction : public NewRpgBaseAction
|
|
{
|
|
public:
|
|
NewRpgGoCampAction(PlayerbotAI* botAI) : NewRpgBaseAction(botAI, "new rpg go camp") {}
|
|
bool Execute(Event event) override;
|
|
};
|
|
|
|
class NewRpgWanderRandomAction : public NewRpgBaseAction
|
|
{
|
|
public:
|
|
NewRpgWanderRandomAction(PlayerbotAI* botAI) : NewRpgBaseAction(botAI, "new rpg wander random") {}
|
|
bool Execute(Event event) override;
|
|
};
|
|
|
|
class NewRpgWanderNpcAction : public NewRpgBaseAction
|
|
{
|
|
public:
|
|
NewRpgWanderNpcAction(PlayerbotAI* botAI) : NewRpgBaseAction(botAI, "new rpg move npcs") {}
|
|
bool Execute(Event event) override;
|
|
|
|
const uint32 npcStayTime = 8 * 1000;
|
|
};
|
|
|
|
class NewRpgDoQuestAction : public NewRpgBaseAction
|
|
{
|
|
public:
|
|
NewRpgDoQuestAction(PlayerbotAI* botAI) : NewRpgBaseAction(botAI, "new rpg do quest") {}
|
|
bool Execute(Event event) override;
|
|
|
|
protected:
|
|
bool DoIncompleteQuest(NewRpgInfo::DoQuest& data);
|
|
bool DoCompletedQuest(NewRpgInfo::DoQuest& data);
|
|
|
|
const uint32 poiStayTime = 5 * 60 * 1000;
|
|
};
|
|
|
|
class NewRpgTravelFlightAction : public NewRpgBaseAction
|
|
{
|
|
public:
|
|
NewRpgTravelFlightAction(PlayerbotAI* botAI) : NewRpgBaseAction(botAI, "new rpg travel flight") {}
|
|
bool Execute(Event event) override;
|
|
};
|
|
|
|
#endif
|