1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-10-30 23:47:41 +02:00

Mtn v3 - fix bugs

Fixes final battle where biters would not spawn at all
Misc changes and tweaks.
This commit is contained in:
Gerkiz
2024-06-10 16:14:37 +02:00
parent ddd0157392
commit c128c0b457
22 changed files with 1550 additions and 1404 deletions

View File

@@ -74,6 +74,8 @@ local function on_entity_died(event)
return
end
local cause = event.cause
local coin_count = get_coin_count(entity)
@@ -122,27 +124,33 @@ local function on_entity_died(event)
end
if forest_zone then
if random(1, 12) == 1 then
player.insert({name = 'coin', count = coin_count})
player.insert({ name = 'coin', count = coin_count })
if p then
StatData.get_data(p.index):increase('coins', coin_count)
end
end
else
player.insert({name = 'coin', count = coin_count})
player.insert({ name = 'coin', count = coin_count })
if p then
StatData.get_data(p.index):increase('coins', coin_count)
end
end
end
end
if entities_that_earn_coins[cause.name] then
event.entity.surface.spill_item_stack(cause.position, {name = 'coin', count = coin_count}, true)
reward_has_been_given = true
if not Public.get('final_battle') then
if entities_that_earn_coins[cause.name] then
event.entity.surface.spill_item_stack(cause.position, { name = 'coin', count = coin_count }, true)
reward_has_been_given = true
end
end
end
if Public.get('final_battle') then
return
end
if reward_has_been_given == false then
event.entity.surface.spill_item_stack(event.entity.position, {name = 'coin', count = coin_count}, true)
event.entity.surface.spill_item_stack(event.entity.position, { name = 'coin', count = coin_count }, true)
end
end

View File

@@ -8,7 +8,7 @@ local this = {}
Global.register(
this,
function(t)
function (t)
this = t
end
)
@@ -51,7 +51,7 @@ local function create_particles(data)
frame_speed = 0.1,
vertical_speed = 0.1,
height = 0.1,
movement = {m2 - (random(0, m) * 0.01), m2 - (random(0, m) * 0.01)}
movement = { m2 - (random(0, m) * 0.01), m2 - (random(0, m) * 0.01) }
}
)
end
@@ -97,7 +97,7 @@ local function spawn_biters(data)
local unit_settings = WD.get('unit_settings')
local unit = surface.create_entity({name = unit_to_create, position = position})
local unit = surface.create_entity({ name = unit_to_create, position = position, force = data.force or 'enemy' })
max_biters.amount = max_biters.amount + 1
if random(1, 30) == 1 then
@@ -134,7 +134,7 @@ local function spawn_worms(data)
WD.wave_defense_set_worm_raffle(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20)
local unit = surface.create_entity({name = unit_to_create, position = position})
local unit = surface.create_entity({ name = unit_to_create, position = position })
max_biters.amount = max_biters.amount + 1
local worm_unit_settings = WD.get('worm_unit_settings')
@@ -151,7 +151,7 @@ local function spawn_worms(data)
end
end
function Public.buried_biter(surface, position, count)
function Public.buried_biter(surface, position, count, force)
if not (surface and surface.valid) then
return
end
@@ -176,21 +176,21 @@ function Public.buried_biter(surface, position, count)
this[game.tick + t][#this[game.tick + t] + 1] = {
callback = 'create_particles',
data = {surface = surface, position = {x = position.x, y = position.y}, amount = math.ceil(t * 0.05)}
data = { surface = surface, position = { x = position.x, y = position.y }, amount = math.ceil(t * 0.05) }
}
if t == 60 then
if count == 1 then
this[game.tick + t][#this[game.tick + t] + 1] = {
callback = 'spawn_biters',
data = {surface = surface, position = {x = position.x, y = position.y}, count = count or 1}
data = { surface = surface, position = { x = position.x, y = position.y }, count = count or 1, force = force or 'enemy' }
}
else
local tick = 2
for _ = 1, count do
this[game.tick + t][#this[game.tick + t] + 1 + tick] = {
callback = 'spawn_biters',
data = {surface = surface, position = {x = position.x, y = position.y}, count = count or 1}
data = { surface = surface, position = { x = position.x, y = position.y }, count = count or 1, force = force or 'enemy' }
}
tick = tick + 2
end
@@ -220,13 +220,13 @@ function Public.buried_worm(surface, position)
this[game.tick + t][#this[game.tick + t] + 1] = {
callback = 'create_particles',
data = {surface = surface, position = {x = position.x, y = position.y}, amount = math.ceil(t * 0.05)}
data = { surface = surface, position = { x = position.x, y = position.y }, amount = math.ceil(t * 0.05) }
}
if t == 60 then
this[game.tick + t][#this[game.tick + t] + 1] = {
callback = 'spawn_worms',
data = {surface = surface, position = {x = position.x, y = position.y}}
data = { surface = surface, position = { x = position.x, y = position.y } }
}
end
end

View File

