mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-10 00:43:27 +02:00
165 lines
4.9 KiB
Lua
165 lines
4.9 KiB
Lua
local Event = require 'utils.event'
|
|
local Global = require 'utils.global'
|
|
|
|
local state = {}
|
|
Global.register(state, function(s) state = s end)
|
|
|
|
local function create_gui_button(player)
|
|
if player.gui.top.melee_mode then
|
|
return
|
|
end
|
|
local tooltip = 'Melee/Ranged mode toggle. Guns and ammo will stay in inventory in melee mode and be restored in ranged mode'
|
|
local b = player.gui.top.add({
|
|
type = 'sprite-button',
|
|
sprite = 'item/pistol',
|
|
name = 'melee_mode',
|
|
tooltip = tooltip})
|
|
b.style.font_color = {r = 0.11, g = 0.8, b = 0.44}
|
|
b.style.font = 'heading-1'
|
|
b.style.minimal_height = 40
|
|
b.style.maximal_width = 40
|
|
b.style.minimal_width = 38
|
|
b.style.maximal_height = 38
|
|
b.style.padding = 1
|
|
b.style.margin = 0
|
|
end
|
|
|
|
local function on_player_joined_game(event)
|
|
create_gui_button(game.players[event.player_index])
|
|
end
|
|
|
|
local function move_to_main(player, from, to)
|
|
local ret = {}
|
|
if from == nil or to == nil then
|
|
return {}
|
|
end
|
|
for i = 1, #from do
|
|
local c = from[i]
|
|
if c.valid_for_read then
|
|
if to.can_insert(c) then
|
|
local amt = to.insert(c)
|
|
ret[#ret + 1] = { name=c.name, count=amt }
|
|
c.count = c.count - amt
|
|
else
|
|
player.print('Unable to move ' .. c.name .. ' to main inventory')
|
|
end
|
|
end
|
|
end
|
|
return ret
|
|
end
|
|
|
|
local function change_to_melee(player)
|
|
local main_inv = player.get_main_inventory()
|
|
local gun_inv = player.get_inventory(defines.inventory.character_guns)
|
|
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
|
|
if main_inv == nil or gun_inv == nil or ammo_inv == nil then
|
|
return false
|
|
end
|
|
local gun_moved = move_to_main(player, gun_inv, main_inv)
|
|
local ammo_moved = move_to_main(player, ammo_inv, main_inv)
|
|
|
|
state[player.index] = { gun = gun_moved, ammo = ammo_moved }
|
|
return true
|
|
end
|
|
|
|
local function try_move_from_main(main, to, what)
|
|
if what == nil or main == nil or to == nil then
|
|
return
|
|
end
|
|
for i = 1, #what do
|
|
local amt_out = main.remove(what[i])
|
|
if amt_out > 0 then
|
|
local amt_in = to.insert({name = what[i].name, count = amt_out})
|
|
if amt_in < amt_out then
|
|
main.insert({name = what[i].name, count = amt_out - amt_in})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function change_to_ranged(player)
|
|
local moved = state[player.index]
|
|
if moved == nil then
|
|
moved = {}
|
|
end
|
|
local main_inv = player.get_main_inventory()
|
|
local gun_inv = player.get_inventory(defines.inventory.character_guns)
|
|
local ammo_inv = player.get_inventory(defines.inventory.character_ammo)
|
|
if main_inv == nil or gun_inv == nil or ammo_inv == nil then
|
|
return false
|
|
end
|
|
try_move_from_main(main_inv, gun_inv, moved.gun)
|
|
try_move_from_main(main_inv, ammo_inv, moved.ammo)
|
|
state[player.index] = {}
|
|
return true
|
|
end
|
|
|
|
local function on_gui_click(event)
|
|
if not event.element then
|
|
return
|
|
end
|
|
if not event.element.valid then
|
|
return
|
|
end
|
|
if event.element.name ~= 'melee_mode' then
|
|
return
|
|
end
|
|
local player = game.players[event.player_index]
|
|
local mm = player.gui.top.melee_mode
|
|
if mm.sprite == 'item/pistol' then
|
|
if change_to_melee(player) then
|
|
player.print('Switching to melee mode, ammo and weapons will stay in main inventory')
|
|
mm.sprite = 'item/dummy-steel-axe'
|
|
else
|
|
player.print('Unable to switch to melee mode. Are you dead?')
|
|
end
|
|
else
|
|
if change_to_ranged(player) then
|
|
player.print('Switching to ranged mode, trying to restore previous guns and ammo')
|
|
mm.sprite = 'item/pistol'
|
|
else
|
|
player.print('Unable to switch to ranged mode. Are you dead?')
|
|
end
|
|
end
|
|
end
|
|
|
|
local function moved_to_string(tbl)
|
|
local ret = ''
|
|
for i = 1, #tbl do
|
|
if ret ~= '' then
|
|
ret = ret .. ', '
|
|
end
|
|
ret = ret .. tbl[i].count .. ' ' .. tbl[i].name
|
|
end
|
|
return ret
|
|
end
|
|
|
|
local function player_inventory_changed(player_index, inv_id, name)
|
|
local player = game.players[player_index]
|
|
if player.gui.top.melee_mode.sprite == 'item/pistol' then
|
|
return
|
|
end
|
|
local inv = player.get_inventory(inv_id)
|
|
local moved = move_to_main(player, inv, player.get_main_inventory())
|
|
if #moved > 0 then
|
|
player.print('In melee mode, moved ' .. moved_to_string(moved) .. ' to main inventory')
|
|
end
|
|
if not inv.is_empty() then
|
|
player.print('WARNING: in melee mode, unable to empty ' .. name .. ' to main inventory')
|
|
end
|
|
end
|
|
|
|
local function on_player_ammo_inventory_changed(event)
|
|
player_inventory_changed(event.player_index, defines.inventory.character_ammo, 'ammo')
|
|
end
|
|
|
|
local function on_player_gun_inventory_changed(event)
|
|
player_inventory_changed(event.player_index, defines.inventory.character_guns, 'guns')
|
|
end
|
|
|
|
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
|
Event.add(defines.events.on_gui_click, on_gui_click)
|
|
Event.add(defines.events.on_player_ammo_inventory_changed, on_player_ammo_inventory_changed)
|
|
Event.add(defines.events.on_player_gun_inventory_changed, on_player_gun_inventory_changed)
|
|
|