Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code(feat) fighter ai #17

Draft
wants to merge 27 commits into
base: experimental
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4913eca
(3000-mass)/3500 or 0.1 if over 3000
Zitchas Apr 20, 2023
2ee13f0
Change to < 2500
Zitchas Apr 20, 2023
b0ac3e1
white space removal
Zitchas Apr 20, 2023
7525f98
AttackRear
Zitchas Apr 20, 2023
e6a9003
whitespace
Zitchas Apr 20, 2023
814e622
More stylistic fixes
Zitchas Apr 21, 2023
1e5e437
style fixes
Zitchas Apr 21, 2023
487d12b
Fixing more whitespace
Zitchas Apr 21, 2023
112611c
command fixes and teseting swizzles
Zitchas Apr 21, 2023
560faaa
A few additional commands
Zitchas Apr 21, 2023
0936b18
Merge remote-tracking branch 'upstream/master' into code(feat)-FighterAI
Zitchas Apr 22, 2023
03368ca
Shortening the weaponsrange to match more typical fighter weapons
Zitchas Apr 22, 2023
b9c3a15
Whitespace errors
Zitchas Apr 22, 2023
e3be745
Merge branch 'experimental' into code(feat)-FighterAI
Zitchas Apr 22, 2023
617f55f
Merge remote-tracking branch 'upstream/master' into code(feat)-FighterAI
Zitchas Apr 23, 2023
2934c5a
Lateral circling basic
Zitchas Apr 23, 2023
37bd67f
Getting more of the intended behavior
Zitchas Apr 24, 2023
867a285
More to the rear
Zitchas Apr 24, 2023
845545c
A tighter "isbehind" value for closer to fully at the rear positioning
Zitchas Apr 27, 2023
39cf643
Merge branch 'experimental' into code(feat)-FighterAI
Zitchas Mar 31, 2024
7159a93
Merge branch 'experimental' into code(feat)-FighterAI
Zitchas Sep 12, 2024
34ab72b
Apply suggestions from code review by TheGiraffe3
Zitchas Sep 12, 2024
4fa77cb
Merge branch 'experimental' into code(feat)-FighterAI
Zitchas Sep 14, 2024
bf27d35
Merge branch 'experimental' into code(feat)-FighterAI
Zitchas Sep 30, 2024
b5d648a
Merge branch 'experimental' into code(feat)-FighterAI
Zitchas Oct 5, 2024
783c9c0
Merge branch 'experimental' into code(feat)-FighterAI
Zitchas Oct 8, 2024
1dad564
Merge branch 'experimental' into code(feat)-FighterAI
Zitchas Oct 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions data/gegno/gegno intro missions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ mission "First Contact: Gegno Vi"
goto watch
` (Try to help the alien defeat the beast.)`
label help
` You aim your sidearm at the beast, preparing to fire. Instead of digging back under the surface, the beast continues to thrash about where it is while the alien batters it down with their spear weapon. Making sure you don't accidentally hit them, you hold your breath and wait until the right moment comes, aiming for the creature's head. The flailing creature begins to gets closer, and your pulse begins to race. A gust of sand blasts directly towards you, and once it clears you fire your weapon. A laser shot flies directly into the face of the beast.`
` You aim your sidearm at the beast, preparing to fire. Instead of digging back under the surface, the beast continues to thrash about where it is while the alien batters it down with their spear weapon. Making sure you don't accidentally hit them, you hold your breath and wait until the right moment comes, aiming for the creature's head. The flailing creature begins to get closer, and your pulse begins to race. A gust of sand blasts directly towards you, and once it clears you fire your weapon. A laser shot flies directly into the face of the beast.`
` Much to your dismay, the shot almost immediately ricochets off of it. You watch as the massive monster tumbles over you, just barely leaping into the air above. The monster plunges into the earth behind you, and you fall to your back with the wind knocked out of you. You raise your sidearm once more. The creature explodes out of the ground with its gaping mouth pointed upward to the sky. With shaking hands, you take aim once again and pull the trigger.`
` A loud, cannon-like bang follows, but it most certainly did not come from your weapon. The beast before you falls downward in a cloud of black smoke, blasting sand and rubble everywhere with a thud. Once you come to your senses, you see the alien marching out of the creature's mouth.`
choice
Expand Down Expand Up @@ -283,7 +283,7 @@ mission "Giaru Gegno: Quarg Contact"
label "has met gegno"
action
set "gegno: met gegno before quarg"
`The visual of a complete Quarg Ringworld is drastically different than the Gegno homeworld you were on before. Such a pristine, advanced structure is quite the opposite of the disorderly industry of Gegno civilisation. The population of Quarg here must be at least around the trillions, many times more than the population of the Gegno homeworld. What's even more interesting is there are other aliens of the kind you met before here on the ring too. The Quarg must have some kind of relations with them, perhaps through trade, maintenance, or other services. Despite them being present, the Quarg seem to be very dismissive of them. However, a few of the aliens occasionally glance over at you with hints of interest.`
`The visual of a complete Quarg Ringworld is drastically different than the Gegno homeworld you were on before. Such a pristine, advanced structure is quite the opposite of the disorderly industry of Gegno civilization. The population of Quarg here must be at least around the trillions, many times more than the population of the Gegno homeworld. What's even more interesting is there are other aliens of the kind you met before here on the ring too. The Quarg must have some kind of relations with them, perhaps through trade, maintenance, or other services. Despite them being present, the Quarg seem to be very dismissive of them. However, a few of the aliens occasionally glance over at you with hints of interest.`
` Soon enough, a few Quarg start to rush towards you much faster than the others and begin a conversation between themselves. You aren't sure what language they are speaking, but judging by the tones and pronunciations, it sounds similar to the one you've heard the aliens speaking before. After a moment or so, one of them motions you to follow them.`

