pioneer/src/Ship-AI.cpp

118 lines
2.6 KiB
C++

// Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
#include "EnumStrings.h"
#include "Frame.h"
#include "Pi.h"
#include "Planet.h"
#include "Player.h"
#include "Ship.h"
#include "ShipAICmd.h"
#include "Space.h"
#include "SpaceStation.h"
#include "libs.h"
#include "lua/LuaConstants.h"
#include "lua/LuaEvent.h"
#include "perlin.h"
#include "ship/Propulsion.h"
// returns true if command is complete
bool Ship::AITimeStep(float timeStep)
{
PROFILE_SCOPED()
// allow the launch thruster thing to happen
if (m_launchLockTimeout > 0.0) return false;
m_decelerating = false;
if (!m_curAICmd) {
if (this == Pi::player) return true;
// just in case the AI left it on
ClearThrusterState();
for (int i = 0; i < Guns::GUNMOUNT_MAX; i++)
SetGunState(i, 0);
return true;
}
if (m_curAICmd->TimeStepUpdate()) {
AIClearInstructions();
// ClearThrusterState(); // otherwise it does one timestep at 10k and gravity is fatal
LuaEvent::Queue("onAICompleted", this, EnumStrings::GetString("ShipAIError", AIMessage()));
return true;
} else
return false;
}
void Ship::AIClearInstructions()
{
if (!m_curAICmd) return;
delete m_curAICmd; // rely on destructor to kill children
m_curAICmd = 0;
m_decelerating = false; // don't adjust unless AI is running
}
void Ship::AIGetStatusText(char *str)
{
if (!m_curAICmd)
strcpy(str, "AI inactive");
else
m_curAICmd->GetStatusText(str);
}
void Ship::AIKamikaze(Body *target)
{
AIClearInstructions();
m_curAICmd = new AICmdKamikaze(this, target);
}
void Ship::AIKill(Ship *target)
{
AIClearInstructions();
SetFuelReserve((GetFuel() < 0.5) ? GetFuel() / 2 : 0.25);
m_curAICmd = new AICmdKill(this, target);
}
/*
void Ship::AIJourney(SystemBodyPath &dest)
{
AIClearInstructions();
// m_curAICmd = new AICmdJourney(this, dest);
}
*/
void Ship::AIFlyTo(Body *target)
{
AIClearInstructions();
SetFuelReserve((GetFuel() < 0.5) ? GetFuel() / 2 : 0.25);
if (target->IsType(ObjectType::SHIP)) { // test code
vector3d posoff(-1000.0, 0.0, 1000.0);
m_curAICmd = new AICmdFormation(this, static_cast<Ship *>(target), posoff);
} else
m_curAICmd = new AICmdFlyTo(this, target);
}
void Ship::AIDock(SpaceStation *target)
{
AIClearInstructions();
SetFuelReserve((GetFuel() < 0.5) ? GetFuel() / 2 : 0.25);
m_curAICmd = new AICmdDock(this, target);
}
void Ship::AIOrbit(Body *target, double alt)
{
AIClearInstructions();
SetFuelReserve((GetFuel() < 0.5) ? GetFuel() / 2 : 0.25);
m_curAICmd = new AICmdFlyAround(this, target, alt);
}
void Ship::AIHoldPosition()
{
AIClearInstructions();
m_curAICmd = new AICmdHoldPosition(this);
}