On Multiplayer Load, Register Table.

Place to get help with not working mods / modding interface.
User avatar
Ranakastrasz
Smart Inserter
Smart Inserter
Posts: 2179
Joined: Thu Jun 12, 2014 3:05 am
Contact:

On Multiplayer Load, Register Table.

Post by Ranakastrasz »

While this seems to work for the player who hosts, people who join don't seem to have this run. I am unsure how to do this properly.


Code: Select all


script.on_configuration_changed(function(data)
    -- If anything changes, at all, refresh everything. 
    -- All mods altering this stuff must do so as well.

    refresh_equipment()
    --[[if data.mod_charges ~= nil then
        refresh_equipment()
    end]]--

    --[[if data.mod_changes ~= nil and data.mod_changes["Modular-Armor"] ~= nil then
        if data.mod_changes["Modular-Armor"].old_version == nil then
            -- "My Mod" was added to an existing game
            refresh_equipment()
        elseif data.mod_changes["Modular-Armor"].old_version ~= data.mod_changes["Modular-Armor"].new_version then
            refresh_equipment()

        end
    end]]--
end)


function registerEquipmentGroup(iGroup)

    --iGroup.mod = iMod
    if not RanaMods.ModularArmor.equipmentData then
        RanaMods.ModularArmor.equipmentData = {}

    end
    if iGroup and iGroup.name and iGroup.type then
        
        for _, v in pairs(RanaMods.ModularArmor.equipmentData) do
            if v.name == iGroup.name then
                return
            end
        end
        table.insert(RanaMods.ModularArmor.equipmentData, iGroup)
        
    else
        return "Invalid Table"
    end
end

function registerPrototype (iGroup,iPrototype,iType)
-- Ideally, this will register equipment group itself, if it doesn't yet exist.
    if not RanaMods.ModularArmor.equipmentData then
        RanaMods.ModularArmor.equipmentData = {}
    end
    if iGroup and iGroup.name and iGroup.type then
        if iPrototype and iPrototype.name and iPrototype.power then
            iPrototype.power = iPrototype.power * RanaMods.ModularArmor.config.powerCoef *RanaMods.ModularArmor.config.secondsPerTick
            for _, v in pairs(RanaMods.ModularArmor.equipmentData) do
                if v.name == iGroup.name then

                    thisTable = nil
                    --[[if iType == "equipment" then
                        if not v.equipment then
                            v.equipment = {}
                        end
                        thisTable = v.equipment
                    elseif iType == "fuel" then
                        if not v.fuel then
                            v.fuel = {}
                        end
                        thisTable = v.fuel
                    else
                        globalPrint("Invalid Type "..iType)
                        return "Invalid Type"
                    end]]--
                    if not v[iType] then
                        v[iType] = {}
                    end
                    
                    for _, data in pairs(v[iType]) do
                        if data.name == iPrototype.name then
                            -- if it already exists, overwrite it.
                            data = iPrototype
                            return
                        end
                    end
                    table.insert(v[iType], iPrototype)
                    
                    break
                end
            end
        else
            return "Invalid iPrototype"
        end
    else
        return "Invalid iGroup"
    end
end



