clean up AI script

alut-include-path
Maikel de Vries 2017-01-19 19:55:50 +01:00
parent 80c07d34e4
commit 3fb539522d
4 changed files with 587 additions and 352 deletions

View File

@ -30,4 +30,27 @@ private func GetTargetYDir(object target, int prec)
{
var moving_target = GetTargetMovementObject(target);
return moving_target->GetYDir(prec);
}
}
// Helper function: Convert target coordinates and projectile out speed to desired shooting angle. Because
// http://en.wikipedia.org/wiki/Trajectory_of_a_projectile says so. No SimFlight checks to check upper
// angle (as that is really easy to evade anyway) just always shoot the lower angle if sight is free.
private func GetBallisticAngle(int dx, int dy, int v, int max_angle)
{
// The variable v is in 1/10 pix/frame.
// The variable gravity is in 1/100 pix/frame^2.
var g = GetGravity();
// Correct vertical distance to account for integration error. Engine adds gravity after movement, so
// targets fly higher than they should. Thus, we aim lower. we don't know the travel time yet, so we
// assume some 90% of v is horizontal (it's ~2px correction for 200px shooting distance).
dy += Abs(dx) * g * 10 / (v * 180);
// The variable q is in 1/10000 (pix/frame)^4.
var q = v**4 - g * (g * dx * dx - 2 * dy * v * v); // dy is negative up
if (q < 0)
return nil; // Out of range.
var a = (Angle(0, 0, g * dx, Sqrt(q) - v * v, 10) + 1800) % 3600 - 1800;
// Check bounds.
if (!Inside(a, -10 * max_angle, 10 * max_angle))
return nil;
return a;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
[DefCore]
id=AI_Vehicles
Version=6,0
Category=C4D_StaticBack
HideInCreator=true

View File

@ -0,0 +1,102 @@
/**
AI Vehicles
Functionality that helps the AI use vehicles.
@author Sven2, Maikel
*/
/*-- General Vehicle --*/
private func ExecuteVehicle(effect fx)
{
// Do we have a vehicle?
if (!fx.vehicle)
return false;
// Use the catapult.
if (fx.vehicle->GetID() == Catapult)
return ExecuteCatapult(fx);
// Don't know how to use this vehicle, so reset it.
fx.vehicle = nil;
return false;
}
private func CheckVehicleAmmo(effect fx, object vehicle)
{
// Check for specific vehicle.
if (vehicle->GetID() == Catapult)
{
if (CheckCatapultAmmo(fx, vehicle))
return true;
}
// Vehicle out of ammo: Can't really be refilled. Stop using that weapon.
fx.vehicle = nil;
this->ObjectCommand("UnGrab");
return false;
}
/*-- Catapult --*/
private func ExecuteCatapult(effect fx)
{
// Still pushing it?
if (GetProcedure() != "PUSH" || GetActionTarget() != fx.vehicle)
{
if (!GetCommand() || !Random(4))
SetCommand("Grab", fx.vehicle);
return true;
}
// Target still in guard range?
if (!fx.ai->CheckTargetInGuardRange(fx))
return false;
// Turn in correct direction.
var x = GetX(), y = GetY(), tx = fx.target->GetX(), ty = fx.target->GetY() - 4;
if (tx > x && !fx.vehicle.dir)
{
fx.vehicle->ControlRight(this);
return true;
}
if (tx < x && fx.vehicle.dir)
{
fx.vehicle->ControlLeft(this);
return true;
}
// Make sure we're aiming.
if (!fx.aim_weapon)
{
if (!fx.vehicle->~ControlUseStart(this))
return false;
fx.aim_weapon = fx.vehicle;
fx.aim_time = fx.time;
return true;
}
// Update catapult animation.
fx.vehicle->~ControlUseHolding(this, tx - x, ty - y);
// Determine power needed to hit target.
var dx = tx - x, dy = ty - y + 20;
var power = Sqrt((GetGravity() * dx * dx) / Max(Abs(dx) + dy, 1));
var dt = dx * 10 / power;
tx += fx.ai->GetTargetXDir(fx.target, dt);
ty += fx.ai->GetTargetYDir(fx.target, dt);
if (!fx.target->GetContact(-1))
dy += GetGravity() * dt * dt / 200;
power = Sqrt((GetGravity() * dx * dx) / Max(Abs(dx) + dy, 1));
power = power + Random(11) - 5;
// Limits imposed by catapult.
fx.projectile_speed = power = BoundBy(power, 20, 100);
// Can shoot now?
if (fx.time >= fx.aim_time + fx.aim_wait && PathFree(x, y - 20, x + dx, y + dy - 20))
{
fx.aim_weapon->~DoFire(this, power, 0);
fx.aim_weapon = nil;
}
return true;
}
private func CheckCatapultAmmo(effect fx, object vehicle)
{
return vehicle->ContentsCount() > 0;
}