Compare commits

...

11 Commits

Author SHA1 Message Date
Revision
2f0a557655
Merge pull request #2150 from mod-playerbots/test-staging
Master update from Test staging
2026-02-23 00:05:48 +01:00
Keleborn
d1cac8d027
Bug fix. Equip Action triggered action (#2142)
# Pull Request

Brighton caught a mistake I made changeing the action registry, so the
correct action was no longer triggering. I cleaned that up, and renamed
the action.


## How to Test the Changes

- This was tested by adding logging to both equip actions. But to test
this without that, the best way to verify the fix is to stop alts from
auto upgrading via config. Then they should correctly follow the
configured behavior.

## Complexity & Impact

Does this change add new decision branches?
- - [x ] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

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:
- - [x] 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?
- - [x] No
- - [ ] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
2026-02-15 16:29:20 -08:00
bash
3c62a45fad Revert "Convert PlayerBots tables to InnoDB (#2083)"
This reverts commit c86032f43b7bccb861c33769385db7a522e75513.
2026-02-15 20:47:26 +01:00
Keleborn
441f9f7552
Warnings PR 1: Event warnings and headers (#2106)
# Pull Request

This is the first in a series of PRs intended to eliminate warnings in
the module. The design intent is to eliminate the calling event when not
needed in the body of the function. Based off of SmashingQuasars work.

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

- Does this change add new decision branches?
    - [x] No
    - [ ] Yes (**explain below**)

- Does this change increase per-bot or per-tick processing?
    - [x] No
    - [ ] Yes (**describe and justify impact**)

- 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?
    - [x] No
    - [ ] Yes (**explain below**)

---

## Final Checklist

- [x] Stability is not compromised
- [x] Performance impact is understood, tested, and acceptable
- [x] Added logic complexity is justified and explained
- [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-02-14 20:55:10 +01:00
bashermens
80aeeda0e8
Flying, waterwalking, swimming movement optimizations and transition fixes. (#2134)
# Pull Request

**Fixes and optimizations for flying, water walking, swimming**:
* optimized triggers
* ensuring movement flag updates only happen between actual transitions
states
* fly bug fix; fly with bots following with stay command midair, fly
down and dismount yourself, follow command and now the bots fall instead
of lingering around in the air)
* updated z-axes correction for water walking and bots (for real players
this is handled client-side)
* added lift off movement for more stabile transition from ground(level)
to flying

**Tested**:
* Test all transitions; water walk, swimming, swimming, walking,
mounting while water walking etc.
* Flying with bots and fly master routes
* Movement flag updates only occur during transitions

**Known issues**: transition between water walking, swimming and back
again, in most cases the bots will stay under the waterline instead of
jumping on the z axes on water level. (will fix that another time)

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

Apply water walking effect on your bots, shaman or dk, and test all
possible transitions and follow actions
of the bots. water walking, swim, walk on land, swimming and walk
without water walking effect/aura, fly mount from water, from ground,
etc.

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)


Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

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:
- - [x] Lightweight mode remains the default
- - [x] 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?
- - [x] No
- - [ ] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
2026-02-14 11:31:45 -08:00
NoxMax
25800f54e8
Fix/Feat: PVP with master and PVP probablity system (thread-safe remake) (#2008)
This is a remake of #1914 that had to be reverted. Original PR had a
thread-safe issue where a crash happens if multiple threads access the
cache at the same time. Unfortunately this problem was not caught in
earlier testing. I don't know if because I was testing on a month old
branch, if my settings had only ~2000, or if I needed test runs longer
than an hour to find out.

Regardless, this has all been addressed. Test have been run on the
latest commits from today (2026/1/11), with all 7500 of my bots active,
with a test run that lasted 15 hours. All stable and bots are following
the probability system without issue.

~~The new edit uses mutex locking, preventing simultaneous access of the
cache by multiple threads.~~
The new edit uses deterministic hashing, thereby not having issues with
cache thread safety to begin with. Thank you @hermensbas for catching
and reverting the original problem PR. Apologies for not catching the
issue myself.

---
Original PR description:

There are two related PVP components in this PR. First is the simple yet
fundamental change to bot behaviour when they are in party. Right now
bots with a master will go into PVP when there's a nearby PVP target,
even if master is not in PVP. This absolutely should not happen. Bots
should not consider PVP at all if master is not in PVP. The fix is only
3 lines in EnemyPlayerValue

The second component is introducing PVP probabilities, to make decisions
more realistic. Right now even a level 1 bot will 100% go into PVP if it
sees a level 80 PVP target. They can't help themselves. So the change
here addresses that insanity. Several thresholds (subject to community
review) are introduced:

1. Bots will not fight a target 5 or more levels higher than them
2. Bots have a 25% chance starting a fight with a target +/- 4 levels
from them.
3. Bots have a 50% chance starting a fight with a target +/- 3 levels
from them.
4. Bots have a 75% chance starting a fight with a target +/- 2 levels
from them.
5. Bots have a 100% chance starting a fight with a target +/- 1 level
from them.
6. Bots have a 25% chance starting a fight with a target 5 or more
levels below them (ganking. thought it would be funny, and technically
realistic of player behaviour)

Exception of course exist for BG/Arena/Duel, and in capitals where bots
will always PVP. Also bots will always defend themselves if attacked.

Few notes: 
1. The if/ else if logic can be further simplified, but only if we use
thresholds that are different by one. So current logic allows for
flexibility of using values like 10/7/5/3 instead of 5/4/3/2.
2. The caching system is per-bot basis. So for some target X, if some
bot decides to attack it, another bot will make its own decision. At
first I used a simplified global system (thinking there might be
performance concerns) where if one bot decides to attack a target then
they all do, but when I switched to the more realistic per-bot basis, I
didn't see an effect on performance.
3. Variables are obviously not configurable right now. I'm starting to
see Bash's POV that maybe we have too many configs 😬 Still,
they can be easily exposed in the future, and if someone is reading this
then, remember to change constexpr to const.

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-02-13 09:31:55 -08:00
Crow
9748e36ad6
Fix potential failure of Magtheridon cube clickers to engage in combat (#2129)
# Pull Request

I noticed a problem that has always existed with the Magtheridon
strategy but just never came up for me due to chance. Cube clicker logic
is based on a timer that resets after every Blast Nova. If the timer is
not reset, the cubes will still be clicked, but the clickers will do
nothing but wait to click on the cubes instead of resuming combat
between Blast Novas. Because tracking of the Blast Nova state happens
during the cube clicking sequence, if a cube clicker is assigned the
singular role to track Blast Nova state (which is done simply by
returning the first DPS bot found), then the timer will not be reset.

This whole strategy needs a refactor, but the simple fix for this
problem for now is just to remove the role check for tracking the Blast
Nova state. I tested the fix, and it works.

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

Does this change add new decision branches?
- - [X] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [X] No
- - [ ] Yes (**describe and justify impact**)

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?
- - [X] No
- - [ ] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [ ] 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

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
2026-02-13 09:25:12 -08:00
Alex Dcnh
17b8d7f68b
Stage1 refactor world position method names (#2126)
# Pull Request

This change replaces the non‑standard
WorldPosition::getX/getY/getZ/getO/getMapId wrappers with the core
getters (GetPositionX/Y/Z, GetOrientation, GetMapId) and removes the
redundant wrappers.
Goal: align the module with AzerothCore conventions, reduce local
adapters, and improve long‑term maintainability.

---

## Design Philosophy

This is a structural cleanup only (coordinate access) and does not alter
any AI behavior or decision logic.
It follows the stability/performance-first philosophy and does not add
branches or extra runtime work.

Before submitting: yes, this change aligns with the principles of
stability, performance, and predictability.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Minimum logic required: use core getters (GetPositionX/Y/Z, GetMapId,
GetOrientation) wherever coordinates are needed.
- Cheapest implementation: direct call replacement and removal of
redundant wrappers.
- Runtime cost: negligible (same data access, no additional logic).

---

## How to Test the Changes

- No functional testing required (behavior‑neutral refactor).
- Recommended: compile the module and run a normal server startup as
validation.

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [x] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

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:
- - [x] Lightweight mode remains the default
- - [x] 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:

- AI tool or model used: Copilot
- Purpose of usage: Translate this PR text from french to English

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

This is a core-friendly cleanup only, with no behavioral change.
No additional logic or CPU cost is introduced.
2026-02-13 09:24:42 -08:00
privatecore
a0a50204ec
Fix action validation checks: isUseful -> isPossible + codestyle fixes and corrections (#2125)
# Pull Request

Fix the incorrect logic flaw when processing actions from different
sources. It should be: `isUseful` -> `isPossible`. The original logic is
based on the Mangosbot code and the impl presented inside
`Engine::DoNextAction`. This should fix all wrong validation orders for
triggers and direct/specific actions.

Code style is based on the AzerothCore style guide + clang-format.

---

## Design Philosophy

We prioritize **stability, performance, and predictability** over
behavioral realism.
Complex player-mimicking logic is intentionally limited due to its
negative impact on scalability, maintainability, and
long-term robustness.

Excessive processing overhead can lead to server hiccups, increased CPU
usage, and degraded performance for all
participants. Because every action and
decision tree is executed **per bot and per trigger**, even small
increases in logic complexity can scale poorly and
negatively affect both players and
world (random) bots. Bots are not expected to behave perfectly, and
perfect simulation of human decision-making is not a
project goal. Increased behavioral
realism often introduces disproportionate cost, reduced predictability,
and significantly higher maintenance overhead.

Every additional branch of logic increases long-term responsibility. All
decision paths must be tested, validated, and
maintained continuously as the system evolves.
If advanced or AI-intensive behavior is introduced, the **default
configuration must remain the lightweight decision
model**. More complex behavior should only be
available as an **explicit opt-in option**, clearly documented as having
a measurable performance cost.

Principles:

- **Stability before intelligence**  
  A stable system is always preferred over a smarter one.

- **Performance is a shared resource**  
  Any increase in bot cost affects all players and all bots.

- **Simple logic scales better than smart logic**  
Predictable behavior under load is more valuable than perfect decisions.

- **Complexity must justify itself**  
  If a feature cannot clearly explain its cost, it should not exist.

- **Defaults must be cheap**  
  Expensive behavior must always be optional and clearly communicated.

- **Bots should look reasonable, not perfect**  
  The goal is believable behavior, not human simulation.

Before submitting, confirm that this change aligns with those
principles.

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
- Describe the **cheapest implementation** that produces an acceptable
result?
- Describe the **runtime cost** when this logic executes across many
bots?

---

## How to Test the Changes

- Step-by-step instructions to test the change
- Any required setup (e.g. multiple players, bots, specific
configuration)
- Expected behavior and how to verify it

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

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?
- - [x] No
- - [ ] Yes (**explain below**)

If yes, please specify:

- AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.)
- Purpose of usage (e.g. brainstorming, refactoring, documentation, code
generation)
- Which parts of the change were influenced or generated
- Whether the result was manually reviewed and adapted

AI assistance is allowed, but all submitted code must be fully
understood, reviewed, and owned by the contributor.
Any AI-influenced changes must be verified against existing CORE and PB
logic. We expect contributors to be honest
about what they do and do not understand.

---

## Final Checklist

- - [x] Stability is not compromised
- - [x] Performance impact is understood, tested, and acceptable
- - [x] Added logic complexity is justified and explained
- - [x] Documentation updated if needed

---

## Notes for Reviewers

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.
2026-02-13 09:24:11 -08:00
Keleborn
80b3823f12
Warnings PR 3, remove std::move when not necessary. (#2108)
# Pull Request

std::move was being used in a few places to return a vector. Its not
necessary. A direct return allows for some optimizations that moving
wouldnt.

## How to Test the Changes

-Bots should initialize correctly 

## Complexity & Impact

- Does this change add new decision branches?
    - [x] No
    - [ ] Yes (**explain below**)

- Does this change increase per-bot or per-tick processing?
    - [x] No
    - [ ] Yes (**describe and justify impact**)

- 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:

- [x] 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?
    - [x] No
    - [ ] Yes (**explain below**)

---

## Final Checklist

- [ ] 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

Anything that significantly improves realism at the cost of stability or
performance should be carefully discussed
before merging.

---------

Co-authored-by: bashermens <31279994+hermensbas@users.noreply.github.com>
2026-02-13 09:22:27 -08:00
Keleborn
ee2a399ac8
Refactor newrpginfo data union to std::variant (#2079)
# 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>
2026-02-13 09:19:54 -08:00
219 changed files with 1599 additions and 1813 deletions

View File

@ -6,9 +6,9 @@
#include "AcceptBattlegroundInvitationAction.h"
#include "Event.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
bool AcceptBgInvitationAction::Execute(Event event)
bool AcceptBgInvitationAction::Execute(Event /*event*/)
{
uint8 type = 0; // arenatype if arena
uint8 unk2 = 0; // unk, can be 0x0 (may be if was invited?) and 0x1
@ -18,9 +18,9 @@ bool AcceptBgInvitationAction::Execute(Event event)
WorldPacket packet(CMSG_BATTLEFIELD_PORT, 20);
packet << type << unk2 << (uint32)bgTypeId_ << unk << action;
// packet << bgTypeId_ << action;
bot->GetSession()->HandleBattleFieldPortOpcode(packet);
botAI->ResetStrategies();
return true;
}

View File

@ -22,7 +22,7 @@ bool AddLootAction::Execute(Event event)
return AI_VALUE(LootObjectStack*, "available loot")->Add(guid);
}
bool AddAllLootAction::Execute(Event event)
bool AddAllLootAction::Execute(Event /*event*/)
{
bool added = false;

View File

@ -58,7 +58,7 @@ bool ReachAreaTriggerAction::Execute(Event event)
return true;
}
bool AreaTriggerAction::Execute(Event event)
bool AreaTriggerAction::Execute(Event /*event*/)
{
LastMovement& movement = context->GetValue<LastMovement&>("last area trigger")->Get();

View File

@ -1,19 +1,20 @@
#include "AutoMaintenanceOnLevelupAction.h"
#include "GuildMgr.h"
#include "SpellMgr.h"
#include "PlayerbotAIConfig.h"
#include "PlayerbotFactory.h"
#include "Playerbots.h"
#include "RandomPlayerbotMgr.h"
#include "SharedDefines.h"
#include "BroadcastHelper.h"
bool AutoMaintenanceOnLevelupAction::Execute(Event event)
bool AutoMaintenanceOnLevelupAction::Execute(Event /*event*/)
{
AutoPickTalents();
AutoLearnSpell();
AutoUpgradeEquip();
AutoTeleportForLevel();
return true;
}

View File

@ -13,9 +13,8 @@
#include "PlayerbotAI.h"
#include "Playerbots.h"
#include "PositionValue.h"
#include "UpdateTime.h"
bool BGJoinAction::Execute(Event event)
bool BGJoinAction::Execute(Event /*event*/)
{
uint32 queueType = AI_VALUE(uint32, "bg type");
if (!queueType) // force join to fill bg
@ -653,7 +652,7 @@ bool FreeBGJoinAction::shouldJoinBg(BattlegroundQueueTypeId queueTypeId, Battleg
return false;
}
bool BGLeaveAction::Execute(Event event)
bool BGLeaveAction::Execute(Event /*event*/)
{
if (!(bot->InBattlegroundQueue() || bot->InBattleground()))
return false;
@ -1064,7 +1063,7 @@ bool BGStatusAction::Execute(Event event)
return true;
}
bool BGStatusCheckAction::Execute(Event event)
bool BGStatusCheckAction::Execute(Event /*event*/)
{
if (bot->IsBeingTeleported())
return false;
@ -1080,7 +1079,7 @@ bool BGStatusCheckAction::Execute(Event event)
bool BGStatusCheckAction::isUseful() { return bot->InBattlegroundQueue(); }
bool BGStrategyCheckAction::Execute(Event event)
bool BGStrategyCheckAction::Execute(Event /*event*/)
{
bool inside_bg = bot->InBattleground() && bot->GetBattleground();
;

View File

@ -1557,7 +1557,7 @@ bool BGTactics::eyJumpDown()
//
// actual bg tactics below
//
bool BGTactics::Execute(Event event)
bool BGTactics::Execute(Event /*event*/)
{
Battleground* bg = bot->GetBattleground();
if (!bg)
@ -4249,7 +4249,7 @@ bool BGTactics::IsLockedInsideKeep()
return false;
}
bool ArenaTactics::Execute(Event event)
bool ArenaTactics::Execute(Event /*event*/)
{
if (!bot->InBattleground())
{

View File

@ -18,7 +18,7 @@ bool BossFireResistanceAction::isUseful()
return bossFireResistanceTrigger.IsActive();
}
bool BossFireResistanceAction::Execute(Event event)
bool BossFireResistanceAction::Execute(Event /*event*/)
{
PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI);
botAI->ChangeStrategy(ADD_STRATEGY_CHAR + paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
@ -32,7 +32,7 @@ bool BossFrostResistanceAction::isUseful()
return bossFrostResistanceTrigger.IsActive();
}
bool BossFrostResistanceAction::Execute(Event event)
bool BossFrostResistanceAction::Execute(Event /*event*/)
{
PaladinFrostResistanceStrategy paladinFrostResistanceStrategy(botAI);
botAI->ChangeStrategy(ADD_STRATEGY_CHAR + paladinFrostResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
@ -46,7 +46,7 @@ bool BossNatureResistanceAction::isUseful()
return bossNatureResistanceTrigger.IsActive();
}
bool BossNatureResistanceAction::Execute(Event event)
bool BossNatureResistanceAction::Execute(Event /*event*/)
{
HunterNatureResistanceStrategy hunterNatureResistanceStrategy(botAI);
botAI->ChangeStrategy(ADD_STRATEGY_CHAR + hunterNatureResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);
@ -60,7 +60,7 @@ bool BossShadowResistanceAction::isUseful()
return bossShadowResistanceTrigger.IsActive();
}
bool BossShadowResistanceAction::Execute(Event event)
bool BossShadowResistanceAction::Execute(Event /*event*/)
{
PaladinShadowResistanceStrategy paladinShadowResistanceStrategy(botAI);
botAI->ChangeStrategy(ADD_STRATEGY_CHAR + paladinShadowResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT);

View File

@ -175,7 +175,7 @@ bool BuyAction::Execute(Event event)
if (needMoneyFor == NeedMoneyFor::gear)
{
botAI->DoSpecificAction("equip upgrades");
botAI->DoSpecificAction("equip upgrades packet action");
}
}
}
@ -206,7 +206,7 @@ bool BuyAction::Execute(Event event)
if (usage == ITEM_USAGE_REPLACE || usage == ITEM_USAGE_EQUIP ||
usage == ITEM_USAGE_BAD_EQUIP || usage == ITEM_USAGE_BROKEN_EQUIP)
{
botAI->DoSpecificAction("equip upgrades");
botAI->DoSpecificAction("equip upgrades packet action");
break;
}
}

View File

@ -7,12 +7,14 @@
#include "Player.h"
#include "PlayerbotAI.h"
bool CancelChannelAction::Execute(Event event)
bool CancelChannelAction::Execute(Event /*event*/)
{
if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
{
bot->InterruptSpell(CURRENT_CHANNELED_SPELL);
return true;
}
return false;
}

View File

@ -334,7 +334,7 @@ bool CastRandomSpellAction::castSpell(uint32 spellId, WorldObject* wo)
return botAI->CastSpell(spellId, wo->GetPositionX(), wo->GetPositionY(), wo->GetPositionZ());
}
bool DisEnchantRandomItemAction::Execute(Event event)
bool DisEnchantRandomItemAction::Execute(Event /*event*/)
{
std::vector<Item*> items =
AI_VALUE2(std::vector<Item*>, "inventory items", "usage " + std::to_string(ITEM_USAGE_DISENCHANT));

View File

@ -10,9 +10,9 @@
#include "Event.h"
#include "PlayerbotAIConfig.h"
#include "PlayerbotFactory.h"
#include "Playerbots.h"
#include "AiObjectContext.h"
#include "Log.h"
#include "RandomPlayerbotMgr.h"
bool ChangeTalentsAction::Execute(Event event)
{
@ -184,7 +184,7 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
// // }
// // }
// return std::move(ret);
// return ret;
// }
// std::vector<TalentPath*> ChangeTalentsAction::getPremadePaths(TalentSpec* oldSpec)
@ -201,7 +201,7 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
// // }
// // }
// return std::move(ret);
// return ret;
// }
// TalentPath* ChangeTalentsAction::getPremadePath(uint32 id)
@ -368,11 +368,11 @@ std::string ChangeTalentsAction::SpecApply(std::string param)
// return nullptr;
// }
bool AutoSetTalentsAction::Execute(Event event)
bool AutoSetTalentsAction::Execute(Event /*event*/)
{
std::ostringstream out;
if (!sPlayerbotAIConfig.autoPickTalents || !sRandomPlayerbotMgr.IsRandomBot(bot))
if (!PlayerbotAIConfig::instance().autoPickTalents || !RandomPlayerbotMgr::instance().IsRandomBot(bot))
return false;
if (bot->GetFreeTalentPoints() <= 0)

View File

@ -42,7 +42,7 @@ void PositionsResetAction::SetStayPosition(float x, float y, float z)
posMap["stay"] = pos;
}
bool FollowChatShortcutAction::Execute(Event event)
bool FollowChatShortcutAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)
@ -116,7 +116,7 @@ bool FollowChatShortcutAction::Execute(Event event)
return true;
}
bool StayChatShortcutAction::Execute(Event event)
bool StayChatShortcutAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)
@ -133,7 +133,7 @@ bool StayChatShortcutAction::Execute(Event event)
return true;
}
bool MoveFromGroupChatShortcutAction::Execute(Event event)
bool MoveFromGroupChatShortcutAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)
@ -148,7 +148,7 @@ bool MoveFromGroupChatShortcutAction::Execute(Event event)
return true;
}
bool FleeChatShortcutAction::Execute(Event event)
bool FleeChatShortcutAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)
@ -171,7 +171,7 @@ bool FleeChatShortcutAction::Execute(Event event)
return true;
}
bool GoawayChatShortcutAction::Execute(Event event)
bool GoawayChatShortcutAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)
@ -188,7 +188,7 @@ bool GoawayChatShortcutAction::Execute(Event event)
return true;
}
bool GrindChatShortcutAction::Execute(Event event)
bool GrindChatShortcutAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)
@ -204,7 +204,7 @@ bool GrindChatShortcutAction::Execute(Event event)
return true;
}
bool TankAttackChatShortcutAction::Execute(Event event)
bool TankAttackChatShortcutAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)
@ -224,7 +224,7 @@ bool TankAttackChatShortcutAction::Execute(Event event)
return true;
}
bool MaxDpsChatShortcutAction::Execute(Event event)
bool MaxDpsChatShortcutAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)
@ -241,7 +241,7 @@ bool MaxDpsChatShortcutAction::Execute(Event event)
return true;
}
bool BwlChatShortcutAction::Execute(Event event)
bool BwlChatShortcutAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)