function refresh_equipment()
    --[[luadata = {raw = loadstring(game.entity_prototypes["DATA_RAW"].order)()}
    reset_equipment()
    for i, equipment in pairs (luadata.raw["battery-equipment"]) do
        if equipment.rana_mod then
            if equipment.rana_mod.powerType then
                -- This will happen repeatedly, but it should work correctly even with duplicate registrations, just failing instead.
                registerEquipmentGroup({name = equipment.rana_mod.powerGroup,type = equipment.rana_mod.powerType})
                registerPrototype({name = equipment.rana_mod.powerGroup,type = equipment.rana_mod.powerType},{name = equipment.name     ,power =  equipment.rana_mod.fuelPower},"equipment")
            end
            -- might have more data attachment types later.
        end
    end
    
    for i, fuel in pairs (luadata.raw["item"]) do
        if fuel.rana_mod then

            if fuel.rana_mod.powerType then
            
                registerEquipmentGroup({name = fuel.rana_mod.powerGroup,type = fuel.rana_mod.powerType})
                registerPrototype({name = fuel.rana_mod.powerGroup,type = fuel.rana_mod.powerType},{name = fuel.name     ,power =  fuel.rana_mod.fuelPower},"fuel")
            end
        end
    end]]--
    
    
    registerEquipmentGroup({name = "conduit",type = "conduit"})
    registerEquipmentGroup({name = "burner" ,type = "fuelled"})
    registerEquipmentGroup({name = "fusion" ,type = "fuelled"})

    registerPrototype({name = "conduit",type = "conduit"},{name = "semiconductor-conduit-equipment"    ,power =  40 * 1000},"equipment")
    registerPrototype({name = "conduit",type = "conduit"},{name = "superconductor-conduit-equipment"   ,power = 720 * 1000},"equipment")
    registerPrototype({name = "burner" ,type = "fuelled"},{name = "engine-equipment"                   ,power = 100 * 1000},"equipment")
    registerPrototype({name = "fusion" ,type = "fuelled"},{name = "fusion-reactor-equipment"           ,power = 960 * 1000},"equipment")
                    
    registerPrototype({name = "burner" ,type = "fuelled"},{name = "solid-fuel"  ,power = 25     * 1000 * 1000},"fuel")
    registerPrototype({name = "burner" ,type = "fuelled"},{name = "coal"        ,power = 8.     * 1000 * 1000},"fuel")
    registerPrototype({name = "burner" ,type = "fuelled"},{name = "raw-wood"    ,power = 4.     * 1000 * 1000},"fuel")
    registerPrototype({name = "fusion" ,type = "fuelled"},{name = "alien-fuel"  ,power = 200.   * 1000 * 1000},"fuel")

end
Last edited by Ranakastrasz on Sun Sep 04, 2016 8:16 pm, edited 2 times in total.
My Mods:
Modular Armor Revamp - V16
Large Chests - V16
Agent Orange - V16
Flare - V16
Easy Refineries - V16
User avatar
Adil
Filter Inserter
Filter Inserter
Posts: 945
Joined: Fri Aug 15, 2014 8:36 pm
Contact:

Re: On Multiplayer Load, Register Table.

Post by Adil »

