1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2024-12-26 22:56:43 +02:00

Adjust for Mtn v3 new season and misc changes

This commit is contained in:
Gerkiz 2024-03-22 00:30:57 +01:00
parent 69a6165447
commit 9e077037fd
20 changed files with 942 additions and 258 deletions

View File

@ -1,7 +1,7 @@
[mountain_fortress_v3]
map_info_main_caption=M O U N T A I N F O R T R E S S V3
map_info_sub_caption= ~~ diggy diggy rocky rocky ~~
map_info_text=[color=red][img=utility/danger_icon] READ THIS! [img=utility/danger_icon]\nIf there are any code bugs or desyncs. Please report asap to @Gerkiz!\nIf there are any game breaking bugs then this map might be shutdown to hot-fix the issue.[/color]\n\nCheck out the [img=utility/custom_tag_icon] for information regarding on how one can win the game!\nCompleting/winning the map increases the difficulty (damage/health).\n\nTo link a chest within the locomotive place a iron or steel chest.\nThen open the chest and press the button in the top right.\n\nThe biters have caught the scent of fish in the cargo wagon.\nGuide the choo into the mountain and protect it as long as possible!\nThis however will not be an easy task,\nsince their strength and numbers increase over time.\n\nIn addition, the southern grounds collapse over time.\n\nDelve deep for greater treasures, but also face increased dangers.\nMining productivity research will overhaul your mining equipment, increasing the size of your backpack.\n\nAs you dig, you will encounter impassable dark chasms or rivers.\nArtillery will try to shoot you down! Dig fast, dig north!\n\nSome explosives may cause rocks to fall down the mountain, filling the void, creating new ways.\nAll they need is a container and a well aimed shot.\n\nEnter the cargo wagon to reveal the wagon surface!\n\nRandom buildings that generate resources can be found throughout the world.\n\nPlacing steel-chests near cargo-wagons enables you to quickly move content.\n\nStaying inside the train aura prevents biters from spawning when mining entities.\n\nRadars cannot be built near each other.\n\nRPG GUI is disabled inside the train.\n\nDisconnecting wagons is disabled.\nYou can't cancel crafting when standing inside the train aura.\n\nDon't try to run north with your Spidertron if the train is not near you.\nYou have been warned.\n\nMining drills have great mining-bonus which also is increased after each research, use them when you can!\n\nThe mystical chest in the locomotive offers some rewards.\nOne must feed the chest to receive such rewards.\n\nGood luck on your journey!
map_info_text=[color=red][img=utility/danger_icon] READ THIS! [img=utility/danger_icon]\nIf there are any code bugs or desyncs. Please report asap to @Gerkiz!\nIf there are any game breaking bugs then this map might be shutdown to hot-fix the issue.[/color]\n\nCheck out the [img=utility/custom_tag_icon] for information regarding on how one can win the game!\nCompleting/winning the map increases the difficulty (damage/health).\n\nThe game [color=red]randomizes[/color] which direction to push.\nSometimes it's north and sometimes it will be south. This is changed upon each soft reset.\n\nTo link a chest within the locomotive place a iron or steel chest.\nThen open the chest and press the button in the top right.\n\nThe biters have caught the scent of fish in the cargo wagon.\nGuide the choo into the mountain and protect it as long as possible!\nThis however will not be an easy task,\nsince their strength and numbers increase over time.\n\nIn addition, the southern grounds collapse over time.\n\nDelve deep for greater treasures, but also face increased dangers.\nMining productivity research will overhaul your mining equipment, increasing the size of your backpack.\n\nAs you dig, you will encounter impassable dark chasms or rivers.\nArtillery will try to shoot you down! Dig fast, dig north!\n\nSome explosives may cause rocks to fall down the mountain, filling the void, creating new ways.\nAll they need is a container and a well aimed shot.\n\nEnter the cargo wagon to reveal the wagon surface!\n\nRandom buildings that generate resources can be found throughout the world.\n\nPlacing steel-chests near cargo-wagons enables you to quickly move content.\n\nStaying inside the train aura prevents biters from spawning when mining entities.\n\nRadars cannot be built near each other.\n\nRPG GUI is disabled inside the train.\n\nDisconnecting wagons is disabled.\nYou can't cancel crafting when standing inside the train aura.\n\nDon't try to run north with your Spidertron if the train is not near you.\nYou have been warned.\n\nMining drills have great mining-bonus which also is increased after each research, use them when you can!\n\nThe mystical chest in the locomotive offers some rewards.\nOne must feed the chest to receive such rewards.\n\nGood luck on your journey!
[breached_wall]
collapse_start=[color=blue]Mapkeeper:[/color]\nWarning, Collapse has begun!
@ -14,7 +14,7 @@ cheating_through=[color=blue]Mapkeeper:[/color] __1__ tried to cheat their way n
hinder=[color=blue]Mapkeeper:[/color] You are too far away from the main locomotive. You cannot go beyond this point.
hinder_collapse=[color=blue]Mapkeeper:[/color] Collapse is too far away. You cannot go beyond this point.
warning=Breaching the far side wall will start collapse.
warning_teleport=[color=blue]Mapkeeper:[/color] __1__ wants to go north, but was given a last chance to rethink their choice. The next player that does this will trigger collapse!
warning_teleport=[color=blue]Mapkeeper:[/color] __1__ wanted to advance, but was given a last chance to rethink their choice. The next player that does this will trigger collapse!
[entity]
treasure_1=[color=blue]Mapkeeper:[/color] You notice an old crate within the rubble. It's filled with treasure!

View File

@ -24,6 +24,10 @@ local clear_breach_text_and_render = function()
if beam2 and beam2.valid then
beam2.destroy()
end
local beam3 = Public.get('zone1_beam3')
if beam3 and beam3.valid then
beam3.destroy()
end
local zone1_text1 = Public.get('zone1_text1')
if zone1_text1 then
rendering.set_text(zone1_text1, 'Collapse has begun!')

View File

@ -14,6 +14,7 @@ Public.generate = require 'maps.mountain_fortress_v3.generate'
Public.get_perlin = require 'maps.mountain_fortress_v3.get_perlin'
Public.gui = require 'maps.mountain_fortress_v3.gui'
Public.highscore = require 'maps.mountain_fortress_v3.highscore'
Public.season_highscore = require 'maps.mountain_fortress_v3.season_highscore'
Public.locomotive = require 'maps.mountain_fortress_v3.locomotive'
Public.loot = require 'maps.mountain_fortress_v3.loot'
Public.mining = require 'maps.mountain_fortress_v3.mining'

View File

