I am, I think, having issues with nested tables, and trying to use table's values as a key for another. I assume I am using the wrong syntax.
Currently, the gameloop doesn't differentiate between fusion and steam generators. I believe that "fuelRate" and "fuelType" don't do what I expect.
Code: Select all
require "defines"
--[[
This module handles the gameloop alteration, allowing conduit modules in power armor grid to tranfer energy between your power grid and your armor.
]]--
--[[
Charging Module Icon
Artist: Treetog ArtWork (Available for custom work)
Iconset: Junior Icons (146 icons)
License: Free for personal desktop use only.
Commercial usage: Not allowed
]]--
--[[ Gen , Size, Gen/size
Conduit : 20kw, 1x1, 20kw
Solar 1 : 15kw, 1x1, 15kw
Solar 2 : 200kw, 3x3, 22.2kw
Burner : 200kw, 2x2, 50kw
Fusion : 1Mw, 4x4, 62.5kw
Energy , duration
Wood : 4 MJ , 20
Coal : 8 MJ , 40
Fuel : 25 MJ , 125
Fusion: 112.5 MJ, 120
]]--
--[[
Proto-shield, 5 capacity, 100k/shield, 100k consumption.
10x used for t1 shield, plus coil
]]--
--[[
Assembly machine
2x2, 3x3
uses 100, 200 energy
+30%, +100%
]]--
--[[
Actuator equipment
25 energy for mini ones.
]]--
local Debug = true -- true
local tickRate = 1
local ticksPerSecond = 60
local tickRatio = tickRate/ticksPerSecond -- To avoid division operations in a loop
local conversionRatio = 1.0 -- Internal armor has values 1/1000th of the normal power network. As of 0.12, it is now a ratio of 10
local conversionAntiRatio = 1.0/conversionRatio -- avoid division
local accumulatorEnergyCap = 5 * 1000 * 1000 -- 100 slots, 20/slot + 80, 2080 transfer rate, 5mil should be sufficient.. This must match accumulator dummy power capacity.
local ArmorTransferRatePerGridSize = 0.8 * 1000 * tickRatio
local ConduitTransferRatePerEquipment = 20 * 1000 * tickRatio
--local SteamFuelRatePerEquipment =
--local FusionFuelRatePerEquipment =
local SteamActivationThreshhold = 0.5
local FusionActivationThreshhold = 0.9
local fuelValues =
{
{
type = "steam-engine-equipment",
power = 100 * 1000 * tickRatio, -- Production per tick at max rate
threshhold = 0.5, -- Power must be below this value for this type of generator to run
{[1] = {"solid-fuel", 25*1000*1000}}, -- Value of each fuel type.
{[2] = {"coal" , 8*1000*1000}},
{[3] = {"raw-wood" , 4*1000*1000}},
},
{
type = "fusion-reactor-equipment",
threshhold = 0.9,
power = 900 * 1000 * tickRatio, -- actually 1000k, but 100k is always active.
{[1] = {"alien-fuel", 100*1000*1000}},
}
}
local priorities =
{
{
type = "input",
{[1] = "primary-input" },
{[2] = "secondary-input" },
},
{
type = "output",
{[1] = "primary-output"},
{[2] = "secondary-output"},
}
}
--[[remote.addinterface("ModularArmor", {
reset = function()
global.ticking = nil
--global.modularArmor = {}
end
})]]--
function verifySettings()
if (tickRate < 0) then
tickRate = 0
throwError("Tick rate must be >= 0.")
end
end
function onload() -- this function
-- globalPrint("onLoad")
if (global.loaded == nil) then
global.loaded = true
-- globalPrint("loaded")
verifySettings()
end
if (not global.modularArmor) then
global.modularArmor = {}
end
if (global.ticking == nil) then
global.ticking = 0
end
game.on_event(defines.events.on_tick, ticker)
end
game.on_init(onload)
game.on_load(onload)
function globalPrint(msg)
local players = game.players
for i=1, #players do
players[i].print(msg)
end
end
function tableIsEmpty(t)
if (t) then
for k in pairs(t) do
return false
end
end
return true
end
function ticker() -- run once per tickRate number of gameticks.
if (global.ticking == 0) then
global.ticking = tickRate - 1
tick()
else
global.ticking = global.ticking - 1
end
end
function tick()
local shouldKeepTicking
local thisPlayer = nil
local players = game.players
local surface = game.surfaces['nauvis']
--globalPrint("tick")
shouldKeepTicking = true -- Due to lack of any alternate method of detecting player's armor state, we have to always tick.
for i=1, #players do
thisPlayer = players[i]
--game.getplayer(1).print(i..' '..player)
--if not global.modularArmor[i] then
-- global.modularArmor[i] = {}
--end
local modularArmor = global.modularArmor[i]
if (not modularArmor) then
modularArmor = {} -- ensure player has data attached
--modularArmor.storedFuel = {["steam"] = 0, ["fusion"] = 0}
global.modularArmor[i] = modularArmor
if (Debug == true) then
game.always_day=true -- test mode stuff
thisPlayer.insert{name="basic-grenade",count=5}
thisPlayer.insert{name="energy-shield-equipment",count=20}
thisPlayer.insert{name="energy-shield-mk2-equipment",count=10}
--thisPlayer.insert{name="energy-shield-module-equipment",count=10}
--thisPlayer.insert{name="energy-shield-core-equipment",count=5}
thisPlayer.insert{name="power-conduit-equipment",count=40}
thisPlayer.insert{name="steam-engine-equipment",count=10}
thisPlayer.insert{name="fusion-reactor-equipment",count=10}
--thisPlayer.insert{name="power-conduit-core-equipment",count=5}
thisPlayer.insert{name="coal",count=50}
thisPlayer.insert{name="solid-fuel",count=50}
thisPlayer.insert{name="alien-fuel",count=50}
--thisPlayer.insert{name="solar-panel-equipment-node",count=20}
thisPlayer.insert{name="solar-panel-equipment",count=20}
thisPlayer.insert{name="solar-panel-equipment-mk2",count=10}
thisPlayer.insert{name="basic-actuator-equipment",count=20}
thisPlayer.insert{name="battery-equipment",count=5}
thisPlayer.insert{name="battery-mk2-equipment",count=5}
thisPlayer.insert{name="basic-modular-armor",count=1}
thisPlayer.insert{name="power-armor",count=1}
thisPlayer.insert{name="power-armor-mk2",count=1}
thisPlayer.insert{name="small-electric-pole",count=200}
thisPlayer.insert{name="solar-panel",count=200}
end
end
if (not modularArmor.storedFuel) then
modularArmor.storedFuel = {}
for i,fuelVal in ipairs(fuelValues) do
local fuelType = fuelVal.type
modularArmor.storedFuel[fuelType] = 1
end
end
-- Removed till I can figure out how to fix the entity.
--[[if modularArmor.unit == nil then
modularArmor.unit = surface.create_entity{name = "modular-accumulator-dummy", position = thisPlayer.position, force=game.forces.player}
-- attach power drain dummy.
modularArmor.unit.destructible = false -- Make dummy invulnerable.
modularArmor.unit.energy = accumulatorEnergyCap -- initialize energy levels
modularArmor.previousEnergy = accumulatorEnergyCap -- and previous energy level from last tick
else
modularArmor.unit.teleport(thisPlayer.character.position) -- Ensure that the power drain dummy is always at the player's position.
end]]--
local armor = thisPlayer.get_inventory(defines.inventory.player_armor)[1] -- Check for armour presence.
if (armor.valid_for_read) then
local grid = armor.grid
if (grid ~= nil) then -- Check for grid existance.
local transferRate = 0 -- Rate of transfer from external network to armor.
transferRate = transferRate + ArmorTransferRatePerGridSize*grid.width*grid.height
local fuelRate = {}
local energy = 0 -- Total energy and energy capacity
local energyCap = 0
-- local shieldHealth = 0 -- Total shield and shield capacity for auto-balancing.
--local shieldCap =0
for i,equipment in ipairs(grid.equipment) do -- Loop through all equipment.
if (equipment.max_energy ~= 0) then
energy = energy + equipment.energy -- If it has energy, add values to total value.
energyCap = energyCap + equipment.max_energy
else
end
for i,fuelVal in ipairs(fuelValues) do
local fuelType = fuelVal.type
if (equipment.name == fuelType) then
--globalPrint(equipment.name.." ? "..fuelType)
if not fuelRate.fuelType then
fuelRate.fuelType = fuelVal.power
else
fuelRate.fuelType = fuelRate.fuelType + fuelVal.power
end
else
end
end
--if equipment.maxshield ~= 0 then
-- shieldHealth = shieldHealth + equipment.shield -- Same with shield.
-- shieldCap = shieldCap + equipment.maxshield
--else
if (equipment.name == "power-conduit-equipment") then -- Also count each conduit module.
transferRate = transferRate + ConduitTransferRatePerEquipment
end
end
local energyWanted = energyCap-energy
local transferRate = math.min(transferRate,energyWanted) -- We cant transfer energy without space to put it into
local accumulatorEnergy = 0*conversionAntiRatio -- Temporarily removed.
--local accumulatorEnergy = (modularArmor.unit.energy - modularArmor.previousEnergy)*conversionAntiRatio -- How much energy was accumulated.
local energyToAdd = math.min(transferRate,accumulatorEnergy) -- Accumulated energy, or transfer wanted, whichever is lower.
local newEnergy = energy+energyToAdd
local storageRatio = newEnergy/energyCap
for i,fuelVal in ipairs(fuelValues) do -- Currently, Fusion power is being used when steam is supposed to be.
local fuelType = fuelVal.type
if fuelRate.fuelType and fuelRate.fuelType > 0.0 then
globalPrint("detected Generator "..fuelRate.fuelType..fuelType)
-- This type exists
local threshhold = energyCap * fuelVal.threshhold -- How much power this generator is allowed to bring you up to.
local energyWanted = threshhold - newEnergy -- How much power we want to generate
energyWanted = math.max(energyWanted,0) -- Can't request negative power
energyWanted = math.min(energyWanted,fuelRate.fuelType) -- Can't make more power than the engines can support
local energyToGenerate = 0
globalPrint("Stored "..modularArmor.storedFuel[fuelType]..fuelType)
globalPrint("Wanted "..energyWanted)
if (modularArmor.storedFuel[fuelType] < energyWanted) then
-- Check for fuel. If available, consume. If not, spend what you have
local mainInventory = thisPlayer.get_inventory(defines.inventory.player_main)
local validFuel = nil
for i,fuel in ipairs(fuelVal) do
if (mainInventory.get_item_count(fuel[i][1]) > 0) then
-- Got some
validFuel = fuel[i]
break
else
-- No luck, skip it
end
globalPrint(fuel[i][1].." "..mainInventory.get_item_count(fuel[i][1]))
end
if (validFuel) then
mainInventory.remove{name = validFuel[1], count = 1}
modularArmor.storedFuel[fuelType] = modularArmor.storedFuel[fuelType] + validFuel[2]
globalPrint(validFuel[1].." "..modularArmor.storedFuel[fuelType])
else
-- Out of fuel
globalPrint("No fuel")
end
else
-- Have enough fuel already.
end
energyToGenerate = math.min(modularArmor.storedFuel[fuelType],energyWanted)
modularArmor.storedFuel[fuelType] = modularArmor.storedFuel[fuelType] - energyToGenerate
energyToAdd = energyToAdd + energyToGenerate
-- Calculate how much fuel to use
-- max, 0,maximum this tick
-- min, maximum this tick, threshholdValue - newenergy
--if (storageRatio)< SteamActivationThreshhold) then
--end
else
-- No such generator.
end
end
--[[ if (steamFuelRate > 0) then
local steamThreshhold = energyCap * SteamActivationThreshhold -- How much power steam is allowed to bring you up to.
local energyWanted = steamThreshhold - newEnergy -- How much power we want to generate
energyWanted = math.max(energyWanted,0) -- Can't request negative power
energyWanted = math.min(energyWanted,steamFuelRate) -- Can't make more power than the engines can support
local energyToGenerate = 0
--globalPrint("Stored "..modularArmor.storedFuel.steam)
--globalPrint("Wanted "..energyWanted)
if (modularArmor.storedFuel.steam < energyWanted) then
-- Check for fuel. If available, consume. If not, spend what you have
local mainInventory = thisPlayer.get_inventory(defines.inventory.player_main)
local validFuel = nil
for i,fuel in ipairs(steamFuelValues) do
if (mainInventory.get_item_count(fuel[i][1]) > 0) then
-- Got some
validFuel = fuel[i]
break
else
-- No luck, skip it
end
--globalPrint(fuel[i][1].." "..mainInventory.get_item_count(fuel[i][1]))
end
if (validFuel) then
mainInventory.remove{name = validFuel[1], count = 1}
modularArmor.storedFuel.steam = modularArmor.storedFuel.steam + validFuel[2]
--globalPrint(validFuel[1].." "..modularArmor.storedFuel.steam)
else
-- Out of fuel
--globalPrint("No fuel")
end
else
-- Have enough fuel already.
end
energyToGenerate = math.min(modularArmor.storedFuel.steam,energyWanted)
modularArmor.storedFuel.steam = modularArmor.storedFuel.steam - energyToGenerate
energyToAdd = energyToAdd + energyToGenerate
-- Calculate how much fuel to use
-- max, 0,maximum this tick
-- min, maximum this tick, threshholdValue - newenergy
--if (storageRatio)< SteamActivationThreshhold) then
--end
end]]--
for i,equipment in ipairs(grid.equipment) do
if (equipment.max_energy ~= 0) then
local difference = equipment.max_energy - equipment.energy
if (energyToAdd > difference) then
energyToAdd = energyToAdd - difference
equipment.energy = equipment.max_energy
else
equipment.energy = equipment.energy + energyToAdd
energyToAdd = 0
break
end
else
end
end
--energyToTransfer = energyToTransfer * conversionRatio
--modularArmor.unit.energy = accumulatorEnergyCap - transferRate*conversionRatio
--modularArmor.previousEnergy = modularArmor.unit.energy - energyToTransfer*conversionRatio -- The additional accumulated energy over
else
end
else
end
end
if (not shouldKeepTicking) then
global.ticking = nil
game.onevent(defines.events.ontick, nil)
end
end
function activateTicker()
if (not global.ticking) then
global.ticking = tickRate
game.onevent(defines.events.ontick, ticker)
end
end