on_configuration_changed
(edit: whoops, I didn't finish the reply yet.)
Last edited by Adil on Sun Sep 04, 2016 7:54 pm, edited 1 time in total.
I do mods. Modding wiki is friend, it teaches how to mod. Api docs is friend too...
I also update mods, some of them even work.
Recently I did a mod tutorial.
User avatar
Ranakastrasz
Smart Inserter
Smart Inserter
Posts: 2179
Joined: Thu Jun 12, 2014 3:05 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Ranakastrasz »

I am using that. Am I using it wrongly, or what?
My Mods:
Modular Armor Revamp - V16
Large Chests - V16
Agent Orange - V16
Flare - V16
Easy Refineries - V16
User avatar
Adil
Filter Inserter
Filter Inserter
Posts: 945
Joined: Fri Aug 15, 2014 8:36 pm
Contact:

Re: On Multiplayer Load, Register Table.

Post by Adil »

on_configuration_changed is supposed to be used for global alterations of game state, which is later sent to players in multiplayer, what do you expect it to do for people that connect?
I do mods. Modding wiki is friend, it teaches how to mod. Api docs is friend too...
I also update mods, some of them even work.
Recently I did a mod tutorial.
User avatar
aubergine18
Smart Inserter
Smart Inserter
Posts: 1264
Joined: Fri Jul 22, 2016 8:51 pm
Contact:

Re: On Multiplayer Load, Register Table.

Post by aubergine18 »

I assume the duplicate code in OP is just a copy/paste typo?

What does the refresh_equipment() function do?

Also, if you just want to check something isn't nil, you don't need to specify `~= nil` so, for example, this

Code: Select all

if data.mod_changes ~= nil then ...
could be written as:

Code: Select all

if data.mod_changes then ...
(Unlike JavaScript, in Lua only nil and false are treated as false... 0, '' and anything else are treated as true)
Better forum search for modders: Enclose your search term in quotes, eg. "font_color" or "custom-input" - it prevents the forum search from splitting on hypens and underscores, resulting in much more accurate results.
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Nexela »

aubergine18 wrote: (Unlike JavaScript, in Lua only nil and false are treated as false... 0, '' and anything else are treated as true)
Including empty tables

table={}

if table then -- will be true
User avatar
Ranakastrasz
Smart Inserter
Smart Inserter
Posts: 2179
Joined: Thu Jun 12, 2014 3:05 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Ranakastrasz »

aubergine18 wrote:I assume the duplicate code in OP is just a copy/paste typo?

What does the refresh_equipment() function do?

Also, if you just want to check something isn't nil, you don't need to specify `~= nil` so, for example, this

Code: Select all

if data.mod_changes ~= nil then ...
could be written as:

Code: Select all

if data.mod_changes then ...
(Unlike JavaScript, in Lua only nil and false are treated as false... 0, '' and anything else are treated as true)
Yea, Typo. Meant to have the relevant functions there instead.

Aware of that. Habit from C++ and vJass.
My Mods:
Modular Armor Revamp - V16
Large Chests - V16
Agent Orange - V16
Flare - V16
Easy Refineries - V16
User avatar
Ranakastrasz
Smart Inserter
Smart Inserter
Posts: 2179
Joined: Thu Jun 12, 2014 3:05 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Ranakastrasz »

Adil wrote:on_configuration_changed is supposed to be used for global alterations of game state, which is later sent to players in multiplayer, what do you expect it to do for people that connect?

Issue is that the table is not valid for the person who joins, implying it was never built by calling the function. It works in single player, fully, implying the table was built. Hence, the joining player's local verson of the table is missing. I'll get the error message, give me a minute.

Edit:
Same error as always when the table isn't there when I was getting it to work in the first place. Works for host, not for client.

Code: Select all

Error while running event on_tick (ID 0) __Modular-Armor__/control.lua: bad argument to #1 to 'ipairs' (table expected, got nil)

Code: Select all


                for x,equipmentData in ipairs(RanaMods.ModularArmor.equipmentData) do -- This line
                    if equipmentData.type == "fuelled" then
                        if not modularArmor.storedFuel[x] then
                            modularArmor.storedFuel[x] = 1
                        end
                    end
                end
My Mods:
Modular Armor Revamp - V16
Large Chests - V16
Agent Orange - V16
Flare - V16
Easy Refineries - V16
orzelek
Smart Inserter
Smart Inserter
Posts: 3928
Joined: Fri Apr 03, 2015 10:20 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by orzelek »

You might need to handle this event if you want to work per player:

Code: Select all

defines.events.on_player_joined_game
It seems that you should be able to do work for given player in there - no idea how will this play with desyncs.
Event also supplies player_index of joining player. There is also an event when player leaves.
User avatar
aubergine18
Smart Inserter
Smart Inserter
Posts: 1264
Joined: Fri Jul 22, 2016 8:51 pm
Contact:

Re: On Multiplayer Load, Register Table.

Post by aubergine18 »

Try using pairs instead of ipairs, the custom lazy instantiated tables that are regularly used in factorio don't support ipairs.

http://lua-api.factorio.com/latest/LuaC ... ustomTable
Better forum search for modders: Enclose your search term in quotes, eg. "font_color" or "custom-input" - it prevents the forum search from splitting on hypens and underscores, resulting in much more accurate results.
User avatar
Ranakastrasz
Smart Inserter
Smart Inserter
Posts: 2179
Joined: Thu Jun 12, 2014 3:05 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Ranakastrasz »

If that was the problem, I doubt it would work for the host player or in single player.
My Mods:
Modular Armor Revamp - V16
Large Chests - V16
Agent Orange - V16
Flare - V16
Easy Refineries - V16
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Nexela »

aubergine18 wrote:Try using pairs instead of ipairs, the custom lazy instantiated tables that are regularly used in factorio don't support ipairs.

http://lua-api.factorio.com/latest/LuaC ... ustomTable
That applies to some of the object tables returned from factorio. ipairs is still valid for iterating over consecutive indexed tables from mods



Rana send me over what you have so far and I will look over it tonight.
User avatar
Ranakastrasz
Smart Inserter
Smart Inserter
Posts: 2179
Joined: Thu Jun 12, 2014 3:05 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Ranakastrasz »

Looking at the Wiki
https://wiki.factorio.com/index.php?tit ... _Lifecycle
it says nothing about on configuration changed so is probably outdated.

However, migrations apperently only run for the person who hosts the game, not for any player who joins afterwards. I suspect that might be related to the issue.

Does on_load still work? And if so, would it work here?
My Mods:
Modular Armor Revamp - V16
Large Chests - V16
Agent Orange - V16
Flare - V16
Easy Refineries - V16
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Nexela »

It depends on what you are doing.

I got everything organized now I just need to go through it all. I will let you know what I have come up with (but honestly seeing some of the stuff I am surprised it even ran in single player)
User avatar
Ranakastrasz
Smart Inserter
Smart Inserter
Posts: 2179
Joined: Thu Jun 12, 2014 3:05 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Ranakastrasz »

That's what I said. It worked great before. Admittedly, I had the table hardcore before too.
My Mods:
Modular Armor Revamp - V16
Large Chests - V16
Agent Orange - V16
Flare - V16
Easy Refineries - V16
Nexela
Smart Inserter
Smart Inserter
Posts: 1828
Joined: Wed May 25, 2016 11:09 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Nexela »

Still busy building my world :) but here is a peek of all 100 errors cleaned up