@ -334,7 +334,7 @@ local function do_beams_away()
return
end
if wave_number > 1000 then
if wave_number > 500 then
local difficulty_index = Difficulty.get('index')
local wave_nth = 9999
if difficulty_index == 1 then
@ -409,11 +409,6 @@ local function do_artillery_turrets_targets()
local art_table = this.art_table
local index = art_table.index
local difficulty_index = Difficulty.get('index')
if difficulty_index == 3 then
return
end
if index > #art_table then
art_table.index = 1
return
@ -614,7 +609,12 @@ Public.refill_artillery_turret_callback =
local pos = turret.position
local x, y = pos.x, pos.y
artillery_data.artillery_area = {{x - 112, y}, {x + 112, y + 212}}
local adjusted_zones = Public.get('adjusted_zones')
if adjusted_zones.reversed then
artillery_data.artillery_area = {{x - 112, y - 212}, {x + 112, y}}
else
artillery_data.artillery_area = {{x - 112, y}, {x + 112, y + 212}}
end
artillery_data.last_fire_tick = 0
art_table[#art_table + 1] = artillery_data
@ -1049,7 +1049,7 @@ function Public.set_difficulty()
end
end
function Public.render_direction(surface)
function Public.render_direction(surface, reversed)
local counter = Public.get('soft_reset_counter')
local winter_mode = Public.get('winter_mode')
local text = 'Welcome to Mountain Fortress v3!'
@ -1098,73 +1098,64 @@ function Public.render_direction(surface)
}
end
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 20},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 30},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 40},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 50},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 60},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = 'Biters will attack this area.',
surface = surface,
target = {-0, 70},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
local x_min = -zone_settings.zone_width / 2
local x_max = zone_settings.zone_width / 2
surface.create_entity({name = 'electric-beam', position = {x_min, 74}, source = {x_min, 74}, target = {x_max, 74}})
surface.create_entity({name = 'electric-beam', position = {x_min, 74}, source = {x_min, 74}, target = {x_max, 74}})
if reversed then
local inc = 0
for _ = 1, 5 do
rendering.draw_text {
text = '',
surface = surface,
target = {-0, -20 - inc},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
inc = inc + 10
end
rendering.draw_text {
text = 'Biters will attack this area.',
surface = surface,
target = {-0, -70},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
surface.create_entity({name = 'electric-beam', position = {x_min, -74}, source = {x_min, -74}, target = {x_max, -74}})
surface.create_entity({name = 'electric-beam', position = {x_min, -74}, source = {x_min, -74}, target = {x_max, -74}})
else
local inc = 0
for _ = 1, 5 do
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 20 + inc},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
inc = inc + 10
end
rendering.draw_text {
text = 'Biters will attack this area.',
surface = surface,
target = {-0, 70},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
surface.create_entity({name = 'electric-beam', position = {x_min, 74}, source = {x_min, 74}, target = {x_max, 74}})
surface.create_entity({name = 'electric-beam', position = {x_min, 74}, source = {x_min, 74}, target = {x_max, 74}})
end
end
function Public.boost_difficulty()
@ -1481,6 +1472,7 @@ function Public.on_player_changed_position(event)
local position = player.position
local surface = game.surfaces[active_surface_index]
local adjusted_zones = Public.get('adjusted_zones')
local p = {x = player.position.x, y = player.position.y}
local config_tile = Public.get('void_or_tile')
@ -1502,14 +1494,28 @@ function Public.on_player_changed_position(event)
end
end
if position.y >= 74 then
player.teleport({position.x, position.y - 1}, surface)
player.print(({'main.forcefield'}), {r = 0.98, g = 0.66, b = 0.22})
if player.character then
player.character.health = player.character.health - 5
player.character.surface.create_entity({name = 'water-splash', position = position})
if player.character.health <= 0 then
player.character.die('enemy')
if adjusted_zones.reversed then
if position.y < -74 then
player.teleport({position.x, position.y + 1}, surface)
player.print(({'main.forcefield'}), {r = 0.98, g = 0.66, b = 0.22})
if player.character then
player.character.health = player.character.health - 5
player.character.surface.create_entity({name = 'water-splash', position = position})
if player.character.health <= 0 then
player.character.die('enemy')
end
end
end
else
if position.y >= 74 then
player.teleport({position.x, position.y - 1}, surface)
player.print(({'main.forcefield'}), {r = 0.98, g = 0.66, b = 0.22})
if player.character then
player.character.health = player.character.health - 5
player.character.surface.create_entity({name = 'water-splash', position = position})
if player.character.health <= 0 then
player.character.die('enemy')
end
end
end
end
@ -1538,6 +1544,8 @@ function Public.disable_tech()
force.technologies['spidertron'].researched = false
force.technologies['atomic-bomb'].enabled = false
force.technologies['atomic-bomb'].researched = false
force.technologies['artillery'].enabled = false
force.technologies['artillery'].researched = false
force.technologies['artillery-shell-range-1'].enabled = false
force.technologies['artillery-shell-range-1'].researched = false
force.technologies['artillery-shell-speed-1'].enabled = false

View File

@ -4,7 +4,12 @@ local simplex_noise = require 'utils.simplex_noise'.d2
--add or use noise templates from here
local noises = {
['cave_ponds'] = {{modifier = 0.014, weight = 0.77}, {modifier = 0.18, weight = 0.085}},
['smol_areas'] = {{modifier = 0.0052, weight = 0.83}, {modifier = 0.139, weight = 0.022}, {modifier = 0.121, weight = 0.01}},
['smol_areas'] = {
{modifier = 0.0052, weight = 0.83},
{modifier = 0.139, weight = 0.144},
{modifier = 0.129, weight = 0.072},
{modifier = 0.111, weight = 0.01}
},
['cave_rivers'] = {
{modifier = 0.0053, weight = 0.71},
{modifier = 0.0086, weight = 0.24},
@ -27,16 +32,6 @@ local noises = {
{modifier = 0.00363, weight = 1.05},
{modifier = 0.01, weight = 0.23}
},
['n1'] = {{modifier = 0.00011, weight = 1.1}},
['n2'] = {{modifier = 0.0011, weight = 1.1}},
['n3'] = {{modifier = 0.011, weight = 1.1}},
['n4'] = {{modifier = 0.11, weight = 1.1}},
['n5'] = {{modifier = 0.077, weight = 1.1}},
['watery_world'] = {
{modifier = 0.00077, weight = 1.1},
{modifier = 0.011, weight = 0.022},
{modifier = 0.11, weight = 0.0055}
},
['no_rocks'] = {
{modifier = 0.00495, weight = 0.945},
{modifier = 0.01665, weight = 0.2475},
@ -62,11 +57,6 @@ local noises = {
{modifier = 0.242, weight = 0.055},
{modifier = 0.055, weight = 0.352}
},
['big_cave'] = {
{modifier = 0.0033, weight = 1.1},
{modifier = 0.022, weight = 0.055},
{modifier = 0.165, weight = 0.022}
},
['small_caves'] = {
{modifier = 0.0066, weight = 1.1},
{modifier = 0.044, weight = 0.165},
@ -98,12 +88,6 @@ local noises = {
{modifier = 0.006, weight = 1},
{modifier = 0.02, weight = 0.15},
{modifier = 0.25, weight = 0.025}
},
['cm_ponds'] = {{modifier = 0.025, weight = 1}, {modifier = 0.05, weight = 0.25}, {modifier = 0.1, weight = 0.05}},
['cm_ocean'] = {
{modifier = 0.002, weight = 1},
{modifier = 0.004, weight = 1},
{modifier = 0.02, weight = 0.05}
}
}

View File

@ -204,6 +204,10 @@ local function changed_surface(player)
local rpg_settings = RPG.settings_frame_name
local main = Public.get('locomotive')
local icw_locomotive = Public.get('icw_locomotive')
if not icw_locomotive then
return
end
local wagon_surface = icw_locomotive.surface
local main_toggle_button = player.gui.top[main_toggle_button_name]
local info = player.gui.top[main_button_name]

View File

@ -96,10 +96,12 @@ local function sort_and_whitelist(whitelisted, column_name, tbl)
)
for i = 1, #t do
local name = t[i].name
if i < 11 then
tbl[get_key(tbl, name)][column_name] = t[i].score
whitelisted[name] = true
if t[i] and t[i].name then
local name = t[i].name
if i < 11 then
tbl[get_key(tbl, name)][column_name] = t[i].score
whitelisted[name] = true
end
end
end
end
@ -110,9 +112,11 @@ local function remove_non_top_10(whitelisted, tbl)
end
for i = 1, #tbl do
local name = tbl[i].name
if not whitelisted[name] then
tbl[i] = nil
if tbl[i] and tbl[i].name then
local name = tbl[i].name
if not whitelisted[name] then
tbl[i] = nil
end
end
end
end
@ -447,6 +451,11 @@ local sorting_symbol = {ascending = '▲', descending = '▼'}
local function get_score_list()
local score_force = this.score_table['player']
local whitelisted_score_tbl = {}
sort_and_whitelist(whitelisted_score_tbl, 'killscore', score_force.players)
sort_and_whitelist(whitelisted_score_tbl, 'mined_entities', score_force.players)
sort_and_whitelist(whitelisted_score_tbl, 'built_entities', score_force.players)
remove_non_top_10(whitelisted_score_tbl, score_force.players)
local score_list = {}
if not score_force then
score_list[#score_list + 1] = {

View File

@ -884,7 +884,14 @@ end
function Public.construct_train(icw, locomotive, carriages)
for i, carriage in pairs(carriages) do
if carriage == locomotive then
local stock = locomotive.get_connected_rolling_stock(defines.rail_direction.front)
local adjusted_zones = WPT.get('adjusted_zones')
local stock
if adjusted_zones.reversed then
stock = locomotive.get_connected_rolling_stock(defines.rail_direction.back)
else
stock = locomotive.get_connected_rolling_stock(defines.rail_direction.front)
end
if stock ~= carriages[i - 1] then
local n = 1
local m = #carriages

View File

@ -398,6 +398,10 @@ local function get_driver_action(entity)
return
end
if player.admin then
return
end
if Session.get_session_player(player) then
local total_time = player.online_time + Session.get_session_player(player)

View File

@ -129,16 +129,28 @@ local set_loco_cargo =
end
)
function Public.locomotive_spawn(surface, position)
function Public.locomotive_spawn(surface, position, reversed)
local this = Public.get()
for y = -6, 6, 2 do
surface.create_entity({name = 'straight-rail', position = {position.x, position.y + y}, force = 'player', direction = 0})
end
this.locomotive = surface.create_entity({name = 'locomotive', position = {position.x, position.y + -3}, force = 'player'})
this.locomotive.get_inventory(defines.inventory.fuel).insert({name = 'wood', count = 100})
this.locomotive_cargo = surface.create_entity({name = 'cargo-wagon', position = {position.x, position.y + 3}, force = 'player'})
this.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = 'raw-fish', count = 8})
if reversed then
for y = 6, -6, -2 do
surface.create_entity({name = 'straight-rail', position = {position.x, position.y + y}, force = 'player', direction = 0})
end
this.locomotive = surface.create_entity({name = 'locomotive', position = {position.x, position.y + 3}, force = 'player', 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'})
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})
end
this.locomotive = surface.create_entity({name = 'locomotive', position = {position.x, position.y + -3}, force = 'player'})
this.locomotive.get_inventory(defines.inventory.fuel).insert({name = 'wood', count = 100})
this.locomotive_cargo = surface.create_entity({name = 'cargo-wagon', position = {position.x, position.y + 3}, force = 'player'})
this.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = 'raw-fish', count = 8})
end
local winter_mode_locomotive = Public.wintery(this.locomotive, 5.5)
if not winter_mode_locomotive then
@ -215,21 +227,40 @@ function Public.locomotive_spawn(surface, position)
if extra_wagons and extra_wagons > 0 then
local pos = this.locomotive_cargo.position
local inc = 6
local new_position = {x = pos.x, y = pos.y + inc}
local inc = 7
if reversed then
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})
end
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})
end
for _ = 1, extra_wagons do
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}
ICW.register_wagon(new_wagon)
for _ = 1, extra_wagons do
local new_wagon = surface.create_entity({name = 'cargo-wagon', position = new_position, force = 'player', defines.direction.south})
if new_wagon and new_wagon.valid then
new_wagon.minable = false
new_wagon.operable = true
inc = inc + 6
new_position = {x = pos.x, y = pos.y - inc}
ICW.register_wagon(new_wagon)
end
end
else
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})
end
for _ = 1, extra_wagons do
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}
ICW.register_wagon(new_wagon)
end
end
end
end
@ -238,7 +269,7 @@ function Public.locomotive_spawn(surface, position)
Task.set_timeout_in_ticks(300, place_tiles_token, {surface = surface, position = position})
Task.set_timeout_in_ticks(50, set_loco_cargo, data)
game.forces.player.set_spawn_position({0, 19}, locomotive.surface)
game.forces.player.set_spawn_position({this.locomotive.position.x - 5, this.locomotive.position.y}, locomotive.surface)
end
return Public

