From b9cfe0f4409928de92210e4f9602f28b137e7294 Mon Sep 17 00:00:00 2001 From: Karl F Date: Tue, 16 Aug 2016 10:51:27 +0200 Subject: [PATCH] Ship knows when a hyperjump is legal or not --- data/libs/Ship.lua | 105 ++++++++++++++++++++++++++++++++++++++++++++- src/WorldView.cpp | 5 ++- 2 files changed, 107 insertions(+), 3 deletions(-) diff --git a/data/libs/Ship.lua b/data/libs/Ship.lua index 9873524e61e..9a92b020fa5 100644 --- a/data/libs/Ship.lua +++ b/data/libs/Ship.lua @@ -367,14 +367,117 @@ Ship.RemoveEquip = function (self, item, count, slot) return ret end -Ship.HyperjumpTo = function (self, path) + +-- +-- Method: IsHyperjumpAllowed +-- +-- Check if hyperjump is allowed, return bool and minimum allowed +-- altitude / distance. +-- +-- > is_allowed, distance = ship:IsHyperjumpAllowed() +-- +-- +-- Return: +-- +-- is_allowed - Boolean. True if allowed at ships current position, +-- flase otherwise +-- +-- distance - The minimum allowed altitude from planetary body, or +-- distance from orbital space station, for a legal hyper juump. +-- +-- Availability: +-- +-- 2016 August +-- +-- Status: +-- +-- experimental +-- +Ship.IsHyperjumpAllowed = function(self) + + -- in meters + local MIN_PLANET_HYPERJUMP_ALTITUDE = 10000 + local MIN_SPACESTATION_HYPERJUMP_DISTANCE = 1000 + + -- get closest non-dynamic (not ships, cargo, missiles) body of ship + local body = self.frameBody + + -- If no body close by, anything goes + if not body then + return true, 0 + end + + -- if alt is nil, then outside frame of ref -> OK to jump + local check = function(alt, dist) return not alt or alt >= dist, dist end + + -- if body exists and not a planet -> allowed + if body and body.type == 'STARPORT_ORBITAL' then + return check(body:DistanceTo(self), MIN_SPACESTATION_HYPERJUMP_DISTANCE) + end + + -- if on a planet: + -- always allowed if not body.hasAtmosphere? + + -- if body is a planet or a star: + if body and body.type ~= 'GRAVPOINT' then + local lat, long, altitude = self:GetGroundPosition() + return check(altitude, MIN_PLANET_HYPERJUMP_ALTITUDE) + end +end + +-- +-- Method: HyperjumpTo +-- +-- Hyperjump ship to system. Makes sure the ship has a hyper drive, +-- that target is withn range, and ship has enough fuel, before +-- initiating the hyperjump countdown. In addition, through the +-- optional argument, the ship can fly to a safe distance, compliant +-- with local authorities' regulation, before initiating the jump. +-- +-- > status = ship:HyperjumpTo(path) +-- > status = ship:HyperjumpTo(path, is_legal) +-- +-- Parameters: +-- +-- path - a for the destination system +-- +-- isLegal - an optional Boolean argument, defaults to false. If +-- true AI will fly the ship ship to legal distance +-- before jumping +-- +-- Return: +-- +-- status - a string that tells if the ship can +-- hyperspace and if not, describes the reason +-- +-- Availability: +-- +-- 2015 +-- +-- Status: +-- +-- experimental +-- +Ship.HyperjumpTo = function (self, path, is_legal) local engine = self:GetEquip("engine", 1) if not engine then return "NO_DRIVE" end + + -- default to false, if nil: + is_legal = not (is_legal == nil) or is_legal + + -- only jump from safe distance + local is_allowed, distance = self:IsHyperjumpAllowed() + if is_legal and self.frameBody and not is_allowed then + print("---> Engage AI for safe distance of hyperjump") + self:AIEnterLowOrbit(self.frameBody) + end + return engine:HyperjumpTo(self, path) end + Ship.CanHyperjumpTo = function(self, path) return self:GetHyperspaceDetails(path) == 'OK' end diff --git a/src/WorldView.cpp b/src/WorldView.cpp index 4f27575986c..205d6d72f69 100644 --- a/src/WorldView.cpp +++ b/src/WorldView.cpp @@ -582,14 +582,15 @@ void WorldView::RefreshHyperspaceButton() { SystemPath target = m_game->GetSectorView()->GetHyperspaceTarget(); if (LuaObject::CallMethod(Pi::player, "CanHyperjumpTo", &target)){ - +// std::cout << "ONE" << std::endl; if(Pi::player->GetFlightState() == Ship::FLYING || Pi::player->GetFlightState() == Ship::JUMPING) { +// std::cout << "TWO" << std::endl; // leave the "disabled" state if not landed: if(m_hyperspaceButton->GetState() == 0) m_hyperspaceButton->StateNext(); - if(!Pi::player->IsHyperspaceAllowed()){ + if(!LuaObject::CallMethod(Pi::player, "IsHyperjumpAllowed")){ // If crossing boundary from above if(3 <= m_hyperspaceButton->GetState()){ m_hyperspaceButton->StatePrev();