1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-02-07 13:31:40 +02:00

Merge pull request #155 from ComfyFactory/mtn_v3

Mtn v3 - refactor files and minor change
This commit is contained in:
Gerkiz 2021-11-07 02:40:54 +01:00 committed by GitHub
commit 793dea005f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 2716 additions and 2601 deletions

View File

@ -10,6 +10,7 @@ local Mining = require 'maps.mountain_fortress_v3.mining'
local Terrain = require 'maps.mountain_fortress_v3.terrain'
local Traps = require 'maps.mountain_fortress_v3.traps'
local Locomotive = require 'maps.mountain_fortress_v3.locomotive'
local DefenseSystem = require 'maps.mountain_fortress_v3.locomotive.defense_system'
local Collapse = require 'modules.collapse'
local Alert = require 'utils.alert'
local Task = require 'utils.task'
@ -228,7 +229,7 @@ local function set_train_final_health(final_damage_amount, repair)
if carriages then
for i = 1, #carriages do
local entity = carriages[i]
Locomotive.enable_poison_defense(entity.position)
DefenseSystem.enable_poison_defense(entity.position)
end
end
@ -247,7 +248,7 @@ local function set_train_final_health(final_damage_amount, repair)
for _ = 1, 10 do
for i = 1, #carriages do
local entity = carriages[i]
Locomotive.enable_robotic_defense(entity.position)
DefenseSystem.enable_robotic_defense(entity.position)
end
end
end

View File