View File

@ -116,6 +116,15 @@ local announce_new_map =
function Public.reset_map()
game.forces.player.reset()
local this = Public.get()
local is_reversed = this.adjusted_zones.reversed
if is_reversed then
is_reversed = false
else
is_reversed = true
end
Public.reset_main_table()
this.adjusted_zones.reversed = is_reversed
local wave_defense_table = WD.get_table()
Misc.reset()
Misc.bottom_button(true)
@ -126,6 +135,7 @@ function Public.reset_map()
this.old_surface_index = this.active_surface_index
Public.stateful.clear_all_frames()
local adjusted_zones = Public.get('adjusted_zones')
Autostash.insert_into_furnace(true)
Autostash.insert_into_wagon(true)
@ -139,7 +149,6 @@ function Public.reset_map()
IC.allowed_surface(game.surfaces[this.active_surface_index].name)
Public.reset_func_table()
game.reset_time_played()
Public.reset_main_table()
OfflinePlayers.init(this.active_surface_index)
OfflinePlayers.set_enabled(true)
@ -167,7 +176,6 @@ function Public.reset_map()
Beam.reset_valid_targets()
game.forces.player.set_spawn_position({x = -27, y = 25}, surface)
game.forces.player.manual_mining_speed_modifier = 0
game.forces.player.set_ammo_damage_modifier('artillery-shell', -0.95)
game.forces.player.worker_robots_battery_modifier = 4
@ -220,17 +228,24 @@ function Public.reset_map()
-- Collapse.set_max_line_size(zone_settings.zone_width)
Collapse.set_max_line_size(540)
Collapse.set_surface_index(surface.index)
Collapse.set_position({0, 130})
Collapse.set_direction('north')
Collapse.start_now(false)
Collapse.disable_collapse(false)
this.locomotive_health = 10000
this.locomotive_max_health = 10000
Public.locomotive_spawn(surface, {x = -18, y = 25})
if adjusted_zones.reversed then
Collapse.set_position({0, -130})
Collapse.set_direction('south')
Public.locomotive_spawn(surface, {x = -18, y = -25}, adjusted_zones.reversed)
else
Collapse.set_position({0, 130})
Collapse.set_direction('north')
Public.locomotive_spawn(surface, {x = -18, y = 25}, adjusted_zones.reversed)
end
Public.render_train_hp()
Public.render_direction(surface)
Public.render_direction(surface, adjusted_zones.reversed)
WD.reset_wave_defense()
wave_defense_table.surface_index = this.active_surface_index
@ -257,12 +272,20 @@ function Public.reset_map()
Public.disable_creative()
Public.boost_difficulty()
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()
if 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)
surface.force_generate_chunk_requests()
end
game.forces.player.set_spawn_position({x = -27, y = -25}, surface)
else
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)
end
game.forces.player.set_spawn_position({x = -27, y = 25}, surface)
game.speed = 1
Task.set_queue_speed(16)