@@ -1,5 +1,5 @@
local Public = require 'maps.mountain_fortress_v3.table'
local Task = require 'utils.task'
local Task = require 'utils.task_token'
local Server = require 'utils.server'
local Collapse = require 'modules.collapse'
local WD = require 'modules.wave_defense.table'
@@ -8,6 +8,14 @@ local Commands = require 'utils.commands'
local mapkeeper = '[color=blue]Mapkeeper:[/color]'
local scenario_name = Public.scenario_name
local gather_time_token =
Task.register(
function ()
local stateful = Public.get_stateful()
stateful.collection.gather_time_timer = 0
end
)
Commands.new('scenario', 'Usable only for admins - controls the scenario!')
:require_admin()
:require_validation()
@@ -101,7 +109,9 @@ Commands.new('mtn_complete_quests', 'Usable only for admins - sets the queue spe
:callback(
function (player)
Discord.send_notification_raw(scenario_name, player.name .. ' completed all the quest via command.')
Public.stateful.set_stateful('objectives_completed_count', 6)
local stateful = Public.get_stateful()
stateful.objectives_completed_count = 6
Task.set_timeout_in_ticks(50, gather_time_token, {})
game.print(mapkeeper .. player.name .. ', has forced completed all quests!', { r = 0.98, g = 0.66, b = 0.22 })
player.print('Quests completed.')
end
@@ -165,20 +175,6 @@ Commands.new('mtn_toggle_orbital_strikes',
end
)
Commands.new('mtn_toggle_end_game', 'Usable only for admins - initiates the final battle!')
:require_admin()
:require_validation()
:callback(
function (player)
Discord.send_notification_raw(scenario_name, player.name .. ' toggled the end game.')
Public.stateful.set_stateful('final_battle', true)
Public.set('final_battle', true)
game.print(mapkeeper .. ' ' .. player.name .. ', has triggered the final battle sequence!',
{ r = 0.98, g = 0.66, b = 0.22 })
end
)
Commands.new('mtn_get_queue_speed', 'Usable only for admins - gets the queue speed of this map!')
:require_admin()
:require_validation()

View File

@@ -398,7 +398,7 @@ local function do_clear_rocks_slowly()
return
end
for _ = 1, 30 do
for _ = 1, 300 do
local entity = table.remove(rocks_to_remove, #rocks_to_remove)
if entity and entity.valid then
@@ -407,6 +407,26 @@ local function do_clear_rocks_slowly()
end
end
local function do_replace_tiles_slowly()
local active_surface_index = Public.get('active_surface_index')
local surface = game.get_surface(active_surface_index)
if not (surface and surface.valid) then
return
end
local tiles_to_replace = Public.get('tiles_to_replace')
if not tiles_to_replace or not next(tiles_to_replace) then
return
end
for _ = 1, 300 do
local tile = table.remove(tiles_to_replace, #tiles_to_replace)
if tile and tile.valid then
surface.set_tiles({ { name = 'water-shallow', position = tile.position } }, true)
end
end
end
local function do_season_fix()
local active_surface_index = Public.get('active_surface_index')
local surface = game.surfaces[active_surface_index]
@@ -423,7 +443,7 @@ local function do_season_fix()
Public.set(
'current_season',
rendering.draw_text {
text = 'Season: ' .. Public.stateful.get_stateful('season'),
text = 'Season: ' .. Public.get_stateful('season'),
surface = surface,
target = { -0, 12 },
color = { r = 0.98, g = 0.77, b = 0.22 },
@@ -522,6 +542,7 @@ local function tick()
do_beams_away()
do_clear_enemy_spawners()
do_clear_rocks_slowly()
do_replace_tiles_slowly()
end
Public.deactivate_callback =
@@ -950,6 +971,27 @@ function Public.find_rocks_and_slowly_remove()
end
end
function Public.find_void_tiles_and_replace()
local active_surface_index = Public.get('active_surface_index')
local surface = game.get_surface(active_surface_index)
if not (surface and surface.valid) then
return
end
local cp = Collapse.get_position()
local rp = Collapse.get_reverse_position()
local area = {
left_top = { x = (-zone_settings.zone_width / 2) + 10, y = cp.y },
right_bottom = { x = (zone_settings.zone_width / 2) - 10, y = rp.y }
}
local tiles = surface.find_tiles_filtered({ area = area, name = { 'out-of-map', 'water', 'deepwater', 'water-green', 'deepwater-green' } })
if tiles and #tiles > 0 then
Public.set('tiles_to_replace', tiles)
end
end
function Public.set_difficulty()
local final_battle = Public.get('final_battle')
if final_battle then
@@ -1106,7 +1148,7 @@ function Public.render_direction(surface, reversed)
Public.set(
'current_season',
rendering.draw_text {
text = 'Season: ' .. Public.stateful.get_stateful('season'),
text = 'Season: ' .. Public.get_stateful('season'),
surface = surface,
target = { -0, 12 },
color = { r = 0.98, g = 0.77, b = 0.22 },

View File

@@ -8,6 +8,7 @@ local WPT = require 'maps.mountain_fortress_v3.table'
local RPG = require 'modules.rpg.main'
local OfflinePlayers = require 'modules.clear_vacant_players'
local Event = require 'utils.event'
local Server = require 'utils.server'
local Public = {}
local main_tile_name = 'black-refined-concrete'
@@ -40,19 +41,19 @@ end
local enable_car_to_be_mined =
Task.register(
function(event)
local entity = event.entity
local owner_name = event.owner_name
if entity and entity.valid then
entity.minable = true
local msg = owner_name .. "'s vehicle is now minable!"
local p = {
position = entity.position
}
Alert.alert_all_players_location(p, msg, nil, 30)
function (event)
local entity = event.entity
local owner_name = event.owner_name
if entity and entity.valid then
entity.minable = true
local msg = owner_name .. "'s vehicle is now minable!"
local p = {
position = entity.position
}
Alert.alert_all_players_location(p, msg, nil, 30)
end
end
end
)
)
local function log_err(err)
local debug_mode = IC.get('debug_mode')
@@ -68,7 +69,7 @@ local function get_trusted_system(player)
if not trust_system[player.index] then
trust_system[player.index] = {
players = {
[player.name] = {trusted = true, drive = true}
[player.name] = { trusted = true, drive = true }
},
allow_anyone = 'left',
auto_upgrade = 'left',
@@ -112,29 +113,29 @@ local function render_owner_text(renders, player, entity, new_owner)
if new_owner then
renders[new_owner.index] =
rendering.draw_text {
text = '## - ' .. new_owner.name .. "'s " .. ce_name .. ' - ##',
surface = entity.surface,
target = entity,
target_offset = {0, -2.6},
color = color,
scale = 1.05,
font = 'default-large-semibold',
alignment = 'center',
scale_with_zoom = false
}
text = '## - ' .. new_owner.name .. "'s " .. ce_name .. ' - ##',
surface = entity.surface,
target = entity,
target_offset = { 0, -2.6 },
color = color,
scale = 1.05,
font = 'default-large-semibold',
alignment = 'center',
scale_with_zoom = false
}
else
renders[player.index] =
rendering.draw_text {
text = '## - ' .. player.name .. "'s " .. ce_name .. ' - ##',
surface = entity.surface,
target = entity,
target_offset = {0, -2.6},
color = color,
scale = 1.05,
font = 'default-large-semibold',
alignment = 'center',
scale_with_zoom = false
}
text = '## - ' .. player.name .. "'s " .. ce_name .. ' - ##',
surface = entity.surface,
target = entity,
target_offset = { 0, -2.6 },
color = color,
scale = 1.05,
font = 'default-large-semibold',
alignment = 'center',
scale_with_zoom = false
}
end
entity.color = color
end
@@ -244,11 +245,11 @@ local function get_saved_entity(entity, index)
if index and index.name ~= entity.name then
local msg =
table.concat(
{
'The built entity is not the same as the saved one. ',
'Saved entity is: ' .. upperCase(index.name) .. ' - Built entity is: ' .. upperCase(entity.name) .. '. '
}
)
{
'The built entity is not the same as the saved one. ',
'Saved entity is: ' .. upperCase(index.name) .. ' - Built entity is: ' .. upperCase(entity.name) .. '. '
}
)
return false, msg
end
return true
@@ -376,7 +377,7 @@ local function save_surface(entity, player)
car.entity = false
car.saved_entity = entity.unit_number
saved_surfaces[player.index] = {saved_entity = entity.unit_number, name = entity.name}
saved_surfaces[player.index] = { saved_entity = entity.unit_number, name = entity.name }
end
local function kick_players_out_of_vehicles(car)
@@ -421,7 +422,7 @@ local function kick_players_from_surface(car, owner_id)
if not car.entity or not car.entity.valid then
local main_surface = game.surfaces[allowed_surface]
if validate_entity(main_surface) then
for _, e in pairs(surface.find_entities_filtered({area = car.area})) do
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.index then
goto continue
@@ -438,7 +439,7 @@ local function kick_players_from_surface(car, owner_id)
end
end
for _, e in pairs(surface.find_entities_filtered({area = car.area})) do
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.index then
goto continue
@@ -467,7 +468,7 @@ local function kick_non_trusted_players_from_surface(car)
local position = car.entity and car.entity.valid and car.entity.position or game.forces.player.get_spawn_position(main_surface)
local owner = game.get_player(car.owner) and game.get_player(car.owner).name or false
Core.iter_connected_players(
function(player)
function (player)
local is_trusted = trust_system and trust_system.players and trust_system.players[player.name] and trust_system.players[player.name].trusted
if player.surface.index == surface_index and player.index ~= car.owner and not is_trusted then
if position then
@@ -654,26 +655,26 @@ local function construct_doors(car)
local doors = IC.get('doors')
for _, x in pairs({area.left_top.x - 1.5, area.right_bottom.x + 1.5}) do
local p = {x = x, y = area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)}
for _, x in pairs({ area.left_top.x - 1.5, area.right_bottom.x + 1.5 }) do
local p = { x = x, y = area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5) }
if p.x < 0 then
surface.set_tiles({{name = main_tile_name, position = {x = p.x + 0.5, y = p.y}}}, true)
surface.set_tiles({ { name = main_tile_name, position = { x = p.x + 0.5, y = p.y } } }, true)
else
surface.set_tiles({{name = main_tile_name, position = {x = p.x - 1, y = p.y}}}, true)
surface.set_tiles({ { name = main_tile_name, position = { x = p.x - 1, y = p.y } } }, true)
end
local e =
surface.create_entity(
{
name = 'car',
position = {x, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)},
force = 'neutral',
create_build_effect_smoke = false
}
)
{
name = 'car',
position = { x, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5) },
force = 'neutral',
create_build_effect_smoke = false
}
)
e.destructible = false
e.minable = false
e.operable = false
e.get_inventory(defines.inventory.fuel).insert({name = 'coal', count = 1})
e.get_inventory(defines.inventory.fuel).insert({ name = 'coal', count = 1 })
if type(car.entity) == 'boolean' then
return
end
@@ -714,34 +715,34 @@ end
local remove_car =
Task.register(
function(data)
local player = data.player
local car = data.car
player.remove_item({name = car.name, count = 1})
end
)
function (data)
local player = data.player
local car = data.car
player.remove_item({ name = car.name, count = 1 })
end
)
local find_remove_car =
Task.register(
function(data)
local index = data.index
local types = data.types
local position = data.position
function (data)
local index = data.index
local types = data.types
local position = data.position
local surface = game.get_surface(index)
if not surface or not surface.valid then
return
end
local surface = game.get_surface(index)
if not surface or not surface.valid then
return
end
for _, dropped_ent in pairs(surface.find_entities_filtered {type = 'item-entity', area = {{position.x - 10, position.y - 10}, {position.x + 10, position.y + 10}}}) do
if dropped_ent and dropped_ent.valid and dropped_ent.stack then
if types[dropped_ent.stack.name] then
dropped_ent.destroy()
for _, dropped_ent in pairs(surface.find_entities_filtered { type = 'item-entity', area = { { position.x - 10, position.y - 10 }, { position.x + 10, position.y + 10 } } }) do
if dropped_ent and dropped_ent.valid and dropped_ent.stack then
if types[dropped_ent.stack.name] then
dropped_ent.destroy()
end
end
end
end
end
)
)
function Public.save_car(event)
local entity = event.entity
@@ -798,11 +799,11 @@ function Public.save_car(event)
}
Task.set_timeout_in_ticks(10, remove_car, params)
if restore_on_theft then
local e = player.surface.create_entity({name = car.name, position = position, force = player.force, create_build_effect_smoke = false})
local e = player.surface.create_entity({ name = car.name, position = position, force = player.force, create_build_effect_smoke = false })
e.health = health
restore_surface(p, e)
elseif p.can_insert({name = car.name, count = 1}) then
p.insert({name = car.name, count = 1, health = health})
elseif p.can_insert({ name = car.name, count = 1 }) then
p.insert({ name = car.name, count = 1, health = health })
p.print(module_tag .. 'Your car was stolen from you - the gods foresaw this and granted you a new one.', Color.info)
end
end
@@ -861,13 +862,13 @@ function Public.remove_surface(player)
return
end
for _, tile in pairs(surface.find_tiles_filtered({area = car.area})) do
surface.set_tiles({{name = 'out-of-map', position = tile.position}}, true)
for _, tile in pairs(surface.find_tiles_filtered({ area = car.area })) do
surface.set_tiles({ { name = 'out-of-map', position = tile.position } }, true)
end
for _, x in pairs({car.area.left_top.x - 1.5, car.area.right_bottom.x + 1.5}) do
local p = {x = x, y = car.area.left_top.y + ((car.area.right_bottom.y - car.area.left_top.y) * 0.5)}
surface.set_tiles({{name = 'out-of-map', position = {x = p.x + 0.5, y = p.y}}}, true)
surface.set_tiles({{name = 'out-of-map', position = {x = p.x - 1, y = p.y}}}, true)
for _, x in pairs({ car.area.left_top.x - 1.5, car.area.right_bottom.x + 1.5 }) do
local p = { x = x, y = car.area.left_top.y + ((car.area.right_bottom.y - car.area.left_top.y) * 0.5) }
surface.set_tiles({ { name = 'out-of-map', position = { x = p.x + 0.5, y = p.y } } }, true)
surface.set_tiles({ { name = 'out-of-map', position = { x = p.x - 1, y = p.y } } }, true)
end
game.delete_surface(surface)
end
@@ -923,6 +924,8 @@ function Public.kill_car(entity)
game.print(module_tag .. owner.name .. messages[math.random(1, #messages)] .. ' ' .. gps_tag)
Server.to_discord_bold(table.concat { '*** ', '[Personal Vehicle] ***', owner.name .. messages[math.random(1, #messages)] .. ' ', gps_tag })
local player_gui_data = IC.get('player_gui_data')
if player_gui_data[owner.name] then
player_gui_data[owner.name] = nil
@@ -941,13 +944,13 @@ function Public.kill_car(entity)
local surface_index = car.surface
local surface = game.surfaces[surface_index]
kill_doors(car)
for _, tile in pairs(surface.find_tiles_filtered({area = car.area})) do
surface.set_tiles({{name = 'out-of-map', position = tile.position}}, true)
for _, tile in pairs(surface.find_tiles_filtered({ area = car.area })) do
surface.set_tiles({ { name = 'out-of-map', position = tile.position } }, true)
end
for _, x in pairs({car.area.left_top.x - 1.5, car.area.right_bottom.x + 1.5}) do
local p = {x = x, y = car.area.left_top.y + ((car.area.right_bottom.y - car.area.left_top.y) * 0.5)}
surface.set_tiles({{name = 'out-of-map', position = {x = p.x + 0.5, y = p.y}}}, true)
surface.set_tiles({{name = 'out-of-map', position = {x = p.x - 1, y = p.y}}}, true)
for _, x in pairs({ car.area.left_top.x - 1.5, car.area.right_bottom.x + 1.5 }) do
local p = { x = x, y = car.area.left_top.y + ((car.area.right_bottom.y - car.area.left_top.y) * 0.5) }
surface.set_tiles({ { name = 'out-of-map', position = { x = p.x + 0.5, y = p.y } } }, true)
surface.set_tiles({ { name = 'out-of-map', position = { x = p.x - 1, y = p.y } } }, true)
end
car.entity.force.chart(surface, car.area)
game.delete_surface(surface)
@@ -979,7 +982,7 @@ function Public.kill_car_but_save_surface(entity)
end
local c = 0
local entities = surface.find_entities_filtered({area = car.area, force = 'player'})
local entities = surface.find_entities_filtered({ area = car.area, force = 'player' })
if entities and #entities > 0 then
for _, e in pairs(entities) do
if e and e.valid and e.name ~= 'character' then
@@ -1093,21 +1096,21 @@ function Public.create_room_surface(unit_number)
['height'] = 2,
['water'] = 0,
['starting_area'] = 1,
['cliff_settings'] = {cliff_elevation_interval = 0, cliff_elevation_0 = 0},
['cliff_settings'] = { cliff_elevation_interval = 0, cliff_elevation_0 = 0 },
['default_enable_all_autoplace_controls'] = true,
['autoplace_settings'] = {
['entity'] = {treat_missing_as_default = false},
['tile'] = {treat_missing_as_default = true},
['decorative'] = {treat_missing_as_default = false}
['entity'] = { treat_missing_as_default = false },
['tile'] = { treat_missing_as_default = true },
['decorative'] = { treat_missing_as_default = false }
}
}
local surface = game.create_surface(tostring(unit_number), map_gen_settings)
surface.freeze_daytime = true
surface.daytime = 0.1
surface.request_to_generate_chunks({16, 16}, 1)
surface.request_to_generate_chunks({ 16, 16 }, 1)
surface.force_generate_chunk_requests()
for _, tile in pairs(surface.find_tiles_filtered({area = {{-2, -2}, {2, 2}}})) do
surface.set_tiles({{name = 'out-of-map', position = tile.position}}, true)
for _, tile in pairs(surface.find_tiles_filtered({ area = { { -2, -2 }, { 2, 2 } } })) do
surface.set_tiles({ { name = 'out-of-map', position = tile.position } }, true)
end
local surfaces = IC.get('surfaces')
surfaces[unit_number] = surface.index
@@ -1129,18 +1132,18 @@ function Public.create_car_room(car)
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}}
tiles[#tiles + 1] = { name = main_tile_name, position = { x, y } }
end
end
for x = -3, 2, 1 do
for y = area.right_bottom.y - 4, area.right_bottom.y - 2, 1 do
tiles[#tiles + 1] = {name = main_tile_name, position = {x, y}}
tiles[#tiles + 1] = { name = main_tile_name, position = { x, y } }
end
end
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}}
tiles[#tiles + 1] = { name = 'water', position = { x, y } }
end
end
@@ -1153,7 +1156,7 @@ function Public.create_car_room(car)
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}}
fishes[#fishes + 1] = { name = 'fish', position = { x, y } }
end
end
@@ -1172,33 +1175,33 @@ function Public.create_car_room(car)
local lx, ly, rx, ry = 4, 1, 5, 1
local position1 = {area.left_top.x + lx, area.left_top.y + ly}
local position2 = {area.right_bottom.x - rx, area.left_top.y + ry}
local position1 = { area.left_top.x + lx, area.left_top.y + ly }
local position2 = { area.right_bottom.x - rx, area.left_top.y + ry }
local e1 =
surface.create_entity(
{
name = 'logistic-chest-requester',
position = position1,
force = 'neutral',
create_build_effect_smoke = false
}
)
{
name = 'logistic-chest-requester',
position = position1,
force = 'neutral',
create_build_effect_smoke = false
}
)
e1.destructible = false
e1.minable = false
local e2 =
surface.create_entity(
{
name = 'logistic-chest-passive-provider',
position = position2,
force = 'neutral',
create_build_effect_smoke = false
}
)
{
name = 'logistic-chest-passive-provider',
position = position2,
force = 'neutral',
create_build_effect_smoke = false
}
)
e2.destructible = false
e2.minable = false
car.transfer_entities = {e1, e2}
car.transfer_entities = { e1, e2 }
return
end
@@ -1269,8 +1272,8 @@ function Public.create_car(event)
cars[un] = {
entity = ce,
area = {
left_top = {x = car_area.left_top.x, y = car_area.left_top.y},
right_bottom = {x = car_area.right_bottom.x, y = car_area.right_bottom.y}
left_top = { x = car_area.left_top.x, y = car_area.left_top.y },
right_bottom = { x = car_area.right_bottom.x, y = car_area.right_bottom.y }
},
doors = {},
health_pool = {
@@ -1310,7 +1313,7 @@ function Public.remove_invalid_cars()
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})
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
@@ -1387,7 +1390,7 @@ function Public.use_door_with_entity(player, door)
if validate_entity(car.entity) then
player_data.fallback_surface = car.entity.surface
player_data.fallback_position = {car.entity.position.x, car.entity.position.y}
player_data.fallback_position = { car.entity.position.x, car.entity.position.y }
end
if validate_entity(car.entity) and car.entity.surface.name == player.surface.name then
@@ -1412,9 +1415,9 @@ function Public.use_door_with_entity(player, door)
local x_vector = door.position.x - player.position.x
local position
if x_vector > 0 then
position = {area.left_top.x + 0.5, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)}
position = { area.left_top.x + 0.5, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5) }
else
position = {area.right_bottom.x - 0.5, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)}
position = { area.right_bottom.x - 0.5, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5) }
end
local p = surface.find_non_colliding_position('character', position, 128, 0.5)
if p then
@@ -1436,7 +1439,7 @@ function Public.use_door_with_entity(player, door)
end
local surface = car.entity.surface
local x_vector = (door.position.x / math.abs(door.position.x)) * 2
local position = {car.entity.position.x + x_vector, car.entity.position.y}
local position = { car.entity.position.x + x_vector, car.entity.position.y }
local surface_position = surface.find_non_colliding_position('character', position, 128, 0.5)
if car.entity.type == 'car' or car.entity.name == 'spidertron' then
player.teleport(surface_position, surface)
@@ -1589,7 +1592,7 @@ Public.kick_non_trusted_players_from_surface = kick_non_trusted_players_from_sur
Event.add(
OfflinePlayers.events.remove_surface,
function(event)
function (event)
local target = event.target
if not target then
return

View File

@@ -10,6 +10,7 @@ local Alert = require 'utils.alert'
local Color = require 'utils.color_presets'
local Modifiers = require 'utils.player_modifiers'
local Core = require 'utils.core'
local Task = require 'utils.task_token'
local zone_settings = Public.zone_settings
@@ -45,6 +46,20 @@ local denied_train_types = {
['artillery-wagon'] = true
}
Public.check_if_spawning_near_train_custom_callback =
Task.register(
function (event)
local entity = event.entity
local disable_spawn_near_target = event.disable_spawn_near_target
if Public.is_around_train(entity) and disable_spawn_near_target then
return true
end
return false
end
)
local function add_random_loot_to_main_market(rarity)
local main_market_items = Public.get('main_market_items')
local items = Public.get_random_item(rarity, true, false)
@@ -85,16 +100,16 @@ local function add_random_loot_to_main_market(rarity)
end
local function death_effects(player)
local position = {x = player.position.x - 0.75, y = player.position.y - 1}
local position = { x = player.position.x - 0.75, y = player.position.y - 1 }
local b = 0.75
for _ = 1, 5, 1 do
local p = {
(position.x + 0.4) + (b * -1 + math.random(0, b * 20) * 0.1),
position.y + (b * -1 + math.random(0, b * 20) * 0.1)
}
player.surface.create_entity({name = 'flying-text', position = p, text = '☠️', color = {255, math.random(0, 100), 0}})
player.surface.create_entity({ name = 'flying-text', position = p, text = '☠️', color = { 255, math.random(0, 100), 0 } })
end
player.play_sound {path = 'utility/axe_fighting', volume_modifier = 0.9}
player.play_sound { path = 'utility/axe_fighting', volume_modifier = 0.9 }
end
local messages = {
@@ -162,7 +177,7 @@ local function hurt_players_outside_of_aura()
local map_name = 'mtn_v3'
Core.iter_connected_players(
function(player)
function (player)
if sub(player.surface.name, 0, #map_name) == map_name then
local position = player.position
local inside = ((position.x - loco.x) ^ 2 + (position.y - loco.y) ^ 2) < upgrades.locomotive_aura_radius ^ 2
@@ -170,9 +185,9 @@ local function hurt_players_outside_of_aura()
local entity = player.character
if entity and entity.valid then
death_effects(player)
player.surface.create_entity({name = 'fire-flame', position = position})
player.surface.create_entity({ name = 'fire-flame', position = position })
if random(1, 3) == 1 then
player.surface.create_entity({name = 'medium-scorchmark', position = position, force = 'neutral'})
player.surface.create_entity({ name = 'medium-scorchmark', position = position, force = 'neutral' })
end
local max_health = floor(player.character.prototype.max_health + player.character_health_bonus + player.force.character_health_bonus)
local vehicle = player.vehicle
@@ -181,7 +196,7 @@ local function hurt_players_outside_of_aura()
end
if death_mode then
if entity.name == 'character' then
game.print(player.name .. messages[random(1, #messages)], {r = 200, g = 0, b = 0})
game.print(player.name .. messages[random(1, #messages)], { r = 200, g = 0, b = 0 })
end
if entity.valid then
entity.die()
@@ -209,7 +224,7 @@ local function hurt_players_outside_of_aura()
if entity.valid then
if entity.health - damage <= 0 then
if entity.name == 'character' then
game.print(player.name .. messages[random(1, #messages)], {r = 200, g = 0, b = 0})
game.print(player.name .. messages[random(1, #messages)], { r = 200, g = 0, b = 0 })
end
end
end
@@ -223,7 +238,7 @@ local function hurt_players_outside_of_aura()
)
end
local function give_passive_xp(data)
local xp_floating_text_color = {r = 188, g = 201, b = 63}
local xp_floating_text_color = { r = 188, g = 201, b = 63 }
local visuals_delay = 1800
local loco_surface = Public.get('loco_surface')
if not (loco_surface and loco_surface.valid) then
@@ -238,7 +253,7 @@ local function give_passive_xp(data)
local loco = locomotive.position
Core.iter_connected_players(
function(player)
function (player)
local position = player.position
local inside = ((position.x - loco.x) ^ 2 + (position.y - loco.y) ^ 2) < upgrades.locomotive_aura_radius ^ 2
if player.afk_time < 200 and not RPG.get_last_spell_cast(player) then
@@ -261,7 +276,7 @@ local function give_passive_xp(data)
player.create_local_flying_text {
text = '+' .. '',
position = {x = pos.x, y = pos.y - 2},
position = { x = pos.x, y = pos.y - 2 },
color = xp_floating_text_color,
time_to_live = 60,
speed = 3
@@ -320,7 +335,7 @@ local function fish_tag()
locomotive_cargo.force.add_chart_tag(
locomotive_cargo.surface,
{
icon = {type = 'item', name = 'raw-fish'},
icon = { type = 'item', name = 'raw-fish' },
position = locomotive_cargo.position,
text = ' '
}
@@ -341,7 +356,7 @@ local function set_player_spawn()
if not position then
return
end
game.forces.player.set_spawn_position({x = position.x, y = position.y}, locomotive.surface)
game.forces.player.set_spawn_position({ x = position.x, y = position.y }, locomotive.surface)
end
local function refill_fish()
@@ -352,7 +367,7 @@ local function refill_fish()
if not locomotive_cargo.valid then
return
end
locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = 'raw-fish', count = random(2, 5)})
locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({ name = 'raw-fish', count = random(2, 5) })
end
local function set_carriages()
@@ -485,12 +500,12 @@ local function on_research_finished(event)
local name = research.name
if name == 'discharge-defense-equipment' then
local message = ({'locomotive.discharge_unlocked'})
local message = ({ 'locomotive.discharge_unlocked' })
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac', 0.1)
end
if name == 'artillery' then
local message = ({'locomotive.artillery_unlocked'})
local message = ({ 'locomotive.artillery_unlocked' })
Alert.alert_all_players(15, message, nil, 'achievement/tech-maniac', 0.1)
end
@@ -506,7 +521,7 @@ local function on_research_finished(event)
local breached_wall = Public.get('breached_wall')
add_random_loot_to_main_market(breached_wall)
local message = ({'locomotive.new_items_at_market'})
local message = ({ 'locomotive.new_items_at_market' })
Alert.alert_all_players(5, message, nil, 'achievement/tech-maniac', 0.1)
Public.refresh_gui()
end
@@ -569,7 +584,7 @@ local function check_on_player_changed_surface()
end
Core.iter_players(
function(player)
function (player)
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
@@ -756,7 +771,7 @@ function Public.render_train_hp()
text = 'HP: ' .. locomotive_health .. ' / ' .. locomotive_max_health,
surface = surface,
target = locomotive,
target_offset = {0, -4.5},
target_offset = { 0, -4.5 },
color = locomotive.color,
scale = 1.40,
font = 'default-game',
@@ -771,7 +786,7 @@ function Public.render_train_hp()
text = 'Comfy Choo Choo',
surface = surface,
target = locomotive,
target_offset = {0, -6.25},
target_offset = { 0, -6.25 },
color = locomotive.color,
scale = 1.80,
font = 'default-game',

View File

@@ -8,130 +8,130 @@ local floor = math.floor
local function initial_cargo_boxes()
return {
{name = 'loader', count = 1},
{name = 'stone-furnace', count = 2},
{name = 'coal', count = random(32, 64)},
{name = 'coal', count = random(32, 64)},
{name = 'loader', count = 1},
{name = 'iron-ore', count = random(32, 128)},
{name = 'copper-ore', count = random(32, 128)},
{name = 'submachine-gun', count = 1},
{name = 'loader', count = 1},
{name = 'submachine-gun', count = 1},
{name = 'submachine-gun', count = 1},
{name = 'stone-furnace', count = 2},
{name = 'submachine-gun', count = 1},
{name = 'submachine-gun', count = 1},
{name = 'loader', count = 1},
{name = 'submachine-gun', count = 1},
{name = 'automation-science-pack', count = random(4, 32)},
{name = 'submachine-gun', count = 1},
{name = 'stone-wall', count = random(4, 32)},
{name = 'shotgun', count = 1},
{name = 'shotgun', count = 1},
{name = 'shotgun', count = 1},
{name = 'stone-wall', count = random(4, 32)},
{name = 'gun-turret', count = 1},
{name = 'gun-turret', count = 1},
{name = 'gun-turret', count = 1},
{name = 'gun-turret', count = 1},
{name = 'stone-wall', count = random(4, 32)},
{name = 'shotgun-shell', count = random(4, 5)},
{name = 'shotgun-shell', count = random(4, 5)},
{name = 'shotgun-shell', count = random(4, 5)},
{name = 'gun-turret', count = 1},
{name = 'land-mine', count = random(6, 18)},
{name = 'grenade', count = random(2, 7)},
{name = 'grenade', count = random(2, 8)},
{name = 'gun-turret', count = 1},
{name = 'grenade', count = random(2, 7)},
{name = 'light-armor', count = random(2, 4)},
{name = 'iron-gear-wheel', count = random(7, 15)},
{name = 'iron-gear-wheel', count = random(7, 15)},
{name = 'gun-turret', count = 1},
{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, 56)},
{name = 'firearm-magazine', count = random(10, 56)},
{name = 'firearm-magazine', count = random(10, 56)},
{name = 'firearm-magazine', count = random(10, 56)},
{name = 'rail', count = random(16, 24)},
{name = 'rail', count = random(16, 24)}
{ name = 'loader', count = 1 },
{ name = 'stone-furnace', count = 2 },
{ name = 'coal', count = random(32, 64) },
{ name = 'coal', count = random(32, 64) },
{ name = 'loader', count = 1 },
{ name = 'iron-ore', count = random(32, 128) },
{ name = 'copper-ore', count = random(32, 128) },
{ name = 'submachine-gun', count = 1 },
{ name = 'loader', count = 1 },
{ name = 'submachine-gun', count = 1 },
{ name = 'submachine-gun', count = 1 },
{ name = 'stone-furnace', count = 2 },
{ name = 'submachine-gun', count = 1 },
{ name = 'submachine-gun', count = 1 },
{ name = 'loader', count = 1 },
{ name = 'submachine-gun', count = 1 },
{ name = 'automation-science-pack', count = random(4, 32) },
{ name = 'submachine-gun', count = 1 },
{ name = 'stone-wall', count = random(4, 32) },
{ name = 'shotgun', count = 1 },
{ name = 'shotgun', count = 1 },
{ name = 'shotgun', count = 1 },
{ name = 'stone-wall', count = random(4, 32) },
{ name = 'gun-turret', count = 1 },
{ name = 'gun-turret', count = 1 },
{ name = 'gun-turret', count = 1 },
{ name = 'gun-turret', count = 1 },
{ name = 'stone-wall', count = random(4, 32) },
{ name = 'shotgun-shell', count = random(4, 5) },
{ name = 'shotgun-shell', count = random(4, 5) },
{ name = 'shotgun-shell', count = random(4, 5) },
{ name = 'gun-turret', count = 1 },
{ name = 'land-mine', count = random(6, 18) },
{ name = 'grenade', count = random(2, 7) },
{ name = 'grenade', count = random(2, 8) },
{ name = 'gun-turret', count = 1 },
{ name = 'grenade', count = random(2, 7) },
{ name = 'light-armor', count = random(2, 4) },
{ name = 'iron-gear-wheel', count = random(7, 15) },
{ name = 'iron-gear-wheel', count = random(7, 15) },
{ name = 'gun-turret', count = 1 },
{ 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, 56) },
{ name = 'firearm-magazine', count = random(10, 56) },
{ name = 'firearm-magazine', count = random(10, 56) },
{ name = 'firearm-magazine', count = random(10, 56) },
{ name = 'rail', count = random(16, 24) },
{ name = 'rail', count = random(16, 24) }
}
end
local place_tiles_token =
Task.register(
function(event)
local surface = event.surface
if not surface or not surface.valid then
return
end
local position = event.position
if not position then
return
end
function (event)
local surface = event.surface
if not surface or not surface.valid then
return
end
local position = event.position
if not position then
return
end
MapFunctions.draw_noise_tile_circle(position, 'black-refined-concrete', surface, 22)
end
)
MapFunctions.draw_noise_tile_circle(position, 'black-refined-concrete', surface, 22)
end
)
local set_loco_cargo =
Task.register(
function(data)
local surface = data.surface
if not surface or not surface.valid then
return
end
function (data)
local surface = data.surface
if not surface or not surface.valid then
return
end
local cargo_boxes = initial_cargo_boxes()
local cargo_boxes = initial_cargo_boxes()
local p = {}
local p = {}
local rad = 16 ^ 2
for x = -15, 15, 1 do
for y = 0, 67, 1 do
local va = floor((0 - x) ^ 2 + (53 - y) ^ 2)
if ((va < rad - 50) and (va > rad - 100)) then
if random(1, 3) == 1 then
p[#p + 1] = {x = x, y = y}
local rad = 16 ^ 2
for x = -15, 15, 1 do
for y = 0, 67, 1 do
local va = floor((0 - x) ^ 2 + (53 - y) ^ 2)
if ((va < rad - 50) and (va > rad - 100)) then
if random(1, 3) == 1 then
p[#p + 1] = { x = x, y = y }
end
end
end
end
end
for i = 1, #cargo_boxes, 1 do
if not p[i] then
break
end
local name = 'crash-site-chest-1'
for i = 1, #cargo_boxes, 1 do
if not p[i] then
break
end
local name = 'crash-site-chest-1'
if random(1, 3) == 1 then
name = 'crash-site-chest-2'
end
if surface.can_place_entity({name = name, position = p[i]}) then
local e = surface.create_entity({name = name, position = p[i], force = 'neutral', create_build_effect_smoke = false})
e.minable = false
e.destructible = true
e.health = random(15, 30)
local inventory = e.get_inventory(defines.inventory.chest)
inventory.insert(cargo_boxes[i])
if random(1, 3) == 1 then
name = 'crash-site-chest-2'
end
if surface.can_place_entity({ name = name, position = p[i] }) then
local e = surface.create_entity({ name = name, position = p[i], force = 'neutral', create_build_effect_smoke = false })
e.minable = false
e.destructible = true
e.health = random(15, 30)
local inventory = e.get_inventory(defines.inventory.chest)
inventory.insert(cargo_boxes[i])
end
end
end
end
)
)
function Public.locomotive_spawn(surface, position, reversed)
local this = Public.get()
local extra_wagons = Public.stateful.get_stateful('extra_wagons')
local extra_wagons = Public.get_stateful('extra_wagons')
if not extra_wagons then
extra_wagons = 0
@@ -140,22 +140,22 @@ function Public.locomotive_spawn(surface, position, reversed)
if reversed then
position.y = position.y - (6 * extra_wagons)
for y = -6, 6, 2 do
surface.create_entity({name = 'straight-rail', position = {position.x, position.y + y}, force = 'player', direction = 0})
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', direction = defines.direction.south})
this.locomotive.get_inventory(defines.inventory.fuel).insert({name = 'wood', count = 100})
this.locomotive = surface.create_entity({ name = 'locomotive', position = { position.x, position.y + -3 }, force = 'player', direction = defines.direction.south })
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', direction = defines.direction.south})
this.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = 'raw-fish', count = 8})
this.locomotive_cargo = surface.create_entity({ name = 'cargo-wagon', position = { position.x, position.y + 3 }, force = 'player', direction = defines.direction.south })
this.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({ name = 'raw-fish', count = 8 })
else
for y = -6, 6, 2 do
surface.create_entity({name = 'straight-rail', position = {position.x, position.y + y}, force = 'player', direction = 0})
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 = 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})
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 })
end
local winter_mode_locomotive = Public.wintery(this.locomotive, 5.5)
@@ -167,7 +167,7 @@ function Public.locomotive_spawn(surface, position, reversed)
intensity = 1,
minimum_darkness = 0,
oriented = true,
color = {255, 255, 255},
color = { 255, 255, 255 },
target = this.locomotive,
surface = surface,
visible = true,
@@ -186,7 +186,7 @@ function Public.locomotive_spawn(surface, position, reversed)
intensity = 1,
minimum_darkness = 0,
oriented = true,
color = {255, 255, 255},
color = { 255, 255, 255 },
target = this.locomotive_cargo,
surface = surface,
visible = true,
@@ -209,16 +209,16 @@ function Public.locomotive_spawn(surface, position, reversed)
orientation = random(0, 100) * 0.01,
x_scale = scale,
y_scale = scale,
tint = {random(60, 255), random(60, 255), random(60, 255)},
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},
target_offset = { -0.7 + random(0, 140) * 0.01, y },
surface = surface
}
)
end
this.locomotive.color = {random(2, 255), random(60, 255), random(60, 255)}
this.locomotive.color = { random(2, 255), random(60, 255), random(60, 255) }
this.locomotive.minable = false
this.locomotive_cargo.minable = false
this.locomotive_cargo.operable = true
@@ -240,19 +240,19 @@ function Public.locomotive_spawn(surface, position, reversed)
local pos = this.locomotive_cargo.position
local new_position = {x = pos.x, y = pos.y + inc}
local new_position = { x = pos.x, y = pos.y + inc }
for y = pos.y, new_position.y + (6 * extra_wagons), 2 do
surface.create_entity({name = 'straight-rail', position = {new_position.x, y}, force = 'player', direction = 0})
surface.create_entity({ name = 'straight-rail', position = { new_position.x, y }, force = 'player', direction = 0 })
end
for _ = 1, extra_wagons do
local new_wagon = surface.create_entity({name = 'cargo-wagon', position = new_position, force = 'player', defines.direction.north})
local new_wagon = surface.create_entity({ name = 'cargo-wagon', position = new_position, force = 'player', defines.direction.north })
if new_wagon and new_wagon.valid then
new_wagon.minable = false
new_wagon.operable = true
inc = inc + 7
new_position = {x = pos.x, y = pos.y + inc}
new_position = { x = pos.x, y = pos.y + inc }
ICW.register_wagon(new_wagon)
end
end
@@ -260,13 +260,13 @@ function Public.locomotive_spawn(surface, position, reversed)
local all_the_fish = Public.get('all_the_fish')
if all_the_fish then
this.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = 'raw-fish', count = 999999})
this.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({ name = 'raw-fish', count = 999999 })
end
Task.set_timeout_in_ticks(15, place_tiles_token, {surface = surface, position = position})
Task.set_timeout_in_ticks(15, place_tiles_token, { surface = surface, position = position })
Task.set_timeout_in_ticks(50, set_loco_cargo, data)
game.forces.player.set_spawn_position({this.locomotive.position.x - 5, this.locomotive.position.y}, locomotive.surface)
game.forces.player.set_spawn_position({ this.locomotive.position.x - 5, this.locomotive.position.y }, locomotive.surface)
end
return Public

View File

@@ -80,7 +80,7 @@ local collapse_kill = {
enabled = true
}
local init_bonus_drill_force = function()
local init_bonus_drill_force = function ()
local bonus_drill = game.forces.bonus_drill
local player = game.forces.player
if not bonus_drill then
@@ -91,7 +91,7 @@ local init_bonus_drill_force = function()
bonus_drill.mining_drill_productivity_bonus = 0.5
end
local is_position_near_tbl = function(position, tbl)
local is_position_near_tbl = function (position, tbl)
local status = false
local function inside(pos)
return pos.x >= position.x and pos.y >= position.y and pos.x <= position.x and pos.y <= position.y
@@ -108,13 +108,13 @@ end
local announce_new_map =
Task.register(
function()
local server_name = Server.check_server_name(scenario_name)
if server_name then
Server.to_discord_named_raw(send_ping_to_channel, role_to_mention .. ' ** Mtn Fortress was just reset! **')
function ()
local server_name = Server.check_server_name(scenario_name)
if server_name then
Server.to_discord_named_raw(send_ping_to_channel, role_to_mention .. ' ** Mtn Fortress was just reset! **')
end
end
end
)
)
function Public.reset_map()
game.forces.player.reset()
@@ -168,7 +168,7 @@ function Public.reset_map()
JailData.set_valid_surface(tostring(surface.name))
JailData.reset_vote_table()
Explosives.set_surface_whitelist({[surface.name] = true})
Explosives.set_surface_whitelist({ [surface.name] = true })
Explosives.disable(false)
Explosives.slow_explode(true)
@@ -194,7 +194,7 @@ function Public.reset_map()
AntiGrief.enable_jail(true)
AntiGrief.damage_entity_threshold(20)
AntiGrief.decon_surface_blacklist(surface.name)
AntiGrief.filtered_types_on_decon({'tree', 'simple-entity', 'fish'})
AntiGrief.filtered_types_on_decon({ 'tree', 'simple-entity', 'fish' })
AntiGrief.set_limit_per_table(2000)
PL.show_roles_in_list(true)
@@ -213,10 +213,10 @@ function Public.reset_map()
player.gui.left['mvps'].destroy()
end
ICMinimap.kill_minimap(player)
Event.raise(Public.events.reset_map, {player_index = player.index})
Event.raise(Public.events.reset_map, { player_index = player.index })
end
Difficulty.reset_difficulty_poll({closing_timeout = game.tick + 36000})
Difficulty.reset_difficulty_poll({ closing_timeout = game.tick + 36000 })
Difficulty.set_gui_width(20)
Collapse.set_kill_entities(false)
@@ -242,15 +242,15 @@ function Public.reset_map()
if this.adjusted_zones.reversed then
Explosives.check_growth_below_void(false)
this.spawn_near_collapse.compare = abs(this.spawn_near_collapse.compare)
Collapse.set_position({0, -130})
Collapse.set_position({ 0, -130 })
Collapse.set_direction('south')
Public.locomotive_spawn(surface, {x = -18, y = -25}, this.adjusted_zones.reversed)
Public.locomotive_spawn(surface, { x = -18, y = -25 }, this.adjusted_zones.reversed)
else
Explosives.check_growth_below_void(true)
this.spawn_near_collapse.compare = abs(this.spawn_near_collapse.compare) * -1
Collapse.set_position({0, 130})
Collapse.set_position({ 0, 130 })
Collapse.set_direction('north')
Public.locomotive_spawn(surface, {x = -18, y = 25}, this.adjusted_zones.reversed)
Public.locomotive_spawn(surface, { x = -18, y = 25 }, this.adjusted_zones.reversed)
end
Public.render_train_hp()
Public.render_direction(surface, this.adjusted_zones.reversed)
@@ -260,7 +260,7 @@ function Public.reset_map()
wave_defense_table.target = this.locomotive
wave_defense_table.nest_building_density = 32
wave_defense_table.game_lost = false
wave_defense_table.spawn_position = {x = 0, y = 84}
wave_defense_table.spawn_position = { x = 0, y = 84 }
WD.alert_boss_wave(true)
WD.enable_side_target(true)
WD.remove_entities(true)
@@ -273,28 +273,31 @@ function Public.reset_map()
WD.increase_average_unit_group_size(true)
WD.increase_max_active_unit_groups(true)
WD.enable_random_spawn_positions(true)
Event.raise(WD.events.on_game_reset, {})
WD.set_track_bosses_only(false)
WD.set_pause_waves_custom_callback(Public.pause_waves_custom_callback_token)
WD.set_threat_event_custom_callback(Public.check_if_spawning_near_train_custom_callback)
-- WD.set_es_unit_limit(400) -- moved to stateful
Event.raise(WD.events.on_game_reset, {})
Public.set_difficulty()
Public.disable_creative()
Public.boost_difficulty()
if this.adjusted_zones.reversed then
if not surface.is_chunk_generated({x = -20, y = -22}) then
surface.request_to_generate_chunks({x = -20, y = -22}, 0.1)
if not surface.is_chunk_generated({ x = -20, y = -22 }) then
surface.request_to_generate_chunks({ x = -20, y = -22 }, 0.1)
surface.force_generate_chunk_requests()
end
game.forces.player.set_spawn_position({x = -27, y = -25}, surface)
WD.set_spawn_position({x = -16, y = -80})
game.forces.player.set_spawn_position({ x = -27, y = -25 }, surface)
WD.set_spawn_position({ x = -16, y = -80 })
WD.enable_inverted(true)
else
if not surface.is_chunk_generated({x = -20, y = 22}) then
surface.request_to_generate_chunks({x = -20, y = 22}, 0.1)
if not surface.is_chunk_generated({ x = -20, y = 22 }) then
surface.request_to_generate_chunks({ x = -20, y = 22 }, 0.1)
surface.force_generate_chunk_requests()
end
game.forces.player.set_spawn_position({x = -27, y = 25}, surface)
WD.set_spawn_position({x = -16, y = 80})
game.forces.player.set_spawn_position({ x = -27, y = 25 }, surface)
WD.set_spawn_position({ x = -16, y = 80 })
WD.enable_inverted(false)
end
@@ -310,7 +313,7 @@ function Public.reset_map()
this.game_lost = false
RPG.rpg_reset_all_players()
RPG.set_surface_name({game.surfaces[this.active_surface_index].name})
RPG.set_surface_name({ game.surfaces[this.active_surface_index].name })
RPG.enable_health_and_mana_bars(true)
RPG.enable_wave_defense(true)
RPG.enable_mana(true)
@@ -339,7 +342,7 @@ function Public.reset_map()
end
end
local is_locomotive_valid = function()
local is_locomotive_valid = function ()
local locomotive = Public.get('locomotive')
if not locomotive or not locomotive.valid then
Public.set('game_lost', true)
@@ -347,18 +350,18 @@ local is_locomotive_valid = function()
end
end
local is_player_valid = function()
local is_player_valid = function ()
local players = game.connected_players
for i = 1, #players do
local player = players[i]
if player.connected and player.controller_type == 2 then
player.set_controller {type = defines.controllers.god}
player.set_controller { type = defines.controllers.god }
player.create_character()
end
end
end
local has_the_game_ended = function()
local has_the_game_ended = function ()
local game_reset_tick = Public.get('game_reset_tick')
if game_reset_tick then
if game_reset_tick < 0 then
@@ -379,7 +382,7 @@ local has_the_game_ended = function()
cause_msg = 'soft-reset'
end
game.print(({'main.reset_in', cause_msg, this.game_reset_tick / 60}), {r = 0.22, g = 0.88, b = 0.22})
game.print(({ 'main.reset_in', cause_msg, this.game_reset_tick / 60 }), { r = 0.22, g = 0.88, b = 0.22 })
end
if this.soft_reset and this.game_reset_tick == 0 then
@@ -392,9 +395,9 @@ local has_the_game_ended = function()
if this.restart and this.game_reset_tick == 0 then
if not this.announced_message then
Public.set_scores()
game.print(({'entity.notify_restart'}), {r = 0.22, g = 0.88, b = 0.22})
game.print(({ 'entity.notify_restart' }), { r = 0.22, g = 0.88, b = 0.22 })
local message = 'Soft-reset is disabled! Server will restart from scenario to load new changes.'
Server.to_discord_bold(table.concat {'*** ', message, ' ***'})
Server.to_discord_bold(table.concat { '*** ', message, ' ***' })
Server.start_scenario('Mountain_Fortress_v3')
this.announced_message = true
return
@@ -403,9 +406,9 @@ local has_the_game_ended = function()
if this.shutdown and this.game_reset_tick == 0 then
if not this.announced_message then
Public.set_scores()
game.print(({'entity.notify_shutdown'}), {r = 0.22, g = 0.88, b = 0.22})
game.print(({ 'entity.notify_shutdown' }), { r = 0.22, g = 0.88, b = 0.22 })
local message = 'Soft-reset is disabled! Server will shutdown. Most likely because of updates.'
Server.to_discord_bold(table.concat {'*** ', message, ' ***'})
Server.to_discord_bold(table.concat { '*** ', message, ' ***' })
Server.stop_scenario()
this.announced_message = true
return
@@ -415,7 +418,7 @@ local has_the_game_ended = function()
end
end
local chunk_load = function()
local chunk_load = function ()
local chunk_load_tick = Public.get('chunk_load_tick')
local tick = game.tick
if chunk_load_tick then
@@ -429,17 +432,17 @@ end
local collapse_message =
Task.register(
function(data)
local pos = data.position
local message = data.message
local collapse_position = {
position = pos
}
Alert.alert_all_players_location(collapse_position, message)
end
)
function (data)
local pos = data.position
local message = data.message
local collapse_position = {
position = pos
}
Alert.alert_all_players_location(collapse_position, message)
end
)
local lock_locomotive_positions = function()
local lock_locomotive_positions = function ()
local locomotive = Public.get('locomotive')
if not locomotive or not locomotive.valid then
return
@@ -455,10 +458,10 @@ local lock_locomotive_positions = function()
end
local locomotive_positions = Public.get('locomotive_pos')
local p = {x = floor(locomotive.position.x), y = floor(locomotive.position.y)}
local p = { x = floor(locomotive.position.x), y = floor(locomotive.position.y) }
local success = is_position_near_tbl(locomotive.position, locomotive_positions.tbl)
if not success and not check_position(locomotive_positions.tbl, p) then
locomotive_positions.tbl[#locomotive_positions.tbl + 1] = {x = p.x, y = p.y}
locomotive_positions.tbl[#locomotive_positions.tbl + 1] = { x = p.x, y = p.y }
end
local total_pos = #locomotive_positions.tbl
@@ -467,7 +470,7 @@ local lock_locomotive_positions = function()
end
end
local compare_collapse_and_train = function()
local compare_collapse_and_train = function ()
local collapse_pos = Collapse.get_position()
local locomotive = Public.get('locomotive')
if not (locomotive and locomotive.valid) then
@@ -491,6 +494,7 @@ local compare_collapse_and_train = function()
else
if Collapse.has_reverse_collapse_started() then
Collapse.reverse_start_now(false, true)
Public.find_void_tiles_and_replace()
end
end
end
@@ -516,7 +520,7 @@ local compare_collapse_and_train = function()
end
end
local collapse_after_wave_200 = function()
local collapse_after_wave_200 = function ()
local final_battle = Public.get('final_battle')
if final_battle then
return
@@ -538,18 +542,18 @@ local collapse_after_wave_200 = function()
local data = {
position = Collapse.get_position()
}
data.message = ({'breached_wall.collapse_start'})
data.message = ({ 'breached_wall.collapse_start' })
Task.set_timeout_in_ticks(100, collapse_message, data)
end
end
local handle_changes = function()
local handle_changes = function ()
Public.set('restart', true)
Public.set('soft_reset', false)
print('Received new changes from backend.')
end
local nth_40_tick = function()
local nth_40_tick = function ()
local update_gui = Public.update_gui
local players = game.connected_players
@@ -564,13 +568,13 @@ local nth_40_tick = function()
chunk_load()
end
local nth_250_tick = function()
local nth_250_tick = function ()
compare_collapse_and_train()
collapse_after_wave_200()
Public.set_spawn_position()
end
local nth_1000_tick = function()
local nth_1000_tick = function ()
Public.set_difficulty()
Public.is_creativity_mode_on()
end
@@ -579,17 +583,17 @@ function Public.init_mtn()
Public.reset_map()
local tooltip = {
[1] = ({'main.diff_tooltip', '500', '50%', '15%', '15%', '1', '12', '50', '10000', '100%', '15', '10'}),
[2] = ({'main.diff_tooltip', '300', '25%', '10%', '10%', '2', '10', '50', '7000', '75%', '8', '8'}),
[3] = ({'main.diff_tooltip', '50', '0%', '0%', '0%', '4', '3', '10', '5000', '50%', '5', '6'})
[1] = ({ 'main.diff_tooltip', '500', '50%', '15%', '15%', '1', '12', '50', '10000', '100%', '15', '10' }),
[2] = ({ 'main.diff_tooltip', '300', '25%', '10%', '10%', '2', '10', '50', '7000', '75%', '8', '8' }),
[3] = ({ 'main.diff_tooltip', '50', '0%', '0%', '0%', '4', '3', '10', '5000', '50%', '5', '6' })
}
Difficulty.set_tooltip(tooltip)
local T = Map.Pop_info()
T.localised_category = 'mountain_fortress_v3'
T.main_caption_color = {r = 150, g = 150, b = 0}
T.sub_caption_color = {r = 0, g = 150, b = 0}
T.main_caption_color = { r = 150, g = 150, b = 0 }
T.sub_caption_color = { r = 0, g = 150, b = 0 }
Explosives.set_destructible_tile('out-of-map', 1500)
Explosives.set_destructible_tile('water', 1000)
@@ -609,7 +613,7 @@ end
Server.on_scenario_changed(
'Mountain_Fortress_v3',
function(data)
function (data)
local scenario = data.scenario
if scenario == 'Mountain_Fortress_v3' then
handle_changes()
@@ -623,7 +627,7 @@ Event.on_nth_tick(1000, nth_1000_tick)
Event.add(
defines.events.on_player_created,
function(event)
function (event)
if event.player_index == 1 then
if not game.is_multiplayer() then
Public.init_mtn()

View File

@@ -12,55 +12,55 @@ local sqrt = math.sqrt
local max_spill = 60
local mining_chance_weights = {
{name = 'iron-plate', chance = 1000},
{name = 'iron-gear-wheel', chance = 750},
{name = 'copper-plate', chance = 750},
{name = 'copper-cable', chance = 500},
{name = 'electronic-circuit', chance = 300},
{name = 'steel-plate', chance = 200},
{name = 'solid-fuel', chance = 150},
{name = 'pipe', chance = 100},
{name = 'iron-stick', chance = 50},
{name = 'battery', chance = 20},
{name = 'empty-barrel', chance = 10},
{name = 'crude-oil-barrel', chance = 30},
{name = 'lubricant-barrel', chance = 20},
{name = 'petroleum-gas-barrel', chance = 15},
{name = 'sulfuric-acid-barrel', chance = 15},
{name = 'heavy-oil-barrel', chance = 15},
{name = 'light-oil-barrel', chance = 15},
{name = 'water-barrel', chance = 10},
{name = 'green-wire', chance = 10},
{name = 'red-wire', chance = 10},
{name = 'explosives', chance = 5},
{name = 'advanced-circuit', chance = 5},
{name = 'nuclear-fuel', chance = 1},
{name = 'pipe-to-ground', chance = 10},
{name = 'plastic-bar', chance = 5},
{name = 'processing-unit', chance = 2},
{name = 'used-up-uranium-fuel-cell', chance = 1},
{name = 'uranium-fuel-cell', chance = 1},
{name = 'rocket-fuel', chance = 3},
{name = 'rocket-control-unit', chance = 1},
{name = 'low-density-structure', chance = 1},
{name = 'heat-pipe', chance = 1},
{name = 'engine-unit', chance = 4},
{name = 'electric-engine-unit', chance = 2},
{name = 'logistic-robot', chance = 1},
{name = 'construction-robot', chance = 1},
{name = 'land-mine', chance = 3},
{name = 'grenade', chance = 10},
{name = 'rocket', chance = 3},
{name = 'explosive-rocket', chance = 3},
{name = 'cannon-shell', chance = 2},
{name = 'explosive-cannon-shell', chance = 2},
{name = 'uranium-cannon-shell', chance = 1},
{name = 'explosive-uranium-cannon-shell', chance = 1},
{name = 'artillery-shell', chance = 1},
{name = 'cluster-grenade', chance = 2},
{name = 'defender-capsule', chance = 5},
{name = 'destroyer-capsule', chance = 1},
{name = 'distractor-capsule', chance = 2}
{ name = 'iron-plate', chance = 1000 },
{ name = 'iron-gear-wheel', chance = 750 },
{ name = 'copper-plate', chance = 750 },
{ name = 'copper-cable', chance = 500 },
{ name = 'electronic-circuit', chance = 300 },
{ name = 'steel-plate', chance = 200 },
{ name = 'solid-fuel', chance = 150 },
{ name = 'pipe', chance = 100 },
{ name = 'iron-stick', chance = 50 },
{ name = 'battery', chance = 20 },
{ name = 'empty-barrel', chance = 10 },
{ name = 'crude-oil-barrel', chance = 30 },
{ name = 'lubricant-barrel', chance = 20 },
{ name = 'petroleum-gas-barrel', chance = 15 },
{ name = 'sulfuric-acid-barrel', chance = 15 },
{ name = 'heavy-oil-barrel', chance = 15 },
{ name = 'light-oil-barrel', chance = 15 },
{ name = 'water-barrel', chance = 10 },
{ name = 'green-wire', chance = 10 },
{ name = 'red-wire', chance = 10 },
{ name = 'explosives', chance = 5 },
{ name = 'advanced-circuit', chance = 5 },
{ name = 'nuclear-fuel', chance = 1 },
{ name = 'pipe-to-ground', chance = 10 },
{ name = 'plastic-bar', chance = 5 },
{ name = 'processing-unit', chance = 2 },
{ name = 'used-up-uranium-fuel-cell', chance = 1 },
{ name = 'uranium-fuel-cell', chance = 1 },
{ name = 'rocket-fuel', chance = 3 },
{ name = 'rocket-control-unit', chance = 1 },
{ name = 'low-density-structure', chance = 1 },
{ name = 'heat-pipe', chance = 1 },
{ name = 'engine-unit', chance = 4 },
{ name = 'electric-engine-unit', chance = 2 },
{ name = 'logistic-robot', chance = 1 },
{ name = 'construction-robot', chance = 1 },
{ name = 'land-mine', chance = 3 },
{ name = 'grenade', chance = 10 },
{ name = 'rocket', chance = 3 },
{ name = 'explosive-rocket', chance = 3 },
{ name = 'cannon-shell', chance = 2 },
{ name = 'explosive-cannon-shell', chance = 2 },
{ name = 'uranium-cannon-shell', chance = 1 },
{ name = 'explosive-uranium-cannon-shell', chance = 1 },
{ name = 'artillery-shell', chance = 1 },
{ name = 'cluster-grenade', chance = 2 },
{ name = 'defender-capsule', chance = 5 },
{ name = 'destroyer-capsule', chance = 1 },
{ name = 'distractor-capsule', chance = 2 }
}
local scrap_yield_amounts = {
@@ -191,11 +191,11 @@ local function create_particles(surface, name, position, amount, cause_position)
end
local mining_chances_ores = {
{name = 'iron-ore', chance = 26},
{name = 'copper-ore', chance = 21},
{name = 'coal', chance = 17},
{name = 'stone', chance = 6},
{name = 'uranium-ore', chance = 2}
{ name = 'iron-ore', chance = 26 },
{ name = 'copper-ore', chance = 21 },
{ name = 'coal', chance = 17 },
{ name = 'stone', chance = 6 },
{ name = 'uranium-ore', chance = 2 }
}
local harvest_raffle_ores = {}
@@ -269,17 +269,20 @@ local function get_amount(data)
end
function Public.entity_died_randomness(data)
if Public.get('final_battle') then
return
end
local entity = data.entity
local surface = data.surface
local harvest
harvest = harvest_raffle_ores[random(1, size_of_ore_raffle)]
local position = {x = entity.position.x, y = entity.position.y}
local position = { x = entity.position.x, y = entity.position.y }
surface.spill_item_stack(position, {name = harvest, count = random(1, 5)}, true)
surface.spill_item_stack(position, { name = harvest, count = random(1, 5) }, true)
local particle = particles[harvest]
create_particles(surface, particle, position, 16, {x = entity.position.x, y = entity.position.y})
create_particles(surface, particle, position, 16, { x = entity.position.x, y = entity.position.y })
end
local function randomness(data)
@@ -300,14 +303,14 @@ local function randomness(data)
harvest = harvest_raffle_ores[random(1, size_of_ore_raffle)]
end
local position = {x = entity.position.x, y = entity.position.y}
local position = { x = entity.position.x, y = entity.position.y }
player.surface.create_entity(
{
name = 'flying-text',
position = position,
text = '+' .. harvest_amount .. ' [img=item/' .. harvest .. ']',
color = {r = 200, g = 160, b = 30}
color = { r = 200, g = 160, b = 30 }
}
)
@@ -317,33 +320,33 @@ local function randomness(data)
if harvest_amount > max_spill then
if spill_items_to_surface then
player.surface.spill_item_stack(position, {name = harvest, count = max_spill}, true)
player.surface.spill_item_stack(position, { name = harvest, count = max_spill }, true)
else
player.insert({name = harvest, count = max_spill})
player.insert({ name = harvest, count = max_spill })
end
harvest_amount = harvest_amount - max_spill
local inserted_count = player.insert({name = harvest, count = harvest_amount})
local inserted_count = player.insert({ name = harvest, count = harvest_amount })
harvest_amount = harvest_amount - inserted_count
if harvest_amount > 0 then
if spill_items_to_surface then
player.surface.spill_item_stack(position, {name = harvest, count = harvest_amount}, true)
player.surface.spill_item_stack(position, { name = harvest, count = harvest_amount }, true)
else
player.insert({name = harvest, count = harvest_amount})
player.insert({ name = harvest, count = harvest_amount })
end
end
else
if spill_items_to_surface then
player.surface.spill_item_stack(position, {name = harvest, count = harvest_amount}, true)
player.surface.spill_item_stack(position, { name = harvest, count = harvest_amount }, true)
else
player.insert({name = harvest, count = harvest_amount})
player.insert({ name = harvest, count = harvest_amount })
end
end
local particle = particles[harvest]
if data.script_character then
create_particles(player.surface, particle, position, 16, {x = data.script_character.position.x, y = data.script_character.position.y})
create_particles(player.surface, particle, position, 16, { x = data.script_character.position.x, y = data.script_character.position.y })
else
create_particles(player.surface, particle, position, 16, {x = player.position.x, y = player.position.y})
create_particles(player.surface, particle, position, 16, { x = player.position.x, y = player.position.y })
end
end
@@ -358,14 +361,14 @@ local function randomness_scrap(data)
local r2 = math.ceil(scrap_yield_amounts[harvest] * (1.7 + (amount_bonus * 1.7)))
local harvest_amount = math.random(r1, r2)
local position = {x = entity.position.x, y = entity.position.y}
local position = { x = entity.position.x, y = entity.position.y }
player.surface.create_entity(
{
name = 'flying-text',
position = position,
text = '+' .. harvest_amount .. ' [img=item/' .. harvest .. ']',
color = {r = 200, g = 160, b = 30}
color = { r = 200, g = 160, b = 30 }
}
)
@@ -375,32 +378,32 @@ local function randomness_scrap(data)
if harvest_amount > max_spill then
if spill_items_to_surface then
player.surface.spill_item_stack(position, {name = harvest, count = max_spill}, true)
player.surface.spill_item_stack(position, { name = harvest, count = max_spill }, true)
else
player.insert({name = harvest, count = max_spill})
player.insert({ name = harvest, count = max_spill })
end
harvest_amount = harvest_amount - max_spill
local inserted_count = player.insert({name = harvest, count = harvest_amount})
local inserted_count = player.insert({ name = harvest, count = harvest_amount })
harvest_amount = harvest_amount - inserted_count
if harvest_amount > 0 then
if spill_items_to_surface then
player.surface.spill_item_stack(position, {name = harvest, count = harvest_amount}, true)
player.surface.spill_item_stack(position, { name = harvest, count = harvest_amount }, true)
else
player.insert({name = harvest, count = harvest_amount})
player.insert({ name = harvest, count = harvest_amount })
end
end
else
if spill_items_to_surface then
player.surface.spill_item_stack(position, {name = harvest, count = harvest_amount}, true)
player.surface.spill_item_stack(position, { name = harvest, count = harvest_amount }, true)
else
player.insert({name = harvest, count = harvest_amount})
player.insert({ name = harvest, count = harvest_amount })
end
end
local particle = particles[harvest]
if data.script_character then
create_particles(player.surface, particle, position, 64, {x = data.script_character.position.x, y = data.script_character.position.y})
create_particles(player.surface, particle, position, 64, { x = data.script_character.position.x, y = data.script_character.position.y })
else
create_particles(player.surface, particle, position, 64, {x = player.position.x, y = player.position.y})
create_particles(player.surface, particle, position, 64, { x = player.position.x, y = player.position.y })
end
end
@@ -433,6 +436,10 @@ function Public.on_player_mined_entity(event)
return
end
if Public.get('final_battle') then
return
end
local data = {
entity = entity,
player = player
@@ -457,7 +464,7 @@ end
Event.add(
Public.events.on_entity_mined,
function(event)
function (event)
if not event then
return
end
@@ -468,7 +475,7 @@ Event.add(
Event.add(
Ai.events.on_entity_mined,
function(event)
function (event)
if not event then
return
end

View File

@@ -61,17 +61,17 @@ end
local spread_particles_token =
Task.register(
function(event)
local player_index = event.player_index
local player = game.get_player(player_index)
if not player or not player.valid then
return
end
local particle = event.particle
function (event)
local player_index = event.player_index
local player = game.get_player(player_index)
if not player or not player.valid then
return
end
local particle = event.particle
create_particles(player.surface, particle, player.position, 128)
end
)
create_particles(player.surface, particle, player.position, 128)
end
)
local function pretty_format(input)
local action = string.gsub(input, '-', ' ')
@@ -147,7 +147,7 @@ end
local function clear_all_frames()
Core.iter_players(
function(player)
function (player)
local b_frame = player.gui.screen[boss_frame_name]
if b_frame then
Gui.remove_data_recursively(b_frame)
@@ -165,7 +165,7 @@ end
local function refresh_frames()
Core.iter_connected_players(
function(player)
function (player)
local frame = player.gui.screen[main_frame_name]
if frame and frame.valid then
Gui.remove_data_recursively(frame)
@@ -180,35 +180,35 @@ end
local warn_player_sound_token =
Task.register(
function(event)
local player_index = event.player_index
local player = game.get_player(player_index)
if not player or not player.valid then
return
function (event)
local player_index = event.player_index
local player = game.get_player(player_index)
if not player or not player.valid then
return
end
local particle = event.particle
player.play_sound { path = 'utility/new_objective', volume_modifier = 0.75 }
create_particles(player.surface, particle, player.position, 128)
end
local particle = event.particle
player.play_sound {path = 'utility/new_objective', volume_modifier = 0.75}
create_particles(player.surface, particle, player.position, 128)
end
)
)
local function create_button(player)
if Gui.get_mod_gui_top_frame() then
local b =
Gui.add_mod_button(
player,
{
type = 'sprite-button',
name = main_button_name,
sprite = 'utility/custom_tag_icon',
tooltip = 'Has information about all objectives that needs to be completed',
style = Gui.button_style
}
)
player,
{
type = 'sprite-button',
name = main_button_name,
sprite = 'utility/custom_tag_icon',
tooltip = 'Has information about all objectives that needs to be completed',
style = Gui.button_style
}
)
if b then
b.style.font_color = {165, 165, 165}
b.style.font_color = { 165, 165, 165 }
b.style.font = 'heading-3'
b.style.minimal_height = 36
b.style.maximal_height = 36
@@ -218,14 +218,14 @@ local function create_button(player)
else
local b =
player.gui.top.add(
{
type = 'sprite-button',
name = main_button_name,
sprite = 'utility/custom_tag_icon',
tooltip = 'Has information about all objectives that needs to be completed',
style = Gui.button_style
}
)
{
type = 'sprite-button',
name = main_button_name,
sprite = 'utility/custom_tag_icon',
tooltip = 'Has information about all objectives that needs to be completed',
style = Gui.button_style
}
)
b.style.minimal_height = 38
b.style.maximal_height = 38
end
@@ -233,13 +233,13 @@ end
local function create_input_element(frame, type, value, items, index, tooltip, custom_space)
if type == 'slider' then
return frame.add({type = 'slider', value = value, minimum_value = 0, maximum_value = 1})
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})
return frame.add({ type = 'checkbox', state = value })
end
if type == 'label' then
local label = frame.add({type = 'label', caption = value})
local label = frame.add({ type = 'label', caption = value })
label.style.font = 'default-listbox'
label.tooltip = tooltip or ''
if custom_space then
@@ -248,62 +248,62 @@ local function create_input_element(frame, type, value, items, index, tooltip, c
return label
end
if type == 'dropdown' then
return frame.add({type = 'drop-down', items = items, selected_index = index})
return frame.add({ type = 'drop-down', items = items, selected_index = index })
end
return frame.add({type = 'text-box', text = value})
return frame.add({ type = 'text-box', text = value })
end
local function play_game_won()
Explosives.disable(false)
Core.iter_connected_players(
function(player)
function (player)
Explosives.detonate_entity(player)
player.play_sound {path = 'utility/game_won', volume_modifier = 0.75}
Task.set_timeout_in_ticks(10, spread_particles_token, {player_index = player.index, particle = 'iron-ore-particle'})
Task.set_timeout_in_ticks(15, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
Task.set_timeout_in_ticks(20, spread_particles_token, {player_index = player.index, particle = 'copper-ore-particle'})
Task.set_timeout_in_ticks(25, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
Task.set_timeout_in_ticks(30, spread_particles_token, {player_index = player.index, particle = 'stone-particle'})
Task.set_timeout_in_ticks(35, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
Task.set_timeout_in_ticks(40, spread_particles_token, {player_index = player.index, particle = 'coal-particle'})
Task.set_timeout_in_ticks(45, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
player.play_sound { path = 'utility/game_won', volume_modifier = 0.75 }
Task.set_timeout_in_ticks(10, spread_particles_token, { player_index = player.index, particle = 'iron-ore-particle' })
Task.set_timeout_in_ticks(15, spread_particles_token, { player_index = player.index, particle = 'branch-particle' })
Task.set_timeout_in_ticks(20, spread_particles_token, { player_index = player.index, particle = 'copper-ore-particle' })
Task.set_timeout_in_ticks(25, spread_particles_token, { player_index = player.index, particle = 'branch-particle' })
Task.set_timeout_in_ticks(30, spread_particles_token, { player_index = player.index, particle = 'stone-particle' })
Task.set_timeout_in_ticks(35, spread_particles_token, { player_index = player.index, particle = 'branch-particle' })
Task.set_timeout_in_ticks(40, spread_particles_token, { player_index = player.index, particle = 'coal-particle' })
Task.set_timeout_in_ticks(45, spread_particles_token, { player_index = player.index, particle = 'branch-particle' })
end
)
end
local function play_achievement_unlocked()
Core.iter_connected_players(
function(player)
player.play_sound {path = 'utility/achievement_unlocked', volume_modifier = 0.75}
Task.set_timeout_in_ticks(10, spread_particles_token, {player_index = player.index, particle = 'iron-ore-particle'})
Task.set_timeout_in_ticks(15, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
Task.set_timeout_in_ticks(20, spread_particles_token, {player_index = player.index, particle = 'copper-ore-particle'})
Task.set_timeout_in_ticks(25, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
Task.set_timeout_in_ticks(30, spread_particles_token, {player_index = player.index, particle = 'stone-particle'})
Task.set_timeout_in_ticks(35, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
Task.set_timeout_in_ticks(40, spread_particles_token, {player_index = player.index, particle = 'coal-particle'})
Task.set_timeout_in_ticks(45, spread_particles_token, {player_index = player.index, particle = 'branch-particle'})
function (player)
player.play_sound { path = 'utility/achievement_unlocked', volume_modifier = 0.75 }
Task.set_timeout_in_ticks(10, spread_particles_token, { player_index = player.index, particle = 'iron-ore-particle' })
Task.set_timeout_in_ticks(15, spread_particles_token, { player_index = player.index, particle = 'branch-particle' })
Task.set_timeout_in_ticks(20, spread_particles_token, { player_index = player.index, particle = 'copper-ore-particle' })
Task.set_timeout_in_ticks(25, spread_particles_token, { player_index = player.index, particle = 'branch-particle' })
Task.set_timeout_in_ticks(30, spread_particles_token, { player_index = player.index, particle = 'stone-particle' })
Task.set_timeout_in_ticks(35, spread_particles_token, { player_index = player.index, particle = 'branch-particle' })
Task.set_timeout_in_ticks(40, spread_particles_token, { player_index = player.index, particle = 'coal-particle' })
Task.set_timeout_in_ticks(45, spread_particles_token, { player_index = player.index, particle = 'branch-particle' })
end
)
end
local function alert_players_sound()
Core.iter_connected_players(
function(player)
Task.set_timeout_in_ticks(10, warn_player_sound_token, {player_index = player.index, particle = 'iron-ore-particle'})
Task.set_timeout_in_ticks(20, warn_player_sound_token, {player_index = player.index, particle = 'branch-particle'})
Task.set_timeout_in_ticks(30, warn_player_sound_token, {player_index = player.index, particle = 'copper-ore-particle'})
Task.set_timeout_in_ticks(40, warn_player_sound_token, {player_index = player.index, particle = 'branch-particle'})
Task.set_timeout_in_ticks(50, warn_player_sound_token, {player_index = player.index, particle = 'stone-particle'})
Task.set_timeout_in_ticks(60, warn_player_sound_token, {player_index = player.index, particle = 'branch-particle'})
Task.set_timeout_in_ticks(70, warn_player_sound_token, {player_index = player.index, particle = 'coal-particle'})
Task.set_timeout_in_ticks(80, warn_player_sound_token, {player_index = player.index, particle = 'branch-particle'})
function (player)
Task.set_timeout_in_ticks(10, warn_player_sound_token, { player_index = player.index, particle = 'iron-ore-particle' })
Task.set_timeout_in_ticks(20, warn_player_sound_token, { player_index = player.index, particle = 'branch-particle' })
Task.set_timeout_in_ticks(30, warn_player_sound_token, { player_index = player.index, particle = 'copper-ore-particle' })
Task.set_timeout_in_ticks(40, warn_player_sound_token, { player_index = player.index, particle = 'branch-particle' })
Task.set_timeout_in_ticks(50, warn_player_sound_token, { player_index = player.index, particle = 'stone-particle' })
Task.set_timeout_in_ticks(60, warn_player_sound_token, { player_index = player.index, particle = 'branch-particle' })
Task.set_timeout_in_ticks(70, warn_player_sound_token, { player_index = player.index, particle = 'coal-particle' })
Task.set_timeout_in_ticks(80, warn_player_sound_token, { player_index = player.index, particle = 'branch-particle' })
end
)
end
local function spacer(frame)
local flow = frame.add({type = 'flow'})
local flow = frame.add({ type = 'flow' })
flow.style.minimal_height = 2
end
@@ -311,33 +311,33 @@ local function objective_frames(stateful, player_frame, objective, data)
local objective_name = objective.name
if objective_name == 'supplies' or objective_name == 'single_item' then
local supplies = stateful.objectives.supplies
local tbl = player_frame.add {type = 'table', column_count = 2}
local tbl = player_frame.add { type = 'table', column_count = 2 }
tbl.style.horizontally_stretchable = true
local left_flow = tbl.add({type = 'flow'})
local left_flow = tbl.add({ type = 'flow' })
left_flow.style.horizontal_align = 'left'
left_flow.style.horizontally_stretchable = true
if objective_name == 'single_item' then
left_flow.add({type = 'label', caption = {'stateful.production_single'}, tooltip = {'stateful.production_tooltip'}})
left_flow.add({ type = 'label', caption = { 'stateful.production_single' }, tooltip = { 'stateful.production_tooltip' } })
else
left_flow.add({type = 'label', caption = {'stateful.production'}, tooltip = {'stateful.production_tooltip'}})
left_flow.add({ type = 'label', caption = { 'stateful.production' }, tooltip = { 'stateful.production_tooltip' } })
end
player_frame.add({type = 'line', direction = 'vertical'})
local right_flow = tbl.add({type = 'flow'})
player_frame.add({ type = 'line', direction = 'vertical' })
local right_flow = tbl.add({ type = 'flow' })
right_flow.style.horizontal_align = 'right'
right_flow.style.horizontally_stretchable = true
if objective_name == 'single_item' then
if stateful.objectives_completed.single_item then
data.single_item_complete = right_flow.add({type = 'label', caption = ' [img=utility/check_mark_green]', tooltip = {'stateful.tooltip_completed'}})
data.single_item_complete = right_flow.add({ type = 'label', caption = ' [img=utility/check_mark_green]', tooltip = { 'stateful.tooltip_completed' } })
else
data.single_item_complete = right_flow.add({type = 'label', caption = ' [img=utility/not_available]', tooltip = {'stateful.tooltip_not_completed'}})
data.single_item_complete = right_flow.add({ type = 'label', caption = ' [img=utility/not_available]', tooltip = { 'stateful.tooltip_not_completed' } })
end
else
if stateful.objectives_completed.supplies then
data.supply_completed = right_flow.add({type = 'label', caption = ' [img=utility/check_mark_green]', tooltip = {'stateful.tooltip_completed'}})
data.supply_completed = right_flow.add({ type = 'label', caption = ' [img=utility/check_mark_green]', tooltip = { 'stateful.tooltip_completed' } })
else
data.supply_completed = right_flow.add({type = 'label', caption = ' [img=utility/not_available]', tooltip = {'stateful.tooltip_not_completed'}})
data.supply_completed = right_flow.add({ type = 'label', caption = ' [img=utility/not_available]', tooltip = { 'stateful.tooltip_not_completed' } })
end
end
@@ -345,15 +345,15 @@ local function objective_frames(stateful, player_frame, objective, data)
data.supply = {}
end
local flow = player_frame.add({type = 'flow'})
local item_table = flow.add({type = 'table', name = 'item_table', column_count = 3})
local flow = player_frame.add({ type = 'flow' })
local item_table = flow.add({ type = 'table', name = 'item_table', column_count = 3 })
if objective_name ~= 'single_item' then
data.supply[#data.supply + 1] = item_table.add({type = 'sprite-button', name = supplies[1].name, sprite = 'item/' .. supplies[1].name, enabled = false, number = supplies[1].count})
data.supply[#data.supply + 1] = item_table.add({type = 'sprite-button', name = supplies[2].name, sprite = 'item/' .. supplies[2].name, enabled = false, number = supplies[2].count})
data.supply[#data.supply + 1] = item_table.add({type = 'sprite-button', name = supplies[3].name, sprite = 'item/' .. supplies[3].name, enabled = false, number = supplies[3].count})
data.supply[#data.supply + 1] = item_table.add({ type = 'sprite-button', name = supplies[1].name, sprite = 'item/' .. supplies[1].name, enabled = false, number = supplies[1].count })
data.supply[#data.supply + 1] = item_table.add({ type = 'sprite-button', name = supplies[2].name, sprite = 'item/' .. supplies[2].name, enabled = false, number = supplies[2].count })
data.supply[#data.supply + 1] = item_table.add({ type = 'sprite-button', name = supplies[3].name, sprite = 'item/' .. supplies[3].name, enabled = false, number = supplies[3].count })
else
local single_item = stateful.objectives.single_item
data.single_item = item_table.add({type = 'sprite-button', name = single_item.name, sprite = 'item/' .. single_item.name, enabled = false, number = single_item.count})
data.single_item = item_table.add({ type = 'sprite-button', name = single_item.name, sprite = 'item/' .. single_item.name, enabled = false, number = single_item.count })
end
return
@@ -363,19 +363,19 @@ local function objective_frames(stateful, player_frame, objective, data)
local _, objective_locale_left, objective_locale_right, tooltip_left, tooltip_right = callback()
local tbl = player_frame.add {type = 'table', column_count = 2}
local tbl = player_frame.add { type = 'table', column_count = 2 }
tbl.style.horizontally_stretchable = true
local left_flow = tbl.add({type = 'flow'})
local left_flow = tbl.add({ type = 'flow' })
left_flow.style.horizontal_align = 'left'
left_flow.style.horizontally_stretchable = true
left_flow.add({type = 'label', caption = objective_locale_left, tooltip = tooltip_left})
local right_flow = tbl.add({type = 'flow'})
left_flow.add({ type = 'label', caption = objective_locale_left, tooltip = tooltip_left })
local right_flow = tbl.add({ type = 'flow' })
right_flow.style.horizontal_align = 'right'
right_flow.style.horizontally_stretchable = true
local objective_locale_right_label = right_flow.add({type = 'label', caption = objective_locale_right, tooltip = tooltip_right})
data.random_objectives[#data.random_objectives + 1] = {name = objective_name, frame = objective_locale_right_label}
local objective_locale_right_label = right_flow.add({ type = 'label', caption = objective_locale_right, tooltip = tooltip_right })
data.random_objectives[#data.random_objectives + 1] = { name = objective_name, frame = objective_locale_right_label }
return
end
@@ -393,16 +393,16 @@ local function buff_window(player)
local inside_table_style = inside_table.style
inside_table_style.width = 530
local info_text = inside_table.add({type = 'label', caption = 'All the buffs that have been gathered throughout the runs!'})
local info_text = inside_table.add({ type = 'label', caption = 'All the buffs that have been gathered throughout the runs!' })
local info_text_style = info_text.style
info_text_style.font = 'heading-2'
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}
info_text_style.font_color = { 0.55, 0.55, 0.99 }
local buff_pane = inside_table.add({type = 'scroll-pane'})
local buff_pane = inside_table.add({ type = 'scroll-pane' })
local ns = buff_pane.style
ns.vertically_squashable = true
ns.bottom_padding = 5
@@ -410,36 +410,36 @@ local function buff_window(player)
ns.right_padding = 5
ns.top_padding = 5
buff_pane.add({type = 'line'})
buff_pane.add({ type = 'line' })
local starting_items_label = buff_pane.add({type = 'label', caption = 'Starting items'})
local starting_items_label = buff_pane.add({ type = 'label', caption = 'Starting items' })
local starting_items_label_style = starting_items_label.style
starting_items_label_style.font = 'heading-3'
starting_items_label_style.padding = 0
starting_items_label_style.horizontal_align = 'left'
starting_items_label_style.font_color = {0.55, 0.55, 0.99}
starting_items_label_style.font_color = { 0.55, 0.55, 0.99 }
local starting_grid = buff_pane.add({type = 'table', column_count = 8})
local starting_grid = buff_pane.add({ type = 'table', column_count = 8 })
buff_pane.add({type = 'line'})
buff_pane.add({ type = 'line' })
local force_label = buff_pane.add({type = 'label', caption = 'Force Buffs'})
local force_label = buff_pane.add({ type = 'label', caption = 'Force Buffs' })
local force_label_style = force_label.style
force_label_style.font = 'heading-3'
force_label_style.padding = 0
force_label_style.horizontal_align = 'left'
force_label_style.font_color = {0.55, 0.55, 0.99}
local force_grid = buff_pane.add({type = 'table', column_count = 2})
force_label_style.font_color = { 0.55, 0.55, 0.99 }
local force_grid = buff_pane.add({ type = 'table', column_count = 2 })
buff_pane.add({type = 'line'})
buff_pane.add({ type = 'line' })
local custom_label = buff_pane.add({type = 'label', caption = 'Custom Buffs'})
local custom_label = buff_pane.add({ type = 'label', caption = 'Custom Buffs' })
local custom_label_style = custom_label.style
custom_label_style.font = 'heading-3'
custom_label_style.padding = 0
custom_label_style.horizontal_align = 'left'
custom_label_style.font_color = {0.55, 0.55, 0.99}
local custom_grid = buff_pane.add({type = 'table', column_count = 2})
custom_label_style.font_color = { 0.55, 0.55, 0.99 }
local custom_grid = buff_pane.add({ type = 'table', column_count = 2 })
if stateful.buffs and next(stateful.buffs) then
if stateful.buffs_collected and next(stateful.buffs_collected) then
@@ -501,64 +501,64 @@ local function boss_frame(player, alert)
local stateful = Public.get_stateful()
local collection = stateful.collection
local frame = player.gui.screen.add {type = 'frame', name = boss_frame_name, caption = {'stateful.win_conditions'}, direction = 'vertical'}
local frame = player.gui.screen.add { type = 'frame', name = boss_frame_name, caption = { 'stateful.win_conditions' }, direction = 'vertical' }
if not alert then
frame.location = {x = 1, y = 45}
frame.location = { x = 1, y = 45 }
else
frame.location = {x = 1, y = 123}
frame.location = { x = 1, y = 123 }
end
frame.style.maximal_height = 500
frame.style.minimal_width = 200
frame.style.maximal_width = 400
local season_tbl = frame.add {type = 'table', column_count = 2}
local season_tbl = frame.add { type = 'table', column_count = 2 }
season_tbl.style.horizontally_stretchable = true
local season_left_flow = season_tbl.add({type = 'flow'})
local season_left_flow = season_tbl.add({ type = 'flow' })
season_left_flow.style.horizontal_align = 'left'
season_left_flow.style.horizontally_stretchable = true
season_left_flow.add({type = 'label', caption = {'stateful.season'}, tooltip = {'stateful.season_tooltip', stateful.time_to_reset}})
frame.add({type = 'line', direction = 'vertical'})
local season_right_flow = season_tbl.add({type = 'flow'})
season_left_flow.add({ type = 'label', caption = { 'stateful.season' }, tooltip = { 'stateful.season_tooltip', stateful.time_to_reset } })
frame.add({ type = 'line', direction = 'vertical' })
local season_right_flow = season_tbl.add({ type = 'flow' })
season_right_flow.style.horizontal_align = 'right'
season_right_flow.style.horizontally_stretchable = true
data.season_label = season_right_flow.add({type = 'label', caption = stateful.season})
data.season_label = season_right_flow.add({ type = 'label', caption = stateful.season })
spacer(frame)
local rounds_survived_tbl = frame.add {type = 'table', column_count = 2}
local rounds_survived_tbl = frame.add { type = 'table', column_count = 2 }
rounds_survived_tbl.style.horizontally_stretchable = true
local rounds_survived_left_flow = rounds_survived_tbl.add({type = 'flow'})
local rounds_survived_left_flow = rounds_survived_tbl.add({ type = 'flow' })
rounds_survived_left_flow.style.horizontal_align = 'left'
rounds_survived_left_flow.style.horizontally_stretchable = true
rounds_survived_left_flow.add({type = 'label', caption = {'stateful.rounds_survived'}, tooltip = {'stateful.rounds_survived_tooltip'}})
frame.add({type = 'line', direction = 'vertical'})
local rounds_survived_right_flow = rounds_survived_tbl.add({type = 'flow'})
rounds_survived_left_flow.add({ type = 'label', caption = { 'stateful.rounds_survived' }, tooltip = { 'stateful.rounds_survived_tooltip' } })
frame.add({ type = 'line', direction = 'vertical' })
local rounds_survived_right_flow = rounds_survived_tbl.add({ type = 'flow' })
rounds_survived_right_flow.style.horizontal_align = 'right'
rounds_survived_right_flow.style.horizontally_stretchable = true
data.rounds_survived_label = rounds_survived_right_flow.add({type = 'label', caption = stateful.rounds_survived})
data.rounds_survived_label = rounds_survived_right_flow.add({ type = 'label', caption = stateful.rounds_survived })
spacer(frame)
frame.add({type = 'line'})
frame.add({ type = 'line' })
spacer(frame)
if not collection.game_won then
local objective_tbl = frame.add {type = 'table', column_count = 2}
local objective_tbl = frame.add { type = 'table', column_count = 2 }
objective_tbl.style.horizontally_stretchable = true
if collection.gather_time <= 0 then
local survive_for_left_flow = objective_tbl.add({type = 'flow'})
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
survive_for_left_flow.add({type = 'label', caption = {'stateful.survive_for'}})
frame.add({type = 'line', direction = 'vertical'})
local survive_for_right_flow = objective_tbl.add({type = 'flow'})
survive_for_left_flow.add({ type = 'label', caption = { 'stateful.survive_for' } })
frame.add({ type = 'line', direction = 'vertical' })
local survive_for_right_flow = objective_tbl.add({ type = 'flow' })
survive_for_right_flow.style.horizontal_align = 'right'
survive_for_right_flow.style.horizontally_stretchable = true
@@ -569,42 +569,42 @@ local function boss_frame(player, alert)
end
if collection.survive_for <= 0 then
data.survive_for = survive_for_right_flow.add({type = 'label', caption = {'stateful.won'}})
data.survive_for = survive_for_right_flow.add({ type = 'label', caption = { 'stateful.won' } })
else
data.survive_for = survive_for_right_flow.add({type = 'label', caption = survive_for_timer})
data.survive_for = survive_for_right_flow.add({ type = 'label', caption = survive_for_timer })
end
end
-- new frame
local biter_sprites_tbl = objective_tbl.add({type = 'flow'})
local biter_sprites_tbl = objective_tbl.add({ type = 'flow' })
biter_sprites_tbl.style.horizontal_align = 'left'
biter_sprites_tbl.style.horizontally_stretchable = true
biter_sprites_tbl.add({type = 'label', caption = {'stateful.biter_sprites'}})
biter_sprites_tbl.add({ type = 'label', caption = { 'stateful.biter_sprites' } })
else
local objective_tbl = frame.add {type = 'table', column_count = 2}
local objective_tbl = frame.add { type = 'table', column_count = 2 }
objective_tbl.style.horizontally_stretchable = true
local game_won_left_flow = objective_tbl.add({type = 'flow'})
local game_won_left_flow = objective_tbl.add({ type = 'flow' })
game_won_left_flow.style.horizontal_align = 'left'
game_won_left_flow.style.horizontally_stretchable = true
game_won_left_flow.add({type = 'label', caption = {'stateful.game_won'}})
game_won_left_flow.add({ type = 'label', caption = { 'stateful.game_won' } })
end
local close = frame.add({type = 'button', name = close_button, caption = 'Close'})
local close = frame.add({ type = 'button', name = close_button, caption = 'Close' })
close.style.horizontally_stretchable = true
Gui.set_data(frame, data)
end
local function refresh_boss_frame()
Core.iter_connected_players(
function(player)
function (player)
boss_frame(player)
end
)
end
main_frame = function(player)
main_frame = function (player)
local main_player_frame = player.gui.screen[main_frame_name]
if main_player_frame then
Gui.remove_data_recursively(main_player_frame)
@@ -618,99 +618,99 @@ main_frame = function(player)
breached_wall = breached_wall - 1
local wave_number = WD.get('wave_number')
local frame = player.gui.screen.add {type = 'frame', name = main_frame_name, caption = {'stateful.win_conditions'}, direction = 'vertical', tooltip = {'stateful.win_conditions_tooltip'}}
local frame = player.gui.screen.add { type = 'frame', name = main_frame_name, caption = { 'stateful.win_conditions' }, direction = 'vertical', tooltip = { 'stateful.win_conditions_tooltip' } }
if Gui.get_mod_gui_top_frame() then
frame.location = {x = 0, y = 67}
frame.location = { x = 0, y = 67 }
else
frame.location = {x = 1, y = 45}
frame.location = { x = 1, y = 45 }
end
frame.style.maximal_height = 700
frame.style.minimal_width = 200
frame.style.maximal_width = 400
local season_tbl = frame.add {type = 'table', column_count = 2}
local season_tbl = frame.add { type = 'table', column_count = 2 }
season_tbl.style.horizontally_stretchable = true
local season_left_flow = season_tbl.add({type = 'flow'})
local season_left_flow = season_tbl.add({ type = 'flow' })
season_left_flow.style.horizontal_align = 'left'
season_left_flow.style.horizontally_stretchable = true
season_left_flow.add({type = 'label', caption = {'stateful.season'}, tooltip = {'stateful.season_tooltip', stateful.time_to_reset}})
frame.add({type = 'line', direction = 'vertical'})
local season_right_flow = season_tbl.add({type = 'flow'})
season_left_flow.add({ type = 'label', caption = { 'stateful.season' }, tooltip = { 'stateful.season_tooltip', stateful.time_to_reset } })
frame.add({ type = 'line', direction = 'vertical' })
local season_right_flow = season_tbl.add({ type = 'flow' })
season_right_flow.style.horizontal_align = 'right'
season_right_flow.style.horizontally_stretchable = true
data.season_label = season_right_flow.add({type = 'label', caption = stateful.season})
data.season_label = season_right_flow.add({ type = 'label', caption = stateful.season })
spacer(frame)
local rounds_survived_tbl = frame.add {type = 'table', column_count = 2}
local rounds_survived_tbl = frame.add { type = 'table', column_count = 2 }
rounds_survived_tbl.style.horizontally_stretchable = true
local rounds_survived_left_flow = rounds_survived_tbl.add({type = 'flow'})
local rounds_survived_left_flow = rounds_survived_tbl.add({ type = 'flow' })
rounds_survived_left_flow.style.horizontal_align = 'left'
rounds_survived_left_flow.style.horizontally_stretchable = true
rounds_survived_left_flow.add({type = 'label', caption = {'stateful.rounds_survived'}, tooltip = {'stateful.rounds_survived_tooltip'}})
frame.add({type = 'line', direction = 'vertical'})
local rounds_survived_right_flow = rounds_survived_tbl.add({type = 'flow'})
rounds_survived_left_flow.add({ type = 'label', caption = { 'stateful.rounds_survived' }, tooltip = { 'stateful.rounds_survived_tooltip' } })
frame.add({ type = 'line', direction = 'vertical' })
local rounds_survived_right_flow = rounds_survived_tbl.add({ type = 'flow' })
rounds_survived_right_flow.style.horizontal_align = 'right'
rounds_survived_right_flow.style.horizontally_stretchable = true
data.rounds_survived_label = rounds_survived_right_flow.add({type = 'label', caption = stateful.rounds_survived})
data.rounds_survived_label = rounds_survived_right_flow.add({ type = 'label', caption = stateful.rounds_survived })
spacer(frame)
frame.add({type = 'line'})
frame.add({ type = 'line' })
spacer(frame)
if stateful.buffs and next(stateful.buffs) then
local buff_tbl = frame.add {type = 'table', column_count = 2}
local buff_tbl = frame.add { type = 'table', column_count = 2 }
buff_tbl.style.horizontally_stretchable = true
local buff_left_flow = buff_tbl.add({type = 'flow'})
local buff_left_flow = buff_tbl.add({ type = 'flow' })
buff_left_flow.style.horizontal_align = 'left'
buff_left_flow.style.horizontally_stretchable = true
local buff_right_flow = buff_tbl.add({type = 'flow'})
local buff_right_flow = buff_tbl.add({ type = 'flow' })
buff_right_flow.style.horizontal_align = 'right'
buff_right_flow.style.horizontally_stretchable = true
buff_right_flow.add({name = on_click_buff_name, type = 'label', caption = '[img=utility/center]', tooltip = {'stateful.buff_tooltip_click'}})
buff_right_flow.add({ name = on_click_buff_name, type = 'label', caption = '[img=utility/center]', tooltip = { 'stateful.buff_tooltip_click' } })
local buff_label = buff_left_flow.add({type = 'label', caption = {'stateful.buffs'}, tooltip = {'stateful.buff_tooltip'}})
local buff_label = buff_left_flow.add({ type = 'label', caption = { 'stateful.buffs' }, tooltip = { 'stateful.buff_tooltip' } })
buff_label.style.single_line = false
frame.add({type = 'line', direction = 'vertical'})
frame.add({ type = 'line', direction = 'vertical' })
spacer(frame)
frame.add({type = 'line'})
frame.add({ type = 'line' })
end
spacer(frame)
if stateful.objectives_completed.boss_time then
local gather_objective_tbl = frame.add {type = 'table', column_count = 2}
local gather_objective_tbl = frame.add { type = 'table', column_count = 2 }
gather_objective_tbl.style.horizontally_stretchable = true
local gather_warning_flow = gather_objective_tbl.add({type = 'flow'})
local gather_warning_flow = gather_objective_tbl.add({ type = 'flow' })
gather_warning_flow.style.horizontal_align = 'left'
gather_warning_flow.style.horizontally_stretchable = true
gather_warning_flow.add({type = 'label', caption = {'stateful.gather'}})
frame.add({type = 'line', direction = 'vertical'})
gather_warning_flow.add({ type = 'label', caption = { 'stateful.gather' } })
frame.add({ type = 'line', direction = 'vertical' })
local objective_tbl = frame.add {type = 'table', column_count = 2}
local objective_tbl = frame.add { type = 'table', column_count = 2 }
objective_tbl.style.horizontally_stretchable = true
local warn_timer_flow_left = objective_tbl.add({type = 'flow'})
local warn_timer_flow_left = objective_tbl.add({ type = 'flow' })
warn_timer_flow_left.style.horizontal_align = 'left'
warn_timer_flow_left.style.horizontally_stretchable = true
warn_timer_flow_left.add({type = 'label', caption = {'stateful.warp'}, tooltip = {'stateful.warp_tooltip'}})
frame.add({type = 'line', direction = 'vertical'})
warn_timer_flow_left.add({ type = 'label', caption = { 'stateful.warp' }, tooltip = { 'stateful.warp_tooltip' } })
frame.add({ type = 'line', direction = 'vertical' })
local warn_timer_flow_right = objective_tbl.add({type = 'flow'})
local warn_timer_flow_right = objective_tbl.add({ type = 'flow' })
warn_timer_flow_right.style.horizontal_align = 'right'
warn_timer_flow_right.style.horizontally_stretchable = true
@@ -720,42 +720,42 @@ main_frame = function(player)
time_left = floor(stateful.collection.gather_time / 60) .. 's'
end
data.gather_time_label = warn_timer_flow_right.add({type = 'label', caption = time_left})
data.gather_time_label = warn_timer_flow_right.add({ type = 'label', caption = time_left })
else
local objective_tbl = frame.add {type = 'table', column_count = 2}
local objective_tbl = frame.add { type = 'table', column_count = 2 }
objective_tbl.style.horizontally_stretchable = true
local zone_left_flow = objective_tbl.add({type = 'flow'})
local zone_left_flow = objective_tbl.add({ type = 'flow' })
zone_left_flow.style.horizontal_align = 'left'
zone_left_flow.style.horizontally_stretchable = true
zone_left_flow.add({type = 'label', caption = {'stateful.zone'}, tooltip = {'stateful.zone_tooltip'}})
frame.add({type = 'line', direction = 'vertical'})
local zone_right_flow = objective_tbl.add({type = 'flow'})
zone_left_flow.add({ type = 'label', caption = { 'stateful.zone' }, tooltip = { 'stateful.zone_tooltip' } })
frame.add({ type = 'line', direction = 'vertical' })
local zone_right_flow = objective_tbl.add({ type = 'flow' })
zone_right_flow.style.horizontal_align = 'right'
zone_right_flow.style.horizontally_stretchable = true
if breached_wall >= stateful.objectives.randomized_zone then
data.randomized_zone_label = zone_right_flow.add({type = 'label', caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/check_mark_green]', tooltip = {'stateful.tooltip_completed'}})
data.randomized_zone_label = zone_right_flow.add({ type = 'label', caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/check_mark_green]', tooltip = { 'stateful.tooltip_completed' } })
else
data.randomized_zone_label = zone_right_flow.add({type = 'label', caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/not_available]', tooltip = {'stateful.tooltip_not_completed'}})
data.randomized_zone_label = zone_right_flow.add({ type = 'label', caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/not_available]', tooltip = { 'stateful.tooltip_not_completed' } })
end
-- new frame
local wave_left_flow = objective_tbl.add({type = 'flow'})
local wave_left_flow = objective_tbl.add({ type = 'flow' })
wave_left_flow.style.horizontal_align = 'left'
wave_left_flow.style.horizontally_stretchable = true
wave_left_flow.add({type = 'label', caption = {'stateful.wave'}, tooltip = {'stateful.wave_tooltip'}})
frame.add({type = 'line', direction = 'vertical'})
local wave_right_flow = objective_tbl.add({type = 'flow'})
wave_left_flow.add({ type = 'label', caption = { 'stateful.wave' }, tooltip = { 'stateful.wave_tooltip' } })
frame.add({ type = 'line', direction = 'vertical' })
local wave_right_flow = objective_tbl.add({ type = 'flow' })
wave_right_flow.style.horizontal_align = 'right'
wave_right_flow.style.horizontally_stretchable = true
if wave_number >= stateful.objectives.randomized_wave then
data.randomized_wave_label = wave_right_flow.add({type = 'label', caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/check_mark_green]', tooltip = {'stateful.tooltip_completed'}})
data.randomized_wave_label = wave_right_flow.add({ type = 'label', caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/check_mark_green]', tooltip = { 'stateful.tooltip_completed' } })
else
data.randomized_wave_label = wave_right_flow.add({type = 'label', caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/not_available]', tooltip = {'stateful.tooltip_not_completed'}})
data.randomized_wave_label = wave_right_flow.add({ type = 'label', caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/not_available]', tooltip = { 'stateful.tooltip_not_completed' } })
end
--dynamic conditions
@@ -769,7 +769,7 @@ main_frame = function(player)
-- warn players
spacer(frame)
frame.add({type = 'line'})
frame.add({ type = 'line' })
spacer(frame)
-- if not stateful.collection.final_arena_disabled then
-- local final_label = frame.add({type = 'label', caption = {'stateful.tooltip_final'}})
@@ -784,7 +784,7 @@ main_frame = function(player)
-- frame.add({type = 'line'})
spacer(frame)
local close = frame.add({type = 'button', name = close_button, caption = 'Close'})
local close = frame.add({ type = 'button', name = close_button, caption = 'Close' })
close.style.horizontally_stretchable = true
Gui.set_data(frame, data)
end
@@ -818,7 +818,7 @@ local function update_data()
if data.randomized_zone_label and data.randomized_zone_label.valid and stateful.objectives.randomized_zone then
if breached_wall >= stateful.objectives.randomized_zone then
data.randomized_zone_label.caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/check_mark_green]'
data.randomized_zone_label.tooltip = {'stateful.tooltip_completed'}
data.randomized_zone_label.tooltip = { 'stateful.tooltip_completed' }
else
data.randomized_zone_label.caption = breached_wall .. '/' .. stateful.objectives.randomized_zone .. ' [img=utility/not_available]'
end
@@ -827,7 +827,7 @@ local function update_data()
if data.randomized_wave_label and data.randomized_wave_label.valid and stateful.objectives.randomized_wave then
if wave_number >= stateful.objectives.randomized_wave then
data.randomized_wave_label.caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/check_mark_green]'
data.randomized_wave_label.tooltip = {'stateful.tooltip_completed'}
data.randomized_wave_label.tooltip = { 'stateful.tooltip_completed' }
else
data.randomized_wave_label.caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/not_available]'
end
@@ -947,7 +947,7 @@ local function update_data()
end
if collection.survive_for <= 0 then
data_boss.survive_for.caption = {'stateful.won'}
data_boss.survive_for.caption = { 'stateful.won' }
else
data_boss.survive_for.caption = survive_for_timer
end
@@ -1079,11 +1079,10 @@ local function update_raw()
LinkedChests.clear_linked_frames()
stateful.final_battle = true
Public.set('final_battle', true)
WD.set('final_battle', true)
collection.survive_for = game.tick + Stateful.scale(10 * 3600, 35 * 3600)
collection.survive_for_timer = collection.survive_for
collection.nuke_blueprint = true
-- Public.stateful_blueprints.nuke_blueprint()
WD.disable_spawning_biters(false)
Public.allocate()
Public.set_final_battle()
@@ -1131,7 +1130,7 @@ local function update_raw()
notify_won_to_discord(buff)
local locomotive = Public.get('locomotive')
if locomotive and locomotive.valid then
locomotive.surface.spill_item_stack(locomotive.position, {name = 'coin', count = 512}, false)
locomotive.surface.spill_item_stack(locomotive.position, { name = 'coin', count = 512 }, false)
end
Public.set('game_reset_tick', 5400)
return
@@ -1193,7 +1192,7 @@ local function update_raw()
notify_won_to_discord(buff)
local locomotive = Public.get('locomotive')
if locomotive and locomotive.valid then
locomotive.surface.spill_item_stack(locomotive.position, {name = 'coin', count = 512}, false)
locomotive.surface.spill_item_stack(locomotive.position, { name = 'coin', count = 512 }, false)
end
Public.set('game_reset_tick', 5400)
return
@@ -1210,13 +1209,15 @@ local function update_raw()
end
Explosives.disable(true)
WD.disable_spawning_biters(true)
Collapse.set_reverse_position({0, reverse_position})
WD.set_track_bosses_only(false)
Collapse.set_reverse_position({ 0, reverse_position })
Collapse.set_reverse_direction()
Collapse.reverse_start_now(true)
Alert.alert_all_players(200, 'Reverse collapse has been initiated!')
Server.to_discord_embed('Reverse collapse has been initiated!')
-- Public.stateful_blueprints.blueprint()
WD.nuke_wave_gui()
WD.set('final_battle', true)
Public.set('pre_final_battle', true)
refresh_frames()
@@ -1236,7 +1237,7 @@ end
Gui.on_click(
main_button_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Mtn v3 open stateful Button')
if is_spamming then
return
@@ -1279,7 +1280,7 @@ Gui.on_click(
Gui.on_click(
close_button,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Mtn v3 close stateful Button')
if is_spamming then
return
@@ -1308,7 +1309,7 @@ Gui.on_click(
Gui.on_click(
close_buffs_window_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Buff Close Button')
if is_spamming then
return
@@ -1329,7 +1330,7 @@ Gui.on_click(
Gui.on_custom_close(
buffs_window_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Buff Custom Close')
if is_spamming then
return
@@ -1350,7 +1351,7 @@ Gui.on_custom_close(
Gui.on_click(
on_click_buff_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Buff Open Button')
if is_spamming then
return

View File

@@ -9,7 +9,6 @@ Public.stateful_gui = require 'maps.mountain_fortress_v3.stateful.gui'
Public.stateful_blueprints = require 'maps.mountain_fortress_v3.stateful.blueprints'
local random = math.random
local shuffle = table.shuffle_table
local valid_types = {
['unit'] = true,
@@ -49,7 +48,7 @@ end
Event.add(
defines.events.on_research_finished,
function(event)
function (event)
local research = event.research
if not research then
return
@@ -71,8 +70,8 @@ Event.add(
)
Event.on_nth_tick(
350,
function()
150,
function ()
local final_battle = Public.get_stateful('final_battle')
if not final_battle then
return
@@ -88,32 +87,32 @@ Event.on_nth_tick(
end
if collection.gather_time and collection.gather_time <= 0 and collection.survive_for and collection.survive_for > 0 then
local spawn_positions = Public.get_stateful('stateful_spawn_points')
local spawn_positions = table.deepcopy(Public.get_stateful('stateful_spawn_points'))
if not spawn_positions then
Public.set_stateful(
'stateful_spawn_points',
{
{{x = -205, y = -37}, {x = 195, y = 37}},
{{x = -205, y = -112}, {x = 195, y = 112}},
{{x = -205, y = -146}, {x = 195, y = 146}},
{{x = -205, y = -112}, {x = 195, y = 112}},
{{x = -205, y = -72}, {x = 195, y = 72}},
{{x = -205, y = -146}, {x = 195, y = 146}},
{{x = -205, y = -37}, {x = 195, y = 37}},
{{x = -205, y = -5}, {x = 195, y = 5}},
{{x = -205, y = -23}, {x = 195, y = 23}},
{{x = -205, y = -5}, {x = 195, y = 5}},
{{x = -205, y = -72}, {x = 195, y = 72}},
{{x = -205, y = -23}, {x = 195, y = 23}},
{{x = -205, y = -54}, {x = 195, y = 54}},
{{x = -205, y = -80}, {x = 195, y = 80}},
{{x = -205, y = -54}, {x = 195, y = 54}},
{{x = -205, y = -80}, {x = 195, y = 80}},
{{x = -205, y = -103}, {x = 195, y = 103}},
{{x = -205, y = -150}, {x = 195, y = 150}},
{{x = -205, y = -103}, {x = 195, y = 103}},
{{x = -205, y = -150}, {x = 195, y = 150}}
{ { x = -205, y = -37 }, { x = 195, y = 37 } },
{ { x = -205, y = -112 }, { x = 195, y = 112 } },
{ { x = -205, y = -146 }, { x = 195, y = 146 } },
{ { x = -205, y = -112 }, { x = 195, y = 112 } },
{ { x = -205, y = -72 }, { x = 195, y = 72 } },
{ { x = -205, y = -146 }, { x = 195, y = 146 } },
{ { x = -205, y = -37 }, { x = 195, y = 37 } },
{ { x = -205, y = -5 }, { x = 195, y = 5 } },
{ { x = -205, y = -23 }, { x = 195, y = 23 } },
{ { x = -205, y = -5 }, { x = 195, y = 5 } },
{ { x = -205, y = -72 }, { x = 195, y = 72 } },
{ { x = -205, y = -23 }, { x = 195, y = 23 } },
{ { x = -205, y = -54 }, { x = 195, y = 54 } },
{ { x = -205, y = -80 }, { x = 195, y = 80 } },
{ { x = -205, y = -54 }, { x = 195, y = 54 } },
{ { x = -205, y = -80 }, { x = 195, y = 80 } },
{ { x = -205, y = -103 }, { x = 195, y = 103 } },
{ { x = -205, y = -150 }, { x = 195, y = 150 } },
{ { x = -205, y = -103 }, { x = 195, y = 103 } },
{ { x = -205, y = -150 }, { x = 195, y = 150 } }
}
)
@@ -129,17 +128,19 @@ Event.on_nth_tick(
return
end
area[1].x = area[1].x - locomotive.position.x
area[1].y = area[1].y - locomotive.position.y
area[2].x = area[2].x + locomotive.position.x
area[1].y = area[1].y + locomotive.position.y
area[2].y = area[2].y + locomotive.position.y
shuffle(area)
if random(1, 2) == 1 then
WD.set_spawn_position(area[1])
else
WD.set_spawn_position(area[2])
end
WD.set_spawn_position(area[1])
WD.set_main_target()
WD.build_worm_custom()
Event.raise(WD.events.on_spawn_unit_group_simple, {fs = true, bypass = true, random_bosses = true, scale = 8, force = 'aggressors_frenzy'})
-- WD.place_custom_nest(locomotive.surface, area[1], 'aggressors_frenzy')
Event.raise(WD.events.on_spawn_unit_group_simple, { fs = true, bypass = true, random_bosses = true, scale = 32, force = 'aggressors_frenzy' })
return
end
@@ -153,7 +154,7 @@ Event.on_nth_tick(
Event.add(
defines.events.on_player_crafted_item,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
@@ -184,7 +185,7 @@ Event.add(
Event.add(
defines.events.on_rocket_launched,
function(event)
function (event)
local rocket_inventory = event.rocket.get_inventory(defines.inventory.rocket)
local slot = rocket_inventory[1]
if slot and slot.valid and slot.valid_for_read then
@@ -204,7 +205,7 @@ Event.add(
Event.add(
RPG.events.on_spell_cast_success,
function(event)
function (event)
local player = game.get_player(event.player_index)
if not player or not player.valid then
return
@@ -237,7 +238,7 @@ Event.add(
Event.on_nth_tick(
14400,
function()
function ()
local final_battle = Public.get_stateful('final_battle')
if not final_battle then
return
@@ -259,7 +260,7 @@ Event.on_nth_tick(
end
if collection.gather_time and collection.gather_time <= 0 and collection.survive_for > 0 then
Beam.new_beam(surface, game.tick + 150)
Beam.new_beam(surface, game.tick + 350)
end
end
)

View File

@@ -310,16 +310,6 @@ local function get_random_buff(fetch_all, only_force)
{ name = 'solid-fuel', count = 100 }
}
},
{
name = 'fast_startup',
discord = 'Assembling starting supplies - start with some assembling machines T1',
modifier = 'starting_items',
limit = 25,
add_per_buff = 2,
items = {
{ name = 'assembling-machine-1', count = 2 }
}
},
{
name = 'fast_startup_1',
discord = 'Assembling starting supplies - start with some assembling machines T2',
@@ -755,6 +745,15 @@ local function scale(setting, limit, factor)
return floor(scale_value)
end
local function scale_lin(setting, limit, factor)
factor = factor or 1.05
local scale_value = math.floor(setting + (factor * this.rounds_survived))
if limit and scale_value >= limit then
return limit
end
return floor(scale_value)
end
local function get_random_items()
local items = {
{ 'advanced-circuit', scale(225000, 9000000) },
@@ -1610,6 +1609,8 @@ function Public.reset_stateful(refresh_gui, clear_buffs)
supplies.single_item.count = supplies.single_item.total
end
WD.set_es_unit_limit(scale_lin(100, 1000, 5.819))
this.objectives.handcrafted_items.actual = 0
this.objectives.handcrafted_items_any.actual = 0
this.objectives.cast_spell.actual = 0
@@ -1625,22 +1626,22 @@ function Public.reset_stateful(refresh_gui, clear_buffs)
end
this.stateful_spawn_points = {
{ { x = -205, y = -37 }, { x = 195, y = 37 } },
{ { x = -205, y = -37 }, { x = 195, y = 37 } },
{ { x = -205, y = -112 }, { x = 195, y = 112 } },
{ { x = -205, y = -146 }, { x = 195, y = 146 } },
{ { x = -205, y = -112 }, { x = 195, y = 112 } },
{ { x = -205, y = -72 }, { x = 195, y = 72 } },
{ { x = -205, y = -72 }, { x = 195, y = 72 } },
{ { x = -205, y = -146 }, { x = 195, y = 146 } },
{ { x = -205, y = -37 }, { x = 195, y = 37 } },
{ { x = -205, y = -5 }, { x = 195, y = 5 } },
{ { x = -205, y = -23 }, { x = 195, y = 23 } },
{ { x = -205, y = -5 }, { x = 195, y = 5 } },
{ { x = -205, y = -72 }, { x = 195, y = 72 } },
{ { x = -205, y = -23 }, { x = 195, y = 23 } },
{ { x = -205, y = -54 }, { x = 195, y = 54 } },
{ { x = -205, y = -80 }, { x = 195, y = 80 } },
{ { x = -205, y = -54 }, { x = 195, y = 54 } },
{ { x = -205, y = -80 }, { x = 195, y = 80 } },
{ { x = -205, y = -37 }, { x = 195, y = 37 } },
{ { x = -205, y = -5 }, { x = 195, y = 5 } },
{ { x = -205, y = -23 }, { x = 195, y = 23 } },
{ { x = -205, y = -5 }, { x = 195, y = 5 } },
{ { x = -205, y = -72 }, { x = 195, y = 72 } },
{ { x = -205, y = -23 }, { x = 195, y = 23 } },
{ { x = -205, y = -54 }, { x = 195, y = 54 } },
{ { x = -205, y = -80 }, { x = 195, y = 80 } },
{ { x = -205, y = -54 }, { x = 195, y = 54 } },
{ { x = -205, y = -80 }, { x = 195, y = 80 } },
{ { x = -205, y = -103 }, { x = 195, y = 103 } },
{ { x = -205, y = -150 }, { x = 195, y = 150 } },
{ { x = -205, y = -103 }, { x = 195, y = 103 } },
@@ -1709,7 +1710,7 @@ function Public.move_all_players()
Alert.alert_all_players(50, message, nil, nil, 1)
Core.iter_connected_players(
function (player)
local pos = surface.find_non_colliding_position('character', locomotive.position, 10, 0)
local pos = surface.find_non_colliding_position('character', locomotive.position, 32, 1)
Public.stateful_gui.boss_frame(player, true)
@@ -1726,7 +1727,7 @@ function Public.move_all_players()
Core.iter_fake_connected_players(
global.characters,
function (player)
local pos = surface.find_non_colliding_position('character', locomotive.position, 10, 0)
local pos = surface.find_non_colliding_position('character', locomotive.position, 32, 1)
if pos then
player.teleport(pos)
@@ -1744,8 +1745,9 @@ function Public.set_final_battle()
return
end
local es_settings = WD.get_es('settings')
WD.set_es('final_battle', true)
this.final_battle = true
es_settings.final_battle = true
Public.set('final_battle', true)
end

View File

@@ -35,14 +35,14 @@ Public.scenario_name = scenario_name
Global.register(
this,
function(tbl)
function (tbl)
this = tbl
end
)
Global.register(
stateful_settings,
function(tbl)
function (tbl)
stateful_settings = tbl
end
)
@@ -149,7 +149,7 @@ function Public.reset_main_table()
this.gap_between_locomotive = {
hinders = {},
gap = 900,
neg_gap = 3520, -- earlier 2112 (3 zones, whereas 704 is one zone)
neg_gap = 3520, -- earlier 2112 (3 zones, whereas 704 is one zone)
neg_gap_collapse = 5520, -- earlier 2112 (3 zones, whereas 704 is one zone)
highest_pos = nil
}
@@ -170,7 +170,7 @@ function Public.reset_main_table()
this.print_tech_to_discord = true
this.biters_killed = 0
this.cleared_nauvis = false
this.locomotive_pos = {tbl = {}}
this.locomotive_pos = { tbl = {} }
this.trusted_only_car_tanks = true
--!grief prevention
this.enable_arties = 6 -- default to callback 6
@@ -304,6 +304,8 @@ function Public.reset_main_table()
this.mystical_chest_completed = 0
this.mystical_chest_enabled = true
this.check_if_threat_below_zero = true
this.rocks_to_remove = nil
this.tiles_to_replace = nil
this.mc_rewards = {
current = {},
temp_boosts = {}
@@ -318,7 +320,7 @@ function Public.reset_main_table()
reversed = stateful_settings.reversed,
disable_terrain = false
}
this.alert_zone_1 = false -- alert the players
this.alert_zone_1 = false -- alert the players
this.radars_reveal_new_chunks = false -- allows for the player to explore the map instead,
this.mining_utils = {
@@ -400,29 +402,29 @@ end
local apply_settings_token =
Task.register(
function(data)
local server_name_matches = Server.check_server_name(scenario_name)
local settings = data and data.value or nil
function (data)
local server_name_matches = Server.check_server_name(scenario_name)
local settings = data and data.value or nil
if not settings then
if server_name_matches then
Server.set_data(dataset, dataset_key, stateful_settings)
if not settings then
if server_name_matches then
Server.set_data(dataset, dataset_key, stateful_settings)
else
Server.set_data(dataset, dataset_key_dev, stateful_settings)
end
else
Server.set_data(dataset, dataset_key_dev, stateful_settings)
for k, v in pairs(settings) do
stateful_settings[k] = v
end
end
else
for k, v in pairs(settings) do
stateful_settings[k] = v
end
end
Public.stateful_on_server_started()
end
)
Public.stateful_on_server_started()
end
)
Event.add(
Server.events.on_server_started,
function()
function ()
local start_data = Server.get_start_data()
if not start_data.initialized then

View File

@@ -7,7 +7,7 @@ local this = {}
Global.register(
this,
function(t)
function (t)
this = t
end
)
@@ -50,7 +50,7 @@ local function create_particles(data)
frame_speed = 0.1,
vertical_speed = 0.1,
height = 0.1,
movement = {m2 - (random(0, m) * 0.01), m2 - (random(0, m) * 0.01)}
movement = { m2 - (random(0, m) * 0.01), m2 - (random(0, m) * 0.01) }
}
)
end
@@ -87,7 +87,7 @@ local function spawn_biters(data)
local unit_settings = Public.get('unit_settings')
local unit = surface.create_entity({name = unit_to_create, position = position})
local unit = surface.create_entity({ name = unit_to_create, position = position, force = data.force or 'enemy' })
if random(1, 30) == 1 then
BiterHealthBooster.add_boss_unit(unit, modified_boss_unit_health.current_value, 0.38)
@@ -98,6 +98,8 @@ local function spawn_biters(data)
end
BiterHealthBooster.add_unit(unit, final_health)
end
Event.raise(Public.events.on_entity_created, { entity = unit, boss_unit = false })
end
local function spawn_worms(data)
@@ -110,7 +112,7 @@ local function spawn_worms(data)
local unit_to_create = Public.wave_defense_roll_worm_name(sqrt(position.x ^ 2 + position.y ^ 2) * 0.20)
local unit = surface.create_entity({name = unit_to_create, position = position})
local unit = surface.create_entity({ name = unit_to_create, position = position })
local worm_unit_settings = Public.get('worm_unit_settings')
if random(1, 30) == 1 then
@@ -124,7 +126,7 @@ local function spawn_worms(data)
end
end
function Public.buried_biter(surface, position, max, entity_name)
function Public.buried_biter(surface, position, max, entity_name, force)
if not surface then
return
end
@@ -155,7 +157,7 @@ function Public.buried_biter(surface, position, max, entity_name)
this[game.tick + t][#this[game.tick + t] + 1] = {
callback = 'create_particles',
data = {surface = surface, position = {x = position.x, y = position.y}, amount = 4}
data = { surface = surface, position = { x = position.x, y = position.y }, amount = 4 }
}
if t > 90 then
@@ -163,7 +165,7 @@ function Public.buried_biter(surface, position, max, entity_name)
a = a + 1
this[game.tick + t][#this[game.tick + t] + 1] = {
callback = 'spawn_biters',
data = {surface = surface, position = {x = position.x, y = position.y}, entity_name = entity_name}
data = { surface = surface, position = { x = position.x, y = position.y }, entity_name = entity_name, force = force or 'enemy' }
}
if a >= max then
break
@@ -202,13 +204,13 @@ function Public.buried_worm(surface, position)
this[game.tick + t][#this[game.tick + t] + 1] = {
callback = 'create_particles',
data = {surface = surface, position = {x = position.x, y = position.y}, amount = 4}
data = { surface = surface, position = { x = position.x, y = position.y }, amount = 4 }
}
if not a then
this[game.tick + t][#this[game.tick + t] + 1] = {
callback = 'spawn_worms',
data = {surface = surface, position = {x = position.x, y = position.y}}
data = { surface = surface, position = { x = position.x, y = position.y } }
}
a = true
end

View File

@@ -6,8 +6,9 @@ Commands.new('wd_debug_module', 'Usable only for admins - controls wave defense
:require_admin()
:require_validation()
:add_parameter('skip/toggle_es/toggle_es_boss/spawn/next/next_50/next_1500/log_all/debug_health', false, 'string')
:add_parameter('state', true, 'boolean')
:callback(
function (player, action)
function (player, action, state)
if action == 'skip' then
Public.get('enable_grace_time').enabled = false
player.print(module_name .. ' grace skipped!')
@@ -15,13 +16,13 @@ Commands.new('wd_debug_module', 'Usable only for admins - controls wave defense
end
if action == 'toggle_es' then
Public.set_module_status()
Public.set_module_status(state or false)
player.print(module_name .. ' ES has been toggled!')
return true
end
if action == 'toggle_es_boss' then
Public.set_track_bosses_only()
Public.set_track_bosses_only(state or false)
player.print(module_name .. ' ES bosses has been toggled!')
return true
end

View File

@@ -22,7 +22,8 @@ local this = {
update_rate = 120,
enabled = true,
track_bosses_only = true,
wave_number = 0
wave_number = 0,
unit_limit = 300,
},
target_settings = {}
}
@@ -31,10 +32,10 @@ Public._esp = {}
Global.register(
this,
function(tbl)
function (tbl)
this = tbl
for _, state in pairs(this.states) do
setmetatable(state, {__index = Public._esp})
setmetatable(state, { __index = Public._esp })
end
end
)
@@ -66,59 +67,77 @@ local tiers = {
}
local tier_damage = {
['small-biter'] = {min = 25, max = 50},
['medium-biter'] = {min = 50, max = 100},
['big-biter'] = {min = 75, max = 150},
['behemoth-biter'] = {min = 100, max = 200},
['small-spitter'] = {min = 25, max = 50},
['medium-spitter'] = {min = 50, max = 100},
['big-spitter'] = {min = 75, max = 150},
['behemoth-spitter'] = {min = 100, max = 200}
['small-biter'] = { min = 25, max = 50 },
['medium-biter'] = { min = 50, max = 100 },
['big-biter'] = { min = 75, max = 150 },
['behemoth-biter'] = { min = 100, max = 200 },
['small-spitter'] = { min = 25, max = 50 },
['medium-spitter'] = { min = 50, max = 100 },
['big-spitter'] = { min = 75, max = 150 },
['behemoth-spitter'] = { min = 100, max = 200 }
}
local commands = {
['flee'] = 'goto',
['goto'] = 'attack_area',
['attack'] = 'attack',
['attack_area'] = 'attack_area',
}
--- A token to register tasks that entities are given
local work_token
work_token =
Token.register(
function(event)
if not event then
return
end
function (event)
if not event then
return
end
local state = Public.get_unit(event.unit_number)
local tick = game.tick
if not state then
return
end
local state = Public.get_unit(event.unit_number)
local tick = game.tick
if not state then
return
end
if state:validate() then
state:work(tick)
set_timeout_in_ticks(state:get_update_rate(), work_token, event)
else
state:remove()
if state:validate() then
state:work(tick)
state.command = commands[state.command]
set_timeout_in_ticks(state:get_update_rate(), work_token, event)
else
state:remove()
end
end
end
)
)
--- Restores a given entity to their original force
local restore_force_token =
Token.register(
function(event)
if not event then
return
end
local force_name = event.force_name
if not force_name then
return
end
function (event)
if not event then
return
end
local force_name = event.force_name
if not force_name then
return
end
local state = Public.get_unit(event.unit_number)
if state then
state:set_force()
state.frenzied = false
local state = Public.get_unit(event.unit_number)
if state then
state:set_force()
state.frenzied = false
end
end
)
local function has_unit_limit_reached()
local uid = Public.get_count()
if uid >= (this.settings.unit_limit and this.settings.unit_limit) then
Public.debug_print('has_unit_limit_reached - Max units reached?')
return true
end
)
return false
end
local function is_closer(pos1, pos2, pos)
return ((pos1.x - pos.x) ^ 2 + (pos1.y - pos.y) ^ 2) < ((pos2.x - pos.x) ^ 2 + (pos2.y - pos.y) ^ 2)
@@ -140,9 +159,9 @@ local function aoe_punch(entity, target, damage)
return
end
local base_vector = {target.position.x - entity.position.x, target.position.y - entity.position.y}
local base_vector = { target.position.x - entity.position.x, target.position.y - entity.position.y }
local vector = {base_vector[1], base_vector[2]}
local vector = { base_vector[1], base_vector[2] }
vector[1] = vector[1] * 1000
vector[2] = vector[2] * 1000
@@ -177,9 +196,9 @@ local function aoe_punch(entity, target, damage)
for i = 1, 16, 1 do
for x = i * -1 * a, i * a, 1 do
for y = i * -1 * a, i * a, 1 do
local p = {cp.x + x + vector[1] * i, cp.y + y + vector[2] * i}
cs.create_trivial_smoke({name = 'train-smoke', position = p})
for _, e in pairs(cs.find_entities({{p[1] - a, p[2] - a}, {p[1] + a, p[2] + a}})) do
local p = { cp.x + x + vector[1] * i, cp.y + y + vector[2] * i }
cs.create_trivial_smoke({ name = 'train-smoke', position = p })
for _, e in pairs(cs.find_entities({ { p[1] - a, p[2] - a }, { p[1] + a, p[2] + a } })) do
if e.valid then
if e.health then
if e.destructible and e.minable and not valid_enemy_forces[e.force.name] then
@@ -249,9 +268,9 @@ local function area_of_effect(entity, radius, callback, find_entities)
for y = area.left_top.y, area.right_bottom.y, 1 do
local d = floor((cp.x - x) ^ 2 + (cp.y - y) ^ 2)
if d < radius then
local p = {x = x, y = y}
local p = { x = x, y = y }
if find_entities then
for _, e in pairs(cs.find_entities({{p.x - 1, p.y - 1}, {p.x + 1, p.y + 1}})) do
for _, e in pairs(cs.find_entities({ { p.x - 1, p.y - 1 }, { p.x + 1, p.y + 1 } })) do
if e and e.valid and e.name ~= 'character' and e.health and e.destructible then
callback(e, p)
end
@@ -266,91 +285,10 @@ end
local function shoot_laser(surface, source, enemy)
local force = source.force
surface.create_entity {name = 'laser-beam', position = source.position, force = 'player', target = enemy, source = source, max_length = 32, duration = 60}
surface.create_entity { name = 'laser-beam', position = source.position, force = 'player', target = enemy, source = source, max_length = 32, duration = 60 }
enemy.damage(20 * (1 + force.get_ammo_damage_modifier('laser') + force.get_gun_speed_modifier('laser')), force, 'laser', source)
end
local function set_commands()
local unit = this.target_settings.main_target
if not unit or not unit.valid then
return
end
local commands = {}
if this.target_settings.last_set_target == 'main' then
this.target_settings.last_set_target = 'random'
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = {x = unit.position.x, y = unit.position.y},
radius = 15,
distraction = defines.distraction.by_enemy
}
commands[#commands + 1] = {
type = defines.command.build_base,
destination = {x = unit.position.x, y = unit.position.y}
}
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = {x = unit.position.x, y = unit.position.y},
radius = 15,
distraction = defines.distraction.by_enemy
}
commands[#commands + 1] = {
type = defines.command.build_base,
destination = {x = unit.position.x, y = unit.position.y}
}
else
commands[#commands + 1] = {
type = defines.command.attack,
target = unit,
distraction = defines.distraction.by_anything
}
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = {x = unit.position.x, y = unit.position.y},
radius = 15,
distraction = defines.distraction.by_enemy
}
commands[#commands + 1] = {
type = defines.command.build_base,
destination = {x = unit.position.x, y = unit.position.y}
}
commands[#commands + 1] = {
type = defines.command.attack,
target = unit,
distraction = defines.distraction.by_anything
}
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = {x = unit.position.x, y = unit.position.y},
radius = 15,
distraction = defines.distraction.by_enemy
}
commands[#commands + 1] = {
type = defines.command.build_base,
destination = {x = unit.position.x, y = unit.position.y}
}
commands[#commands + 1] = {
type = defines.command.attack,
target = unit,
distraction = defines.distraction.by_anything
}
this.target_settings.last_set_target = 'main'
end
local command = {
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
commands = commands
}
local surface = unit.surface
surface.set_multi_command({command = command, unit_count = 5000, force = 'aggressors'})
this.target_settings.commands = commands
end
local function set_forces()
local aggressors = game.forces.aggressors
local aggressors_frenzy = game.forces.aggressors_frenzy
@@ -380,11 +318,12 @@ end
local function on_init()
this.states = {}
this.settings.spawned_units = 0
this.settings.frenzy_length = 3600
this.settings.frenzy_burst_length = 160
this.settings.update_rate = 120
this.target_settings = {}
this.final_battle = false
this.settings.final_battle = false
set_forces()
end
@@ -457,18 +396,6 @@ local function on_target_aquired(event)
else
this.target_settings.main_target = event.target
end
local tick = game.tick
if not this.target_settings.last_set_commands then
set_commands()
this.target_settings.last_set_commands = tick + 200
this.target_settings.last_set_target = 'main'
end
if tick > this.target_settings.last_set_commands then
set_commands()
end
end
local function on_entity_created(event)
@@ -496,10 +423,13 @@ local function on_entity_created(event)
end
state:set_burst_frenzy()
state:set_boss()
else
entity.destroy()
end
else
state = Public.new(data)
if not state then
entity.destroy()
return
end
state:set_burst_frenzy()
@@ -565,6 +495,10 @@ local function on_entity_damaged(event)
state:spawn_children()
end
if random(1, 128) == 1 then
state:flee_command()
end
if state.boss_unit and entity.health <= max / 2 and state.teleported < 5 then
state.teleported = state.teleported + 1
if random(1, 4) == 1 then
@@ -577,13 +511,15 @@ end
---@param data table
---@return table|nil
function Public.new(data)
local uid = Public.get_count()
if uid > 200 then
if has_unit_limit_reached() then
if data.entity and data.entity.valid then
data.entity.destroy()
end
return
end
local state = setmetatable({}, {__index = Public._esp})
local uid = Public.get_count()
local state = setmetatable({}, { __index = Public._esp })
local tick = game.tick
state.entity = data.entity
state.surface_id = state.entity.surface_index
@@ -591,17 +527,13 @@ function Public.new(data)
state.unit_number = state.entity.unit_number
state.teleported = 0
state.uid = uid
state.command = 'goto'
state.id = state.entity.unit_number
state.update_rate = this.settings.update_rate + (10 * state.uid)
if data.delayed then
state.delayed = tick + data.delayed
state.ttl = data.ttl or (tick + data.delayed) + 7200 -- 2 minutes duration
else
state.ttl = data.ttl or tick + 3600 -- 1 minutes duration
state:validate()
end
state.ttl = data.ttl or tick + (5 * 3600) -- 5 minutes duration
state:validate()
set_timeout_in_ticks(state.update_rate, work_token, {unit_number = state.unit_number})
set_timeout_in_ticks(state.update_rate, work_token, { unit_number = state.unit_number })
this.states[state.id] = state
@@ -655,6 +587,22 @@ function Public.get_boss_unit()
end
end
-- Clears invalid units
---@return table|nil
function Public.check_states()
local c = 0
for _, state in pairs(this.states) do
if state then
if not (state.entity and state.entity.valid) then
state:remove()
else
c = c + 1
end
end
end
this.settings.spawned_units = c
end
-- Gets a boss unit
---@return integer
function Public.get_count()
@@ -665,6 +613,8 @@ function Public.get_count()
end
end
this.settings.spawned_units = c
return c
end
@@ -680,6 +630,10 @@ end
-- Removes the given entity from tracking
function Public._esp:remove()
if self.entity and self.entity.valid then
self.entity.destroy()
end
this.states[self.id] = nil
end
@@ -727,7 +681,7 @@ function Public._esp:set_burst_frenzy()
end
self.frenzied = true
set_timeout_in_ticks(this.settings.frenzy_burst_length, restore_force_token, {force_name = self.force.name, unit_number = self.unit_number})
set_timeout_in_ticks(this.settings.frenzy_burst_length, restore_force_token, { force_name = self.force.name, unit_number = self.unit_number })
entity.force = game.forces.aggressors_frenzy
self.force = entity.force
@@ -740,6 +694,10 @@ function Public._esp:spawn_children()
return
end
if has_unit_limit_reached() then
return
end
local tier = tiers[entity.name]
if not tier then
@@ -748,9 +706,9 @@ function Public._esp:spawn_children()
local max = entity.prototype.max_health
if entity.health <= max / 2 and not self.spawned_children then
if entity.health <= max / 4 and not self.spawned_children then
self.spawned_children = true
Public.buried_biter(entity.surface, entity.position, 1, tier)
Public.buried_biter(entity.surface, entity.position, 1, tier, entity.force.name)
end
end
@@ -789,7 +747,7 @@ function Public._esp:laser(boss)
local surface = entity.surface
local enemies = surface.find_entities_filtered {radius = 10, limit = limit, force = 'player', position = entity.position}
local enemies = surface.find_entities_filtered { radius = 10, limit = limit, force = 'player', position = entity.position }
if enemies == nil or #enemies == 0 then
return
end
@@ -808,9 +766,9 @@ function Public._esp:spew_damage()
return
end
local position = {entity.position.x + (-5 + random(0, 10)), entity.position.y + (-5 + random(0, 10))}
local position = { entity.position.x + (-5 + random(0, 10)), entity.position.y + (-5 + random(0, 10)) }
entity.surface.create_entity({name = 'acid-stream-spitter-medium', position = position, target = position, source = position})
entity.surface.create_entity({ name = 'acid-stream-spitter-medium', position = position, target = position, source = position })
end
--- Creates a projectile.
@@ -820,7 +778,7 @@ function Public._esp:fire_projectile()
return
end
local position = {entity.position.x + (-10 + random(0, 20)), entity.position.y + (-10 + random(0, 20))}
local position = { entity.position.x + (-10 + random(0, 20)), entity.position.y + (-10 + random(0, 20)) }
entity.surface.create_entity(
{
@@ -842,7 +800,7 @@ function Public._esp:aoe_attack()
return
end
local position = {x = entity.position.x + (-10 + random(0, 20)), y = entity.position.y + (-10 + random(0, 20))}
local position = { x = entity.position.x + (-10 + random(0, 20)), y = entity.position.y + (-10 + random(0, 20)) }
local target = {
valid = true,
@@ -867,7 +825,7 @@ function Public._esp:area_of_spit_attack(range)
area_of_effect(
entity,
range or 10,
function(p)
function (p)
do_projectile(entity.surface, 'acid-stream-spitter-big', p, entity.force, p)
end,
false
@@ -895,11 +853,11 @@ function Public._esp:find_targets()
local obstacles =
entity.surface.find_entities_filtered {
position = entity.position,
radius = step_length / 2,
type = {'simple-entity', 'tree'},
limit = 50
}
position = entity.position,
radius = step_length / 2,
type = { 'simple-entity', 'tree' },
limit = 50
}
if obstacles then
shuffle_distance(obstacles, entity.position)
self.commands = self.commands or {}
@@ -915,49 +873,6 @@ function Public._esp:find_targets()
end
end
--- Attack target
function Public._esp:attack_target()
local entity = self.entity
if not entity or not entity.valid then
return
end
local tick = game.tick
if not self.moving_to_attack_target then
self.moving_to_attack_target = 0
end
if tick < self.moving_to_attack_target then
return
end
self.moving_to_attack_target = tick + 200
if this.target_settings.commands and this.target_settings.commands.commands then
this.target_settings.commands = nil
return
end
if not this.target_settings.commands then
return
end
local compound_commands = this.target_settings.commands
if self.commands and next(self.commands) then
compound_commands = self.commands
end
local command = {
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
commands = compound_commands
}
pcall(entity.set_command, command)
self.commands = nil
end
-- Sets the attack speed for the given force
function Public._esp:set_attack_speed(speed)
if not speed then
@@ -982,7 +897,7 @@ function Public._esp:switch_position()
return
end
local position = {entity.position.x + (-5 + random(0, 15)), entity.position.y + (5 + random(0, 15))}
local position = { entity.position.x + (-5 + random(0, 15)), entity.position.y + (5 + random(0, 15)) }
local rand = entity.surface.find_non_colliding_position(entity.name, position, 0.2, 0.5)
if rand then
@@ -1018,7 +933,9 @@ function Public._esp:set_boss()
self.boss_unit = true
if this.final_battle then
self:set_ttl(game.tick + (20 * 3600))
if this.settings.final_battle then
self.go_havoc = true
self.proj_int = tick + 120
self.clear_go_havoc = tick + 3600
@@ -1033,21 +950,111 @@ function Public._esp:set_boss()
end
end
--- Sets the time to live timer for the unit
function Public._esp:set_ttl(ttl)
if not ttl then
error('No ttl given')
end
self.ttl = ttl
end
function Public._esp:go_to_location_command()
local unit = this.target_settings.main_target
if not unit or not unit.valid then
return
end
local entity = self.entity
if not entity or not entity.valid then
return
end
pcall(entity.set_command, {
type = defines.command.go_to_location,
destination_entity = unit,
radius = 3
})
end
function Public._esp:attack_command()
local unit = this.target_settings.main_target
if not unit or not unit.valid then
return
end
local entity = self.entity
if not entity or not entity.valid then
return
end
pcall(entity.set_command, {
type = defines.command.attack,
target = unit
})
end
function Public._esp:attack_area_command()
local unit = this.target_settings.main_target
if not unit or not unit.valid then
return
end
local entity = self.entity
if not entity or not entity.valid then
return
end
pcall(entity.set_command, {
type = defines.command.attack_area,
destination = { x = unit.position.x, y = unit.position.y },
radius = 15,
distraction = defines.distraction.by_anything
})
end
function Public._esp:flee_command()
local unit = this.target_settings.main_target
if not unit or not unit.valid then
return
end
local entity = self.entity
if not entity or not entity.valid then
return
end
pcall(entity.set_command, {
type = defines.command.flee,
from = unit,
})
end
function Public._esp:work(tick)
if self.go_frenzy then
self:set_frenzy()
end
if self.command == 'goto' then
self:go_to_location_command()
elseif self.command == 'attack' then
self:attack_command()
elseif self.command == 'attack_area' then
self:attack_area_command()
end
if self.go_havoc and self.clear_go_havoc > tick then
if tick > self.proj_int then
self:attack_target()
if tick < self.proj_int then
self:fire_projectile()
self.proj_int = tick + 120
end
return
end
self:attack_target()
if self.boss_unit then
if random(1, 20) == 1 then
@@ -1069,6 +1076,9 @@ function Public._esp:work(tick)
self:aoe_attack()
end
end
if tick > self.ttl then
self:remove()
end
elseif tick < self.ttl then
if random(1, 30) == 1 then
self:find_targets()
@@ -1084,15 +1094,6 @@ function Public._esp:work(tick)
end
end
Public.set_module_status = function()
on_init()
this.settings.enabled = not this.settings.enabled
end
Public.set_track_bosses_only = function()
this.settings.track_bosses_only = not this.settings.track_bosses_only
end
Event.on_init(on_init)
Event.add(de.on_entity_died, on_entity_died)
Event.add(de.on_entity_damaged, on_entity_damaged)
@@ -1102,6 +1103,7 @@ Event.add(ev.on_entity_created, on_entity_created)
Event.add(ev.on_target_aquired, on_target_aquired)
Event.add(ev.on_evolution_factor_changed, on_evolution_factor_changed)
Event.add(ev.on_game_reset, on_init)
Event.on_nth_tick(100, Public.check_states)
--- This gets values from our table
-- @param key <string>
@@ -1132,4 +1134,22 @@ function Public.set_es(key, value)
end
end
---@param value boolean
function Public.set_module_status(value)
on_init()
this.settings.enabled = value or false
end
---@param value boolean
function Public.set_track_bosses_only(value)
this.settings.track_bosses_only = value or false
end
---@param value integer|number
function Public.set_es_unit_limit(value)
this.settings.unit_limit = value or 300
end
Public.has_unit_limit_reached = has_unit_limit_reached
return Public

View File

@@ -25,11 +25,11 @@ local function normalize_spawn_position()
local collapse_spawn_position = Collapse.get_position()
local inverted = Public.get('inverted')
if inverted then
local new_pos = {x = 0, y = collapse_spawn_position.y + 40}
local new_pos = { x = 0, y = collapse_spawn_position.y + 40 }
Public.set_spawn_position(new_pos)
return new_pos
else
local new_pos = {x = 0, y = collapse_spawn_position.y - 40}
local new_pos = { x = 0, y = collapse_spawn_position.y - 40 }
Public.set_spawn_position(new_pos)
return new_pos
end
@@ -92,8 +92,8 @@ local function remove_trees(entity)
local surface = entity.surface
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'}
local area = { { pos.x - radius, pos.y - radius }, { pos.x + radius, pos.y + radius } }
local trees = surface.find_entities_filtered { area = area, type = 'tree' }
if #trees > 0 then
for _, tree in pairs(trees) do
if tree and tree.valid then
@@ -110,8 +110,8 @@ local function remove_rocks(entity)
local surface = entity.surface
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'}
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' }
if #rocks > 0 then
for _, rock in pairs(rocks) do
if rock and rock.valid then
@@ -136,11 +136,11 @@ local function fill_tiles(entity, size)
'deepwater',
'deepwater-green'
}
local area = {{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}}
local tiles = surface.find_tiles_filtered {area = area, name = t}
local area = { { pos.x - radius, pos.y - radius }, { pos.x + radius, pos.y + radius } }
local tiles = surface.find_tiles_filtered { area = area, name = t }
if #tiles > 0 then
for _, tile in pairs(tiles) do
surface.set_tiles({{name = 'sand-1', position = tile.position}}, true)
surface.set_tiles({ { name = 'sand-1', position = tile.position } }, true)
end
end
Public.debug_print('fill_tiles - filled tiles cause we found non-placable tiles.')
@@ -163,11 +163,11 @@ local function get_spawn_pos()
local inverted = Public.get('inverted')
if inverted then
if initial_position.y - target.position.y < -10 then
initial_position = {x = initial_position.x, y = initial_position.y + 50}
initial_position = { x = initial_position.x, y = initial_position.y + 50 }
end
else
if initial_position.y - target.position.y > 10 then
initial_position = {x = initial_position.x, y = initial_position.y - 50}
initial_position = { x = initial_position.x, y = initial_position.y - 50 }
end
end
@@ -188,9 +188,9 @@ local function get_spawn_pos()
c = c + 1
valid_position = Public.get('spawn_position')
Public.debug_print(serpent.block('valid_position - x:' .. valid_position.x .. ' y:' .. valid_position.y))
remove_trees({surface = surface, position = valid_position, valid = true})
remove_rocks({surface = surface, position = valid_position, valid = true})
fill_tiles({surface = surface, position = valid_position, valid = true})
remove_trees({ surface = surface, position = valid_position, valid = true })
remove_rocks({ surface = surface, position = valid_position, valid = true })
fill_tiles({ surface = surface, position = valid_position, valid = true })
Public.set('spot', 'nil')
if c == 5 then
return Public.debug_print('get_spawn_pos - we could not find a spawning pos?')
@@ -333,7 +333,7 @@ local function set_main_target()
local target = Public.get('target')
if target then
if target.valid then
raise(Public.events.on_target_aquired, {target = target})
raise(Public.events.on_target_aquired, { target = target })
return
end
end
@@ -349,12 +349,12 @@ local function set_main_target()
sec_target = get_random_character()
end
if not sec_target then
raise(Public.events.on_target_aquired, {target = target})
raise(Public.events.on_target_aquired, { target = target })
return
end
Public.set('target', sec_target)
raise(Public.events.on_target_aquired, {target = target})
raise(Public.events.on_target_aquired, { target = target })
Public.debug_print('set_main_target -- New main target ' .. sec_target.name .. ' at position x' .. sec_target.position.x .. ' y' .. sec_target.position.y .. ' selected.')
end
@@ -367,7 +367,7 @@ local function set_group_spawn_position(surface)
if not position then
return
end
Public.set('spawn_position', {x = position.x, y = position.y})
Public.set('spawn_position', { x = position.x, y = position.y })
local spawn_position = get_spawn_pos()
if spawn_position then
Public.debug_print('set_group_spawn_position -- Changed position to x' .. spawn_position.x .. ' y' .. spawn_position.y .. '.')
@@ -403,7 +403,7 @@ local function set_enemy_evolution()
enemy.evolution_factor = evolution_factor
raise(Public.events.on_evolution_factor_changed, {evolution_factor = evolution_factor})
raise(Public.events.on_evolution_factor_changed, { evolution_factor = evolution_factor })
end
local function can_units_spawn()
@@ -464,7 +464,7 @@ local function spawn_biter(surface, position, force_spawn, is_boss_biter, unit_s
if not force_spawn then
if not is_boss_biter then
if not can_units_spawn() then
return
return false
end
end
end
@@ -484,9 +484,9 @@ local function spawn_biter(surface, position, force_spawn, is_boss_biter, unit_s
if enable_random_spawn_positions then
if random(1, 3) == 1 then
position = {x = (-1 * (position.x + random(1, 10))), y = (position.y + random(1, 10))}
position = { x = (-1 * (position.x + random(1, 10))), y = (position.y + random(1, 10)) }
else
position = {x = (position.x + random(1, 10)), y = (position.y + random(1, 10))}
position = { x = (position.x + random(1, 10)), y = (position.y + random(1, 10)) }
end
end
@@ -502,10 +502,20 @@ local function spawn_biter(surface, position, force_spawn, is_boss_biter, unit_s
force = 'aggressors'
end
local biter = surface.create_entity({name = name, position = position, force = force})
-- biter.ai_settings.allow_destroy_when_commands_fail = true
-- biter.ai_settings.allow_try_return_to_spawner = false
-- biter.ai_settings.do_separation = true
local e = { name = name, position = position, force = force }
if not surface.can_place_entity(e) then
return false
end
local biter = surface.create_entity(e)
if not biter or not biter.valid then
return false
end
biter.ai_settings.allow_destroy_when_commands_fail = true
biter.ai_settings.allow_try_return_to_spawner = false
biter.ai_settings.do_separation = true
local increase_health_per_wave = Public.get('increase_health_per_wave')
local boost_units_when_wave_is_above = Public.get('boost_units_when_wave_is_above')
@@ -553,7 +563,7 @@ local function spawn_biter(surface, position, force_spawn, is_boss_biter, unit_s
generated_units.boss_units[#generated_units.boss_units + 1] = biter
else
generated_units.active_biters[biter.unit_number] = {entity = biter, spawn_tick = game.tick}
generated_units.active_biters[biter.unit_number] = { entity = biter, spawn_tick = game.tick }
end
local active_biter_count = Public.get('active_biter_count')
Public.set('active_biter_count', active_biter_count + 1)
@@ -573,9 +583,9 @@ local function spawn_worm(surface, position, is_boss_worm)
if enable_random_spawn_positions then
if random(1, 3) == 1 then
position = {x = (-1 * (position.x + random(1, 10))), y = (position.y + random(1, 10))}
position = { x = (-1 * (position.x + random(1, 10))), y = (position.y + random(1, 10)) }
else
position = {x = (position.x + random(1, 10)), y = (position.y + random(1, 10))}
position = { x = (position.x + random(1, 10)), y = (position.y + random(1, 10)) }
end
end
@@ -591,7 +601,7 @@ local function spawn_worm(surface, position, is_boss_worm)
force = 'aggressors'
end
local worm = surface.create_entity({name = name, position = position, force = force})
local worm = surface.create_entity({ name = name, position = position, force = force })
local increase_health_per_wave = Public.get('increase_health_per_wave')
local boost_units_when_wave_is_above = Public.get('boost_units_when_wave_is_above')
local boost_bosses_when_wave_is_above = Public.get('boost_bosses_when_wave_is_above')
@@ -757,7 +767,7 @@ local function set_next_wave()
local pos = {
position = spawn_position
}
Alert.alert_all_players_location(pos, msg, {r = 0.8, g = 0.1, b = 0.1})
Alert.alert_all_players_location(pos, msg, { r = 0.8, g = 0.1, b = 0.1 })
end
threat_gain = threat_gain * 2
else
@@ -792,12 +802,12 @@ end
local function reform_group(group)
local unit_group_command_step_length = Public.get('unit_group_command_step_length')
local group_position = {x = group.position.x, y = group.position.y}
local group_position = { x = group.position.x, y = group.position.y }
local step_length = unit_group_command_step_length
local generated_units = Public.get('generated_units')
local position = group.surface.find_non_colliding_position('biter-spawner', group_position, step_length, 4)
if position then
local new_group = group.surface.create_unit_group {position = position, force = group.force}
local new_group = group.surface.create_unit_group { position = position, force = group.force }
for _, biter in pairs(group.members) do
new_group.add_member(biter)
end
@@ -834,7 +844,7 @@ local function get_side_targets(group)
local search_side_targets = Public.get('search_side_targets')
local commands = {}
local group_position = {x = group.position.x, y = group.position.y}
local group_position = { x = group.position.x, y = group.position.y }
local step_length = unit_group_command_step_length
local side_target = Public.get_side_target()
@@ -849,11 +859,11 @@ local function get_side_targets(group)
local old_position = group_position
local obstacles =
group.surface.find_entities_filtered {
position = old_position,
radius = step_length * 2,
type = search_side_targets,
limit = 100
}
position = old_position,
radius = step_length * 2,
type = search_side_targets,
limit = 100
}
if obstacles then
for v = 1, #obstacles, 1 do
if obstacles[v].valid then
@@ -879,7 +889,7 @@ end
local function get_main_command(group)
local unit_group_command_step_length = Public.get('unit_group_command_step_length')
local commands = {}
local group_position = {x = group.position.x, y = group.position.y}
local group_position = { x = group.position.x, y = group.position.y }
local step_length = unit_group_command_step_length
local target = Public.get('target')
@@ -908,11 +918,11 @@ local function get_main_command(group)
group_position.y = group_position.y + vector[2]
local obstacles =
group.surface.find_entities_filtered {
position = old_position,
radius = step_length / 2,
type = {'simple-entity', 'tree'},
limit = 50
}
position = old_position,
radius = step_length / 2,
type = { 'simple-entity', 'tree' },
limit = 50
}
if obstacles then
shuffle_distance(obstacles, old_position)
for ii = 1, #obstacles, 1 do
@@ -929,7 +939,7 @@ local function get_main_command(group)
if position then
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = {x = position.x, y = position.y},
destination = { x = position.x, y = position.y },
radius = 16,
distraction = defines.distraction.by_anything
}
@@ -939,7 +949,7 @@ local function get_main_command(group)
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = {x = target_position.x, y = target_position.y},
destination = { x = target_position.x, y = target_position.y },
radius = 8,
distraction = defines.distraction.by_anything
}
@@ -1131,10 +1141,10 @@ local function spawn_unit_group(fs, only_bosses)
local radius = 10
local area = {
left_top = {spawn_position.x - radius, spawn_position.y - radius},
right_bottom = {spawn_position.x + radius, spawn_position.y + radius}
left_top = { spawn_position.x - radius, spawn_position.y - radius },
right_bottom = { spawn_position.x + radius, spawn_position.y + radius }
}
for _, v in pairs(surface.find_entities_filtered {area = area, name = 'land-mine'}) do
for _, v in pairs(surface.find_entities_filtered { area = area, name = 'land-mine' }) do
if v and v.valid then
Public.debug_print('spawn_unit_group - found land-mines')
v.die()
@@ -1142,9 +1152,9 @@ local function spawn_unit_group(fs, only_bosses)
end
if remove_entities and not (fs and fs.bypass) then
remove_trees({surface = surface, position = spawn_position, valid = true})
remove_rocks({surface = surface, position = spawn_position, valid = true})
fill_tiles({surface = surface, position = spawn_position, valid = true})
remove_trees({ surface = surface, position = spawn_position, valid = true })
remove_rocks({ surface = surface, position = spawn_position, valid = true })
fill_tiles({ surface = surface, position = spawn_position, valid = true })
end
local wave_number = Public.get('wave_number')
@@ -1163,12 +1173,12 @@ local function spawn_unit_group(fs, only_bosses)
local generated_units = Public.get('generated_units')
local unit_group = surface.create_unit_group({position = spawn_position, force = force})
local unit_group = surface.create_unit_group({ position = spawn_position, force = force })
event_data.unit_group = unit_group
generated_units.unit_group_pos.index = generated_units.unit_group_pos.index + 1
generated_units.unit_group_pos.positions[unit_group.group_number] = {position = unit_group.position, index = 0}
generated_units.unit_group_pos.positions[unit_group.group_number] = { position = unit_group.position, index = 0 }
local average_unit_group_size = Public.get('average_unit_group_size')
local unit_settings = Public.get('unit_settings')
event_data.unit_settings = unit_settings
@@ -1189,7 +1199,7 @@ local function spawn_unit_group(fs, only_bosses)
end
unit_group.add_member(biter)
raise(Public.events.on_entity_created, {entity = biter, boss_unit = false, target = target})
raise(Public.events.on_entity_created, { entity = biter, boss_unit = false })
-- command_to_side_target(unit_group)
end
end
@@ -1211,7 +1221,7 @@ local function spawn_unit_group(fs, only_bosses)
break
end
unit_group.add_member(biter)
raise(Public.events.on_entity_created, {entity = biter, boss_unit = true, target = target})
raise(Public.events.on_entity_created, { entity = biter, boss_unit = true })
end
Public.set('boss_wave', false)
end
@@ -1232,7 +1242,7 @@ local function spawn_unit_group(fs, only_bosses)
break
end
unit_group.add_member(biter)
raise(Public.events.on_entity_created, {entity = biter, boss_unit = true, target = target})
raise(Public.events.on_entity_created, { entity = biter, boss_unit = true })
end
end
@@ -1250,7 +1260,7 @@ end
local function spawn_unit_group_simple(fs)
local target = Public.get('target')
if not valid(target) then
Public.debug_print('spawn_unit_group - Target was not valid?')
Public.debug_print('spawn_unit_group_simple - Target was not valid?')
return
end
@@ -1266,7 +1276,6 @@ local function spawn_unit_group_simple(fs)
local wave_number = Public.get('wave_number')
Public.wave_defense_set_unit_raffle(wave_number)
local event_data = {}
local es_settings = Public.get_es('settings')
@@ -1277,20 +1286,13 @@ local function spawn_unit_group_simple(fs)
local generated_units = Public.get('generated_units')
local unit_group = surface.create_unit_group({position = spawn_position, force = force})
local unit_group = surface.create_unit_group({ position = spawn_position, force = force })
event_data.unit_group = unit_group
generated_units.unit_group_pos.index = generated_units.unit_group_pos.index + 1
generated_units.unit_group_pos.positions[unit_group.group_number] = {position = unit_group.position, index = 0}
local average_unit_group_size = Public.get('average_unit_group_size')
generated_units.unit_group_pos.positions[unit_group.group_number] = { position = unit_group.position, index = 0 }
local unit_settings = Public.get('unit_settings')
event_data.unit_settings = unit_settings
local group_size = floor(average_unit_group_size * Public.group_size_modifier_raffle[random(1, Public.group_size_modifier_raffle_size)])
event_data.group_size = group_size
event_data.boss_wave = false
if not es_settings.generated_units then
es_settings.generated_units = 0
@@ -1300,16 +1302,20 @@ local function spawn_unit_group_simple(fs)
end
local count = fs.scale or 1
event_data.spawn_count = count
local s = 0
for i = 1, count, 1 do
local is_boss = i % 2 == 0
local biter = spawn_biter(surface, spawn_position, fs, is_boss, unit_settings, final_battle)
if not biter then
Public.debug_print('spawn_unit_group - No biter was found?')
break
local is_boss = i % 4 == 0
local biter = spawn_biter(surface, spawn_position, fs and fs.bypass, is_boss, unit_settings, final_battle)
if biter then
s = s + 1
unit_group.add_member(biter)
raise(Public.events.on_entity_created, { entity = biter, boss_unit = is_boss })
end
unit_group.add_member(biter)
raise(Public.events.on_entity_created, {entity = biter, boss_unit = true, target = target})
end
if s == 0 then
Public.debug_print('spawn_unit_group - No biter was spawned?')
return
end
generated_units.unit_groups[unit_group.group_number] = unit_group
@@ -1318,8 +1324,6 @@ local function spawn_unit_group_simple(fs)
if random(1, 2) == 1 then
Public.set('random_group', unit_group)
end
Public.set('spot', 'nil')
raise(Public.events.on_unit_group_created, event_data)
return true
end
@@ -1381,7 +1385,7 @@ end
if is_loaded_bool('maps.mountain_fortress_v3.table') then
local Core = require 'maps.mountain_fortress_v3.core'
check_if_near_target = function(position)
check_if_near_target = function (position)
local entity = {
valid = true,
position = position
@@ -1396,7 +1400,7 @@ if is_loaded_bool('maps.mountain_fortress_v3.table') then
return false
end
else
check_if_near_target = function()
check_if_near_target = function ()
return false
end
end
@@ -1421,16 +1425,19 @@ Public.spawn_unit_group = spawn_unit_group
Event.on_nth_tick(
30,
function()
function ()
local tick = game.tick
local game_lost = Public.get('game_lost')
if game_lost then
return
end
local final_battle = Public.get('final_battle')
if final_battle then
return
end
local paused = Public.get('paused')
if paused and not final_battle then
if paused then
local players = game.connected_players
for _, player in pairs(players) do
Public.update_gui(player)
@@ -1462,10 +1469,6 @@ Event.on_nth_tick(
tick_tasks_t2[t2]()
end
if final_battle then
return
end
local players = game.connected_players
for _, player in pairs(players) do
Public.update_gui(player)
@@ -1475,9 +1478,9 @@ Event.on_nth_tick(
Event.add(
Public.events.on_biters_evolved,
function(event)
function (event)
if not event then
event = {force = game.forces.enemy}
event = { force = game.forces.enemy }
end
increase_biter_damage(event.force)
@@ -1493,12 +1496,13 @@ Event.add(Public.events.on_spawn_unit_group_simple, spawn_unit_group_simple)
Event.on_nth_tick(
50,
function()
function ()
local final_battle = Public.get('final_battle')
if final_battle then
return
end
local tick_to_spawn_unit_groups = Public.get('tick_to_spawn_unit_groups')
local tick = game.tick
local will_not_spawn = tick % tick_to_spawn_unit_groups ~= 0
@@ -1524,5 +1528,6 @@ Public.set_next_wave = set_next_wave
Public.normalize_spawn_position = normalize_spawn_position
Public.check_if_near_target = check_if_near_target
Public.spawn_worm = spawn_worm
Public.set_main_target = set_main_target
return Public

View File

@@ -4,7 +4,8 @@ local Gui = require 'utils.gui'
local Event = require 'utils.event'
local this = {
pause_waves_custom_callback = nil
pause_waves_custom_callback = nil,
threat_event_custom_callback = nil
}
local Public = {}
Public.events = {
@@ -22,28 +23,28 @@ local insert = table.insert
Global.register(
this,
function(tbl)
function (tbl)
this = tbl
end
)
Public.group_size_modifier_raffle = {}
local group_size_chances = {
{4, 0.4},
{5, 0.5},
{6, 0.6},
{7, 0.7},
{8, 0.8},
{9, 0.9},
{10, 1},
{9, 1.1},
{8, 1.2},
{7, 1.3},
{6, 1.4},
{5, 1.5},
{4, 1.6},
{3, 1.7},
{2, 1.8}
{ 4, 0.4 },
{ 5, 0.5 },
{ 6, 0.6 },
{ 7, 0.7 },
{ 8, 0.8 },
{ 9, 0.9 },
{ 10, 1 },
{ 9, 1.1 },
{ 8, 1.2 },
{ 7, 1.3 },
{ 6, 1.4 },
{ 5, 1.5 },
{ 4, 1.6 },
{ 3, 1.7 },
{ 2, 1.8 }
}
for _, v in pairs(group_size_chances) do
@@ -71,7 +72,7 @@ function Public.reset_wave_defense()
this.log_wave_to_discord = true
this.paused = false
this.pause_without_votes = true
this.pause_wave_in_ticks = 18000 -- 5 minutes
this.pause_wave_in_ticks = 18000 -- 5 minutes
this.next_pause_interval = game.tick + 216000 -- 1 hour
this.game_lost = false
this.get_random_close_spawner_attempts = 5
@@ -89,7 +90,7 @@ function Public.reset_wave_defense()
}
this.side_targets = {}
this.simple_entity_shredding_cost_modifier = 0.009
this.spawn_position = {x = 0, y = 64}
this.spawn_position = { x = 0, y = 64 }
this.spitter_raffle = {}
this.surface_index = 1
this.target = nil
@@ -103,7 +104,7 @@ function Public.reset_wave_defense()
this.random_group = nil
this.unit_group_command_delay = 3600 * 20
this.unit_group_command_step_length = 15
this.search_side_targets = {'simple-entity', 'tree', 'car', 'spider-vehicle', 'character'}
this.search_side_targets = { 'simple-entity', 'tree', 'car', 'spider-vehicle', 'character' }
this.wave_interval = 3600
this.wave_enforced = false
this.wave_number = 0
@@ -162,10 +163,10 @@ function Public.reset_wave_defense()
this.worm_unit_settings = {
-- note that final health modifier isn't lower than 1
scale_units_by_health = {
['land-mine'] = 0.5, -- not active as of now
['gun-turret'] = 0.5, -- not active as of now
['land-mine'] = 0.5, -- not active as of now
['gun-turret'] = 0.5, -- not active as of now
['flamethrower-turret'] = 0.4, -- not active as of now
['artillery-turret'] = 0.25, -- not active as of now
['artillery-turret'] = 0.25, -- not active as of now
['small-worm-turret'] = 0.8,
['medium-worm-turret'] = 0.6,
['big-worm-turret'] = 0.3,
@@ -438,7 +439,7 @@ end
function Public.nuke_wave_gui()
if Gui.get_mod_gui_top_frame() then
Core.iter_players(
function(player)
function (player)
local g = Gui.get_button_flow(player)['wave_defense']
if g and g.valid then
g.destroy()
@@ -447,7 +448,7 @@ function Public.nuke_wave_gui()
)
else
Core.iter_players(
function(player)
function (player)
if player.gui.top.wave_defense and player.gui.top.wave_defense.valid then
player.gui.top.wave_defense.destroy()
end
@@ -456,9 +457,9 @@ function Public.nuke_wave_gui()
end
end
--- Sets a custom callback whenever the pause_waves func is run
function Public.set_pause_waves_custom_callback(value)
this.pause_waves_custom_callback = value or nil
--- Sets a custom callback
function Public.set_pause_waves_custom_callback(callback)
this.pause_waves_custom_callback = callback or nil
end
--- Gets a custom callback
@@ -466,6 +467,16 @@ function Public.get_pause_waves_custom_callback()
return this.pause_waves_custom_callback or nil
end
--- Sets a custom callback
function Public.set_threat_event_custom_callback(callback)
this.threat_event_custom_callback = callback or nil
end
--- Gets a custom callback
function Public.get_threat_event_custom_callback()
return this.threat_event_custom_callback or nil
end
--- Toggle debug - when you need to troubleshoot.
-- @param <null>
function Public.toggle_debug()
@@ -505,7 +516,7 @@ end
-- Event.on_nth_tick(30, Public.debug_module)
Event.on_init(
function()
function ()
Public.reset_wave_defense()
end
)

View File

@@ -6,18 +6,17 @@ local Task = require 'utils.task'
local round = math.round
local random = math.random
local place_nest_near_unit_group
local immunity_spawner =
Token.register(
function(data)
local entity = data.entity
if not entity or not entity.valid then
return
function (data)
local entity = data.entity
if not entity or not entity.valid then
return
end
entity.destructible = true
end
entity.destructible = true
end
)
)
local function is_boss(entity)
local unit_number = entity.unit_number
@@ -63,156 +62,130 @@ local function remove_unit(entity)
end
end
if is_loaded_bool('maps.mountain_fortress_v3.table') then
local Core = require 'maps.mountain_fortress_v3.core'
place_nest_near_unit_group = function()
local random_group = Public.get('random_group')
if not (random_group and random_group.valid) then
return
end
local disable_spawn_near_target = Public.get('disable_spawn_near_target')
local generated_units = Public.get('generated_units')
local group = generated_units.unit_groups[random_group.group_number]
if not group then
return
end
if not group.valid then
return
end
if not group.members then
return
end
if not group.members[1] then
return
end
local unit = group.members[random(1, #group.members)]
if not unit.valid then
return
end
if Core.is_around_train(unit) and disable_spawn_near_target then
Public.debug_print('place_nest_near_unit_group - cannot spawn inside locomotive aura')
return
end
local name = 'biter-spawner'
if random(1, 3) == 1 then
name = 'spitter-spawner'
end
local position = unit.surface.find_non_colliding_position(name, unit.position, 12, 1)
if not position then
return
end
local r = Public.get('nest_building_density')
if
unit.surface.count_entities_filtered(
{
type = 'unit-spawner',
force = unit.force,
area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}
}
) > 0
then
return
end
local boss = is_boss(unit)
local modified_unit_health = Public.get('modified_unit_health')
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
local spawner = unit.surface.create_entity({name = name, position = position, force = unit.force})
spawner.destructible = false
local immunity_delay = random(100, 200)
Task.set_timeout_in_ticks(immunity_delay, immunity_spawner, {entity = spawner})
if boss then
BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health.current_value, 0.5)
else
BiterHealthBooster.add_unit(spawner, modified_unit_health.current_value)
end
generated_units.nests[#generated_units.nests + 1] = spawner
unit.surface.create_entity({name = 'blood-explosion-huge', position = position})
unit.surface.create_entity({name = 'blood-explosion-huge', position = unit.position})
remove_unit(unit)
unit.destroy()
local threat = Public.get('threat')
Public.set('threat', threat - Public.threat_values[name])
return true
local place_nest_near_unit_group = function ()
local random_group = Public.get('random_group')
if not (random_group and random_group.valid) then
return
end
else
place_nest_near_unit_group = function()
local random_group = Public.get('random_group')
if not (random_group and random_group.valid) then
return
end
local generated_units = Public.get('generated_units')
local group = generated_units.unit_groups[random_group.group_number]
if not group then
return
end
if not group.valid then
return
end
if not group.members then
return
end
if not group.members[1] then
return
end
local unit = group.members[random(1, #group.members)]
if not unit.valid then
return
end
local name = 'biter-spawner'
if random(1, 3) == 1 then
name = 'spitter-spawner'
end
local position = unit.surface.find_non_colliding_position(name, unit.position, 12, 1)
if not position then
return
end
local r = Public.get('nest_building_density')
if
unit.surface.count_entities_filtered(
{
type = 'unit-spawner',
force = unit.force,
area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}
}
) > 0
then
return
end
local disable_spawn_near_target = Public.get('disable_spawn_near_target')
local boss = is_boss(unit)
local modified_unit_health = Public.get('modified_unit_health')
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
local spawner = unit.surface.create_entity({name = name, position = position, force = unit.force})
spawner.destructible = false
Task.set_timeout_in_ticks(100, immunity_spawner, {entity = spawner})
if boss then
BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health.current_value, 0.5)
else
BiterHealthBooster.add_unit(spawner, modified_unit_health.current_value)
end
generated_units.nests[#generated_units.nests + 1] = spawner
unit.surface.create_entity({name = 'blood-explosion-huge', position = position})
unit.surface.create_entity({name = 'blood-explosion-huge', position = unit.position})
remove_unit(unit)
unit.destroy()
local threat = Public.get('threat')
Public.set('threat', threat - Public.threat_values[name])
return true
local generated_units = Public.get('generated_units')
local group = generated_units.unit_groups[random_group.group_number]
if not group then
return
end
if not group.valid then
return
end
if not group.members then
return
end
if not group.members[1] then
return
end
local unit = group.members[random(1, #group.members)]
if not unit.valid then
return
end
local custom_callback = Public.get('threat_event_custom_callback')
if custom_callback then
local cb = Task.get(custom_callback)
if cb then
local result = cb({ entity = unit, disable_spawn_near_target = disable_spawn_near_target })
if result then
Public.debug_print('place_nest_near_unit_group - custom callback returned true')
return
end
end
end
local name = 'biter-spawner'
if random(1, 3) == 1 then
name = 'spitter-spawner'
end
local position = unit.surface.find_non_colliding_position(name, unit.position, 12, 1)
if not position then
return
end
local r = Public.get('nest_building_density')
if
unit.surface.count_entities_filtered(
{
type = 'unit-spawner',
force = unit.force,
area = { { position.x - r, position.y - r }, { position.x + r, position.y + r } }
}
) > 0
then
return
end
local boss = is_boss(unit)
local modified_unit_health = Public.get('modified_unit_health')
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
local spawner = unit.surface.create_entity({ name = name, position = position, force = unit.force })
spawner.destructible = false
local immunity_delay = random(100, 200)
Task.set_timeout_in_ticks(immunity_delay, immunity_spawner, { entity = spawner })
if boss then
BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health.current_value, 0.5)
else
BiterHealthBooster.add_unit(spawner, modified_unit_health.current_value)
end
generated_units.nests[#generated_units.nests + 1] = spawner
unit.surface.create_entity({ name = 'blood-explosion-huge', position = position })
unit.surface.create_entity({ name = 'blood-explosion-huge', position = unit.position })
remove_unit(unit)
unit.destroy()
local threat = Public.get('threat')
Public.set('threat', threat - Public.threat_values[name])
return true
end
Public.place_custom_nest = function (surface, position, force)
local name = 'biter-spawner'
if random(1, 3) == 1 then
name = 'spitter-spawner'
end
if not position then
return
end
position = surface.find_non_colliding_position(name, position, 12, 1)
if not position then
return
end
local r = Public.get('nest_building_density')
if
surface.count_entities_filtered(
{
type = 'unit-spawner',
force = force,
area = { { position.x - r, position.y - r }, { position.x + r, position.y + r } }
}
) > 0
then
return
end
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
local spawner = surface.create_entity({ name = name, position = position, force = force })
spawner.destructible = false
local immunity_delay = random(100, 200)
Task.set_timeout_in_ticks(immunity_delay, immunity_spawner, { entity = spawner })
BiterHealthBooster.add_boss_unit(spawner, modified_boss_unit_health.current_value, 0.5)
surface.create_entity({ name = 'blood-explosion-huge', position = position })
surface.create_entity({ name = 'blood-explosion-huge', position = position })
end
function Public.build_nest()
@@ -293,13 +266,13 @@ function Public.build_worm()
{
type = 'turret',
force = unit.force,
area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}
area = { { position.x - r, position.y - r }, { position.x + r, position.y + r } }
}
) > 0
then
then
return
end
local u = unit.surface.create_entity({name = worm, position = position, force = unit.force})
local u = unit.surface.create_entity({ name = worm, position = position, force = unit.force })
local worm_unit_settings = Public.get('worm_unit_settings')
local modified_unit_health = Public.get('modified_unit_health')
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
@@ -314,8 +287,8 @@ function Public.build_worm()
BiterHealthBooster.add_unit(u, final_health)
end
unit.surface.create_entity({name = 'blood-explosion-huge', position = position})
unit.surface.create_entity({name = 'blood-explosion-huge', position = unit.position})
unit.surface.create_entity({ name = 'blood-explosion-huge', position = position })
unit.surface.create_entity({ name = 'blood-explosion-huge', position = unit.position })
remove_unit(unit)
unit.destroy()
Public.set('threat', threat - Public.threat_values[worm])
@@ -364,21 +337,21 @@ function Public.build_worm_custom()
{
type = 'turret',
force = unit.force,
area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}
area = { { position.x - r, position.y - r }, { position.x + r, position.y + r } }
}
) > 0
then
then
return
end
local u = unit.surface.create_entity({name = worm, position = position, force = unit.force})
local u = unit.surface.create_entity({ name = worm, position = position, force = unit.force })
local modified_boss_unit_health = Public.get('modified_boss_unit_health')
BiterHealthBooster.add_boss_unit(u, modified_boss_unit_health.current_value, 0.5)
table.remove(group, generated_units.boss_unit_index)
unit.surface.create_entity({name = 'blood-explosion-huge', position = position})
unit.surface.create_entity({name = 'blood-explosion-huge', position = unit.position})
unit.surface.create_entity({ name = 'blood-explosion-huge', position = position })
unit.surface.create_entity({ name = 'blood-explosion-huge', position = unit.position })
remove_unit(unit)
unit.destroy()
end
@@ -390,14 +363,14 @@ local function shred_simple_entities(entity)
end
local simple_entities =
entity.surface.find_entities_filtered(
{
type = 'simple-entity',
area = {
{entity.position.x - 3, entity.position.y - 3},
{entity.position.x + 3, entity.position.y + 3}
{
type = 'simple-entity',
area = {
{ entity.position.x - 3, entity.position.y - 3 },
{ entity.position.x + 3, entity.position.y + 3 }
}
}
}
)
)
if #simple_entities == 0 then
return
end
@@ -444,7 +417,7 @@ local function spawn_unit_spawner_inhabitants(entity)
end
Public.wave_defense_set_unit_raffle(wave_number)
for _ = 1, count, 1 do
local position = {entity.position.x + (-4 + math.random(0, 8)), entity.position.y + (-4 + math.random(0, 8))}
local position = { entity.position.x + (-4 + math.random(0, 8)), entity.position.y + (-4 + math.random(0, 8)) }
if math.random(1, 4) == 1 then
entity.surface.create_entity(
{

View File

@@ -388,6 +388,8 @@ function Public.new(name, help)
error('Command already exists: ' .. name, 2)
end
if game then error('Cannot run new() when game is initialized : ' .. name, 2) end
local command =
setmetatable(
{
@@ -549,4 +551,24 @@ function Public:callback(func)
end
end
Public.new('get', 'Hover over an object to get its name.')
:require_admin()
:callback(
function (player)
local entity = player.selected
if not entity or not entity.valid then
return false
end
player.print('[color=orange]Name:[/color] ' .. entity.name)
player.print('[color=orange]Type:[/color] ' .. entity.type)
player.print('[color=orange]Force:[/color] ' .. entity.force.name)
player.print('[color=orange]Destructible:[/color] ' .. (entity.destructible and 'true' or 'false'))
player.print('[color=orange]Minable:[/color] ' .. (entity.minable and 'true' or 'false'))
player.print('[color=orange]Unit Number:[/color] ' .. (entity.unit_number or 'nil'))
player.print('[color=orange]Position:[/color] ' .. serpent.line(entity.position))
return true
end
)
return Public

View File

@@ -666,6 +666,7 @@ local function jail(player, offender, msg, raised, mute)
votejail[offender].jailed = true
end
-- Enable this to clear the console for the jailed player
to_jail_player.clear_console()
Utils.print_to(offender, message)
return true

View File

@@ -33,7 +33,7 @@ local this = {
Global.register(
this,
function(tbl)
function (tbl)
this = tbl
end
)
@@ -63,29 +63,29 @@ end
local delayed_last_page_token =
Task.register(
function(event)
local player_index = event.player_index
local player = game.get_player(player_index)
if not player or not player.valid then
return
end
function (event)
local player_index = event.player_index
local player = game.get_player(player_index)
if not player or not player.valid then
return
end
local element = event.element
if not element or not element.valid then
return
end
local element = event.element
if not element or not element.valid then
return
end
local player_data = get_player_data(player)
if not player_data or not player_data.table_count then
return
end
local last_page = ceil(player_data.table_count / rows_per_page)
local player_data = get_player_data(player)
if not player_data or not player_data.table_count then
return
end
local last_page = ceil(player_data.table_count / rows_per_page)
player_data.current_page = last_page
local data = {player = player, frame = element}
create_admin_panel(data)
end
)
player_data.current_page = last_page
local data = { player = player, frame = element }
create_admin_panel(data)
end
)
local function clear_validation_action(player_name, action)
local admin_button_validation = AntiGrief.get('admin_button_validation')
@@ -96,22 +96,22 @@ end
local clear_validation_token =
Token.register(
function(event)
local action = event.action
if not action then
return
end
local player_name = event.player_name
if not player_name then
return
end
function (event)
local action = event.action
if not action then
return
end
local player_name = event.player_name
if not player_name then
return
end
local admin_button_validation = AntiGrief.get('admin_button_validation')
if admin_button_validation and admin_button_validation[action] then
admin_button_validation[action][player_name] = nil
local admin_button_validation = AntiGrief.get('admin_button_validation')
if admin_button_validation and admin_button_validation[action] then
admin_button_validation[action][player_name] = nil
end
end
end
)
)
local function validate_action(player, action)
local admin_button_validation = AntiGrief.get('admin_button_validation')
@@ -121,7 +121,7 @@ local function validate_action(player, action)
if not admin_button_validation[action][player.name] then
admin_button_validation[action][player.name] = true
Task.set_timeout_in_ticks(100, clear_validation_token, {player_name = player.name, action = action})
Task.set_timeout_in_ticks(200, clear_validation_token, { player_name = player.name, action = action })
player.print('Please run this again if you are certain that you want to run this action[' .. action .. '].', Color.warning)
return true
end
@@ -131,7 +131,7 @@ end
local function admin_only_message(str)
for _, player in pairs(game.connected_players) do
if player.admin == true then
player.print('Admins-only-message: ' .. str, {r = 0.88, g = 0.88, b = 0.88})
player.print('Admins-only-message: ' .. str, { r = 0.88, g = 0.88, b = 0.88 })
end
end
end
@@ -142,7 +142,7 @@ local function jail(player, source_player)
end
if player.name == source_player.name then
player.print("You can't select yourself!", {r = 1, g = 0.5, b = 0.1})
player.print("You can't select yourself!", { r = 1, g = 0.5, b = 0.1 })
clear_validation_action(source_player.name, 'jail')
return
end
@@ -150,13 +150,34 @@ local function jail(player, source_player)
clear_validation_action(source_player.name, 'jail')
end
local function clear_biters(player)
if validate_action(player, 'clear_biters') then
return
end
local surface = player.surface
local count = 0
for c in surface.get_chunks() do
for _, entity in pairs(surface.find_entities_filtered({ area = { { c.x * 32, c.y * 32 }, { c.x * 32 + 32, c.y * 32 + 32 } }, type = "unit" })) do
if entity and entity.valid then
entity.destroy()
count = count + 1
end
end
end
player.print('Cleared: ' .. count .. ' biters.', Color.warning)
clear_validation_action(player.name, 'clear_biters')
end
local function mute(player, source_player)
if validate_action(source_player, 'mute') then
return
end
if player.name == source_player.name then
player.print("You can't select yourself!", {r = 1, g = 0.5, b = 0.1})
player.print("You can't select yourself!", { r = 1, g = 0.5, b = 0.1 })
clear_validation_action(source_player.name, 'mute')
return
end
@@ -164,7 +185,7 @@ local function mute(player, source_player)
local muted = Jailed.mute_player(player)
local muted_str = muted and 'muted' or 'unmuted'
clear_validation_action(source_player.name, 'jail')
game.print(player.name .. ' was ' .. muted_str .. ' by player ' .. source_player.name .. '!', {r = 1, g = 0.5, b = 0.1})
game.print(player.name .. ' was ' .. muted_str .. ' by player ' .. source_player.name .. '!', { r = 1, g = 0.5, b = 0.1 })
end
local function free(player, source_player)
@@ -173,7 +194,7 @@ local function free(player, source_player)
end
if player.name == source_player.name then
player.print("You can't select yourself!", {r = 1, g = 0.5, b = 0.1})
player.print("You can't select yourself!", { r = 1, g = 0.5, b = 0.1 })
clear_validation_action(source_player.name, 'free')
return
end
@@ -193,19 +214,19 @@ local function bring_player(player, source_player)
end
if player.name == source_player.name then
player.print("You can't select yourself!", {r = 1, g = 0.5, b = 0.1})
player.print("You can't select yourself!", { r = 1, g = 0.5, b = 0.1 })
clear_validation_action(source_player.name, 'bring_player')
return
end
if player.driving == true then
source_player.print('Target player is in a vehicle, teleport not available.', {r = 0.88, g = 0.88, b = 0.88})
source_player.print('Target player is in a vehicle, teleport not available.', { r = 0.88, g = 0.88, b = 0.88 })
clear_validation_action(source_player.name, 'bring_player')
return
end
local pos = source_player.surface.find_non_colliding_position('character', source_player.position, 50, 1)
if pos then
player.teleport(pos, source_player.surface)
game.print(player.name .. ' has been teleported to ' .. source_player.name .. '. ' .. bring_player_messages[math.random(1, #bring_player_messages)], {r = 0.98, g = 0.66, b = 0.22})
game.print(player.name .. ' has been teleported to ' .. source_player.name .. '. ' .. bring_player_messages[math.random(1, #bring_player_messages)], { r = 0.98, g = 0.66, b = 0.22 })
clear_validation_action(source_player.name, 'bring_player')
end
end
@@ -220,29 +241,29 @@ local function go_to_player(player, source_player)
end
if player.name == source_player.name then
player.print("You can't select yourself!", {r = 1, g = 0.5, b = 0.1})
player.print("You can't select yourself!", { r = 1, g = 0.5, b = 0.1 })
clear_validation_action(source_player.name, 'go_to_player')
return
end
local pos = player.surface.find_non_colliding_position('character', player.position, 50, 1)
if pos then
source_player.teleport(pos, player.surface)
game.print(source_player.name .. ' is visiting ' .. player.name .. '. ' .. go_to_player_messages[math.random(1, #go_to_player_messages)], {r = 0.98, g = 0.66, b = 0.22})
game.print(source_player.name .. ' is visiting ' .. player.name .. '. ' .. go_to_player_messages[math.random(1, #go_to_player_messages)], { r = 0.98, g = 0.66, b = 0.22 })
clear_validation_action(source_player.name, 'go_to_player')
end
end
local function spank(player, source_player)
if player.name == source_player.name then
return player.print("You can't select yourself!", {r = 1, g = 0.5, b = 0.1})
return player.print("You can't select yourself!", { r = 1, g = 0.5, b = 0.1 })
end
if player.character then
if player.character.health > 1 then
player.character.damage(1, 'player')
end
player.character.health = player.character.health - 5
player.surface.create_entity({name = 'water-splash', position = player.position})
game.print(source_player.name .. ' spanked ' .. player.name, {r = 0.98, g = 0.66, b = 0.22})
player.surface.create_entity({ name = 'water-splash', position = player.position })
game.print(source_player.name .. ' spanked ' .. player.name, { r = 0.98, g = 0.66, b = 0.22 })
end
end
@@ -252,15 +273,15 @@ local damage_messages = {
}
local function damage(player, source_player)
if player.name == source_player.name then
return player.print("You can't select yourself!", {r = 1, g = 0.5, b = 0.1})
return player.print("You can't select yourself!", { r = 1, g = 0.5, b = 0.1 })
end
if player.character then
if player.character.health > 1 then
player.character.damage(1, 'player')
end
player.character.health = player.character.health - 125
player.surface.create_entity({name = 'big-explosion', position = player.position})
game.print(player.name .. damage_messages[math.random(1, #damage_messages)] .. source_player.name, {r = 0.98, g = 0.66, b = 0.22})
player.surface.create_entity({ name = 'big-explosion', position = player.position })
game.print(player.name .. damage_messages[math.random(1, #damage_messages)] .. source_player.name, { r = 0.98, g = 0.66, b = 0.22 })
end
end
@@ -276,13 +297,13 @@ local function kill(player, source_player)
return
end
if player.name == source_player.name then
player.print("You can't select yourself!", {r = 1, g = 0.5, b = 0.1})
player.print("You can't select yourself!", { r = 1, g = 0.5, b = 0.1 })
clear_validation_action(source_player.name, 'kill')
return
end
if player.character then
player.character.die('player')
game.print(player.name .. kill_messages[math.random(1, #kill_messages)], {r = 0.98, g = 0.66, b = 0.22})
game.print(player.name .. kill_messages[math.random(1, #kill_messages)], { r = 0.98, g = 0.66, b = 0.22 })
admin_only_message(source_player.name .. ' killed ' .. player.name)
clear_validation_action(source_player.name, 'kill')
end
@@ -298,7 +319,7 @@ local function enemy(player, source_player)
end
if player.name == source_player.name then
player.print("You can't select yourself!", {r = 1, g = 0.5, b = 0.1})
player.print("You can't select yourself!", { r = 1, g = 0.5, b = 0.1 })
clear_validation_action(source_player.name, 'enemy')
return
end
@@ -306,7 +327,7 @@ local function enemy(player, source_player)
game.create_force('enemy_players')
end
player.force = game.forces.enemy_players
game.print(player.name .. ' is now an enemy! ' .. enemy_messages[math.random(1, #enemy_messages)], {r = 0.95, g = 0.15, b = 0.15})
game.print(player.name .. ' is now an enemy! ' .. enemy_messages[math.random(1, #enemy_messages)], { r = 0.95, g = 0.15, b = 0.15 })
admin_only_message(source_player.name .. ' has turned ' .. player.name .. ' into an enemy')
clear_validation_action(source_player.name, 'enemy')
end
@@ -317,12 +338,12 @@ local function ally(player, source_player)
end
if player.name == source_player.name then
player.print("You can't select yourself!", {r = 1, g = 0.5, b = 0.1})
player.print("You can't select yourself!", { r = 1, g = 0.5, b = 0.1 })
clear_validation_action(source_player.name, 'ally')
return
end
player.force = game.forces.player
game.print(player.name .. ' is our ally again!', {r = 0.98, g = 0.66, b = 0.22})
game.print(player.name .. ' is our ally again!', { r = 0.98, g = 0.66, b = 0.22 })
admin_only_message(source_player.name .. ' made ' .. player.name .. ' our ally')
clear_validation_action(source_player.name, 'ally')
end
@@ -334,10 +355,10 @@ local function turn_off_global_speakers(player)
local counter = 0
for _, surface in pairs(game.surfaces) do
local speakers = surface.find_entities_filtered({name = 'programmable-speaker'})
local speakers = surface.find_entities_filtered({ name = 'programmable-speaker' })
for _, speaker in pairs(speakers) do
if speaker.parameters.playback_globally == true then
speaker.surface.create_entity({name = 'massive-explosion', position = speaker.position})
speaker.surface.create_entity({ name = 'massive-explosion', position = speaker.position })
speaker.destroy()
counter = counter + 1
end
@@ -347,9 +368,9 @@ local function turn_off_global_speakers(player)
return
end
if counter == 1 then
game.print(player.name .. ' has nuked ' .. counter .. ' global speaker.', {r = 0.98, g = 0.66, b = 0.22})
game.print(player.name .. ' has nuked ' .. counter .. ' global speaker.', { r = 0.98, g = 0.66, b = 0.22 })
else
game.print(player.name .. ' has nuked ' .. counter .. ' global speakers.', {r = 0.98, g = 0.66, b = 0.22})
game.print(player.name .. ' has nuked ' .. counter .. ' global speakers.', { r = 0.98, g = 0.66, b = 0.22 })
end
clear_validation_action(player.name, 'turn_off_global_speakers')
end
@@ -361,7 +382,7 @@ local function delete_all_blueprints(player)
local counter = 0
for _, surface in pairs(game.surfaces) do
for _, ghost in pairs(surface.find_entities_filtered({type = {'entity-ghost', 'tile-ghost'}})) do
for _, ghost in pairs(surface.find_entities_filtered({ type = { 'entity-ghost', 'tile-ghost' } })) do
ghost.destroy()
counter = counter + 1
end
@@ -371,9 +392,9 @@ local function delete_all_blueprints(player)
return
end
if counter == 1 then
game.print(counter .. ' blueprint has been cleared!', {r = 0.98, g = 0.66, b = 0.22})
game.print(counter .. ' blueprint has been cleared!', { r = 0.98, g = 0.66, b = 0.22 })
else
game.print(counter .. ' blueprints have been cleared!', {r = 0.98, g = 0.66, b = 0.22})
game.print(counter .. ' blueprints have been cleared!', { r = 0.98, g = 0.66, b = 0.22 })
end
local server_name = Server.get_server_name() or 'CommandHandler'
Discord.send_notification_raw(server_name, player.name .. ' cleared all the blueprints on the map.')
@@ -389,7 +410,7 @@ local function pause_game_tick(player)
local paused = game.tick_paused
local paused_str = paused and 'unpaused' or 'paused'
game.tick_paused = not paused
game.print('Game has been ' .. paused_str .. ' by ' .. player.name, {r = 0.98, g = 0.66, b = 0.22})
game.print('Game has been ' .. paused_str .. ' by ' .. player.name, { r = 0.98, g = 0.66, b = 0.22 })
local server_name = Server.get_server_name() or 'CommandHandler'
Discord.send_notification_raw(server_name, player.name .. ' ' .. paused_str .. ' the game.')
clear_validation_action(player.name, 'pause_game_tick')
@@ -411,7 +432,7 @@ local function clear_items_on_ground(player)
end
local i = 0
for _, entity in pairs(player.surface.find_entities_filtered {type = 'item-entity', name = 'item-on-ground'}) do
for _, entity in pairs(player.surface.find_entities_filtered { type = 'item-entity', name = 'item-on-ground' }) do
if entity and entity.valid then
entity.destroy()
i = i + 1
@@ -429,7 +450,7 @@ local function create_mini_camera_gui(player, caption, position, surface)
if player.gui.center['mini_camera'] then
player.gui.center['mini_camera'].destroy()
end
local frame = player.gui.center.add({type = 'frame', name = 'mini_camera', caption = caption})
local frame = player.gui.center.add({ type = 'frame', name = 'mini_camera', caption = caption })
surface = tonumber(surface)
surface = game.surfaces[surface]
if not surface or not surface.valid then
@@ -438,14 +459,14 @@ local function create_mini_camera_gui(player, caption, position, surface)
local camera =
frame.add(
{
type = 'camera',
name = 'mini_cam_element',
position = position,
zoom = 0.6,
surface_index = surface.index
}
)
{
type = 'camera',
name = 'mini_cam_element',
position = position,
zoom = 0.6,
surface_index = surface.index
}
)
camera.style.minimal_width = 640
camera.style.minimal_height = 480
end
@@ -555,14 +576,14 @@ local function draw_events(player_data)
else
scroll_pane =
frame.add(
{
type = 'scroll-pane',
name = 'datalog',
direction = 'vertical',
horizontal_scroll_policy = 'never',
vertical_scroll_policy = 'auto'
}
)
{
type = 'scroll-pane',
name = 'datalog',
direction = 'vertical',
horizontal_scroll_policy = 'never',
vertical_scroll_policy = 'auto'
}
)
scroll_pane.style.maximal_height = 200
scroll_pane.style.minimal_width = 790
end
@@ -570,7 +591,7 @@ local function draw_events(player_data)
search_text_locally(
history,
player_data,
function(history_label, tooltip)
function (history_label, tooltip)
if not history_label then
return
end
@@ -624,7 +645,7 @@ local function text_changed(event)
player_data.search_text = nil
local last_page = ceil(player_data.table_count / rows_per_page)
player_data.current_page = last_page
local data = {player = player, frame = frame}
local data = { player = player, frame = frame }
create_admin_panel(data)
return
end
@@ -650,36 +671,36 @@ local function create_pagination_buttons(player_data, frame, table_count)
local button_flow =
frame.add {
type = 'flow',
direction = 'horizontal'
}
type = 'flow',
direction = 'horizontal'
}
local prev_button =
button_flow.add {
type = 'button',
name = prev_button_name,
caption = '◀️',
style = 'back_button'
}
type = 'button',
name = prev_button_name,
caption = '◀️',
style = 'back_button'
}
prev_button.style.font = 'default-bold'
prev_button.style.minimal_width = 32
prev_button.tooltip = 'Previous page\nHolding [color=yellow]shift[/color] while pressing LMB/RMB will jump to the first page.'
local count_label =
button_flow.add {
type = 'label',
name = count_label_name,
caption = current_page .. '/' .. last_page
}
type = 'label',
name = count_label_name,
caption = current_page .. '/' .. last_page
}
count_label.style.font = 'default-bold'
player_data.count_label = count_label
local next_button =
button_flow.add {
type = 'button',
name = next_button_name,
caption = '▶️',
style = 'forward_button'
}
type = 'button',
name = next_button_name,
caption = '▶️',
style = 'forward_button'
}
next_button.style.font = 'default-bold'
next_button.style.minimal_width = 32
next_button.tooltip = 'Next page\nHolding [color=yellow]shift[/color] while pressing LMB/RMB will jump to the last page.'
@@ -687,7 +708,7 @@ local function create_pagination_buttons(player_data, frame, table_count)
player_data.table_count = table_count
end
create_admin_panel = function(data)
create_admin_panel = function (data)
local player = data.player
local frame = data.frame
local antigrief = AntiGrief.get()
@@ -726,14 +747,14 @@ create_admin_panel = function(data)
checkbox_caption = 'Currently showing: all players that have played on this server.'
end
frame.add({type = 'checkbox', name = listable_players_name, caption = checkbox_caption, state = checkbox_state or false})
frame.add({ type = 'checkbox', name = listable_players_name, caption = checkbox_caption, state = checkbox_state or false })
local drop_down = frame.add({type = 'drop-down', name = 'admin_player_select', items = player_names, selected_index = selected_index})
local drop_down = frame.add({ type = 'drop-down', name = 'admin_player_select', items = player_names, selected_index = selected_index })
drop_down.style.minimal_width = 326
drop_down.style.right_padding = 12
drop_down.style.left_padding = 12
local t = frame.add({type = 'table', column_count = 4})
local t = frame.add({ type = 'table', column_count = 4 })
local buttons = {
t.add(
{
@@ -751,7 +772,7 @@ create_admin_panel = function(data)
tooltip = 'Jails and mutes the player, they will no longer be able to chat.'
}
),
t.add({type = 'button', caption = 'Free', name = 'free', tooltip = 'Frees the player from jail.'}),
t.add({ type = 'button', caption = 'Free', name = 'free', tooltip = 'Frees the player from jail.' }),
t.add(
{
type = 'button',
@@ -800,7 +821,7 @@ create_admin_panel = function(data)
tooltip = 'Damages the selected player with greater damage.\nCan not kill the player.'
}
),
t.add({type = 'button', caption = 'Kill', name = 'kill', tooltip = 'Kills the selected player instantly.'})
t.add({ type = 'button', caption = 'Kill', name = 'kill', tooltip = 'Kills the selected player instantly.' })
}
for _, button in pairs(buttons) do
button.style.font = 'default-bold'
@@ -808,12 +829,12 @@ create_admin_panel = function(data)
button.style.minimal_width = 106
end
local line = frame.add {type = 'line'}
local line = frame.add { type = 'line' }
line.style.top_margin = 8
line.style.bottom_margin = 8
frame.add({type = 'label', caption = 'Global Actions:'})
local actionTable = frame.add({type = 'table', column_count = 4})
frame.add({ type = 'label', caption = 'Global Actions:' })
local actionTable = frame.add({ type = 'table', column_count = 4 })
local bottomButtons = {
actionTable.add(
{
@@ -854,6 +875,14 @@ create_admin_panel = function(data)
name = 'clear_items_on_ground',
tooltip = 'Clears all items on the ground.\nThis might lag the game!'
}
),
actionTable.add(
{
type = 'button',
caption = 'Remove biters',
name = 'clear_biters',
tooltip = 'Clears out all biters (friendly and enemy).\nThis might lag the game!'
}
)
--- t.add({type = "button", caption = "Cancel all deconstruction orders", name = "remove_all_deconstruction_orders"})
}
@@ -862,7 +891,7 @@ create_admin_panel = function(data)
button.style.minimal_width = 80
end
local bottomLine = frame.add {type = 'line'}
local bottomLine = frame.add { type = 'line' }
bottomLine.style.top_margin = 8
bottomLine.style.bottom_margin = 8
@@ -905,34 +934,34 @@ create_admin_panel = function(data)
return
end
local search_table = frame.add({type = 'table', column_count = 3})
search_table.add({type = 'label', caption = 'Search: '})
local search_text = search_table.add({type = 'textfield'})
local search_table = frame.add({ type = 'table', column_count = 3 })
search_table.add({ type = 'label', caption = 'Search: ' })
local search_text = search_table.add({ type = 'textfield' })
search_text.text = player_data.search_text or ''
search_text.style.width = 140
local btn =
search_table.add {
type = 'sprite-button',
tooltip = '[color=blue]Info![/color]\nSearching does not filter the amount of pages shown.\nThis is a limitation in the Factorio engine.\nIterating over the whole table would lag the game.\nSo when searching, you will still see the same amount of pages.\nAnd the results will be "janky".',
sprite = 'utility/questionmark'
}
type = 'sprite-button',
tooltip = '[color=blue]Info![/color]\nSearching does not filter the amount of pages shown.\nThis is a limitation in the Factorio engine.\nIterating over the whole table would lag the game.\nSo when searching, you will still see the same amount of pages.\nAnd the results will be "janky".',
sprite = 'utility/questionmark'
}
btn.style.height = 20
btn.style.width = 20
btn.enabled = false
btn.focus()
local bottomLine2 = frame.add({type = 'label', caption = '----------------------------------------------'})
local bottomLine2 = frame.add({ type = 'label', caption = '----------------------------------------------' })
bottomLine2.style.font = 'default-listbox'
bottomLine2.style.font_color = {r = 0.98, g = 0.66, b = 0.22}
bottomLine2.style.font_color = { r = 0.98, g = 0.66, b = 0.22 }
local selected_index_2 = 1
if player_data and player_data.selected_history_index then
selected_index_2 = player_data.selected_history_index
end
local pagination_table = frame.add({type = 'table', column_count = 2, name = 'pagination_table'})
local pagination_table = frame.add({ type = 'table', column_count = 2, name = 'pagination_table' })
local drop_down_2 = pagination_table.add({type = 'drop-down', name = 'admin_history_select', items = histories, selected_index = selected_index_2})
local drop_down_2 = pagination_table.add({ type = 'drop-down', name = 'admin_history_select', items = histories, selected_index = selected_index_2 })
drop_down_2.style.right_padding = 12
drop_down_2.style.left_padding = 12
@@ -979,7 +1008,8 @@ local admin_global_functions = {
['delete_all_blueprints'] = delete_all_blueprints,
['pause_game_tick'] = pause_game_tick,
['save_game'] = save_game,
['clear_items_on_ground'] = clear_items_on_ground
['clear_items_on_ground'] = clear_items_on_ground,
['clear_biters'] = clear_biters
}
local function get_surface_from_string(str)
@@ -1047,7 +1077,7 @@ local function get_position_from_string(str)
local y = string.sub(str, y_pos, y_pos + a1)
x = tonumber(x)
y = tonumber(y)
local position = {x = x, y = y}
local position = { x = x, y = y }
return position
end
@@ -1085,7 +1115,7 @@ local function on_gui_click(event)
return
end
if target_player_name == 'Select Player' then
player.print('[AdminGui] No target player selected.', {r = 0.88, g = 0.88, b = 0.88})
player.print('[AdminGui] No target player selected.', { r = 0.88, g = 0.88, b = 0.88 })
return
end
local target_player = game.players[target_player_name]
@@ -1148,7 +1178,7 @@ local function on_gui_selection_state_changed(event)
return
end
Task.set_timeout_in_ticks(5, delayed_last_page_token, {player_index = player.index, element = frame})
Task.set_timeout_in_ticks(5, delayed_last_page_token, { player_index = player.index, element = frame })
player_data.current_page = 1
@@ -1156,7 +1186,7 @@ local function on_gui_selection_state_changed(event)
if is_spamming then
return
end
local data = {player = player, frame = frame}
local data = { player = player, frame = frame }
create_admin_panel(data)
end
if name == 'admin_player_select' then
@@ -1176,16 +1206,16 @@ local function on_gui_selection_state_changed(event)
return
end
local data = {player = player, frame = frame}
local data = { player = player, frame = frame }
create_admin_panel(data)
end
end
Gui.add_tab_to_gui({name = module_name, caption = 'Admin', id = create_admin_panel_token, admin = true})
Gui.add_tab_to_gui({ name = module_name, caption = 'Admin', id = create_admin_panel_token, admin = true })
Gui.on_click(
module_name,
function(event)
function (event)
local player = event.player
Gui.reload_active_tab(player)
end
@@ -1248,7 +1278,7 @@ end
Gui.on_click(
prev_button_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Prev button click')
if is_spamming then
return
@@ -1289,14 +1319,14 @@ Gui.on_click(
player_data.current_page = current_page
local data = {player = player, frame = element.parent.parent.parent}
local data = { player = player, frame = element.parent.parent.parent }
create_admin_panel(data)
end
)
Gui.on_click(
next_button_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Next button click')
if is_spamming then
return
@@ -1342,14 +1372,14 @@ Gui.on_click(
player_data.current_page = current_page
local data = {player = player, frame = element.parent.parent.parent}
local data = { player = player, frame = element.parent.parent.parent }
create_admin_panel(data)
end
)
Gui.on_checked_state_changed(
listable_players_name,
function(event)
function (event)
local is_spamming = SpamProtection.is_spamming(event.player, nil, 'Listable players click')
if is_spamming then
return
@@ -1369,7 +1399,7 @@ Gui.on_checked_state_changed(
player_data.show_all_players = element.state
local data = {player = player, frame = element.parent}
local data = { player = player, frame = element.parent }
create_admin_panel(data)
end
)