1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-10 00:43:27 +02:00
ComfyFactorio/maps/mountain_fortress_v3/locomotive.lua

575 lines
17 KiB
Lua
Raw Normal View History

2020-05-17 12:23:55 +02:00
local Event = require 'utils.event'
2020-07-06 15:45:09 +02:00
local Market = require 'maps.mountain_fortress_v3.basic_markets'
2021-11-07 02:18:33 +02:00
local LocomotiveMarket = require 'maps.mountain_fortress_v3.locomotive.market'
2020-05-17 12:23:55 +02:00
local ICW = require 'maps.mountain_fortress_v3.icw.main'
local WPT = require 'maps.mountain_fortress_v3.table'
local ICFunctions = require 'maps.mountain_fortress_v3.ic.functions'
2020-08-14 22:07:54 +02:00
local Session = require 'utils.datastore.session_data'
2020-10-30 23:05:05 +02:00
local Difficulty = require 'modules.difficulty_vote_by_amount'
2021-05-25 22:19:20 +02:00
local RPG = require 'modules.rpg.main'
2020-07-06 15:45:09 +02:00
local Gui = require 'utils.gui'
2020-06-07 13:33:24 +02:00
local Alert = require 'utils.alert'
2020-07-06 15:45:09 +02:00
local Math2D = require 'math2d'
2021-11-07 02:18:33 +02:00
local PermissionGroups = require 'maps.mountain_fortress_v3.locomotive.permission_groups'
2020-05-17 12:23:55 +02:00
local Public = {}
2021-11-07 02:18:33 +02:00
2021-05-25 22:19:20 +02:00
local rpg_main_frame = RPG.main_frame_name
2020-08-09 20:22:33 +02:00
local random = math.random
local floor = math.floor
local round = math.round
2020-05-17 12:23:55 +02:00
2021-10-02 21:04:15 +02:00
local clear_items_upon_surface_entry = {
2021-10-02 21:15:31 +02:00
['entity-ghost'] = true,
2021-10-02 21:04:15 +02:00
['small-electric-pole'] = true,
['medium-electric-pole'] = true,
['big-electric-pole'] = true,
['substation'] = true
}
local function add_random_loot_to_main_market(rarity)
local main_market_items = WPT.get('main_market_items')
local items = Market.get_random_item(rarity, true, false)
2020-10-24 14:46:14 +02:00
if not items then
return false
end
local types = game.item_prototypes
for k, v in pairs(main_market_items) do
if not v.static then
main_market_items[k] = nil
end
end
for k, v in pairs(items) do
local price = v.price[1][2] + random(1, 15) * rarity
local value = v.price[1][1]
local stack = 1
if v.offer.item == 'coin' then
price = v.price[1][2]
stack = v.offer.count
if not stack then
stack = v.price[1][2]
end
end
2020-10-24 14:46:14 +02:00
if not main_market_items[v.offer.item] then
main_market_items[v.offer.item] = {
stack = stack,
value = value,
price = price,
tooltip = types[v.offer.item].localised_name,
upgrade = false
}
end
end
end
2020-05-17 12:23:55 +02:00
local function validate_player(player)
if not player then
return false
end
if not player.valid then
return false
end
if not player.character then
return false
end
if not player.connected then
return false
end
2021-11-07 02:18:33 +02:00
if not game.get_player(player.name) then
2020-05-17 12:23:55 +02:00
return false
end
return true
end
local function property_boost(data)
2020-08-14 17:16:04 +02:00
local xp_floating_text_color = {r = 188, g = 201, b = 63}
2020-05-17 12:23:55 +02:00
local visuals_delay = 1800
2020-11-17 13:45:27 +02:00
local loco_surface = WPT.get('loco_surface')
if not (loco_surface and loco_surface.valid) then
return
end
2020-11-15 20:23:54 +02:00
local locomotive_xp_aura = WPT.get('locomotive_xp_aura')
local locomotive = WPT.get('locomotive')
local xp_points = WPT.get('xp_points')
local aura = locomotive_xp_aura
2020-05-17 12:23:55 +02:00
local rpg = data.rpg
2020-11-15 20:23:54 +02:00
local loco = locomotive.position
2020-05-17 12:23:55 +02:00
local area = {
left_top = {x = loco.x - aura, y = loco.y - aura},
right_bottom = {x = loco.x + aura, y = loco.y + aura}
}
for _, player in pairs(game.connected_players) do
if not validate_player(player) then
return
end
2020-05-23 21:18:18 +02:00
if player.afk_time < 200 then
2020-11-17 13:45:27 +02:00
if Math2D.bounding_box.contains_point(area, player.position) or player.surface.index == loco_surface.index then
if player.surface.index == loco_surface.index then
2021-11-07 02:18:33 +02:00
PermissionGroups.add_player_to_permission_group(player, 'limited')
elseif ICFunctions.get_player_surface(player) then
2021-11-07 02:18:33 +02:00
return PermissionGroups.add_player_to_permission_group(player, 'limited')
else
2021-11-07 02:18:33 +02:00
PermissionGroups.add_player_to_permission_group(player, 'near_locomotive')
end
2020-05-23 21:18:18 +02:00
local pos = player.position
2021-05-25 22:19:20 +02:00
RPG.gain_xp(player, 0.5 * (rpg[player.index].bonus + xp_points))
2020-05-23 21:18:18 +02:00
player.create_local_flying_text {
text = '+' .. '',
position = {x = pos.x, y = pos.y - 2},
color = xp_floating_text_color,
time_to_live = 60,
speed = 3
}
rpg[player.index].xp_since_last_floaty_text = 0
rpg[player.index].last_floaty_text = game.tick + visuals_delay
if player.gui.screen[rpg_main_frame] then
local f = player.gui.screen[rpg_main_frame]
2020-07-28 11:24:16 +02:00
local d = Gui.get_data(f)
if d.exp_gui and d.exp_gui.valid then
2020-08-09 20:22:33 +02:00
d.exp_gui.caption = floor(rpg[player.index].xp)
2020-07-28 11:24:16 +02:00
end
end
2020-07-24 17:33:28 +02:00
else
local active_surface_index = WPT.get('active_surface_index')
local surface = game.surfaces[active_surface_index]
if surface and surface.valid then
if player.surface.index == surface.index then
2021-11-07 02:18:33 +02:00
PermissionGroups.add_player_to_permission_group(player, 'main_surface')
end
end
2020-05-23 21:18:18 +02:00
end
2020-05-17 12:23:55 +02:00
end
end
end
2020-07-07 16:30:04 +02:00
local function is_around_train(data)
local entity = data.entity
2020-08-26 11:08:12 +02:00
local aura = data.aura + 20
2020-07-07 16:30:04 +02:00
local loco = data.locomotive.position
local area = {
left_top = {x = loco.x - aura, y = loco.y - aura},
right_bottom = {x = loco.x + aura, y = loco.y + aura}
}
local pos = entity.position
if Math2D.bounding_box.contains_point(area, pos) then
return true
end
return false
end
2020-05-17 12:23:55 +02:00
local function fish_tag()
2020-11-15 20:23:54 +02:00
local locomotive_cargo = WPT.get('locomotive_cargo')
if not (locomotive_cargo and locomotive_cargo.valid) then
2020-05-17 12:23:55 +02:00
return
end
2020-11-15 20:23:54 +02:00
if not (locomotive_cargo.surface and locomotive_cargo.surface.valid) then
2020-05-17 12:23:55 +02:00
return
end
2020-11-15 20:23:54 +02:00
local locomotive_tag = WPT.get('locomotive_tag')
if locomotive_tag then
if locomotive_tag.valid then
if locomotive_tag.position.x == locomotive_cargo.position.x and locomotive_tag.position.y == locomotive_cargo.position.y then
2020-05-17 12:23:55 +02:00
return
end
2020-11-15 20:23:54 +02:00
locomotive_tag.destroy()
2020-05-17 12:23:55 +02:00
end
end
2021-05-16 14:42:15 +02:00
WPT.set(
'locomotive_tag',
2020-11-15 20:23:54 +02:00
locomotive_cargo.force.add_chart_tag(
2021-05-16 14:42:15 +02:00
locomotive_cargo.surface,
{
icon = {type = 'item', name = 'raw-fish'},
position = locomotive_cargo.position,
text = ' '
}
)
2020-05-17 12:23:55 +02:00
)
end
2020-06-03 20:09:00 +02:00
local function set_player_spawn()
local locomotive = WPT.get('locomotive')
if not locomotive then
2020-05-17 12:23:55 +02:00
return
end
2020-06-03 20:09:00 +02:00
if not locomotive.valid then
2020-05-17 12:23:55 +02:00
return
end
2020-06-03 20:09:00 +02:00
local position = locomotive.surface.find_non_colliding_position('stone-furnace', locomotive.position, 16, 2)
2020-05-17 12:23:55 +02:00
if not position then
return
end
2020-06-03 20:09:00 +02:00
game.forces.player.set_spawn_position({x = position.x, y = position.y}, locomotive.surface)
end
local function refill_fish()
local locomotive_cargo = WPT.get('locomotive_cargo')
if not locomotive_cargo then
return
end
if not locomotive_cargo.valid then
return
end
2020-08-09 20:22:33 +02:00
locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = 'raw-fish', count = random(2, 5)})
2020-05-17 12:23:55 +02:00
end
local function set_carriages()
local locomotive = WPT.get('locomotive')
if not locomotive or not locomotive.valid then
return
end
2021-06-06 20:14:26 +02:00
if not locomotive.train then
return
end
local carriages = locomotive.train.carriages
local t = {}
for i = 1, #carriages do
local e = carriages[i]
if (e and e.valid) then
t[e.unit_number] = true
end
end
WPT.set('carriages_numbers', t)
WPT.set('carriages', locomotive.train.carriages)
end
2020-05-19 23:00:52 +02:00
local function set_locomotive_health()
2020-11-15 20:23:54 +02:00
local locomotive_health = WPT.get('locomotive_health')
local locomotive_max_health = WPT.get('locomotive_max_health')
local locomotive = WPT.get('locomotive')
2020-07-28 11:24:16 +02:00
2020-11-04 18:14:30 +02:00
local function check_health()
2020-11-15 20:23:54 +02:00
local m = locomotive_health / locomotive_max_health
2021-03-14 23:49:18 +02:00
if locomotive_health > locomotive_max_health then
WPT.set('locomotive_health', locomotive_max_health)
end
2021-05-15 16:01:07 +02:00
rendering.set_text(WPT.get('health_text'), 'HP: ' .. round(locomotive_health) .. ' / ' .. round(locomotive_max_health))
2020-11-15 20:23:54 +02:00
local carriages = WPT.get('carriages')
if carriages then
for i = 1, #carriages do
local entity = carriages[i]
2020-11-04 18:14:30 +02:00
if not (entity and entity.valid) then
return
end
local cargo_health = 600
2020-11-04 18:14:30 +02:00
if entity.type == 'locomotive' then
entity.health = 1000 * m
else
entity.health = cargo_health * m
2020-11-04 18:14:30 +02:00
end
end
end
end
2020-11-15 20:23:54 +02:00
if not (locomotive and locomotive.valid) then
2020-05-20 09:10:17 +02:00
return
end
2020-07-28 11:24:16 +02:00
2020-11-04 18:14:30 +02:00
check_health()
2020-05-19 23:00:52 +02:00
end
2020-06-03 20:09:00 +02:00
local function validate_index()
local locomotive = WPT.get('locomotive')
if not locomotive then
return
end
if not locomotive.valid then
return
end
2020-07-28 11:24:16 +02:00
2021-05-16 14:42:15 +02:00
local icw_table = ICW.get_table()
2020-06-03 20:09:00 +02:00
local icw_locomotive = WPT.get('icw_locomotive')
local loco_surface = icw_locomotive.surface
local unit_surface = locomotive.unit_number
local locomotive_surface = game.surfaces[icw_table.wagons[unit_surface].surface.index]
2020-11-23 23:10:45 +02:00
if loco_surface.valid then
WPT.set('loco_surface', locomotive_surface)
2020-06-03 20:09:00 +02:00
end
end
2021-11-07 02:18:33 +02:00
local function on_research_finished(event)
local research = event.research
if not research then
2020-06-03 20:09:00 +02:00
return
end
2021-11-07 02:18:33 +02:00
local name = research.name
2020-06-03 20:09:00 +02:00
2021-11-07 02:18:33 +02:00
if name == 'discharge-defense-equipment' then
local message = ({'locomotive.discharge_unlocked'})
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac', 0.1)
2021-05-23 17:03:52 +02:00
end
2021-11-07 02:18:33 +02:00
if name == 'artillery' then
local message = ({'locomotive.artillery_unlocked'})
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac', 0.1)
2020-08-26 12:09:06 +02:00
end
2020-06-03 20:09:00 +02:00
2021-11-07 02:18:33 +02:00
local locomotive = WPT.get('locomotive')
if not locomotive or not locomotive.valid then
2020-12-29 01:09:18 +02:00
return
end
2021-11-07 02:18:33 +02:00
local market_announce = WPT.get('market_announce')
if market_announce > game.tick then
2020-06-03 20:09:00 +02:00
return
end
2021-11-07 02:18:33 +02:00
local breached_wall = WPT.get('breached_wall')
add_random_loot_to_main_market(breached_wall)
local message = ({'locomotive.new_items_at_market'})
Alert.alert_all_players(5, message, nil, 'achievement/tech-maniac', 0.1)
LocomotiveMarket.refresh_gui()
2020-06-03 20:09:00 +02:00
end
2021-11-07 02:18:33 +02:00
local function on_player_changed_surface(event)
2020-06-03 20:09:00 +02:00
local player = game.players[event.player_index]
2021-11-07 02:18:33 +02:00
if not validate_player(player) then
2021-05-23 17:03:52 +02:00
return
end
2020-06-03 20:09:00 +02:00
2021-11-07 02:18:33 +02:00
local active_surface = WPT.get('active_surface_index')
local surface = game.surfaces[active_surface]
if not surface or not surface.valid then
2020-06-03 20:09:00 +02:00
return
end
2020-12-14 20:36:37 +02:00
2021-11-07 02:18:33 +02:00
local itemGhost = player.cursor_ghost
if itemGhost then
player.cursor_ghost = nil
2020-11-25 20:55:51 +02:00
end
2020-06-03 20:09:00 +02:00
2021-11-07 02:18:33 +02:00
local item = player.cursor_stack
if item and item.valid_for_read then
local name = item.name
if clear_items_upon_surface_entry[name] then
player.cursor_stack.clear()
end
2020-07-01 19:35:38 +02:00
end
2021-11-07 02:18:33 +02:00
if player.surface.name == 'nauvis' then
local pos = surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5)
if pos then
player.teleport(pos, surface)
else
pos = game.forces.player.get_spawn_position(surface)
player.teleport(pos, surface)
end
2021-05-23 17:03:52 +02:00
end
2021-11-07 02:18:33 +02:00
local locomotive_surface = WPT.get('loco_surface')
2020-06-03 20:09:00 +02:00
2021-11-07 02:18:33 +02:00
if locomotive_surface and locomotive_surface.valid and player.surface.index == locomotive_surface.index then
return PermissionGroups.add_player_to_permission_group(player, 'limited')
elseif ICFunctions.get_player_surface(player) then
return PermissionGroups.add_player_to_permission_group(player, 'limited')
elseif player.surface.index == surface.index then
return PermissionGroups.add_player_to_permission_group(player, 'main_surface')
2020-06-03 20:09:00 +02:00
end
2021-11-07 02:18:33 +02:00
end
2020-08-26 12:09:06 +02:00
2021-11-07 02:18:33 +02:00
local function on_player_driving_changed_state(event)
local player = game.players[event.player_index]
if not player or not player.valid then
2020-12-14 20:36:37 +02:00
return
end
2021-11-07 02:18:33 +02:00
local entity = event.entity
if not entity or not entity.valid then
2020-06-03 20:09:00 +02:00
return
end
2021-11-07 02:18:33 +02:00
local trusted = Session.get_trusted_table()
if #trusted == 0 then
2020-06-03 20:09:00 +02:00
return
end
2021-11-07 02:18:33 +02:00
local locomotive = WPT.get('locomotive')
if not locomotive or not locomotive.valid then
2020-06-03 20:09:00 +02:00
return
end
2021-11-07 02:18:33 +02:00
if entity.unit_number == locomotive.unit_number then
if not trusted[player.name] then
if player.character and player.character.valid and player.character.driving then
player.character.driving = false
end
end
end
2020-06-03 20:09:00 +02:00
end
2021-11-07 02:18:33 +02:00
function Public.boost_players_around_train()
local rpg = RPG.get('rpg_t')
local active_surface_index = WPT.get('active_surface_index')
if not active_surface_index then
2020-06-03 20:09:00 +02:00
return
end
2021-11-07 02:18:33 +02:00
local locomotive = WPT.get('locomotive')
if not (locomotive and locomotive.valid) then
2020-06-03 20:09:00 +02:00
return
end
2021-11-07 02:18:33 +02:00
local surface = game.surfaces[active_surface_index]
local icw_table = ICW.get_table()
local unit_surface = locomotive.unit_number
local locomotive_surface = game.surfaces[icw_table.wagons[unit_surface].surface.index]
2020-06-03 20:09:00 +02:00
2021-11-07 02:18:33 +02:00
local data = {
surface = surface,
locomotive_surface = locomotive_surface,
rpg = rpg
}
property_boost(data)
end
2020-06-03 20:09:00 +02:00
2021-11-07 02:18:33 +02:00
function Public.is_around_train(entity)
local locomotive = WPT.get('locomotive')
local active_surface_index = WPT.get('active_surface_index')
2020-06-03 20:09:00 +02:00
2021-11-07 02:18:33 +02:00
if not active_surface_index then
return false
2020-06-03 20:09:00 +02:00
end
2021-11-07 02:18:33 +02:00
if not locomotive then
return false
2021-05-23 17:03:52 +02:00
end
2021-11-07 02:18:33 +02:00
if not locomotive.valid then
return false
2020-07-06 15:45:09 +02:00
end
2021-11-07 02:18:33 +02:00
if not entity or not entity.valid then
return false
2020-06-03 20:09:00 +02:00
end
2021-11-07 02:18:33 +02:00
local surface = game.surfaces[active_surface_index]
local aura = WPT.get('locomotive_xp_aura')
2020-07-07 16:30:04 +02:00
local data = {
locomotive = locomotive,
surface = surface,
2020-08-26 11:08:12 +02:00
entity = entity,
aura = aura
2020-07-07 16:30:04 +02:00
}
local success = is_around_train(data)
return success
end
2020-05-17 12:23:55 +02:00
function Public.render_train_hp()
2020-11-15 20:23:54 +02:00
local active_surface_index = WPT.get('active_surface_index')
local surface = game.surfaces[active_surface_index]
local locomotive_health = WPT.get('locomotive_health')
local locomotive_max_health = WPT.get('locomotive_max_health')
local locomotive = WPT.get('locomotive')
local locomotive_xp_aura = WPT.get('locomotive_xp_aura')
2020-05-17 12:23:55 +02:00
2020-11-15 20:23:54 +02:00
WPT.set().health_text =
2020-05-17 12:23:55 +02:00
rendering.draw_text {
2020-11-15 20:23:54 +02:00
text = 'HP: ' .. locomotive_health .. ' / ' .. locomotive_max_health,
2020-05-17 12:23:55 +02:00
surface = surface,
2020-11-15 20:23:54 +02:00
target = locomotive,
2020-06-21 09:29:01 +02:00
target_offset = {0, -4.5},
2020-11-15 20:23:54 +02:00
color = locomotive.color,
2020-05-17 12:23:55 +02:00
scale = 1.40,
font = 'default-game',
alignment = 'center',
scale_with_zoom = false
}
2020-11-15 20:23:54 +02:00
WPT.set().caption =
2020-05-17 12:23:55 +02:00
rendering.draw_text {
2020-05-21 23:08:23 +02:00
text = 'Comfy Choo Choo',
2020-05-17 12:23:55 +02:00
surface = surface,
2020-11-15 20:23:54 +02:00
target = locomotive,
2020-06-21 09:29:01 +02:00
target_offset = {0, -6.25},
2020-11-15 20:23:54 +02:00
color = locomotive.color,
2020-05-17 12:23:55 +02:00
scale = 1.80,
font = 'default-game',
alignment = 'center',
scale_with_zoom = false
}
2020-11-15 20:23:54 +02:00
WPT.set().circle =
2020-05-17 12:23:55 +02:00
rendering.draw_circle {
surface = surface,
2020-11-15 20:23:54 +02:00
target = locomotive,
color = locomotive.color,
2020-05-17 12:23:55 +02:00
filled = false,
2020-11-15 20:23:54 +02:00
radius = locomotive_xp_aura,
2020-05-17 12:23:55 +02:00
only_in_alt_mode = true
}
end
2020-06-07 13:33:24 +02:00
function Public.transfer_pollution()
local locomotive = WPT.get('locomotive')
2021-05-16 14:42:15 +02:00
if not locomotive or not locomotive.valid then
2020-06-07 13:33:24 +02:00
return
end
2021-05-16 14:42:15 +02:00
local active_surface_index = WPT.get('active_surface_index')
2020-08-14 22:41:45 +02:00
local active_surface = game.surfaces[active_surface_index]
if not active_surface or not active_surface.valid then
return
end
2021-05-16 14:42:15 +02:00
local icw_locomotive = WPT.get('icw_locomotive')
local surface = icw_locomotive.surface
if not surface or not surface.valid then
2020-08-14 22:41:45 +02:00
return
end
2020-06-07 13:33:24 +02:00
local total_interior_pollution = surface.get_total_pollution()
2020-06-25 17:59:16 +02:00
local pollution = surface.get_total_pollution() * (3 / (4 / 3 + 1)) * Difficulty.get().difficulty_vote_value
2020-08-14 22:41:45 +02:00
active_surface.pollute(locomotive.position, pollution)
2020-06-07 13:33:24 +02:00
game.pollution_statistics.on_flow('locomotive', pollution - total_interior_pollution)
surface.clear_pollution()
end
2020-07-28 11:24:16 +02:00
local boost_players = Public.boost_players_around_train
local pollute_area = Public.transfer_pollution
local function tick()
local ticker = game.tick
if ticker % 30 == 0 then
set_locomotive_health()
validate_index()
fish_tag()
end
if ticker % 120 == 0 then
2020-08-09 20:31:50 +02:00
-- tp_player()
2020-07-28 11:24:16 +02:00
boost_players()
end
2020-08-04 12:10:15 +02:00
if ticker % 1200 == 0 then
2020-07-28 11:24:16 +02:00
set_player_spawn()
refill_fish()
end
2020-08-04 12:10:15 +02:00
if ticker % 2500 == 0 then
pollute_area()
end
2020-07-28 11:24:16 +02:00
end
2020-05-20 09:09:39 +02:00
Event.on_nth_tick(5, tick)
2021-11-07 02:18:33 +02:00
2020-07-06 15:45:09 +02:00
Event.add(defines.events.on_research_finished, on_research_finished)
2020-08-04 12:10:15 +02:00
Event.add(defines.events.on_player_changed_surface, on_player_changed_surface)
2021-02-04 21:23:07 +02:00
Event.add(defines.events.on_player_driving_changed_state, on_player_driving_changed_state)
Event.add(defines.events.on_train_created, set_carriages)
2020-05-17 12:23:55 +02:00
return Public