View File

@ -2,6 +2,7 @@ local Public = require 'maps.mountain_fortress_v3.table'
local RPG = require 'modules.rpg.main'
local Event = require 'utils.event'
local Ai = require 'modules.ai'
local Misc = require 'utils.commands.misc'
require 'modules.check_fullness'
local random = math.random
@ -421,12 +422,17 @@ function Public.on_player_mined_entity(event)
end
local buffer = event.buffer
local creative_enabled = Misc.get('creative_enabled')
if valid_rocks[entity.name] or valid_trees[entity.name] or is_scrap then
if buffer then
buffer.clear()
end
if creative_enabled then
return
end
local data = {
entity = entity,
player = player

View File

@ -0,0 +1,326 @@
local Event = require 'utils.event'
local Public = require 'maps.mountain_fortress_v3.table'
local Global = require 'utils.global'
local Server = require 'utils.server'
local Gui = require 'utils.gui'
local Task = require 'utils.task_token'
local SpamProtection = require 'utils.spam_protection'
local module_name = Gui.uid_name()
local score_dataset = 'seasons'
local score_key = 'mtn_v3'
local set_data = Server.set_data
local try_get_data = Server.try_get_data
local insert = table.insert
local this = {
seasons = {},
sort_by = {}
}
Global.register(
this,
function(t)
this = t
end
)
local function sort_list(method, column_name, score_list)
local comparators = {
['ascending'] = function(a, b)
return a[column_name] < b[column_name]
end,
['descending'] = function(a, b)
return a[column_name] > b[column_name]
end
}
table.sort(score_list, comparators[method])
return score_list
end
local function write_additional_stats(key)
local current_date = Server.get_current_date(true)
if not current_date then
return
end
local season = Public.get_stateful('season')
local rounds_survived = Public.get_stateful('rounds_survived')
local total_buffs = Public.get_stateful('total_buffs')
local previous_raw_date = Public.get_stateful('current_date')
local previous_date = Server.get_current_date(true, false, previous_raw_date)
if not previous_date then
return
end
this.seasons[#this.seasons] = {
season_index = season,
rounds_survived = rounds_survived,
buffs_granted = total_buffs,
started = previous_date,
ended = current_date
}
if key then
set_data(score_dataset, key, this.seasons)
end
end
local get_scores =
Task.register(
function(data)
local value = data.value
this.seasons = value
end
)
function Public.get_season_scores()
local secs = Server.get_current_time()
if not secs then
return
else
try_get_data(score_dataset, score_key, get_scores)
end
end
-- local Core = require 'maps.mountain_fortress_v3.core' Core.set_season_scores()
function Public.set_season_scores()
local secs = Server.get_current_time()
if not secs then
return
else
write_additional_stats(score_key)
end
end
local function on_init()
local secs = Server.get_current_time()
if not secs then
write_additional_stats()
return
end
end
local sorting_symbol = {ascending = '', descending = ''}
local function get_score_list()
local seasons = this.seasons
local score_list = {}
if not seasons then
score_list[#score_list + 1] = {
season_index = 'N/A',
rounds_survived = 'N/A',
buffs_granted = 'N/A',
started = 'N/A',
ended = 'N/A'
}
return score_list
end
for _, data in pairs(seasons) do
insert(
score_list,
{
season_index = data.season_index,
rounds_survived = data.rounds_survived,
buffs_granted = data.buffs_granted,
started = data.started,
ended = data.ended
}
)
end
return score_list
end
local function show_score(data)
local player = data.player
local frame = data.frame
frame.clear()
local flow = frame.add {type = 'flow'}
local sFlow = flow.style
sFlow.horizontally_stretchable = true
sFlow.horizontal_align = 'center'
sFlow.vertical_align = 'center'
-- Score per player
local t = frame.add {type = 'table', column_count = 5}
-- Score headers
local headers = {
{column = 'season_index', name = 'season_index', caption = 'Season', tooltip = 'Season index.'},
{column = 'rounds_survived', name = 'rounds_survived', caption = 'Rounds survived', tooltip = 'Rounds survived in the season.'},
{column = 'buffs_granted', name = 'buffs_granted', caption = 'Buffs granted', tooltip = 'Buffs granted to players which is gained each round won.'},
{column = 'started', name = 'started', caption = 'Start date', tooltip = 'Start date of the season.'},
{column = 'ended', name = 'ended', caption = 'Stop date', tooltip = 'Stop date of the season.'}
}
local sorting_pref = this.sort_by[player.index]
for _, header in ipairs(headers) do
local cap = header.caption
-- Add sorting symbol if any
if header.column and sorting_pref.column == header.column then
local symbol = sorting_symbol[sorting_pref.method]
cap = symbol .. cap
end
-- Header
local label =
t.add {
type = 'label',
caption = cap,
tooltip = header.tooltip or '',
name = header.name
}
label.style.font = 'default-listbox'
label.style.font_color = {r = 0.98, g = 0.66, b = 0.22} -- yellow
label.style.minimal_width = 125
label.style.horizontal_align = 'center'
end
-- Score list
local score_list = get_score_list()
score_list = sort_list(sorting_pref.method, sorting_pref.column, score_list)
-- New pane for scores (while keeping headers at same position)
local scroll_pane =
frame.add(
{
type = 'scroll-pane',
name = 'score_scroll_pane',
direction = 'vertical',
horizontal_scroll_policy = 'never',
vertical_scroll_policy = 'auto'
}
)
scroll_pane.style.maximal_height = 400
scroll_pane.style.minimal_width = 700
t = scroll_pane.add {type = 'table', column_count = 5}
-- Score entries
local i = 0
for _, data in pairs(score_list) do
i = i + 1
local lines = {
{caption = data.season_index},
{caption = data.rounds_survived},
{caption = data.buffs_granted},
{caption = data.started},
{caption = data.ended}
}
local default_color = {r = 0.9, g = 0.9, b = 0.9}
for _, column in ipairs(lines) do
local label =
t.add {
type = 'label',
caption = column.caption,
color = column.color or default_color
}
label.style.font = 'default'
label.style.minimal_width = 125
label.style.maximal_width = 150
label.style.horizontal_align = 'center'
end -- foreach column
end -- foreach entry
end
local show_score_token = Task.register(show_score)
local function on_gui_click(event)
local element = event.element
if not element or not element.valid then
return
end
local player = game.get_player(event.element.player_index)
if not player then
return
end
local frame = Gui.get_player_active_frame(player)
if not frame then
return
end
if frame.name ~= 'Seasons' then
return
end
local is_spamming = SpamProtection.is_spamming(player, nil, 'Season Gui Click')
if is_spamming then
return
end
local name = event.element.name
-- Handles click on a score header
local element_to_column = {
['season_index'] = 'season_index',
['rounds_survived'] = 'rounds_survived',
['buffs_granted'] = 'buffs_granted',
['started'] = 'started',
['ended'] = 'ended'
}
local column = element_to_column[name]
if column then
local sorting_pref = this.sort_by[player.index]
if sorting_pref.column == column and sorting_pref.method == 'descending' then
sorting_pref.method = 'ascending'
else
sorting_pref.method = 'descending'
sorting_pref.column = column
end
show_score({player = player, frame = frame})
return
end
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
if not this.sort_by[player.index] then
this.sort_by[player.index] = {method = 'descending', column = 'season_index'}
end
end
local function on_player_left_game(event)
local player = game.players[event.player_index]
if this.sort_by[player.index] then
this.sort_by[player.index] = nil
end
end
Server.on_data_set_changed(
score_dataset,
function(data)
if data.key == score_key then
if data.value then
this.seasons = data.value
end
end
end
)
Gui.add_tab_to_gui({name = module_name, caption = 'Seasons', id = show_score_token, admin = false, only_server_sided = true})
Gui.on_click(
module_name,
function(event)
local player = event.player
Gui.reload_active_tab(player)
end
)
Event.on_init(on_init)
Event.add(defines.events.on_player_left_game, on_player_left_game)
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
Event.add(defines.events.on_gui_click, on_gui_click)
Event.add(Server.events.on_server_started, Public.get_season_scores)
return Public

View File

@ -21,12 +21,25 @@ local function reset_forces(new_surface, old_surface)
end
local function teleport_players(surface)
game.forces.player.set_spawn_position({-27, 25}, surface)
local position = game.forces.player.get_spawn_position(surface)
local adjusted_zones = Public.get('adjusted_zones')
local position
if not position then
if adjusted_zones.reversed then
game.forces.player.set_spawn_position({-27, -25}, surface)
position = game.forces.player.get_spawn_position(surface)
if not position then
game.forces.player.set_spawn_position({-27, -25}, surface)
position = game.forces.player.get_spawn_position(surface)
end
else
game.forces.player.set_spawn_position({-27, 25}, surface)
position = game.forces.player.get_spawn_position(surface)
if not position then
game.forces.player.set_spawn_position({-27, 25}, surface)
position = game.forces.player.get_spawn_position(surface)
end
end
for _, player in pairs(game.connected_players) do

View File

@ -858,6 +858,7 @@ local function apply_buffs()
local starting_items = Public.get_func('starting_items')
if this.buffs and next(this.buffs) then
local total_buffs = 0
if not this.buffs_collected then
this.buffs_collected = {}
end
@ -867,6 +868,7 @@ local function apply_buffs()
local force = game.forces.player
for _, buff in pairs(this.buffs) do
if buff then
total_buffs = total_buffs + 1
if buff.modifier == 'rpg_distance' then
for _, buff_name in pairs(buff.modifiers) do
if buff_name == 'character_reach_distance_bonus' then
@ -977,6 +979,7 @@ local function apply_buffs()
end
end
end
this.total_buffs = total_buffs
end
Public.equip_players(starting_items)
end
@ -1012,6 +1015,8 @@ local function apply_startup_settings(settings)
Server.set_data(dataset, dataset_key_previous, settings)
end
Public.set_season_scores()
local s = this.season or 1
game.server_save('Season_' .. s .. '_Mtn_v3_' .. tostring(current_time))
notify_season_over_to_discord()
@ -1308,18 +1313,36 @@ function Public.migrate_and_create(locomotive)
if not surface or not surface.valid then
return
end
local adjusted_zones = Public.get('adjusted_zones')
local position = locomotive.position
local inc = 6
local new_position = {x = position.x, y = position.y + inc}
if adjusted_zones.reversed then
local new_position = {x = position.x, y = position.y - inc}
for index, entity in pairs(carriages) do
if index ~= 1 then
if entity and entity.valid and entity.unit_number ~= locomotive.unit_number then
local new_wagon = surface.create_entity({name = entity.name, position = new_position, force = 'player', defines.direction.north})
if new_wagon and new_wagon.valid then
inc = inc + 7
new_position = {x = position.x, y = position.y + inc}
ICW.migrate_wagon(entity, new_wagon)
for index, entity in pairs(carriages) do
if index ~= 1 then
if entity and entity.valid and entity.unit_number ~= locomotive.unit_number then
local new_wagon = surface.create_entity({name = entity.name, position = new_position, force = 'player', defines.direction.south})
if new_wagon and new_wagon.valid then
inc = inc + 6
new_position = {x = position.x, y = position.y - inc}
ICW.migrate_wagon(entity, new_wagon)
end
end
end
end
else
local new_position = {x = position.x, y = position.y + inc}
for index, entity in pairs(carriages) do
if index ~= 1 then
if entity and entity.valid and entity.unit_number ~= locomotive.unit_number then
local new_wagon = surface.create_entity({name = entity.name, position = new_position, force = 'player', defines.direction.north})
if new_wagon and new_wagon.valid then
inc = inc + 7
new_position = {x = position.x, y = position.y + inc}
ICW.migrate_wagon(entity, new_wagon)
end
end
end
end

View File

@ -283,7 +283,9 @@ function Public.reset_main_table()
forest = {},
size = nil,
shuffled_zones = nil,
starting_zone = false
starting_zone = false,
reversed = false,
disable_terrain = false
}
this.alert_zone_1 = false -- alert the players
this.radars_reveal_new_chunks = false -- allows for the player to explore the map instead,

