diff --git a/features/player_create.lua b/features/player_create.lua index b3348e15..551db8a8 100644 --- a/features/player_create.lua +++ b/features/player_create.lua @@ -48,14 +48,20 @@ local function player_created(event) gui.top.style = 'slot_table_spacing_horizontal_flow' gui.left.style = 'slot_table_spacing_vertical_flow' + if not config.cutscene then + Public.show_start_up(player) + end + + local character = player.character + if not character or not character.valid then + return + end + local player_insert = player.insert for _, item in pairs(config.starting_items) do player_insert(item) end - if not config.cutscene then - Public.show_start_up(player) - end end Event.add(defines.events.on_player_created, player_created) @@ -89,6 +95,20 @@ if _CHEATS then player.cheat_mode = true local cheats = config.cheats + if not memory.forces_initialized[force.name] then + force.manual_mining_speed_modifier = cheats.manual_mining_speed_modifier + force.character_inventory_slots_bonus = cheats.character_inventory_slots_bonus + force.character_running_speed_modifier = cheats.character_running_speed_modifier + force.character_health_bonus = cheats.character_health_bonus + end + + memory.forces_initialized[force.name] = true + + local character = player.character + if not character or not character.valid then + return + end + local player_insert = player.insert if cheats.start_with_power_armor then @@ -114,15 +134,6 @@ if _CHEATS then for _, item in pairs(cheats.starting_items) do player_insert(item) end - - if not memory.forces_initialized[force.name] then - force.manual_mining_speed_modifier = cheats.manual_mining_speed_modifier - force.character_inventory_slots_bonus = cheats.character_inventory_slots_bonus - force.character_running_speed_modifier = cheats.character_running_speed_modifier - force.character_health_bonus = cheats.character_health_bonus - end - - memory.forces_initialized[force.name] = true end Event.add(defines.events.on_player_created, player_created_cheat_mode) diff --git a/map_gen/maps/space_race.lua b/map_gen/maps/space_race.lua new file mode 100644 index 00000000..38231905 --- /dev/null +++ b/map_gen/maps/space_race.lua @@ -0,0 +1 @@ +return require 'map_gen.maps.space_race.map' diff --git a/map_gen/maps/space_race/map.lua b/map_gen/maps/space_race/map.lua new file mode 100644 index 00000000..68ccfbea --- /dev/null +++ b/map_gen/maps/space_race/map.lua @@ -0,0 +1,212 @@ +require 'map_gen.maps.space_race.scenario' + +local b = require 'map_gen.shared.builders' +local Global = require 'utils.global' +local RS = require 'map_gen.shared.redmew_surface' +local Map_gen_presets = require 'resources.map_gen_settings' +local table = require 'utils.table' +local Random = require 'map_gen.shared.random' + +local seed = nil + +local uranium_none = { + autoplace_controls = { + ['uranium-ore'] = { + frequency = 1, + richness = 1, + size = 0 + } + } +} + +RS.set_map_gen_settings({Map_gen_presets.oil_none, uranium_none}) + +local function build_map() + local width_1 = 256 + + local wilderness_shallow_water = b.line_y(width_1) + wilderness_shallow_water = b.change_tile(wilderness_shallow_water, true, 'water-shallow') -- water-mud is also walkable + + local inf = function() + return 100000000 + end + + local function no_ores(_, _, world, tile) + if not tile then + return + end + for _, e in ipairs(world.surface.find_entities_filtered({type = 'resource', area = {{world.x, world.y}, {world.x + 1, world.y + 1}}})) do + e.destroy() + end + return tile + end + + local uranium_island = b.circle(10) + uranium_island = b.apply_effect(uranium_island, no_ores) + local uranium_ore = b.resource(b.rectangle(2, 2), 'uranium-ore', inf, true) + uranium_island = b.apply_entity(uranium_island, uranium_ore) + + local uranium_island_water = b.change_tile(b.circle(20), true, 'water') + local uranium_island_bridge = b.all({b.any({b.line_x(2), b.line_y(2)}), b.circle(20)}) + uranium_island_bridge = b.change_tile(uranium_island_bridge, true, 'water-shallow') + uranium_island_water = b.if_else(uranium_island_bridge, uranium_island_water) + + uranium_island = b.if_else(uranium_island, uranium_island_water) + + wilderness_shallow_water = b.if_else(uranium_island, wilderness_shallow_water) + + local width_2 = 256 + local width_3 = 9 + + local wilderness_land = b.line_y(width_2) + + local function value(base, mult, pow) + return function(x, y) + x = x * 10 + local d = math.sqrt(x * x + y * y) + return base + mult * d ^ pow + end + end + + local function oil_transform(shape) + shape = b.throttle_world_xy(shape, 1, 6, 1, 6) + return shape + end + local ores = { + {weight = 100}, + {transform = oil_transform, resource = 'crude-oil', value = value(180000, 50, 1.1), weight = 33} + } + + local random = Random.new(seed, seed * 2) + + local total_weights = {} + local t = 0 + for _, v in ipairs(ores) do + t = t + v.weight + table.insert(total_weights, t) + end + + local p_cols = 64 + local p_rows = 64 + local pattern = {} + + for r = 1, p_rows do + local row = {} + pattern[r] = row + for c = 1, p_cols do + local i = random:next_int(1, t) + local index = table.binary_search(total_weights, i) + if (index < 0) then + index = bit32.bnot(index) + end + local ore_data = ores[index] + + local transform = ore_data.transform + if not transform then + row[c] = b.no_entity + else + local ore_shape = transform(b.circle(10)) + + local x = random:next_int(-32, 32) + local y = random:next_int(-32, 32) + + ore_shape = b.translate(ore_shape, x, y) + + local ore = b.resource(ore_shape, ore_data.resource, ore_data.value, true) + row[c] = ore + end + end + end + + local oil = b.grid_pattern_full_overlap(pattern, p_cols, p_rows, width_2, 64) + + local safe_zone = b.translate(b.circle(256), -(width_2 / 2 + width_3 / 2), 0) + + local function no_biters(_, _, world, tile) + if not tile then + return + end + for _, e in ipairs(world.surface.find_entities_filtered({type = 'unit-spawner', area = {{world.x, world.y}, {world.x + 1, world.y + 1}}})) do + e.destroy() + end + for _, e in ipairs(world.surface.find_entities_filtered({type = 'turret', area = {{world.x, world.y}, {world.x + 1, world.y + 1}}})) do + e.destroy() + end + for _, e in ipairs(world.surface.find_entities_filtered({type = 'unit', area = {{world.x, world.y}, {world.x + 1, world.y + 1}}})) do + e.destroy() + end + return tile + end + + safe_zone = b.apply_effect(safe_zone, no_biters) + + local landfill_water = b.translate(b.circle(128), -(width_2 / 2 + width_3 / 2), 0) + landfill_water = b.change_map_gen_collision_tile(landfill_water, 'water-tile', 'landfill') + + landfill_water = b.apply_effect(landfill_water, no_biters) + + wilderness_land = b.apply_entity(wilderness_land, oil) + + wilderness_land = b.add(safe_zone, wilderness_land) + + wilderness_land = b.add(landfill_water, wilderness_land) + + local small_circle = b.circle(24) + + local function constant(x) + return function() + return x + end + end + + local start_iron = b.resource(small_circle, 'iron-ore', constant(750)) + local start_copper = b.resource(small_circle, 'copper-ore', constant(600)) + local start_stone = b.resource(small_circle, 'stone', constant(600)) + local start_coal = b.resource(small_circle, 'coal', constant(600)) + local start_segmented = b.segment_pattern({start_iron, start_copper, start_stone, start_coal}) + local start_resources = b.apply_entity(small_circle, start_segmented) + start_resources = b.translate(start_resources, -(width_2 / 2 + width_3 / 2 + 59), 0) + start_resources = b.change_map_gen_collision_tile(start_resources, 'water-tile', 'landfill') + start_resources = b.apply_effect(start_resources, no_biters) + + wilderness_land = b.add(start_resources, wilderness_land) + + local wilderness_land_left = b.translate(wilderness_land, -(width_1 + width_2) / 2, 0) + local wilderness_land_right = b.translate(b.flip_x(wilderness_land), (width_1 + width_2) / 2, 0) + local wilderness_ditch = b.line_y(width_3) + wilderness_ditch = b.change_tile(wilderness_ditch, true, 'out-of-map') + wilderness_ditch = b.if_else(b.change_tile(b.rectangle(3, 17), true, 'landfill'), wilderness_ditch) + local rocket_silo_shape = b.rectangle(9, 9) + rocket_silo_shape = b.change_tile(rocket_silo_shape, true, 'landfill') + wilderness_ditch = b.if_else(rocket_silo_shape, wilderness_ditch) + + local wilderness_ditch_left = b.translate(wilderness_ditch, -(width_1 / 2 + width_2 + width_3 / 2), 0) + local wilderness_ditch_right = b.translate(b.rotate(wilderness_ditch, math.pi), (width_1 / 2 + width_2 + width_3 / 2), 0) + local wilderness = b.any({wilderness_shallow_water, wilderness_ditch_left, wilderness_ditch_right, wilderness_land_left, wilderness_land_right}) + + local map = b.if_else(wilderness, b.full_shape) + + return map +end + +local map + +local function dummy_map(x, y, world) + return map(x, y, world) +end + +Global.register_init( + {seed = seed}, + function(tbl) + local oil_seed = RS.get_surface().map_gen_settings.seed + tbl.ore_seed = oil_seed or seed + + --game.forces['player'].technologies['landfill'].enabled = false + end, + function(tbl) + seed = tbl.ore_seed + map = build_map() + end +) + +return dummy_map diff --git a/map_gen/maps/space_race/map_info.lua b/map_gen/maps/space_race/map_info.lua new file mode 100644 index 00000000..9f0f58f6 --- /dev/null +++ b/map_gen/maps/space_race/map_info.lua @@ -0,0 +1,9 @@ +local ScenarioInfo = require 'features.gui.info' + +ScenarioInfo.set_map_name('Space Race') +ScenarioInfo.set_map_description('World at War! This is not a cold war, it is a radioative hot war') +ScenarioInfo.add_map_extra_info( + [[ +Version: v0.1 +]] +) diff --git a/map_gen/maps/space_race/scenario.lua b/map_gen/maps/space_race/scenario.lua new file mode 100644 index 00000000..98a80516 --- /dev/null +++ b/map_gen/maps/space_race/scenario.lua @@ -0,0 +1,190 @@ +local Event = require 'utils.event' +local RS = require 'map_gen.shared.redmew_surface' +local Command = require 'utils.command' +local Color = require 'resources.color_presets' +local insert = table.insert + +require 'map_gen.maps.space_race.map_info' + +local config = global.config + +config.market.enabled = false + +local force_USA +local force_USSR + +local lobby_permissions + +local player_ports = { + USA = {{x = -397, y = 0}, {x = -380, y = 0}}, + USSR = {{x = 397, y = 0}, {x = 380, y = 0}} +} + +Event.on_init( + function() + force_USA = game.create_force('United Factory Employees') + force_USSR = game.create_force('Union of Factory Workers') + + local surface = RS.get_surface() + + force_USSR.set_spawn_position({x = 397, y = 0}, surface) + force_USA.set_spawn_position({x = -397, y = 0}, surface) + + lobby_permissions = game.permissions.create_group('lobby') + lobby_permissions.set_allows_action(defines.input_action.start_walking, false) + + --game.forces.player.chart(RS.get_surface(), {{x = 380, y = 16}, {x = 400, y = -16}}) + --game.forces.player.chart(RS.get_surface(), {{x = -380, y = 16}, {x = -400, y = -16}}) + + --game.forces.player.chart(RS.get_surface(), {{x = 400, y = 65}, {x = -400, y = -33}}) + + surface.create_entity {name = 'rocket-silo', position = {x = 388.5, y = -0.5}, force = force_USSR} + surface.create_entity {name = 'rocket-silo', position = {x = -388.5, y = 0.5}, force = force_USA} + + for force_side, ports in pairs(player_ports) do + local force + if force_side == 'USA' then + force = force_USA + elseif force_side == 'USSR' then + force = force_USSR + end + for _, port in pairs(ports) do + rendering.draw_text {text = {'', 'Use the /warp command to teleport across'}, surface = surface, target = port, color = Color.red, forces = {force}, alignment = 'center', scale = 0.5} + end + end + end +) + +local function victory(force) + game.print('Congratulations to ' .. force.name .. '. You have gained factory dominance!') +end + +local function lost(force) + if force == force_USA then + victory(force_USSR) + else + victory(force_USA) + end +end + +local function on_entity_died(event) + local entity = event.entity + if entity.name == 'rocket-silo' then + lost(entity.force) + end +end + +local function on_rocket_launched(event) + victory(event.entity.force) +end + +local function to_lobby(player_index) + local player = game.get_player(player_index) + lobby_permissions.add_player(player) + player.character.destroy() + player.set_controller {type = defines.controllers.ghost} + player.print('Waiting for lobby!') +end + +local function on_player_created(event) + to_lobby(event.player_index) +end + +Event.add(defines.events.on_entity_died, on_entity_died) +Event.add(defines.events.on_rocket_launched, on_rocket_launched) +Event.add(defines.events.on_player_created, on_player_created) + +local function allow_teleport(force, position) + if force == force_USA and position.x > 0 then + return false + elseif force == force_USSR and position.x < 0 then + return false + end + return math.abs(position.x) > 377 and math.abs(position.x) < 400 and position.y > -10 and position.y < 10 +end + +local function get_teleport_location(force, to_safe_zone) + local port_number = to_safe_zone and 1 or 2 + local position + if force == force_USA then + position = player_ports.USA[port_number] + elseif force == force_USSR then + position = player_ports.USSR[port_number] + else + position = {0, 0} + end + return position +end + +local function teleport(_, player) + local position = player.character.position + local force = player.force + if allow_teleport(force, position) then + if math.abs(position.x) < 388.5 then + player.teleport(get_teleport_location(force, true)) + else + player.teleport(get_teleport_location(force, false)) + end + else + player.print('[color=yellow]Could not warp, you are too far from rocket silo![/color]') + end +end + +Command.add('warp', {description = 'Use to switch between PVP and Safe-zone in Space Race', capture_excess_arguments = false, allowed_by_server = false}, teleport) + +local function join_usa(_, player) + local force = player.force + if force ~= force_USSR and force ~= force_USA then + player.force = force_USA + player.print('You have joined United Factory Employees!') + player.set_controller {type = defines.controllers.god} + player.create_character() + lobby_permissions.remove_player(player) + player.teleport(get_teleport_location(force_USA, true)) + return + end + player.print('Failed to join new team, do not be a spy!') +end + +Command.add('join-usa', {description = 'Use to join United Factory Employees in Space Race', capture_excess_arguments = false, allowed_by_server = false}, join_usa) + +local function join_ussr(_, player) + local force = player.force + if force ~= force_USSR and force ~= force_USA then + player.force = force_USSR + player.print('You have joined Union of Factory Workers!') + player.set_controller {type = defines.controllers.god} + player.create_character() + lobby_permissions.remove_player(player) + player.teleport(get_teleport_location(force_USSR, true)) + return + end + player.print('Failed to join new team, do not be a spy!') +end + +Command.add('join-ussr', {description = 'Use to join Union of Factory Workers in Space Race', capture_excess_arguments = false, allowed_by_server = false}, join_ussr) + +--393 384 -4 +5 {{x = -393, y = -4}, {x = -384, y = 5}} + +--[[TODO + +Disable artillery turret range research + +Spawn points for the two forces + +Coin rewards +Custom market with rewards brought with coins (and uranium) + +Side selection + +Waiting for players + +Artillery turret long warm up + Global warning when setup + +Disable tank recipe -> Brought with coins in the market + Global warning when deployed + +Introduction / Map information + +Starting trees! + +]]