games/pioneer: Updated for version 20240203.

Signed-off-by: Willy Sudiarto Raharjo <willysr@slackbuilds.org>
This commit is contained in:
Gene Carlson 2024-02-04 16:04:29 +09:00 committed by Willy Sudiarto Raharjo
parent 08be6aa64c
commit 9df1f6a269
No known key found for this signature in database
GPG Key ID: 3F617144D7238786
5 changed files with 26 additions and 510 deletions

View File

@ -8,8 +8,9 @@ try your hand at piracy, make your fortune trading between systems, or
do missions for the various factions fighting for power, freedom or
self-determination.
WARNING: If pioneer is already installed, uninstall it before compiling
or important game data may be missing and pioneer will fail to start.
To build with debugging support, use:
DEBUG="yes" ./pioneer.SlackBuild
OpenGL core profile version 3.1 or newer is a runtime dependency. To
determine what version of OpenGL is installed, use:
@ -17,11 +18,3 @@ determine what version of OpenGL is installed, use:
glxinfo | grep "core profile version"
lua52 is an optional dependency.
To build with debugging support, use:
DEBUG="yes" ./pioneer.SlackBuild
If building in a graphical session, a popup window about a failure to
write to a log file will likely appear and stop the build. This is
harmless, and the build proceeds normally after clicking "OK."

View File