@ -610,6 +610,17 @@ local function get_player_data(player)
return players[player.index]
end
local function get_persistent_player_data(player)
local players = IC.get('players_persistent')
local player_data = players[player.index]
if players[player.index] then
return player_data
end
players[player.index] = {}
return players[player.index]
end
local remove_car =
Token.register(
function(data)
@ -936,18 +947,30 @@ function Public.create_car_room(car)
end
end
local fishes = {}
for x = area.left_top.x, area.right_bottom.x - 1, 1 do
for y = -0, 1, 1 do
tiles[#tiles + 1] = {name = 'water', position = {x, y}}
fishes[#fishes + 1] = {name = 'fish', position = {x, y}}
end
end
surface.set_tiles(tiles, true)
for _, fish in pairs(fishes) do
surface.create_entity(fish)
local p = game.get_player(car.owner)
if p and p.valid then
local player_data = get_persistent_player_data(p)
if not player_data.placed_fish then
local fishes = {}
for x = area.left_top.x, area.right_bottom.x - 1, 1 do
for y = -0, 1, 1 do
fishes[#fishes + 1] = {name = 'fish', position = {x, y}}
end
end
for _, fish in pairs(fishes) do
surface.create_entity(fish)
end
player_data.placed_fish = true
end
end
construct_doors(car)

View File

@ -39,6 +39,7 @@ function Public.reset()
this.allowed_surface = 'nauvis'
this.trust_system = {}
this.players = {}
this.players_persistent = {}
this.player_gui_data = {}
this.surfaces = {}
this.minimap = {}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
local WPT = require 'maps.mountain_fortress_v3.table'
local random = math.random
local rad = math.rad
local sin = math.sin
local cos = math.cos
local Public = {}
local function create_defense_system(position, name, target)
local active_surface_index = WPT.get('active_surface_index')
local surface = game.surfaces[active_surface_index]
local random_angles = {
rad(random(359)),
rad(random(359)),
rad(random(359)),
rad(random(359))
}
surface.create_entity(
{
name = name,
position = {x = position.x, y = position.y},
target = target,
speed = 1.5,
force = 'player'
}
)
surface.create_entity(
{
name = name,
position = {
x = position.x + 12 * cos(random_angles[1]),
y = position.y + 12 * sin(random_angles[1])
},
target = target,
speed = 1.5,
force = 'player'
}
)
surface.create_entity(
{
name = name,
position = {
x = position.x + 12 * cos(random_angles[2]),
y = position.y + 12 * sin(random_angles[2])
},
target = target,
speed = 1.5,
force = 'player'
}
)
surface.create_entity(
{
name = name,
position = {
x = position.x + 12 * cos(random_angles[3]),
y = position.y + 12 * sin(random_angles[3])
},
target = target,
speed = 1.5,
force = 'player'
}
)
surface.create_entity(
{
name = name,
position = {
x = position.x + 12 * cos(random_angles[4]),
y = position.y + 12 * sin(random_angles[4])
},
target = target,
speed = 1.5,
force = 'player'
}
)
end
function Public.enable_poison_defense(pos)
local locomotive = WPT.get('locomotive')
if not locomotive then
return
end
if not locomotive.valid then
return
end
pos = pos or locomotive.position
create_defense_system({x = pos.x, y = pos.y}, 'poison-cloud', pos)
if random(1, 4) == 1 then
local random_angles = {rad(random(344))}
create_defense_system({x = pos.x + 24 * cos(random_angles[1]), y = pos.y + -24 * sin(random_angles[1])}, 'poison-cloud', pos)
end
end
function Public.enable_robotic_defense(pos)
local locomotive = WPT.get('locomotive')
if not locomotive then
return
end
if not locomotive.valid then
return
end
pos = pos or locomotive.position
create_defense_system({x = pos.x, y = pos.y}, 'destroyer-capsule', pos)
if random(1, 4) == 1 then
local random_angles = {rad(random(324))}
create_defense_system({x = pos.x + 24 * cos(random_angles[1]), y = pos.y + -24 * sin(random_angles[1])}, 'destroyer-capsule', pos)
end
end
return Public

View File

@ -0,0 +1,126 @@
local Event = require 'utils.event'
local WPT = require 'maps.mountain_fortress_v3.table'
local random = math.random
local Public = {}
local function shoo(event)
local icw_locomotive = WPT.get('icw_locomotive')
local loco_surface = icw_locomotive.surface
if not loco_surface.valid then
return
end
local player = game.players[event.player_index]
if player and player.valid then
if player.surface.index ~= loco_surface.index then
return
end
end
local locomotive_biter = WPT.get('locomotive_biter')
local surface = player.surface
local message = event.message
message = string.lower(message)
for word in string.gmatch(message, '%g+') do
if word == 'shoo' then
if not locomotive_biter or not locomotive_biter.valid then
Public.spawn_biter()
return
end
surface.create_entity(
{
name = 'rocket',
position = locomotive_biter.position,
force = 'enemy',
speed = 1,
max_range = 1200,
target = locomotive_biter,
source = locomotive_biter
}
)
if locomotive_biter and locomotive_biter.valid then
local explosion = {
name = 'massive-explosion',
position = locomotive_biter.position
}
surface.create_entity(explosion)
locomotive_biter.destroy()
WPT.set().locomotive_biter = nil
end
return
end
end
end
function Public.spawn_biter()
local this = WPT.get()
local loco_surface = this.icw_locomotive.surface
if not loco_surface.valid then
return
end
local locomotive = this.icw_locomotive
local center_position = {
x = locomotive.area.left_top.x + (locomotive.area.right_bottom.x - locomotive.area.left_top.x) * 0.5,
y = locomotive.area.left_top.y + (locomotive.area.right_bottom.y - locomotive.area.left_top.y) * 0.5
}
if not this.icw_area then
this.icw_area = center_position
end
local position = loco_surface.find_non_colliding_position('market', center_position, 128, 0.5)
local biters = {
'small-biter',
'medium-biter',
'big-biter',
'behemoth-biter',
'small-spitter',
'medium-spitter',
'big-spitter',
'behemoth-spitter',
'compilatron'
}
local size_of = #biters
if not position then
return
end
local chosen_ent = biters[random(1, size_of)]
this.locomotive_biter = loco_surface.create_entity({name = chosen_ent, position = position, force = 'player', create_build_effect_smoke = false})
rendering.draw_text {
text = ({'locomotive.shoo'}),
surface = this.locomotive_biter.surface,
target = this.locomotive_biter,
target_offset = {0, -3.5},
scale = 1.05,
font = 'default-large-semibold',
color = {r = 175, g = 75, b = 255},
alignment = 'center',
scale_with_zoom = false
}
this.locomotive_biter.ai_settings.allow_destroy_when_commands_fail = false
this.locomotive_biter.ai_settings.allow_try_return_to_spawner = false
end
local function on_console_chat(event)
if not event.player_index then
return
end
shoo(event)
end
Event.add(defines.events.on_console_chat, on_console_chat)
return Public

View File

@ -0,0 +1,220 @@
local Event = require 'utils.event'
local ICW = require 'maps.mountain_fortress_v3.icw.main'
local WPT = require 'maps.mountain_fortress_v3.table'
local Public = {}
local function contains_positions(area)
local function inside(pos)
local lt = area.left_top
local rb = area.right_bottom
return pos.x >= lt.x and pos.y >= lt.y and pos.x <= rb.x and pos.y <= rb.y
end
local wagons = ICW.get_table('wagons')
for _, wagon in pairs(wagons) do
if wagon.entity and wagon.entity.valid then
if wagon.entity.name == 'cargo-wagon' then
if inside(wagon.entity.position, area) then
return true, wagon.entity
end
end
end
end
return false, nil
end
local function on_built_entity(event)
local entity = event.created_entity
if not entity.valid then
return
end
if entity.name ~= 'steel-chest' then
return
end
local map_name = 'mountain_fortress_v3'
if string.sub(entity.surface.name, 0, #map_name) ~= map_name then
return
end
local area = {
left_top = {x = entity.position.x - 3, y = entity.position.y - 3},
right_bottom = {x = entity.position.x + 3, y = entity.position.y + 3}
}
local success, train = contains_positions(area)
if not success then
return
end
local outside_chests = WPT.get('outside_chests')
local chests_linked_to = WPT.get('chests_linked_to')
local chest_limit_outside_upgrades = WPT.get('chest_limit_outside_upgrades')
local chest_created
local increased = false
for k, data in pairs(outside_chests) do
if data and data.chest and data.chest.valid then
if chests_linked_to[train.unit_number] then
local linked_to = chests_linked_to[train.unit_number].count
if linked_to == chest_limit_outside_upgrades then
return
end
outside_chests[entity.unit_number] = {chest = entity, position = entity.position, linked = train.unit_number}
if not increased then
chests_linked_to[train.unit_number].count = linked_to + 1
chests_linked_to[train.unit_number][entity.unit_number] = true
increased = true
goto continue
end
else
outside_chests[entity.unit_number] = {chest = entity, position = entity.position, linked = train.unit_number}
chests_linked_to[train.unit_number] = {count = 1}
end
::continue::
rendering.draw_text {
text = '',
surface = entity.surface,
target = entity,
target_offset = {0, -0.6},
scale = 2,
color = {r = 0, g = 0.6, b = 1},
alignment = 'center'
}
chest_created = true
end
end
if chest_created then
return
end
if next(outside_chests) == nil then
outside_chests[entity.unit_number] = {chest = entity, position = entity.position, linked = train.unit_number}
chests_linked_to[train.unit_number] = {count = 1}
chests_linked_to[train.unit_number][entity.unit_number] = true
rendering.draw_text {
text = '',
surface = entity.surface,
target = entity,
target_offset = {0, -0.6},
scale = 2,
color = {r = 0, g = 0.6, b = 1},
alignment = 'center'
}
return
end
end
local function on_player_and_robot_mined_entity(event)
local entity = event.entity
if not entity.valid then
return
end
local outside_chests = WPT.get('outside_chests')
local chests_linked_to = WPT.get('chests_linked_to')
if outside_chests[entity.unit_number] then
for k, data in pairs(chests_linked_to) do
if data[entity.unit_number] then
data.count = data.count - 1
if data.count <= 0 then
chests_linked_to[k] = nil
end
end
if chests_linked_to[k] and chests_linked_to[k][entity.unit_number] then
chests_linked_to[k][entity.unit_number] = nil
end
end
outside_chests[entity.unit_number] = nil
end
end
local function divide_contents()
local outside_chests = WPT.get('outside_chests')
local chests_linked_to = WPT.get('chests_linked_to')
local target_chest
if not next(outside_chests) then
goto final
end
for key, data in pairs(outside_chests) do
local chest = data.chest
local area = {
left_top = {x = data.position.x - 4, y = data.position.y - 4},
right_bottom = {x = data.position.x + 4, y = data.position.y + 4}
}
if not (chest and chest.valid) then
if chests_linked_to[data.linked] then
if chests_linked_to[data.linked][key] then
chests_linked_to[data.linked][key] = nil
chests_linked_to[data.linked].count = chests_linked_to[data.linked].count - 1
if chests_linked_to[data.linked].count <= 0 then
chests_linked_to[data.linked] = nil
end
end
end
outside_chests[key] = nil
goto continue
end
local success, entity = contains_positions(area)
if success then
target_chest = entity
else
if chests_linked_to[data.linked] then
if chests_linked_to[data.linked][key] then
chests_linked_to[data.linked][key] = nil
chests_linked_to[data.linked].count = chests_linked_to[data.linked].count - 1
if chests_linked_to[data.linked].count <= 0 then
chests_linked_to[data.linked] = nil
end
end
end
goto continue
end
local chest1 = chest.get_inventory(defines.inventory.chest)
local chest2 = target_chest.get_inventory(defines.inventory.cargo_wagon)
for item, count in pairs(chest1.get_contents()) do
local t = {name = item, count = count}
local c = chest2.insert(t)
if (c > 0) then
chest1.remove({name = item, count = c})
end
end
::continue::
end
::final::
end
local function tick()
local ticker = game.tick
if ticker % 30 == 0 then
divide_contents()
end
end
Event.on_nth_tick(5, tick)
Event.add(defines.events.on_built_entity, on_built_entity)
Event.add(defines.events.on_robot_built_entity, on_built_entity)
Event.add(defines.events.on_entity_died, on_player_and_robot_mined_entity)
Event.add(defines.events.on_pre_player_mined_item, on_player_and_robot_mined_entity)
Event.add(defines.events.on_robot_mined_entity, on_player_and_robot_mined_entity)
return Public

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,155 @@
local WPT = require 'maps.mountain_fortress_v3.table'
local Session = require 'utils.datastore.session_data'
local Jailed = require 'utils.datastore.jail_data'
local Antigrief = require 'antigrief'
local Public = {}
function Public.add_player_to_permission_group(player, group, forced)
local jailed = Jailed.get_jailed_table()
local enable_permission_group_disconnect = WPT.get('disconnect_wagon')
local session = Session.get_session_table()
local AG = Antigrief.get()
local allow_decon = WPT.get('allow_decon')
local default_group = game.permissions.get_group('Default')
default_group.set_allows_action(defines.input_action.deconstruct, false)
default_group.set_allows_action(defines.input_action.activate_cut, false)
if not game.permissions.get_group('limited') then
local limited_group = game.permissions.create_group('limited')
limited_group.set_allows_action(defines.input_action.cancel_craft, false)
limited_group.set_allows_action(defines.input_action.drop_item, false)
if allow_decon then
limited_group.set_allows_action(defines.input_action.deconstruct, true)
else
limited_group.set_allows_action(defines.input_action.deconstruct, false)
end
limited_group.set_allows_action(defines.input_action.activate_cut, false)
end
if not game.permissions.get_group('near_locomotive') then
local near_locomotive_group = game.permissions.create_group('near_locomotive')
near_locomotive_group.set_allows_action(defines.input_action.cancel_craft, false)
near_locomotive_group.set_allows_action(defines.input_action.drop_item, false)
near_locomotive_group.set_allows_action(defines.input_action.deconstruct, false)
near_locomotive_group.set_allows_action(defines.input_action.activate_cut, false)
end
if not game.permissions.get_group('main_surface') then
local main_surface_group = game.permissions.create_group('main_surface')
main_surface_group.set_allows_action(defines.input_action.deconstruct, false)
main_surface_group.set_allows_action(defines.input_action.activate_cut, false)
end
if not game.permissions.get_group('not_trusted') then
local not_trusted = game.permissions.create_group('not_trusted')
not_trusted.set_allows_action(defines.input_action.cancel_craft, false)
not_trusted.set_allows_action(defines.input_action.edit_permission_group, false)
not_trusted.set_allows_action(defines.input_action.import_permissions_string, false)
not_trusted.set_allows_action(defines.input_action.delete_permission_group, false)
not_trusted.set_allows_action(defines.input_action.add_permission_group, false)
not_trusted.set_allows_action(defines.input_action.admin_action, false)
not_trusted.set_allows_action(defines.input_action.drop_item, false)
not_trusted.set_allows_action(defines.input_action.disconnect_rolling_stock, false)
not_trusted.set_allows_action(defines.input_action.connect_rolling_stock, false)
not_trusted.set_allows_action(defines.input_action.open_train_gui, false)
not_trusted.set_allows_action(defines.input_action.open_train_station_gui, false)
not_trusted.set_allows_action(defines.input_action.open_trains_gui, false)
not_trusted.set_allows_action(defines.input_action.change_train_stop_station, false)
not_trusted.set_allows_action(defines.input_action.change_train_wait_condition, false)
not_trusted.set_allows_action(defines.input_action.change_train_wait_condition_data, false)
not_trusted.set_allows_action(defines.input_action.drag_train_schedule, false)
not_trusted.set_allows_action(defines.input_action.drag_train_wait_condition, false)
not_trusted.set_allows_action(defines.input_action.go_to_train_station, false)
not_trusted.set_allows_action(defines.input_action.remove_train_station, false)
not_trusted.set_allows_action(defines.input_action.set_trains_limit, false)
not_trusted.set_allows_action(defines.input_action.set_train_stopped, false)
not_trusted.set_allows_action(defines.input_action.deconstruct, false)
not_trusted.set_allows_action(defines.input_action.activate_cut, false)
end
if not AG.enabled then
default_group.add_player(player)
return
end
local gulag = game.permissions.get_group('gulag')
local tbl = gulag and gulag.players
for i = 1, #tbl do
if tbl[i].index == player.index then
return
end
end
if forced then
default_group.add_player(player)
return
end
local playtime = player.online_time
if session[player.name] then
playtime = player.online_time + session[player.name]
end
if jailed[player.name] then
return
end
if enable_permission_group_disconnect then
local limited_group = game.permissions.get_group('limited')
local main_surface_group = game.permissions.get_group('main_surface')
local near_locomotive_group = game.permissions.get_group('near_locomotive')
if limited_group then
limited_group.set_allows_action(defines.input_action.disconnect_rolling_stock, true)
end
if main_surface_group then
main_surface_group.set_allows_action(defines.input_action.disconnect_rolling_stock, true)
end
if near_locomotive_group then
near_locomotive_group.set_allows_action(defines.input_action.disconnect_rolling_stock, true)
end
if default_group then
default_group.set_allows_action(defines.input_action.disconnect_rolling_stock, true)
end
else
local limited_group = game.permissions.get_group('limited')
local main_surface_group = game.permissions.get_group('main_surface')
local near_locomotive_group = game.permissions.get_group('near_locomotive')
if limited_group then
limited_group.set_allows_action(defines.input_action.disconnect_rolling_stock, false)
end
if main_surface_group then
main_surface_group.set_allows_action(defines.input_action.disconnect_rolling_stock, false)
end
if near_locomotive_group then
near_locomotive_group.set_allows_action(defines.input_action.disconnect_rolling_stock, false)
end
if default_group then
default_group.set_allows_action(defines.input_action.disconnect_rolling_stock, false)
end
end
if playtime < 5184000 then -- 24 hours
local not_trusted = game.permissions.get_group('not_trusted')
if not player.admin then
not_trusted.add_player(player)
end
else
if group == 'limited' then
local limited_group = game.permissions.get_group('limited')
limited_group.add_player(player)
elseif group == 'main_surface' then
local main_surface_group = game.permissions.get_group('main_surface')
main_surface_group.add_player(player)
elseif group == 'near_locomotive' then
local near_locomotive_group = game.permissions.get_group('near_locomotive')
near_locomotive_group.add_player(player)
elseif group == 'default' then
default_group.add_player(player)
end
end
end
return Public

View File

@ -0,0 +1,186 @@
local Generate = require 'maps.mountain_fortress_v3.generate'
local ICW = require 'maps.mountain_fortress_v3.icw.main'
local WPT = require 'maps.mountain_fortress_v3.table'
local Task = require 'utils.task'
local Token = require 'utils.token'
local MapFunctions = require 'tools.map_functions'
local Public = {}
local random = math.random
local function initial_cargo_boxes()
return {
{name = 'loader', count = 1},
{name = 'coal', count = random(32, 64)},
{name = 'coal', count = random(32, 64)},
{name = 'iron-ore', count = random(32, 128)},
{name = 'copper-ore', count = random(32, 128)},
{name = 'empty-barrel', count = random(16, 32)},
{name = 'submachine-gun', count = 1},
{name = 'submachine-gun', count = 1},
{name = 'submachine-gun', count = 1},
{name = 'submachine-gun', count = 1},
{name = 'submachine-gun', count = 1},
{name = 'shotgun', count = 1},
{name = 'shotgun', count = 1},
{name = 'shotgun', count = 1},
{name = 'shotgun-shell', count = random(4, 5)},
{name = 'shotgun-shell', count = random(4, 5)},
{name = 'land-mine', count = random(6, 18)},
{name = 'grenade', count = random(2, 3)},
{name = 'grenade', count = random(2, 3)},
{name = 'grenade', count = random(2, 3)},
{name = 'iron-gear-wheel', count = random(7, 15)},
{name = 'iron-gear-wheel', count = random(7, 15)},
{name = 'iron-gear-wheel', count = random(7, 15)},
{name = 'iron-gear-wheel', count = random(7, 15)},
{name = 'iron-plate', count = random(15, 23)},
{name = 'iron-plate', count = random(15, 23)},
{name = 'iron-plate', count = random(15, 23)},
{name = 'iron-plate', count = random(15, 23)},
{name = 'copper-plate', count = random(15, 23)},
{name = 'copper-plate', count = random(15, 23)},
{name = 'copper-plate', count = random(15, 23)},
{name = 'copper-plate', count = random(15, 23)},
{name = 'firearm-magazine', count = random(10, 30)},
{name = 'firearm-magazine', count = random(10, 30)},
{name = 'firearm-magazine', count = random(10, 30)},
{name = 'rail', count = random(16, 24)},
{name = 'rail', count = random(16, 24)}
}
end
local set_loco_tiles =
Token.register(
function(data)
local position = data.position
local surface = data.surface
if not surface or not surface.valid then
return
end
local cargo_boxes = initial_cargo_boxes()
local p = {}
for x = position.x - 5, 1, 3 do
for y = 1, position.y + 5, 2 do
if random(1, 4) == 1 then
p[#p + 1] = {x = x, y = y}
end
end
end
if random(1, 6) == 1 then
MapFunctions.draw_noise_tile_circle(position, 'blue-refined-concrete', surface, 18)
elseif random(1, 5) == 1 then
MapFunctions.draw_noise_tile_circle(position, 'black-refined-concrete', surface, 18)
elseif random(1, 4) == 1 then
MapFunctions.draw_noise_tile_circle(position, 'cyan-refined-concrete', surface, 18)
elseif random(1, 3) == 1 then
MapFunctions.draw_noise_tile_circle(position, 'hazard-concrete-right', surface, 18)
else
MapFunctions.draw_noise_tile_circle(position, 'blue-refined-concrete', surface, 18)
end
for i = 1, #cargo_boxes, 1 do
if not p[i] then
break
end
if surface.can_place_entity({name = 'wooden-chest', position = p[i]}) then
local e = surface.create_entity({name = 'wooden-chest', position = p[i], force = 'player', create_build_effect_smoke = false})
e.minable = false
local inventory = e.get_inventory(defines.inventory.chest)
inventory.insert(cargo_boxes[i])
end
end
end
)
function Public.locomotive_spawn(surface, position)
local this = WPT.get()
for y = -6, 6, 2 do
surface.create_entity({name = 'straight-rail', position = {position.x, position.y + y}, force = 'player', direction = 0})
end
this.locomotive = surface.create_entity({name = 'locomotive', position = {position.x, position.y + -3}, force = 'player'})
this.locomotive.get_inventory(defines.inventory.fuel).insert({name = 'wood', count = 100})
this.locomotive_cargo = surface.create_entity({name = 'cargo-wagon', position = {position.x, position.y + 3}, force = 'player'})
this.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = 'raw-fish', count = 8})
local winter_mode_locomotive = Generate.wintery(this.locomotive, 5.5)
if not winter_mode_locomotive then
rendering.draw_light(
{
sprite = 'utility/light_medium',
scale = 5.5,
intensity = 1,
minimum_darkness = 0,
oriented = true,
color = {255, 255, 255},
target = this.locomotive,
surface = surface,
visible = true,
only_in_alt_mode = false
}
)
end
local winter_mode_cargo = Generate.wintery(this.locomotive_cargo, 5.5)
if not winter_mode_cargo then
rendering.draw_light(
{
sprite = 'utility/light_medium',
scale = 5.5,
intensity = 1,
minimum_darkness = 0,
oriented = true,
color = {255, 255, 255},
target = this.locomotive_cargo,
surface = surface,
visible = true,
only_in_alt_mode = false
}
)
end
local data = {
surface = surface,
position = position
}
Task.set_timeout_in_ticks(400, set_loco_tiles, data)
for y = -1, 0, 0.05 do
local scale = random(50, 100) * 0.01
rendering.draw_sprite(
{
sprite = 'item/raw-fish',
orientation = random(0, 100) * 0.01,
x_scale = scale,
y_scale = scale,
tint = {random(60, 255), random(60, 255), random(60, 255)},
render_layer = 'selection-box',
target = this.locomotive_cargo,
target_offset = {-0.7 + random(0, 140) * 0.01, y},
surface = surface
}
)
end
this.locomotive.color = {0, 255, random(60, 255)}
this.locomotive.minable = false
this.locomotive_cargo.minable = false
this.locomotive_cargo.operable = true
local locomotive = ICW.register_wagon(this.locomotive)
ICW.register_wagon(this.locomotive_cargo)
this.icw_locomotive = locomotive
game.forces.player.set_spawn_position({0, 19}, locomotive.surface)
end
return Public

View File

@ -28,6 +28,7 @@ local RPG = require 'modules.rpg.main'
local Event = require 'utils.event'
local WPT = require 'maps.mountain_fortress_v3.table'
local Locomotive = require 'maps.mountain_fortress_v3.locomotive'
local SpawnLocomotive = require 'maps.mountain_fortress_v3.locomotive.spawn_locomotive'
local Score = require 'comfy_panel.score'
local Poll = require 'comfy_panel.poll'
local Collapse = require 'modules.collapse'
@ -44,6 +45,8 @@ local Reset = require 'functions.soft_reset'
local JailData = require 'utils.datastore.jail_data'
local RPG_Progression = require 'utils.datastore.rpg_data'
require 'maps.mountain_fortress_v3.locomotive.market'
require 'maps.mountain_fortress_v3.locomotive.linked_chests'
require 'maps.mountain_fortress_v3.rocks_yield_ore_veins'
require 'maps.mountain_fortress_v3.generate'
@ -245,7 +248,7 @@ function Public.reset_map()
this.locomotive_health = 10000
this.locomotive_max_health = 10000
Locomotive.locomotive_spawn(surface, {x = -18, y = 25})
SpawnLocomotive.locomotive_spawn(surface, {x = -18, y = 25})
Locomotive.render_train_hp()
Functions.render_direction(surface)

View File

@ -1,9 +1,18 @@
local Color = require 'utils.color_presets'
local Event = require 'utils.event'
local WPT = require 'maps.mountain_fortress_v3.table'
local WD = require 'modules.wave_defense.table'
local RPG = require 'modules.rpg.main'
local Alert = require 'utils.alert'
local Task = require 'utils.task'
local Token = require 'utils.token'
local Public = {}
local shuffle = table.shuffle_table
local insert = table.insert
local random = math.random
local floor = math.floor
local insert = table.insert
local abs = math.abs
local item_worths = {
['wooden-chest'] = 4,
@ -198,6 +207,340 @@ local function get_raffle_keys()
return raffle_keys
end
local function get_random_weighted(weighted_table, weight_index)
local total_weight = 0
weight_index = weight_index or 1
for _, w in pairs(weighted_table) do
total_weight = total_weight + w[weight_index]
end
local index = random() * total_weight
local weight_sum = 0
for k, w in pairs(weighted_table) do
weight_sum = weight_sum + w[weight_index]
if weight_sum >= index then
return w, k
end
end
end
local function init_price_check(locomotive, mystical_chest)
local roll = 48 + abs(locomotive.position.y) * 1.75
roll = roll * random(25, 1337) * 0.01
local item_stacks = {}
local roll_count = 2
for _ = 1, roll_count, 1 do
for _, stack in pairs(Public.roll(floor(roll / roll_count), 2)) do
if not item_stacks[stack.name] then
item_stacks[stack.name] = stack.count
else
item_stacks[stack.name] = item_stacks[stack.name] + stack.count
end
end
end
local price = {}
for k, v in pairs(item_stacks) do
insert(price, {name = k, count = v})
end
mystical_chest.price = price
end
local function roll_item_stacks(remaining_budget, max_slots, blacklist)
local item_stack_set = {}
local item_stack_set_worth = 0
for i = 1, max_slots, 1 do
if remaining_budget <= 0 then
break
end
local item_stack = Public.roll_item_stack(remaining_budget, blacklist)
item_stack_set[i] = item_stack
remaining_budget = remaining_budget - item_stack.count * item_worths[item_stack.name]
item_stack_set_worth = item_stack_set_worth + item_stack.count * item_worths[item_stack.name]
end
return item_stack_set, item_stack_set_worth
end
local pause_wd_token =
Token.register(
function()
WD.pause(false)
local mc_rewards = WPT.get('mc_rewards')
mc_rewards.temp_boosts.wave_defense = nil
end
)
local restore_mining_speed_token =
Token.register(
function()
local mc_rewards = WPT.get('mc_rewards')
local force = game.forces.player
if mc_rewards.temp_boosts.mining then
force.manual_mining_speed_modifier = force.manual_mining_speed_modifier - 0.5
mc_rewards.temp_boosts.mining = nil
end
end
)
local restore_movement_speed_token =
Token.register(
function()
local mc_rewards = WPT.get('mc_rewards')
local force = game.forces.player
if mc_rewards.temp_boosts.movement then
force.character_running_speed_modifier = force.character_running_speed_modifier - 0.2
mc_rewards.temp_boosts.movement = nil
end
end
)
local mc_random_rewards = {
{
name = 'XP',
color = {r = 0.00, g = 0.45, b = 0.00},
tooltip = 'Selecting this will insert random XP onto the global xp pool!',
func = (function(player)
local rng = random(1024, 10240)
RPG.add_to_global_pool(rng)
local message = ({'locomotive.xp_bonus', player.name})
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac')
return true
end),
512
},
{
name = 'Coins',
color = {r = 0.00, g = 0.35, b = 0.00},
tooltip = 'Selecting this will grant each player some coins!',
func = (function(p)
local rng = random(256, 512)
local players = game.connected_players
for i = 1, #players do
local player = players[i]
if player and player.valid then
if player.can_insert({name = 'coin', count = rng}) then
player.insert({name = 'coin', count = rng})
end
end
end
local message = ({'locomotive.coin_bonus', p.name})
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac')
return true
end),
512
},
{
name = 'Movement bonus',
str = 'movement',
color = {r = 0.00, g = 0.25, b = 0.00},
tooltip = 'Selecting this will grant the team a bonus movement speed for 15 minutes!',
func = (function(player)
local mc_rewards = WPT.get('mc_rewards')
local force = game.forces.player
if mc_rewards.temp_boosts.movement then
return false, '[Rewards] Movement bonus is already applied. Please choose another reward.'
end
mc_rewards.temp_boosts.movement = true
Task.set_timeout_in_ticks(54000, restore_movement_speed_token)
force.character_running_speed_modifier = force.character_running_speed_modifier + 0.2
local message = ({'locomotive.movement_bonus', player.name})
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac')
return true
end),
512
},
{
name = 'Mining bonus',
str = 'mining',
color = {r = 0.00, g = 0.00, b = 0.25},
tooltip = 'Selecting this will grant the team a bonus mining speed for 15 minutes!',
func = (function(player)
local mc_rewards = WPT.get('mc_rewards')
local force = game.forces.player
if mc_rewards.temp_boosts.mining then
return false, '[Rewards] Mining bonus is already applied. Please choose another reward.'
end
mc_rewards.temp_boosts.mining = true
Task.set_timeout_in_ticks(54000, restore_mining_speed_token)
force.manual_mining_speed_modifier = force.manual_mining_speed_modifier + 0.5
local message = ({'locomotive.mining_bonus', player.name})
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac')
return true
end),
512
},
{
name = 'Inventory Bonus',
color = {r = 0.00, g = 0.00, b = 0.25},
tooltip = 'Selecting this will grant the team permanent inventory bonus!',
func = (function(player)
local force = game.forces.player
force.character_inventory_slots_bonus = force.character_inventory_slots_bonus + 1
local message = ({'locomotive.inventory_bonus', player.name})
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac')
return true
end),
512
},
{
name = 'Heal Locomotive',
color = {r = 0.00, g = 0.00, b = 0.25},
tooltip = 'Selecting this will heal the main locomotive to full health!',
func = (function(player)
local locomotive_max_health = WPT.get('locomotive_max_health')
WPT.set('locomotive_health', locomotive_max_health)
local message = ({'locomotive.locomotive_health', player.name})
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac')
return true
end),
256
},
{
name = 'Wave Defense',
str = 'wave_defense',
color = {r = 0.35, g = 0.00, b = 0.00},
tooltip = 'Selecting this will pause the wave defense for 15 minutes. Ideal if you want to take a break!',
func = (function(player)
local mc_rewards = WPT.get('mc_rewards')
if mc_rewards.temp_boosts.wave_defense then
return false, '[Rewards] Wave Defense break is already applied. Please choose another reward.'
end
mc_rewards.temp_boosts.wave_defense = true
WD.pause(true)
Task.set_timeout_in_ticks(54000, pause_wd_token)
local message = ({'locomotive.wd_paused', player.name})
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac')
return true
end),
64
}
}
local function mystical_chest_reward(player)
if player.gui.screen['reward_system'] then
player.gui.screen['reward_system'].destroy()
return
end
local frame = player.gui.screen.add {type = 'frame', caption = 'Mystical Reward:', name = 'reward_system', direction = 'vertical'}
frame.auto_center = true
frame = frame.add {type = 'frame', name = 'reward_system_1', direction = 'vertical', style = 'inside_shallow_frame'}
frame.style.padding = 4
local mc_rewards = WPT.get('mc_rewards')
mc_rewards.current = {}
for i = 1, 3 do
local d, key = get_random_weighted(mc_random_rewards)
if not mc_rewards.current[key] and not mc_rewards.temp_boosts[d.str] then
mc_rewards.current[key] = {
id = i,
name = d.name
}
local b = frame.add({type = 'button', name = tostring(i), caption = d.name})
b.style.font_color = d.color
b.style.font = 'heading-2'
b.style.minimal_width = 180
b.style.horizontal_align = 'center'
b.tooltip = d.tooltip
end
end
if not next(mc_rewards.current) then
if player.gui.screen['reward_system'] then
player.gui.screen['reward_system'].destroy()
end
return player.print('[Rewards] No rewards are available.', Color.fail)
end
-- something fancy to reward players
end
local function container_opened(event)
local entity = event.entity
if not entity then
return
end
if not entity.valid then
return
end
if not entity.unit_number then
return
end
local mystical_chest = WPT.get('mystical_chest')
if not mystical_chest then
return
end
if not (mystical_chest.entity and mystical_chest.entity.valid) then
return
end
if entity.unit_number ~= mystical_chest.entity.unit_number then
return
end
local player = game.get_player(event.player_index)
if not (player and player.valid) then
return
end
Public.add_mystical_chest(player)
end
local function on_gui_opened(event)
container_opened(event)
end
local function on_gui_closed(event)
container_opened(event)
end
local function on_gui_click(event)
local element = event.element
if not (element and element.valid) then
return
end
if element.type ~= 'button' then
return
end
if element.parent.name ~= 'reward_system_1' then
return
end
local i = tonumber(element.name)
local mc_rewards = WPT.get('mc_rewards')
local current = mc_rewards.current
local player = game.get_player(element.player_index)
if not (player and player.valid) then
return
end
for id, data in pairs(current) do
if data.id == i then
local success, msg = mc_random_rewards[id].func(player)
if not success then
return player.print(msg, Color.fail)
end
break
end
end
element.parent.parent.destroy()
end
function Public.roll_item_stack(remaining_budget, blacklist)
if remaining_budget <= 0 then
return
@ -229,23 +572,6 @@ function Public.roll_item_stack(remaining_budget, blacklist)
return {name = item_name, count = item_count}
end
local function roll_item_stacks(remaining_budget, max_slots, blacklist)
local item_stack_set = {}
local item_stack_set_worth = 0
for i = 1, max_slots, 1 do
if remaining_budget <= 0 then
break
end
local item_stack = Public.roll_item_stack(remaining_budget, blacklist)
item_stack_set[i] = item_stack
remaining_budget = remaining_budget - item_stack.count * item_worths[item_stack.name]
item_stack_set_worth = item_stack_set_worth + item_stack.count * item_worths[item_stack.name]
end
return item_stack_set, item_stack_set_worth
end
function Public.roll(budget, max_slots, blacklist)
if not budget then
return
@ -279,4 +605,57 @@ function Public.roll(budget, max_slots, blacklist)
return final_stack_set
end
function Public.add_mystical_chest(player)
local locomotive = WPT.get('locomotive')
if not locomotive then
return
end
if not locomotive.valid then
return
end
local mystical_chest = WPT.get('mystical_chest')
if not (mystical_chest.entity and mystical_chest.entity.valid) then
return
end
if not mystical_chest.price then
init_price_check(locomotive, mystical_chest)
end
local entity = mystical_chest.entity
local inventory = mystical_chest.entity.get_inventory(defines.inventory.chest)
for key, item_stack in pairs(mystical_chest.price) do
local count_removed = inventory.remove(item_stack)
mystical_chest.price[key].count = mystical_chest.price[key].count - count_removed
if mystical_chest.price[key].count <= 0 then
table.remove(mystical_chest.price, key)
end
end
if #mystical_chest.price == 0 then
init_price_check(locomotive, mystical_chest)
if player and player.valid then
mystical_chest_reward(player)
end
return true
end
for slot = 1, 30, 1 do
entity.clear_request_slot(slot)
end
for slot, item_stack in pairs(mystical_chest.price) do
mystical_chest.entity.set_request_slot(item_stack, slot)
end
end
Public.init_price_check = init_price_check
Event.add(defines.events.on_gui_opened, on_gui_opened)
Event.add(defines.events.on_gui_closed, on_gui_closed)
Event.add(defines.events.on_gui_click, on_gui_click)
return Public