diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..84900fd --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 avosirenfal + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Localized_Charging_1.0.0/constants.lua b/Localized_Charging_1.0.0/constants.lua new file mode 100644 index 0000000..f6edc96 --- /dev/null +++ b/Localized_Charging_1.0.0/constants.lua @@ -0,0 +1,4 @@ +require('volt_util') + +scan_tick = ms_to_ticks(500) +vehicle_inventory_check = ms_to_ticks(1000) \ No newline at end of file diff --git a/Localized_Charging_1.0.0/control.lua b/Localized_Charging_1.0.0/control.lua new file mode 100644 index 0000000..e723c54 --- /dev/null +++ b/Localized_Charging_1.0.0/control.lua @@ -0,0 +1,304 @@ +require('constants') + +script.on_init(function() + global.interfaces = {} + global.vehicles = {} +end) + +local charging_info = { + ["localized-charging-pole"] = { + ['interface'] = 'localized-charging-pole-interface', + ['range'] = 10, + ['efficiency'] = 0.5, + }, +} + +local electric_vehicles = { + ['electric-locomotive'] = true, + -- airship mod lol + ['gunship'] = true, + ['jet'] = true, + ['cargo-plane'] = true, + ['flying-fortress'] = true, + -- predictabowl vehicle mammoth tank + ['tank-mk3'] = true, +} + +local function defaultdict(d) + t = {} + setmetatable(t, { + __index = function (t, k) + local ret = d() + rawset(t, k, ret) + return ret + end + }) + return t +end + +local function get_chargable_items(grid) + local items = {} + + for _, item in pairs(grid.equipment) do + if(item.max_energy - item.energy > 0) then + table.insert(items, item) + end + end + + return items +end + +script.on_event(defines.events.on_tick, function(event) + local remove = {} + + for k, vehicle_info in pairs(global.vehicles) do + vehicle = vehicle_info.vehicle + + if(not vehicle.valid) then + table.insert(remove, k) + elseif(vehicle.grid ~= nil) then + local grid = vehicle.grid + local available_power = grid.available_in_batteries + local current_power = vehicle.energy + -- vehicles have a maximum energy cap that we have no way to read, so just get a delta to determine what we spent + vehicle.energy = vehicle.energy + available_power + local spent_power = vehicle.energy - current_power + + if(spent_power > 0) then + for _, item in pairs(grid.equipment) do + if(item.energy > 0) then + if(item.energy > spent_power) then + item.energy = item.energy - spent_power + break + else + spent_power = spent_power - item.energy + item.energy = 0 + end + end + end + end + end + end + + for _, k in pairs(remove) do + global.vehicles[k] = nil + end + + if not (game.tick % scan_tick == 0) then + return + end + + local targets = {} + local split = defaultdict(function() return 0 end) + + -- vehicles are checked for validity in the upper loop + for _, vehicle_info in pairs(global.vehicles) do + vehicle = vehicle_info.vehicle + + if(vehicle_info.charging == true or (game.tick - vehicle_info.lastCheck > vehicle_inventory_check)) then + vehicle_info.lastCheck = game.tick + + -- maybe grid can be situational in future patches, who knows? + local grid = vehicle.grid + local hit = false + + if(grid ~= nil and grid.battery_capacity - grid.available_in_batteries > 0) then + local pt = { + ['ent'] = vehicle, + ['grid'] = grid, + ['towers'] = {}, + } + + for name, info in pairs(charging_info) do + for _, tower in pairs(game.surfaces[1].find_entities_filtered{ + area={ + {vehicle.position['x'] - info['range'], vehicle.position['y'] - info['range']}, + {vehicle.position['x'] + info['range'], vehicle.position['y'] + info['range']}, + }, + name=name, + }) do + if(tower.force.name == vehicle.force.name and global.interfaces[tower.unit_number].energy > 0) then + -- towers can charge multiple targets, find out which way the power will be split before actually doing the charge tick + if(hit ~= true) then + table.insert(targets, pt) + hit = true + end + + table.insert(pt.towers, tower) + split[tower.unit_number] = split[tower.unit_number] + 1 + end + end + end + end + + vehicle_info.charging = hit + end + end + + for _, player in pairs(game.connected_players) do + if(player.controller_type ~= defines.controllers.ghost and player.character ~= nil) then + -- armor inventory is a one length inventory + local item = player.get_inventory(defines.inventory.player_armor)[1] + + if(item.valid_for_read and item.grid and item.grid.battery_capacity - item.grid.available_in_batteries > 0) then + local hit = false + local pt = { + ['ent'] = player.character, + ['grid'] = item.grid, + ['towers'] = {}, + } + + for name, info in pairs(charging_info) do + for _, tower in pairs(game.surfaces[1].find_entities_filtered{ + area={ + {player.position['x'] - info['range'], player.position['y'] - info['range']}, + {player.position['x'] + info['range'], player.position['y'] + info['range']}, + }, + name=name, + }) do + if(tower.force.name == player.force.name and global.interfaces[tower.unit_number].energy > 0) then + -- towers can charge multiple targets, find out which way the power will be split before actually doing the charge tick + if(hit ~= true) then + table.insert(targets, pt) + hit = true + end + + table.insert(pt.towers, tower) + split[tower.unit_number] = split[tower.unit_number] + 1 + end + end + end + end + end + end + + for _, info in pairs(targets) do + local grid = info.grid + local items = get_chargable_items(grid) + local item = table.remove(items, 1) + + if(item == nil) then -- wat + game.print('Voltage: this should never happen: no chargable items?') + error('Voltage: this should never happen: no chargable items?') + end + + for _, tower in pairs(info.towers) do + local power_info = charging_info[tower.name] + local interface = global.interfaces[tower.unit_number] + + -- lightning effect + game.surfaces[1].create_entity{ + name = "charging-charge", + position = {tower.position['x'], tower.position['y'] - 1.5}, + force = info.ent.force, + target = info.ent + } + + repeat + local s = split[tower.unit_number] + + if(s == nil or s < 1) then + error('Voltage: invalid tower split: ' .. tostring(s)) + end + + -- use ceil here to counter float imprecision + local transfer = math.ceil(math.min(item.max_energy - item.energy, interface.energy / s)) + interface.energy = interface.energy - transfer + item.energy = item.energy + math.ceil(transfer * power_info.efficiency) + + if(item.max_energy - item.energy < 1) then + -- charge the next item + item = table.remove(items, 1) + + -- everything has been charged + if(item == nil) then + break + end + end + until interface.energy < 1 + + if(item == nil) then + break + end + end + end +end) + +local function on_entity_created(entity) + if(charging_info[entity.name] ~= nil) then + local uid = entity.unit_number + local interface = game.surfaces[1].create_entity{ + name = "localized-charging-pole-interface", + position = {entity.position['x'], entity.position['y']}, + -- stop ai in everything mode from attacking this invulnerable building + force=game.forces['enemy'] --entity.force + } + + interface.operable = false + interface.destructible = false + interface.minable = false + + global.interfaces[uid] = interface + elseif(electric_vehicles[entity.name] ~= nil) then + -- trains could be paused here if they haven't been detected as moving + -- cars, etc can't be paused by event because there's no way to detect their inventory changing as it happens (no event) + table.insert(global.vehicles, { + ['vehicle'] = entity, + ['charging'] = false, + -- the last time the grid was scanned for non-empty batteries + ['lastCheck'] = 0, + }) + end +end + +local function on_entity_deleted(entity) + local interface = global.interfaces[entity.unit_number] + + if(interface ~= nil) then + interface.destroy() + end +end + +-- hooks + +script.on_event(defines.events.on_robot_built_entity, function(event) + on_entity_created(event.created_entity) +end) + +script.on_event(defines.events.on_built_entity, function(event) + on_entity_created(event.created_entity) +end) + + +script.on_event(defines.events.on_entity_died, function(event) + on_entity_deleted(event.entity) +end) + +script.on_event(defines.events.on_preplayer_mined_item, function(event) + on_entity_deleted(event.entity) +end) + +script.on_event(defines.events.on_robot_pre_mined, function(event) + on_entity_deleted(event.entity) +end) + + +-- unpause vehicle when player starts driving it, repause it with a player -> vehicle map to determine +-- which vehicle stopped driving +-- this is for tanks, jets, etc +-- +-- script.on_event(defines.events.on_player_driving_changed_state, function(event) +-- local player = game.players[event.player_index] + +-- if(player.vehicle == nil) then +-- return +-- end + +-- local entity = player.vehicle + +-- if(entity.name == 'electric-locomotive') then +-- local current = entity.energy +-- entity.energy = entity.energy + 1000 +-- game.print('added: ' .. tostring(entity.energy - current)) +-- end +-- end) \ No newline at end of file diff --git a/Localized_Charging_1.0.0/data.lua b/Localized_Charging_1.0.0/data.lua new file mode 100644 index 0000000..cde766c --- /dev/null +++ b/Localized_Charging_1.0.0/data.lua @@ -0,0 +1,5 @@ +require('prototypes.items') +require('prototypes.recipes') +require('prototypes.charger') +require('prototypes.vehicles') +require('prototypes.technologies') \ No newline at end of file diff --git a/Localized_Charging_1.0.0/graphics/entity/localized-charging-pole/bright.png b/Localized_Charging_1.0.0/graphics/entity/localized-charging-pole/bright.png new file mode 100644 index 0000000..c9bbdfd Binary files /dev/null and b/Localized_Charging_1.0.0/graphics/entity/localized-charging-pole/bright.png differ diff --git a/Localized_Charging_1.0.0/graphics/entity/localized-charging-pole/powered.png b/Localized_Charging_1.0.0/graphics/entity/localized-charging-pole/powered.png new file mode 100644 index 0000000..8b980d8 Binary files /dev/null and b/Localized_Charging_1.0.0/graphics/entity/localized-charging-pole/powered.png differ diff --git a/Localized_Charging_1.0.0/graphics/entity/localized-charging-pole/unpowered.png b/Localized_Charging_1.0.0/graphics/entity/localized-charging-pole/unpowered.png new file mode 100644 index 0000000..9bdf193 Binary files /dev/null and b/Localized_Charging_1.0.0/graphics/entity/localized-charging-pole/unpowered.png differ diff --git a/Localized_Charging_1.0.0/graphics/entity/projectile/induction-charge-beam.png b/Localized_Charging_1.0.0/graphics/entity/projectile/induction-charge-beam.png new file mode 100644 index 0000000..8e47fc5 Binary files /dev/null and b/Localized_Charging_1.0.0/graphics/entity/projectile/induction-charge-beam.png differ diff --git a/Localized_Charging_1.0.0/graphics/icons/electric-locomotive.png b/Localized_Charging_1.0.0/graphics/icons/electric-locomotive.png new file mode 100644 index 0000000..472f6c4 Binary files /dev/null and b/Localized_Charging_1.0.0/graphics/icons/electric-locomotive.png differ diff --git a/Localized_Charging_1.0.0/graphics/icons/localized-charging-pole.png b/Localized_Charging_1.0.0/graphics/icons/localized-charging-pole.png new file mode 100644 index 0000000..b6c9cfa Binary files /dev/null and b/Localized_Charging_1.0.0/graphics/icons/localized-charging-pole.png differ diff --git a/Localized_Charging_1.0.0/graphics/technology/electric-trains.png b/Localized_Charging_1.0.0/graphics/technology/electric-trains.png new file mode 100644 index 0000000..c642878 Binary files /dev/null and b/Localized_Charging_1.0.0/graphics/technology/electric-trains.png differ diff --git a/Localized_Charging_1.0.0/info.json b/Localized_Charging_1.0.0/info.json new file mode 100644 index 0000000..7e6a568 --- /dev/null +++ b/Localized_Charging_1.0.0/info.json @@ -0,0 +1,10 @@ + +{ + "name": "Localized_Charging", + "version": "1.0.0", + "title": "Localized_Charging", + "author": "Sirenfal", + "description": "Wireless electricity mod", + "dependencies": ["base >= 0.14.0"], + "factorio_version": "0.14.0" +} diff --git a/Localized_Charging_1.0.0/locale/en.cfg b/Localized_Charging_1.0.0/locale/en.cfg new file mode 100644 index 0000000..9b08dbf --- /dev/null +++ b/Localized_Charging_1.0.0/locale/en.cfg @@ -0,0 +1,13 @@ +[entity-name] +localized-charging-pole=Localized Charging Pole + +[vehicles] +electric-locomotive=Electric Locomotive + +[technology-name] +voltage-electric-trains=Electric Trains +voltage-wireless-energy-distribution=Wireless Energy Distribution + +[technology-description] +voltage-electric-trains=Higher powered trains that run off of electric batteries. +voltage-wireless-energy-distribution=A powerful charging system that will charge nearby power armor and certain electric vehicles at 20MW/s. It will use 40MW/s because the charging is inefficient. diff --git a/Localized_Charging_1.0.0/prototypes/charger.lua b/Localized_Charging_1.0.0/prototypes/charger.lua new file mode 100644 index 0000000..b2a0b17 --- /dev/null +++ b/Localized_Charging_1.0.0/prototypes/charger.lua @@ -0,0 +1,144 @@ +require('constants') + +-- in megawatts per second +local charging_output = 40 + +data:extend({ + { + type = "explosion", + name = "charging-charge", + flags = {"not-on-map", "placeable-off-grid"}, + animation_speed = 1, + rotate = true, + beam = true, + animations = + { + { + filename = "__Localized_Charging__/graphics/entity/projectile/induction-charge-beam.png", + priority = "extra-high", + width = 20, + height = 70, + frame_count = 6, + } + }, + light = { + intensity = 0.15, + size = 14, + shift = {0, 1.5}, + color = {r = 70 / 255, g = 153 / 255, b = 223 / 255}, + }, + -- smoke = "smoke-fast", + -- smoke_count = 1, + -- smoke_slow_down_factor = 1 + }, + { + type = "electric-energy-interface", + name = "localized-charging-pole-interface", + icon = "__Localized_Charging__/graphics/icons/localized-charging-pole.png", + localised_name = {'entity-name.localized-charging-pole'}, + collision_box = {{-0.65, -0.65}, {0.65, 0.65}}, + flags = {"not-blueprintable", "not-deconstructable", "not-on-map", "placeable-off-grid"}, + max_health = 0, + corpse = "medium-remnants", + collision_mask = {}, + energy_source = + { + type = "electric", + buffer_capacity = ((charging_output * scan_tick) / 60) .. 'MJ', + usage_priority = "secondary-input", + input_flow_limit = (charging_output * scan_tick) .. 'MW', + output_flow_limit = "0W" + }, + energy_production = "0W", + energy_usage = "0kW", + picture = + { + filename = "__core__/graphics/empty.png", + priority = "low", + width = 1, + height = 1, + }, + }, + { + type = "electric-pole", + name = 'localized-charging-pole', + localised_name = {'entity-name.localized-charging-pole'}, + icon = "__Localized_Charging__/graphics/icons/localized-charging-pole.png", + flags = {"placeable-neutral", "player-creation"}, + minable = {hardness = 0.2, mining_time = 0.5, result = "localized-charging-pole"}, + max_health = 400, + corpse = "medium-remnants", + resistances = + { + { + type = "fire", + percent = 100 + } + }, + collision_box = {{-0.65, -0.65}, {0.65, 0.65}}, + selection_box = {{-1, -1}, {1, 1}}, + drawing_box = {{-1, -3}, {1, 0.5}}, + maximum_wire_distance = 30, + supply_area_distance = 0, + vehicle_impact_sound = { filename = "__base__/sound/car-metal-impact.ogg", volume = 0.65 }, + pictures = + { + filename = '__Localized_Charging__/graphics/entity/localized-charging-pole/powered.png', + priority = "high", + width = 168, + height = 165, + direction_count = 4, + shift = {1.6, -1.1} + }, + connection_points = + { + { + shadow = + { + copper = {2.7, 0}, + }, + wire = + { + copper = {0, -3.125}, + } + }, + { + shadow = + { + copper = {3.1, 0.2}, + }, + wire = + { + copper = {-0.0625, -3.125}, + } + }, + { + shadow = + { + copper = {2.9, 0.06}, + }, + wire = + { + copper = {-0.09375, -3.09375}, + } + }, + { + shadow = + { + copper = {3.1, 0.2}, + }, + wire = + { + copper = {-0.0625, -3.1875}, + } + } + }, + radius_visualisation_picture = + { + filename = "__base__/graphics/entity/small-electric-pole/electric-pole-radius-visualization.png", + width = 12, + height = 12, + priority = "extra-high-no-scale" + }, + }, +}) \ No newline at end of file diff --git a/Localized_Charging_1.0.0/prototypes/items.lua b/Localized_Charging_1.0.0/prototypes/items.lua new file mode 100644 index 0000000..c9c0eab --- /dev/null +++ b/Localized_Charging_1.0.0/prototypes/items.lua @@ -0,0 +1,22 @@ +require('volt_util') + +data:extend({ + { + type = "item", + name = "localized-charging-pole", + localised_name = {'entity-name.localized-charging-pole'}, + icon = "__Localized_Charging__/graphics/icons/localized-charging-pole.png", + flags = {"goes-to-quickbar"}, + subgroup = "energy-pipe-distribution", + order = "a[energy]-b[localized-charging-pole]", + place_result = "localized-charging-pole", + stack_size = 10 + }, + clone_existing_data(data.raw['item-with-entity-data']['diesel-locomotive'], { + name = "electric-locomotive", + localised_name={'vehicles.electric-locomotive'}, + icon = "__Localized_Charging__/graphics/icons/electric-locomotive.png", + order = "a[train-system]-f[electric-locomotive]", + place_result = "electric-locomotive", + }), +}) \ No newline at end of file diff --git a/Localized_Charging_1.0.0/prototypes/recipes.lua b/Localized_Charging_1.0.0/prototypes/recipes.lua new file mode 100644 index 0000000..5f15d30 --- /dev/null +++ b/Localized_Charging_1.0.0/prototypes/recipes.lua @@ -0,0 +1,30 @@ +data:extend({ + { + type = "recipe", + name = "localized-charging-pole", + localised_name = {'entity-name.localized-charging-pole'}, + enabled = false, + ingredients = { + {"advanced-circuit", 50}, + {"electronic-circuit", 125}, + {"iron-plate", 150}, + {"steel-plate", 30}, + {"wood", 5}, + {"battery", 50}, + }, + result = "localized-charging-pole", + }, + { + type = "recipe", + name = "electric-locomotive", + localised_name = {'vehicles.electric-locomotive'}, + enabled = false, + ingredients = { + {"electric-engine-unit", 50}, + {"electronic-circuit", 50}, + {"steel-plate", 75}, + {"effectivity-module", 5}, + }, + result = "electric-locomotive" + }, +}) \ No newline at end of file diff --git a/Localized_Charging_1.0.0/prototypes/technologies.lua b/Localized_Charging_1.0.0/prototypes/technologies.lua new file mode 100644 index 0000000..0ee861f --- /dev/null +++ b/Localized_Charging_1.0.0/prototypes/technologies.lua @@ -0,0 +1,47 @@ +data:extend({ + { + type = "technology", + name = "voltage-electric-trains", + icon = "__Localized_Charging__/graphics/technology/electric-trains.png", + icon_size = 128, + effects = { + { + type = "unlock-recipe", + recipe = "electric-locomotive", + }, + }, + prerequisites = {"railway", "effectivity-module"}, + unit = { + count = 200, + ingredients = { + {"science-pack-1", 1}, + {"science-pack-2", 1}, + {"science-pack-3", 1}, + }, + time = 45, + }, + order = "c-g-d", + }, + { + type = "technology", + name = "voltage-wireless-energy-distribution", + icon = "__base__/graphics/technology/electric-energy-distribution.png", + effects = { + { + type = "unlock-recipe", + recipe = "localized-charging-pole", + } + }, + prerequisites = {"electric-energy-distribution-2"}, + unit = { + count = 200, + ingredients = { + {"science-pack-1", 1}, + {"science-pack-2", 1}, + {"science-pack-3", 1} + }, + time = 45 + }, + order = "c-e-c", + }, +}) diff --git a/Localized_Charging_1.0.0/prototypes/vehicles.lua b/Localized_Charging_1.0.0/prototypes/vehicles.lua new file mode 100644 index 0000000..e7c73c2 --- /dev/null +++ b/Localized_Charging_1.0.0/prototypes/vehicles.lua @@ -0,0 +1,58 @@ +require('volt_util') + + +data:extend({ + { + type = "equipment-grid", + name = "voltage-electric-locomotive", + width = 10, + height = 10, + equipment_categories = {"armor"}, + }, + clone_existing_data(data.raw.locomotive['diesel-locomotive'], { + name='electric-locomotive', + localised_name={'vehicles.electric-locomotive'}, + icon = "__Localized_Charging__/graphics/icons/electric-locomotive.png", + minable = {mining_time = 1, result = "electric-locomotive"}, + weight = 1750, + max_speed = 1.5, + max_power = "2MW", + reversing_power_modifier = 1.0, + braking_force = 30, + order="electric-locomotive", + equipment_grid = "voltage-electric-locomotive", + equipment_categories = {"armor"}, + energy_source = + { + type = "burner", + effectivity = 1, + fuel_inventory_size = 0, + }, + front_light = { + __partial__ = true, + { + picture = + { + scale = 4.5, + }, + size = 4.5, + intensity = 0.75 + }, + { + picture = + { + scale = 4.5, + }, + size = 4.5, + intensity = 0.75 + } + }, + working_sound = { + sound = { + filename = "__base__/sound/electric-furnace.ogg", + volume = 0.4, + }, + match_speed_to_activity = true, + }, + }), +}) \ No newline at end of file diff --git a/Localized_Charging_1.0.0/volt_util.lua b/Localized_Charging_1.0.0/volt_util.lua new file mode 100644 index 0000000..14f1f6b --- /dev/null +++ b/Localized_Charging_1.0.0/volt_util.lua @@ -0,0 +1,43 @@ +require('util') + +function ms_to_ticks(ms) + return math.ceil(ms / (1000 / 60)) +end + +local function _clone_onto(source, override, partial) + local partial = partial or false + + if(override['__partial__'] ~= nil) then + partial = true + override['__partial__'] = nil + else + return override + end + + -- TODO: handle numeric-only arrays specially here (merge properly if partial) + + for k,v in pairs(override) do + if(source[k] ~= nil and type(source[k]) == 'table') then + source[k] = _clone_onto(source[k], v, true) + else + -- __partial__ will leak for tables here, but who cares? + source[k] = v + end + end + + return source +end + +-- each key will fully replace that key unless __partial__ is in the table, in which case +-- it will be merged with any keys from this table replacing keys in the source table +-- partial true/false is recursive after each occurence +function clone_existing_data(entry, data) + if(entry == nil) then + error('Tried to clone non-existant data key') + end + + local new = table.deepcopy(entry) + data['__partial__'] = true + + return _clone_onto(new, data) +end \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a304ce3 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# What does this mod do? + +This mod is a replacement for Wireless Charging because that mod was unfortunately causing desyncs on my multiplayer server. This mod is a bit different, since I had the opportunity to change things anyway. + +This mod adds a much more powerful electric train. It may be slightly overpowered, balance isn't one of my concerns. I will happily accept suggestions. + +The Localized Charging Pole will recharge all nearby chargable targets: players, electric trains, aircraft from the Aircraft mod (no changes required). Electric vehicles like aircraft and electric trains can move solely on power from the batteries in their equipment grid. Aircraft, being able to use coal, will use coal as a backup source if there is no more power available to move with. + +The pole recharges at 20MW/s, split across any targets (e.g. if two things are being charged each will receive 10MW/s). The pole consumes 40MW/s, only recharging at 50% efficiency. + +# (For developers) Compatibility + +I haven't specifically written this mod for other people to interact with, but I would be happy to add/help support any other mods. If you want to do things with my mod I should probably add an API. Please let me know, or submit a PR yourself. \ No newline at end of file