label "walking"
Expand Down
215 changes: 214 additions & 1 deletion source/AI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2046,6 +2046,39 @@ bool AI::MoveTo(Ship &ship, Command &command, const Point &targetPosition,



bool AI::MoveThrough(Ship &ship, Command &command, const Point &targetPosition,
const Point &targetVelocity, double radius, double slow)
{
const Point &position = ship.Position();
const Point &velocity = ship.Velocity();
const Angle &angle = ship.Facing();
Point dp = targetPosition - position;
Point dv = targetVelocity - velocity;

double speed = dv.Length();

bool isClose = (dp.Length() < radius);
if(isClose && speed < slow)
return true;

bool shouldReverse = false;
// dp = targetPosition - StoppingPoint(ship, targetVelocity, shouldReverse);
bool isFacing = (dp.Unit().Dot(angle.Unit()) > .95);
if(!isClose || (!isFacing && !shouldReverse))
command.SetTurn(TurnToward(ship, dp));
if(isFacing)
command.SetThrust(1.);
else if(shouldReverse)
{
command.SetTurn(TurnToward(ship, velocity));
command.SetThrust(-1.);
}

return false;
}



bool AI::Stop(Ship &ship, Command &command, double maxSpeed, const Point direction)
{
const Point &velocity = ship.Velocity();
Expand Down Expand Up @@ -2113,6 +2146,180 @@ bool AI::Stop(Ship &ship, Command &command, double maxSpeed, const Point directi



void AI::StrikeThrough(Ship& ship, Command& command, const Ship& target)
{
int targetTurretRange = target.GetAICache().TurretRange();
int weaponsRange = 864; // need to calculate turn around distance v attacker gun range.
Point direction = ship.Position() - target.Position();
double length = direction.Length();

Point northUnit = target.Facing().Unit();
Point westUnit(northUnit.Y(), -northUnit.X());
Point eastUnit(-northUnit.Y(), northUnit.X());

// Point east = (target.Position() + eastUnit * targetTurretRange);
// Point west = (target.Position() + westUnit * targetTurretRange);

// Point frontAvoid = (direction.Unit().Cross(target.Facing().Unit()) < 0. ? west : east);
// Point velocity = ship.Velocity();
bool inFront = direction.Unit().Dot(target.Facing().Unit()) > .9;
bool isFacing = direction.Unit().Dot(ship.Facing().Unit()) < 0;
bool outerRadius = direction.Length() < targetTurretRange * 1.2; // should be max target gun & turget turret range
Zitchas marked this conversation as resolved.
Show resolved Hide resolved
// double speed = ship.MaxVelocity();

if(outerRadius)
{
// if(inFront && isFacing)
// {
// MoveThrough(ship, command, frontAvoid, target.Velocity(), 20., speed);
// if(command.Has(Command::FORWARD) && ShouldUseAfterburner(ship))
// command |= Command::AFTERBURNER;
// }
// else if(inFront)
// {
// command |= Command::FORWARD;
// }

if(inFront && isFacing)
{
command.SetTurn(TurnToward(ship, TargetAim(ship, target)));
command.SetLateralThrust(-1);
command.SetThrust(1.);
}
else if(length >= weaponsRange)
{
command.SetTurn(TurnToward(ship, TargetAim(ship, target)));
command.SetThrust(1.);
}
else if(length < weaponsRange && ship.Facing().Unit().Dot(ship.Velocity().Unit()) > .7)
{
command.SetTurn(TurnToward(ship, TargetAim(ship, target)));
command.SetThrust(1.);
}
else if(length < weaponsRange && ship.Facing().Unit().Dot(ship.Velocity().Unit()) < .7)
{
command.SetTurn(TurnToward(ship, TargetAim(ship, target)));
}
else if(length < weaponsRange)
{
command.SetThrust(1.);
}
}
else
{
command.SetTurn(TurnToward(ship, TargetAim(ship, target)));
command.SetThrust(1.);
}
}



void AI::AttackRear(Ship& ship, Command& command, const Ship& target)
{
int weaponsRange = 370; // attacker weapon range this will be passed in eventually
int targetTurretRange = target.GetAICache().TurretRange();
Point offset = target.Position() - target.Facing().Unit() * weaponsRange;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Point offset = target.Position() - target.Facing().Unit() * weaponsRange;

Point direction = ship.Position() - target.Position();
Point d = (target.Position() + target.Velocity()) - (ship.Position() + ship.Velocity());

Point northUnit = target.Facing().Unit();
Point southUnit = -target.Facing().Unit();
Point westUnit(northUnit.Y(), -northUnit.X());
Point eastUnit(-northUnit.Y(), northUnit.X());

Point northWestUnit(northUnit.X() + westUnit.X(), northUnit.Y() + westUnit.Y());
Point northWest = (target.Position() + northWestUnit * targetTurretRange / 1.41);

Point northEastUnit(northUnit.X() + eastUnit.X(), northUnit.Y() + eastUnit.Y());
Point northEast = (target.Position() + northEastUnit * targetTurretRange / 1.41);

Point southWestUnit(southUnit.X() + westUnit.X(), southUnit.Y() + westUnit.Y());
Point southWest = (target.Position() + southWestUnit * targetTurretRange / 1.41);

Point southEastUnit(southUnit.X() + eastUnit.X(), southUnit.Y() + eastUnit.Y());
Point southEast = (target.Position() + southEastUnit * targetTurretRange / 1.41);

Point frontAvoid = (direction.Cross(ship.Facing().Unit()) < 0. ? northWest : northEast);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Point frontAvoid = (direction.Cross(ship.Facing().Unit()) < 0. ? northWest : northEast);

Point rearAvoid = (direction.Cross(target.Facing().Unit()) > 0. ? southWest : southEast);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Point rearAvoid = (direction.Cross(target.Facing().Unit()) > 0. ? southWest : southEast);


bool isBehind = direction.Unit().Dot(target.Facing().Unit()) < -.90;
bool justLeft = direction.Unit().Dot(target.Facing().Unit()) < -.8 && direction.Cross(target.Facing().Unit()) > 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool justLeft = direction.Unit().Dot(target.Facing().Unit()) < -.8 && direction.Cross(target.Facing().Unit()) > 0;

bool justRight = direction.Unit().Dot(target.Facing().Unit()) < -.8 && direction.Cross(target.Facing().Unit()) <= 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool justRight = direction.Unit().Dot(target.Facing().Unit()) < -.8 && direction.Cross(target.Facing().Unit()) <= 0;

bool inFront = direction.Unit().Dot(target.Facing().Unit()) > .75;

bool atSide = (!inFront && !isBehind);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
bool atSide = (!inFront && !isBehind);

bool inRange = direction.Length() < weaponsRange;
bool tooClose = direction.Length() < weaponsRange * .9;
bool outerRadius = direction.Length() < weaponsRange * 2;
double reverseSpeed = ship.MaxReverseVelocity();
double speed = ship.MaxVelocity();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
double speed = ship.MaxVelocity();



if (outerRadius)
{
if (!isBehind) // not behind the target
{
command.SetTurn(TurnToward(ship, TargetAim(ship, target))-0.2);
command.SetLateralThrust(TurnToward(ship, TargetAim(ship, target)));
if(!inRange) command.SetThrust(1.);
ship.SetSwizzle(27);
}
/*if (inFront)
{
MoveThrough(ship, command, frontAvoid, target.Velocity(), 20., speed);
ship.SetSwizzle(27);
}
else if(atSide)
{
MoveThrough(ship, command, rearAvoid, target.Velocity(), 20., speed);
ship.SetSwizzle(0);
}
else if(!isBehind) // not behind target
{
MoveTo(ship, command, offset, target.Velocity(), 80., 20);
ship.SetSwizzle(8);
}
else if(!inRange) // behind but too far away
{
command.SetTurn(TurnToward(ship, TargetAim(ship, target)));
command.SetThrust(1.);
ship.SetSwizzle(5);
}*/
else if(tooClose) // behind target but too close
{
if(reverseSpeed && target.Velocity().Dot(-d.Unit()) <= reverseSpeed)
{
command.SetTurn(TurnToward(ship, d)-0.2);
command.SetLateralThrust(-1.);
if(ship.Facing().Unit().Dot(d) >= 0.)
command.SetThrust(-1.);
}
else
{
command.SetTurn(TurnToward(ship, d) - 0.2);
command.SetLateralThrust(-1.);
}
ship.SetSwizzle(14);
}
else if(inRange) // behind target, in sweet spot.
{
// if(justRight) command.SetLateralThrust(-1.);
// else if(justLeft) command.SetLateralThrust(1.);
command.SetLateralThrust(-1.);
command.SetTurn(TurnToward(ship, TargetAim(ship, target)));
ship.SetSwizzle(3);
}
}
else
{
command.SetTurn(TurnToward(ship, TargetAim(ship, target)));
command.SetThrust(1.);
ship.SetSwizzle(26);
}
}



void AI::PrepareForHyperspace(Ship &ship, Command &command)
{
bool hasHyperdrive = ship.JumpNavigation().HasHyperdrive();
Expand Down Expand Up @@ -2316,7 +2523,10 @@ void AI::Attack(Ship &ship, Command &command, const Ship &target)
MoveToAttack(ship, command, target);
return;
}

if(target.TrueTurnRate() < ship.Acceleration() * 1.2)
{
AttackRear(ship, command, target);
}
// Check if this ship is fast enough to keep distance from target.
// Have a 10% minimum to avoid ships getting in a chase loop.
const bool isAbleToRun = target.MaxVelocity() * SAFETY_MULTIPLIER < ship.MaxVelocity();
Expand Down Expand Up @@ -2376,6 +2586,9 @@ void AI::Attack(Ship &ship, Command &command, const Ship &target)
}
}
// Fire if we can or move closer to use all weapons.
if(target.TrueTurnRate() < ship.Acceleration() * 1.2) AttackRear(ship, command, target);
else if(ship.Attributes().Get("rear")) StrikeThrough(ship, command, target);
else if(ship.Attributes().Get("strike")) StrikeThrough(ship, command, target);
else
if(weaponDistanceFromTarget < shortestRange * .75)
AimToAttack(ship, command, target);
Expand Down
4 changes: 4 additions & 0 deletions source/AI.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,13 @@ template <class Type>
static bool MoveToPlanet(Ship &ship, Command &command);
static bool MoveTo(Ship &ship, Command &command, const Point &targetPosition,
const Point &targetVelocity, double radius, double slow);
static bool MoveThrough(Ship &ship, Command &command, const Point &targetPosition,
const Point &targetVelocity, double radius, double slow);
static bool Stop(Ship &ship, Command &command, double maxSpeed = 0., const Point direction = Point());
static void PrepareForHyperspace(Ship &ship, Command &command);
static void CircleAround(Ship &ship, Command &command, const Body &target);
static void StrikeThrough(Ship &ship, Command &command, const Ship &target);
static void AttackRear(Ship &ship, Command &command, const Ship &target);
static void Swarm(Ship &ship, Command &command, const Body &target);
static void KeepStation(Ship &ship, Command &command, const Body &target);
static void Attack(Ship &ship, Command &command, const Ship &target);
Expand Down