Code: Select all

--luacheck: globals luadata RanaMods

require "config"
require 'libs/EvoGUI'
--require "interfaces"

luadata = nil

-------------------------------------------------------------------------------
--[Helper Functions]--
local function print(msg)
  if RanaMods.ModularArmor.config.Debug then
			for _, player in game.players do
			player.print(msg)
		end
	end
end


local function verifySettings()
  if (RanaMods.ModularArmor.config.tickRate < 0) then
    RanaMods.ModularArmor.config.tickRate = 1
    print("Tick rate must be >= 0.")
  end
end

-------------------------------------------------------------------------------
--[Script Functions]--
local function registerEquipmentGroup(iGroup)
  --iGroup.mod = iMod
  if not RanaMods.ModularArmor.equipmentData then
    RanaMods.ModularArmor.equipmentData = {}

  end
  if iGroup and iGroup.name and iGroup.type then

    for _, v in pairs(RanaMods.ModularArmor.equipmentData) do
      if v.name == iGroup.name then
        return
      end
    end
    table.insert(RanaMods.ModularArmor.equipmentData, iGroup)

  else
    return "Invalid Table"
  end
end

local function registerPrototype (iGroup,iPrototype,iType)
  -- Ideally, this will register equipment group itself, if it doesn't yet exist.
  if not RanaMods.ModularArmor.equipmentData then
    RanaMods.ModularArmor.equipmentData = {}
  end
  if iGroup and iGroup.name and iGroup.type then
    if iPrototype and iPrototype.name and iPrototype.power then
      iPrototype.power = iPrototype.power * RanaMods.ModularArmor.config.powerCoef *RanaMods.ModularArmor.config.secondsPerTick
      for _, v in pairs(RanaMods.ModularArmor.equipmentData) do
        if v.name == iGroup.name then

          --thisTable = nil
          --[[if iType == "equipment" then
          if not v.equipment then
            v.equipment = {}
          end
          thisTable = v.equipment
        elseif iType == "fuel" then
          if not v.fuel then
            v.fuel = {}
          end
          thisTable = v.fuel
        else
          globalPrint("Invalid Type "..iType)
          return "Invalid Type"
          end]]--
          if not v[iType] then
            v[iType] = {}
          end

          for i, data in pairs(v[iType]) do
            if data.name == iPrototype.name then
              -- if it already exists, overwrite it.
              v[iType][i] = iPrototype
              return
            else
							table.insert(v[iType], iPrototype)
						end
          end
          break
        end
      end
    else
      return "Invalid iPrototype"
    end
  else
    return "Invalid iGroup"
  end
end

-- local function reset_equipment()
--   RanaMods.ModularArmor.equipmentData = {}
-- end

