Skip to content

Commit

Permalink
Merge pull request #541 from Wargus/clean-up
Browse files Browse the repository at this point in the history
Clean up
  • Loading branch information
Jarod42 authored Oct 14, 2023
2 parents 6e4043e + 8544518 commit a2ddb8f
Show file tree
Hide file tree
Showing 21 changed files with 200 additions and 250 deletions.
113 changes: 53 additions & 60 deletions src/action/action_attack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,14 @@ bool COrder_Attack::IsValid() const /* override */
PixelPos COrder_Attack::Show(const CViewport &vp,
const PixelPos &lastScreenPos) const /* override */
{
PixelPos targetPos;
PixelPos orderedPos;
bool isAttackMove = IsAutoTargeting();
const bool isAttackMove = IsAutoTargeting();
const PixelPos targetPos = this->HasGoal()
? vp.MapToScreenPixelPos(this->GetGoal()->GetMapPixelPosCenter())
: IsMovingToAttackPos() ? vp.TilePosToScreen_Center(this->attackMovePos)
: vp.TilePosToScreen_Center(this->goalPos);
const PixelPos orderedPos = isAttackMove ? vp.TilePosToScreen_Center(this->attackMovePos) : targetPos;
const Uint32 color = isAttackMove ? ColorOrange : ColorRed;

targetPos = this->HasGoal() ? vp.MapToScreenPixelPos(this->GetGoal()->GetMapPixelPosCenter())
: IsMovingToAttackPos() ? vp.TilePosToScreen_Center(this->attackMovePos)
: vp.TilePosToScreen_Center(this->goalPos);

orderedPos = isAttackMove ? vp.TilePosToScreen_Center(this->attackMovePos)
: targetPos;

Uint32 color = isAttackMove ? ColorOrange : ColorRed;
Video.FillCircleClip(color, lastScreenPos, 2);
Video.DrawLineClip(ColorRed, lastScreenPos, orderedPos);
Video.FillCircleClip(color, orderedPos, 3);
Expand Down Expand Up @@ -317,10 +313,6 @@ bool COrder_Attack::OnAiHitUnit(CUnit &unit, CUnit *attacker, int /*damage*/) /*
return false;
}

bool COrder_Attack::IsWeakTargetSelected() const
{
return (this->State & AUTO_TARGETING) != 0;
}
bool COrder_Attack::IsAutoTargeting() const
{
return (this->State & AUTO_TARGETING) != 0;
Expand All @@ -335,14 +327,14 @@ bool COrder_Attack::IsAttackGroundOrWall() const
return this->Action == UnitAction::AttackGround || Map.WallOnMap(this->goalPos);
}

CUnit *COrder_Attack::BestTarget(const CUnit &unit, CUnit *const target1, CUnit *const target2) const
CUnit &COrder_Attack::BestTarget(const CUnit &unit, CUnit &target1, CUnit &target2) const
{
Assert(target1 != nullptr);
Assert(target2 != nullptr);

return (GameSettings.SimplifiedAutoTargeting
? ((TargetPriorityCalculate(&unit, target1) > TargetPriorityCalculate(&unit, target2)) ? target1 : target2)
: ((ThreatCalculate(unit, *target1) < ThreatCalculate(unit, *target2)) ? target1 : target2));
? ((TargetPriorityCalculate(unit, target1) > TargetPriorityCalculate(unit, target2))
? target1
: target2)
: ((ThreatCalculate(unit, target1) < ThreatCalculate(unit, target2)) ? target1
: target2));
}

/**
Expand All @@ -352,23 +344,22 @@ CUnit *COrder_Attack::BestTarget(const CUnit &unit, CUnit *const target1, CUnit
** @param target Target that offered as the new current goal
**
*/
void COrder_Attack::OfferNewTarget(const CUnit &unit, CUnit *const target)
void COrder_Attack::OfferNewTarget(const CUnit &unit, CUnit &target)
{
Assert(target != nullptr);
Assert(this->IsAutoTargeting() || unit.Player->AiEnabled);

/// if attacker cant't move (stand_ground, building, in a bunker or transport)
const bool immobile = this->Action == UnitAction::StandGround || unit.Removed || !unit.CanMove();
if (immobile && !InAttackRange(unit, *target)) {
if (immobile && !InAttackRange(unit, target)) {
return;
}
CUnit *best = (this->offeredTarget != nullptr && this->offeredTarget->IsVisibleAsGoal(*unit.Player))
? BestTarget(unit, this->offeredTarget, target)
CUnit &best = (this->offeredTarget != nullptr && this->offeredTarget->IsVisibleAsGoal(*unit.Player))
? BestTarget(unit, *this->offeredTarget, target)
: target;
if (this->offeredTarget != nullptr) {
this->offeredTarget.Reset();
}
this->offeredTarget = best;
this->offeredTarget = &best;
}

/**
Expand All @@ -387,7 +378,7 @@ bool COrder_Attack::CheckIfGoalValid(CUnit &unit)
CUnit *goal = this->GetGoal();

// Wall was destroyed
if (!goal && this->State & ATTACK_TARGET && this->Action != UnitAction::AttackGround && !Map.WallOnMap(this->goalPos)) {
if (!goal && (this->State & ATTACK_TARGET) && this->Action != UnitAction::AttackGround && !Map.WallOnMap(this->goalPos)) {
return false;
}
// Position or valid target, it is ok.
Expand Down Expand Up @@ -417,7 +408,7 @@ void COrder_Attack::TurnToTarget(CUnit &unit, const CUnit *target)
return;
}
const Vec2i dir = target ? (target->tilePos + target->Type->GetHalfTileSize() - unit.tilePos)
: (this->goalPos - unit.tilePos);
: (this->goalPos - unit.tilePos);
const unsigned char oldDir = unit.Direction;

UnitHeadingFromDeltaXY(unit, dir);
Expand Down Expand Up @@ -447,9 +438,9 @@ void COrder_Attack::SetAutoTarget(CUnit &unit, CUnit *target)
this->ClearGoal();
}
this->SetGoal(target);
this->goalPos = target->tilePos;
this->Range = unit.Stats->Variables[ATTACKRANGE_INDEX].Max;
this->MinRange = unit.Type->MinAttackRange;
this->goalPos = target->tilePos;
this->Range = unit.Stats->Variables[ATTACKRANGE_INDEX].Max;
this->MinRange = unit.Type->MinAttackRange;
if (unit.Type->BoolFlag[SKIRMISHER_INDEX].value) {
this->SkirmishRange = this->Range;
}
Expand All @@ -476,8 +467,9 @@ bool COrder_Attack::AutoSelectTarget(CUnit &unit)

// if unit can't attack, or if unit is not bunkered and removed - exit, no targets
if (unit.Type->CanAttack == false
|| (unit.Removed
&& (unit.Container == nullptr || unit.Container->Type->BoolFlag[ATTACKFROMTRANSPORTER_INDEX].value == false))) {
|| (unit.Removed
&& (unit.Container == nullptr
|| unit.Container->Type->BoolFlag[ATTACKFROMTRANSPORTER_INDEX].value == false))) {
this->offeredTarget.Reset();
return false;
}
Expand All @@ -498,9 +490,9 @@ bool COrder_Attack::AutoSelectTarget(CUnit &unit)
/// If we have target offered from outside - try it
if (this->offeredTarget != nullptr) {
if (this->offeredTarget->IsVisibleAsGoal(*unit.Player)
&& (!immobile || InAttackRange(unit, *this->offeredTarget))) {

newTarget = newTarget ? BestTarget(unit, this->offeredTarget, newTarget) : &(*this->offeredTarget);
&& (!immobile || InAttackRange(unit, *this->offeredTarget))) {
newTarget = newTarget ? &BestTarget(unit, *this->offeredTarget, *newTarget)
: static_cast<CUnit*>(this->offeredTarget);
}
this->offeredTarget.Reset();
}
Expand All @@ -518,8 +510,8 @@ bool COrder_Attack::AutoSelectTarget(CUnit &unit)
return true;
}
if (GameSettings.SimplifiedAutoTargeting) {
const int goal_priority = TargetPriorityCalculate(&unit, goal);
const int newTarget_priority = TargetPriorityCalculate(&unit, newTarget);
const int goal_priority = TargetPriorityCalculate(unit, *goal);
const int newTarget_priority = TargetPriorityCalculate(unit, *newTarget);

if ((newTarget_priority & AT_PRIORITY_MASK_HI) > (goal_priority & AT_PRIORITY_MASK_HI)) {
if (goal_priority & AT_ATTACKED_BY_FACTOR) { /// if unit under attack by current goal
Expand Down Expand Up @@ -556,19 +548,19 @@ bool COrder_Attack::AutoSelectTarget(CUnit &unit)
** Restore action/order when current action is finished
**
** @param unit
** @param canBeFinished False if ony restore order/action needed
** @param canBeFinished False if only restore order/action needed
**
** @return false if order/action restored, true else (if order finished).
** @return false if order/action restored, true else (if order finished).
*/
bool COrder_Attack::EndActionAttack(CUnit &unit, const bool canBeFinished = true)
{
/// Restore saved order only when UnderAttack counter is expired
if ((unit.UnderAttack && IsAutoTargeting()) || !unit.RestoreOrder()) {
if (IsAutoTargeting() && this->goalPos != this->attackMovePos) {
this->goalPos = this->attackMovePos;
this->Range = 0;
this->MinRange = 0;
this->State = AUTO_TARGETING;
this->goalPos = this->attackMovePos;
this->Range = 0;
this->MinRange = 0;
this->State = AUTO_TARGETING;
return false;
}
this->Finished = canBeFinished;
Expand All @@ -584,7 +576,7 @@ bool COrder_Attack::EndActionAttack(CUnit &unit, const bool canBeFinished = true
*/
void COrder_Attack::MoveToBetterPos(CUnit &unit)
{
CUnit *goal = this->GetGoal();
CUnit *goal = this->GetGoal();

/// Save current goalPos if target is ground or wall
if (!goal && IsAttackGroundOrWall()) {
Expand All @@ -594,13 +586,15 @@ void COrder_Attack::MoveToBetterPos(CUnit &unit)
this->attackMovePos = this->goalPos;
}
}
this->goalPos = goal ? GetRndPosInDirection(unit.tilePos, *goal, true, unit.Type->MinAttackRange, 3)
: GetRndPosInDirection(unit.tilePos, this->goalPos, true, unit.Type->MinAttackRange, 3);
this->Range = 0;
this->MinRange = 0;
unit.Frame = 0;
this->State &= AUTO_TARGETING;
this->State |= MOVE_TO_ATTACKPOS;
this->goalPos =
goal
? GetRndPosInDirection(unit.tilePos, *goal, true, unit.Type->MinAttackRange, 3)
: GetRndPosInDirection(unit.tilePos, this->goalPos, true, unit.Type->MinAttackRange, 3);
this->Range = 0;
this->MinRange = 0;
unit.Frame = 0;
this->State &= AUTO_TARGETING;
this->State |= MOVE_TO_ATTACKPOS;
}

/**
Expand Down Expand Up @@ -645,9 +639,9 @@ bool COrder_Attack::IsTargetTooClose(const CUnit &unit) const
if (!this->HasGoal() && !IsAttackGroundOrWall()) {
return false;
}
const int distance = this->HasGoal() ? unit.MapDistanceTo(*this->GetGoal())
: IsMovingToAttackPos() ? unit.MapDistanceTo(this->attackMovePos)
: unit.MapDistanceTo(this->goalPos);
const int distance = this->HasGoal() ? unit.MapDistanceTo(*this->GetGoal())
: IsMovingToAttackPos() ? unit.MapDistanceTo(this->attackMovePos)
: unit.MapDistanceTo(this->goalPos);
const bool tooClose = distance < unit.Type->MinAttackRange;
return tooClose;
}
Expand Down Expand Up @@ -759,8 +753,8 @@ void COrder_Attack::MoveToTarget(CUnit &unit)
}
// Attacking wall or ground.
if (((goal && goal->Type && goal->Type->BoolFlag[WALL_INDEX].value)
|| (!goal && IsAttackGroundOrWall()))
&& InAttackRange(unit, this->goalPos)) {
|| (!goal && IsAttackGroundOrWall()))
&& InAttackRange(unit, this->goalPos)) {

// Reached wall or ground, now attacking it
TurnToTarget(unit, nullptr);
Expand All @@ -781,7 +775,6 @@ void COrder_Attack::MoveToTarget(CUnit &unit)
this->ClearGoal();
}
EndActionAttack(unit);
return;
}

/**
Expand Down Expand Up @@ -868,7 +861,7 @@ void COrder_Attack::Execute(CUnit &unit) /* override */
this->State |= MOVE_TO_TARGET;
// FIXME: should use a reachable place to reduce pathfinder time.

// FALL THROUGH
[[fallthrough]];
case MOVE_TO_TARGET:
case MOVE_TO_TARGET + AUTO_TARGETING:
case MOVE_TO_ATTACKPOS:
Expand Down
2 changes: 1 addition & 1 deletion src/action/action_resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -989,9 +989,9 @@ int COrder_Resource::StopGathering(CUnit &unit)
int COrder_Resource::MoveToDepot(CUnit &unit)
{
const ResourceInfo &resinfo = *unit.Type->ResInfo[this->CurrentResource];
Assert(this->GetGoal());
CUnit &goal = *this->GetGoal();
CPlayer &player = *unit.Player;
Assert(&goal);

switch (DoActionMove(unit)) { // reached end-point?
case PF_UNREACHABLE:
Expand Down
28 changes: 10 additions & 18 deletions src/ai/ai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@

int AiSleepCycles; /// Ai sleeps # cycles

std::vector<CAiType *> AiTypes; /// List of all AI types.
std::vector<std::unique_ptr<CAiType>> AiTypes; /// List of all AI types.
AiHelper AiHelpers; /// AI helper variables

PlayerAi *AiPlayer; /// Current AI player
Expand Down Expand Up @@ -439,22 +439,17 @@ void AiInit(CPlayer &player)
LogPrint("AI: Look at the DefineAi() documentation.\n");
Exit(0);
}
size_t i;
CAiType *ait = nullptr;

for (i = 0; i < AiTypes.size(); ++i) {
ait = AiTypes[i];
if (!ait->Race.empty() && ait->Race != PlayerRaces.Name[player.Race]) {
continue;
}
if (!player.AiName.empty() && ait->Name != player.AiName) {
continue;
}
break;
}
if (i == AiTypes.size()) {
auto it = ranges::find_if(AiTypes, [&](const auto& ait){
return (ait->Race.empty() || ait->Race == PlayerRaces.Name[player.Race])
&& (player.AiName.empty() || ait->Name == player.AiName);
});
CAiType *ait = nullptr;
if (it == AiTypes.end()) {
LogPrint("AI: Found no matching ai scripts at all, defaulting to the first AI!\n");
ait = AiTypes[0];
ait = AiTypes[0].get();
} else {
ait = it->get();
}
if (player.AiName.empty()) {
LogPrint("AI: not found!!!!!!!!!!\n");
Expand Down Expand Up @@ -505,9 +500,6 @@ void FreeAi()
CleanAi();

// Free AiTypes.
for (CAiType *aitype : AiTypes) {
delete aitype;
}
AiTypes.clear();

// Free AiHelpers.
Expand Down
3 changes: 2 additions & 1 deletion src/ai/ai_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
----------------------------------------------------------------------------*/

#include <array>
#include <memory>
#include <optional>
#include <vector>

Expand Down Expand Up @@ -378,7 +379,7 @@ class AiHelper
-- Variables
----------------------------------------------------------------------------*/

extern std::vector<CAiType *> AiTypes; /// List of all AI types
extern std::vector<std::unique_ptr<CAiType>> AiTypes; /// List of all AI types
extern AiHelper AiHelpers; /// AI helper variables

extern int UnitTypeEquivs[UnitTypeMax + 1]; /// equivalence between unittypes
Expand Down
29 changes: 14 additions & 15 deletions src/ai/ai_plan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,31 +430,31 @@ bool AiForce::PlanAttack()
return false;
}

static bool ChooseRandomUnexploredPositionNear(const Vec2i &center, Vec2i *pos)
static std::optional<Vec2i> ChooseRandomUnexploredPositionNear(const Vec2i &center)
{
Assert(pos != nullptr);

int ray = 3;
const int maxTryCount = 8;
for (int i = 0; i != maxTryCount; ++i) {
pos->x = center.x + SyncRand() % (2 * ray + 1) - ray;
pos->y = center.y + SyncRand() % (2 * ray + 1) - ray;
Vec2i pos;
pos.x = center.x + SyncRand() % (2 * ray + 1) - ray;
pos.y = center.y + SyncRand() % (2 * ray + 1) - ray;

if (Map.Info.IsPointOnMap(*pos)
&& Map.Field(*pos)->playerInfo.IsExplored(*AiPlayer->Player) == false) {
return true;
if (Map.Info.IsPointOnMap(pos)
&& Map.Field(pos)->playerInfo.IsExplored(*AiPlayer->Player) == false) {
return pos;
}
ray = 3 * ray / 2;
}
return false;
return std::nullopt;
}

static CUnit *GetBestExplorer(const AiExplorationRequest &request, Vec2i *pos)
static std::pair<CUnit *, Vec2i> GetBestExplorer(const AiExplorationRequest &request)
{
// Choose a target, "near"
const Vec2i &center = request.pos;
if (ChooseRandomUnexploredPositionNear(center, pos) == false) {
return nullptr;
auto pos = ChooseRandomUnexploredPositionNear(center);
if (!pos) {
return {nullptr, {-1, -1}};
}
// We have an unexplored tile in sight (pos)

Expand Down Expand Up @@ -495,7 +495,7 @@ static CUnit *GetBestExplorer(const AiExplorationRequest &request, Vec2i *pos)
bestunit = unit;
}
}
return bestunit;
return {bestunit, *pos};
}


Expand All @@ -517,8 +517,7 @@ void AiSendExplorers()
const int requestid = SyncRand() % requestcount;
const AiExplorationRequest &request = AiPlayer->FirstExplorationRequest[requestid];

Vec2i pos;
CUnit *bestunit = GetBestExplorer(request, &pos);
const auto& [bestunit, pos] = GetBestExplorer(request);
if (bestunit != nullptr) {
CommandMove(*bestunit, pos, FlushCommands);
AiPlayer->LastExplorationGameCycle = GameCycle;
Expand Down
Loading

0 comments on commit a2ddb8f

Please sign in to comment.