View File

@ -452,51 +452,102 @@ local function wall(p, data)
force = 'neutral',
callback = stone_wall
}
local adjusted_zones = Public.get('adjusted_zones')
if not alert_zone_1 and data.y >= -zone_settings.zone_depth then
local x_min = -zone_settings.zone_width / 2
local x_max = zone_settings.zone_width / 2
Public.set('zone1_beam1', surface.create_entity({name = 'electric-beam', position = {x_min, p.y}, source = {x_min, p.y}, target = {x_max, p.y}}))
Public.set('zone1_beam2', surface.create_entity({name = 'electric-beam', position = {x_min, p.y}, source = {x_min, p.y}, target = {x_max, p.y}}))
Public.set('alert_zone_1', true)
Public.set(
'zone1_text1',
rendering.draw_text {
text = ({'breached_wall.warning'}),
surface = surface,
target = {0, p.y + 35},
color = {r = 255, g = 106, b = 0},
scale = 10,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
)
Public.set(
'zone1_text2',
rendering.draw_text {
text = ({'breached_wall.warning'}),
surface = surface,
target = {-180, p.y + 35},
color = {r = 255, g = 106, b = 0},
scale = 10,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
)
Public.set(
'zone1_text3',
rendering.draw_text {
text = ({'breached_wall.warning'}),
surface = surface,
target = {180, p.y + 35},
color = {r = 255, g = 106, b = 0},
scale = 10,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
)
if adjusted_zones.reversed then
Public.set('zone1_beam1', surface.create_entity({name = 'electric-beam', position = {x_min, p.y + 30}, source = {x_min, p.y + 30}, target = {x_max, p.y + 30}}))
Public.set('zone1_beam2', surface.create_entity({name = 'electric-beam', position = {x_min, p.y + 30}, source = {x_min, p.y + 30}, target = {x_max, p.y + 30}}))
Public.set('zone1_beam3', surface.create_entity({name = 'electric-beam', position = {x_min, p.y + 30}, source = {x_min, p.y + 30}, target = {x_max, p.y + 30}}))
Public.set('alert_zone_1', true)
Public.set(
'zone1_text1',
rendering.draw_text {
text = ({'breached_wall.warning'}),
surface = surface,
target = {0, p.y - 35},
color = {r = 255, g = 106, b = 0},
scale = 10,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
)
Public.set(
'zone1_text2',
rendering.draw_text {
text = ({'breached_wall.warning'}),
surface = surface,
target = {-180, p.y - 35},
color = {r = 255, g = 106, b = 0},
scale = 10,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
)
Public.set(
'zone1_text3',
rendering.draw_text {
text = ({'breached_wall.warning'}),
surface = surface,
target = {180, p.y - 35},
color = {r = 255, g = 106, b = 0},
scale = 10,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
)
else
Public.set('zone1_beam1', surface.create_entity({name = 'electric-beam', position = {x_min, p.y}, source = {x_min, p.y}, target = {x_max, p.y}}))
Public.set('zone1_beam2', surface.create_entity({name = 'electric-beam', position = {x_min, p.y}, source = {x_min, p.y}, target = {x_max, p.y}}))
Public.set('zone1_beam3', surface.create_entity({name = 'electric-beam', position = {x_min, p.y}, source = {x_min, p.y}, target = {x_max, p.y}}))
Public.set('alert_zone_1', true)
Public.set(
'zone1_text1',
rendering.draw_text {
text = ({'breached_wall.warning'}),
surface = surface,
target = {0, p.y + 35},
color = {r = 255, g = 106, b = 0},
scale = 10,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
)
Public.set(
'zone1_text2',
rendering.draw_text {
text = ({'breached_wall.warning'}),
surface = surface,
target = {-180, p.y + 35},
color = {r = 255, g = 106, b = 0},
scale = 10,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
)
Public.set(
'zone1_text3',
rendering.draw_text {
text = ({'breached_wall.warning'}),
surface = surface,
target = {180, p.y + 35},
color = {r = 255, g = 106, b = 0},
scale = 10,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
)
end
end
end
else
@ -2750,7 +2801,7 @@ local function border_chunk(p, data)
local pos = p
if random(1, ceil(pos.y + pos.y) + 64) == 1 then
if random(1, ceil(abs(pos.y) + abs(pos.y)) + 64) == 1 then
entities[#entities + 1] = {name = trees[random(1, #trees)], position = pos}
end
@ -2761,7 +2812,7 @@ local function border_chunk(p, data)
local scrap_mineable_entities, scrap_mineable_entities_index = get_scrap_mineable_entities()
if not is_out_of_map(pos) then
if random(1, ceil(pos.y + pos.y) + 32) == 1 then
if random(1, ceil(abs(pos.y) + abs(pos.y)) + 32) == 1 then
entities[#entities + 1] = {
name = scrap_mineable_entities[random(1, scrap_mineable_entities_index)],
position = pos,
@ -2769,14 +2820,14 @@ local function border_chunk(p, data)
}
end
if random(1, pos.y + 2) == 1 then
if random(1, abs(pos.y) + 2) == 1 then
decoratives[#decoratives + 1] = {
name = 'rock-small',
position = pos,
amount = random(1, 32)
}
end
if random(1, pos.y + 2) == 1 then
if random(1, abs(pos.y) + 2) == 1 then
decoratives[#decoratives + 1] = {
name = 'rock-tiny',
position = pos,
@ -2842,31 +2893,56 @@ function Public.heavy_functions(data)
local p = data.position
local adjusted_zones = Public.get('adjusted_zones')
if adjusted_zones.disable_terrain then
return
end
init_terrain(adjusted_zones)
if not data.seed then
data.seed = Public.get('random_seed')
end
if top_y % zone_settings.zone_depth == 0 and top_y < 0 then
Public.set('left_top', data.left_top)
return wall(p, data)
end
if adjusted_zones.reversed then
if top_y % zone_settings.zone_depth == 0 and top_y > 0 then
Public.set('left_top', data.left_top)
return wall(p, data)
end
if top_y < 0 then
return process_bits(p, data, adjusted_zones)
end
if top_y > -0 then
return process_bits(p, data, adjusted_zones)
end
if top_y > 120 then
return out_of_map(p, data)
end
if top_y < -150 then
return out_of_map(p, data)
end
if top_y > 75 then
return biter_chunk(p, data)
end
if top_y < -100 then
return biter_chunk(p, data)
end
if top_y >= 0 then
return border_chunk(p, data)
if top_y <= -0 then
return border_chunk(p, data)
end
else
if top_y % zone_settings.zone_depth == 0 and top_y < 0 then
Public.set('left_top', data.left_top)
return wall(p, data)
end
if top_y < 0 then
return process_bits(p, data, adjusted_zones)
end
if top_y > 120 then
return out_of_map(p, data)
end
if top_y > 75 then
return biter_chunk(p, data)
end
if top_y >= 0 then
return border_chunk(p, data)
end
end
end
@ -2894,6 +2970,11 @@ Event.add(
return
end
local adjusted_zones = Public.get('adjusted_zones')
if adjusted_zones.disable_terrain then
return
end
local area = e.area
local left_top = area.left_top
if not surface then
@ -2918,28 +2999,53 @@ Event.add(
)
end
if left_top.y == -128 and left_top.x == -128 then
local locomotive = Public.get('locomotive')
if locomotive and locomotive.valid then
local position = locomotive.position
for _, entity in pairs(surface.find_entities_filtered({area = {{position.x - 5, position.y - 6}, {position.x + 5, position.y + 10}}, type = 'simple-entity'})) do
entity.destroy()
if adjusted_zones.reversed then
if left_top.y == 128 and left_top.x == -128 then
local locomotive = Public.get('locomotive')
if locomotive and locomotive.valid then
local position = locomotive.position
for _, entity in pairs(surface.find_entities_filtered({area = {{position.x - 5, position.y + 6}, {position.x + 5, position.y - 10}}, type = 'simple-entity'})) do
entity.destroy()
end
end
end
end
if left_top.y < -32 then
game.forces.player.chart(surface, {{left_top.x, left_top.y}, {left_top.x + 31, left_top.y + 31}})
end
local tiles = {}
if math.abs(left_top.y) > 128 then
for k, v in pairs(loading_chunk_vectors) do
tiles[k] = {name = 'out-of-map', position = {left_top.x + v[1], left_top.y + v[2]}}
if left_top.y > 32 then
game.forces.player.chart(surface, {{left_top.x, left_top.y}, {left_top.x + 31, left_top.y + 31}})
end
local tiles = {}
if left_top.y < -128 then
for k, v in pairs(loading_chunk_vectors) do
tiles[k] = {name = 'out-of-map', position = {left_top.x + v[1], left_top.y + v[2]}}
end
end
surface.set_tiles(tiles, false)
else
if left_top.y == -128 and left_top.x == -128 then
local locomotive = Public.get('locomotive')
if locomotive and locomotive.valid then
local position = locomotive.position
for _, entity in pairs(surface.find_entities_filtered({area = {{position.x - 5, position.y - 6}, {position.x + 5, position.y + 10}}, type = 'simple-entity'})) do
entity.destroy()
end
end
end
if left_top.y < -32 then
game.forces.player.chart(surface, {{left_top.x, left_top.y}, {left_top.x + 31, left_top.y + 31}})
end
local tiles = {}
if math.abs(left_top.y) > 128 then
for k, v in pairs(loading_chunk_vectors) do
tiles[k] = {name = 'out-of-map', position = {left_top.x + v[1], left_top.y + v[2]}}
end
end
surface.set_tiles(tiles, false)
end
surface.set_tiles(tiles, false)
end
)

View File

@ -26,6 +26,22 @@ local remove = table.remove
local round = math.round
local default_radius = 5
local armor_names = {
'power-armor-mk2',
'power-armor',
'modular-armor',
'heavy-armor',
'light-armor'
}
local weapon_names = {
['rocket-launcher'] = 'rocket',
['submachine-gun'] = {'uranium-rounds-magazine', 'piercing-rounds-magazine', 'firearm-magazine'},
['shotgun'] = {'piercing-shotgun-shell', 'shotgun-shell'},
['pistol'] = {'uranium-rounds-magazine', 'piercing-rounds-magazine', 'firearm-magazine'}
}
local remove_character
Public.command = {
noop = 0,
seek_and_destroy_cmd = 1,
@ -63,6 +79,8 @@ local function char_callback(callback)
local data = entities[i]
if data and data.entity and data.entity.valid then
callback(data)
elseif data and data.unit_number then
remove_character(data.unit_number)
end
end
end
@ -88,6 +106,21 @@ local function is_mining_target_taken(selected)
return false
end
local function count_active_characters(player_index)
if not next(this.characters) then
return
end
local count = 0
for _, data in pairs(this.characters) do
if data and data.player_index == player_index then
count = count + 1
end
end
return count
end
local function add_character(player_index, entity, render_id, data)
local index = #this.characters + 1
if not this.characters[index] then
@ -123,7 +156,7 @@ local function exists_character(unit_number)
return false
end
local function remove_character(unit_number)
remove_character = function(unit_number)
if not next(this.characters) then
return
end
@ -196,20 +229,37 @@ local function move_to(entity, target, min_distance)
return state.walking
end
local function refill_ammo(entity)
local function refill_ammo(player, entity)
if not entity or not entity.valid then
return
end
local inventory = player.get_main_inventory()
local weapon = entity.get_inventory(defines.inventory.character_guns)[entity.selected_gun_index]
if weapon and weapon.valid_for_read then
local selected_ammo = entity.get_inventory(defines.inventory.character_ammo)[entity.selected_gun_index]
if selected_ammo then
if not selected_ammo.valid_for_read then
if weapon.name == 'rocket-launcher' then
local player_has_ammo = inventory.get_item_count('rocket')
if player_has_ammo > 0 then
entity.insert({name = 'rocket', count = 1})
player.remove_item({name = 'rocket', count = 1})
end
end
if weapon.name == 'shotgun' then
entity.insert({name = 'shotgun-shell', count = 5})
local player_has_ammo = inventory.get_item_count('shotgun-shell')
if player_has_ammo > 4 then
entity.insert({name = 'shotgun-shell', count = 5})
player.remove_item({name = 'shotgun-shell', count = 5})
end
end
if weapon.name == 'pistol' then
entity.insert({name = 'firearm-magazine', count = 5})
local player_has_ammo = inventory.get_item_count('firearm-magazine')
if player_has_ammo > 4 then
entity.insert({name = 'firearm-magazine', count = 5})
player.remove_item({name = 'firearm-magazine', count = 5})
end
end
end
end
@ -253,7 +303,15 @@ local function shoot_stop(entity)
}
end
local function insert_weapons(entity)
local function has_armor_equipped(entity)
local armor = entity.get_inventory(defines.inventory.character_armor)[1]
if armor.valid_for_read then
return true
end
return false
end
local function insert_weapons_and_armor(player, entity, armor_only)
if not entity or not entity.valid then
return
end
@ -262,15 +320,41 @@ local function insert_weapons(entity)
return
end
if Utils.rand_range(1, 15) == 1 then
entity.insert({name = 'shotgun', count = 1})
entity.insert({name = 'shotgun-shell', count = 5})
elseif Utils.rand_range(1, 10) == 1 then
entity.insert({name = 'submachine-gun', count = 1})
entity.insert({name = 'firearm-magazine', count = 5})
else
entity.insert({name = 'pistol', count = 1})
entity.insert({name = 'firearm-magazine', count = 5})
local inventory = player.get_main_inventory()
for _, armor_name in pairs(armor_names) do
if not has_armor_equipped(entity) and inventory.get_item_count(armor_name) > 0 then
entity.insert({name = armor_name, count = 1})
player.remove_item({name = armor_name, count = 1})
break
end
end
if armor_only then
return
end
for weapon_name, ammo in pairs(weapon_names) do
if inventory.get_item_count(weapon_name) > 0 then
entity.insert({name = weapon_name, count = 1})
player.remove_item({name = weapon_name, count = 1})
if type(ammo) ~= 'table' then
if inventory.get_item_count(ammo) > 0 then
entity.insert({name = ammo, count = 1})
player.remove_item({name = ammo, count = 1})
end
else
for _, ammo_name in pairs(ammo) do
if inventory.get_item_count(ammo_name) > 0 then
entity.insert({name = ammo_name, count = 1})
player.remove_item({name = ammo_name, count = 1})
break
end
end
end
break
end
end
end
@ -331,6 +415,8 @@ local function seek_and_mine(data)
data.radius = 1
insert_weapons_and_armor(player, entity, true)
if not move_to(entity, target, 1) then
if not is_mining_target_taken(target) then
if data.raised_event then
@ -389,8 +475,8 @@ local function seek_enemy_and_destroy(data)
return
end
data.radius = default_radius
insert_weapons(entity)
refill_ammo(entity)
insert_weapons_and_armor(player, entity)
refill_ammo(player, entity)
local inside = ((entity.position.x - data.walking_position.position.x) ^ 2 + (entity.position.y - data.walking_position.position.y) ^ 2) < 1 ^ 2
data.walking_position.position = get_near_position(entity)
@ -406,7 +492,7 @@ local function seek_enemy_and_destroy(data)
data.command = Public.command.seek_and_mine_cmd
seek_and_mine(data)
else
if not move_to(entity, target, Utils.rand_range(5, 10)) then
if not move_to(entity, target, Utils.rand_range(10, 20)) then
shoot_at(entity, target)
else
shoot_stop(entity)
@ -426,11 +512,11 @@ function Public.create_char(data)
end
if not data.player_index or not data.command then
return error('No correct data was not provided.', 2)
return error('No correct data was provided.', 2)
end
if data.command ~= Public.command.seek_and_destroy_cmd and data.command ~= Public.command.attack_objects_cmd and data.command ~= Public.command.seek_and_mine_cmd then
return error('No correct command was not provided.', 2)
return error('No correct command was provided.', 2)
end
local player = game.get_player(data.player_index)
@ -438,6 +524,11 @@ function Public.create_char(data)
return error('Provided player was not valid or not connected.', 2)
end
local count = count_active_characters(data.player_index)
if count >= 5 then
return false
end
local surface = player.surface
local valid_position = surface.find_non_colliding_position('character', {x = player.position.x, y = player.position.y + 2}, 3, 0.5)
if not valid_position then

View File

@ -1122,7 +1122,7 @@ spells[#spells + 1] = {
end
}
spells[#spells + 1] = {
local drone_enemy = {
name = {'spells.drone_enemy'},
entityName = 'drone_enemy',
target = false,
@ -1140,7 +1140,11 @@ spells[#spells + 1] = {
callback = function(data)
local self = data.self
local player = data.player
Ai.create_char({player_index = player.index, command = 1, search_local = true})
local suc = Ai.create_char({player_index = player.index, command = 1, search_local = true})
if not suc then
Public.cast_spell(player, true)
return false
end
Public.cast_spell(player)
Public.remove_mana(player, self.mana_cost)
@ -1148,7 +1152,15 @@ spells[#spells + 1] = {
end
}
spells[#spells + 1] = {
if _DEBUG then
drone_enemy.mana_cost = 1
drone_enemy.level = 1
drone_enemy.cooldown = 1
end
spells[#spells + 1] = drone_enemy
local drone_mine = {
name = {'spells.drone_mine'},
entityName = 'drone_mine',
target = false,
@ -1166,7 +1178,11 @@ spells[#spells + 1] = {
callback = function(data)
local self = data.self
local player = data.player
Ai.create_char({player_index = player.index, command = 2, search_local = false})
local suc = Ai.create_char({player_index = player.index, command = 2, search_local = false})
if not suc then
Public.cast_spell(player, true)
return false
end
Public.cast_spell(player)
Public.remove_mana(player, self.mana_cost)
@ -1174,6 +1190,14 @@ spells[#spells + 1] = {
end
}
if _DEBUG then
drone_mine.mana_cost = 1
drone_mine.level = 1
drone_mine.cooldown = 1
end
spells[#spells + 1] = drone_mine
Public.projectile_types = {
['explosives'] = {name = 'grenade', count = 0.5, max_range = 32, tick_speed = 1},
['distractor-capsule'] = {name = 'distractor-capsule', count = 1, max_range = 32, tick_speed = 1},

View File

@ -418,6 +418,18 @@ local fortress_functions = {
WPT.set('winter_mode', false)
get_actor(event, '[WinteryMode]', 'has disabled wintery mode.', true)
end
end,
['disable_terrain'] = function(event)
local WPT = is_loaded('maps.mountain_fortress_v3.table')
local adjusted_zones = WPT.get('adjusted_zones')
if event.element.switch_state == 'left' then
adjusted_zones.disable_terrain = false
get_actor(event, '[TerrainGen]', 'has enabled terrain gen.', true)
else
WPT.set('winter_mode', false)
adjusted_zones.disable_terrain = true
get_actor(event, '[TerrainGen]', 'has disabled terrain gen.', true)
end
end
}
@ -777,6 +789,12 @@ local function build_config_gui(data)
end
add_switch(scroll_pane, switch_state, 'christmas_mode', 'Wintery Mode', 'On = Enables wintery mode.\nOff = Disables wintery mode.')
scroll_pane.add({type = 'line'})
if not Module.adjusted_zones.disable_terrain then
switch_state = 'left'
end
add_switch(scroll_pane, switch_state, 'disable_terrain', 'Disable Terrain', 'On = Enable terrain gen.\nOff = Disables terrain gen.')
scroll_pane.add({type = 'line'})
end
if global.tokens.maps_pirates_memory then