local function refresh_equipment()
  registerEquipmentGroup({name = "conduit",type = "conduit"})
  registerEquipmentGroup({name = "burner" ,type = "fuelled"})
  registerEquipmentGroup({name = "fusion" ,type = "fuelled"})

  registerPrototype({name = "conduit",type = "conduit"},{name = "semiconductor-conduit-equipment" ,power = 40 * 1000},"equipment")
  registerPrototype({name = "conduit",type = "conduit"},{name = "superconductor-conduit-equipment" ,power = 720 * 1000},"equipment")
  registerPrototype({name = "burner" ,type = "fuelled"},{name = "engine-equipment" ,power = 100 * 1000},"equipment")
  registerPrototype({name = "fusion" ,type = "fuelled"},{name = "fusion-reactor-equipment" ,power = 960 * 1000},"equipment")

  registerPrototype({name = "burner" ,type = "fuelled"},{name = "solid-fuel" ,power = 25 * 1000 * 1000},"fuel")
  registerPrototype({name = "burner" ,type = "fuelled"},{name = "coal" ,power = 8. * 1000 * 1000},"fuel")
  registerPrototype({name = "burner" ,type = "fuelled"},{name = "raw-wood" ,power = 4. * 1000 * 1000},"fuel")
  registerPrototype({name = "fusion" ,type = "fuelled"},{name = "alien-fuel" ,power = 200. * 1000 * 1000},"fuel")

end

-------------------------------------------------------------------------------
--[Event Functions]--
script.on_init(function()
    -- globalPrint("onLoad")
    if (global.loaded == nil) then
      global.loaded = true
      -- globalPrint("loaded")

      verifySettings()
    end
    refresh_equipment()

    --[[if (not global.surface) then
    global.surface = game.surfaces['nauvis']
    end]]--
    if (not global.modularArmor) then
      global.modularArmor = {}
    end
    if (global.ticking == nil) then
      global.ticking = 0
    end
    --if not evo_gui then
    --evo_gui = EvoGUI.new(Natural_Evolution_state)
    --evo_gui = EvoGUI.new(Expansion_State)

    --end
end)

script.on_configuration_changed(function()
    -- If anything changes, at all, refresh everything.
    -- All mods altering this stuff must do so as well.

    refresh_equipment()
    --[[if data.mod_charges ~= nil then
    refresh_equipment()
    end]]--

    --[[if data.mod_changes ~= nil and data.mod_changes["Modular-Armor"] ~= nil then
    if data.mod_changes["Modular-Armor"].old_version == nil then
      -- "My Mod" was added to an existing game
      refresh_equipment()
    elseif data.mod_changes["Modular-Armor"].old_version ~= data.mod_changes["Modular-Armor"].new_version then
      refresh_equipment()

    end
    end]]--
end)

-------------------------------------------------------------------------------
--[Tick Functions]--

local function killDummies(id)
  --GlobalPrint("1")
  if id.units then
    if id.units.accumulator then
      id.units.accumulator.destroy()
      id.units.accumulator = nil
		end
	end
end

local function tickDummies(id,iSurface,iPosition) -- This and kill dummies need to use a factory. I have no idea what that is. Need research
  --GlobalPrint("2")
  if not id.units then
    id.units = {}
	end
  if not id.units.accumulator then
    id.units.accumulator = iSurface.create_entity{name = "laser-turret-dummy", position = iPosition, force=game.forces.player}
    id.units.accumulator.energy = RanaMods.ModularArmor.config.accumulatorEnergyCap -- initialize energy levels
    id.previousEnergy = id.units.accumulator.energy -- and previous energy level from last tick
    id.units.accumulator.destructible = false -- Make dummy invulnerable.
  else
    id.units.accumulator.teleport(iPosition) -- Ensure that the power drain dummy is always at the player's position.
  end
end

