diff --git a/data/modules/FuelScoop.lua b/data/modules/FuelScoop.lua index 2e1d6b6cde8..ee752ff861e 100644 --- a/data/modules/FuelScoop.lua +++ b/data/modules/FuelScoop.lua @@ -12,11 +12,11 @@ local lc = Lang.GetResource("core") -- These callbacks are triggered from C++ or Lua and are responsible for -- providing UI feedback about the scooping process. -Event.Register("onShipScoopFuel", function(ship, body) +Event.Register("onShipScoopFuel", function(ship, body, amount) ---@type CargoManager local cargoMgr = ship:GetComponent('CargoManager') - cargoMgr:AddCommodity(Commodities.hydrogen, 1) + cargoMgr:AddCommodity(Commodities.hydrogen, amount) if ship == Game.player then Game.AddCommsLogLine(lc.FUEL_SCOOP_ACTIVE_N_TONNES_H_COLLECTED:gsub('%%quantity', diff --git a/src/Ship.cpp b/src/Ship.cpp index f86aa5b8f08..c2ec5ffb5d3 100644 --- a/src/Ship.cpp +++ b/src/Ship.cpp @@ -1256,10 +1256,23 @@ void Ship::StaticUpdate(const float timeStep) const vector3d vdir = GetVelocity().Normalized(); const vector3d pdir = -GetOrient().VectorZ(); const double dot = vdir.Dot(pdir); - if ((m_stats.free_capacity) && (dot > 0.90) && (speed > 100.0) && (density > 0.3)) { - const double rate = speed * density * 0.00000333 * double(m_stats.fuel_scoop_cap); - if (Pi::rng.Double() < rate) { - LuaEvent::Queue("onShipScoopFuel", this, p); + const double speed_times_density = speed * density; + /* + * speed = m/s, density = g/cm^3 -> T/m^3, pressure = Pa -> N/m^2 -> kg/(m*s^2) + * m T kg m*kg^2 kg^2 + * - * --- * ----- = 1000 ------- = 1000 ------- + * s m^3 m*s^2 m^4*s^3 m^3*s^3 + * + * fuel_scoop_cap = area, m^2. rate = kg^2/(m*s^3) = (Pa*kg)/s^2 + */ + const double hydrogen_density = 0.0002; + if ((m_stats.free_capacity) && (dot > 0.90) && speed_times_density > (100.0 * 0.3)) { + const double rate = speed_times_density * hydrogen_density * double(m_stats.fuel_scoop_cap); + m_hydrogenScoopedAccumulator += rate * timeStep; + if (m_hydrogenScoopedAccumulator > 1) { + const double scoopedTons = floor(m_hydrogenScoopedAccumulator); + LuaEvent::Queue("onShipScoopFuel", this, p, scoopedTons); + m_hydrogenScoopedAccumulator -= scoopedTons; } } } diff --git a/src/Ship.h b/src/Ship.h index a1b2ffea78b..c021bc372ab 100644 --- a/src/Ship.h +++ b/src/Ship.h @@ -330,6 +330,8 @@ class Ship : public DynamicBody { std::string m_shipName; + double m_hydrogenScoopedAccumulator = 0; + public: // FIXME: these methods are deprecated; all calls should use the propulsion object directly. void ClearAngThrusterState() { m_propulsion->ClearAngThrusterState(); }