Skip to content

Commit

Permalink
* Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
avosirenfal committed Jan 9, 2017
0 parents commit aae9c8d
Show file tree
Hide file tree
Showing 20 changed files with 714 additions and 0 deletions.
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 4 additions & 0 deletions Localized_Charging_1.0.0/constants.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require('volt_util')

scan_tick = ms_to_ticks(500)
vehicle_inventory_check = ms_to_ticks(1000)
304 changes: 304 additions & 0 deletions Localized_Charging_1.0.0/control.lua
Original file line number Diff line number Diff line change
@@ -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)
5 changes: 5 additions & 0 deletions Localized_Charging_1.0.0/data.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
require('prototypes.items')
require('prototypes.recipes')
require('prototypes.charger')
require('prototypes.vehicles')
require('prototypes.technologies')
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions Localized_Charging_1.0.0/info.json
Original file line number Diff line number Diff line change
@@ -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"
}
13 changes: 13 additions & 0 deletions Localized_Charging_1.0.0/locale/en.cfg
Original file line number Diff line number Diff line change
@@ -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.
Loading

0 comments on commit aae9c8d

Please sign in to comment.