local function tick()
  --local shouldKeepTicking
  --globalPrint("tick")
  --shouldKeepTicking = true -- Due to lack of any alternate method of detecting player's armor state, we have to always tick.

  for x, thisPlayer in pairs(game.players) do
    if (thisPlayer.connected) then
      if (thisPlayer.character) then
        --game.getplayer(1).print(x..' '..player)

        --if not global.modularArmor[x] then
        -- global.modularArmor[x] = {}
        --end
        local modularArmor = global.modularArmor[x]

        if (not modularArmor) then

          modularArmor = {} -- ensure player has data attached
          --modularArmor.storedFuel = {["steam"] = 0, ["fusion"] = 0}
          global.modularArmor[x] = modularArmor

        end
        if (not modularArmor.storedFuel) then
          modularArmor.storedFuel = {}
        end
        for j,equipmentData in ipairs(RanaMods.ModularArmor.equipmentData) do
          if equipmentData.type == "fuelled" then
            if not modularArmor.storedFuel[j] then
              modularArmor.storedFuel[j] = 1
            end
          end
        end

        if (not modularArmor.shieldData) then
          modularArmor.shieldData = {}
          modularArmor.shieldData.previousShield = 0
          modularArmor.shieldData.lastDamage = 0
          --modularArmor.shieldData.direction = 0
          --modularArmor.shieldData.lastSFX = 0
        end

        -- Removed till I can figure out how to fix the entity.
        --[[if modularArmor.units and modularArmor.units.name == "modular-accumulator-dummy" then
        modularArmor.units.destroy()
      end
      if modularArmor.units == nil then
        modularArmor.units = {}
        end]]--
        -- Ensure dummies exist.
        --[[]]--

        local armor = thisPlayer.get_inventory(defines.inventory.player_armor)[1] -- Check for armour presence.

        -- /c ((game.players[1].get_inventory(defines.inventory.player_armor)[1]).grid).put{equipment = "battery-equipment"}
        -- /c ((game.players[1].get_inventory(defines.inventory.player_armor)[1]).grid).put{equipment = game.players[1].insert{name = "battery-equipment",count=1}}

        if (armor.valid_for_read) then

          if (armor.has_grid) then -- Check for grid existence.
            local grid = armor.grid

            tickDummies(modularArmor,thisPlayer.character.surface,thisPlayer.character.position)-- validate, create, and move dummy units.

            local transferRate = 0 -- Rate of transfer from external network to armor.

            --transferRate = transferRate + ArmorTransferRatePerGridSize*grid.width*grid.height

            local fuelRates = {}

            local energy = 0 -- Total energy and energy capacity
            local energyCap = 0 -- need smallest fraction count as well. Essentially, if any of them have less than 50% or 90%, activate fusion and steam respectively.
            --local hasBattery = false -- Due to lack of a good energy distrubution system, I only limit production so long as you have a battery. Otherwise, things near the end of the list don't get any energy.
            -- Disabled, since power distribution percentages of 98 and 99% don't really have problems anymore. You would need 50 mini-shields, which wont happen
            local shieldHealth = 0 -- Total shield and shield capacity for auto-balancing.
            local shieldCap = 0
            for _,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
                --if equipment.type == "battery-equipment" then
                -- hasBattery = true
                --else
                --end
              end

              if equipment.max_shield ~= 0 then
                shieldHealth = shieldHealth + equipment.shield -- Same with shield.
                shieldCap = shieldCap + equipment.max_shield
              end

              for z,equipmentData in ipairs(RanaMods.ModularArmor.equipmentData) do -- Count all scripted equipment
                --globalPrint(z)
                for _,equipmentType in ipairs (equipmentData.equipment) do
                  --globalPrint(y)
                  --globalPrint(equipmentType.name)
                  if (equipment.name == equipmentType.name) then
                    --globalPrint(equipment.name.." ? "..fuelType)
                    if equipmentData.type == "fuelled" then -- Get total production rate for each type.

                      if not fuelRates[z] then
                        fuelRates[z] = equipmentType.power
                      else
                        fuelRates[z] = fuelRates[z] + equipmentType.power
                      end
                    elseif equipmentData.type == "conduit" then -- And network transfer rate.
                      transferRate = transferRate + equipmentType.power
                    end
                  end
                end
              end

              --[[if (equipment.name == "power-conduit-equipment") then -- Also count each conduit module.
              transferRate = transferRate + data.ConduitTransferRatePerEquipment
              end]]--
            end

            local shieldFraction = shieldHealth/shieldCap

            if shieldCap > 0 then

              if shieldHealth < modularArmor.shieldData.previousShield then
                -- Took damage last tick.
                modularArmor.shieldData.lastDamage = 0
              --else
                -- Not taking damage this tick. Might have taken damage previously however.

              end
              if modularArmor.shieldData.lastDamage < 300 then
                transferRate = transferRate * 0.1
              end

              modularArmor.shieldData.previousShield = shieldHealth
              modularArmor.shieldData.lastDamage = modularArmor.shieldData.lastDamage+1
            end

            local energyWanted = energyCap-energy

            transferRate = math.min(transferRate,energyWanted) -- We cant transfer energy without space to put it into

            --local accumulatorEnergy = 0*conversionAntiRatio -- Temporarily removed.
            local accumulatorEnergy = (modularArmor.units.accumulator.energy - modularArmor.previousEnergy)--*conversionAntiRatio -- How much energy was accumulated since last tick
            --globalPrint("Accumulator "..accumulatorEnergy)
            local energyToAdd = math.min(transferRate,accumulatorEnergy) -- Accumulated energy, or transfer wanted, whichever is lower.
            local newEnergy = energy+energyToAdd
            --local storageRatio = newEnergy/energyCap

            --accumulatorEnergy = accumulatorEnergy - energyToAdd -- Remove
            -- SFX
            -- if energyToAdd >= 10000 and game.tick%60 == 0 then
            -- global.surface.create_entity{name = "conduit-sparks", position = thisPlayer.character.position, force=game.forces.neutral}
            --end
            --globalPrint("Accumulator -- "..accumulatorEnergy)
            --global.surface.create_entity{name = "smoke-fast", position = thisPlayer.character.position, force=game.forces.neutral}

            for f,equipment in ipairs(RanaMods.ModularArmor.equipmentData) do
              if equipment.type == "fuelled" then

                --globalPrint("detected Generator "..(fuelRates.fuelType)..(fuelType))
                if (fuelRates[f] and (fuelRates[f] > 0.0)) then -- Make sure it exists, and that is is above zero.
                  --globalPrint("detected Generator "..fuelRates.fuelType..fuelType)
                  -- This type exists
                  local threshhold = energyCap -- How much power this generator is allowed to bring you up to.
                  -- Currently leaving it at 100% for now, till I have a better idea how I want to do this.
                  --if hasBattery then
                  --threshhold = threshhold * fuelVal.threshhold -- Without a battery, you cannot regulate energy production.
                  --else

                  --end
                  energyWanted = threshhold - newEnergy -- How much power we want to generate
                  energyWanted = math.max(energyWanted,0) -- Can't request negative power
                  energyWanted = math.min(energyWanted,fuelRates[f]) -- Can't make more power than the engines can support
                  local energyToGenerate = 0  --luacheck: ignore

                  --globalPrint("Stored "..modularArmor.storedFuel[x]..fuelType)
                  --globalPrint("Wanted "..energyWanted)
                  if (modularArmor.storedFuel[f] < 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 _,fuel in ipairs(equipment.fuel) do
                      if (mainInventory.get_item_count(fuel.name) > 0) then
                        -- Got some
                        validFuel = fuel
                        break
                      --else
                        -- No luck, skip it
                      end
                      --globalPrint(fuel[x][1].." "..mainInventory.get_item_count(fuel[x][1]))
                    end
                    if (validFuel) then
                      mainInventory.remove{name = validFuel.name, count = 1}
                      modularArmor.storedFuel[f] = modularArmor.storedFuel[f] + validFuel.power
                      --surface.create_entity{name="flying-text", position=thisPlayer.character.position, text=("-1 "..validFuel[1]), color={r=1,g=1,b=1}}
                      --globalPrint(validFuel[1].." "..modularArmor.storedFuel[x])
                    else
                      if RanaMods.ModularArmor.config.LowFuelMessage then
                        if (game.tick%RanaMods.ModularArmor.config.ticksPerSecond == 0) then
                          thisPlayer.character.surface.create_entity{name="flying-text", position=thisPlayer.character.position, text=("No "..(equipment.name).." fuel"), color={r=1,g=0.25,b=0.25}}
                          -- Needs a better feedback method.
                        end
                      end
                      -- Out of fuel
                      --globalPrint("No fuel")
                    end

                  --else
                    -- Have enough fuel already.
                  end
                  energyToGenerate = math.min(modularArmor.storedFuel[x],energyWanted)

                  modularArmor.storedFuel[x] = modularArmor.storedFuel[x] - energyToGenerate

                  energyToAdd = energyToAdd + energyToGenerate

                  --global.surface.pollute(thisPlayer.character.position, energyToGenerate*RanaMods.ModularArmor.config.pollutionCoef)

                  --end
                --else
                  -- No such generator.
                end
              --else
                -- Its a conduit.
              end
            end

            -- I have energy to add, Energy Cap, and current energy.
            -- I want to give amount proportional to amount missing to each elements. Ones with less get a higher fraction.
            -- The amount I have available needs to be split into fractions of amount missing overall.
            -- For each point missing from an element, add energyFraction to it.
            -- Calc extra as well, and if it is greater than like 10%, feed into accumulator for next tick.
            for _,equipment in ipairs(grid.equipment) do -- Basic Setup. Distribute as much to first in line, remainder to next, and next, till you run out.
              if (equipment.max_energy ~= 0 and energyToAdd > 0) then -- Poor Distribution method.
                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 -- Removed since it interferes with shield.
                end
              end
              if (equipment.max_shield ~= 0) then

                equipment.shield = equipment.max_shield * shieldFraction -- This part is a quick autobalance. All shields get equal power.
                --shieldHealth = shieldHealth + equipment.shield
                --equipment.shield = equipment.shield - (equipment.max_shield*ShieldDecayPerTick)
              --else -- Ideally, I want to send power from high efficiency ones to lower efficiency ones. That minimizes power consumption.

              end

            end

            modularArmor.units.accumulator.energy = RanaMods.ModularArmor.config.accumulatorEnergyCap - transferRate--*conversionRatio
            modularArmor.previousEnergy = modularArmor.units.accumulator.energy --*conversionRatio -- The additional accumulated energy over

          else
            killDummies(modularArmor)
          end
        else
          killDummies(modularArmor)
        end
      --else
        -- No player
        -- killDummies(modularArmor)
      end
    end
  end
end

local function ticker() -- run once per tickRate number of gameticks.
  if (game.tick % RanaMods.ModularArmor.config.tickRate) == 0 then
    tick()
  end
end
script.on_event(defines.events.on_tick, ticker)
User avatar
aubergine18
Smart Inserter
Smart Inserter
Posts: 1264
Joined: Fri Jul 22, 2016 8:51 pm
Contact:

Re: On Multiplayer Load, Register Table.

Post by aubergine18 »

Note the current EvoGUI remote interface only handles single player (new version in development that will allow multiplayer).
Better forum search for modders: Enclose your search term in quotes, eg. "font_color" or "custom-input" - it prevents the forum search from splitting on hypens and underscores, resulting in much more accurate results.
User avatar
Ranakastrasz
Smart Inserter
Smart Inserter
Posts: 2179
Joined: Thu Jun 12, 2014 3:05 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Ranakastrasz »

Eh, I was experimenting with that for a bit. but I haven't actually gotten around to doing anything with it.

Also, Evogui remote seems to work in multiplayer for other mods that use it.
My Mods:
Modular Armor Revamp - V16
Large Chests - V16
Agent Orange - V16
Flare - V16
Easy Refineries - V16
User avatar
aubergine18
Smart Inserter
Smart Inserter
Posts: 1264
Joined: Fri Jul 22, 2016 8:51 pm
Contact:

Re: On Multiplayer Load, Register Table.

Post by aubergine18 »

Ranakastrasz wrote:Eh, I was experimenting with that for a bit. but I haven't actually gotten around to doing anything with it.

Also, Evogui remote seems to work in multiplayer for other mods that use it.
It comes bundled with several internal sensors, which use a different API that handles multiplayer. As for external sensors, however, the current remote API doesn't provide any way for those to properly provide data for multiple players (they might still work, to an extent, but only for player 1). It's possible some mods manually add sensors without using the API (not recommended) to get around this limitation.
Better forum search for modders: Enclose your search term in quotes, eg. "font_color" or "custom-input" - it prevents the forum search from splitting on hypens and underscores, resulting in much more accurate results.
User avatar
Ranakastrasz
Smart Inserter
Smart Inserter
Posts: 2179
Joined: Thu Jun 12, 2014 3:05 am
Contact:

Re: On Multiplayer Load, Register Table.

Post by Ranakastrasz »

Eh, Off topic. Anyhow, Replacing the event with on_load seems to have fixed it for all of my test cases. Single player. Single Player Loaded. Multiplayer. Multiplayer Loaded. Multiplayer Loaded, saved, Loaded.

Presumably I missed something and it will explode, but it is at least pretending to work again, so I am kinda happy.





Now I can go and try to poke those new-fangled equipment alteration events, as well as table manipulation and so on.
My Mods:
Modular Armor Revamp - V16
Large Chests - V16
Agent Orange - V16
Flare - V16
Easy Refineries - V16
Post Reply

Return to “Modding help”