1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2024-12-30 23:17:53 +02:00

desync fix and tweaks

This commit is contained in:
Gerkiz 2020-08-21 13:56:01 +02:00
parent 062d63ca6e
commit 179400ded8
15 changed files with 859 additions and 219 deletions

View File

@ -11,7 +11,8 @@ local blacklist = {
['fluid-wagon'] = true,
['land-mine'] = true,
['car'] = true,
['tank'] = true
['tank'] = true,
['spidertron'] = true
}
market.weapons = {

View File

@ -14,6 +14,7 @@ local BiterHealthBooster = require 'modules.biter_health_booster'
local Difficulty = require 'modules.difficulty_vote'
local Traps = require 'maps.mountain_fortress_v3.traps'
local Locomotive = require 'maps.mountain_fortress_v3.locomotive'
local ExplosiveBullets = require 'maps.mountain_fortress_v3.explosive_gun_bullets'
local Alert = require 'utils.alert'
local Task = require 'utils.task'
local Token = require 'utils.token'
@ -382,7 +383,13 @@ local function on_player_mined_entity(event)
if entity.type == 'simple-entity' or entity.type == 'tree' then
this.mined_scrap = this.mined_scrap + 1
Mining.on_player_mined_entity(event)
give_coin(player)
if entity.type == 'tree' then
if random(1, 2) == 1 then
give_coin(player)
end
else
give_coin(player)
end
if rpg_char.stone_path then
entity.surface.set_tiles({{name = 'stone-path', position = entity.position}}, true)
end
@ -570,12 +577,13 @@ local function on_entity_damaged(event)
return
end
protect_entities(event)
biters_chew_rocks_faster(event)
local wave_number = WD.get_wave()
local boss_wave_warning = WD.alert_boss_wave()
local munch_time = WPT.get('munch_time')
protect_entities(event)
biters_chew_rocks_faster(event)
if munch_time then
if boss_wave_warning or wave_number >= 1500 then
if random(0, 512) == 1 then
@ -583,6 +591,10 @@ local function on_entity_damaged(event)
end
end
end
if WPT.get('explosive_bullets') then
ExplosiveBullets.explosive_bullets(event)
return
end
end
local function on_player_repaired_entity(event)

View File

@ -0,0 +1,64 @@
local radius = 3
local random = math.random
local floor = math.floor
local sqrt = math.sqrt
local Public = {}
local function splash_damage(surface, position, final_damage_amount)
local create = surface.create_entity
local damage = random(floor(final_damage_amount * 3), floor(final_damage_amount * 4))
for _, e in pairs(
surface.find_entities_filtered(
{area = {{position.x - radius, position.y - radius}, {position.x + radius, position.y + radius}}}
)
) do
if e.valid and e.health then
local distance_from_center = sqrt((e.position.x - position.x) ^ 2 + (e.position.y - position.y) ^ 2)
if distance_from_center <= radius then
local damage_distance_modifier = 1 - distance_from_center / radius
if damage > 0 then
if random(1, 3) == 1 then
create({name = 'explosion', position = e.position})
end
e.damage(damage * damage_distance_modifier, 'player', 'explosion')
end
end
end
end
end
function Public.explosive_bullets(event)
if random(1, 3) ~= 1 then
return false
end
local entity = event.entity
if not entity or not entity.valid then
return
end
if event.damage_type.name ~= 'physical' then
return false
end
local player = event.cause
if not player or not player.valid or player.name ~= 'character' then
return
end
if player.shooting_state.state == defines.shooting.not_shooting then
return false
end
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
if selected_weapon and selected_weapon.name ~= 'submachine-gun' and selected_weapon.name ~= 'pistol' then
return false
end
local surface = player.surface
local create = surface.create_entity
create({name = 'explosion', position = entity.position})
splash_damage(surface, entity.position, event.final_damage_amount)
end
return Public

View File

@ -259,6 +259,7 @@ local function on_player_changed_surface(event)
info.tooltip = 'Shows statistics!'
info.sprite = 'item/dummy-steel-axe'
info.visible = true
elseif player.surface == wagon_surface then
if wd then
wd.visible = false
@ -281,6 +282,7 @@ local function on_player_changed_surface(event)
if info then
info.tooltip = 'Hide locomotive minimap!'
info.sprite = 'utility/map'
info.visible = true
end
if player.gui.top[main_frame_name] then
if frame then
@ -288,6 +290,10 @@ local function on_player_changed_surface(event)
return
end
end
else
if info and info.visible then
info.visible = false
end
end
end

View File

@ -25,6 +25,16 @@ local function log_err(ic, err)
end
end
local function get_trusted_system(this, player)
if not this.trust_system[player.index] then
this.trust_system[player.index] = {
[player.name] = true
}
end
return this.trust_system[player.index]
end
local function upperCase(str)
return (str:gsub('^%l', string.upper))
end
@ -70,9 +80,39 @@ local function get_owner_car_object(cars, player)
return false
end
local function get_entity_from_player_surface(cars, player)
for k, car in pairs(cars) do
if validate_entity(car.entity) then
if validate_entity(car.surface) then
if car.surface.index == player.surface.index then
return car.entity
end
end
end
end
return false
end
local function get_owner_car_surface(cars, player, target)
for k, car in pairs(cars) do
if car.owner == player.index then
if validate_entity(car.surface) then
if car.surface.index == target.surface.index then
return true
else
return false
end
else
return false
end
end
end
return false
end
local function get_player_surface(ic, player)
local surfaces = ic.surfaces
for k, surface in pairs(surfaces) do
for _, surface in pairs(surfaces) do
if validate_entity(surface) then
if surface.index == player.surface.index then
return true
@ -282,7 +322,7 @@ end
local function kick_players_out_of_vehicles(car)
for _, player in pairs(game.connected_players) do
local character = player.character
if character and character.valid and character.driving then
if validate_entity(character) and character.driving then
if car.surface == player.surface then
character.driving = false
end
@ -290,15 +330,15 @@ local function kick_players_out_of_vehicles(car)
end
end
local function kick_player_from_surface(ic, car)
if not car.surface or not car.surface.valid then
local function kick_players_from_surface(ic, car)
if not validate_entity(car.surface) then
return log_err('Car surface was not valid.')
end
if not car.entity or not car.entity.valid then
local main_surface = game.surfaces[ic.allowed_surface]
if main_surface and main_surface.valid then
if validate_entity(main_surface) then
for _, e in pairs(car.surface.find_entities_filtered({area = car.area})) do
if e and e.valid and e.name == 'character' and e.player then
if validate_entity(e) and e.name == 'character' and e.player then
e.player.teleport(
main_surface.find_non_colliding_position(
'character',
@ -316,7 +356,7 @@ local function kick_player_from_surface(ic, car)
end
for _, e in pairs(car.surface.find_entities_filtered({area = car.area})) do
if e and e.valid and e.name == 'character' and e.player then
if validate_entity(e) and e.name == 'character' and e.player then
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)
@ -327,6 +367,46 @@ local function kick_player_from_surface(ic, car)
end
end
local function kick_player_from_surface(ic, player, target)
local cars = ic.cars
local main_surface = game.surfaces[ic.allowed_surface]
if not validate_entity(main_surface) then
return
end
local c = get_owner_car_object(cars, player)
local car = ic.cars[c]
if not validate_entity(car.entity) then
return
end
if validate_entity(player) then
if validate_entity(target) then
local locate = get_owner_car_surface(cars, player, target)
if locate then
local p = car.entity.surface.find_non_colliding_position('character', car.entity.position, 128, 0.5)
if p then
target.teleport(p, car.entity.surface)
else
target.teleport(
main_surface.find_non_colliding_position(
'character',
game.forces.player.get_spawn_position(main_surface),
3,
0,
5
),
main_surface
)
end
target.print('You were kicked out of ' .. player.name .. ' vehicle.', Color.warning)
end
end
end
end
local function restore_surface(ic, player, entity)
local ce = entity
local saved_surfaces = ic.saved_surfaces
@ -515,7 +595,7 @@ function Public.save_car(ic, event)
local health = entity.health
kick_players_out_of_vehicles(car)
kick_player_from_surface(ic, car)
kick_players_from_surface(ic, car)
get_player_data(ic, player)
if car.owner == player.index then
@ -568,7 +648,7 @@ function Public.kill_car(ic, entity)
local surface = car.surface
kick_players_out_of_vehicles(car)
kill_doors(ic, car)
kick_player_from_surface(ic, car)
kick_players_from_surface(ic, car)
for _, tile in pairs(surface.find_tiles_filtered({area = car.area})) do
surface.set_tiles({{name = 'out-of-map', position = tile.position}}, true)
end
@ -581,8 +661,17 @@ function Public.validate_owner(ic, player, entity)
local cars = ic.cars
local unit_number = entity.unit_number
local car = cars[unit_number]
if car and car.entity and validate_entity(car.entity) then
if not car then
return
end
if validate_entity(car.entity) then
local p = game.players[car.owner]
local list = get_trusted_system(ic, p)
if p and p.valid then
if list[player.name] then
return
end
end
if p then
if car.owner ~= player.index and player.driving then
player.driving = false
@ -790,7 +879,7 @@ function Public.remove_invalid_cars(ic)
ic.doors[key] = nil
end
end
kick_player_from_surface(ic, car)
kick_players_from_surface(ic, car)
end
end
for k, surface in pairs(ic.surfaces) do
@ -807,7 +896,7 @@ function Public.infinity_scrap(ic, event, recreate)
end
local entity = event.entity
if not entity or not entity.valid then
if not validate_entity(entity) then
return
end
@ -824,8 +913,19 @@ function Public.infinity_scrap(ic, event, recreate)
return
end
if get_player_surface(ic, player) then
if recreate then
entity.surface.create_entity({name = 'sand-rock-big', position = entity.position})
return
end
end
if not is_owner_on_car_surface(ic, player) then
if get_player_surface(ic, player) then
if recreate then
entity.surface.create_entity({name = 'sand-rock-big', position = entity.position})
return
end
entity.surface.create_entity({name = 'sand-rock-big', position = entity.position})
player.print('This is not your rock to mine!', Color.warning)
event.buffer.clear()
@ -833,11 +933,6 @@ function Public.infinity_scrap(ic, event, recreate)
end
end
if recreate then
entity.surface.create_entity({name = 'sand-rock-big', position = entity.position})
return
end
local items = {
'iron-plate',
'iron-gear-wheel',
@ -979,6 +1074,18 @@ function Public.use_door_with_entity(ic, player, door)
return
end
local owner = game.players[car.owner]
local list = get_trusted_system(ic, owner)
if owner and owner.valid then
if not list[player.name] then
player.driving = false
return player.print(
'You have not been approved by ' .. owner.name .. ' to enter their vehicle.',
Color.warning
)
end
end
player_data.fallback_surface = car.entity.surface.index
player_data.fallback_position = {car.entity.position.x, car.entity.position.y}
@ -1023,4 +1130,8 @@ function Public.item_transfer(ic)
end
end
Public.kick_player_from_surface = kick_player_from_surface
Public.get_player_surface = get_player_surface
Public.get_entity_from_player_surface = get_entity_from_player_surface
return Public

View File

@ -1,7 +1,8 @@
local ic = require 'maps.mountain_fortress_v3.ic.table'
local ICT = require 'maps.mountain_fortress_v3.ic.table'
local Color = require 'utils.color_presets'
local Gui = require 'utils.gui'
local Tabs = require 'comfy_panel.main'
local Event = require 'utils.event'
local Public = {}
@ -9,7 +10,12 @@ local Public = {}
local save_button_name = Gui.uid_name()
local discard_button_name = Gui.uid_name()
local main_frame_name = Gui.uid_name()
local draw_add_player_frame_name = Gui.uid_name()
local main_toolbar_name = Gui.uid_name()
local add_player_name = Gui.uid_name()
local kick_player_name = Gui.uid_name()
local raise_event = script.raise_event
local function increment(t, k)
t[k] = true
@ -19,47 +25,33 @@ local function decrement(t, k)
t[k] = nil
end
local function create_player_table(this, player)
local function create_player_table(player)
local this = ICT.get()
if not this.trust_system[player.index] then
this.trust_system[player.index] = {}
this.trust_system[player.index] = {
[player.name] = true
}
end
return this.trust_system[player.index]
end
local function create_input_element(frame, type, value, items, index)
if type == 'slider' then
return frame.add({type = 'slider', value = value, minimum_value = 0, maximum_value = 1})
end
if type == 'boolean' then
return frame.add({type = 'checkbox', state = value})
end
if type == 'dropdown' then
return frame.add({type = 'drop-down', name = 'admin_player_select', items = items, selected_index = index})
end
return frame.add({type = 'text-box', text = value})
end
local function remove_main_frame(main_frame)
Gui.remove_data_recursively(main_frame)
main_frame.destroy()
end
local function draw_main_frame(player)
local this = ic.get()
local player_list = create_player_table(this, player)
local function draw_add_player(frame)
local main_frame =
player.gui.screen.add(
frame.add(
{
type = 'frame',
name = main_frame_name,
caption = 'Car Settings',
name = draw_add_player_frame_name,
caption = 'Add Player',
direction = 'vertical'
}
)
main_frame.auto_center = true
local main_frame_style = main_frame.style
main_frame_style.width = 400
main_frame_style.width = 325
main_frame_style.use_header_filler = true
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
@ -67,97 +59,15 @@ local function draw_main_frame(player)
inside_frame_style.padding = 0
local inside_table = inside_frame.add {type = 'table', column_count = 1}
local inside_table_style = inside_table.style
inside_table_style.vertical_spacing = 0
inside_table_style.vertical_spacing = 5
inside_table_style.top_padding = 10
inside_table_style.left_padding = 10
inside_table_style.right_padding = 0
inside_table_style.bottom_padding = 10
inside_table_style.width = 325
inside_table.add({type = 'line'})
local info_text = inside_table.add({type = 'label', caption = 'Trust List'})
local info_text_style = info_text.style
info_text_style.font = 'default-bold'
info_text_style.padding = 0
info_text_style.left_padding = 10
info_text_style.horizontal_align = 'left'
info_text_style.vertical_align = 'bottom'
info_text_style.font_color = {0.55, 0.55, 0.99}
inside_table.add({type = 'line'})
local settings_frame = inside_table.add({type = 'scroll-pane'})
local settings_style = settings_frame.style
settings_style.vertically_squashable = true
settings_style.bottom_padding = 5
settings_style.left_padding = 5
settings_style.right_padding = 5
settings_style.top_padding = 5
local settings_grid = settings_frame.add({type = 'table', column_count = 2})
local accept_label =
settings_grid.add(
{
type = 'label',
caption = 'Add a trusted player.',
tooltip = ''
}
)
accept_label.tooltip = 'This will allow the given player to join your vehicle.'
local players = game.connected_players
local allowed = {}
for _, p in pairs(players) do
if not player_list[p.name] then
allowed[#allowed + 1] = tostring(p.name)
end
end
local accept_label_style = accept_label.style
accept_label_style.horizontally_stretchable = true
accept_label_style.height = 35
accept_label_style.vertical_align = 'center'
local name_input = settings_grid.add({type = 'flow'})
local name_input_style = name_input.style
name_input_style.height = 35
name_input_style.vertical_align = 'center'
local trusted_players_input = create_input_element(name_input, 'dropdown', false, allowed, 1)
local denied = {}
local deny_players_input
if next(player_list) then
for _, p in pairs(player_list) do
denied[#denied + 1] = p
end
local deny_label =
settings_grid.add(
{
type = 'label',
caption = 'Remove a trusted player.',
tooltip = ''
}
)
deny_label.tooltip = 'This will instantly kick the player from your vehicle.'
local deny_label_style = deny_label.style
deny_label_style.horizontally_stretchable = true
deny_label_style.height = 35
deny_label_style.vertical_align = 'center'
local deny_input = settings_grid.add({type = 'flow'})
local deny_input_style = deny_input.style
deny_input_style.height = 35
deny_input_style.vertical_align = 'center'
deny_players_input = create_input_element(deny_input, 'dropdown', false, denied, 1)
end
local data = {
trusted_players_input = trusted_players_input
}
if deny_players_input then
data.deny_players_input = deny_players_input
end
local add_player_frame = main_frame.add({type = 'textfield', text = 'Name of the player.'})
add_player_frame.style.width = 140
local bottom_flow = main_frame.add({type = 'flow', direction = 'horizontal'})
@ -165,16 +75,150 @@ local function draw_main_frame(player)
left_flow.style.horizontal_align = 'left'
left_flow.style.horizontally_stretchable = true
local close_button = left_flow.add({type = 'button', name = discard_button_name, caption = 'Discard changes'})
local close_button = left_flow.add({type = 'button', name = discard_button_name, caption = 'Discard'})
close_button.style = 'back_button'
close_button.style.maximal_width = 100
local right_flow = bottom_flow.add({type = 'flow'})
right_flow.style.horizontal_align = 'right'
local save_button = right_flow.add({type = 'button', name = save_button_name, caption = 'Save changes'})
local save_button = right_flow.add({type = 'button', name = save_button_name, caption = 'Save'})
save_button.style = 'confirm_button'
save_button.style.maximal_width = 100
Gui.set_data(save_button, data)
Gui.set_data(save_button, add_player_frame)
end
local function draw_players(data)
local player_table = data.player_table
local add_player_frame = data.add_player_frame
local player = data.player
local player_list = create_player_table(player)
for p, _ in pairs(player_list) do
Gui.set_data(add_player_frame, p)
local t_label =
player_table.add(
{
type = 'label',
caption = p
}
)
t_label.style.minimal_width = 75
t_label.style.horizontal_align = 'center'
local a_label =
player_table.add(
{
type = 'label',
caption = '✔️'
}
)
a_label.style.minimal_width = 75
a_label.style.horizontal_align = 'center'
a_label.style.font = 'default-large-bold'
local kick_flow = player_table.add {type = 'flow'}
local kick_player_button =
kick_flow.add(
{
type = 'button',
caption = 'Kick ' .. p,
name = kick_player_name
}
)
if player.name == t_label.caption then
kick_player_button.enabled = false
end
kick_player_button.style.minimal_width = 75
Gui.set_data(kick_player_button, p)
end
end
local function draw_main_frame(player)
local main_frame =
player.gui.screen.add(
{
type = 'frame',
name = main_frame_name,
caption = 'Car Settings',
direction = 'vertical',
style = 'inner_frame_in_outer_frame'
}
)
main_frame.auto_center = true
local main_frame_style = main_frame.style
main_frame_style.width = 350
main_frame_style.use_header_filler = true
local inside_frame = main_frame.add {type = 'frame', style = 'inside_shallow_frame'}
local inside_frame_style = inside_frame.style
inside_frame_style.padding = 0
local inside_table = inside_frame.add {type = 'table', column_count = 1}
local inside_table_style = inside_table.style
inside_table_style.vertical_spacing = 5
inside_table_style.top_padding = 10
inside_table_style.left_padding = 10
inside_table_style.right_padding = 0
inside_table_style.bottom_padding = 10
inside_table_style.width = 350
local add_player_frame = inside_table.add({type = 'button', caption = 'Add Player', name = add_player_name})
local player_table =
inside_table.add {
type = 'table',
column_count = 3,
draw_horizontal_lines = true,
draw_vertical_lines = true,
vertical_centering = true
}
local player_table_style = player_table.style
player_table_style.vertical_spacing = 10
player_table_style.width = 350
player_table_style.horizontal_spacing = 30
local name_label =
player_table.add(
{
type = 'label',
caption = 'Name',
tooltip = ''
}
)
name_label.style.minimal_width = 75
name_label.style.horizontal_align = 'center'
local trusted_label =
player_table.add(
{
type = 'label',
caption = 'Allowed',
tooltip = ''
}
)
trusted_label.style.minimal_width = 75
trusted_label.style.horizontal_align = 'center'
local operations_label =
player_table.add(
{
type = 'label',
caption = 'Operations',
tooltip = ''
}
)
operations_label.style.minimal_width = 75
operations_label.style.horizontal_align = 'center'
local data = {
player_table = player_table,
add_player_frame = add_player_frame,
player = player
}
draw_players(data)
player.opened = main_frame
end
@ -210,8 +254,7 @@ local function add_toolbar(player, remove)
end
local tooltip = 'Control who may enter your vehicle.'
local b =
player.gui.top.add(
player.gui.top.add(
{
type = 'sprite-button',
sprite = 'item/spidertron',
@ -219,14 +262,6 @@ local function add_toolbar(player, remove)
tooltip = tooltip
}
)
b.style.font_color = {r = 0.11, g = 0.8, b = 0.44}
b.style.font = 'heading-1'
b.style.minimal_height = 38
b.style.minimal_width = 38
b.style.maximal_height = 38
b.style.maximal_width = 38
b.style.padding = 1
b.style.margin = 0
end
local function remove_toolbar(player)
@ -243,6 +278,28 @@ local function remove_toolbar(player)
end
end
Gui.on_click(
add_player_name,
function(event)
local player = event.player
if not player or not player.valid or not player.character then
return
end
local screen = player.gui.screen
local frame = screen[main_frame_name]
if not frame or not frame.valid then
return
end
local player_frame = frame[draw_add_player_frame_name]
if not player_frame or not player_frame.valid then
draw_add_player(frame)
else
player_frame.destroy()
end
end
)
Gui.on_click(
save_button_name,
function(event)
@ -251,57 +308,80 @@ Gui.on_click(
return
end
local this = ic.get()
local player_list = this.trust_system[player.index]
local player_list = create_player_table(player)
local screen = player.gui.screen
local frame = screen[main_frame_name]
local data = Gui.get_data(event.element)
local trusted_players_input = data.trusted_players_input
local deny_players_input = data.deny_players_input
local add_player_frame = Gui.get_data(event.element)
if frame and frame.valid then
if trusted_players_input and trusted_players_input.valid and trusted_players_input.selected_index then
local index = trusted_players_input.selected_index
if not index then
if add_player_frame and add_player_frame.valid and add_player_frame.text then
local text = add_player_frame.text
if not text then
return
end
local target = game.players[index]
if not target or not target.valid then
local player_to_add = game.get_player(text)
if not player_to_add or not player_to_add.valid then
return player.print('Target player was not valid.', Color.warning)
end
local name = target.name
if target.index == player.index then
return player.print('Target player is not valid.', Color.warning)
end
local name = player_to_add.name
if not player_list[name] then
player.print(name .. ' was added to your vehicle.', Color.info)
increment(this.trust_system[player.index], name)
player_to_add.print(player.name .. ' added you to their vehicle. You may now enter it.', Color.info)
increment(player_list, name)
else
return player.print('Target player is already trusted.', Color.warning)
end
remove_main_frame(event.element)
if player.gui.screen[main_frame_name] then
toggle(player, true)
end
end
end
end
)
if deny_players_input and deny_players_input.valid and deny_players_input.selected_index then
local index = deny_players_input.selected_index
if not index then
return
end
local target = game.players[index]
if not target or not target.valid then
player.print('Target player was not valid.', Color.warning)
return
end
local name = target.name
Gui.on_click(
kick_player_name,
function(event)
local player = event.player
if not player or not player.valid or not player.character then
return
end
if target.index == player.index then
return player.print('Target player is not valid.', Color.warning)
end
if player_list[name] then
player.print(name .. ' was removed from your vehicle.', Color.info)
decrement(this.trust_system[player.index], name)
end
local player_list = create_player_table(player)
local screen = player.gui.screen
local frame = screen[main_frame_name]
local player_name = Gui.get_data(event.element)
local this = ICT.get()
if frame and frame.valid then
if not player_name then
return
end
local target = game.get_player(player_name)
if not target or not target.valid then
player.print('Target player was not valid.', Color.warning)
return
end
local name = target.name
if player_list[name] then
player.print(name .. ' was removed from your vehicle.', Color.info)
decrement(player_list, name)
raise_event(
ICT.events.on_player_kicked_from_surface,
{
player = player,
target = target,
this = this
}
)
end
remove_main_frame(event.element)
@ -319,11 +399,15 @@ Gui.on_click(
local player = event.player
local screen = player.gui.screen
local frame = screen[main_frame_name]
if not frame or not frame.valid then
return
end
local player_frame = frame[draw_add_player_frame_name]
if not player or not player.valid or not player.character then
return
end
if frame and frame.valid then
frame.destroy()
if player_frame and player_frame.valid then
player_frame.destroy()
end
end
)
@ -351,4 +435,20 @@ Public.toggle = toggle
Public.add_toolbar = add_toolbar
Public.remove_toolbar = remove_toolbar
Event.add(
defines.events.on_gui_closed,
function(event)
local player = game.get_player(event.player_index)
local screen = player.gui.screen
local frame = screen[main_frame_name]
if not player or not player.valid or not player.character then
return
end
if frame and frame.valid then
frame.destroy()
end
end
)
return Public

View File

@ -3,6 +3,7 @@ require 'modules.check_fullness'
local Event = require 'utils.event'
local Functions = require 'maps.mountain_fortress_v3.ic.functions'
local IC = require 'maps.mountain_fortress_v3.ic.table'
local Minimap = require 'maps.mountain_fortress_v3.ic.minimap'
local Public = {}
Public.reset = IC.reset
@ -16,7 +17,7 @@ local function on_entity_died(event)
local ic = IC.get()
if entity.type == 'car' or entity.name == 'spidertron'then
if entity.type == 'car' or entity.name == 'spidertron' then
Functions.kill_car(ic, entity)
end
@ -33,7 +34,7 @@ local function on_player_mined_entity(event)
local ic = IC.get()
if entity.type == 'car' or entity.name == 'spidertron'then
if entity.type == 'car' or entity.name == 'spidertron' then
Functions.save_car(ic, event)
end
@ -50,7 +51,7 @@ local function on_robot_mined_entity(event)
end
local ic = IC.get()
if entity.type == 'car' or entity.name == 'spidertron'then
if entity.type == 'car' or entity.name == 'spidertron' then
Functions.kill_car(ic, entity)
end
@ -95,15 +96,48 @@ local function on_tick()
Functions.item_transfer(ic)
end
if tick % 600 == 0 then
if tick % 240 == 0 then
Minimap.update_minimap()
end
if tick % 400 == 0 then
Functions.remove_invalid_cars(ic)
end
end
local function on_gui_click(event)
local element = event.element
if not element or not element.valid then
return
end
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
end
if event.element.name == 'minimap_button' then
Minimap.minimap(player, false)
elseif event.element.name == 'minimap_frame' or event.element.name == 'minimap_toggle_frame' then
Minimap.toggle_minimap(event)
elseif event.element.name == 'switch_auto_map' then
Minimap.toggle_auto(player)
end
end
local function trigger_on_player_kicked_from_surface(data)
local player = data.player
local target = data.target
local this = data.this
Functions.kick_player_from_surface(this, player, target)
end
local function on_init()
Public.reset()
end
local changed_surface = Minimap.changed_surface
Event.on_init(on_init)
Event.add(defines.events.on_tick, on_tick)
Event.add(defines.events.on_player_driving_changed_state, on_player_driving_changed_state)
@ -111,13 +145,7 @@ Event.add(defines.events.on_entity_died, on_entity_died)
Event.add(defines.events.on_built_entity, on_built_entity)
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
Event.add(defines.events.on_robot_mined_entity, on_robot_mined_entity)
--[[ Event.add(
defines.events.on_player_joined_game,
function(e)
local p = game.get_player(e.player_index)
p.insert({name = 'car', count = 5})
p.insert({name = 'tank', count = 5})
end
)
]]
Event.add(defines.events.on_gui_click, on_gui_click)
Event.add(defines.events.on_player_changed_surface, changed_surface)
Event.add(IC.events.on_player_kicked_from_surface, trigger_on_player_kicked_from_surface)
return Public

View File

@ -0,0 +1,255 @@
local Public = {}
local ICT = require 'maps.mountain_fortress_v3.ic.table'
local Functions = require 'maps.mountain_fortress_v3.ic.functions'
local Gui = require 'maps.mountain_fortress_v3.ic.gui'
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
if not game.players[player.name] then
return false
end
return true
end
local function create_button(player)
local button =
player.gui.top.add(
{
type = 'sprite-button',
name = 'minimap_button',
sprite = 'utility/map',
tooltip = 'Open or close minimap.'
}
)
button.visible = false
end
function Public.toggle_button(player)
if not player.gui.top['minimap_button'] then
create_button(player)
end
local ic = ICT.get()
local button = player.gui.top['minimap_button']
if Functions.get_player_surface(ic, player) then
button.visible = true
else
button.visible = false
end
end
local function get_player_data(player)
local ic = ICT.get()
local player_data = ic.minimap[player.index]
if ic.minimap[player.index] then
return player_data
end
ic.minimap[player.index] = {
surface = ic.allowed_surface,
zoom = 0.30,
map_size = 360,
auto_map = true
}
return ic.minimap[player.index]
end
function Public.toggle_auto(player)
local ic = ICT.get()
local switch = player.gui.screen.minimap_toggle_frame['switch_auto_map']
if not switch or not switch.valid then
return
end
if switch.switch_state == 'left' then
ic.minimap[player.index].auto_map = true
elseif switch.switch_state == 'right' then
ic.minimap[player.index].auto_map = false
end
end
local function kill_minimap(player)
local element = player.gui.screen.minimap_toggle_frame
if not element or not element.valid then
return
end
if element.visible then
element.visible = false
end
end
local function kill_frame(player)
if player.gui.screen.minimap_toggle_frame then
local element = player.gui.screen.minimap_toggle_frame.minimap_frame
if not element or not element.valid then
return
end
element.destroy()
end
end
local function draw_minimap(player)
local ic = ICT.get()
local surface = game.surfaces[ic.allowed_surface]
if not surface or not surface.valid then
return
end
local cars = ic.cars
local entity = Functions.get_entity_from_player_surface(cars, player)
if not entity or not entity.valid then
kill_minimap(player)
kill_frame(player)
return
end
local position = entity.position
local player_data = get_player_data(player)
local frame = player.gui.screen.minimap_toggle_frame
if not frame then
frame =
player.gui.screen.add(
{type = 'frame', direction = 'vertical', name = 'minimap_toggle_frame', caption = 'Outside View'}
)
frame.location = {x = 10, y = 45}
end
frame.visible = true
local element = frame['minimap_frame']
if not element then
element =
player.gui.screen.minimap_toggle_frame.add(
{
type = 'camera',
name = 'minimap_frame',
position = position,
surface_index = surface.index,
zoom = player_data.zoom,
tooltip = 'LMB: Increase zoom level.\nRMB: Decrease zoom level.\nMMB: Toggle camera size.'
}
)
element.style.margin = 1
element.style.minimal_height = player_data.map_size
element.style.minimal_width = player_data.map_size
return
end
element.position = position
end
function Public.minimap(player, autoaction)
local player_data = get_player_data(player)
local frame = player.gui.screen['minimap_toggle_frame']
local ic = ICT.get()
if frame and frame.visible then
kill_minimap(player)
else
if Functions.get_player_surface(ic, player) then
if autoaction then
if player_data.auto_map then
draw_minimap(player)
end
else
draw_minimap(player)
end
end
end
end
function Public.update_minimap()
local ic = ICT.get()
for k, player in pairs(game.connected_players) do
if Functions.get_player_surface(ic, player) and player.gui.screen.minimap_toggle_frame then
kill_frame(player)
draw_minimap(player)
end
end
end
function Public.toggle_minimap(event)
local element = event.element
if not element then
return
end
if not element.valid then
return
end
if element.name ~= 'minimap_frame' then
return
end
local player = game.players[event.player_index]
local player_data = get_player_data(player)
if event.button == defines.mouse_button_type.right then
player_data.zoom = player_data.zoom - 0.07
if player_data.zoom < 0.07 then
player_data.zoom = 0.07
end
element.zoom = player_data.zoom
return
end
if event.button == defines.mouse_button_type.left then
player_data.zoom = player_data.zoom + 0.07
if player_data.zoom > 2 then
player_data.zoom = 2
end
element.zoom = player_data.zoom
return
end
if event.button == defines.mouse_button_type.middle then
player_data.map_size = player_data.map_size + 50
if player_data.map_size > 650 then
player_data.map_size = 250
end
element.style.minimal_height = player_data.map_size
element.style.minimal_width = player_data.map_size
element.style.maximal_height = player_data.map_size
element.style.maximal_width = player_data.map_size
return
end
end
function Public.changed_surface(event)
local player = game.players[event.player_index]
if not validate_player(player) then
return
end
local ic = ICT.get()
local surface = game.surfaces[ic.allowed_surface]
if not surface or not surface.valid then
return
end
local wd = player.gui.top['wave_defense']
local diff = player.gui.top['difficulty_gui']
if Functions.get_player_surface(ic, player) then
Public.toggle_button(player)
if wd and wd.visible then
wd.visible = false
end
if diff and diff.visible then
diff.visible = false
end
elseif player.surface.index == surface.index then
Gui.remove_toolbar(player)
Public.toggle_button(player)
kill_minimap(player)
if wd and not wd.visible then
wd.visible = true
end
if diff and not diff.visible then
diff.visible = true
end
end
end
return Public

View File

@ -1,4 +1,5 @@
local Global = require 'utils.global'
local Event = require 'utils.event'
local this = {}
Global.register(
@ -8,7 +9,11 @@ Global.register(
end
)
local Public = {}
local Public = {
events = {
on_player_kicked_from_surface = Event.generate_event_name('on_player_kicked_from_surface')
}
}
function Public.reset()
if this.surfaces then
@ -21,7 +26,7 @@ function Public.reset()
for k, _ in pairs(this) do
this[k] = nil
end
this.debug_mode = true
this.debug_mode = false
this.restore_on_theft = false
this.doors = {}
this.cars = {}
@ -30,13 +35,13 @@ function Public.reset()
this.trust_system = {}
this.players = {}
this.surfaces = {}
this.minimap = {}
this.infinity_scrap_enabled = true
this.entity_type = {
['car'] = true,
['tank'] = true,
['spidertron'] = true
}
this.car_areas = {
['car'] = {left_top = {x = -20, y = 0}, right_bottom = {x = 20, y = 20}},
['tank'] = {left_top = {x = -30, y = 0}, right_bottom = {x = 30, y = 40}},

View File

@ -891,6 +891,28 @@ local function gui_click(event)
return
end
if name == 'explosive_bullets' then
player.remove_item({name = item.value, count = item.price})
local message =
shopkeeper ..
player.name ..
' has bought the explosive bullet modifier for ' .. format_number(item.price, true) .. ' coins.'
Alert.alert_all_players(5, message)
Server.to_discord_bold(
table.concat {
player.name ..
' has bought the explosive bullet modifier for ' .. format_number(item.price) .. ' coins.'
}
)
this.explosive_bullets = true
redraw_market_items(data.item_frame, player, data.search_text)
redraw_coins_left(data.coins_left, player)
return
end
if name == 'flamethrower_turrets' then
player.remove_item({name = item.value, count = item.price})
if item.stack >= 1 then
@ -1727,6 +1749,7 @@ function Public.get_items()
local health_cost = 10000 * (1 + health_upgrades)
local aura_cost = 4000 * (1 + aura_upgrades)
local xp_point_boost_cost = 5000 * (1 + xp_points_upgrade)
local explosive_bullets_cost = 20000
local flamethrower_turrets_cost = 2500 * (1 + flame_turret)
local land_mine_cost = 2 * (1 + landmine)
local skill_reset_cost = 100000
@ -1784,6 +1807,29 @@ function Public.get_items()
upgrade = true,
static = true
}
if WPT.get('explosive_bullets') then
main_market_items['explosive_bullets'] = {
stack = 1,
value = 'coin',
price = explosive_bullets_cost,
tooltip = 'Sold out!',
sprite = 'achievement/steamrolled',
enabled = false,
upgrade = true,
static = true
}
else
main_market_items['explosive_bullets'] = {
stack = 1,
value = 'coin',
price = explosive_bullets_cost,
tooltip = 'Upgrades ordinary SMG ammo to explosive bullets.',
sprite = 'achievement/steamrolled',
enabled = true,
upgrade = true,
static = true
}
end
main_market_items['flamethrower_turrets'] = {
stack = 1,
value = 'coin',
@ -1976,13 +2022,13 @@ function Public.get_items()
enabled = false
}
local wave_number = WD.get_wave()
if wave_number == 200 then
if wave_number >= 200 then
main_market_items['vehicle-machine-gun'].enabled = true
main_market_items['vehicle-machine-gun'].tooltip = 'Car Machine Gun'
elseif wave_number == 400 then
elseif wave_number >= 400 then
main_market_items['tank-machine-gun'].enabled = true
main_market_items['tank-machine-gun'].tooltip = 'Tank Machine Gune'
elseif wave_number == 650 then
elseif wave_number >= 650 then
main_market_items['tank-cannon'].enabled = true
main_market_items['tank-cannon'].tooltip = 'Tank Cannon'
end

View File

@ -115,6 +115,8 @@ local collapse_kill = {
local disable_tech = function()
game.forces.player.technologies['landfill'].enabled = false
game.forces.player.technologies['spidertron'].enabled = false
game.forces.player.technologies['spidertron'].researched = false
game.forces.player.technologies['optics'].researched = true
game.forces.player.technologies['railway'].researched = true
game.forces.player.technologies['land-mine'].enabled = false
@ -158,7 +160,7 @@ local set_difficulty = function()
else
if player_count >= 8 and player_count <= 12 then
Collapse.set_speed(8)
elseif player_count >= 20 then
elseif player_count >= 20 and player_count <= 24 then
Collapse.set_speed(6)
elseif player_count >= 35 then
Collapse.set_speed(5)
@ -339,6 +341,7 @@ function Public.reset_map()
end
Difficulty.reset_difficulty_poll({difficulty_poll_closing_timeout = game.tick + 36000})
game.map_settings.path_finder.max_work_done_per_tick = 4000
Diff.gui_width = 20
Collapse.set_kill_entities(false)
@ -536,7 +539,7 @@ local remove_offline_players = function()
then
this.offline_players[i] = nil
else
if offline_players[i] and offline_players[i].tick < game.tick - 54000 then
if offline_players[i] and offline_players[i].tick < game.tick - 34000 then
local name = offline_players[i].name
player_inv[1] =
game.players[offline_players[i].index].get_inventory(defines.inventory.character_main)
@ -606,7 +609,7 @@ local remove_offline_players = function()
end
local on_research_finished = function(event)
disable_recipes()
disable_tech()
local research = event.research
local this = WPT.get()
@ -851,7 +854,6 @@ end
local on_tick = function()
local active_surface_index = WPT.get('active_surface_index')
local surface = game.surfaces[active_surface_index]
local wave_defense_table = WD.get_table()
local update_gui = Gui_mf.update_gui
local tick = game.tick
@ -870,9 +872,9 @@ local on_tick = function()
collapse_after_wave_100()
Entities.set_scores()
local collapse_pos = Collapse.get_position()
local position = surface.find_non_colliding_position('stone-furnace', collapse_pos, 128, 1)
local position = surface.find_non_colliding_position('rocket-silo', collapse_pos, 128, 1)
if position then
wave_defense_table.spawn_position = position
WD.set_spawn_position(position)
end
end
end
@ -936,6 +938,7 @@ local on_init = function()
Explosives.set_destructible_tile('deepwater', 1000)
Explosives.set_destructible_tile('water-shallow', 1000)
Explosives.set_destructible_tile('water-mud', 1000)
Explosives.set_destructible_tile('lab-dark-2', 1000)
Explosives.set_whitelist_entity('straight-rail')
Explosives.set_whitelist_entity('curved-rail')
Explosives.set_whitelist_entity('character')

View File

@ -98,6 +98,7 @@ function Public.reset_table()
randomized = false
}
this.collapse_grace = true
this.explosive_bullets = false
this.locomotive_biter = nil
this.disconnect_wagon = false
this.spidertron_unlocked_at_wave = 11

View File

@ -948,7 +948,7 @@ local function on_player_used_capsule(event)
return
end
if mana <= object.mana_cost then
if mana < object.mana_cost then
return p('You don´t have enough mana to cast this spell.', Color.fail)
end

View File

@ -75,7 +75,7 @@ end
local function remove_trees(entity)
local surface = entity.surface
local radius = 5
local radius = 10
local pos = entity.position
local area = {{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}}
local trees = surface.find_entities_filtered {area = area, type = 'tree'}
@ -90,7 +90,7 @@ end
local function remove_rocks(entity)
local surface = entity.surface
local radius = 5
local radius = 10
local pos = entity.position
local area = {{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}}
local rocks = surface.find_entities_filtered {area = area, type = 'simple-entity'}
@ -102,7 +102,7 @@ local function remove_rocks(entity)
end
end
end
--[[
local function create_tiles(entity)
local collapse
local check_collapse_position = WD.get('check_collapse_position')
@ -145,8 +145,7 @@ local function create_tiles(entity)
end
end
end
end
end ]]
local function is_unit_valid(biter)
local this = WD.get()
if not biter.entity then
@ -356,10 +355,10 @@ local function spawn_biter(surface, is_boss_biter)
local biter = surface.create_entity({name = name, position = position, force = 'enemy'})
biter.ai_settings.allow_destroy_when_commands_fail = true
biter.ai_settings.allow_try_return_to_spawner = false
biter.ai_settings.do_separation = true
if this.remove_entities then
remove_trees(biter)
remove_rocks(biter)
create_tiles(biter)
end
if is_boss_biter then
BiterHealthBooster.add_boss_unit(biter, global.biter_health_boost * 5, 0.35)
@ -590,7 +589,7 @@ local function get_commmands(group)
return commands
end
local function command_unit_group(group, wd)
local function command_unit_group(group)
local this = WD.get()
if not this.unit_group_last_command[group.group_number] then
this.unit_group_last_command[group.group_number] = game.tick - (this.unit_group_command_delay + 1)

View File

@ -96,6 +96,15 @@ function Public.alert_boss_wave(value)
return this.alert_boss_wave
end
function Public.set_spawn_position(value)
if type(value) == 'table' then
this.spawn_position = value
else
error('Value must be of type table.')
end
return this.spawn_position
end
function Public.remove_entities(value)
if value then
this.remove_entities = value