View File

@ -7,9 +7,10 @@
#include "Event.h"
#include "GuildTaskMgr.h"
#include "Playerbots.h"
#include "PlayerbotAIConfig.h"
#include "PlayerbotAI.h"
bool CheckMailAction::Execute(Event event)
bool CheckMailAction::Execute(Event /*event*/)
{
WorldPacket p;
bot->GetSession()->HandleQueryNextMailTime(p);
@ -28,7 +29,7 @@ bool CheckMailAction::Execute(Event event)
continue;
uint32 account = owner->GetSession()->GetAccountId();
if (sPlayerbotAIConfig.IsInRandomAccountList(account))
if (PlayerbotAIConfig::instance().IsInRandomAccountList(account))
continue;
ProcessMail(mail, owner, trans);

View File

@ -55,63 +55,6 @@ MountData CollectMountData(const Player* bot)
return data;
}
bool CheckMountStateAction::isUseful()
{
// Not useful when:
if (botAI->IsInVehicle() || bot->isDead() || bot->HasUnitState(UNIT_STATE_IN_FLIGHT) ||
!bot->IsOutdoors() || bot->InArena())
return false;
master = GetMaster();
// Get shapeshift states, only applicable when there's a master
if (master)
{
botInShapeshiftForm = bot->GetShapeshiftForm();
masterInShapeshiftForm = master->GetShapeshiftForm();
}
// Not useful when in combat and not currently mounted / travel formed
if ((bot->IsInCombat() || botAI->GetState() == BOT_STATE_COMBAT) &&
!bot->IsMounted() && botInShapeshiftForm != FORM_TRAVEL && botInShapeshiftForm != FORM_FLIGHT && botInShapeshiftForm != FORM_FLIGHT_EPIC)
return false;
// In addition to checking IsOutdoors, also check whether bot is clipping below floor slightly because that will
// cause bot to falsly indicate they are outdoors. This fixes bug where bot tries to mount indoors (which seems
// to mostly be an issue in tunnels of WSG and AV)
float posZ = bot->GetPositionZ();
float groundLevel = bot->GetMapWaterOrGroundLevel(bot->GetPositionX(), bot->GetPositionY(), posZ);
if (!bot->IsMounted() && !bot->HasWaterWalkAura() && posZ < groundLevel)
return false;
// Not useful when bot does not have mount strat and is not currently mounted
if (!GET_PLAYERBOT_AI(bot)->HasStrategy("mount", BOT_STATE_NON_COMBAT) && !bot->IsMounted())
return false;
// Not useful when level lower than minimum required
if (bot->GetLevel() < sPlayerbotAIConfig.useGroundMountAtMinLevel)
return false;
// Allow mounting while transformed only if the form allows it
if (bot->HasAuraType(SPELL_AURA_TRANSFORM) && bot->IsInDisallowedMountForm())
return false;
// BG Logic
if (bot->InBattleground())
{
// Do not use when carrying BG Flags
if (bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG) || bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL))
return false;
// Only mount if BG starts in less than 30 sec
if (Battleground* bg = bot->GetBattleground())
if (bg->GetStatus() == STATUS_WAIT_JOIN && bg->GetStartDelayTime() > BG_START_DELAY_30S)
return false;
}
return true;
}
bool CheckMountStateAction::Execute(Event /*event*/)
{
// Determine if there are no attackers
@ -182,6 +125,63 @@ bool CheckMountStateAction::Execute(Event /*event*/)
return false;
}
bool CheckMountStateAction::isUseful()
{
// Not useful when:
if (botAI->IsInVehicle() || bot->isDead() || bot->HasUnitState(UNIT_STATE_IN_FLIGHT) ||
!bot->IsOutdoors() || bot->InArena())
return false;
master = GetMaster();
// Get shapeshift states, only applicable when there's a master
if (master)
{
botInShapeshiftForm = bot->GetShapeshiftForm();
masterInShapeshiftForm = master->GetShapeshiftForm();
}
// Not useful when in combat and not currently mounted / travel formed
if ((bot->IsInCombat() || botAI->GetState() == BOT_STATE_COMBAT) &&
!bot->IsMounted() && botInShapeshiftForm != FORM_TRAVEL && botInShapeshiftForm != FORM_FLIGHT && botInShapeshiftForm != FORM_FLIGHT_EPIC)
return false;
// In addition to checking IsOutdoors, also check whether bot is clipping below floor slightly because that will
// cause bot to falsly indicate they are outdoors. This fixes bug where bot tries to mount indoors (which seems
// to mostly be an issue in tunnels of WSG and AV)
float posZ = bot->GetPositionZ();
float groundLevel = bot->GetMapWaterOrGroundLevel(bot->GetPositionX(), bot->GetPositionY(), posZ);
if (!bot->IsMounted() && !bot->HasWaterWalkAura() && posZ < groundLevel)
return false;
// Not useful when bot does not have mount strat and is not currently mounted
if (!GET_PLAYERBOT_AI(bot)->HasStrategy("mount", BOT_STATE_NON_COMBAT) && !bot->IsMounted())
return false;
// Not useful when level lower than minimum required
if (bot->GetLevel() < sPlayerbotAIConfig.useGroundMountAtMinLevel)
return false;
// Allow mounting while transformed only if the form allows it
if (bot->HasAuraType(SPELL_AURA_TRANSFORM) && bot->IsInDisallowedMountForm())
return false;
// BG Logic
if (bot->InBattleground())
{
// Do not use when carrying BG Flags
if (bot->HasAura(BG_WS_SPELL_WARSONG_FLAG) || bot->HasAura(BG_WS_SPELL_SILVERWING_FLAG) || bot->HasAura(BG_EY_NETHERSTORM_FLAG_SPELL))
return false;
// Only mount if BG starts in less than 30 sec
if (Battleground* bg = bot->GetBattleground())
if (bg->GetStatus() == STATUS_WAIT_JOIN && bg->GetStartDelayTime() > BG_START_DELAY_30S)
return false;
}
return true;
}
bool CheckMountStateAction::Mount()
{
// Remove current Shapeshift if need be

View File

@ -6,12 +6,15 @@
#include "CheckValuesAction.h"
#include "Event.h"
#include "Playerbots.h"
#include "ServerFacade.h"
#include "PlayerbotAI.h"
#include "TravelNode.h"
#include "AiObjectContext.h"
CheckValuesAction::CheckValuesAction(PlayerbotAI* botAI) : Action(botAI, "check values") {}
bool CheckValuesAction::Execute(Event event)
bool CheckValuesAction::Execute(Event /*event*/)
{
if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT))
{

View File

@ -6,7 +6,6 @@
#include <random>
#include "ChooseRpgTargetAction.h"
#include "BattlegroundMgr.h"
#include "BudgetValues.h"
#include "ChatHelper.h"
#include "Event.h"
@ -14,7 +13,6 @@
#include "GuildCreateActions.h"
#include "Playerbots.h"
#include "RpgSubActions.h"
#include "Util.h"
#include "ServerFacade.h"
#include "PossibleRpgTargetsValue.h"
@ -112,7 +110,7 @@ float ChooseRpgTargetAction::getMaxRelevance(GuidPosition guidP)
return floor((maxRelevance - 1.0) * 1000.0f);
}
bool ChooseRpgTargetAction::Execute(Event event)
bool ChooseRpgTargetAction::Execute(Event /*event*/)
{
//TravelTarget* travelTarget = AI_VALUE(TravelTarget*, "travel target"); //not used, line marked for removal.
Player* master = botAI->GetMaster();
@ -320,7 +318,7 @@ bool ChooseRpgTargetAction::isFollowValid(Player* bot, WorldPosition pos)
inDungeon = true;
if (realMaster && realMaster->IsInWorld() && realMaster->GetMap()->IsDungeon() &&
(realMaster->GetMapId() != pos.getMapId()))
(realMaster->GetMapId() != pos.GetMapId()))
return false;
}
@ -334,7 +332,7 @@ bool ChooseRpgTargetAction::isFollowValid(Player* bot, WorldPosition pos)
return false;
Formation* formation = AI_VALUE(Formation*, "formation");
float distance = groupLeader->GetDistance2d(pos.getX(), pos.getY());
float distance = groupLeader->GetDistance2d(pos.GetPositionX(), pos.GetPositionY());
if (!botAI->HasActivePlayerMaster() && distance < 50.0f)
{

View File

@ -30,38 +30,7 @@ bool AttackEnemyFlagCarrierAction::isUseful()
PlayerHasFlag::IsCapturingFlag(bot);
}
bool AttackAnythingAction::isUseful()
{
if (!bot || !botAI) // Prevents invalid accesses
return false;
if (!botAI->AllowActivity(GRIND_ACTIVITY)) // Bot cannot be active
return false;
if (botAI->HasStrategy("stay", BOT_STATE_NON_COMBAT))
return false;
if (bot->IsInCombat())
return false;
Unit* target = GetTarget();
if (!target || !target->IsInWorld()) // Checks if the target is valid and in the world
return false;
std::string const name = std::string(target->GetName());
if (!name.empty() &&
(name.find("Dummy") != std::string::npos ||
name.find("Charge Target") != std::string::npos ||
name.find("Melee Target") != std::string::npos ||
name.find("Ranged Target") != std::string::npos))
{
return false;
}
return true;
}
bool DropTargetAction::Execute(Event event)
bool DropTargetAction::Execute(Event /*event*/)
{
Unit* target = context->GetValue<Unit*>("current target")->Get();
if (target && target->isDead())
@ -127,7 +96,38 @@ bool AttackAnythingAction::Execute(Event event)
return result;
}
bool AttackAnythingAction::isPossible() { return AttackAction::isPossible() && GetTarget(); }
bool AttackAnythingAction::isUseful()
{
if (!bot || !botAI) // Prevents invalid accesses
return false;
if (!botAI->AllowActivity(GRIND_ACTIVITY)) // Bot cannot be active
return false;
if (botAI->HasStrategy("stay", BOT_STATE_NON_COMBAT))
return false;
if (bot->IsInCombat())
return false;
Unit* target = GetTarget();
if (!target || !target->IsInWorld()) // Checks if the target is valid and in the world
return false;
std::string const name = std::string(target->GetName());
if (!name.empty() &&
(name.find("Dummy") != std::string::npos ||
name.find("Charge Target") != std::string::npos ||
name.find("Melee Target") != std::string::npos ||
name.find("Ranged Target") != std::string::npos))
{
return false;
}
return true;
}
bool AttackAnythingAction::isPossible() { return GetTarget() && AttackAction::isPossible(); }
bool DpsAssistAction::isUseful()
{
@ -137,7 +137,7 @@ bool DpsAssistAction::isUseful()
return true;
}
bool AttackRtiTargetAction::Execute(Event event)
bool AttackRtiTargetAction::Execute(Event /*event*/)
{
Unit* rtiTarget = AI_VALUE(Unit*, "rti target");

View File

@ -9,7 +9,7 @@
#include "LootObjectStack.h"
#include "Playerbots.h"
bool ChooseTravelTargetAction::Execute(Event event)
bool ChooseTravelTargetAction::Execute(Event /*event*/)
{
// Player* requester = event.getOwner() ? event.getOwner() : GetMaster(); //not used, line marked for removal.

View File

@ -7,7 +7,11 @@
#include "ChooseTravelTargetAction.h"
#include "MapMgr.h"
#include "Playerbots.h"
#include "TravelMgr.h"
#include "Player.h"
#include "PlayerbotAI.h"
#include "SpellMgr.h"
#include "Spell.h"
bool DebugAction::Execute(Event event)
{
@ -28,8 +32,8 @@ bool DebugAction::Execute(Event event)
uint32 areaId = 0;
uint32 zoneId = 0;
sMapMgr->GetZoneAndAreaId(PHASEMASK_NORMAL, zoneId, areaId, pos.getMapId(), pos.getX(), pos.getY(),
pos.getZ());
sMapMgr->GetZoneAndAreaId(PHASEMASK_NORMAL, zoneId, areaId, pos.GetMapId(), pos.GetPositionX(), pos.GetPositionY(),
pos.GetPositionZ());
std::ostringstream out;
out << zoneId << "," << areaId << "," << (pos.getAreaName().empty() ? "none" : pos.getAreaName()) << ",";
@ -298,7 +302,7 @@ bool DebugAction::Execute(Event event)
for (auto p : ppath)
{
Creature* wpCreature =
bot->SummonCreature(1, p.getX(), p.getY(), p.getZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 20000.0f);
bot->SummonCreature(1, p.GetPositionX(), p.GetPositionY(), p.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 20000.0f);
// addAura(246, wpCreature);
units.push_back(wpCreature->GetGUID());
@ -325,11 +329,11 @@ bool DebugAction::Execute(Event event)
WorldPosition botPos(bot);
WorldPosition botPos1 = botPos;
botPos.setX(botPos.getX() + cos(ang) * dist);
botPos.setY(botPos.getY() + sin(ang) * dist);
botPos.setX(botPos.GetPositionX() + cos(ang) * dist);
botPos.setY(botPos.GetPositionY() + sin(ang) * dist);
botPos.setZ(botPos.getHeight() + 2);
Creature* wpCreature = bot->SummonCreature(2334, botPos.getX(), botPos.getY(), botPos.getZ(), 0,
Creature* wpCreature = bot->SummonCreature(2334, botPos.GetPositionX(), botPos.GetPositionY(), botPos.GetPositionZ(), 0,
TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
FakeSpell(spellEffect, wpCreature, wpCreature, prev->GetGUID(), {}, {}, botPos, botPos);
@ -352,11 +356,11 @@ bool DebugAction::Execute(Event event)
WorldPosition botPos(bot);
WorldPosition botPos1 = botPos;
botPos.setX(botPos.getX() + cos(ang) * dist);
botPos.setY(botPos.getY() + sin(ang) * dist);
botPos.setX(botPos.GetPositionX() + cos(ang) * dist);
botPos.setY(botPos.GetPositionY() + sin(ang) * dist);
botPos.setZ(botPos.getHeight() + 2);
Creature* wpCreature = bot->SummonCreature(2334, botPos.getX(), botPos.getY(), botPos.getZ(), 0,
Creature* wpCreature = bot->SummonCreature(2334, botPos.GetPositionX(), botPos.GetPositionY(), botPos.GetPositionZ(), 0,
TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
if (wpCreature)
@ -383,11 +387,11 @@ bool DebugAction::Execute(Event event)
WorldPosition botPos(bot);
WorldPosition botPos1 = botPos;
botPos.setX(botPos.getX() + cos(ang) * dist);
botPos.setY(botPos.getY() + sin(ang) * dist);
botPos.setX(botPos.GetPositionX() + cos(ang) * dist);
botPos.setY(botPos.GetPositionY() + sin(ang) * dist);
botPos.setZ(botPos.getHeight() + 2);
Creature* wpCreature = bot->SummonCreature(2334, botPos.getX(), botPos.getY(), botPos.getZ(), 0,
Creature* wpCreature = bot->SummonCreature(2334, botPos.GetPositionX(), botPos.GetPositionY(), botPos.GetPositionZ(), 0,
TEMPSUMMON_TIMED_DESPAWN, 5000.0f + i * 100.0f);
wpCreature->SetObjectScale(0.5f);
@ -411,11 +415,11 @@ bool DebugAction::Execute(Event event)
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + cos(ang) * dist);
botPos.setY(botPos.getY() + sin(ang) * dist);
botPos.setX(botPos.GetPositionX() + cos(ang) * dist);
botPos.setY(botPos.GetPositionY() + sin(ang) * dist);
botPos.setZ(botPos.getHeight() + 2);
Creature* wpCreature = bot->SummonCreature(2334, botPos.getX(), botPos.getY(), botPos.getZ(), 0,
Creature* wpCreature = bot->SummonCreature(2334, botPos.GetPositionX(), botPos.GetPositionY(), botPos.GetPositionZ(), 0,
TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
units.push_back(wpCreature->GetGUID());
@ -480,13 +484,13 @@ bool DebugAction::Execute(Event event)
uint32 effect = dx + dy * 10 + spellEffect * 100;
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + (dx - 5) * 5);
botPos.setY(botPos.getY() + (dy - 5) * 5);
botPos.setX(botPos.GetPositionX() + (dx - 5) * 5);
botPos.setY(botPos.GetPositionY() + (dy - 5) * 5);
botPos.setZ(botPos.getHeight());
Creature* wpCreature =
bot->SummonCreature((dy == 0 && (dx == 0 || dx == 2)) ? 6 : 2, botPos.getX(), botPos.getY(),
botPos.getZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
bot->SummonCreature((dy == 0 && (dx == 0 || dx == 2)) ? 6 : 2, botPos.GetPositionX(), botPos.GetPositionY(),
botPos.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
if (wpCreature)
{
@ -512,11 +516,11 @@ bool DebugAction::Execute(Event event)
uint32 effect = dx + dy * 10 + spellEffect * 100;
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + (dx - 5) * 5);
botPos.setY(botPos.getY() + (dy - 5) * 5);
botPos.setX(botPos.GetPositionX() + (dx - 5) * 5);
botPos.setY(botPos.GetPositionY() + (dy - 5) * 5);
botPos.setZ(botPos.getHeight());
Creature* wpCreature = bot->SummonCreature(effect, botPos.getX(), botPos.getY(), botPos.getZ(), 0,
Creature* wpCreature = bot->SummonCreature(effect, botPos.GetPositionX(), botPos.GetPositionY(), botPos.GetPositionZ(), 0,
TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
}
}
@ -532,8 +536,8 @@ bool DebugAction::Execute(Event event)
uint32 effect = dx + dy * 10 + spellEffect * 100;
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + (dx - 5) * 5);
botPos.setY(botPos.getY() + (dy - 5) * 5);
botPos.setX(botPos.GetPositionX() + (dx - 5) * 5);
botPos.setY(botPos.GetPositionY() + (dy - 5) * 5);
botPos.setZ(botPos.getHeight());
FakeSpell(effect, bot, nullptr, ObjectGuid::Empty, {}, {}, botPos, botPos, true);
@ -552,11 +556,11 @@ bool DebugAction::Execute(Event event)
uint32 effect = dx + dy * 10 + spellEffect * 100;
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + (dx - 5) * 5);
botPos.setY(botPos.getY() + (dy - 5) * 5);
botPos.setX(botPos.GetPositionX() + (dx - 5) * 5);
botPos.setY(botPos.GetPositionY() + (dy - 5) * 5);
botPos.setZ(botPos.getHeight());
Creature* wpCreature = bot->SummonCreature(2334, botPos.getX(), botPos.getY(), botPos.getZ(), 0,
Creature* wpCreature = bot->SummonCreature(2334, botPos.GetPositionX(), botPos.GetPositionY(), botPos.GetPositionZ(), 0,
TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
if (wpCreature)
@ -568,7 +572,7 @@ bool DebugAction::Execute(Event event)
// wpCreature->SendMessageToSet(&data, true);
datMap.push_back(data);
// wpCreature->MonsterMoveWithSpeed(botPos.getX(), botPos.getY() + 80, botPos.getZ(), 8.0f, true,
// wpCreature->MonsterMoveWithSpeed(botPos.GetPositionX(), botPos.GetPositionY() + 80, botPos.GetPositionZ(), 8.0f, true,
// true);
}
}
@ -600,13 +604,13 @@ bool DebugAction::Execute(Event event)
uint32 effect = dx + dy * 10 + spellEffect * 100;
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + (dx - 5) * 5);
botPos.setY(botPos.getY() + (dy - 5) * 5);
botPos.setX(botPos.GetPositionX() + (dx - 5) * 5);
botPos.setY(botPos.GetPositionY() + (dy - 5) * 5);
botPos.setZ(botPos.getHeight());
Creature* wpCreature =
bot->SummonCreature((dy == 0 && (dx == 0 || dx == 2)) ? 6 : 2, botPos.getX(), botPos.getY(),
botPos.getZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
bot->SummonCreature((dy == 0 && (dx == 0 || dx == 2)) ? 6 : 2, botPos.GetPositionX(), botPos.GetPositionY(),
botPos.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
if (wpCreature)
{
@ -646,12 +650,12 @@ bool DebugAction::Execute(Event event)
uint32 effect = dx + dy * 10 + spellEffect * 100;
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + (dx - 5) * 5);
botPos.setY(botPos.getY() + (dy - 5) * 5);
botPos.setX(botPos.GetPositionX() + (dx - 5) * 5);
botPos.setY(botPos.GetPositionY() + (dy - 5) * 5);
botPos.setZ(botPos.getHeight());
wpCreature = bot->SummonCreature((dy == 0 && (dx == 0 || dx == 2)) ? 6 : 2, botPos.getX(),
botPos.getY(), botPos.getZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
wpCreature = bot->SummonCreature((dy == 0 && (dx == 0 || dx == 2)) ? 6 : 2, botPos.GetPositionX(),
botPos.GetPositionY(), botPos.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
if (wpCreature && lCreature)
{
@ -675,11 +679,11 @@ bool DebugAction::Execute(Event event)
uint32 effect = dx + dy * 10 + spellEffect * 100;
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + (dx - 5) * 5);
botPos.setY(botPos.getY() + (dy - 5) * 5);
botPos.setX(botPos.GetPositionX() + (dx - 5) * 5);
botPos.setY(botPos.GetPositionY() + (dy - 5) * 5);
botPos.setZ(botPos.getHeight());
wpCreature = bot->SummonCreature(2334, botPos.getX(), botPos.getY(), botPos.getZ(), 0,
wpCreature = bot->SummonCreature(2334, botPos.GetPositionX(), botPos.GetPositionY(), botPos.GetPositionZ(), 0,
TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
if (wpCreature)
@ -708,11 +712,11 @@ bool DebugAction::Execute(Event event)
{
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + (dx - 5) * 5);
botPos.setY(botPos.getY() + (dy - 5) * 5);
botPos.setX(botPos.GetPositionX() + (dx - 5) * 5);
botPos.setY(botPos.GetPositionY() + (dy - 5) * 5);
botPos.setZ(botPos.getHeight());
Creature* wpCreature = bot->SummonCreature(2334, botPos.getX(), botPos.getY(), botPos.getZ(), 0,
Creature* wpCreature = bot->SummonCreature(2334, botPos.GetPositionX(), botPos.GetPositionY(), botPos.GetPositionZ(), 0,
TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
all_targets.push_back(wpCreature->GetGUID());
@ -788,11 +792,11 @@ bool DebugAction::Execute(Event event)
{
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + (dx - 5) * 5);
botPos.setY(botPos.getY() + (dy - 5) * 5);
botPos.setX(botPos.GetPositionX() + (dx - 5) * 5);
botPos.setY(botPos.GetPositionY() + (dy - 5) * 5);
botPos.setZ(botPos.getHeight());
Creature* wpCreature = bot->SummonCreature(2334, botPos.getX(), botPos.getY(), botPos.getZ(), 0,
Creature* wpCreature = bot->SummonCreature(2334, botPos.GetPositionX(), botPos.GetPositionY(), botPos.GetPositionZ(), 0,
TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
all_targets.push_back(wpCreature->GetGUID());
@ -868,13 +872,13 @@ bool DebugAction::Execute(Event event)
uint32 effect = dx + dy * 10 + soundEffects * 100;
WorldPosition botPos(bot);
botPos.setX(botPos.getX() + (dx - 5) * 5);
botPos.setY(botPos.getY() + (dy - 5) * 5);
botPos.setX(botPos.GetPositionX() + (dx - 5) * 5);
botPos.setY(botPos.GetPositionY() + (dy - 5) * 5);
botPos.setZ(botPos.getHeight());
Creature* wpCreature =
bot->SummonCreature((dy == 0 && (dx == 0 || dx == 2)) ? 6 : 2, botPos.getX(), botPos.getY(),
botPos.getZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
bot->SummonCreature((dy == 0 && (dx == 0 || dx == 2)) ? 6 : 2, botPos.GetPositionX(), botPos.GetPositionY(),
botPos.GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000.0f);
wpCreature->PlayDistanceSound(effect);
}
@ -964,7 +968,7 @@ void DebugAction::FakeSpell(uint32 spellId, Unit* truecaster, Unit* caster, Obje
m_targets.SetDst(dest);
if ((spellInfo && spellInfo->Targets & TARGET_FLAG_SOURCE_LOCATION) || forceDest)
m_targets.SetSrc(source.getX(), source.getY(), source.getZ());
m_targets.SetSrc(source.GetPositionX(), source.GetPositionY(), source.GetPositionZ());
if (!forceDest && target)
if (!spellInfo ||

View File

@ -6,15 +6,19 @@
#include "DelayAction.h"
#include "Event.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
#include "PlayerbotAIConfig.h"
bool DelayAction::Execute(Event event)
bool DelayAction::Execute(Event /*event*/)
{
uint32 delay = sPlayerbotAIConfig.passiveDelay + sPlayerbotAIConfig.globalCoolDown;
const uint32 delay = PlayerbotAIConfig::instance().passiveDelay + PlayerbotAIConfig::instance().globalCoolDown;
botAI->SetNextCheckDelay(delay);
return true;
}
bool DelayAction::isUseful() { return !botAI->AllowActivity(ALL_ACTIVITY); }
bool DelayAction::isUseful()
{
return !botAI->AllowActivity(ALL_ACTIVITY);
}

View File

@ -39,7 +39,7 @@ void DestroyItemAction::DestroyItem(FindItemVisitor* visitor)
bool SmartDestroyItemAction::isUseful() { return !botAI->HasActivePlayerMaster(); }
bool SmartDestroyItemAction::Execute(Event event)
bool SmartDestroyItemAction::Execute(Event /*event*/)
{
uint8 bagSpace = AI_VALUE(uint8, "bag space");

View File

@ -6,7 +6,6 @@
#include "EmoteAction.h"
#include "Event.h"
#include "PlayerbotTextMgr.h"
#include "Playerbots.h"
#include "ServerFacade.h"
@ -787,7 +786,7 @@ bool EmoteAction::isUseful()
return time(nullptr) >= lastEmote;
}
bool TalkAction::Execute(Event event)
bool TalkAction::Execute(Event /*event*/)
{
Unit* target = botAI->GetUnit(AI_VALUE(ObjectGuid, "talk target"));
if (!target)

View File

@ -364,12 +364,12 @@ ItemIds EquipAction::SelectInventoryItemsToEquip()
return items;
}
bool EquipUpgradesTriggeredAction::Execute(Event event)
bool EquipUpgradesPacketAction::Execute(Event event)
{
if (!sPlayerbotAIConfig.autoEquipUpgradeLoot && !sRandomPlayerbotMgr.IsRandomBot(bot))
return false;
if (event.GetSource() == "trade status")
std::string const source = event.GetSource();
if (source == "trade status")
{
WorldPacket p(event.getPacket());
p.rpos(0);
@ -380,7 +380,7 @@ bool EquipUpgradesTriggeredAction::Execute(Event event)
return false;
}
if (event.GetSource() == "item push result")
else if (source == "item push result")
{
WorldPacket p(event.getPacket());
p.rpos(0);
@ -406,7 +406,7 @@ bool EquipUpgradesTriggeredAction::Execute(Event event)
return true;
}
bool EquipUpgradeAction::Execute(Event event)
bool EquipUpgradeAction::Execute(Event /*event*/)
{
ItemIds items = SelectInventoryItemsToEquip();
EquipItems(items);

View File

@ -29,10 +29,10 @@ private:
void EquipItem(Item* item);
};
class EquipUpgradesTriggeredAction : public EquipAction
class EquipUpgradesPacketAction : public EquipAction
{
public:
explicit EquipUpgradesTriggeredAction(PlayerbotAI* botAI, std::string const name = "equip upgrades") : EquipAction(botAI, name) {}
explicit EquipUpgradesPacketAction(PlayerbotAI* botAI, std::string const name = "equip upgrades packet action") : EquipAction(botAI, name) {}
bool Execute(Event event) override;
};

View File

@ -246,7 +246,7 @@ WorldPosition FindFishingHole(PlayerbotAI* botAI)
return WorldPosition();
}
bool MoveNearWaterAction::Execute(Event event)
bool MoveNearWaterAction::Execute(Event /*event*/)
{
WorldPosition landSpot = AI_VALUE(WorldPosition, "fishing spot");
if (landSpot.IsValid())
@ -336,7 +336,7 @@ bool MoveNearWaterAction::isPossible()
return false;
}
bool EquipFishingPoleAction::Execute(Event event)
bool EquipFishingPoleAction::Execute(Event /*event*/)
{
if (!_pole)
return false;
@ -463,7 +463,7 @@ bool UseBobberAction::isUseful()
return AI_VALUE(bool, "can use fishing bobber");
}
bool UseBobberAction::Execute(Event event)
bool UseBobberAction::Execute(Event /*event*/)
{
GuidVector gos = AI_VALUE(GuidVector, "nearest game objects no los");
for (auto const& guid : gos)
@ -485,7 +485,7 @@ bool UseBobberAction::Execute(Event event)
return false;
}
bool EndMasterFishingAction::Execute(Event event)
bool EndMasterFishingAction::Execute(Event /*event*/)
{
botAI->ChangeStrategy("-master fishing", BOT_STATE_NON_COMBAT);
return true;
@ -503,7 +503,7 @@ bool EndMasterFishingAction::isUseful()
return !nearWater.IsValid();
}
bool RemoveBobberStrategyAction::Execute(Event event)
bool RemoveBobberStrategyAction::Execute(Event /*event*/)
{
botAI->ChangeStrategy("-use bobber", BOT_STATE_NON_COMBAT);
return true;

View File

@ -7,22 +7,24 @@
#define _PLAYERBOT_FISHINGACTION_H
#include "Action.h"
#include "MovementActions.h"
#include "Event.h"
#include "MovementActions.h"
#include "Playerbots.h"
extern const uint32 FISHING_SPELL;
extern const uint32 FISHING_POLE;
extern const uint32 FISHING_BOBBER;
WorldPosition FindWaterRadial(Player* bot, float x, float y, float z, Map* map, uint32 phaseMask, float minDistance, float maxDistance, float increment, bool checkLOS=false, int numDirections = 16);
WorldPosition FindWaterRadial(Player* bot, float x, float y, float z, Map* map, uint32 phaseMask, float minDistance,
float maxDistance, float increment, bool checkLOS = false, int numDirections = 16);
class PlayerbotAI;
class FishingAction : public Action
{
public:
FishingAction(PlayerbotAI* botAI) : Action(botAI, "go fishing"){}
FishingAction(PlayerbotAI* botAI) : Action(botAI, "go fishing") {}
bool Execute(Event event) override;
bool isUseful() override;
};
@ -31,8 +33,10 @@ class EquipFishingPoleAction : public Action
{
public:
EquipFishingPoleAction(PlayerbotAI* botAI) : Action(botAI, "equip fishing pole") {}
bool Execute(Event event) override;
bool isUseful() override;
private:
Item* _pole = nullptr;
};
@ -40,7 +44,8 @@ private:
class MoveNearWaterAction : public MovementAction
{
public:
MoveNearWaterAction(PlayerbotAI* botAI): MovementAction(botAI, "move near water") {}
MoveNearWaterAction(PlayerbotAI* botAI) : MovementAction(botAI, "move near water") {}
bool Execute(Event event) override;
bool isUseful() override;
bool isPossible() override;
@ -50,6 +55,7 @@ class UseBobberAction : public Action
{
public:
UseBobberAction(PlayerbotAI* botAI) : Action(botAI, "use fishing bobber") {}
bool Execute(Event event) override;
bool isUseful() override;
};
@ -58,6 +64,7 @@ class EndMasterFishingAction : public Action
{
public:
EndMasterFishingAction(PlayerbotAI* botAI) : Action(botAI, "end master fishing") {}
bool Execute(Event event) override;
bool isUseful() override;
};
@ -66,6 +73,8 @@ class RemoveBobberStrategyAction : public Action
{
public:
RemoveBobberStrategyAction(PlayerbotAI* botAI) : Action(botAI, "remove bobber strategy") {}
bool Execute(Event event) override;
};
#endif

View File

@ -5,17 +5,14 @@
#include "FollowActions.h"
#include <cstddef>
#include "Event.h"
#include "Formations.h"
#include "LastMovementValue.h"
#include "PlayerbotAI.h"
#include "Playerbots.h"
#include "ServerFacade.h"
#include "SharedDefines.h"
bool FollowAction::Execute(Event event)
bool FollowAction::Execute(Event /*event*/)
{
Formation* formation = AI_VALUE(Formation*, "formation");
std::string const target = formation->GetTargetName();
@ -116,7 +113,7 @@ bool FollowAction::CanDeadFollow(Unit* target)
return true;
}
bool FleeToGroupLeaderAction::Execute(Event event)
bool FleeToGroupLeaderAction::Execute(Event /*event*/)
{
Unit* fTarget = AI_VALUE(Unit*, "group leader");
bool canFollow = Follow(fTarget);

View File

@ -11,8 +11,6 @@
#include "CreatureAI.h"
#include "Playerbots.h"
#include "CharmInfo.h"
#include "SharedDefines.h"
#include "ObjectGuid.h"
#include "SpellMgr.h"
#include "SpellInfo.h"
#include <vector>
@ -54,7 +52,7 @@ bool MeleeAction::isUseful()
return true;
}
bool TogglePetSpellAutoCastAction::Execute(Event event)
bool TogglePetSpellAutoCastAction::Execute(Event /*event*/)
{
Pet* pet = bot->GetPet();
if (!pet)
@ -119,7 +117,7 @@ bool TogglePetSpellAutoCastAction::Execute(Event event)
return toggled;
}
bool PetAttackAction::Execute(Event event)
bool PetAttackAction::Execute(Event /*event*/)
{
Guardian* pet = bot->GetGuardianPet();
if (!pet)

View File

@ -17,19 +17,17 @@
#include "WorldPacket.h"
#include "Group.h"
#include "Chat.h"
#include "Language.h"
#include "GenericBuffUtils.h"
#include "PlayerbotAI.h"
using ai::buff::MakeAuraQualifierForBuff;
using ai::buff::UpgradeToGroupIfAppropriate;
CastSpellAction::CastSpellAction(PlayerbotAI* botAI, std::string const spell)
: Action(botAI, spell), range(botAI->GetRange("spell")), spell(spell)
{
}
bool CastSpellAction::Execute(Event event)
bool CastSpellAction::Execute(Event /*event*/)
{
if (spell == "conjure food" || spell == "conjure water")
{
@ -78,6 +76,35 @@ bool CastSpellAction::Execute(Event event)
return botAI->CastSpell(spell, GetTarget());
}
bool CastSpellAction::isUseful()
{
if (botAI->IsInVehicle() && !botAI->IsInVehicle(false, false, true))
return false;
if (spell == "mount" && !bot->IsMounted() && !bot->IsInCombat())
return true;
if (spell == "mount" && bot->IsInCombat())
{
bot->Dismount();
return false;
}
Unit* spellTarget = GetTarget();
if (!spellTarget)
return false;
if (!spellTarget->IsInWorld() || spellTarget->GetMapId() != bot->GetMapId())
return false;
// float combatReach = bot->GetCombatReach() + target->GetCombatReach();
// if (!botAI->IsRanged(bot))
// combatReach += 4.0f / 3.0f;
return AI_VALUE2(bool, "spell cast useful", spell);
// && ServerFacade::instance().GetDistance2d(bot, target) <= (range + combatReach);
}
bool CastSpellAction::isPossible()
{
if (botAI->IsInVehicle() && !botAI->IsInVehicle(false, false, true))
@ -106,36 +133,6 @@ bool CastSpellAction::isPossible()
return botAI->CanCastSpell(spell, GetTarget());
}
bool CastSpellAction::isUseful()
{
if (botAI->IsInVehicle() && !botAI->IsInVehicle(false, false, true))
return false;
if (spell == "mount" && !bot->IsMounted() && !bot->IsInCombat())
return true;
if (spell == "mount" && bot->IsInCombat())
{
bot->Dismount();
return false;
}
Unit* spellTarget = GetTarget();
if (!spellTarget)
return false;
if (!spellTarget->IsInWorld() || spellTarget->GetMapId() != bot->GetMapId())
return false;
// float combatReach = bot->GetCombatReach() + spellTarget->GetCombatReach();
// if (!botAI->IsRanged(bot))
// combatReach += 4.0f / 3.0f;
return spellTarget &&
AI_VALUE2(bool, "spell cast useful",
spell); // && ServerFacade::instance().GetDistance2d(bot, spellTarget) <= (range + combatReach);
}
CastMeleeSpellAction::CastMeleeSpellAction(PlayerbotAI* botAI, std::string const spell) : CastSpellAction(botAI, spell)
{
range = ATTACK_DISTANCE;
@ -233,7 +230,7 @@ Value<Unit*>* BuffOnPartyAction::GetTargetValue()
return context->GetValue<Unit*>("party member without aura", MakeAuraQualifierForBuff(spell));
}
bool BuffOnPartyAction::Execute(Event event)
bool BuffOnPartyAction::Execute(Event /*event*/)
{
std::string castName = spell; // default = mono
@ -290,7 +287,7 @@ Value<Unit*>* CastSnareSpellAction::GetTargetValue() { return context->GetValue<
Value<Unit*>* CastCrowdControlSpellAction::GetTargetValue() { return context->GetValue<Unit*>("cc target", getName()); }
bool CastCrowdControlSpellAction::Execute(Event event) { return botAI->CastSpell(getName(), GetTarget()); }
bool CastCrowdControlSpellAction::Execute(Event /*event*/) { return botAI->CastSpell(getName(), GetTarget()); }
bool CastCrowdControlSpellAction::isPossible() { return botAI->CanCastSpell(getName(), GetTarget()); }
@ -308,13 +305,13 @@ bool CastVehicleSpellAction::isPossible()
bool CastVehicleSpellAction::isUseful() { return botAI->IsInVehicle(false, true); }
bool CastVehicleSpellAction::Execute(Event event)
bool CastVehicleSpellAction::Execute(Event /*event*/)
{
uint32 spellId = AI_VALUE2(uint32, "vehicle spell id", spell);
return botAI->CastVehicleSpell(spellId, GetTarget());
}
bool UseTrinketAction::Execute(Event event)
bool UseTrinketAction::Execute(Event /*event*/)
{
Item* trinket1 = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_TRINKET1);

View File

@ -23,8 +23,8 @@ public:
std::string const GetTargetName() override { return "current target"; };
bool Execute(Event event) override;
bool isPossible() override;
bool isUseful() override;
bool isPossible() override;
ActionThreatType getThreatType() override { return ActionThreatType::Single; }
std::vector<NextAction> getPrerequisites() override

View File

@ -11,7 +11,7 @@
std::vector<std::string> split(std::string const s, char delim);
bool GiveItemAction::Execute(Event event)
bool GiveItemAction::Execute(Event /*event*/)
{
Unit* target = GetTarget();
if (!target)

View File

@ -10,7 +10,7 @@
GreetAction::GreetAction(PlayerbotAI* botAI) : Action(botAI, "greet") {}
bool GreetAction::Execute(Event event)
bool GreetAction::Execute(Event /*event*/)
{
ObjectGuid guid = AI_VALUE(ObjectGuid, "new player nearby");
if (!guid || !guid.IsPlayer())

View File

@ -6,7 +6,8 @@
#include "GuildBankAction.h"
#include "GuildMgr.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
#include "AiObjectContext.h"
bool GuildBankAction::Execute(Event event)
{

View File

@ -12,9 +12,9 @@
#include "Playerbots.h"
#include "RandomPlayerbotFactory.h"
#include "ServerFacade.h"
#include "SharedDefines.h" // GOLD
#include "SharedDefines.h"
bool BuyPetitionAction::Execute(Event event)
bool BuyPetitionAction::Execute(Event /*event*/)
{
GuidVector vendors = botAI->GetAiObjectContext()->GetValue<GuidVector>("nearest npcs")->Get();
bool vendored = false, result = false;
@ -152,7 +152,7 @@ bool PetitionOfferAction::Execute(Event event)
bool PetitionOfferAction::isUseful() { return !bot->GetGuildId(); }
bool PetitionOfferNearbyAction::Execute(Event event)
bool PetitionOfferNearbyAction::Execute(Event /*event*/)
{
uint32 found = 0;
@ -209,7 +209,7 @@ bool PetitionOfferNearbyAction::isUseful()
AI_VALUE(uint8, "petition signs") < sWorld->getIntConfig(CONFIG_MIN_PETITION_SIGNS);
}
bool PetitionTurnInAction::Execute(Event event)
bool PetitionTurnInAction::Execute(Event /*event*/)
{
GuidVector vendors = botAI->GetAiObjectContext()->GetValue<GuidVector>("nearest npcs")->Get();
bool vendored = false, result = false;
@ -297,7 +297,7 @@ bool PetitionTurnInAction::isUseful()
!context->GetValue<TravelTarget*>("travel target")->Get()->isTraveling();
}
bool BuyTabardAction::Execute(Event event)
bool BuyTabardAction::Execute(Event /*event*/)
{
bool canBuy = botAI->DoSpecificAction("buy", Event("buy tabard", "Hitem:5976:"));
if (canBuy && AI_VALUE2(uint32, "item count", chat->FormatQItem(5976)))

View File

@ -128,7 +128,7 @@ bool GuildRemoveAction::PlayerIsValid(Player* member)
return member->GetGuildId() == bot->GetGuildId() && GetRankId(bot) < GetRankId(member);
};
bool GuildManageNearbyAction::Execute(Event event)
bool GuildManageNearbyAction::Execute(Event /*event*/)
{
uint32 found = 0;
@ -149,7 +149,6 @@ bool GuildManageNearbyAction::Execute(Event event)
// Promote or demote nearby members based on chance.
if (player->GetGuildId() && player->GetGuildId() == bot->GetGuildId())
{
Guild::Member* member = guild->GetMember(player->GetGUID());
uint32 dCount = AI_VALUE(uint32, "death count");
if (!urand(0, 30) && dCount < 2 && guild->GetRankRights(botMember->GetRankId()) & GR_RIGHT_PROMOTE)

View File

@ -7,13 +7,13 @@
#include "ChatActionContext.h"
#include "Event.h"
#include "Playerbots.h"
#include "AiObjectContext.h"
HelpAction::HelpAction(PlayerbotAI* botAI) : Action(botAI, "help") { chatContext = new ChatActionContext(); }
HelpAction::~HelpAction() { delete chatContext; }
bool HelpAction::Execute(Event event)
bool HelpAction::Execute(Event /*event*/)
{
TellChatCommands();
TellStrategies();

View File

@ -6,15 +6,16 @@
#include "HireAction.h"
#include "Event.h"
#include "Playerbots.h"
#include "RandomPlayerbotMgr.h"
#include "PlayerbotAI.h"
bool HireAction::Execute(Event event)
bool HireAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)
return false;
if (!sRandomPlayerbotMgr.IsRandomBot(bot))
if (!RandomPlayerbotMgr::instance().IsRandomBot(bot))
return false;
uint32 account = master->GetSession()->GetAccountId();
@ -39,7 +40,7 @@ bool HireAction::Execute(Event event)
return false;
}
uint32 discount = sRandomPlayerbotMgr.GetTradeDiscount(bot, master);
uint32 discount = RandomPlayerbotMgr::instance().GetTradeDiscount(bot, master);
uint32 m = 1 + (bot->GetLevel() / 10);
uint32 moneyReq = m * 5000 * bot->GetLevel();
if (discount < moneyReq)
@ -54,7 +55,7 @@ bool HireAction::Execute(Event event)
botAI->TellMaster("I will join you at your next relogin");
bot->SetMoney(moneyReq);
sRandomPlayerbotMgr.Remove(bot);
RandomPlayerbotMgr::instance().Remove(bot);
CharacterDatabase.Execute("UPDATE characters SET account = {} WHERE guid = {}", account,
bot->GetGUID().GetCounter());

View File

@ -10,7 +10,7 @@
ImbueWithPoisonAction::ImbueWithPoisonAction(PlayerbotAI* botAI) : Action(botAI, "apply poison") {}
bool ImbueWithPoisonAction::Execute(Event event)
bool ImbueWithPoisonAction::Execute(Event /*event*/)
{
if (bot->IsInCombat())
return false;
@ -103,7 +103,7 @@ bool ImbueWithPoisonAction::Execute(Event event)
// Search and apply stone to weapons
ImbueWithStoneAction::ImbueWithStoneAction(PlayerbotAI* botAI) : Action(botAI, "apply stone") {}
bool ImbueWithStoneAction::Execute(Event event)
bool ImbueWithStoneAction::Execute(Event /*event*/)
{
if (bot->IsInCombat())
return false;
@ -148,7 +148,7 @@ bool ImbueWithStoneAction::Execute(Event event)
// Search and apply oil to weapons
ImbueWithOilAction::ImbueWithOilAction(PlayerbotAI* botAI) : Action(botAI, "apply oil") {}
bool ImbueWithOilAction::Execute(Event event)
bool ImbueWithOilAction::Execute(Event /*event*/)
{
if (bot->IsInCombat())
return false;
@ -201,7 +201,7 @@ static const uint32 uPrioritizedHealingItemIds[19] = {
TryEmergencyAction::TryEmergencyAction(PlayerbotAI* botAI) : Action(botAI, "try emergency") {}
bool TryEmergencyAction::Execute(Event event)
bool TryEmergencyAction::Execute(Event /*event*/)
{
// Do not use consumable if bot can heal self
if ((botAI->IsHeal(bot)) && (bot->GetPowerPct(POWER_MANA) > 20))

View File

@ -351,9 +351,7 @@ uint32 InventoryAction::GetItemCount(FindItemVisitor* visitor, IterateItemsMask
std::vector<Item*>& items = visitor->GetResult();
for (Item* item : items)
{
count += item->GetCount();
}
return count;
}

View File

@ -8,7 +8,6 @@
#include "BroadcastHelper.h"
#include "Event.h"
#include "GuildMgr.h"
#include "Log.h"
#include "PlayerbotOperations.h"
#include "Playerbots.h"
#include "PlayerbotWorldThreadProcessor.h"
@ -44,7 +43,7 @@ bool InviteToGroupAction::Invite(Player* inviter, Player* player)
return true;
}
bool InviteNearbyToGroupAction::Execute(Event event)
bool InviteNearbyToGroupAction::Execute(Event /*event*/)
{
GuidVector nearGuids = botAI->GetAiObjectContext()->GetValue<GuidVector>("nearest friendly players")->Get();
for (auto& i : nearGuids)
@ -62,7 +61,7 @@ bool InviteNearbyToGroupAction::Execute(Event event)
if (player->GetGroup())
continue;
if (!sPlayerbotAIConfig.randomBotInvitePlayer && GET_PLAYERBOT_AI(player)->IsRealPlayer())
if (!PlayerbotAIConfig::instance().randomBotInvitePlayer && GET_PLAYERBOT_AI(player)->IsRealPlayer())
continue;
Group* group = bot->GetGroup();
@ -88,7 +87,7 @@ bool InviteNearbyToGroupAction::Execute(Event event)
if (abs(int32(player->GetLevel() - bot->GetLevel())) > 2)
continue;
if (ServerFacade::instance().GetDistance2d(bot, player) > sPlayerbotAIConfig.sightDistance)
if (ServerFacade::instance().GetDistance2d(bot, player) > PlayerbotAIConfig::instance().sightDistance)
continue;
// When inviting the 5th member of the group convert to raid for future invites.
@ -99,7 +98,7 @@ bool InviteNearbyToGroupAction::Execute(Event event)
PlayerbotWorldThreadProcessor::instance().QueueOperation(std::move(convertOp));
}
if (sPlayerbotAIConfig.inviteChat && sRandomPlayerbotMgr.IsRandomBot(bot))
if (PlayerbotAIConfig::instance().inviteChat && RandomPlayerbotMgr::instance().IsRandomBot(bot))
{
std::map<std::string, std::string> placeholders;
placeholders["%player"] = player->GetName();
@ -120,7 +119,7 @@ bool InviteNearbyToGroupAction::Execute(Event event)
bool InviteNearbyToGroupAction::isUseful()
{
if (!sPlayerbotAIConfig.randomBotGroupNearby)
if (!PlayerbotAIConfig::instance().randomBotGroupNearby)
return false;
if (bot->InBattleground())
@ -166,7 +165,7 @@ std::vector<Player*> InviteGuildToGroupAction::getGuildMembers()
return worker.GetResult();
}
bool InviteGuildToGroupAction::Execute(Event event)
bool InviteGuildToGroupAction::Execute(Event /*event*/)
{
Guild* guild = sGuildMgr->GetGuildById(bot->GetGuildId());
@ -186,7 +185,7 @@ bool InviteGuildToGroupAction::Execute(Event event)
if (player->isDND())
continue;
if (!sPlayerbotAIConfig.randomBotInvitePlayer && GET_PLAYERBOT_AI(player)->IsRealPlayer())
if (!PlayerbotAIConfig::instance().randomBotInvitePlayer && GET_PLAYERBOT_AI(player)->IsRealPlayer())
continue;
if (player->IsBeingTeleported())
@ -221,7 +220,7 @@ bool InviteGuildToGroupAction::Execute(Event event)
player->GetLevel() + 5) // Do not invite members that too low level or risk dragging them to deadly places.
continue;
if (!playerAi && ServerFacade::instance().GetDistance2d(bot, player) > sPlayerbotAIConfig.sightDistance)
if (!playerAi && ServerFacade::instance().GetDistance2d(bot, player) > PlayerbotAIConfig::instance().sightDistance)
continue;
Group* group = bot->GetGroup();
@ -233,8 +232,8 @@ bool InviteGuildToGroupAction::Execute(Event event)
PlayerbotWorldThreadProcessor::instance().QueueOperation(std::move(convertOp));
}
if (sPlayerbotAIConfig.inviteChat &&
(sRandomPlayerbotMgr.IsRandomBot(bot) || !botAI->HasActivePlayerMaster()))
if (PlayerbotAIConfig::instance().inviteChat &&
(RandomPlayerbotMgr::instance().IsRandomBot(bot) || !botAI->HasActivePlayerMaster()))
{
BroadcastHelper::BroadcastGuildGroupOrRaidInvite(botAI, bot, player, group);
}

View File

@ -92,7 +92,7 @@ bool LeaveGroupAction::Leave()
return true;
}
bool LeaveFarAwayAction::Execute(Event event)
bool LeaveFarAwayAction::Execute(Event /*event*/)
{
// allow bot to leave party when they want
return Leave();

View File

@ -8,11 +8,11 @@
#include "AiFactory.h"
#include "ItemVisitors.h"
#include "LFGMgr.h"
#include "LFGPackets.h"
#include "Opcodes.h"
#include "Playerbots.h"
#include "World.h"
#include "WorldPacket.h"
#include "RandomPlayerbotMgr.h"
using namespace lfg;
@ -20,7 +20,7 @@ bool LfgJoinAction::Execute(Event event) { return JoinLFG(); }
uint32 LfgJoinAction::GetRoles()
{
if (!sRandomPlayerbotMgr.IsRandomBot(bot))
if (!RandomPlayerbotMgr::instance().IsRandomBot(bot))
{
if (botAI->IsTank(bot))
return PLAYER_ROLE_TANK;
@ -101,7 +101,7 @@ bool LfgJoinAction::JoinLFG()
LfgDungeonSet list;
std::vector<uint32> selected;
std::vector<uint32> dungeons = sRandomPlayerbotMgr.LfgDungeons[bot->GetTeamId()];
std::vector<uint32> dungeons = RandomPlayerbotMgr::instance().LfgDungeons[bot->GetTeamId()];
if (!dungeons.size())
return false;
@ -170,7 +170,7 @@ bool LfgJoinAction::JoinLFG()
return true;
}
bool LfgRoleCheckAction::Execute(Event event)
bool LfgRoleCheckAction::Execute(Event /*event*/)
{
if (Group* group = bot->GetGroup())
{
@ -216,9 +216,9 @@ bool LfgAcceptAction::Execute(Event event)
*packet << id << true;
bot->GetSession()->QueuePacket(packet);
if (sRandomPlayerbotMgr.IsRandomBot(bot) && !bot->GetGroup())
if (RandomPlayerbotMgr::instance().IsRandomBot(bot) && !bot->GetGroup())
{
sRandomPlayerbotMgr.Refresh(bot);
RandomPlayerbotMgr::instance().Refresh(bot);
botAI->ResetStrategies();
}
@ -251,9 +251,9 @@ bool LfgAcceptAction::Execute(Event event)
*packet << id << true;
bot->GetSession()->QueuePacket(packet);
if (sRandomPlayerbotMgr.IsRandomBot(bot) && !bot->GetGroup())
if (RandomPlayerbotMgr::instance().IsRandomBot(bot) && !bot->GetGroup())
{
sRandomPlayerbotMgr.Refresh(bot);
RandomPlayerbotMgr::instance().Refresh(bot);
botAI->ResetStrategies();
}
@ -265,7 +265,7 @@ bool LfgAcceptAction::Execute(Event event)
return false;
}
bool LfgLeaveAction::Execute(Event event)
bool LfgLeaveAction::Execute(Event /*event*/)
{
// Don't leave if lfg strategy enabled
// if (botAI->HasStrategy("lfg", BOT_STATE_NON_COMBAT))
@ -337,7 +337,7 @@ bool LfgJoinAction::isUseful()
if (bot->isDead())
return false;
if (!sRandomPlayerbotMgr.IsRandomBot(bot))
if (!RandomPlayerbotMgr::instance().IsRandomBot(bot))
return false;
Map* map = bot->GetMap();

View File

@ -13,7 +13,7 @@
#include "PlayerbotAIConfig.h"
#include "Playerbots.h"
bool LootRollAction::Execute(Event event)
bool LootRollAction::Execute(Event /*event*/)
{
Group* group = bot->GetGroup();
if (!group)

View File

@ -11,20 +11,16 @@
#include "LastMovementValue.h"
#include "Playerbots.h"
bool MoveToRpgTargetAction::Execute(Event event)
bool MoveToRpgTargetAction::Execute(Event /*event*/)
{
GuidPosition guidP = AI_VALUE(GuidPosition, "rpg target");
Unit* unit = botAI->GetUnit(guidP);
if (unit && !unit->IsInWorld())
{
return false;
}
GameObject* go = botAI->GetGameObject(guidP);
if (go && !go->IsInWorld())
{
return false;
}
Player* player = guidP.GetPlayer();
WorldObject* wo = nullptr;
if (unit)

View File

@ -7,10 +7,9 @@
#include "ChooseRpgTargetAction.h"
#include "LootObjectStack.h"
#include "PathGenerator.h"
#include "Playerbots.h"
bool MoveToTravelTargetAction::Execute(Event event)
bool MoveToTravelTargetAction::Execute(Event /*event*/)
{
TravelTarget* target = AI_VALUE(TravelTarget*, "travel target");

View File

@ -15,7 +15,6 @@
#include "FleeManager.h"
#include "G3D/Vector3.h"
#include "GameObject.h"
#include "Geometry.h"
#include "LastMovementValue.h"
#include "LootObjectStack.h"
#include "Map.h"
@ -36,9 +35,7 @@
#include "SpellAuraEffects.h"
#include "SpellInfo.h"
#include "Stances.h"
#include "TargetedMovementGenerator.h"
#include "Timer.h"
#include "Transport.h"
#include "Unit.h"
#include "Vehicle.h"
#include "WaypointMovementGenerator.h"
@ -67,18 +64,14 @@ bool MovementAction::JumpTo(uint32 mapId, float x, float y, float z, MovementPri
{
UpdateMovementState();
if (!IsMovingAllowed(mapId, x, y, z))
{
return false;
}
if (IsDuplicateMove(mapId, x, y, z))
{
return false;
}
if (IsWaitingForLastMove(priority))
{
return false;
}
float botZ = bot->GetPositionZ();
float speed = bot->GetSpeed(MOVE_RUN);
MotionMaster& mm = *bot->GetMotionMaster();
mm.Clear();
@ -370,7 +363,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// {
// movePosition = endPosition;
// if (startPosition.getMapId() != endPosition.getMapId() || totalDistance > maxDist)
// if (startPosition.GetMapId() != endPosition.GetMapId() || totalDistance > maxDist)
// {
// if (!TravelNodeMap::instance().getNodes().empty() && !bot->InBattleground())
// {
@ -421,7 +414,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// {
// //Use standard PathGenerator to find a route.
// PathGenerator path(mover);
// path.CalculatePath(movePosition.getX(), movePosition.getY(), movePosition.getZ(), false);
// path.CalculatePath(movePosition.GetPositionX(), movePosition.GetPositionY(), movePosition.GetPositionZ(), false);
// PathType type = path.GetPathType();
// Movement::PointsArray const& points = path.GetPath();
// movePath.addPath(startPosition.fromPointsArray(points));
@ -485,8 +478,8 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// else
// {
// LOG_DEBUG("playerbots", "!entry");
// return bot->TeleportTo(movePosition.getMapId(), movePosition.getX(), movePosition.getY(),
// movePosition.getZ(), movePosition.getO(), 0);
// return bot->TeleportTo(movePosition.GetMapId(), movePosition.GetPositionX(), movePosition.GetPositionY(),
// movePosition.GetPositionZ(), movePosition.GetOrientation(), 0);
// }
// }
@ -563,14 +556,14 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// AI_VALUE(LastMovement&, "last movement").setPath(movePath);
// if (!movePosition || movePosition.getMapId() != bot->GetMapId())
// if (!movePosition || movePosition.GetMapId() != bot->GetMapId())
// {
// movePath.clear();
// AI_VALUE(LastMovement&, "last movement").setPath(movePath);
// if (botAI->HasStrategy("debug move", BOT_STATE_NON_COMBAT))
// botAI->TellMasterNoFacing("No point. Rebuilding.");
// LOG_DEBUG("playerbots", "!movePosition || movePosition.getMapId() != bot->GetMapId()");
// LOG_DEBUG("playerbots", "!movePosition || movePosition.GetMapId() != bot->GetMapId()");
// return false;
// }
@ -609,15 +602,15 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// float cz = z;
// for (auto i : movePath.getPath())
// {
// CreateWp(bot, i.point.getX(), i.point.getY(), i.point.getZ(), 0.f, 2334);
// CreateWp(bot, i.point.GetPositionX(), i.point.GetPositionY(), i.point.GetPositionZ(), 0.f, 2334);
// cx = i.point.getX();
// cy = i.point.getY();
// cz = i.point.getZ();
// cx = i.point.GetPositionX();
// cy = i.point.GetPositionY();
// cz = i.point.GetPositionZ();
// }
// }
// else
// CreateWp(bot, movePosition.getX(), movePosition.getY(), movePosition.getZ(), 0, 2334, true);
// CreateWp(bot, movePosition.GetPositionX(), movePosition.GetPositionY(), movePosition.GetPositionZ(), 0, 2334, true);
// }
// //Log bot movement
@ -634,8 +627,8 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// sPlayerbotAIConfig.log("bot_movement.csv", out.str().c_str());
// }
// // LOG_DEBUG("playerbots", "({}, {}) -> ({}, {})", startPosition.getX(), startPosition.getY(),
// movePosition.getX(), movePosition.getY()); if (!react)
// // LOG_DEBUG("playerbots", "({}, {}) -> ({}, {})", startPosition.GetPositionX(), startPosition.GetPositionY(),
// movePosition.GetPositionX(), movePosition.GetPositionY()); if (!react)
// if (totalDistance > maxDist)
// WaitForReach(startPosition.distance(movePosition) - 10.0f);
// else
@ -671,7 +664,7 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// // else
// // {
// // mover->GetMotionMaster()->GetDestination(x, y, z);
// // if (movePosition.distance(WorldPosition(movePosition.getMapId(), x, y, z, 0)) > minDist)
// // if (movePosition.distance(WorldPosition(movePosition.GetMapId(), x, y, z, 0)) > minDist)
// // {
// // mover->StopMoving();
// // mover->GetMotionMaster()->Clear();
@ -685,8 +678,8 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// AI_VALUE(LastMovement&, "last movement").nextTeleport = now +
// (time_t)MoveDelay(startPosition.distance(movePosition)); LOG_DEBUG("playerbots", "totalDistance > maxDist &&
// !detailedMove && !botAI->HasPlayerNearby(&movePosition)"); return bot->TeleportTo(movePosition.getMapId(),
// movePosition.getX(), movePosition.getY(), movePosition.getZ(), startPosition.getAngleTo(movePosition));
// !detailedMove && !botAI->HasPlayerNearby(&movePosition)"); return bot->TeleportTo(movePosition.GetMapId(),
// movePosition.GetPositionX(), movePosition.GetPositionY(), movePosition.GetPositionZ(), startPosition.getAngleTo(movePosition));
// }
// // walk if master walks and is close
@ -708,9 +701,9 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// if (!bot->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !bot->HasAuraType(SPELL_AURA_FLY))
// {
// bot->SetWalk(masterWalking);
// bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), movePosition.getX(), movePosition.getY(),
// movePosition.getZ(), generatePath); WaitForReach(startPosition.distance(movePosition));
// // LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY());
// bot->GetMotionMaster()->MovePoint(movePosition.GetMapId(), movePosition.GetPositionX(), movePosition.GetPositionY(),
// movePosition.GetPositionZ(), generatePath); WaitForReach(startPosition.distance(movePosition));
// // LOG_DEBUG("playerbots", "Movepoint to ({}, {})", movePosition.GetPositionX(), movePosition.GetPositionY());
// }
// else
// {
@ -756,9 +749,9 @@ bool MovementAction::MoveTo(uint32 mapId, float x, float y, float z, bool idle,
// }
// }
// bot->GetMotionMaster()->MovePoint(movePosition.getMapId(), Position(movePosition.getX(), movePosition.getY(),
// movePosition.getZ(), 0.f)); WaitForReach(startPosition.distance(movePosition)); LOG_DEBUG("playerbots",
// "Movepoint to ({}, {})", movePosition.getX(), movePosition.getY());
// bot->GetMotionMaster()->MovePoint(movePosition.GetMapId(), Position(movePosition.GetPositionX(), movePosition.GetPositionY(),
// movePosition.GetPositionZ(), 0.f)); WaitForReach(startPosition.distance(movePosition)); LOG_DEBUG("playerbots",
// "Movepoint to ({}, {})", movePosition.GetPositionX(), movePosition.GetPositionY());
// }
// AI_VALUE(LastMovement&, "last movement").setShort(movePosition);
@ -953,68 +946,70 @@ bool MovementAction::Follow(Unit* target, float distance) { return Follow(target
void MovementAction::UpdateMovementState()
{
const bool isCurrentlyRestricted = // see if the bot is currently slowed, rooted, or otherwise unable to move
bot->HasUnitState(UNIT_STATE_LOST_CONTROL) ||
bot->IsRooted() ||
bot->isFrozen() ||
bot->IsPolymorphed();
const bool isCurrentlyRestricted = // see if the bot is currently slowed, rooted, or otherwise unable to move
bot->HasUnitState(UNIT_STATE_LOST_CONTROL) || bot->IsRooted() || bot->isFrozen() || bot->IsPolymorphed();
// no update movement flags while movement is current restricted.
if (!isCurrentlyRestricted && bot->IsAlive())
{
// state flags
const auto master = botAI ? botAI->GetMaster() : nullptr; // real player or not
const bool masterIsFlying = master ? master->HasUnitMovementFlag(MOVEMENTFLAG_FLYING) : true;
const bool masterIsSwimming = master ? master->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) : true;
const auto liquidState = bot->GetLiquidData().Status; // default LIQUID_MAP_NO_WATER
const auto master = botAI ? botAI->GetMaster() : nullptr;
const auto liquidState = bot->GetLiquidData().Status;
const float gZ = bot->GetMapWaterOrGroundLevel(bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ());
const bool wantsToFly = bot->HasIncreaseMountedFlightSpeedAura() || bot->HasFlyAura();
const bool onGroundZ = bot->GetPositionZ() < gZ + 1.f;
const bool canSwim = liquidState == LIQUID_MAP_IN_WATER || liquidState == LIQUID_MAP_UNDER_WATER;
const bool canFly = bot->HasIncreaseMountedFlightSpeedAura() || bot->HasFlyAura();
const bool canWaterWalk = bot->HasWaterWalkAura();
const bool isMasterFlying = master ? master->HasUnitMovementFlag(MOVEMENTFLAG_FLYING) : true;
const bool isMasterSwimming = master ? master->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING) : true;
const bool isFlying = bot->HasUnitMovementFlag(MOVEMENTFLAG_FLYING);
const bool isWaterArea = liquidState != LIQUID_MAP_NO_WATER;
const bool isUnderWater = liquidState == LIQUID_MAP_UNDER_WATER;
const bool isInWater = liquidState == LIQUID_MAP_IN_WATER;
const bool isWaterWalking = bot->HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
const bool isSwimming = bot->HasUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
const bool wantsToWaterWalk = bot->HasWaterWalkAura();
const bool wantsToSwim = isInWater || isUnderWater;
const bool onGroundZ = (bot->GetPositionZ() < gZ + 1.f) && !isWaterArea;
const bool isWaterWalking = bot->HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
bool movementFlagsUpdated = false;
// handle water state
if (isWaterArea && !isFlying)
// handle water (fragile logic do not alter without testing every detail, animation and transition)
if (liquidState != LIQUID_MAP_NO_WATER && !isFlying)
{
// water walking
if (wantsToWaterWalk && !isWaterWalking && !masterIsSwimming)
if (canWaterWalk && !isMasterSwimming && !isWaterWalking)
{
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
bot->SetSwim(false);
bot->AddUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
movementFlagsUpdated = true;
}
// swimming
else if (wantsToSwim && !isSwimming && masterIsSwimming)
else if ((!canWaterWalk || isMasterSwimming) && isWaterWalking)
{
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
bot->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
if (canSwim)
bot->SetSwim(true);
movementFlagsUpdated = true;
}
else if (!canSwim && isSwimming)
{
bot->SetSwim(false);
movementFlagsUpdated = true;
}
}
else if (isSwimming || isWaterWalking)
// reset when not around water while swimming or water walking
if (liquidState == LIQUID_MAP_NO_WATER && (isSwimming || isWaterWalking))
{
// reset water flags
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
bot->SetSwim(false);
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_WATERWALKING);
movementFlagsUpdated = true;
}
// handle flying state
if (wantsToFly && !isFlying && masterIsFlying)
// handle flying
if ((canFly && !isFlying) && isMasterFlying)
{
bot->AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
bot->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
bot->AddUnitMovementFlag(MOVEMENTFLAG_FLYING);
movementFlagsUpdated = true;
// required for transition and state monitoring.
if (MotionMaster* mm = bot->GetMotionMaster())
mm->MoveTakeoff(0, {bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ() + 1.F}, 0.F, true);
}
else if ((!wantsToFly || onGroundZ) && isFlying)
else if ((!canFly && !isWaterWalking && isFlying) || (!isMasterFlying && isFlying && onGroundZ))
{
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_CAN_FLY);
bot->RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
@ -1022,15 +1017,16 @@ void MovementAction::UpdateMovementState()
movementFlagsUpdated = true;
}
// detect if movement restrictions have been lifted, CC just ended.
// detect if movement/CC restrictions have been ended, refresh movement state for animations.
if (wasMovementRestricted)
movementFlagsUpdated = true; // refresh movement state to ensure animations play correctly
movementFlagsUpdated = true;
// movement flags should only be updated between state changes, if not it will break certain effects.
if (movementFlagsUpdated)
bot->SendMovementFlagUpdate();
}
// Save current state for the next check
// Save current state for the next check
wasMovementRestricted = isCurrentlyRestricted;
// Temporary speed increase in group
@ -1190,7 +1186,7 @@ bool MovementAction::Follow(Unit* target, float distance, float angle)
WorldPosition cPos(corpse);
if (botPos.fDist(cPos) > sPlayerbotAIConfig.spellDistance)
return MoveTo(cPos.getMapId(), cPos.getX(), cPos.getY(), cPos.getZ());
return MoveTo(cPos.GetMapId(), cPos.GetPositionX(), cPos.GetPositionY(), cPos.GetPositionZ());
}
}
@ -1217,7 +1213,7 @@ bool MovementAction::Follow(Unit* target, float distance, float angle)
if ((lDist * 1.5 < tDist && ang < static_cast<float>(M_PI) / 2) ||
target->HasUnitState(UNIT_STATE_IN_FLIGHT))
{
return MoveTo(longMove.getMapId(), longMove.getX(), longMove.getY(), longMove.getZ());
return MoveTo(longMove.GetMapId(), longMove.GetPositionX(), longMove.GetPositionY(), longMove.GetPositionZ());
}
}
}
@ -1813,12 +1809,11 @@ void MovementAction::DoMovePoint(Unit* unit, float x, float y, float z, bool gen
if (!mm)
return;
// enable water walking
if (unit->HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING))
// bot water collision correction
if (unit->HasUnitMovementFlag(MOVEMENTFLAG_WATERWALKING) && unit->HasWaterWalkAura())
{
float gZ = unit->GetMapWaterOrGroundLevel(unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ());
unit->UpdatePosition(unit->GetPositionX(), unit->GetPositionY(), gZ, false);
// z = gZ; no overwrite Z axe otherwise you cant steer the bots into swimming when water walking.
}
mm->Clear();
@ -1844,7 +1839,7 @@ void MovementAction::DoMovePoint(Unit* unit, float x, float y, float z, bool gen
}
}
bool FleeAction::Execute(Event event)
bool FleeAction::Execute(Event /*event*/)
{
return MoveAway(AI_VALUE(Unit*, "current target"), sPlayerbotAIConfig.fleeDistance, true);
}
@ -1852,9 +1847,8 @@ bool FleeAction::Execute(Event event)
bool FleeAction::isUseful()
{
if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL) != nullptr)
{
return false;
}
Unit* target = AI_VALUE(Unit*, "current target");
if (target && target->IsInWorld() && !bot->IsWithinMeleeRange(target))
return false;
@ -1862,12 +1856,10 @@ bool FleeAction::isUseful()
return true;
}
bool FleeWithPetAction::Execute(Event event)
bool FleeWithPetAction::Execute(Event /*event*/)
{
if (Pet* pet = bot->GetPet())
{
botAI->PetFollow();
}
return Flee(AI_VALUE(Unit*, "current target"));
}
@ -1875,15 +1867,14 @@ bool FleeWithPetAction::Execute(Event event)
bool AvoidAoeAction::isUseful()
{
if (getMSTime() - moveInterval < lastMoveTimer)
{
return false;
}
GuidVector traps = AI_VALUE(GuidVector, "nearest trap with damage");
GuidVector triggers = AI_VALUE(GuidVector, "possible triggers");
return AI_VALUE(Aura*, "area debuff") || !traps.empty() || !triggers.empty();
}
bool AvoidAoeAction::Execute(Event event)
bool AvoidAoeAction::Execute(Event /*event*/)
{
// Case #1: Aura with dynamic object (e.g. rain of fire)
if (AvoidAuraWithDynamicObj())
@ -2307,17 +2298,15 @@ bool MovementAction::CheckLastFlee(float curAngle, std::list<FleeInfo>& infoList
bool CombatFormationMoveAction::isUseful()
{
if (getMSTime() - moveInterval < lastMoveTimer)
{
return false;
}
if (bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL) != nullptr)
{
return false;
}
return true;
}
bool CombatFormationMoveAction::Execute(Event event)
bool CombatFormationMoveAction::Execute(Event /*event*/)
{
float dis = AI_VALUE(float, "disperse distance");
if (dis <= 0.0f || (!bot->IsInCombat() && botAI->HasStrategy("stay", BotState::BOT_STATE_NON_COMBAT)) ||
@ -2448,7 +2437,7 @@ Player* CombatFormationMoveAction::NearestGroupMember(float dis)
return result;
}
bool TankFaceAction::Execute(Event event)
bool TankFaceAction::Execute(Event /*event*/)
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target)
@ -2532,7 +2521,7 @@ bool RearFlankAction::isUseful()
return inFront || inRear;
}
bool RearFlankAction::Execute(Event event)
bool RearFlankAction::Execute(Event /*event*/)
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target)
@ -2643,9 +2632,9 @@ bool DisperseSetAction::Execute(Event event)
return true;
}
bool RunAwayAction::Execute(Event event) { return Flee(AI_VALUE(Unit*, "group leader")); }
bool RunAwayAction::Execute(Event /*event*/) { return Flee(AI_VALUE(Unit*, "group leader")); }
bool MoveToLootAction::Execute(Event event)
bool MoveToLootAction::Execute(Event /*event*/)
{
LootObject loot = AI_VALUE(LootObject, "loot target");
if (!loot.IsLootPossible(bot))
@ -2654,7 +2643,7 @@ bool MoveToLootAction::Execute(Event event)
return MoveNear(loot.GetWorldObject(bot), sPlayerbotAIConfig.contactDistance);
}
bool MoveOutOfEnemyContactAction::Execute(Event event)
bool MoveOutOfEnemyContactAction::Execute(Event /*event*/)
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target)
@ -2665,7 +2654,7 @@ bool MoveOutOfEnemyContactAction::Execute(Event event)
bool MoveOutOfEnemyContactAction::isUseful() { return AI_VALUE2(bool, "inside target", "current target"); }
bool SetFacingTargetAction::Execute(Event event)
bool SetFacingTargetAction::Execute(Event /*event*/)
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target)
@ -2691,7 +2680,7 @@ bool SetFacingTargetAction::isPossible()
return true;
}
bool SetBehindTargetAction::Execute(Event event)
bool SetBehindTargetAction::Execute(Event /*event*/)
{
Unit* target = AI_VALUE(Unit*, "current target");
if (!target)
@ -2751,7 +2740,7 @@ bool SetBehindTargetAction::Execute(Event event)
false, true, MovementPriority::MOVEMENT_COMBAT);
}
bool MoveOutOfCollisionAction::Execute(Event event)
bool MoveOutOfCollisionAction::Execute(Event /*event*/)
{
float angle = M_PI * 2000 / frand(1.f, 1000.f);
float distance = sPlayerbotAIConfig.followDistance;
@ -2769,7 +2758,7 @@ bool MoveOutOfCollisionAction::isUseful()
botAI->GetAiObjectContext()->GetValue<GuidVector>("nearest friendly players")->Get().size() < 15;
}
bool MoveRandomAction::Execute(Event event)
bool MoveRandomAction::Execute(Event /*event*/)
{
float distance = sPlayerbotAIConfig.tooCloseDistance + urand(10, 30);
@ -2801,9 +2790,9 @@ bool MoveRandomAction::Execute(Event event)
bool MoveRandomAction::isUseful() { return !AI_VALUE(GuidPosition, "rpg target"); }
bool MoveInsideAction::Execute(Event event) { return MoveInside(bot->GetMapId(), x, y, bot->GetPositionZ(), distance); }
bool MoveInsideAction::Execute(Event /*event*/) { return MoveInside(bot->GetMapId(), x, y, bot->GetPositionZ(), distance); }
bool RotateAroundTheCenterPointAction::Execute(Event event)
bool RotateAroundTheCenterPointAction::Execute(Event /*event*/)
{
uint32 next_point = GetCurrWaypoint();
if (MoveTo(bot->GetMapId(), waypoints[next_point].first, waypoints[next_point].second, bot->GetPositionZ(), false,
@ -2823,10 +2812,9 @@ bool MoveFromGroupAction::Execute(Event event)
return MoveFromGroup(distance);
}
bool MoveAwayFromCreatureAction::Execute(Event event)
bool MoveAwayFromCreatureAction::Execute(Event /*event*/)
{
GuidVector targets = AI_VALUE(GuidVector, "nearest npcs");
Creature* nearestCreature = bot->FindNearestCreature(creatureId, range, alive);
// Find all creatures with the specified Id
std::vector<Unit*> creatures;
@ -2904,16 +2892,14 @@ bool MoveAwayFromCreatureAction::Execute(Event event)
bool MoveAwayFromCreatureAction::isPossible() { return bot->CanFreeMove(); }
bool MoveAwayFromPlayerWithDebuffAction::Execute(Event event)
bool MoveAwayFromPlayerWithDebuffAction::Execute(Event /*event*/)
{
Player* closestPlayer = nullptr;
float minDistance = 0.0f;
Group* group = bot->GetGroup();
if (!group)
{
return false;
}
std::vector<Player*> debuffedPlayers;

View File

@ -49,18 +49,16 @@ bool DrinkAction::Execute(Event event)
bool DrinkAction::isUseful()
{
return UseItemAction::isUseful() &&
AI_VALUE2(bool, "has mana", "self target") &&
AI_VALUE2(uint8, "mana", "self target") < 100;
return UseItemAction::isUseful() && AI_VALUE2(bool, "has mana", "self target") &&
AI_VALUE2(uint8, "mana", "self target") < 100;
}
bool DrinkAction::isPossible()
{
return !bot->IsInCombat() &&
!bot->IsMounted() &&
!botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form",
"aquatic form","flight form", "swift flight form", nullptr) &&
(botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible());
return !bot->IsInCombat() && !bot->IsMounted() &&
!botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form",
"flight form", "swift flight form", nullptr) &&
(botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible());
}
bool EatAction::Execute(Event event)
@ -102,17 +100,12 @@ bool EatAction::Execute(Event event)
return UseItemAction::Execute(event);
}
bool EatAction::isUseful()
{
return UseItemAction::isUseful() &&
AI_VALUE2(uint8, "health", "self target") < 100;
}
bool EatAction::isUseful() { return UseItemAction::isUseful() && AI_VALUE2(uint8, "health", "self target") < 100; }
bool EatAction::isPossible()
{
return !bot->IsInCombat() &&
!bot->IsMounted() &&
!botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form",
"aquatic form","flight form", "swift flight form", nullptr) &&
(botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible());
return !bot->IsInCombat() && !bot->IsMounted() &&
!botAI->HasAnyAuraOf(GetTarget(), "dire bear form", "bear form", "cat form", "travel form", "aquatic form",
"flight form", "swift flight form", nullptr) &&
(botAI->HasCheat(BotCheatMask::food) || UseItemAction::isPossible());
}

View File

@ -7,7 +7,7 @@
#include "LootObjectStack.h"
#include "AiObjectContext.h"
bool OpenItemAction::Execute(Event event)
bool OpenItemAction::Execute(Event /*event*/)
{
bool foundOpenable = false;

View File

@ -7,10 +7,9 @@
#include "Event.h"
#include "PlayerbotOperations.h"
#include "Playerbots.h"
#include "PlayerbotWorldThreadProcessor.h"
bool PassLeadershipToMasterAction::Execute(Event event)
bool PassLeadershipToMasterAction::Execute(Event /*event*/)
{
if (Player* master = GetMaster())
if (master && master != bot && bot->GetGroup() && bot->GetGroup()->IsMember(master->GetGUID()))

View File

@ -9,8 +9,6 @@
#include <string>
#include "Action.h"
#include "PlayerbotFactory.h"
#include "Unit.h"
class PlayerbotAI;

View File

@ -102,7 +102,7 @@ bool PositionAction::Execute(Event event)
return false;
}
bool MoveToPositionAction::Execute(Event event)
bool MoveToPositionAction::Execute(Event /*event*/)
{
PositionInfo pos = context->GetValue<PositionMap&>("position")->Get()[qualifier];
if (!pos.isSet())
@ -123,7 +123,7 @@ bool MoveToPositionAction::isUseful()
return pos.isSet() && distance > sPlayerbotAIConfig.followDistance && distance < sPlayerbotAIConfig.reactDistance;
}
bool SetReturnPositionAction::Execute(Event event)
bool SetReturnPositionAction::Execute(Event /*event*/)
{
PositionMap& posMap = context->GetValue<PositionMap&>("position")->Get();
PositionInfo returnPos = posMap["return"];

View File

@ -7,7 +7,7 @@
#include "ChatHelper.h"
#include "Event.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
void QueryQuestAction::TellObjective(std::string const name, uint32 available, uint32 required)
{

View File

@ -5,6 +5,7 @@
#include "QuestAction.h"
#include <sstream>
#include <algorithm>
#include "Chat.h"
#include "ChatHelper.h"
@ -116,7 +117,8 @@ bool QuestAction::CompleteQuest(Player* player, uint32 entry)
player->CastedCreatureOrGO(creature, ObjectGuid(), spell_id);
}
}*/
/*else*/ if (creature > 0)
/*else*/
if (creature > 0)
{
if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature))
for (uint16 z = 0; z < creaturecount; ++z)
@ -432,7 +434,7 @@ bool QuestItemPushResultAction::Execute(Event event)
return false;
}
bool QuestUpdateFailedAction::Execute(Event event)
bool QuestUpdateFailedAction::Execute(Event /*event*/)
{
//opcode SMSG_QUESTUPDATE_FAILED is never sent...(yet?)
return false;

View File

@ -8,7 +8,7 @@
#include "Event.h"
#include "Playerbots.h"
bool RandomBotUpdateAction::Execute(Event event)
bool RandomBotUpdateAction::Execute(Event /*event*/)
{
if (!sRandomPlayerbotMgr.IsRandomBot(bot))
return false;

View File

@ -10,7 +10,7 @@
#include "Playerbots.h"
#include "ServerFacade.h"
bool ReachTargetAction::Execute(Event event) { return ReachCombatTo(AI_VALUE(Unit*, GetTargetName()), distance); }
bool ReachTargetAction::Execute(Event /*event*/) { return ReachCombatTo(AI_VALUE(Unit*, GetTargetName()), distance); }
bool ReachTargetAction::isUseful()
{

View File

@ -78,7 +78,7 @@ void ReleaseSpiritAction::LogRelease(const std::string& releaseMsg, bool isAutoR
}
// AutoReleaseSpiritAction implementation
bool AutoReleaseSpiritAction::Execute(Event event)
bool AutoReleaseSpiritAction::Execute(Event /*event*/)
{
IncrementDeathCount();
bot->DurabilityRepairAll(false, 1.0f, false);
@ -214,7 +214,7 @@ bool AutoReleaseSpiritAction::ShouldDelayBattlegroundRelease() const
return true;
}
bool RepopAction::Execute(Event event)
bool RepopAction::Execute(Event /*event*/)
{
const GraveyardStruct* graveyard = GetGrave(
AI_VALUE(uint32, "death count") > 10 ||
@ -250,7 +250,7 @@ void RepopAction::PerformGraveyardTeleport(const GraveyardStruct* graveyard) con
}
// SelfResurrectAction implementation for Warlock's Soulstone Resurrection/Shaman's Reincarnation
bool SelfResurrectAction::Execute(Event event)
bool SelfResurrectAction::Execute(Event /*event*/)
{
if (!bot->IsAlive() && bot->GetUInt32Value(PLAYER_SELF_RES_SPELL))
{

View File

@ -7,7 +7,7 @@
#include "Event.h"
#include "LastMovementValue.h"
#include "Playerbots.h"
#include "AiObjectContext.h"
bool RememberTaxiAction::Execute(Event event)
{

View File

@ -9,7 +9,7 @@
#include "Event.h"
#include "Playerbots.h"
bool RepairAllAction::Execute(Event event)
bool RepairAllAction::Execute(Event /*event*/)
{
GuidVector npcs = AI_VALUE(GuidVector, "nearest npcs");
for (ObjectGuid const guid : npcs)

View File

@ -5,14 +5,13 @@
#include "ResetInstancesAction.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
bool ResetInstancesAction::Execute(Event event)
bool ResetInstancesAction::Execute(Event /*event*/)
{
WorldPacket packet(CMSG_RESET_INSTANCES, 0);
bot->GetSession()->HandleResetInstancesOpcode(packet);
botAI->TellMaster("Resetting all instances");
return true;
}

View File

@ -10,11 +10,11 @@
#include "Event.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
#include "ServerFacade.h"
#include "NearestGameObjects.h"
bool RevealGatheringItemAction::Execute(Event event)
bool RevealGatheringItemAction::Execute(Event /*event*/)
{
if (!bot->GetGroup())
return false;

View File

@ -9,7 +9,6 @@
#include "FleeManager.h"
#include "GameGraveyard.h"
#include "MapMgr.h"
#include "PlayerbotFactory.h"
#include "Playerbots.h"
#include "RandomPlayerbotMgr.h"
#include "ServerFacade.h"
@ -74,7 +73,7 @@ bool ReviveFromCorpseAction::Execute(Event event)
return true;
}
bool FindCorpseAction::Execute(Event event)
bool FindCorpseAction::Execute(Event /*event*/)
{
if (bot->InBattleground())
return false;
@ -150,7 +149,7 @@ bool FindCorpseAction::Execute(Event event)
{
float rx, ry, rz;
if (manager.CalculateDestination(&rx, &ry, &rz))
moveToPos = WorldPosition(moveToPos.getMapId(), rx, ry, rz, 0.0);
moveToPos = WorldPosition(moveToPos.GetMapId(), rx, ry, rz, 0.0);
else if (!moveToPos.GetReachableRandomPointOnGround(bot, reclaimDist, urand(0, 1)))
moveToPos = corpsePos;
}
@ -170,7 +169,7 @@ bool FindCorpseAction::Execute(Event event)
{
bot->GetMotionMaster()->Clear();
bot->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TELEPORTED | AURA_INTERRUPT_FLAG_CHANGE_MAP);
bot->TeleportTo(moveToPos.getMapId(), moveToPos.getX(), moveToPos.getY(), moveToPos.getZ(), 0);
bot->TeleportTo(moveToPos.GetMapId(), moveToPos.GetPositionX(), moveToPos.GetPositionY(), moveToPos.GetPositionZ(), 0);
}
moved = true;
@ -184,7 +183,7 @@ bool FindCorpseAction::Execute(Event event)
if (deadTime < 10 * MINUTE && dCount < 5) // Look for corpse up to 30 minutes.
{
moved =
MoveTo(moveToPos.getMapId(), moveToPos.getX(), moveToPos.getY(), moveToPos.getZ(), false, false);
MoveTo(moveToPos.GetMapId(), moveToPos.GetPositionX(), moveToPos.GetPositionY(), moveToPos.GetPositionZ(), false, false);
}
if (!moved)
@ -237,10 +236,10 @@ GraveyardStruct const* SpiritHealerAction::GetGrave(bool startZone)
{
uint32 areaId = 0;
uint32 zoneId = 0;
sMapMgr->GetZoneAndAreaId(bot->GetPhaseMask(), zoneId, areaId, travelPos.getMapId(), travelPos.getX(),
travelPos.getY(), travelPos.getZ());
ClosestGrave = sGraveyard->GetClosestGraveyard(travelPos.getMapId(), travelPos.getX(), travelPos.getY(),
travelPos.getZ(), bot->GetTeamId(), areaId, zoneId,
sMapMgr->GetZoneAndAreaId(bot->GetPhaseMask(), zoneId, areaId, travelPos.GetMapId(), travelPos.GetPositionX(),
travelPos.GetPositionY(), travelPos.GetPositionZ());
ClosestGrave = sGraveyard->GetClosestGraveyard(travelPos.GetMapId(), travelPos.GetPositionX(), travelPos.GetPositionY(),
travelPos.GetPositionZ(), bot->GetTeamId(), areaId, zoneId,
bot->getClass() == CLASS_DEATH_KNIGHT);
if (ClosestGrave)
@ -293,7 +292,7 @@ GraveyardStruct const* SpiritHealerAction::GetGrave(bool startZone)
return ClosestGrave;
}
bool SpiritHealerAction::Execute(Event event)
bool SpiritHealerAction::Execute(Event /*event*/)
{
Corpse* corpse = bot->GetCorpse();
if (!corpse)

View File

@ -7,7 +7,6 @@
#include <random>
#include "BattlegroundMgr.h"
#include "ChatHelper.h"
#include "EmoteAction.h"
#include "Event.h"
@ -16,7 +15,7 @@
#include "ServerFacade.h"
#include "RpgSubActions.h"
bool RpgAction::Execute(Event event)
bool RpgAction::Execute(Event /*event*/)
{
GuidPosition guidP = AI_VALUE(GuidPosition, "rpg target");
if (!guidP && botAI->GetMaster())
@ -85,7 +84,7 @@ bool RpgAction::SetNextRpgAction()
isChecked = true;
Action* action = botAI->GetAiObjectContext()->GetAction(nextAction.getName());
if (!dynamic_cast<RpgEnabled*>(action) || !action->isPossible() || !action->isUseful())
if (!dynamic_cast<RpgEnabled*>(action) || !action->isUseful() || !action->isPossible())
continue;
actions.push_back(action);

View File

@ -99,7 +99,7 @@ Event RpgSubAction::ActionEvent(Event event) { return event; }
bool RpgStayAction::isUseful() { return rpg->InRange() && !botAI->HasRealPlayerMaster(); }
bool RpgStayAction::Execute(Event event)
bool RpgStayAction::Execute(Event /*event*/)
{
bot->PlayerTalkClass->SendCloseGossip();
@ -109,7 +109,7 @@ bool RpgStayAction::Execute(Event event)
bool RpgWorkAction::isUseful() { return rpg->InRange() && !botAI->HasRealPlayerMaster(); }
bool RpgWorkAction::Execute(Event event)
bool RpgWorkAction::Execute(Event /*event*/)
{
bot->HandleEmoteCommand(EMOTE_STATE_USE_STANDING);
rpg->AfterExecute();
@ -118,7 +118,7 @@ bool RpgWorkAction::Execute(Event event)
bool RpgEmoteAction::isUseful() { return rpg->InRange() && !botAI->HasRealPlayerMaster(); }
bool RpgEmoteAction::Execute(Event event)
bool RpgEmoteAction::Execute(Event /*event*/)
{
uint32 type = TalkAction::GetRandomEmote(rpg->guidP().GetUnit());
@ -133,7 +133,7 @@ bool RpgEmoteAction::Execute(Event event)
return true;
}
bool RpgCancelAction::Execute(Event event)
bool RpgCancelAction::Execute(Event /*event*/)
{
RESET_AI_VALUE(GuidPosition, "rpg target");
rpg->OnExecute("");
@ -142,7 +142,7 @@ bool RpgCancelAction::Execute(Event event)
bool RpgTaxiAction::isUseful() { return rpg->InRange() && !botAI->HasRealPlayerMaster(); }
bool RpgTaxiAction::Execute(Event event)
bool RpgTaxiAction::Execute(Event /*event*/)
{
GuidPosition guidP = rpg->guidP();
@ -150,7 +150,7 @@ bool RpgTaxiAction::Execute(Event event)
bot->GetSession()->HandleCancelMountAuraOpcode(emptyPacket);
uint32 node =
sObjectMgr->GetNearestTaxiNode(guidP.getX(), guidP.getY(), guidP.getZ(), guidP.getMapId(), bot->GetTeamId());
sObjectMgr->GetNearestTaxiNode(guidP.GetPositionX(), guidP.GetPositionY(), guidP.GetPositionZ(), guidP.GetMapId(), bot->GetTeamId());
std::vector<uint32> nodes;
for (uint32 i = 0; i < sTaxiPathStore.GetNumRows(); ++i)
@ -203,12 +203,12 @@ bool RpgTaxiAction::Execute(Event event)
return true;
}
bool RpgDiscoverAction::Execute(Event event)
bool RpgDiscoverAction::Execute(Event /*event*/)
{
GuidPosition guidP = rpg->guidP();
uint32 node =
sObjectMgr->GetNearestTaxiNode(guidP.getX(), guidP.getY(), guidP.getZ(), guidP.getMapId(), bot->GetTeamId());
sObjectMgr->GetNearestTaxiNode(guidP.GetPositionX(), guidP.GetPositionY(), guidP.GetPositionZ(), guidP.GetMapId(), bot->GetTeamId());
if (!node)
return false;
@ -222,7 +222,7 @@ bool RpgDiscoverAction::Execute(Event event)
std::string const RpgStartQuestAction::ActionName() { return "accept all quests"; }
Event RpgStartQuestAction::ActionEvent(Event event)
Event RpgStartQuestAction::ActionEvent(Event /*event*/)
{
WorldPacket p(CMSG_QUESTGIVER_ACCEPT_QUEST);
p << rpg->guid();
@ -232,7 +232,7 @@ Event RpgStartQuestAction::ActionEvent(Event event)
std::string const RpgEndQuestAction::ActionName() { return "talk to quest giver"; }
Event RpgEndQuestAction::ActionEvent(Event event)
Event RpgEndQuestAction::ActionEvent(Event /*event*/)
{
WorldPacket p(CMSG_QUESTGIVER_COMPLETE_QUEST);
p << rpg->guid();
@ -242,17 +242,17 @@ Event RpgEndQuestAction::ActionEvent(Event event)
std::string const RpgBuyAction::ActionName() { return "buy"; }
Event RpgBuyAction::ActionEvent(Event event) { return Event("rpg action", "vendor"); }
Event RpgBuyAction::ActionEvent(Event /*event*/) { return Event("rpg action", "vendor"); }
std::string const RpgSellAction::ActionName() { return "sell"; }
Event RpgSellAction::ActionEvent(Event event) { return Event("rpg action", "vendor"); }
Event RpgSellAction::ActionEvent(Event /*event*/) { return Event("rpg action", "vendor"); }
std::string const RpgRepairAction::ActionName() { return "repair"; }
std::string const RpgTrainAction::ActionName() { return "trainer"; }
bool RpgHealAction::Execute(Event event)
bool RpgHealAction::Execute(Event /*event*/)
{
bool retVal = false;
@ -287,21 +287,21 @@ std::string const RpgBuyPetitionAction::ActionName() { return "buy petition"; }
std::string const RpgUseAction::ActionName() { return "use"; }
Event RpgUseAction::ActionEvent(Event event)
Event RpgUseAction::ActionEvent(Event /*event*/)
{
return Event("rpg action", chat->FormatWorldobject(rpg->guidP().GetWorldObject()));
}
std::string const RpgSpellAction::ActionName() { return "cast random spell"; }
Event RpgSpellAction::ActionEvent(Event event)
Event RpgSpellAction::ActionEvent(Event /*event*/)
{
return Event("rpg action", chat->FormatWorldobject(rpg->guidP().GetWorldObject()));
}
std::string const RpgCraftAction::ActionName() { return "craft random item"; }
Event RpgCraftAction::ActionEvent(Event event)
Event RpgCraftAction::ActionEvent(Event /*event*/)
{
return Event("rpg action", chat->FormatWorldobject(rpg->guidP().GetWorldObject()));
}
@ -341,7 +341,7 @@ std::vector<Item*> RpgTradeUsefulAction::CanGiveItems(GuidPosition guidPosition)
return giveItems;
}
bool RpgTradeUsefulAction::Execute(Event event)
bool RpgTradeUsefulAction::Execute(Event /*event*/)
{
GuidPosition guidP = AI_VALUE(GuidPosition, "rpg target");
@ -416,7 +416,7 @@ bool RpgDuelAction::isUseful()
return true;
}
bool RpgDuelAction::Execute(Event event)
bool RpgDuelAction::Execute(Event /*event*/)
{
GuidPosition guidP = AI_VALUE(GuidPosition, "rpg target");
@ -434,7 +434,7 @@ bool RpgMountAnimAction::isUseful()
return AI_VALUE2(bool, "mounted", "self target") && !AI_VALUE2(bool, "moving", "self target");
}
bool RpgMountAnimAction::Execute(Event event)
bool RpgMountAnimAction::Execute(Event /*event*/)
{
WorldPacket p;
bot->GetSession()->HandleMountSpecialAnimOpcode(p);

View File

@ -55,7 +55,7 @@ void RtiAction::AppendRti(std::ostringstream& out, std::string const type)
out << " (" << target->GetName() << ")";
}
bool MarkRtiAction::Execute(Event event)
bool MarkRtiAction::Execute(Event /*event*/)
{
Group* group = bot->GetGroup();
if (!group)

View File

@ -80,8 +80,9 @@ bool RTSCAction::Execute(Event event)
SET_AI_VALUE2(WorldPosition, "RTSC saved location", locationName, spellPosition);
Creature* wpCreature =
bot->SummonCreature(15631, spellPosition.getX(), spellPosition.getY(), spellPosition.getZ(),
spellPosition.getO(), TEMPSUMMON_TIMED_DESPAWN, 2000.0f);
bot->SummonCreature(15631, spellPosition.GetPositionX(), spellPosition.GetPositionY(),
spellPosition.GetPositionZ(), spellPosition.GetOrientation(), TEMPSUMMON_TIMED_DESPAWN,
2000.0f);
wpCreature->SetObjectScale(0.5f);
return true;
@ -110,8 +111,9 @@ bool RTSCAction::Execute(Event event)
if (spellPosition)
{
Creature* wpCreature =
bot->SummonCreature(15631, spellPosition.getX(), spellPosition.getY(), spellPosition.getZ(),
spellPosition.getO(), TEMPSUMMON_TIMED_DESPAWN, 2000.0f);
bot->SummonCreature(15631, spellPosition.GetPositionX(), spellPosition.GetPositionY(),
spellPosition.GetPositionZ(), spellPosition.GetOrientation(),
TEMPSUMMON_TIMED_DESPAWN, 2000.0f);
wpCreature->SetObjectScale(0.5f);
}

View File

@ -9,9 +9,7 @@
#include <regex>
#include <string>
#include "ChannelMgr.h"
#include "Event.h"
#include "GuildMgr.h"
#include "PlayerbotTextMgr.h"
#include "Playerbots.h"
@ -56,7 +54,7 @@ static const std::unordered_set<std::string> noReplyMsgStarts = {"e ", "accept "
SayAction::SayAction(PlayerbotAI* botAI) : Action(botAI, "say"), Qualified() {}
bool SayAction::Execute(Event event)
bool SayAction::Execute(Event /*event*/)
{
std::string text = "";
std::map<std::string, std::string> placeholders;
@ -92,7 +90,6 @@ bool SayAction::Execute(Event event)
}
// set delay before next say
time_t lastSaid = AI_VALUE2(time_t, "last said", qualifier);
uint32 nextTime = time(nullptr) + urand(1, 30);
botAI->GetAiObjectContext()->GetValue<time_t>("last said", qualifier)->Set(nextTime);

View File

@ -14,7 +14,7 @@ bool SecurityCheckAction::isUseful()
botAI->GetMaster()->GetSession()->GetSecurity() < SEC_GAMEMASTER && !GET_PLAYERBOT_AI(botAI->GetMaster());
}
bool SecurityCheckAction::Execute(Event event)
bool SecurityCheckAction::Execute(Event /*event*/)
{
if (Group* group = bot->GetGroup())
{

View File

@ -7,7 +7,6 @@
#include "Event.h"
#include "Formations.h"
#include "PathGenerator.h"
#include "Playerbots.h"
#include "RTSCValues.h"
#include "RtscAction.h"
@ -134,8 +133,8 @@ bool SeeSpellAction::Execute(Event event)
SET_AI_VALUE2(WorldPosition, "RTSC saved location", locationName, spellPosition);
Creature* wpCreature =
bot->SummonCreature(15631, spellPosition.getX(), spellPosition.getY(), spellPosition.getZ(),
spellPosition.getO(), TEMPSUMMON_TIMED_DESPAWN, 2000.0f);
bot->SummonCreature(15631, spellPosition.GetPositionX(), spellPosition.GetPositionY(), spellPosition.GetPositionZ(),
spellPosition.GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 2000.0f);
wpCreature->SetObjectScale(0.5f);
RESET_AI_VALUE(std::string, "RTSC next spell action");
@ -167,14 +166,14 @@ bool SeeSpellAction::MoveToSpell(WorldPosition& spellPosition, bool inFormation)
PositionMap& posMap = AI_VALUE(PositionMap&, "position");
PositionInfo stayPosition = posMap["stay"];
stayPosition.Set(spellPosition.getX(), spellPosition.getY(), spellPosition.getZ(), spellPosition.getMapId());
stayPosition.Set(spellPosition.GetPositionX(), spellPosition.GetPositionY(), spellPosition.GetPositionZ(), spellPosition.GetMapId());
posMap["stay"] = stayPosition;
}
if (bot->IsWithinLOS(spellPosition.getX(), spellPosition.getY(), spellPosition.getZ()))
return MoveNear(spellPosition.getMapId(), spellPosition.getX(), spellPosition.getY(), spellPosition.getZ(), 0);
if (bot->IsWithinLOS(spellPosition.GetPositionX(), spellPosition.GetPositionY(), spellPosition.GetPositionZ()))
return MoveNear(spellPosition.GetMapId(), spellPosition.GetPositionX(), spellPosition.GetPositionY(), spellPosition.GetPositionZ(), 0);
return MoveTo(spellPosition.getMapId(), spellPosition.getX(), spellPosition.getY(), spellPosition.getZ(), false,
return MoveTo(spellPosition.GetMapId(), spellPosition.GetPositionX(), spellPosition.GetPositionY(), spellPosition.GetPositionZ(), false,
false);
}

View File

@ -49,9 +49,7 @@ bool SetCraftAction::Execute(Event event)
if (skillSpells.empty())
{
for (SkillLineAbilityEntry const* skillLine : sSkillLineAbilityStore)
{
skillSpells[skillLine->Spell] = skillLine;
}
}
data.required.clear();
@ -78,9 +76,7 @@ bool SetCraftAction::Execute(Event event)
for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
{
if (spellInfo->Reagent[x] <= 0)
{
continue;
}
uint32 itemid = spellInfo->Reagent[x];
uint32 reagentsRequired = spellInfo->ReagentCount[x];
@ -132,9 +128,8 @@ void SetCraftAction::TellCraft()
if (ItemTemplate const* reagent = sObjectMgr->GetItemTemplate(item))
{
if (first)
{
first = false;
}
else
out << ", ";
@ -142,9 +137,7 @@ void SetCraftAction::TellCraft()
uint32 given = data.obtained[item];
if (given)
{
out << "|cffffff00(x" << given << " given)|r ";
}
}
}

View File

@ -8,7 +8,7 @@
#include "Event.h"
#include "Playerbots.h"
bool SetHomeAction::Execute(Event event)
bool SetHomeAction::Execute(Event /*event*/)
{
Player* master = GetMaster();

View File

@ -7,9 +7,9 @@
#include "ChatHelper.h"
#include "Event.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
bool StatsAction::Execute(Event event)
bool StatsAction::Execute(Event /*event*/)
{
std::ostringstream out;

View File

@ -39,7 +39,7 @@ bool StayActionBase::Stay()
return true;
}
bool StayAction::Execute(Event event) { return Stay(); }
bool StayAction::Execute(Event /*event*/) { return Stay(); }
bool StayAction::isUseful()
{
@ -49,9 +49,7 @@ bool StayAction::isUseful()
{
const float distance = bot->GetDistance(stayPosition.x, stayPosition.y, stayPosition.z);
if (sPlayerbotAIConfig.followDistance)
{
return false;
}
}
// move from group takes priority over stay as it's added and removed automatically
@ -64,7 +62,7 @@ bool StayAction::isUseful()
return AI_VALUE2(bool, "moving", "self target");
}
bool SitAction::Execute(Event event)
bool SitAction::Execute(Event /*event*/)
{
if (bot->isMoving())
return false;

View File

@ -7,25 +7,19 @@
#include "SuggestWhatToDoAction.h"
#include "ServerFacade.h"
#include "ChannelMgr.h"
#include "Event.h"
#include "ItemVisitors.h"
#include "AiFactory.h"
#include "ChatHelper.h"
#include "Playerbots.h"
#include "PlayerbotTextMgr.h"
#include "Config.h"
#include "BroadcastHelper.h"
#include "AiFactory.h"
#include "ChannelMgr.h"
#include "ChatHelper.h"
#include "Config.h"
#include "Event.h"
#include "GuildMgr.h"
#include "ItemVisitors.h"
#include "PlayerbotTextMgr.h"
#include "Playerbots.h"
#include "ServerFacade.h"
#include "Channel.h"
enum eTalkType
{
@ -62,7 +56,7 @@ bool SuggestWhatToDoAction::isUseful()
return (time(0) - lastSaid) > 30;
}
bool SuggestWhatToDoAction::Execute(Event event)
bool SuggestWhatToDoAction::Execute(Event /*event*/)
{
uint32 index = rand() % suggestions.size();
auto fnct_ptr = suggestions[index];
@ -258,7 +252,7 @@ private:
SuggestDungeonAction::SuggestDungeonAction(PlayerbotAI* botAI) : SuggestWhatToDoAction(botAI, "suggest dungeon") {}
bool SuggestDungeonAction::Execute(Event event)
bool SuggestDungeonAction::Execute(Event /*event*/)
{
// TODO: use PlayerbotDungeonRepository::instance()
@ -325,7 +319,7 @@ bool SuggestDungeonAction::Execute(Event event)
SuggestTradeAction::SuggestTradeAction(PlayerbotAI* botAI) : SuggestWhatToDoAction(botAI, "suggest trade") {}
bool SuggestTradeAction::Execute(Event event)
bool SuggestTradeAction::Execute(Event /*event*/)
{
uint32 quality = urand(0, 100);
if (quality > 95)

View File

@ -6,12 +6,10 @@
#include "TameAction.h"
#include <algorithm>
#include <cctype>
#include <iomanip>
#include <random>
#include <set>
#include <sstream>
#include "DBCStructure.h"
#include "Log.h"
#include "ObjectMgr.h"
#include "Pet.h"
#include "Player.h"

View File

@ -7,9 +7,12 @@
#include "Event.h"
#include "LastMovementValue.h"
#include "Playerbots.h"
#include "AiObjectContext.h"
#include "PlayerbotAI.h"
#include "SpellMgr.h"
#include "Spell.h"
bool TeleportAction::Execute(Event event)
bool TeleportAction::Execute(Event /*event*/)
{
/*
// List of allowed portal entries (you can populate this dynamically)
@ -74,7 +77,7 @@ bool TeleportAction::Execute(Event event)
continue;
uint32 spellId = goInfo->spellcaster.spellId;
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
SpellInfo const* spellInfo = SpellMgr::instance()->GetSpellInfo(spellId);
if (!spellInfo || !spellInfo->HasEffect(SPELL_EFFECT_TELEPORT_UNITS))
continue;

View File

@ -4,11 +4,9 @@
*/
#include "TellLosAction.h"
#include <istream>
#include <sstream>
#include "ChatHelper.h"
#include "DBCStores.h"
#include "Event.h"
#include "ItemTemplate.h"
#include "ObjectMgr.h"
@ -77,7 +75,7 @@ void TellLosAction::ListGameObjects(std::string const title, GuidVector gos)
}
}
bool TellAuraAction::Execute(Event event)
bool TellAuraAction::Execute(Event /*event*/)
{
botAI->TellMaster("--- Auras ---");
sLog->outMessage("playerbot", LOG_LEVEL_DEBUG, "--- Auras ---");
@ -130,7 +128,7 @@ bool TellAuraAction::Execute(Event event)
return true;
}
bool TellEstimatedDpsAction::Execute(Event event)
bool TellEstimatedDpsAction::Execute(Event /*event*/)
{
float dps = AI_VALUE(float, "estimated group dps");
botAI->TellMaster("Estimated Group DPS: " + std::to_string(dps));

View File

@ -8,13 +8,13 @@
#include "Event.h"
#include "Playerbots.h"
bool TellMasterAction::Execute(Event event)
bool TellMasterAction::Execute(Event /*event*/)
{
botAI->TellMaster(text);
return true;
}
bool OutOfReactRangeAction::Execute(Event event)
bool OutOfReactRangeAction::Execute(Event /*event*/)
{
botAI->TellMaster("Wait for me!");
return true;

View File

@ -6,10 +6,10 @@
#include "TellReputationAction.h"
#include "Event.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
#include "ReputationMgr.h"
bool TellReputationAction::Execute(Event event)
bool TellReputationAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)

View File

@ -6,10 +6,11 @@
#include "TellTargetAction.h"
#include "Event.h"
#include "Playerbots.h"
#include "ThreatMgr.h"
#include "AiObjectContext.h"
#include "PlayerbotAI.h"
bool TellTargetAction::Execute(Event event)
bool TellTargetAction::Execute(Event /*event*/)
{
Unit* target = context->GetValue<Unit*>("current target")->Get();
if (target)
@ -24,7 +25,7 @@ bool TellTargetAction::Execute(Event event)
return true;
}
bool TellAttackersAction::Execute(Event event)
bool TellAttackersAction::Execute(Event /*event*/)
{
botAI->TellMaster("--- Attackers ---");

View File

@ -8,7 +8,7 @@
#include "Event.h"
#include "ItemCountValue.h"
#include "ItemVisitors.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
bool TradeAction::Execute(Event event)
{
@ -106,9 +106,7 @@ bool TradeAction::TradeItem(Item const* item, int8 slot)
for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT && tradeSlot == -1; i++)
{
if (pTrade->GetItem(TradeSlots(i)) == nullptr)
{
tradeSlot = i;
}
}
}

View File

@ -276,14 +276,11 @@ bool TradeStatusAction::CheckTrade()
botAI->PlaySound(TEXT_EMOTE_NO);
return false;
}
success = true;
}
}
else
{
success = true;
}
if (success)
{
@ -340,9 +337,7 @@ int32 TradeStatusAction::CalculateCost(Player* player, bool sell)
if (!craftData.IsEmpty())
{
if (player == trader && !sell && craftData.IsRequired(proto->ItemId))
{
continue;
}
if (player == bot && sell && craftData.itemId == proto->ItemId && craftData.IsFulfilled())
{
@ -352,13 +347,11 @@ int32 TradeStatusAction::CalculateCost(Player* player, bool sell)
}
if (sell)
{
sum += item->GetCount() * proto->SellPrice * sRandomPlayerbotMgr.GetSellMultiplier(bot);
}
else
{
sum += item->GetCount() * proto->BuyPrice * sRandomPlayerbotMgr.GetBuyMultiplier(bot);
}
}
return sum;

View File

@ -155,7 +155,7 @@ void TrainerAction::TellFooter(uint32 totalCost)
}
}
bool MaintenanceAction::Execute(Event event)
bool MaintenanceAction::Execute(Event /*event*/)
{
if (!sPlayerbotAIConfig.maintenanceCommand)
{
@ -255,7 +255,7 @@ bool MaintenanceAction::Execute(Event event)
return true;
}
bool RemoveGlyphAction::Execute(Event event)
bool RemoveGlyphAction::Execute(Event /*event*/)
{
for (uint32 slotIndex = 0; slotIndex < MAX_GLYPH_SLOT_INDEX; ++slotIndex)
{
@ -265,7 +265,7 @@ bool RemoveGlyphAction::Execute(Event event)
return true;
}
bool AutoGearAction::Execute(Event event)
bool AutoGearAction::Execute(Event /*event*/)
{
if (!sPlayerbotAIConfig.autoGearCommand)
{

View File

@ -10,7 +10,7 @@
#include "GridNotifiersImpl.h"
#include "Playerbots.h"
bool TravelAction::Execute(Event event)
bool TravelAction::Execute(Event /*event*/)
{
TravelTarget* target = AI_VALUE(TravelTarget*, "travel target");
@ -60,12 +60,14 @@ bool TravelAction::isUseful()
(!AI_VALUE(GuidPosition, "rpg target") || !AI_VALUE(ObjectGuid, "pull target"));
}
bool MoveToDarkPortalAction::Execute(Event event)
bool MoveToDarkPortalAction::Execute(Event /*event*/)
{
if (bot->GetGroup())
{
if (bot->GetGroup()->GetLeaderGUID() != bot->GetGUID() &&
!GET_PLAYERBOT_AI(GET_PLAYERBOT_AI(bot)->GetGroupLeader()))
return false;
}
if (bot->GetLevel() > 57)
{
@ -111,7 +113,7 @@ bool MoveToDarkPortalAction::Execute(Event event)
bool MoveToDarkPortalAction::isUseful() { return bot->GetLevel() > 54; }
bool DarkPortalAzerothAction::Execute(Event event)
bool DarkPortalAzerothAction::Execute(Event /*event*/)
{
if (bot->GetLevel() > 57)
{
@ -126,7 +128,7 @@ bool DarkPortalAzerothAction::Execute(Event event)
bool DarkPortalAzerothAction::isUseful() { return bot->GetLevel() > 57; }
bool MoveFromDarkPortalAction::Execute(Event event)
bool MoveFromDarkPortalAction::Execute(Event /*event*/)
{
RESET_AI_VALUE(GuidPosition, "rpg target");

View File

@ -1,14 +1,13 @@
#include "UnlockItemAction.h"
#include "PlayerbotAI.h"
#include "ItemTemplate.h"
#include "WorldPacket.h"
#include "Player.h"
#include "ObjectMgr.h"
#include "SpellInfo.h"
#define PICK_LOCK_SPELL_ID 1804
inline constexpr uint32_t PICK_LOCK_SPELL_ID = 1804;
bool UnlockItemAction::Execute(Event event)
bool UnlockItemAction::Execute(Event /*event*/)
{
bool foundLockedItem = false;
@ -32,7 +31,5 @@ void UnlockItemAction::UnlockItem(Item* item)
botAI->TellMaster(out.str());
}
else
{
botAI->TellError("Failed to cast Pick Lock.");
}
}

View File

@ -1,11 +1,11 @@
#include "UnlockTradedItemAction.h"
#include "Playerbots.h"
#include "PlayerbotAI.h"
#include "TradeData.h"
#include "SpellInfo.h"
#define PICK_LOCK_SPELL_ID 1804
inline constexpr uint32_t PICK_LOCK_SPELL_ID = 1804;
bool UnlockTradedItemAction::Execute(Event event)
bool UnlockTradedItemAction::Execute(Event /*event*/)
{
Player* trader = bot->GetTrader();
if (!trader)

View File

@ -7,9 +7,9 @@
#include "ChatHelper.h"
#include "Event.h"
#include "ItemPackets.h"
#include "ItemUsageValue.h"
#include "Playerbots.h"
#include "ItemPackets.h"
bool UseItemAction::Execute(Event event)
{
@ -416,14 +416,7 @@ bool UseHearthStone::Execute(Event event)
bool UseHearthStone::isUseful() { return !bot->InBattleground(); }
bool UseRandomRecipe::isUseful()
{
return !bot->IsInCombat() && !botAI->HasActivePlayerMaster() && !bot->InBattleground();
}
bool UseRandomRecipe::isPossible() { return AI_VALUE2(uint32, "item count", "recipe") > 0; }
bool UseRandomRecipe::Execute(Event event)
bool UseRandomRecipe::Execute(Event /*event*/)
{
std::vector<Item*> recipes = AI_VALUE2(std::vector<Item*>, "inventory items", "recipe");
@ -445,14 +438,14 @@ bool UseRandomRecipe::Execute(Event event)
return used;
}
bool UseRandomQuestItem::isUseful()
bool UseRandomRecipe::isUseful()
{
return !botAI->HasActivePlayerMaster() && !bot->InBattleground() && !bot->HasUnitState(UNIT_STATE_IN_FLIGHT);
return !bot->IsInCombat() && !botAI->HasActivePlayerMaster() && !bot->InBattleground();
}
bool UseRandomQuestItem::isPossible() { return AI_VALUE2(uint32, "item count", "quest") > 0; }
bool UseRandomRecipe::isPossible() { return AI_VALUE2(uint32, "item count", "recipe") > 0; }
bool UseRandomQuestItem::Execute(Event event)
bool UseRandomQuestItem::Execute(Event /*event*/)
{
Unit* unitTarget = nullptr;
ObjectGuid goTarget;
@ -478,7 +471,6 @@ bool UseRandomQuestItem::Execute(Event event)
break;
}
}
}
if (!item)
@ -490,3 +482,10 @@ bool UseRandomQuestItem::Execute(Event event)
return used;
}
bool UseRandomQuestItem::isUseful()
{
return !botAI->HasActivePlayerMaster() && !bot->InBattleground() && !bot->HasUnitState(UNIT_STATE_IN_FLIGHT);
}
bool UseRandomQuestItem::isPossible() { return AI_VALUE2(uint32, "item count", "quest") > 0; }

View File

@ -69,8 +69,8 @@ class UseHearthStone : public UseItemAction
public:
UseHearthStone(PlayerbotAI* botAI) : UseItemAction(botAI, "hearthstone", true) {}
bool isUseful() override;
bool Execute(Event event) override;
bool isUseful() override;
};
class UseRandomRecipe : public UseItemAction
@ -78,9 +78,9 @@ class UseRandomRecipe : public UseItemAction
public:
UseRandomRecipe(PlayerbotAI* botAI) : UseItemAction(botAI, "random recipe", true) {}
bool Execute(Event event) override;
bool isUseful() override;
bool isPossible() override;
bool Execute(Event event) override;
};
class UseRandomQuestItem : public UseItemAction
@ -88,9 +88,9 @@ class UseRandomQuestItem : public UseItemAction
public:
UseRandomQuestItem(PlayerbotAI* botAI) : UseItemAction(botAI, "random quest item", true) {}
bool Execute(Event event) override;
bool isUseful() override;
bool isPossible() override;
bool Execute(Event event) override;
};
#endif

View File

@ -55,16 +55,14 @@ bool UseMeetingStoneAction::Execute(Event event)
return Teleport(master, bot, false);
}
bool SummonAction::Execute(Event event)
bool SummonAction::Execute(Event /*event*/)
{
Player* master = GetMaster();
if (!master)
return false;
if (Pet* pet = bot->GetPet())
{
botAI->PetFollow();
}
if (master->GetSession()->GetSecurity() >= SEC_PLAYER)
{

View File

@ -95,7 +95,7 @@ bool EnterVehicleAction::EnterVehicle(Unit* vehicleBase, bool moveIfFar)
return true;
}
bool LeaveVehicleAction::Execute(Event event)
bool LeaveVehicleAction::Execute(Event /*event*/)
{
Vehicle* myVehicle = bot->GetVehicle();
if (!myVehicle)

View File

@ -120,7 +120,6 @@ public:
creators["use"] = &ChatActionContext::use;
creators["item count"] = &ChatActionContext::item_count;
creators["equip"] = &ChatActionContext::equip;
creators["equip upgrades"] = &ChatActionContext::equip_upgrade;
creators["unequip"] = &ChatActionContext::unequip;
creators["sell"] = &ChatActionContext::sell;
creators["buy"] = &ChatActionContext::buy;

View File

@ -5,8 +5,6 @@
#include "ChatCommandHandlerStrategy.h"
#include "Playerbots.h"
class ChatCommandActionNodeFactoryInternal : public NamedObjectFactory<ActionNode>
{
public:

View File

@ -5,7 +5,6 @@
#include "CombatStrategy.h"
#include "Playerbots.h"
#include "Strategy.h"
void CombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)

View File

@ -5,8 +5,6 @@
#include "DuelStrategy.h"
#include "Playerbots.h"
void DuelStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
PassTroughStrategy::InitTriggers(triggers);

View File

@ -5,8 +5,6 @@
#include "FollowMasterStrategy.h"
#include "Playerbots.h"
std::vector<NextAction> FollowMasterStrategy::getDefaultActions()
{
return {

View File

@ -5,8 +5,6 @@
#include "GuardStrategy.h"
#include "Playerbots.h"
std::vector<NextAction> GuardStrategy::getDefaultActions()
{
return {

View File

@ -5,8 +5,6 @@
#include "NonCombatStrategy.h"
#include "Playerbots.h"
void NonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
{
triggers.push_back(new TriggerNode("random", { NextAction("clean quest log", 1.0f) }));
@ -58,7 +56,7 @@ void MasterFishingStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
"random",
{
NextAction("end master fishing", 12.0f),
NextAction("equip upgrades", 6.0f)
NextAction("equip upgrades packet action", 6.0f)
}
)
);

View File

@ -5,8 +5,6 @@
#include "RTSCStrategy.h"
#include "Playerbots.h"
RTSCStrategy::RTSCStrategy(PlayerbotAI* botAI) : Strategy(botAI) {}
void RTSCStrategy::InitTriggers(std::vector<TriggerNode*>& triggers) {}

View File

@ -5,8 +5,6 @@
#include "RacialsStrategy.h"
#include "Playerbots.h"
class RacialsStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{
public:

View File

@ -5,8 +5,6 @@
#include "UsePotionsStrategy.h"
#include "Playerbots.h"
class UsePotionsStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{
public:

View File

@ -32,7 +32,7 @@ void WorldPacketHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
triggers.push_back(new TriggerNode("activate taxi", { NextAction("remember taxi", relevance),
NextAction("taxi", relevance) }));
triggers.push_back(new TriggerNode("taxi done", { NextAction("taxi", relevance) }));
triggers.push_back(new TriggerNode("trade status", { NextAction("accept trade", relevance), NextAction("equip upgrades", relevance) }));
triggers.push_back(new TriggerNode("trade status", { NextAction("accept trade", relevance), NextAction("equip upgrades packet action", relevance) }));
triggers.push_back(new TriggerNode("trade status extended", { NextAction("trade status extended", relevance) }));
triggers.push_back(new TriggerNode("area trigger", { NextAction("reach area trigger", relevance) }));
triggers.push_back(new TriggerNode("within area trigger", { NextAction("area trigger", relevance) }));
@ -40,9 +40,9 @@ void WorldPacketHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
triggers.push_back(new TriggerNode("item push result", { NextAction("unlock items", relevance),
NextAction("open items", relevance),
NextAction("query item usage", relevance),
NextAction("equip upgrades", relevance) }));
NextAction("equip upgrades packet action", relevance) }));
triggers.push_back(new TriggerNode("item push result", { NextAction("quest item push result", relevance) }));
triggers.push_back(new TriggerNode("loot roll won", { NextAction("equip upgrades", relevance) }));
triggers.push_back(new TriggerNode("loot roll won", { NextAction("equip upgrades packet action", relevance) }));
triggers.push_back(new TriggerNode("ready check finished", { NextAction("finish ready check", relevance) }));
// triggers.push_back(new TriggerNode("often", { NextAction("security check", relevance), NextAction("check mail", relevance) }));
triggers.push_back(new TriggerNode("guild invite", { NextAction("guild accept", relevance) }));

Some files were not shown because too many files have changed in this diff Show More