本文整理汇总了C++中Ship::Position方法的典型用法代码示例。如果您正苦于以下问题:C++ Ship::Position方法的具体用法?C++ Ship::Position怎么用?C++ Ship::Position使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Ship
的用法示例。
在下文中一共展示了Ship::Position方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: TargetAim
// Get a vector giving the direction this ship should aim in in order to do
// maximum damaged to a target at the given position with its non-turret,
// non-homing weapons. If the ship has no non-homing weapons, this just
// returns the direction to the target.
Point AI::TargetAim(const Ship &ship)
{
Point result;
shared_ptr<const Ship> target = ship.GetTargetShip();
if(!target)
return result;
for(const Armament::Weapon &weapon : ship.Weapons())
{
const Outfit *outfit = weapon.GetOutfit();
if(!outfit || weapon.IsHoming() || weapon.IsTurret())
continue;
Point start = ship.Position() + ship.Facing().Rotate(weapon.GetPoint());
Point p = target->Position() - start + ship.GetPersonality().Confusion();
Point v = target->Velocity() - ship.Velocity();
double steps = Armament::RendevousTime(p, v, outfit->Velocity());
if(!(steps == steps))
continue;
steps = min(steps, outfit->TotalLifetime());
p += steps * v;
double damage = outfit->ShieldDamage() + outfit->HullDamage();
result += p.Unit() * damage;
}
if(!result)
return target->Position() - ship.Position();
return result;
}
示例2: CircleAround
void AI::CircleAround(Ship &ship, Command &command, const Ship &target)
{
// This is not the behavior I want, but it's reasonable.
Point direction = target.Position() - ship.Position();
command.SetTurn(TurnToward(ship, direction));
if(ship.Facing().Unit().Dot(direction) >= 0. && direction.Length() > 200.)
command |= Command::FORWARD;
}
示例3: DoScatter
void AI::DoScatter(Ship &ship, Command &command, const list<shared_ptr<Ship>> &ships)
{
if(!command.Has(Command::FORWARD))
return;
double turnRate = ship.TurnRate();
double acceleration = ship.Acceleration();
for(const shared_ptr<Ship> &other : ships)
{
if(other.get() == &ship)
continue;
// Check for any ships that have nearly the same movement profile as
// this ship and are in nearly the same location.
Point offset = other->Position() - ship.Position();
if(offset.LengthSquared() > 400.)
continue;
if(fabs(other->TurnRate() / turnRate - 1.) > .05)
continue;
if(fabs(other->Acceleration() / acceleration - 1.) > .05)
continue;
// Move away from this ship. What side of me is it on?
command.SetTurn(offset.Cross(ship.Facing().Unit()) > 0. ? 1. : -1.);
return;
}
}
示例4:
// Fire an anti-missile. Returns true if the missile should be killed.
bool Armament::Weapon::FireAntiMissile(Ship &ship, const Projectile &projectile, list<Effect> &effects)
{
int strength = outfit->AntiMissile();
if(!strength)
return false;
double range = outfit->Velocity();
// Check if the missile is in range.
Point start = ship.Position() + ship.Facing().Rotate(point);
Point offset = projectile.Position() - start;
if(offset.Length() > range)
return false;
// Figure out where the effect should be placed. Anti-missiles do not create
// projectiles; they just create a blast animation.
start += (.5 * range) * offset.Unit();
Angle aim = TO_DEG * atan2(offset.X(), -offset.Y());
for(const auto &eit : outfit->HitEffects())
for(int i = 0; i < eit.second; ++i)
{
effects.push_back(*eit.first);
effects.back().Place(start, ship.Velocity(), aim);
}
Fire(ship);
return (Random::Int(strength) > Random::Int(projectile.MissileStrength()));
}
示例5: DoCloak
void AI::DoCloak(Ship &ship, Command &command, const list<shared_ptr<Ship>> &ships)
{
if(ship.Attributes().Get("cloak"))
{
// Never cloak if it will cause you to be stranded.
if(ship.Attributes().Get("cloaking fuel") && !ship.Attributes().Get("ramscoop"))
{
double fuel = ship.Fuel() * ship.Attributes().Get("fuel capacity");
fuel -= ship.Attributes().Get("cloaking fuel");
if(fuel < ship.JumpFuel())
return;
}
// Otherwise, always cloak if you are in imminent danger.
static const double MAX_RANGE = 10000.;
double nearestEnemy = MAX_RANGE;
for(const auto &other : ships)
if(other->GetSystem() == ship.GetSystem() && other->IsTargetable() &&
other->GetGovernment()->IsEnemy(ship.GetGovernment()))
nearestEnemy = min(nearestEnemy,
ship.Position().Distance(other->Position()));
if(ship.Hull() + ship.Shields() < 1. && nearestEnemy < 2000.)
command |= Command::CLOAK;
// Also cloak if there are no enemies nearby and cloaking does
// not cost you fuel.
if(nearestEnemy == MAX_RANGE && !ship.Attributes().Get("cloaking fuel"))
command |= Command::CLOAK;
}
}
示例6: InBlastRadius
// Check if the given ship is within this projectile's blast radius. (The
// projectile will not explode unless it is also within the trigger radius.)
bool Projectile::InBlastRadius(const Ship &ship, int step, double closestHit) const
{
// "Invisible" ships can be killed by weapons with blast radii.
Point offset = position + closestHit * velocity - ship.Position();
if(offset.Length() <= weapon->BlastRadius())
return true;
const Mask &mask = ship.GetMask(step);
return mask.WithinRange(offset, ship.Facing(), weapon->BlastRadius());
}
示例7: CheckCollision
// Check if this projectile collides with the given step, with the animation
// frame for the given step.
double Projectile::CheckCollision(const Ship &ship, int step) const
{
const Mask &mask = ship.GetMask(step);
Point offset = position - ship.Position();
double radius = weapon->TriggerRadius();
if(radius > 0. && mask.WithinRange(offset, angle, radius))
return 0.;
return mask.Collide(offset, velocity, ship.Facing());
}
示例8: Attack
void AI::Attack(Ship &ship, Command &command, const Ship &target)
{
Point d = target.Position() - ship.Position();
// First, figure out what your shortest-range weapon is.
double shortestRange = 4000.;
for(const Armament::Weapon &weapon : ship.Weapons())
{
const Outfit *outfit = weapon.GetOutfit();
if(outfit && !weapon.IsAntiMissile())
shortestRange = min(outfit->Range(), shortestRange);
}
// Deploy any fighters you are carrying.
if(!ship.IsYours())
command |= Command::DEPLOY;
// If this ship only has long-range weapons, it should keep its distance
// instead of trying to close with the target ship.
if(shortestRange > 1000. && d.Length() < .5 * shortestRange)
{
command.SetTurn(TurnToward(ship, -d));
if(ship.Facing().Unit().Dot(d) <= 0.)
command |= Command::FORWARD;
return;
}
// First of all, aim in the direction that will hit this target.
command.SetTurn(TurnToward(ship, TargetAim(ship)));
// Calculate this ship's "turning radius; that is, the smallest circle it
// can make while at full speed.
double stepsInFullTurn = 360. / ship.TurnRate();
double circumference = stepsInFullTurn * ship.Velocity().Length();
double diameter = max(200., circumference / PI);
// This isn't perfect, but it works well enough.
if((ship.Facing().Unit().Dot(d) >= 0. && d.Length() > diameter)
|| (ship.Velocity().Dot(d) < 0. && ship.Facing().Unit().Dot(d.Unit()) >= .9))
command |= Command::FORWARD;
}
示例9: RendezvousTime
// Fire this weapon. If it is a turret, it automatically points toward
// the given ship's target. If the weapon requires ammunition, it will
// be subtracted from the given ship.
void Armament::Weapon::Fire(Ship &ship, list<Projectile> &projectiles, list<Effect> &effects)
{
// Since this is only called internally by Armament (no one else has non-
// const access), assume Armament checked that this is a valid call.
Angle aim = ship.Facing();
// Get projectiles to start at the right position. They are drawn at an
// offset of (.5 * velocity) and that velocity includes the velocity of the
// ship that fired them.
Point start = ship.Position() + aim.Rotate(point) - .5 * ship.Velocity();
shared_ptr<const Ship> target = ship.GetTargetShip();
// If you are boarding your target, do not fire on it.
if(ship.IsBoarding() || ship.Commands().Has(Command::BOARD))
target.reset();
if(!isTurret || !target || target->GetSystem() != ship.GetSystem())
aim += angle;
else
{
Point p = target->Position() - start + ship.GetPersonality().Confusion();
Point v = target->Velocity() - ship.Velocity();
double steps = RendezvousTime(p, v, outfit->Velocity());
// Special case: RendezvousTime() may return NaN. But in that case, this
// comparison will return false.
if(!(steps < outfit->TotalLifetime()))
steps = outfit->TotalLifetime();
p += steps * v;
aim = Angle(TO_DEG * atan2(p.X(), -p.Y()));
}
projectiles.emplace_back(ship, start, aim, outfit);
if(outfit->WeaponSound())
Audio::Play(outfit->WeaponSound(), start);
double force = outfit->FiringForce();
if(force)
ship.ApplyForce(aim.Unit() * -force);
for(const auto &eit : outfit->FireEffects())
for(int i = 0; i < eit.second; ++i)
{
effects.push_back(*eit.first);
effects.back().Place(start, ship.Velocity(), aim);
}
Fire(ship);
}
示例10: AddSprites
void Engine::AddSprites(const Ship &ship)
{
bool hasFighters = ship.PositionFighters();
double cloak = ship.Cloaking();
bool drawCloaked = (cloak && ship.GetGovernment()->IsPlayer());
if(ship.IsThrusting())
for(const Point &point : ship.EnginePoints())
{
Point pos = ship.Facing().Rotate(point) * ship.Zoom() + ship.Position();
// If multiple engines with the same flare are installed, draw up to
// three copies of the flare sprite.
for(const auto &it : ship.Attributes().FlareSprites())
for(int i = 0; i < it.second && i < 3; ++i)
{
Body sprite(it.first, pos, ship.Velocity(), ship.Facing());
draw[calcTickTock].Add(sprite, cloak);
}
}
if(hasFighters)
for(const Ship::Bay &bay : ship.Bays())
if(bay.side == Ship::Bay::UNDER && bay.ship)
{
if(drawCloaked)
draw[calcTickTock].AddSwizzled(*bay.ship, 7);
draw[calcTickTock].Add(*bay.ship, cloak);
}
if(drawCloaked)
draw[calcTickTock].AddSwizzled(ship, 7);
draw[calcTickTock].Add(ship, cloak);
if(hasFighters)
for(const Ship::Bay &bay : ship.Bays())
if(bay.side == Ship::Bay::OVER && bay.ship)
{
if(drawCloaked)
draw[calcTickTock].AddSwizzled(*bay.ship, 7);
draw[calcTickTock].Add(*bay.ship, cloak);
}
}
示例11: MoveTo
bool AI::MoveTo(Ship &ship, Command &command, const Point &target, double radius, double slow)
{
const Point &position = ship.Position();
const Point &velocity = ship.Velocity();
const Angle &angle = ship.Facing();
Point distance = target - position;
double speed = velocity.Length();
bool isClose = (distance.Length() < radius);
if(isClose && speed < slow)
return true;
distance = target - StoppingPoint(ship);
bool isFacing = (distance.Unit().Dot(angle.Unit()) > .8);
if(!isClose || !isFacing)
command.SetTurn(TurnToward(ship, distance));
if(isFacing)
command |= Command::FORWARD;
return false;
}
示例12: StoppingPoint
Point AI::StoppingPoint(const Ship &ship)
{
const Point &position = ship.Position();
const Point &velocity = ship.Velocity();
const Angle &angle = ship.Facing();
double acceleration = ship.Acceleration();
double turnRate = ship.TurnRate();
// If I were to turn around and stop now, where would that put me?
double v = velocity.Length();
if(!v)
return position;
// This assumes you're facing exactly the wrong way.
double degreesToTurn = TO_DEG * acos(-velocity.Unit().Dot(angle.Unit()));
double stopDistance = v * (degreesToTurn / turnRate);
// Sum of: v + (v - a) + (v - 2a) + ... + 0.
// The number of terms will be v / a.
// The average term's value will be v / 2. So:
stopDistance += .5 * v * v / acceleration;
return position + stopDistance * velocity.Unit();
}
示例13: Refuel
void AI::Refuel(Ship &ship, Command &command)
{
if(ship.GetParent() && ship.GetParent()->GetTargetPlanet())
ship.SetTargetPlanet(ship.GetParent()->GetTargetPlanet());
else if(!ship.GetTargetPlanet())
{
double closest = numeric_limits<double>::infinity();
for(const StellarObject &object : ship.GetSystem()->Objects())
if(object.GetPlanet() && object.GetPlanet()->HasSpaceport())
{
double distance = ship.Position().Distance(object.Position());
if(distance < closest)
{
ship.SetTargetPlanet(&object);
closest = distance;
}
}
}
if(ship.GetTargetPlanet())
{
MoveToPlanet(ship, command);
command |= Command::LAND;
}
}
示例14: InBlastRadius
// Check if the given ship is within this projectile's blast radius. (The
// projectile will not explode unless it is also within the trigger radius.)
bool Projectile::InBlastRadius(const Ship &ship, int step) const
{
const Mask &mask = ship.GetSprite().GetMask(step);
return mask.WithinRange(position - ship.Position(), ship.Facing(), weapon->BlastRadius());
}
示例15: DoSurveillance
void AI::DoSurveillance(Ship &ship, Command &command, const list<shared_ptr<Ship>> &ships) const
{
const shared_ptr<Ship> &target = ship.GetTargetShip();
if(target && (!target->IsTargetable() || target->GetSystem() != ship.GetSystem()))
ship.SetTargetShip(shared_ptr<Ship>());
if(target && ship.GetGovernment()->IsEnemy(target->GetGovernment()))
{
MoveIndependent(ship, command);
command |= AutoFire(ship, ships);
return;
}
bool cargoScan = ship.Attributes().Get("cargo scan");
bool outfitScan = ship.Attributes().Get("outfit scan");
double atmosphereScan = ship.Attributes().Get("atmosphere scan");
bool jumpDrive = ship.Attributes().Get("jump drive");
bool hyperdrive = ship.Attributes().Get("hyperdrive");
// This function is only called for ships that are in the player's system.
if(ship.GetTargetSystem())
{
PrepareForHyperspace(ship, command);
command |= Command::JUMP;
command |= Command::DEPLOY;
}
else if(ship.GetTargetPlanet())
{
MoveToPlanet(ship, command);
double distance = ship.Position().Distance(ship.GetTargetPlanet()->Position());
if(distance < atmosphereScan && !Random::Int(100))
ship.SetTargetPlanet(nullptr);
else
command |= Command::LAND;
}
else if(ship.GetTargetShip() && ship.GetTargetShip()->IsTargetable()
&& ship.GetTargetShip()->GetSystem() == ship.GetSystem())
{
bool mustScanCargo = cargoScan && !Has(ship, target, ShipEvent::SCAN_CARGO);
bool mustScanOutfits = outfitScan && !Has(ship, target, ShipEvent::SCAN_OUTFITS);
bool isInSystem = (ship.GetSystem() == target->GetSystem() && !target->IsEnteringHyperspace());
if(!isInSystem || (!mustScanCargo && !mustScanOutfits))
ship.SetTargetShip(shared_ptr<Ship>());
else
{
CircleAround(ship, command, *target);
command |= Command::SCAN;
}
}
else
{
shared_ptr<Ship> newTarget = FindTarget(ship, ships);
if(newTarget && ship.GetGovernment()->IsEnemy(newTarget->GetGovernment()))
{
ship.SetTargetShip(newTarget);
return;
}
vector<shared_ptr<Ship>> targetShips;
vector<const StellarObject *> targetPlanets;
vector<const System *> targetSystems;
if(cargoScan || outfitScan)
for(const auto &it : ships)
if(it->GetGovernment() != ship.GetGovernment() && it->IsTargetable()
&& it->GetSystem() == ship.GetSystem())
{
if(Has(ship, it, ShipEvent::SCAN_CARGO) && Has(ship, it, ShipEvent::SCAN_OUTFITS))
continue;
targetShips.push_back(it);
}
if(atmosphereScan)
for(const StellarObject &object : ship.GetSystem()->Objects())
if(!object.IsStar() && object.Radius() < 130.)
targetPlanets.push_back(&object);
if(jumpDrive)
for(const System *link : ship.GetSystem()->Neighbors())
targetSystems.push_back(link);
else if(hyperdrive)
for(const System *link : ship.GetSystem()->Links())
targetSystems.push_back(link);
unsigned total = targetShips.size() + targetPlanets.size() + targetSystems.size();
if(!total)
return;
unsigned index = Random::Int(total);
if(index < targetShips.size())
ship.SetTargetShip(targetShips[index]);
else
{
index -= targetShips.size();
if(index < targetPlanets.size())
ship.SetTargetPlanet(targetPlanets[index]);
else
ship.SetTargetSystem(targetSystems[index - targetPlanets.size()]);
}
}
//.........这里部分代码省略.........