diff --git a/maps/mountain_fortress_v3/functions.lua b/maps/mountain_fortress_v3/functions.lua index f7b4237f..ec877637 100644 --- a/maps/mountain_fortress_v3/functions.lua +++ b/maps/mountain_fortress_v3/functions.lua @@ -2400,6 +2400,8 @@ function Public.on_player_joined_game(event) end end + + if player.online_time < 1 then if not players[player.index] then players[player.index] = {} @@ -2444,6 +2446,8 @@ function Public.on_player_joined_game(event) end end + + local locomotive = Public.get('locomotive') if not locomotive or not locomotive.valid then @@ -2467,6 +2471,16 @@ function Public.on_player_joined_game(event) player.teleport(pos, surface) end end + + if player.surface.name == 'nauvis' or player.surface.index == '1' then + local pos = surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0) + if pos then + player.teleport(pos, surface) + else + pos = game.forces.player.get_spawn_position(surface) + player.teleport(pos, surface) + end + end end function Public.on_player_created(event) @@ -2551,6 +2565,31 @@ function Public.on_pre_player_toggled_map_editor(event) Task.set_timeout_in_ticks(5, exit_editor_mode_token, { player_index = player.index }) end +function Public.on_player_changed_surface(event) + local player = game.get_player(event.player_index) + if not player or not player.valid then + return + end + + local surface_index = event.surface_index + if not surface_index then + log('No surface index found - old one was removed.') + end + + local active_surface_index = Public.get('active_surface_index') + local surface = game.surfaces[active_surface_index or 'fortress'] + + if player.surface.name == 'nauvis' or player.surface.index == '1' then + local pos = surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0) + if pos then + player.teleport(pos, surface) + else + pos = game.forces.player.get_spawn_position(surface) + player.teleport(pos, surface) + end + end +end + function Public.on_player_changed_position(event) local active_surface_index = Public.get('active_surface_index') if not active_surface_index then @@ -2976,6 +3015,7 @@ local on_player_changed_position = Public.on_player_changed_position local on_player_respawned = Public.on_player_respawned local on_player_driving_changed_state = Public.on_player_driving_changed_state local on_pre_player_toggled_map_editor = Public.on_pre_player_toggled_map_editor +local on_player_changed_surface = Public.on_player_changed_surface Event.add(de.on_player_joined_game, on_player_joined_game) Event.add(de.on_player_left_game, on_player_left_game) @@ -2984,6 +3024,7 @@ Event.add(de.on_player_changed_position, on_player_changed_position) Event.add(de.on_player_respawned, on_player_respawned) Event.add(de.on_player_driving_changed_state, on_player_driving_changed_state) Event.add(de.on_pre_player_toggled_map_editor, on_pre_player_toggled_map_editor) +Event.add(de.on_player_changed_surface, on_player_changed_surface) Event.add(de.on_player_cursor_stack_changed, on_player_cursor_stack_changed) Event.add(de.on_chart_tag_added, on_chart_tag_added) Event.add(de.on_marked_for_deconstruction, on_marked_for_deconstruction) diff --git a/maps/mountain_fortress_v3/ic/functions.lua b/maps/mountain_fortress_v3/ic/functions.lua index af4b5c5d..e93f87da 100644 --- a/maps/mountain_fortress_v3/ic/functions.lua +++ b/maps/mountain_fortress_v3/ic/functions.lua @@ -35,11 +35,7 @@ local messages = { } local function validate_entity(entity) - if not (entity and entity.valid) then - return false - end - - if type(entity) == 'boolean' then + if not entity or not entity.valid then return false end @@ -54,17 +50,17 @@ local function get_car_by_unit_number(unit_number) return cars[unit_number] end ----Returns the car from the surface_name. ----@param surface_name any ----@return table|nil -local function get_car_by_surface_name(surface_name) +---Returns the car from the matching surface. +---@param surface_index any +---@return boolean +local function get_car_by_surface(surface_index) local cars = IC.get('cars') for _, car in pairs(cars) do - if car.surface_name == surface_name then - return car + if car.surface == surface_index then + return true end end - return nil + return false end local function log_err(err) @@ -244,7 +240,7 @@ end local function get_player_entity(player) local cars = IC.get('cars') for _, car in pairs(cars) do - if car.owner == player.name and type(car.entity) == 'boolean' then + if car.owner == player.name and car.saved then return car, true elseif car.owner == player.name then return car, false @@ -292,6 +288,7 @@ local function replace_entity(cars, entity, index) cars[unit_number] = c cars[unit_number].entity = entity cars[unit_number].saved_entity = nil + cars[unit_number].saved = false cars[unit_number].transfer_entities = car.transfer_entities cars[unit_number].health_pool = { enabled = upgrades.has_upgraded_health_pool or false, @@ -319,7 +316,7 @@ local function replace_surface(surfaces, entity, index) if not validate_entity(entity) then return end - for k, surface_index in pairs(surfaces) do + for car_to_surface_index, surface_index in pairs(surfaces) do local surface = game.surfaces[surface_index] local unit_number = entity.unit_number if validate_entity(surface) then @@ -327,7 +324,7 @@ local function replace_surface(surfaces, entity, index) local car = get_car_by_unit_number(unit_number) surface.name = car.surface_name surfaces[unit_number] = surface.index - surfaces[k] = nil + surfaces[car_to_surface_index] = nil end end end @@ -401,7 +398,8 @@ local function save_surface(entity, player) local saved_surfaces = IC.get('saved_surfaces') local car = cars[entity.unit_number] - car.entity = false + car.entity = nil + car.saved = true car.saved_entity = entity.unit_number saved_surfaces[player.name] = { saved_entity = entity.unit_number, name = entity.name } @@ -426,9 +424,8 @@ end ---Kicks players out of the car surface. ---@param car any ----@param owner_id any ---@return nil -local function kick_players_from_surface(car, owner_id) +local function kick_players_from_surface(car) local surface_index = car.surface local surface = game.surfaces[surface_index] local allowed_surface = IC.get('allowed_surface') @@ -440,14 +437,10 @@ local function kick_players_from_surface(car, owner_id) if validate_entity(main_surface) then for _, e in pairs(surface.find_entities_filtered({ area = car.area })) do if validate_entity(e) and e.name == 'character' and e.player then - if owner_id and owner_id == e.player.name then - goto continue - end local p = main_surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(main_surface), 3, 0) if p then e.player.teleport(p, main_surface) end - ::continue:: end end return log_err('Car entity was not valid.') @@ -456,16 +449,12 @@ local function kick_players_from_surface(car, owner_id) for _, e in pairs(surface.find_entities_filtered({ name = 'character' })) do if validate_entity(e) and e.name == 'character' and e.player then - if owner_id and owner_id == e.player.name then - goto continue - end local p = car.entity.surface.find_non_colliding_position('character', car.entity.position, 128, 0.5) if p then e.player.teleport(p, car.entity.surface) else e.player.teleport(car.entity.position, car.entity.surface) end - ::continue:: end end end @@ -510,10 +499,6 @@ local function kick_player_from_surface(player, target) local car = get_owner_car_object(player) - if not validate_entity(car) then - return - end - if not validate_entity(car.entity) then return end @@ -709,7 +694,7 @@ local function construct_doors(car) e.minable_flag = false e.operable = false e.get_inventory(defines.inventory.fuel).insert({ name = 'coal', count = 1 }) - if type(car.entity) == 'boolean' then + if car.saved then return end doors[e.unit_number] = car.entity.unit_number @@ -977,6 +962,10 @@ function Public.kill_car(entity) local surface_index = car.surface local surface = game.surfaces[surface_index] + if not surface or not surface.valid then + log('[IC] Car surface was not valid upon trying to delete.') + return + end kill_doors(car) for _, tile in pairs(surface.find_tiles_filtered({ area = car.area })) do surface.set_tiles({ { name = out_of_map_tile, position = tile.position } }, true) @@ -1168,6 +1157,7 @@ function Public.create_car_room(car) area = car_areas[entity_type] end + for x = area.left_top.x, area.right_bottom.x - 1, 1 do for y = area.left_top.y + 2, area.right_bottom.y - 3, 1 do tiles[#tiles + 1] = { name = main_tile_name, position = { x, y } } @@ -1288,10 +1278,6 @@ function Public.create_car(event) return end - if type(ce) == 'boolean' then - return - end - local saved_surface = restore_surface(player, ce) if saved_surface then return @@ -1339,37 +1325,69 @@ function Public.remove_invalid_cars() local cars = IC.get('cars') local doors = IC.get('doors') local surfaces = IC.get('surfaces') - for k, car in pairs(cars) do - if type(car.entity) ~= 'boolean' then + for car_index, car in pairs(cars) do + if car and not car.saved then if not validate_entity(car.entity) then - cars[k] = nil - for key, value in pairs(doors) do - if k == value then + cars[car_index] = nil + for key, door_to_car_index in pairs(doors) do + if car_index == door_to_car_index then doors[key] = nil end end kick_players_from_surface(car) + log('IC::remove_invalid_cars -> car.entity was not valid - removing unit number: ' .. car_index) else - local owner = game.get_player(car.owner) and game.get_player(car.owner) or false - if (not (owner and owner.connected) or JailData.get_is_jailed(owner.name)) and not car.schedule_enable_mining then - car.schedule_enable_mining = true - Task.set_timeout_in_ticks(30, enable_car_to_be_mined, { entity = car.entity, owner_name = owner.name }) - end - if owner and owner.connected then - car.schedule_enable_mining = nil + local owner = game.get_player(car.owner) + if owner and owner.valid then + if JailData.get_is_jailed(owner.name) and not car.schedule_enable_mining then + car.schedule_enable_mining = true + Task.set_timeout_in_ticks(30, enable_car_to_be_mined, { entity = car.entity, owner_name = owner.name }) + end + + if not owner.connected and not car.schedule_enable_mining then + car.schedule_enable_mining = true + Task.set_timeout_in_ticks(30, enable_car_to_be_mined, { entity = car.entity, owner_name = owner.name }) + end + + if owner.connected and car.schedule_enable_mining then + car.schedule_enable_mining = nil + end + else + if not car.schedule_enable_mining then + Task.set_timeout_in_ticks(30, enable_car_to_be_mined, { entity = car.entity, owner_name = owner.name }) + cars[car_index] = nil + if cars[car_index] then + log('IC::remove_invalid_cars -> car will be deleted since no valid owner was found.') + log(serpent.block(cars[car_index])) + cars[car_index] = nil + end + end end end end + end - for surface_key, index in pairs(surfaces) do - local surface = game.surfaces[index] - if not validate_entity(surface) then - return - end - if not get_car_by_surface_name(car.surface_name) then + for car_to_surface_index, surface_index in pairs(surfaces) do + local surface = game.surfaces[surface_index] + if surface and surface.valid then + local valid_surface = get_car_by_surface(surface.index) + if not valid_surface then + log(serpent.block(car_to_surface_index)) + log(serpent.block(cars[car_to_surface_index])) + log(serpent.block(cars)) game.delete_surface(surface) - surfaces[surface_key] = nil + surfaces[car_to_surface_index] = nil + log('IC::remove_invalid_cars -> surface was valid and will be deleted since no car entry.') + end + else + if cars[car_to_surface_index] then + log('IC::remove_invalid_cars -> car will be deleted since no valid surface was found.') + log(serpent.block(cars[car_to_surface_index])) + cars[car_to_surface_index] = nil end + + log('IC::remove_invalid_cars -> surface was not valid upon trying to delete for: ' .. car_to_surface_index) + surfaces[car_to_surface_index] = nil end end end diff --git a/maps/mountain_fortress_v3/mystical_chest.lua b/maps/mountain_fortress_v3/mystical_chest.lua index d62e8989..5c6428c1 100644 --- a/maps/mountain_fortress_v3/mystical_chest.lua +++ b/maps/mountain_fortress_v3/mystical_chest.lua @@ -1,3 +1,4 @@ +local Server = require 'utils.server' local Color = require 'utils.color_presets' local Event = require 'utils.event' local Public = require 'maps.mountain_fortress_v3.table' @@ -247,6 +248,7 @@ local mc_random_rewards = { RPG.add_to_global_pool(rng) local message = ({ 'locomotive.xp_bonus', player.name }) Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac') + Server.to_discord_bold(table.concat { '*** ', '[Mystical Chest] ' .. player.name .. ' has granted xp bonus for the whole team!', ' ***' }) return true end), 512 @@ -279,6 +281,7 @@ local mc_random_rewards = { end local message = ({ 'locomotive.coin_bonus', p.name }) Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac') + Server.to_discord_bold(table.concat { '*** ', '[Mystical Chest] ' .. p.name .. ' has granted coinsies for the whole team!', ' ***' }) return true end), 512 @@ -306,6 +309,7 @@ local mc_random_rewards = { force.character_running_speed_modifier = force.character_running_speed_modifier + speed local message = ({ 'locomotive.movement_bonus', player.name }) Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac') + Server.to_discord_bold(table.concat { '*** ', '[Mystical Chest] ' .. player.name .. ' has granted movement speed bonus for the whole team!', ' ***' }) return true end), 512 @@ -328,6 +332,7 @@ local mc_random_rewards = { force.manual_mining_speed_modifier = force.manual_mining_speed_modifier + 1 local message = ({ 'locomotive.mining_bonus', player.name }) Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac') + Server.to_discord_bold(table.concat { '*** ', '[Mystical Chest] ' .. player.name .. ' has granted mining speed bonus for the whole team!', ' ***' }) return true end), 512 @@ -350,6 +355,7 @@ local mc_random_rewards = { force.manual_crafting_speed_modifier = force.manual_crafting_speed_modifier + 2 local message = ({ 'locomotive.crafting_bonus', player.name }) Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac') + Server.to_discord_bold(table.concat { '*** ', '[Mystical Chest] ' .. player.name .. ' has granted crafting speed bonus for the whole team!', ' ***' }) return true end), 256 diff --git a/maps/mountain_fortress_v3/stateful/gui.lua b/maps/mountain_fortress_v3/stateful/gui.lua index c03cd8e1..db084983 100644 --- a/maps/mountain_fortress_v3/stateful/gui.lua +++ b/maps/mountain_fortress_v3/stateful/gui.lua @@ -507,6 +507,7 @@ local function boss_frame(player, alert) local stateful = Public.get_stateful() local collection = stateful.collection + if not collection then return end local frame = player.gui.screen.add { type = 'frame', name = boss_frame_name, caption = { 'stateful.win_conditions' }, direction = 'vertical' } if not alert then @@ -574,7 +575,7 @@ local function boss_frame(player, alert) local objective_tbl = frame.add { type = 'table', column_count = 2 } objective_tbl.style.horizontally_stretchable = true - if collection.gather_time <= 0 then + if collection.gather_time and collection.gather_time <= 0 then local survive_for_left_flow = objective_tbl.add({ type = 'flow' }) survive_for_left_flow.style.horizontal_align = 'left' survive_for_left_flow.style.horizontally_stretchable = true diff --git a/modules/rpg/functions.lua b/modules/rpg/functions.lua index 8034c3e3..d949b919 100644 --- a/modules/rpg/functions.lua +++ b/modules/rpg/functions.lua @@ -71,7 +71,7 @@ local function create_healthbar(player, size) entity = player.character, offset = { 0, -2.5 }, }, - surface = player.surface + surface = player.physical_surface } ) end @@ -88,7 +88,7 @@ local function create_manabar(player, size) entity = player.character, offset = { 0, -2.0 }, }, - surface = player.surface + surface = player.physical_surface } ) end diff --git a/modules/rpg/main.lua b/modules/rpg/main.lua index a1a9fc0b..4fb4b30f 100644 --- a/modules/rpg/main.lua +++ b/modules/rpg/main.lua @@ -166,11 +166,12 @@ local get_cause_player = { ['car'] = function (cause) local players = {} local driver = cause.get_driver() - if driver then - if driver.player then - players[#players + 1] = driver.player - end + if driver and driver.valid and driver.is_player() then + players[#players + 1] = driver + else + players[#players + 1] = driver.player end + local passenger = cause.get_passenger() if passenger then if passenger.player then diff --git a/modules/show_inventory.lua b/modules/show_inventory.lua index 9a658507..9977cdec 100644 --- a/modules/show_inventory.lua +++ b/modules/show_inventory.lua @@ -122,12 +122,6 @@ local function validate_player(player) if not player.valid then return false end - if not player.character then - return false - end - if not player.connected then - return false - end if not game.get_player(player.index) then return false end @@ -181,6 +175,13 @@ end local function redraw_inventory(gui, source, target, caption, panel_type) gui.clear() + if not panel_type then + if gui and gui.valid then + gui.destroy() + end + return + end + local items_table = gui.add({ type = 'table', column_count = 11 }) local types = prototypes.item @@ -208,13 +209,13 @@ local function redraw_inventory(gui, source, target, caption, panel_type) sprite = 'item/' .. name, number = count, name = name, - tooltip = {'', (quality.name == 'normal' and '' or {'', quality.localised_name, ' '}), types[name].localised_name}, + tooltip = { '', (quality.name == 'normal' and '' or { '', quality.localised_name, ' ' }), types[name].localised_name }, style = 'slot_button' } ) button.enabled = false if quality.name ~= 'normal' then - local qual_button = button.add({type = 'sprite-button', sprite = 'quality/' .. quality.name, style = 'transparent_slot'}) + local qual_button = button.add({ type = 'sprite-button', sprite = 'quality/' .. quality.name, style = 'transparent_slot' }) qual_button.style.top_padding = 18 qual_button.style.right_padding = 18 end @@ -231,13 +232,13 @@ local function redraw_inventory(gui, source, target, caption, panel_type) sprite = 'item/' .. item.name, number = item.count, name = item.name .. item.quality, - tooltip = {'', (item.quality == 'normal' and '' or {'', prototypes.quality[item.quality].localised_name, ' '}), types[item.name].localised_name}, + tooltip = { '', (item.quality == 'normal' and '' or { '', prototypes.quality[item.quality].localised_name, ' ' }), types[item.name].localised_name }, style = 'slot_button' } ) armor_gui.enabled = false if item.quality ~= 'normal' then - local qualgrid_button = armor_gui.add({type = 'sprite-button', sprite = 'quality/' .. quality.name, style = 'transparent_slot'}) + local qualgrid_button = armor_gui.add({ type = 'sprite-button', sprite = 'quality/' .. quality.name, style = 'transparent_slot' }) qualgrid_button.style.top_padding = 18 qualgrid_button.style.right_padding = 18 end @@ -473,7 +474,7 @@ function Public.show_inventory(player, target_player) open_inventory(player, target_player) return true else - player.print('[Inventory] Please type a name of a player who is connected.', Color.warning) + player.print('[Inventory] Please type a valid player name.', Color.warning) return false end end