@ -1,41 +0,0 @@
--- src/lua/LuaPushPull.h.orig 2023-09-18 14:23:51.229000000 +0900
+++ src/lua/LuaPushPull.h 2023-09-18 14:32:10.777000000 +0900
@@ -12,10 +12,10 @@
#include <tuple>
inline void pi_lua_generic_push(lua_State *l, bool value) { lua_pushboolean(l, value); }
-inline void pi_lua_generic_push(lua_State *l, int value) { lua_pushinteger(l, value); }
+inline void pi_lua_generic_push(lua_State *l, int32_t value) { lua_pushinteger(l, value); }
inline void pi_lua_generic_push(lua_State *l, int64_t value) { lua_pushinteger(l, value); }
-inline void pi_lua_generic_push(lua_State *l, unsigned int value) { lua_pushinteger(l, value); }
-inline void pi_lua_generic_push(lua_State *l, size_t value) { lua_pushinteger(l, value); }
+inline void pi_lua_generic_push(lua_State *l, uint32_t value) { lua_pushinteger(l, value); }
+inline void pi_lua_generic_push(lua_State *l, uint64_t value) { lua_pushinteger(l, value); }
inline void pi_lua_generic_push(lua_State *l, double value) { lua_pushnumber(l, value); }
inline void pi_lua_generic_push(lua_State *l, const char *value) { lua_pushstring(l, value); }
inline void pi_lua_generic_push(lua_State *l, const std::string &value)
@@ -29,10 +29,10 @@
inline void pi_lua_generic_push(lua_State *l, const std::nullptr_t &value) { lua_pushnil(l); }
inline void pi_lua_generic_pull(lua_State *l, int index, bool &out) { out = lua_toboolean(l, index); }
-inline void pi_lua_generic_pull(lua_State *l, int index, int &out) { out = luaL_checkinteger(l, index); }
+inline void pi_lua_generic_pull(lua_State *l, int index, int32_t &out) { out = luaL_checkinteger(l, index); }
inline void pi_lua_generic_pull(lua_State *l, int index, int64_t &out) { out = luaL_checkinteger(l, index); }
-inline void pi_lua_generic_pull(lua_State *l, int index, unsigned int &out) { out = luaL_checkunsigned(l, index); }
-inline void pi_lua_generic_pull(lua_State *l, int index, size_t &out) { out = luaL_checkunsigned(l, index); }
+inline void pi_lua_generic_pull(lua_State *l, int index, uint32_t &out) { out = luaL_checkinteger(l, index); }
+inline void pi_lua_generic_pull(lua_State *l, int index, uint64_t &out) { out = luaL_checkinteger(l, index); }
inline void pi_lua_generic_pull(lua_State *l, int index, float &out) { out = luaL_checknumber(l, index); }
inline void pi_lua_generic_pull(lua_State *l, int index, double &out) { out = luaL_checknumber(l, index); }
inline void pi_lua_generic_pull(lua_State *l, int index, const char *&out) { out = luaL_checkstring(l, index); }
--- src/lua/LuaShip.cpp.orig 2023-09-18 14:42:08.048000000 +0900
+++ src/lua/LuaShip.cpp 2023-09-18 14:42:20.781000000 +0900
@@ -19,7 +19,7 @@
#include "SpaceStation.h"
#include "ship/PlayerShipController.h"
#include "ship/PrecalcPath.h"
-#include "src/lua.h"
+#include "lua.h"
/*
* Class: Ship

View File

@ -3,7 +3,7 @@
# Slackware build script for pioneer
# Copyright 2015-2019 Hunter Sezen California, USA
# Copyright 2023 K. Eugene Carlson Tsukuba, JP
# Copyright 2023-2024 K. Eugene Carlson Tsukuba, JP
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
@ -26,7 +26,7 @@
cd $(dirname $0) ; CWD=$(pwd)
PRGNAM=pioneer
VERSION=${VERSION:-20230203}
VERSION=${VERSION:-20240203}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
PKGTYPE=${PKGTYPE:-tgz}
@ -94,17 +94,19 @@ pkg-config --exists glew && GLEW=ON
# as cmake seems to search for them in order.
pkg-config --exists lua5.2 && ! pkg-config --exists lua && LUA=ON
# Fix 32-bit build (PR 5538) and system lua build (PR 5526).
patch -p0 < $CWD/fix-build.patch
# Post-release autopilot fixes (PR 5481, 5551).
patch -p1 < $CWD/ship-ai.patch
# 20210214 bkw: prevent the build from writing to /root/, without
# breaking ccache if it's in use.
mkdir -p tmphome
mkdir -p tmphome/.local/share/pioneer
export CCACHE_DIR=${CCACHE_DIR:-$HOME/.ccache}
export HOME=$( pwd )/tmphome
OSNAME="$(awk -F= '/^ID=/{print $2}' /etc/os-release)"
OSVER="$(awk -F= '/^VERSION_ID=/{print $2}' /etc/os-release)"
OSCODENAME="$(awk -F= '/^VERSION_CODENAME=/{print $2}' /etc/os-release)"
# This version information string can be included when reporting issues
# upstream.
INFOSTRING="$OSNAME-$OSVER-$OSCODENAME-$PRGNAM-$VERSION-$ARCH-$BUILD$TAG"
mkdir -p build
cd build
cmake \
@ -112,9 +114,10 @@ cd build
-DCMAKE_CXX_FLAGS:STRING="$SLKCFLAGS" \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_INSTALL_BINDIR=games \
-DPIONEER_DATA_DIR=/usr/share/games/$PRGNAM \
-DCMAKE_INSTALL_DATADIR=/usr/share/games \
-DUSE_SYSTEM_LIBGLEW=$GLEW \
-DUSE_SYSTEM_LIBLUA=$LUA \
-DPROJECT_VERSION_INFO="$INFOSTRING" \
-DCMAKE_BUILD_TYPE=$RELEASE ..
make
make install DESTDIR=$PKG
@ -126,6 +129,14 @@ if [ "$DEBUG" = 0 ]; then
grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
fi
# Clean up the data directory, put icons and files where they are
# supposed to be and install an SVG icon.
rm -rf $PKG/usr/share/games/$PRGNAM/{licenses,*txt,*md}
mv $PKG/usr/share/games/{icons,applications,metainfo} $PKG/usr/share
mkdir -p $PKG/usr/share/icons/hicolor/scalable/apps
install -m 0644 application-icon/badge-full.svg \
$PKG/usr/share/icons/hicolor/scalable/apps/net.pioneerspacesim.Pioneer.svg
mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION
cp -a licenses *.txt README.md $PKG/usr/doc/$PRGNAM-$VERSION
rm -f $PKG/usr/doc/$PRGNAM-$VERSION/{CMakeLists,SAVEBUMP}.txt

View File

@ -1,8 +1,8 @@
PRGNAM="pioneer"
VERSION="20230203"
VERSION="20240203"
HOMEPAGE="https://pioneerspacesim.net/"
DOWNLOAD="https://github.com/pioneerspacesim/pioneer/archive/20230203/pioneer-20230203.tar.gz"
MD5SUM="15f3e74303a098bb198f15c8674c43d4"
DOWNLOAD="https://github.com/pioneerspacesim/pioneer/archive/20240203/pioneer-20240203.tar.gz"
MD5SUM="0404c477b33d428f7b48686c71569b52"
DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
REQUIRES="assimp"

View File

@ -1,447 +0,0 @@
--- pioneer-20230203.orig/src/ShipAICmd.cpp 2023-07-19 23:54:00.245824921 +0900
+++ pioneer-20230203/src/ShipAICmd.cpp 2023-07-19 23:54:15.061778840 +0900
@@ -731,7 +731,7 @@
//2 - unsafe escape from effect radius
//3 - unsafe entry to effect radius
//4 - probable path intercept
-int CheckCollision(DynamicBody *dBody, const vector3d &pathdir, double pathdist, const vector3d &tpos, double endvel, double r)
+int CheckCollision(DynamicBody *dBody, const vector3d &pathdir, double pathdist, double tlen, double endvel, double r)
{
Propulsion *prop = dBody->GetComponent<Propulsion>();
if (!prop) // This body doesn't have any propulsion to avoid collision
@@ -742,24 +742,35 @@
Body *body = Frame::GetFrame(dBody->GetFrame())->GetBody();
if (!body) return 0;
vector3d spos = dBody->GetPosition();
- double tlen = tpos.Length(), slen = spos.Length();
+ double slen = spos.Length();
double fr = MaxFeatureRad(body);
- // if target inside, check if direct entry is safe (30 degree)
+ // find closest point to obstructor
+ double distToTangent = -spos.Dot(pathdir);
+
+ // if target inside, check if direct entry is safe
+ // no 30 deg aproach anymore as after FlyAround this couses overshoot
if (tlen < r) {
- double af = (tlen > fr) ? 0.5 * (1 - (tlen - fr) / (r - fr)) : 0.5;
- if (pathdir.Dot(tpos) > -af * tlen)
- if (slen < fr)
+
+ vector3d tangent = spos + distToTangent * pathdir;
+
+ //The target is obscured
+ if(distToTangent < pathdist && tangent.LengthSqr() < fr * fr) {
+ if (slen < fr )
return 1;
- else
- return 3;
- else
- return 0;
+
+ return 3;
+ }
+
+ //The speed checks are now done in the CheckSuicide function
+ return 0;
}
- // if ship inside, check for max feature height and direct escape (30 degree)
+ // if ship inside, target outside, check for max feature height and direct escape (30 degree)
if (slen < r) {
- if (slen < fr) return 1;
+ if (slen < fr)
+ return 1;
+
double af = (slen > fr) ? 0.5 * (1 - (slen - fr) / (r - fr)) : 0.5;
if (pathdir.Dot(spos) < af * slen)
return 2;
@@ -768,25 +779,15 @@
}
// now for the intercept calc
- // find closest point to obstructor
- double tanlen = -spos.Dot(pathdir);
- if (tanlen < 0 || tanlen > pathdist) return 0; // closest point outside path
+ if (distToTangent < 0 || distToTangent > pathdist) return 0; // closest point to obstructor outside path
+
+
+ vector3d sidePos = spos - pathdir * spos.Dot(pathdir);
+
+ //Check if the path goes through the obstructor effective radious
+ if(sidePos.LengthSqr() < r * r) return 4;
- vector3d perpdir = (tanlen * pathdir + spos).Normalized();
- double perpspeed = dBody->GetVelocity().Dot(perpdir);
- double parspeed = dBody->GetVelocity().Dot(pathdir);
- if (parspeed < 0) parspeed = 0; // shouldn't break any important case
- if (perpspeed > 0) perpspeed = 0; // prevent attempts to speculatively fly through planets
-
- // find time that dBody will pass through that point
- // get velocity as if accelerating from start or end, pick smallest
- double ivelsqr = endvel * endvel + 2 * prop->GetAccelFwd() * (pathdist - tanlen); // could put endvel in here
- double fvelsqr = parspeed * parspeed + 2 * prop->GetAccelFwd() * tanlen;
- double tanspeed = sqrt(ivelsqr < fvelsqr ? ivelsqr : fvelsqr);
- double time = tanlen / (0.5 * (parspeed + tanspeed)); // actually correct?
- double dist = spos.Dot(perpdir) + perpspeed * time; // spos.perpdir should be positive
- if (dist < r) return 4;
return 0;
}
@@ -828,20 +829,57 @@
return true;
}
+
// check for collision course with frame body
-// tandir is normal vector from planet to target pos or dir
-static bool CheckSuicide(DynamicBody *dBody, const vector3d &tandir)
+//#define DEBUG_CHECK_SUICIDE
+static bool CheckSuicide(DynamicBody *dBody, const vector3d &obspos, double obsMass, double safeAlt, double targetAlt, bool recovering)
{
- Body *body = Frame::GetFrame(dBody->GetFrame())->GetBody();
if (!dBody->HasComponent<Propulsion>()) return false;
Propulsion *prop = dBody->GetComponent<Propulsion>();
assert(prop != nullptr);
- if (!body || !body->IsType(ObjectType::TERRAINBODY)) return false;
- double vel = dBody->GetVelocity().Dot(tandir); // vel towards is negative
- double dist = dBody->GetPosition().Length() - MaxFeatureRad(body);
- if (vel < -1.0 && vel * vel > 2.0 * prop->GetAccelMin() * dist)
+ double obsDist = obspos.Length();
+
+ //sanity check
+ if(obsDist > 100 * safeAlt)
+ return false;
+
+ vector3d velDir = dBody->GetVelocity().NormalizedSafe();
+ double tangDist = obspos.Dot(velDir);
+
+ //ship passed the planet
+ if(tangDist < 0) return false;
+
+ double tangLenSqr = (obspos - velDir * tangDist).LengthSqr();
+
+ //or pitched speed vector above the safty horizon
+ if(tangLenSqr > safeAlt * safeAlt) return false;
+
+ //Ignore speed check -> continue the recovery until speed vector is over horizon
+ if(recovering) return true;
+ //below are more strict speed conditions to enter the recovery
+
+ //for final apreach the targetAlt must be used for safe speed check
+ double zeroSpeedAlt = std::min(safeAlt, targetAlt);
+
+ if(zeroSpeedAlt*zeroSpeedAlt < tangLenSqr) return false;
+
+ //distance to point of pircing of planet surface or sefe alt sphere by speed vector
+ double breakingDist = tangDist - sqrt(zeroSpeedAlt*zeroSpeedAlt - tangLenSqr);
+
+#ifdef DEBUG_CHECK_SUICIDE
+ if (dBody->IsType(ObjectType::PLAYER)) {
+ std::cout << "CheckSuicide breakingDist=" << breakingDist << std::endl;
+ std::cout << "Speed Check v^2 vs maxV^2: " << dBody->GetVelocity().LengthSqr() << "\t"
+ << 2*(prop->GetAccelFwd()*breakingDist - G*obsMass*(obsDist-zeroSpeedAlt)/(obsDist*zeroSpeedAlt)) << std::endl;
+ }
+#endif
+
+ //Energy equation with planet gravity taken into account
+ if (breakingDist > 100
+ && dBody->GetVelocity().LengthSqr() > 2*(prop->GetAccelFwd()*breakingDist - G*obsMass*(obsDist-zeroSpeedAlt)/(obsDist*zeroSpeedAlt)))
return true;
+
return false;
}
@@ -869,7 +907,6 @@
{
AICommand::PostLoadFixup(space);
m_target = space->GetBodyByIndex(m_targetIndex);
- m_lockhead = true;
m_frameId = m_target ? m_target->GetFrame() : FrameId();
// Ensure needed sub-system:
m_prop = m_dBody->GetComponent<Propulsion>();
@@ -884,10 +921,11 @@
assert(m_prop != nullptr);
m_frameId = FrameId::Invalid;
m_state = -6;
- m_lockhead = true;
m_endvel = 0;
m_tangent = false;
m_is_flyto = true;
+ m_suicideRecovery = false;
+
if (!target->IsType(ObjectType::TERRAINBODY))
m_dist = VICINITY_MIN;
else
@@ -915,8 +953,8 @@
m_endvel(endvel),
m_tangent(tangent),
m_state(-6),
- m_lockhead(true),
- m_frameId(FrameId::Invalid)
+ m_frameId(FrameId::Invalid),
+ m_suicideRecovery(false)
{
m_prop = dBody->GetComponent<Propulsion>();
assert(m_prop != nullptr);
@@ -933,6 +971,10 @@
m_endvel = jsonObj["end_vel"];
m_tangent = jsonObj["tangent"];
m_state = jsonObj["state"];
+ if(jsonObj.find("suicide_recovery") != jsonObj.end())
+ m_suicideRecovery = jsonObj["suicide_recovery"];
+ else
+ m_suicideRecovery = false;
} catch (Json::type_error &) {
throw SavedGameCorruptException();
}
@@ -952,6 +994,7 @@
aiCommandObj["end_vel"] = m_endvel;
aiCommandObj["tangent"] = m_tangent;
aiCommandObj["state"] = m_state;
+ aiCommandObj["suicide_recovery"] = m_suicideRecovery;
jsonObj["ai_command"] = aiCommandObj; // Add ai command object to supplied object.
}
@@ -992,9 +1035,51 @@
FrameId targframeId = m_target ? m_target->GetFrame() : m_targframeId;
ParentSafetyAdjust(m_dBody, targframeId, targpos, targvel);
vector3d relpos = targpos - m_dBody->GetPosition();
+ double targdist = relpos.Length();
+
+ Body* planetNear = Frame::GetFrame(m_dBody->GetFrame())->GetBody();
+ double targetAlt = targpos.Length();
+
+ if(planetNear) {
+ double M = planetNear->IsType(ObjectType::TERRAINBODY) ? planetNear->GetMass() : 0;
+ double safeAlt = MaxEffectRad(planetNear, m_prop);
+ vector3d obspos = -m_dBody->GetPosition();
+
+
+ if ((m_suicideRecovery = CheckSuicide(m_dBody, obspos, M, safeAlt, targetAlt, m_suicideRecovery))) {
+
+ //find best orientationg to get to horizon
+ vector3d sidedir = obspos.Cross(m_dBody->GetVelocity()).NormalizedSafe();
+ vector3d updir = sidedir.Cross(m_dBody->GetVelocity()).NormalizedSafe();
+
+ //clamped tangent of Yaw mismatch to target - for driving side trust
+ constexpr double cSideDriveRange = 0.02;
+ double targetSideTan = Clamp(targdist > 1 ? relpos.Dot(sidedir)/targdist : 0, -cSideDriveRange, cSideDriveRange);
+
+ //Bellow safe alt (gravity too big for thrusters) breaking will kill the ship eventually
+ //so in this case ship accelerates along speed vector otherwise it is safe to break
+ float sign = G*M/obspos.LengthSqr() > 0.9 * m_prop->GetAccelUp() ? 1.0 : -1.0;
+
+ double ang = m_prop->AIFaceDirection(m_dBody->GetVelocity() * sign);
+ m_prop->AIFaceUpdir(updir);
+#ifdef DEBUG_CHECK_SUICIDE
+ if (m_dBody->IsType(ObjectType::PLAYER)) {
+ std::cout << "SUICIDE recovery! ang=" << ang << " targetSideTan=" << targetSideTan << std::endl;
+ std::cout << "safeAlt=" << safeAlt << " obsdist=" << obspos.Length() << " targetpos.Length()=" << targpos.Length() << std::endl;
+ }
+#endif
+
+ //Full Up and Forward thruster.
+ //Side thrust depends on relative pos of the target - not relevant for recovery but it is nice
+ //to be aligned with the target after surviving.
+ m_prop->SetLinThrusterState(ang < 0.05 ? vector3d(sign * targetSideTan * (1/cSideDriveRange), 1, -1) : vector3d(0.0));
+
+ return false;
+ }
+ }
+
vector3d reldir = relpos.NormalizedSafe();
vector3d relvel = targvel - m_dBody->GetVelocity();
- double targdist = relpos.Length();
#ifdef DEBUG_AUTOPILOT
if (m_ship->IsType(ObjectType::PLAYER))
@@ -1018,7 +1103,7 @@
double erad = MaxEffectRad(body, m_prop);
Frame *targframe = Frame::GetFrame(targframeId);
if ((m_target && body != m_target) || (targframe && (!m_tangent || body != targframe->GetBody()))) {
- int coll = CheckCollision(m_dBody, reldir, targdist, targpos, m_endvel, erad);
+ int coll = CheckCollision(m_dBody, reldir, targdist, targetAlt, m_endvel, erad);
if (coll == 0) { // no collision
if (m_child) {
m_child.reset();
@@ -1027,7 +1112,7 @@
double ang = m_prop->AIFaceDirection(m_dBody->GetPosition());
m_prop->AIMatchVel(ang < 0.05 ? 1000.0 * m_dBody->GetPosition().Normalized() : vector3d(0.0));
} else { // same thing for 2/3/4
- if (!m_child) m_child.reset(new AICmdFlyAround(m_dBody, Frame::GetFrame(m_frameId)->GetBody(), erad * 1.05, 0.0));
+ if (!m_child) m_child.reset(new AICmdFlyAround(m_dBody, body, erad * 1.05, 0.0));
static_cast<AICmdFlyAround *>(m_child.get())->SetTargPos(targpos);
ProcessChild();
}
@@ -1068,7 +1153,7 @@
const vector3d perpdir = (perpspeed > 1e-30) ? perpvel / perpspeed : vector3d(0, 0, 1);
double sidefactor = perpspeed / (tt * 0.5);
- if (curspeed > (tt + timestep) * maxdecel || maxdecel < sidefactor) {
+ if (curspeed - m_endvel > (tt + timestep) * maxdecel || maxdecel < sidefactor) {
m_prop->AIFaceDirection(relvel);
m_prop->AIMatchVel(targvel);
m_state = -5;
@@ -1118,7 +1203,11 @@
// then flip the ship so we can use our main thrusters to decelerate
if (m_state && !is_zero_exact(sdiff) && sdiff < maxdecel * timestep * 60) head = -head;
if (!m_state && decel) sidefactor = -sidefactor;
- head = head * maxdecel + perpdir * sidefactor;
+
+ // check that head does not become zero length
+ if (maxdecel > 0.001 || abs(sidefactor) > 0.001) {
+ head = head * maxdecel + perpdir * sidefactor;
+ }
// face appropriate direction
if (m_state >= 3) {
@@ -1410,7 +1499,6 @@
assert(!std::isnan(alt));
assert(!std::isnan(vel));
m_obstructor = obstructor;
- m_alt = alt;
m_vel = vel;
m_targmode = mode;
@@ -1423,6 +1511,8 @@
Frame *nonRot = Frame::GetFrame(obsFrame->GetNonRotFrame());
alt = std::min(alt, 0.95 * nonRot->GetRadius());
+ m_alt = alt;
+
// generate suitable velocity if none provided
double minacc = (mode == 2) ? 0 : m_prop->GetAccelMin();
double mass = obstructor->IsType(ObjectType::TERRAINBODY) ? obstructor->GetMass() : 0;
@@ -1484,8 +1574,8 @@
assert(prop != 0);
if (targalt > m_alt) return m_vel;
- double t = sqrt(2.0 * targdist / prop->GetAccelFwd());
- double vmaxprox = prop->GetAccelMin() * t; // limit by target proximity
+ //either use reverse accel or implement dir flipping in FlyAround
+ double vmaxprox = sqrt(2 * prop->GetAccelRev() * targdist);
double vmaxstep = std::max(m_alt * 0.05, m_alt - targalt);
vmaxstep /= Pi::game->GetTimeStep(); // limit by distance covered per timestep
return std::min(m_vel, std::min(vmaxprox, vmaxstep));
@@ -1514,22 +1604,16 @@
}
double timestep = Pi::game->GetTimeStep();
- vector3d targpos = (!m_targmode) ? m_targpos :
- m_dBody->GetVelocity().NormalizedSafe() * m_dBody->GetPosition().LengthSqr();
+ vector3d targpos = (!m_targmode) ? m_targpos : m_dBody->GetVelocity().NormalizedSafe() * m_dBody->GetPosition().LengthSqr();
vector3d obspos = m_obstructor->GetPositionRelTo(m_dBody);
double obsdist = obspos.Length();
vector3d obsdir = obspos / obsdist;
vector3d relpos = targpos - m_dBody->GetPosition();
+ double targetDist = relpos.Length();
+ vector3d shipToTargDir = relpos / targetDist;
- // frame body suicide check, response
- if (CheckSuicide(m_dBody, -obsdir)) {
- m_prop->AIFaceDirection(m_dBody->GetPosition()); // face away from planet
- m_prop->AIMatchVel(vector3d(0.0));
- return false;
- }
-
- // if too far away, fly to tangent
- if (obsdist > 1.1 * m_alt) {
+ // if too far away or overshoot -> fly to tangent
+ if (obsdist > 1.1 * m_alt || m_dBody->GetVelocity().Dot(shipToTargDir) < 0) {
double v;
FrameId obsframeId = Frame::GetFrame(m_obstructor->GetFrame())->GetNonRotFrame();
vector3d tangent = GenerateTangent(m_dBody, obsframeId, targpos, m_alt);
@@ -1546,7 +1630,7 @@
}
// limit m_vel by target proximity & distance covered per frame
- double vel = (m_targmode) ? m_vel : MaxVel(relpos.Length(), targpos.Length());
+ double vel = (m_targmode) ? m_vel : MaxVel(targetDist, targpos.Length());
// all calculations in ship's frame
vector3d fwddir = (obsdir.Cross(relpos).Cross(obsdir)).NormalizedSafe();
--- pioneer-20230203.orig/src/ShipAICmd.h 2023-07-19 23:54:00.245824921 +0900
+++ pioneer-20230203/src/ShipAICmd.h 2023-07-20 00:09:55.718866370 +0900
@@ -137,10 +137,10 @@
bool m_tangent; // true if path is to a tangent of the target frame's body
int m_state;
- bool m_lockhead;
int m_targetIndex; // used during deserialisation
vector3d m_reldir; // target direction relative to ship at last frame change
FrameId m_frameId; // last frame of ship
+ bool m_suicideRecovery;
};
class AICmdFlyAround : public AICommand {
--- pioneer-20230203.orig/src/lua/LuaSpace.cpp 2023-07-19 23:54:00.250824905 +0900
+++ pioneer-20230203/src/lua/LuaSpace.cpp 2023-07-20 00:12:51.625324432 +0900
@@ -187,7 +187,7 @@
}
// functions from ShipAiCmd.cpp
-extern int CheckCollision(DynamicBody *dBody, const vector3d &pathdir, double pathdist, const vector3d &tpos, double endvel, double r);
+extern int CheckCollision(DynamicBody *dBody, const vector3d &pathdir, double pathdist, double targAlt, double endvel, double r);
extern double MaxEffectRad(const Body *body, Propulsion *prop);
/*
@@ -256,19 +256,20 @@
// check for collision at spawn position
const vector3d shippos = ship->GetPosition();
const vector3d targpos = targetbody->GetPositionRelTo(ship->GetFrame());
+ double targAlt = targpos.Length();
const vector3d relpos = targpos - shippos;
const vector3d reldir = relpos.NormalizedSafe();
const double targdist = relpos.Length();
Body *body = Frame::GetFrame(ship->GetFrame())->GetBody();
const double erad = MaxEffectRad(body, ship->GetPropulsion());
- const int coll = CheckCollision(ship, reldir, targdist, targpos, 0, erad);
+ const int coll = CheckCollision(ship, reldir, targdist, targAlt, 0, erad);
if (coll) {
// need to correct positon, to avoid collision
- if (targpos.Length() > erad) {
+ if (targAlt > erad) {
// target is above the effective radius of obstructor - rotate the ship's position
// around the target position, so that the obstructor's "effective radius" does not cross the path
// direction obstructor -> target
- const vector3d z = targpos.Normalized();
+ const vector3d z = targpos/targAlt;
// the axis around which the position of the ship will rotate
const vector3d y = z.Cross(shippos).NormalizedSafe();
// just the third axis of this basis
@@ -276,7 +277,7 @@
// this is the basis in which the position of the ship will rotate
const matrix3x3d corrCS = matrix3x3d::FromVectors(x, y, z).Transpose();
- const double len = targpos.Length();
+ const double len = targAlt;
// two possible positions of the ship, when flying around the obstructor to the right or left
// rotate (in the given basis) the direction from the target to the obstructor, so that it passes tangentially to the obstructor
const vector3d safe1 = corrCS.Transpose() * (matrix3x3d::RotateY(+asin(erad / len)) * corrCS * -targpos).Normalized() * targdist;
@@ -288,7 +289,7 @@
ship->SetPosition(safe2 + targpos);
} else {
// target below the effective radius of obstructor. Position the ship direct above the target
- ship->SetPosition(targpos + targpos.Normalized() * targdist);
+ ship->SetPosition(targpos + targpos/targAlt * targdist);
}
// update velocity direction
ship->SetVelocity((targpos - ship->GetPosition()).Normalized() * pp.getVel() + targetbody->GetVelocityRelTo(ship->GetFrame()));
--- pioneer-20230203.orig/src/ship/Propulsion.cpp 2023-07-19 23:54:00.252824899 +0900
+++ pioneer-20230203/src/ship/Propulsion.cpp 2023-07-20 00:14:14.857068275 +0900
@@ -185,9 +185,9 @@
double Propulsion::GetThrustMin() const
{
// These are the weakest thrusters in a ship
- double val = static_cast<double>(m_linThrust[THRUSTER_UP]);
- val = std::min(val, static_cast<double>(m_linThrust[THRUSTER_RIGHT]));
- val = std::min(val, static_cast<double>(m_linThrust[THRUSTER_LEFT]));
+ double val = GetThrust(THRUSTER_UP);
+ val = std::min(val, GetThrust(THRUSTER_RIGHT));
+ val = std::min(val, GetThrust(THRUSTER_LEFT));
return val;
}