diff --git a/comfy_panel/poll.lua b/comfy_panel/poll.lua index 913819ee..4e8274a1 100644 --- a/comfy_panel/poll.lua +++ b/comfy_panel/poll.lua @@ -105,6 +105,7 @@ local function do_remaining_time(poll, remaining_time_label) local ticks = end_tick - game.tick if ticks < 0 then remaining_time_label.caption = 'Poll Finished.' + polls.running = false return false else local time = math.ceil(ticks / 60) @@ -726,6 +727,8 @@ local function create_poll(event) insert(polls, poll_data) + polls.running = true + show_new_poll(poll_data) send_poll_result_to_discord(poll_data) @@ -828,11 +831,9 @@ local function player_joined(event) end local function tick() - for _, v in pairs(polls) do - if game.tick >= v.end_tick then - return - end - end + if not polls.running then + return + end for _, p in pairs(game.connected_players) do local frame = p.gui.left[main_frame_name] if frame and frame.valid then @@ -1213,7 +1214,6 @@ function Class.reset() end function Class.get_no_notify_players() - log(serpent.block(no_notify_players)) return no_notify_players end diff --git a/maps/biter_battles_v2/functions.lua b/maps/biter_battles_v2/functions.lua index 1fc84fd7..dba4efc1 100644 --- a/maps/biter_battles_v2/functions.lua +++ b/maps/biter_battles_v2/functions.lua @@ -136,7 +136,7 @@ end function Public.init_player(player) local surface = game.surfaces.biter_battles - if player.crafting_queue then + if player.crafting_queue_size and player.crafting_queue_size > 0 then for i = 1, #player.crafting_queue, 1 do if player.crafting_queue_size == 0 then break end player.cancel_crafting({index = 1, count = 65535}) diff --git a/maps/biter_battles_v2/game_over.lua b/maps/biter_battles_v2/game_over.lua index 835d8826..35948e58 100644 --- a/maps/biter_battles_v2/game_over.lua +++ b/maps/biter_battles_v2/game_over.lua @@ -98,7 +98,7 @@ local function silo_kaboom(entity) local surface = entity.surface local center_position = entity.position local force = entity.force - local r = 46 + local r = 32 local square_distance = r ^ 2 local shells_square_distance = square_distance * 0.75 local kabooms = {"explosive-cannon-projectile", "explosive-cannon-projectile", "artillery-projectile"} diff --git a/maps/biter_battles_v2/mirror_terrain.lua b/maps/biter_battles_v2/mirror_terrain.lua index 3d90db7b..230bbd16 100644 --- a/maps/biter_battles_v2/mirror_terrain.lua +++ b/maps/biter_battles_v2/mirror_terrain.lua @@ -281,8 +281,9 @@ local works = { } function Public.ticking_work() - local work = works[game.ticks_played % 2 + 1] - if not work then return end + local tick = game.ticks_played + if tick < 4 then return end + local work = works[tick % 2 + 1] if global.server_restart_timer then return end work() end diff --git a/maps/biter_battles_v2/terrain.lua b/maps/biter_battles_v2/terrain.lua index 5cf492dc..d85027f0 100644 --- a/maps/biter_battles_v2/terrain.lua +++ b/maps/biter_battles_v2/terrain.lua @@ -567,6 +567,9 @@ function Public.generate_spawn_goodies(surface) ["production-science-pack"] = true, ["utility-science-pack"] = true, ["space-science-pack"] = true, + ["loader"] = true, + ["fast-loader"] = true, + ["express-loader"] = true, } local container_names = {"wooden-chest", "wooden-chest", "iron-chest"} for k, tile in pairs(tiles) do diff --git a/maps/mountain_fortress_v2/main.lua b/maps/mountain_fortress_v2/main.lua index fcea9395..ca58f4c6 100644 --- a/maps/mountain_fortress_v2/main.lua +++ b/maps/mountain_fortress_v2/main.lua @@ -1,7 +1,5 @@ -- Mountain digger fortress, protect the cargo wagon! -- by MewMew - --enable / disable collapsing of the map -global.collapse_enabled = true global.offline_loot = true local darkness = false @@ -9,6 +7,7 @@ require "player_modifiers" require "functions.soft_reset" require "functions.basic_markets" +local Collapse = require "modules.collapse" local RPG = require "modules.rpg" require "modules.wave_defense.main" require "modules.biters_yield_coins" @@ -21,7 +20,6 @@ require "modules.rocks_heal_over_time" require "modules.rocks_yield_ore_veins" local level_depth = require "maps.mountain_fortress_v2.terrain" local Immersive_cargo_wagons = require "modules.immersive_cargo_wagons.main" -local Collapse = require "maps.mountain_fortress_v2.collapse" require "maps.mountain_fortress_v2.flamethrower_nerf" local BiterRolls = require "modules.wave_defense.biter_rolls" local BiterHealthBooster = require "modules.biter_health_booster" @@ -45,14 +43,16 @@ local treasure_chest_messages = { local function set_difficulty() local wave_defense_table = WD.get_table() local player_count = #game.connected_players - + wave_defense_table.max_active_biters = 1024 -- threat gain / wave wave_defense_table.threat_gain_multiplier = 2 + player_count * 0.1 - --1 additional map collapse tile / 8 players in game, with too high threat, the collapse speeds up. - global.map_collapse.speed = math.floor(player_count * 0.125) + 1 + math.floor(wave_defense_table.threat / 100000) + local amount = player_count * 0.25 + 21 + amount = math.floor(amount) + if amount > 10 then amount = 10 end + Collapse.set_amount(amount) --20 Players for fastest wave_interval wave_defense_table.wave_interval = 3600 - player_count * 90 @@ -61,7 +61,7 @@ end function Public.reset_map() Immersive_cargo_wagons.reset() - + for _,player in pairs(game.players) do if player.controller_type == defines.controllers.editor then player.toggle_map_editor() end end @@ -135,8 +135,14 @@ function Public.reset_map() wave_defense_table.nest_building_density = 32 wave_defense_table.game_lost = false game.reset_time_played() - - Collapse.init() + + Collapse.set_kill_entities(false) + Collapse.set_speed(2) + Collapse.set_amount(1) + Collapse.set_max_line_size(level_depth) + Collapse.set_surface(surface) + Collapse.set_position({0, 130}) + Collapse.set_direction("north") RPG.rpg_reset_all_players() @@ -431,15 +437,11 @@ local function tick() if tick % 1800 == 0 then Locomotive.set_player_spawn_and_refill_fish() local surface = game.surfaces[global.active_surface_index] - local last_position = global.map_collapse.last_position - local position = surface.find_non_colliding_position("stone-furnace", {last_position.x, last_position.y - 32}, 128, 4) + local position = surface.find_non_colliding_position("stone-furnace", Collapse.get_position(), 128, 1) if position then local wave_defense_table = WD.get_table() wave_defense_table.spawn_position = position end - -- if tick % 216000 == 0 then - -- Collapse.delete_out_of_map_chunks(surface) - -- end if global.offline_loot then offline_players() end @@ -453,8 +455,6 @@ local function tick() end Locomotive.fish_tag() end - if not global.collapse_enabled then return end - Collapse.process() end local function on_init() diff --git a/maps/railway_troopers_v2/main.lua b/maps/railway_troopers_v2/main.lua index ce7a734f..a3c4e2d9 100644 --- a/maps/railway_troopers_v2/main.lua +++ b/maps/railway_troopers_v2/main.lua @@ -1,5 +1,6 @@ require "modules.biters_yield_ore" require "modules.difficulty_vote" +require "modules.satellite_score" local difficulties_votes = { [1] = 32, @@ -182,7 +183,7 @@ local function on_chunk_generated(event) local seed = game.surfaces["railway_troopers"].map_gen_settings.seed for _, e in pairs(surface.find_entities_filtered({force = "enemy", area = event.area})) do local noise = Get_noise("n3", e.position, seed) - if noise > 0 then e.destroy() end + if noise > 0.05 then e.destroy() end end end diff --git a/maps/scrapyard/burden.lua b/maps/scrapyard/burden.lua new file mode 100644 index 00000000..a3b454d5 --- /dev/null +++ b/maps/scrapyard/burden.lua @@ -0,0 +1,57 @@ +local Event = require 'utils.event' +local Modifier = require "player_modifiers" +local Color = require 'utils.color_presets' + +local function validate_player(player) + if not player then return false end + if not player.valid then return false end + if not player.character then return false end + if not player.connected then return false end + if not game.players[player.name] then return false end + return true +end + +local function compute_fullness(player) + local inv = player.get_inventory(defines.inventory.character_main) + local max_stacks = #inv + local num_stacks = 0 + + local contents = inv.get_contents() + for item, count in pairs(contents) do + local stack_size = 1 + if game.item_prototypes[item].stackable then + stack_size = game.item_prototypes[item].stack_size + end + + num_stacks = num_stacks + count / stack_size + end + + return num_stacks / max_stacks +end + +local function check_burden(event) + local player_modifiers = Modifier.get_table() + local player = game.players[event.player_index] + validate_player(player) + local fullness = compute_fullness(player) + player_modifiers[player.index].character_running_speed_modifier["scrapyard"] = 0.3 - fullness + player_modifiers[player.index].character_mining_speed_modifier["scrapyard"] = 0.3 - fullness + Modifier.update_player_modifiers(player) + if fullness >= 0.5 and fullness <= 0.51 then + player.print("You feel all of a sudden burden.", Color.yellow) + elseif fullness >= 0.9 and fullness <= 0.91 then + player.print("Maybe you should drop some of that inventory to lessen the burden.", Color.red) + end +end + + +local function on_init(event) + script.on_event(defines.events.on_player_main_inventory_changed, check_burden) +end + +local function on_load(event) + script.on_event(defines.events.on_player_main_inventory_changed, check_burden) +end + +Event.on_init(on_init) +Event.on_load(on_load) diff --git a/maps/scrapyard/comfylatron.lua b/maps/scrapyard/comfylatron.lua index 401b15f1..dbf47816 100644 --- a/maps/scrapyard/comfylatron.lua +++ b/maps/scrapyard/comfylatron.lua @@ -21,10 +21,10 @@ local texts = { "psk psk psk, over here", "on my way", "i need to leave", - "comfylatron seeking target", + "grandmaster seeking target", "gotta go fast", "gas gas gas", - "comfylatron coming through" + "grandmaster coming through" }, ["greetings"] = { "=^_^=", @@ -46,7 +46,8 @@ local texts = { "Hello everyone", "Hey engineers", "Hey", - "Hi" + "Hi", + "... nerds!" }, ["talks"] = { "We’re making beer. I’m the brewery!", @@ -54,6 +55,7 @@ local texts = { "Hey sexy mama. Wanna kill all humans?", "My story is a lot like yours, only more interesting ‘cause it involves robots.", "I'm 40% zinc!", + "Is this the right way to the junkyard?", "There was nothing wrong with that food. The salt level was 10% less than a lethal dose.", "One zero zero zero one zero one zero one zero one zero one... two.", "My place is two cubic meters, and we only take up 1.5 cubic meters. We've got room for a whole 'nother two thirds of a person!", @@ -64,6 +66,7 @@ local texts = { "Never discuss infinity with me. I can go on about it forever >.<", "I realised the decimals have a point.", "Do you want a piece of pi?", + "Oh boy, we're soon home!", "I have 13 children, i know how to multiply ^.^", "I am a weapon of math disruption!", "My grandma makes the best square roots :3", @@ -92,6 +95,7 @@ local texts = { "*_*", "I came here with a simple dream... a dream of killing all humans. And this is how it must end?", "Bot-on-bot violence? Where will it end?", + "Will no one assist the grandmaster?", "Thanks to you, I went on a soul-searching journey. I hate those!", "From now on, you guys'll do all the work while I sit on the couch and do nothing." } @@ -358,8 +362,8 @@ local function spawn_comfylatron(surface, x, y) if not this.comfylatron_last_player_visit then this.comfylatron_last_player_visit = 0 end if not this.comfylatron_habitat then this.comfylatron_habitat = { - left_top = {x = -9, y = -6}, - right_bottom = {x = 10, y = 38} + left_top = {x = -18, y = 3}, + right_bottom = {x = 17, y = 67} } end this.comfylatron = surface.create_entity({ diff --git a/maps/scrapyard/icw/constants.lua b/maps/scrapyard/icw/constants.lua new file mode 100644 index 00000000..d9f5b8b4 --- /dev/null +++ b/maps/scrapyard/icw/constants.lua @@ -0,0 +1,17 @@ +local Public = {} + +Public.wagon_types = { + ["cargo-wagon"] = true, + ["artillery-wagon"] = true, + ["fluid-wagon"] = true, + ["locomotive"] = true, +} + +Public.wagon_areas = { + ["cargo-wagon"] = {left_top = {x = -18, y = 0}, right_bottom = {x = 18, y = 70}}, + ["artillery-wagon"] = {left_top = {x = -18, y = 0}, right_bottom = {x = 18, y = 70}}, + ["fluid-wagon"] = {left_top = {x = -18, y = 0}, right_bottom = {x = 18, y = 70}}, + ["locomotive"] = {left_top = {x = -18, y = 0}, right_bottom = {x = 18, y = 70}}, +} + +return Public \ No newline at end of file diff --git a/maps/scrapyard/icw/functions.lua b/maps/scrapyard/icw/functions.lua new file mode 100644 index 00000000..46bcea96 --- /dev/null +++ b/maps/scrapyard/icw/functions.lua @@ -0,0 +1,585 @@ +local Public = {} + +local Constants = require "maps.scrapyard.icw.constants" + +local table_insert = table.insert +local table_remove = table.remove +local math_round = math.round +local math_random = math.random + +function Public.request_reconstruction(icw) + icw.rebuild_tick = game.tick + 30 +end + +local function delete_empty_surfaces(icw) + for k, surface in pairs(icw.surfaces) do + if not icw.trains[tonumber(surface.name)] then + game.delete_surface(surface) + table_remove(icw.surfaces, k) + end + end +end + +local function connect_power_pole(entity, wagon_area_left_top_y) + local surface = entity.surface + local max_wire_distance = entity.prototype.max_wire_distance + local area = { + {entity.position.x - max_wire_distance, entity.position.y - max_wire_distance}, + {entity.position.x + max_wire_distance, entity.position.y - 1}, + } + for _, pole in pairs(surface.find_entities_filtered({area = area, name = entity.name})) do + if pole.position.y < wagon_area_left_top_y then + entity.connect_neighbour(pole) + return + end + end +end + +local function equal_fluid(source_tank, target_tank) + local source_fluid = source_tank.fluidbox[1] + if not source_fluid then return end + + local target_fluid = target_tank.fluidbox[1] + local source_fluid_amount = source_fluid.amount + + local amount + if target_fluid then + amount = source_fluid_amount - ((target_fluid.amount + source_fluid_amount) * 0.5) + else + amount = source_fluid.amount * 0.5 + end + + if amount <= 0 then return end + + local inserted_amount = target_tank.insert_fluid({name = source_fluid.name, amount = amount, temperature = source_fluid.temperature}) + if inserted_amount > 0 then source_tank.remove_fluid({name = source_fluid.name, amount = inserted_amount}) end +end + +local function divide_fluid(wagon, storage_tank) + local fluid_wagon = wagon.entity + equal_fluid(fluid_wagon, storage_tank) + equal_fluid(storage_tank, fluid_wagon) +end + +local function input_filtered(wagon_inventory, chest, chest_inventory, free_slots) + local request_stacks = {} + local prototypes = game.item_prototypes + for slot_index = 1, 4, 1 do + local stack = chest.get_request_slot(slot_index) + if stack then + request_stacks[stack.name] = 10 * prototypes[stack.name].stack_size + end + end + for i = 1, wagon_inventory.get_bar() - 1, 1 do + if free_slots <= 0 then return end + local stack = wagon_inventory[i] + if stack.valid_for_read then + local request_stack = request_stacks[stack.name] + if request_stack and request_stack > chest_inventory.get_item_count(stack.name) then + chest_inventory.insert(stack) + stack.clear() + free_slots = free_slots - 1 + end + end + end +end + +local function input_cargo(wagon, chest) + if not chest.request_from_buffers then return end + + local wagon_entity = wagon.entity + if not wagon_entity.valid then + wagon.transfer_entities = nil + return + end + + local wagon_inventory = wagon_entity.get_inventory(defines.inventory.cargo_wagon) + if wagon_inventory.is_empty() then return end + + local chest_inventory = chest.get_inventory(defines.inventory.chest) + local free_slots = 0 + for i = 1, chest_inventory.get_bar() - 1, 1 do + if not chest_inventory[i].valid_for_read then free_slots = free_slots + 1 end + end + + if chest.get_request_slot(1) then input_filtered(wagon_inventory, chest, chest_inventory, free_slots) return end + + for i = 1, wagon_inventory.get_bar() - 1, 1 do + if free_slots <= 0 then return end + if wagon_inventory[i].valid_for_read then + chest_inventory.insert(wagon_inventory[i]) + wagon_inventory[i].clear() + free_slots = free_slots - 1 + end + end +end + +local function output_cargo(wagon, passive_chest) + local passive_chest_inventory = passive_chest.get_inventory(defines.inventory.cargo_wagon) + if passive_chest_inventory.is_empty() then return end + local wagon_inventory = wagon.entity.get_inventory(defines.inventory.cargo_wagon) + local free_slots = 0 + for i = 1, wagon_inventory.get_bar() - 1, 1 do + if not wagon_inventory[i].valid_for_read and not wagon_inventory.get_filter(i) then free_slots = free_slots + 1 end + end + for i = 1, passive_chest_inventory.get_bar() - 1, 1 do + if free_slots <= 0 then return end + if passive_chest_inventory[i].valid_for_read then + wagon_inventory.insert(passive_chest_inventory[i]) + passive_chest_inventory[i].clear() + free_slots = free_slots - 1 + end + end +end + +local transfer_functions = { + ["storage-tank"] = divide_fluid, + ["logistic-chest-requester"] = input_cargo, + ["logistic-chest-passive-provider"] = output_cargo, +} + +local function get_wagon_for_entity(icw, entity) + local train = icw.trains[tonumber(entity.surface.name)] + if not train then return end + local position = entity.position + for k, unit_number in pairs(train.wagons) do + local wagon = icw.wagons[unit_number] + if wagon then + local left_top = wagon.area.left_top + local right_bottom = wagon.area.right_bottom + if position.x >= left_top.x and position.y >= left_top.y and position.x <= right_bottom.x and position.y <= right_bottom.y then + return wagon + end + end + end + return false +end + +local function kill_wagon_doors(icw, wagon) + for k, e in pairs(wagon.doors) do + icw.doors[e.unit_number] = nil + e.destroy() + wagon.doors[k] = nil + end +end + +local function construct_wagon_doors(icw, wagon) + local area = wagon.area + local surface = wagon.surface + + for _, x in pairs({area.left_top.x - 0.55, area.right_bottom.x + 0.55}) do + 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 + }) + e.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 1}) + e.destructible = false + e.minable = false + e.operable = false + icw.doors[e.unit_number] = wagon.entity.unit_number + table_insert(wagon.doors, e) + end +end + +local function get_player_data(icw, player) + local player_data = icw.players[player.index] + if icw.players[player.index] then return player_data end + + icw.players[player.index] = { + zoom = 0.30, + map_size = 360, + } + return icw.players[player.index] +end + +function Public.kill_minimap(player) + local element = player.gui.left.icw_map + if element then element.destroy() end +end + +function Public.kill_wagon(icw, entity) + if not Constants.wagon_types[entity.type] then return end + local wagon = icw.wagons[entity.unit_number] + local surface = wagon.surface + kill_wagon_doors(icw, wagon) + for _, e in pairs(surface.find_entities_filtered({area = wagon.area})) do + if e.name == "character" and e.player then + local p = wagon.entity.surface.find_non_colliding_position("character", wagon.entity.position, 128, 0.5) + if p then + e.player.teleport(p, wagon.entity.surface) + else + e.player.teleport(wagon.entity.position, wagon.entity.surface) + end + Public.kill_minimap(e.player) + else + e.die() + end + end + for _, tile in pairs(surface.find_tiles_filtered({area = wagon.area})) do + surface.set_tiles({{name = "out-of-map", position = tile.position}}, true) + end + wagon.entity.force.chart(surface, wagon.area) + icw.wagons[entity.unit_number] = nil + Public.request_reconstruction(icw) +end + +function Public.create_room_surface(icw, unit_number) + if game.surfaces[tostring(unit_number)] then return game.surfaces[tostring(unit_number)] end + local map_gen_settings = { + ["width"] = 2, + ["height"] = 2, + ["water"] = 0, + ["starting_area"] = 1, + ["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}, + }, + } + local surface = game.create_surface(unit_number, map_gen_settings) + surface.freeze_daytime = true + surface.daytime = 0.1 + surface.request_to_generate_chunks({16, 16}, 2) + 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) + end + table_insert(icw.surfaces, surface) + return surface +end + +function Public.create_wagon_room(icw, wagon) + local surface = wagon.surface + local area = wagon.area + + local main_tile_name = "tutorial-grid" + --if wagon.entity.type == "locomotive" then + -- main_tile_name = "lab-dark-2" + --end + + local tiles = {} + for x = -3, 2, 1 do + table_insert(tiles, {name = "hazard-concrete-right", position = {x, area.left_top.y}}) + table_insert(tiles, {name = "hazard-concrete-right", position = {x, area.right_bottom.y - 1}}) + end + for x = area.left_top.x, area.right_bottom.x - 1, 1 do + for y = area.left_top.y + 2, area.right_bottom.y - 3, 1 do + table_insert(tiles, {name = main_tile_name, position = {x, y}}) + end + end + for x = -3, 2, 1 do + for y = 1, 3, 1 do + table_insert(tiles, {name = main_tile_name, position = {x,y}}) + end + for y = area.right_bottom.y - 4, area.right_bottom.y - 2, 1 do + table_insert(tiles, {name = main_tile_name, position = {x,y}}) + end + end + + if wagon.entity.type == "locomotive" then + for x = -3, 2, 1 do + for y = 10, 12, 1 do + table_insert(tiles, {name = "water", position = {x, y}}) + end + end + end + + surface.set_tiles(tiles, true) + + construct_wagon_doors(icw, wagon) + + if wagon.entity.type == "fluid-wagon" then + local height = area.right_bottom.y - area.left_top.y + local positions = { + {area.right_bottom.x, area.left_top.y + height * 0.25}, + {area.right_bottom.x, area.left_top.y + height * 0.75}, + {area.left_top.x - 1, area.left_top.y + height * 0.25}, + {area.left_top.x - 1, area.left_top.y + height * 0.75}, + } + table.shuffle_table(positions) + local e = surface.create_entity({ + name = "storage-tank", + position = positions[1], + force = "neutral", + create_build_effect_smoke = false + }) + e.destructible = false + e.minable = false + wagon.transfer_entities = {e} + return + end + + if wagon.entity.type == "cargo-wagon" then + local vectors = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}} + local v = vectors[math_random(1, 4)] + local position = {math_random(area.left_top.x + 4, area.right_bottom.x - 4), math_random(area.left_top.y + 6, area.right_bottom.y - 6)} + + local e = surface.create_entity({ + name = "logistic-chest-requester", + position = position, + force = "neutral", + create_build_effect_smoke = false + }) + e.destructible = false + e.minable = false + + e2 = surface.create_entity({ + name = "logistic-chest-passive-provider", + position = {position[1] + v[1], position[2] + v[2]}, + force = "neutral", + create_build_effect_smoke = false + }) + e2.destructible = false + e2.minable = false + + wagon.transfer_entities = {e, e2} + return + end +end + +function Public.create_wagon(icw, created_entity) + if not created_entity.unit_number then return end + if icw.trains[tonumber(created_entity.surface.name)] or icw.wagons[tonumber(created_entity.surface.name)] then return end + if not Constants.wagon_types[created_entity.type] then return end + local wagon_area = Constants.wagon_areas[created_entity.type] + + icw.wagons[created_entity.unit_number] = { + entity = created_entity, + area = {left_top = {x = wagon_area.left_top.x, y = wagon_area.left_top.y}, right_bottom = {x = wagon_area.right_bottom.x, y = wagon_area.right_bottom.y}}, + surface = Public.create_room_surface(icw, created_entity.unit_number), + doors = {}, + entity_count = 0, + } + Public.create_wagon_room(icw, icw.wagons[created_entity.unit_number]) + Public.request_reconstruction(icw) + return icw.wagons[created_entity.unit_number] +end + +function Public.add_wagon_entity_count(icw, added_entity) + local wagon = get_wagon_for_entity(icw, added_entity) + if not wagon then return end + wagon.entity_count = wagon.entity_count + 1 + wagon.entity.minable = false +end + +function Public.subtract_wagon_entity_count(icw, removed_entity) + local wagon = get_wagon_for_entity(icw, removed_entity) + if not wagon then return end + wagon.entity_count = wagon.entity_count - 1 + if wagon.entity_count > 0 then return end + wagon.entity.minable = true +end + +function Public.use_cargo_wagon_door(icw, player, door) + local player_data = get_player_data(icw, player) + if player_data.state then + player_data.state = player_data.state - 1 + if player_data.state == 0 then + player_data.state = nil + end + return + end + + if not door then return end + if not door.valid then return end + local doors = icw.doors + local wagons = icw.wagons + + local wagon = false + if doors[door.unit_number] then wagon = wagons[doors[door.unit_number]] end + if wagons[door.unit_number] then wagon = wagons[door.unit_number] end + if not wagon then return end + + if wagon.entity.surface.name ~= player.surface.name then + local surface = wagon.entity.surface + local x_vector = (door.position.x / math.abs(door.position.x)) * 2 + local position = {wagon.entity.position.x + x_vector, wagon.entity.position.y} + local position = surface.find_non_colliding_position("character", position, 128, 0.5) + if not position then return end + player.teleport(position, surface) + player_data.state = 2 + player.driving = true + Public.kill_minimap(player) + else + local surface = wagon.surface + local area = wagon.area + 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)} + else + 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 + player.teleport(p, surface) + else + player.teleport(position, surface) + end + end +end + +function Public.move_room_to_train(icw, train, wagon) + if not wagon then return end + + table_insert(train.wagons, wagon.entity.unit_number) + + local destination_area = { + left_top = {x = wagon.area.left_top.x, y = train.top_y}, + right_bottom = {x = wagon.area.right_bottom.x, y = train.top_y + (wagon.area.right_bottom.y - wagon.area.left_top.y)} + } + + train.top_y = destination_area.right_bottom.y + + if destination_area.left_top.x == wagon.area.left_top.x and destination_area.left_top.y == wagon.area.left_top.y and wagon.surface.name == train.surface.name then return end + + kill_wagon_doors(icw, wagon) + + local player_positions = {} + for _, e in pairs(wagon.surface.find_entities_filtered({name = "character", area = wagon.area})) do + local player = e.player + if player then + player_positions[player.index] = {player.position.x, player.position.y + (destination_area.left_top.y - wagon.area.left_top.y)} + player.teleport({0,0}, game.surfaces.nauvis) + end + end + + wagon.surface.clone_area({ + source_area = wagon.area, + destination_area = destination_area, + destination_surface = train.surface, + clone_tiles = true, + clone_entities = true, + clone_decoratives = true, + clear_destination_entities = true, + clear_destination_decoratives = true, + expand_map = true, + }) + + for player_index, position in pairs(player_positions) do + local player = game.players[player_index] + player.teleport(position, train.surface) + end + + for _, tile in pairs(wagon.surface.find_tiles_filtered({area = wagon.area})) do + wagon.surface.set_tiles({{name = "out-of-map", position = tile.position}}, true) + end + wagon.entity.force.chart(wagon.surface, wagon.area) + + wagon.surface = train.surface + wagon.area = destination_area + wagon.transfer_entities = {} + construct_wagon_doors(icw, wagon) + + local left_top_y = wagon.area.left_top.y + for _, e in pairs(wagon.surface.find_entities_filtered({type = "electric-pole", area = wagon.area})) do + connect_power_pole(e, left_top_y) + end + + for _, e in pairs(wagon.surface.find_entities_filtered({area = wagon.area, force = "neutral"})) do + if transfer_functions[e.name] then + table_insert(wagon.transfer_entities, e) + end + end +end + +function Public.construct_train(icw, carriages) + local unit_number = carriages[1].unit_number + + if icw.trains[unit_number] then return end + + local train = {surface = Public.create_room_surface(icw, unit_number), wagons = {}, top_y = 0} + icw.trains[unit_number] = train + + for k, carriage in pairs(carriages) do + Public.move_room_to_train(icw, train, icw.wagons[carriage.unit_number]) + end +end + +function Public.reconstruct_all_trains(icw) + icw.trains = {} + for unit_number, wagon in pairs(icw.wagons) do + if wagon.entity and wagon.entity.valid then + local carriages = wagon.entity.train.carriages + Public.construct_train(icw, carriages) + end + end + delete_empty_surfaces(icw) +end + +function Public.item_transfer(icw) + for _, wagon in pairs(icw.wagons) do + if wagon.transfer_entities then + for k, e in pairs(wagon.transfer_entities) do + transfer_functions[e.name](wagon, e) + end + end + end +end + +function Public.draw_minimap(icw, player, surface, position) + local element = player.gui.left.icw_map + if not element then + local player_data = get_player_data(icw, player) + element = player.gui.left.add({ + type = "camera", + name = "icw_map", + position = position, + surface_index = surface.index, + zoom = player_data.zoom, + tooltip = "LMB: Increase zoom level.\nRMB: Decrease zoom level.\nMMB: Toggle camera size." + }) + element.style.margin = 1 + element.style.minimal_height = player_data.map_size + element.style.minimal_width = player_data.map_size + return + end + element.position = position +end + +function Public.update_minimap(icw) + for k, player in pairs(game.connected_players) do + if player.character and player.character.valid then + local wagon = get_wagon_for_entity(icw, player.character) + if wagon then + Public.draw_minimap(icw, player, wagon.entity.surface, wagon.entity.position) + end + end + end +end + +function Public.toggle_minimap(icw, event) + local element = event.element + if not element then return end + if not element.valid then return end + if element.name ~= "icw_map" then return end + local player = game.players[event.player_index] + local player_data = get_player_data(icw, player) + if event.button == defines.mouse_button_type.right then + player_data.zoom = player_data.zoom - 0.07 + if player_data.zoom < 0.07 then player_data.zoom = 0.07 end + element.zoom = player_data.zoom + return + end + if event.button == defines.mouse_button_type.left then + player_data.zoom = player_data.zoom + 0.07 + if player_data.zoom > 2 then player_data.zoom = 2 end + element.zoom = player_data.zoom + return + end + if event.button == defines.mouse_button_type.middle then + player_data.map_size = player_data.map_size + 50 + if player_data.map_size > 650 then player_data.map_size = 250 end + element.style.minimal_height = player_data.map_size + element.style.minimal_width = player_data.map_size + element.style.maximal_height = player_data.map_size + element.style.maximal_width = player_data.map_size + return + end +end + +return Public \ No newline at end of file diff --git a/maps/scrapyard/icw/main.lua b/maps/scrapyard/icw/main.lua new file mode 100644 index 00000000..89f4e952 --- /dev/null +++ b/maps/scrapyard/icw/main.lua @@ -0,0 +1,148 @@ +local Global = require 'utils.global' +local Event = require 'utils.event' +local Functions = require "maps.scrapyard.icw.functions" +local Public = {} + +local math_round = math.round + +local icw = {} +Global.register( + icw, + function(tbl) + icw = tbl + end +) + +function Public.reset() + if icw.surfaces then + for k, surface in pairs(icw.surfaces) do + if surface and surface.valid then + game.delete_surface(surface) + end + end + end + for k, v in pairs(icw) do icw[k] = nil end + icw.doors = {} + icw.wagons = {} + icw.trains = {} + icw.players = {} + icw.surfaces = {} +end + +local function on_entity_died(event) + local entity = event.entity + if not entity and not entity.valid then return end + Functions.subtract_wagon_entity_count(icw, entity) + Functions.kill_wagon(icw, entity) +end + +local function on_player_mined_entity(event) + local entity = event.entity + if not entity and not entity.valid then return end + Functions.subtract_wagon_entity_count(icw, entity) + Functions.kill_wagon(icw, entity) +end + +local function on_robot_mined_entity(event) + local entity = event.entity + if not entity and not entity.valid then return end + Functions.subtract_wagon_entity_count(icw, entity) + Functions.kill_wagon(icw, entity) +end + +local function on_built_entity(event) + local created_entity = event.created_entity + Functions.create_wagon(icw, created_entity) + Functions.add_wagon_entity_count(icw, created_entity) +end + +local function on_robot_built_entity(event) + local created_entity = event.created_entity + Functions.create_wagon(icw, created_entity) + Functions.add_wagon_entity_count(icw, created_entity) +end + +local function on_player_driving_changed_state(event) + local player = game.players[event.player_index] + Functions.use_cargo_wagon_door(icw, player, event.entity) +end +--[[ +local function on_player_created(event) + local player = game.players[event.player_index] + player.insert({name = "cargo-wagon", count = 5}) + player.insert({name = "artillery-wagon", count = 5}) + player.insert({name = "fluid-wagon", count = 5}) + player.insert({name = "locomotive", count = 5}) + player.insert({name = "rail", count = 100}) +end +]] +local function on_gui_closed(event) + local entity = event.entity + if not entity then return end + if not entity.valid then return end + if not entity.unit_number then return end + if not icw.wagons[entity.unit_number] then return end + Functions.kill_minimap(game.players[event.player_index]) +end + +local function on_gui_opened(event) + local entity = event.entity + if not entity then return end + if not entity.valid then return end + if not entity.unit_number then return end + local wagon = icw.wagons[entity.unit_number] + if not wagon then return end + Functions.draw_minimap(icw, game.players[event.player_index], wagon.surface, {wagon.area.left_top.x + (wagon.area.right_bottom.x - wagon.area.left_top.x) * 0.5, wagon.area.left_top.y + (wagon.area.right_bottom.y - wagon.area.left_top.y) * 0.5}) +end + +local function on_player_died(event) + Functions.kill_minimap(game.players[event.player_index]) +end + +local function on_train_created(event) + Functions.request_reconstruction(icw) +end + +local function on_gui_click(event) + Functions.toggle_minimap(icw, event) +end + +local function on_tick() + local tick = game.tick + if tick % 60 == 0 then Functions.item_transfer(icw) end + if tick % 240 == 0 then Functions.update_minimap(icw) end + + if not icw.rebuild_tick then return end + if icw.rebuild_tick ~= tick then return end + Functions.reconstruct_all_trains(icw) + icw.rebuild_tick = nil +end + +local function on_init() + Public.reset() +end + +function Public.get_table() + return icw +end + +function Public.register_wagon(wagon_entity) + return Functions.create_wagon(icw, wagon_entity) +end + +Event.on_init(on_init) +Event.add(defines.events.on_tick, on_tick) +Event.add(defines.events.on_player_driving_changed_state, on_player_driving_changed_state) +Event.add(defines.events.on_entity_died, on_entity_died) +Event.add(defines.events.on_built_entity, on_built_entity) +Event.add(defines.events.on_train_created, on_train_created) +Event.add(defines.events.on_robot_built_entity, on_robot_built_entity) +Event.add(defines.events.on_player_died, on_player_died) +--Event.add(defines.events.on_player_created, on_player_created) +Event.add(defines.events.on_gui_click, on_gui_click) +Event.add(defines.events.on_gui_closed, on_gui_closed) +Event.add(defines.events.on_gui_opened, on_gui_opened) +Event.add(defines.events.on_player_mined_entity, on_player_mined_entity) +Event.add(defines.events.on_robot_mined_entity, on_robot_mined_entity) + +return Public \ No newline at end of file diff --git a/maps/scrapyard/locomotive.lua b/maps/scrapyard/locomotive.lua index c9f84a57..c2d15e4a 100644 --- a/maps/scrapyard/locomotive.lua +++ b/maps/scrapyard/locomotive.lua @@ -1,6 +1,6 @@ local Event = require 'utils.event' local Power = require "maps.scrapyard.power" -local ICW = require "modules.immersive_cargo_wagons.main" +local ICW = require "maps.scrapyard.icw.main" local Scrap_table = require "maps.scrapyard.table" local Public = {} @@ -20,7 +20,7 @@ function Public.render_train_hp() scale_with_zoom = false } this.caption = rendering.draw_text{ - text = "Scrapyard Train", + text = "Grandmasters Train", surface = surface, target = this.locomotive, target_offset = {0, -4.25}, @@ -40,10 +40,6 @@ function Public.locomotive_spawn(surface, position) 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.power_source = surface.create_entity {name = 'hidden-hidden-electric-energy-interface', position = {position.x, position.y + -3, force = "player"}} - --this.ow_energy.electric_buffer_size = 2400000 - --this.ow_energy.power_production = 40000 - 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}) @@ -62,6 +58,19 @@ function Public.locomotive_spawn(surface, position) ICW.register_wagon(this.locomotive_cargo) end +function Public.inside(pos, area) + local lt = area.left_top + local rb = area.right_bottom + + return pos.x >= lt.x and pos.y >= lt.y and pos.x <= rb.x and pos.y <= rb.y +end +function Public.contains_positions(pos, area) + if Public.inside(pos, area) then + return true + end + return false +end + function Public.power_source() local this = Scrap_table.get_table() local surface = game.surfaces[this.active_surface_index] @@ -71,7 +80,12 @@ function Public.power_source() if not this.locomotive.surface.valid then return end if this.ow_energy then if this.ow_energy.valid then - if this.ow_energy.position.x == this.locomotive.position.x and this.ow_energy.position.y == this.locomotive.position.y+2 then return end + local position = this.ow_energy.position + local area = { + left_top = {x = position.x - 2, y = position.y - 2}, + right_bottom = {x = position.x + 2, y = position.y + 2} + } + if Public.contains_positions(this.locomotive.position, area) then return end this.old_ow_energy = this.ow_energy.energy this.ow_energy.destroy() this.energy["scrapyard"] = nil @@ -81,7 +95,7 @@ function Public.power_source() name = "electric-energy-interface", position = { x=this.locomotive.position.x, - y=this.locomotive.position.y+2 + y=this.locomotive.position.y+1 }, create_build_effect_smoke = false, force = game.forces.neutral @@ -110,7 +124,7 @@ function Public.on_teleported_player() local this = Scrap_table.get_table() local unit_surface = this.locomotive.unit_number local loco_surface = game.surfaces[tostring(unit_surface)] - local pos = {x=-9, y=3} + local pos = {x=-17, y=3} if not this.lo_energy then this.lo_energy = loco_surface.create_entity{ name = "electric-energy-interface", diff --git a/maps/scrapyard/main.lua b/maps/scrapyard/main.lua index e1c998f2..09c1f758 100644 --- a/maps/scrapyard/main.lua +++ b/maps/scrapyard/main.lua @@ -2,9 +2,10 @@ require "on_tick_schedule" require "modules.dynamic_landfill" require "modules.difficulty_vote" require "modules.shotgun_buff" -require "modules.burden" +require "maps.scrapyard.burden" require "modules.rocks_heal_over_time" -require "modules.mineable_wreckage_yields_scrap" +require "modules.no_deconstruction_of_neutral_entities" +require "maps.scrapyard.mineable_wreckage_yields_scrap" require "maps.scrapyard.flamethrower_nerf" require "modules.rocks_yield_ore_veins" require "modules.spawners_contain_biters" @@ -13,11 +14,12 @@ require "modules.biter_noms_you" require "modules.explosives" require "modules.wave_defense.main" require "maps.scrapyard.comfylatron" +require "modules.rocks_broken_paint_tiles" -local ICW = require "modules.immersive_cargo_wagons.main" +local ICW = require "maps.scrapyard.icw.main" local WD = require "modules.wave_defense.table" local Map = require 'modules.map_info' -local RPG = require 'modules.rpg' +local RPG = require 'maps.scrapyard.rpg' local Reset = require "functions.soft_reset" local BiterRolls = require "modules.wave_defense.biter_rolls" local unearthing_worm = require "functions.unearthing_worm" @@ -38,7 +40,6 @@ local Public = {} local math_random = math.random local math_floor = math.floor -local disabled_for_deconstruction = {["fish"] = true, ["rock-huge"] = true, ["rock-big"] = true, ["sand-rock-big"] = true, ["mineable-wreckage"] = true} local starting_items = {['pistol'] = 1, ['firearm-magazine'] = 16, ['wood'] = 4, ['rail'] = 16, ['raw-fish'] = 2} local disabled_entities = {"gun-turret", "laser-turret", "flamethrower-turret", "land-mine"} local treasure_chest_messages = { @@ -56,14 +57,24 @@ local function shuffle(tbl) return tbl end -local function set_objective_health(final_damage_amount) +local function set_objective_health(entity, final_damage_amount) local this = Scrap_table.get_table() if final_damage_amount == 0 then return end this.locomotive_health = math_floor(this.locomotive_health - final_damage_amount) + this.cargo_health = math_floor(this.cargo_health - final_damage_amount) if this.locomotive_health > this.locomotive_max_health then this.locomotive_health = this.locomotive_max_health end + if this.cargo_health > this.cargo_max_health then this.cargo_health = this.cargo_max_health end if this.locomotive_health <= 0 then Public.loco_died() end + local m + if entity == this.locomotive then + m = this.locomotive_health / this.locomotive_max_health + entity.health = 1000 * m + elseif entity == this.locomotive_cargo then + m = this.cargo_health / this.cargo_max_health + entity.health = 600 * m + end rendering.set_text(this.health_text, "HP: " .. this.locomotive_health .. " / " .. this.locomotive_max_health) end @@ -124,6 +135,8 @@ function Public.reset_map() surface.daytime = 0.7 this.locomotive_health = 10000 this.locomotive_max_health = 10000 + this.cargo_health = 10000 + this.cargo_max_health = 10000 Locomotive(surface, {x = -18, y = 10}) render_train_hp() @@ -260,7 +273,7 @@ end local function protect_this(entity) local this = Scrap_table.get_table() - if entity.surface.name ~= "scrapyard" then return true end + if string.sub(entity.surface.name, 0, 9) ~= "scrapyard" then return true end local protected = {this.locomotive, this.locomotive_cargo} for i = 1, #protected do if protected[i] == entity then @@ -278,7 +291,7 @@ local function protect_train(event) if event.cause then if event.cause.force.index == 2 or event.cause.force.name == "scrap_defense" or event.cause.force.name == "scrap" then if this.locomotive_health <= 0 then goto continue end - set_objective_health(event.final_damage_amount) + set_objective_health(event.entity, event.final_damage_amount) end end ::continue:: @@ -288,6 +301,11 @@ local function protect_train(event) end end +local function change_tile(surface,pos) + local colors = {"black", "orange", "red", "yellow", "acid", "brown", "green", "blue"} + surface.set_tiles{{name = colors[math_random(1, #colors)].. "-refined-concrete", position=pos}} +end + local function on_player_changed_position(event) local this = Scrap_table.get_table() local player = game.players[event.player_index] @@ -296,6 +314,13 @@ local function on_player_changed_position(event) local surface = game.surfaces[this.active_surface_index] if position.x >= 960 * 0.5 then return end if position.x < 960 * -0.5 then return end + if position.y < 5 then + local shallow = surface.get_tile(position).name == "water-shallow" + local deepwater = surface.get_tile(position).name == "deepwater-green" + if shallow or deepwater then goto continue end + change_tile(surface, position) + end + ::continue:: if position.y < 5 then Terrain.reveal(player) end if position.y >= 190 then player.teleport({position.x, position.y - 1}, surface) @@ -308,12 +333,6 @@ local function on_player_changed_position(event) end end -local function on_marked_for_deconstruction(event) - if disabled_for_deconstruction[event.entity.name] then - event.entity.cancel_deconstruction(game.players[event.player_index].force.name) - end -end - local function on_player_left_game(event) set_difficulty() end @@ -449,20 +468,42 @@ local function on_entity_damaged(event) biters_chew_rocks_faster(event) end +local function on_player_repaired_entity(event) + local this = Scrap_table.get_table() + if not event.entity then return end + if not event.entity.valid then return end + if not event.entity.health then return end + local entity = event.entity + if entity == this.locomotive_cargo or entity == this.locomotive then + set_objective_health(entity, -4) + end +end + function Public.loco_died() local this = Scrap_table.get_table() local surface = game.surfaces[this.active_surface_index] local wave_defense_table = WD.get_table() this.locomotive_health = 0 + this.locomotive.color = {0.49, 0, 255, 1} + rendering.set_text(this.health_text, "HP: " .. this.locomotive_health .. " / " .. this.locomotive_max_health) wave_defense_table.game_lost = true wave_defense_table.target = nil - game.print("[color=blue]Grandmaster:[/color] Oh noooeeeew!", {r = 1, g = 0.5, b = 0.1}) - game.print("[color=blue]Grandmaster:[/color] The scrapyard train was destroyed! Better luck next time.", {r = 1, g = 0.5, b = 0.1}) - for i = 1, 6, 1 do + game.print("[color=blue]Grandmaster:[/color] Oh noooeeeew, they destroyed my train!", {r = 1, g = 0.5, b = 0.1}) + game.print("[color=blue]Grandmaster:[/color] Better luck next time.", {r = 1, g = 0.5, b = 0.1}) + for i = 1, 12, 1 do + surface.create_entity({name = "big-artillery-explosion", position = this.locomotive.position}) + end + for i = 1, 12, 1 do surface.create_entity({name = "big-artillery-explosion", position = this.locomotive_cargo.position}) end - surface.spill_item_stack(this.locomotive.position,{name = "raw-fish", count = 512}, false) - surface.spill_item_stack(this.locomotive_cargo.position,{name = "raw-fish", count = 512}, false) + for i = 1, 12, 1 do + surface.create_entity({name = "big-artillery-explosion", position = this.locomotive_cargo.position}) + end + for i = 1, 12, 1 do + surface.create_entity({name = "big-artillery-explosion", position = this.locomotive_cargo.position}) + end + surface.spill_item_stack(this.locomotive.position,{name = "coin", count = 512}, false) + surface.spill_item_stack(this.locomotive_cargo.position,{name = "coin", count = 512}, false) this.game_reset_tick = game.tick + 1800 for _, player in pairs(game.connected_players) do player.play_sound{path="utility/game_lost", volume_modifier=0.75} @@ -518,6 +559,7 @@ end local function on_built_entity(event) + if string.sub(event.created_entity.surface.name, 0, 9) ~= "scrapyard" then return end local player = game.players[event.player_index] local y = event.created_entity.position.y local ent = event.created_entity @@ -541,6 +583,7 @@ local function on_built_entity(event) end local function on_robot_built_entity(event) + if string.sub(event.created_entity.surface.name, 0, 9) ~= "scrapyard" then return end local y = event.created_entity.position.y local ent = event.created_entity if y >= 150 then @@ -578,9 +621,12 @@ local on_init = function() game.forces.scrap.set_friend('player', true) game.forces.scrap.set_friend('enemy', true) game.forces.scrap.share_chart = false + global.rocks_yield_ore_maximum_amount = 999 + global.rocks_yield_ore_base_amount = 50 + global.rocks_yield_ore_distance_modifier = 0.025 Public.reset_map() local T = Map.Pop_info() - T.main_caption = "S c r a p y a r d" + T.main_caption = "R a i n b o w S c r a p y a r d" T.sub_caption = " ---defend the choo---" T.text = table.concat({ "The biters have catched the scent of fish in the cargo wagon.\n", @@ -640,13 +686,15 @@ Event.on_nth_tick(5, on_tick) Event.on_init(on_init) Event.add(defines.events.on_research_finished, on_research_finished) Event.add(defines.events.on_entity_damaged, on_entity_damaged) -Event.add(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction) Event.add(defines.events.on_player_joined_game, on_player_joined_game) Event.add(defines.events.on_player_left_game, on_player_left_game) +Event.add(defines.events.on_player_repaired_entity, on_player_repaired_entity) Event.add(defines.events.on_player_mined_entity, on_player_mined_entity) Event.add(defines.events.on_entity_died, on_entity_died) Event.add(defines.events.on_robot_built_entity, on_robot_built_entity) Event.add(defines.events.on_built_entity, on_built_entity) Event.add(defines.events.on_player_changed_position, on_player_changed_position) +require "modules.rocks_yield_ore" + return Public \ No newline at end of file diff --git a/maps/scrapyard/mineable_wreckage_yields_scrap.lua b/maps/scrapyard/mineable_wreckage_yields_scrap.lua new file mode 100644 index 00000000..a9eaadb4 --- /dev/null +++ b/maps/scrapyard/mineable_wreckage_yields_scrap.lua @@ -0,0 +1,155 @@ +local mining_chance_weights = { + {name = "iron-ore", chance = 570}, + {name = "copper-ore", chance = 570}, + {name = "stone", chance = 550}, + {name = "coal", chance = 500}, + {name = "iron-plate", chance = 400}, + {name = "iron-gear-wheel", chance = 390}, + {name = "copper-plate", chance = 400}, + {name = "copper-cable", chance = 380}, + {name = "electronic-circuit", chance = 150}, + {name = "steel-plate", chance = 120}, + {name = "solid-fuel", chance = 89}, + {name = "pipe", chance = 75}, + {name = "iron-stick", chance = 50}, + {name = "battery", chance = 20}, + {name = "empty-barrel", chance = 10}, + {name = "crude-oil-barrel", chance = 10}, + {name = "lubricant-barrel", chance = 10}, + {name = "petroleum-gas-barrel", chance = 10}, + {name = "sulfuric-acid-barrel", chance = 10}, + {name = "heavy-oil-barrel", chance = 10}, + {name = "light-oil-barrel", chance = 10}, + {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 = { + ["iron-ore"] = 8, + ["copper-ore"] = 8, + ["stone"] = 4, + ["coal"] = 6, + ["iron-plate"] = 16, + ["iron-gear-wheel"] = 8, + ["iron-stick"] = 16, + ["copper-plate"] = 16, + ["copper-cable"] = 24, + ["electronic-circuit"] = 8, + ["steel-plate"] = 4, + ["pipe"] = 8, + ["solid-fuel"] = 4, + ["empty-barrel"] = 3, + ["crude-oil-barrel"] = 3, + ["lubricant-barrel"] = 3, + ["petroleum-gas-barrel"] = 3, + ["sulfuric-acid-barrel"] = 3, + ["heavy-oil-barrel"] = 3, + ["light-oil-barrel"] = 3, + ["water-barrel"] = 3, + ["battery"] = 2, + ["explosives"] = 4, + ["advanced-circuit"] = 2, + ["nuclear-fuel"] = 0.1, + ["pipe-to-ground"] = 1, + ["plastic-bar"] = 4, + ["processing-unit"] = 1, + ["used-up-uranium-fuel-cell"] = 1, + ["uranium-fuel-cell"] = 0.3, + ["rocket-fuel"] = 0.3, + ["rocket-control-unit"] = 0.3, + ["low-density-structure"] = 0.3, + ["heat-pipe"] = 1, + ["green-wire"] = 8, + ["red-wire"] = 8, + ["engine-unit"] = 2, + ["electric-engine-unit"] = 2, + ["logistic-robot"] = 0.3, + ["construction-robot"] = 0.3, + + ["land-mine"] = 1, + ["grenade"] = 2, + ["rocket"] = 2, + ["explosive-rocket"] = 2, + ["cannon-shell"] = 2, + ["explosive-cannon-shell"] = 2, + ["uranium-cannon-shell"] = 2, + ["explosive-uranium-cannon-shell"] = 2, + ["artillery-shell"] = 0.3, + ["cluster-grenade"] = 0.3, + ["defender-capsule"] = 2, + ["destroyer-capsule"] = 0.3, + ["distractor-capsule"] = 0.3 +} + +local scrap_raffle = {} +for _, t in pairs (mining_chance_weights) do + for x = 1, t.chance, 1 do + table.insert(scrap_raffle, t.name) + end +end + +local size_of_scrap_raffle = #scrap_raffle + +local function on_player_mined_entity(event) + local entity = event.entity + if not entity.valid then return end + if entity.name ~= "mineable-wreckage" then return end + + event.buffer.clear() + + local scrap = scrap_raffle[math.random(1, size_of_scrap_raffle)] + + local amount_bonus = (game.forces.enemy.evolution_factor * 2) + (game.forces.player.mining_drill_productivity_bonus * 2) + local r1 = math.ceil(scrap_yield_amounts[scrap] * (0.3 + (amount_bonus * 0.3))) + local r2 = math.ceil(scrap_yield_amounts[scrap] * (1.7 + (amount_bonus * 1.7))) + local amount = math.random(r1, r2) + + local player = game.players[event.player_index] + local inserted_count = player.insert({name = scrap, count = amount}) + + if inserted_count ~= amount then + local amount_to_spill = amount - inserted_count + entity.surface.spill_item_stack(entity.position,{name = scrap, count = amount_to_spill}, true) + end + + entity.surface.create_entity({ + name = "flying-text", + position = entity.position, + text = "+" .. amount .. " [img=item/" .. scrap .. "]", + color = {r=0.98, g=0.66, b=0.22} + }) +end + +local Event = require 'utils.event' +Event.add(defines.events.on_player_mined_entity, on_player_mined_entity) \ No newline at end of file diff --git a/maps/scrapyard/power.lua b/maps/scrapyard/power.lua index b7744164..bc724879 100644 --- a/maps/scrapyard/power.lua +++ b/maps/scrapyard/power.lua @@ -9,9 +9,6 @@ end local function tick() local this = Scrap_table.get_table() - if not this.energy then - this.energy = {} - end if not this.energy["scrapyard"] then this.energy["scrapyard"] = this.ow_energy end diff --git a/maps/scrapyard/rpg.lua b/maps/scrapyard/rpg.lua new file mode 100644 index 00000000..28e1514a --- /dev/null +++ b/maps/scrapyard/rpg.lua @@ -0,0 +1,845 @@ +--[[ +Character Experience Gain RPG by MewMew + +STRENGTH > character_inventory_slots_bonus , character_mining_speed_modifier + +MAGIC > character_build_distance_bonus, character_item_drop_distance_bonus, character_reach_distance_bonus, + character_item_pickup_distance_bonus, character_loot_pickup_distance_bonus, + +DEXTERITY > character_running_speed_modifier, character_crafting_speed_modifier + +VITALITY > character_health_bonus + +Modified by Gerkiz *-* +]] + +require "player_modifiers" + +local math_random = math.random +local Global = require 'utils.global' +local Tabs = require "comfy_panel.main" +local P = require "player_modifiers" +local visuals_delay = 1800 +local level_up_floating_text_color = {0, 205, 0} +local xp_floating_text_color = {157, 157, 157} +local experience_levels = {0} +for a = 1, 9999, 1 do + experience_levels[#experience_levels + 1] = experience_levels[#experience_levels] + a * 8 +end +local gain_info_tooltip = "XP gain from mining, moving, crafting, repairing and combat." + +local rpg_t = {} +local rpg_frame_icons = { + "entity/small-worm-turret", "entity/medium-worm-turret", "entity/big-worm-turret", "entity/behemoth-worm-turret", + "entity/small-biter", "entity/small-biter", "entity/small-spitter", "entity/medium-biter", "entity/medium-biter", + "entity/medium-spitter", "entity/big-biter", "entity/big-biter", "entity/big-spitter", "entity/behemoth-biter", "entity/behemoth-biter", + "entity/behemoth-spitter" +} + +Global.register( + {rpg_t=rpg_t, rpg_frame_icons=rpg_frame_icons}, + function(tbl) + rpg_t = tbl.rpg_t + rpg_frame_icons = tbl.rpg_frame_icons + end +) + +local Public = {} + +function Public.get_table() + return rpg_t +end + +local classes = { + ["engineer"] = "ENGINEER", + ["strength"] = "MINER", + ["magic"] = "SORCERER", + ["dexterity"] = "ROGUE", + ["vitality"] = "TANK", +} + +local function level_up_effects(player) + local position = {x = player.position.x - 0.75, y = player.position.y - 1} + player.surface.create_entity({name = "flying-text", position = position, text = "+LVL ", color = level_up_floating_text_color}) + local b = 0.75 + for a = 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}}) + end + player.play_sound{path="utility/achievement_unlocked", volume_modifier=0.40} +end + +local function get_melee_modifier(player) return (rpg_t[player.index].strength - 10) * 0.10 end + +local function get_life_on_hit(player) return (rpg_t[player.index].vitality - 10) * 0.4 end + +local function get_one_punch_chance(player) + if rpg_t[player.index].strength < 100 then return 0 end + local chance = math.round(rpg_t[player.index].strength * 0.01, 1) + if chance > 100 then chance = 100 end + return chance +end + +local function draw_gui_char_button(player) + if player.gui.top.rpg then return end + local b = player.gui.top.add({type = "sprite-button", name = "rpg", caption = "CHAR"}) + b.style.font_color = {165,165,165} + b.style.font = "heading-1" + b.style.minimal_height = 38 + b.style.minimal_width = 60 + b.style.padding = 0 + b.style.margin = 0 +end + +local function update_char_button(player) + if not player.gui.top.rpg then draw_gui_char_button(player) end + if rpg_t[player.index].points_to_distribute > 0 then + player.gui.top.rpg.style.font_color = {245, 0, 0} + else + player.gui.top.rpg.style.font_color = {175,175,175} + end +end + +local function update_player_stats(player) + local player_modifiers = P.get_table() + local strength = rpg_t[player.index].strength - 10 + player_modifiers[player.index].character_inventory_slots_bonus["rpg"] = math.round(strength * 0.2, 3) + player_modifiers[player.index].character_mining_speed_modifier["rpg"] = math.round(strength * 0.008, 3) + + local magic = rpg_t[player.index].magic - 10 + local v = magic * 0.15 + player_modifiers[player.index].character_build_distance_bonus["rpg"] = math.round(v, 3) + player_modifiers[player.index].character_item_drop_distance_bonus["rpg"] = math.round(v, 3) + player_modifiers[player.index].character_reach_distance_bonus["rpg"] = math.round(v, 3) + player_modifiers[player.index].character_loot_pickup_distance_bonus["rpg"] = math.round(v * 0.5, 3) + player_modifiers[player.index].character_item_pickup_distance_bonus["rpg"] = math.round(v * 0.25, 3) + player_modifiers[player.index].character_resource_reach_distance_bonus["rpg"] = math.round(v * 0.15, 3) + + local dexterity = rpg_t[player.index].dexterity - 10 + player_modifiers[player.index].character_running_speed_modifier["rpg"] = math.round(dexterity * 0.002, 3) + player_modifiers[player.index].character_crafting_speed_modifier["rpg"] = math.round(dexterity * 0.015, 3) + + player_modifiers[player.index].character_health_bonus["rpg"] = math.round((rpg_t[player.index].vitality - 10) * 6, 3) + + P.update_player_modifiers(player) +end + +local function get_class(player) + local average = (rpg_t[player.index].strength + rpg_t[player.index].magic + rpg_t[player.index].dexterity + rpg_t[player.index].vitality) / 4 + local high_attribute = 0 + local high_attribute_name = "" + for _, attribute in pairs({"strength", "magic", "dexterity", "vitality"}) do + if rpg_t[player.index][attribute] > high_attribute then + high_attribute = rpg_t[player.index][attribute] + high_attribute_name = attribute + end + end + if high_attribute < average + average * 0.25 then high_attribute_name = "engineer" end + return classes[high_attribute_name] +end + +local function add_gui_description(element, value, width) + local e = element.add({type = "label", caption = value}) + e.style.single_line = false + e.style.maximal_width = width + e.style.minimal_width = width + e.style.maximal_height = 40 + e.style.minimal_height = 38 + e.style.font = "default-bold" + e.style.font_color = {175, 175, 200} + e.style.horizontal_align = "right" + e.style.vertical_align = "center" + return e +end + +local function add_gui_stat(element, value, width) + local e = element.add({type = "sprite-button", caption = value}) + e.style.maximal_width = width + e.style.minimal_width = width + e.style.maximal_height = 38 + e.style.minimal_height = 38 + e.style.font = "default-bold" + e.style.font_color = {222, 222, 222} + e.style.horizontal_align = "center" + e.style.vertical_align = "center" + return e +end + +local function add_gui_increase_stat(element, name, player, width) + local sprite = "virtual-signal/signal-red" + local symbol = "✚" + if rpg_t[player.index].points_to_distribute <= 0 then sprite = "virtual-signal/signal-black" end + local e = element.add({type = "sprite-button", name = name, caption = symbol, sprite = sprite}) + e.style.maximal_height = 38 + e.style.minimal_height = 38 + e.style.maximal_width = 38 + e.style.minimal_width = 38 + e.style.font = "default-large-semibold" + e.style.font_color = {0,0,0} + e.style.horizontal_align = "center" + e.style.vertical_align = "center" + e.style.padding = 0 + e.style.margin = 0 + e.tooltip = "Rightclick to allocate 5 points." + + return e +end + +local function add_separator(element, width) + local e = element.add({type = "line"}) + e.style.maximal_width = width + e.style.minimal_width = width + e.style.minimal_height = 12 + return e +end + +local function draw_gui(player, forced) + if not forced then + if rpg_t[player.index].gui_refresh_delay > game.tick then return end + end + + Tabs.comfy_panel_clear_left_gui(player) + + if player.gui.left.rpg then player.gui.left.rpg.destroy() end + if not player.character then return end + + local frame = player.gui.left.add({type = "frame", name = "rpg", direction = "vertical"}) + frame.style.maximal_width = 425 + frame.style.minimal_width = 425 + frame.style.margin = 6 + + add_separator(frame, 400) + + local t = frame.add({type = "table", column_count = 2}) + local e = add_gui_stat(t, player.name, 200) + e.style.font_color = player.chat_color + e.style.font = "default-large-bold" + local e = add_gui_stat(t, get_class(player), 200) + e.style.font = "default-large-bold" + + add_separator(frame, 400) + + local t = frame.add({type = "table", column_count = 4}) + t.style.cell_padding = 1 + + add_gui_description(t, "LEVEL", 80) + add_gui_stat(t, rpg_t[player.index].level, 80) + + add_gui_description(t, "EXPERIENCE", 100) + local e = add_gui_stat(t, math.floor(rpg_t[player.index].xp), 125) + e.tooltip = gain_info_tooltip + + add_gui_description(t, " ", 75) + add_gui_description(t, " ", 75) + + add_gui_description(t, "NEXT LEVEL", 100) + local e = add_gui_stat(t, experience_levels[rpg_t[player.index].level + 1], 125) + e.tooltip = gain_info_tooltip + + add_separator(frame, 400) + + local t = frame.add({type = "table", column_count = 2}) + local tt = t.add({type = "table", column_count = 3}) + tt.style.cell_padding = 1 + local w1 = 85 + local w2 = 63 + + local tip = "Increases inventory slots and mining speed.\nIncreases melee damage." + local e = add_gui_description(tt, "STRENGTH", w1) + e.tooltip = tip + local e = add_gui_stat(tt, rpg_t[player.index].strength, w2) + e.tooltip = tip + add_gui_increase_stat(tt, "strength", player) + + local tip = "Increases reach distance." + local e = add_gui_description(tt, "MAGIC", w1) + e.tooltip = tip + local e = add_gui_stat(tt, rpg_t[player.index].magic, w2) + e.tooltip = tip + add_gui_increase_stat(tt, "magic", player) + + local tip = "Increases running and crafting speed." + local e = add_gui_description(tt, "DEXTERITY", w1) + e.tooltip = tip + local e = add_gui_stat(tt, rpg_t[player.index].dexterity, w2) + e.tooltip = tip + add_gui_increase_stat(tt, "dexterity", player) + + local tip = "Increases health.\nIncreases melee life on-hit." + local e = add_gui_description(tt, "VITALITY", w1) + e.tooltip = tip + local e = add_gui_stat(tt, rpg_t[player.index].vitality, w2) + e.tooltip = tip + add_gui_increase_stat(tt, "vitality", player) + + add_gui_description(tt, "POINTS TO\nDISTRIBUTE", w1) + local e = add_gui_stat(tt, rpg_t[player.index].points_to_distribute, w2) + e.style.font_color = {200, 0, 0} + add_gui_description(tt, " ", w2) + + add_gui_description(tt, " ", w1) + add_gui_description(tt, " ", w2) + add_gui_description(tt, " ", w2) + + add_gui_description(tt, "LIFE", w1) + add_gui_stat(tt, math.floor(player.character.health), w2) + add_gui_stat(tt, math.floor(player.character.prototype.max_health + player.character_health_bonus + player.force.character_health_bonus), w2) + + local shield = 0 + local shield_max = 0 + local i = player.character.get_inventory(defines.inventory.character_armor) + if not i.is_empty() then + if i[1].grid then + shield = math.floor(i[1].grid.shield) + shield_max = math.floor(i[1].grid.max_shield) + end + end + add_gui_description(tt, "SHIELD", w1) + add_gui_stat(tt, shield, w2) + add_gui_stat(tt, shield_max, w2) + + + local tt = t.add({type = "table", column_count = 3}) + tt.style.cell_padding = 1 + local w0 = 2 + local w1 = 80 + local w2 = 80 + + add_gui_description(tt, " ", w0) + add_gui_description(tt, "MINING\nSPEED", w1) + local value = (player.force.manual_mining_speed_modifier + player.character_mining_speed_modifier + 1) * 100 .. "%" + add_gui_stat(tt, value, w2) + + add_gui_description(tt, " ", w0) + add_gui_description(tt, "SLOT\nBONUS", w1) + local value = "+ " .. player.force.character_inventory_slots_bonus + player.character_inventory_slots_bonus + add_gui_stat(tt, value, w2) + + add_gui_description(tt, " ", w0) + add_gui_description(tt, "MELEE\nDAMAGE", w1) + local value = 100 * (1 + get_melee_modifier(player)) .. "%" + local e = add_gui_stat(tt, value, w2) + e.tooltip = "Life on-hit: " .. get_life_on_hit(player) .. "\nOne punch chance: " .. get_one_punch_chance(player) .. "%" + + local e = add_gui_description(tt, "", w0) + e.style.maximal_height = 10 + local e = add_gui_description(tt, "", w0) + e.style.maximal_height = 10 + local e = add_gui_description(tt, "", w0) + e.style.maximal_height = 10 + + local value = "+ " .. (player.force.character_reach_distance_bonus + player.character_reach_distance_bonus) + local tooltip = "" + tooltip = tooltip .. "Reach distance bonus: " .. player.character_reach_distance_bonus + tooltip = tooltip .. "\nBuild distance bonus: " .. player.character_build_distance_bonus + tooltip = tooltip .. "\nItem drop distance bonus: " .. player.character_item_drop_distance_bonus + tooltip = tooltip .. "\nLoot pickup distance bonus: " .. player.character_loot_pickup_distance_bonus + tooltip = tooltip .. "\nItem pickup distance bonus: " .. player.character_item_pickup_distance_bonus + tooltip = tooltip .. "\nResource reach distance bonus: " .. player.character_resource_reach_distance_bonus + add_gui_description(tt, " ", w0) + local e = add_gui_description(tt, "REACH\nDISTANCE", w1) + e.tooltip = tooltip + local e = add_gui_stat(tt, value, w2) + e.tooltip = tooltip + + local e = add_gui_description(tt, "", w0) + e.style.maximal_height = 10 + local e = add_gui_description(tt, "", w0) + e.style.maximal_height = 10 + local e = add_gui_description(tt, "", w0) + e.style.maximal_height = 10 + + add_gui_description(tt, " ", w0) + add_gui_description(tt, "CRAFTING\nSPEED", w1) + local value = (player.force.manual_crafting_speed_modifier + player.character_crafting_speed_modifier + 1) * 100 .. "%" + add_gui_stat(tt, value, w2) + + add_gui_description(tt, " ", w0) + add_gui_description(tt, "RUNNING\nSPEED", w1) + local value = (player.force.character_running_speed_modifier + player.character_running_speed_modifier + 1) * 100 .. "%" + add_gui_stat(tt, value, w2) + + local e = add_gui_description(tt, "", w0) + e.style.maximal_height = 10 + local e = add_gui_description(tt, "", w0) + e.style.maximal_height = 10 + local e = add_gui_description(tt, "", w0) + e.style.maximal_height = 10 + + add_gui_description(tt, " ", w0) + add_gui_description(tt, "HEALTH\nBONUS", w1) + local value = "+ " .. (player.force.character_health_bonus + player.character_health_bonus) + add_gui_stat(tt, value, w2) + + add_separator(frame, 400) + local t = frame.add({type = "table", column_count = 14}) + for i = 1, 14, 1 do + local e = t.add({type = "sprite", sprite = rpg_frame_icons[i]}) + e.style.maximal_width = 24 + e.style.maximal_height = 24 + e.style.padding = 0 + end + add_separator(frame, 400) + + rpg_t[player.index].gui_refresh_delay = game.tick + 60 + update_char_button(player) +end + +local function draw_level_text(player) + if not player.character then return end + + if rpg_t[player.index].text then + rendering.destroy(rpg_t[player.index].text) + rpg_t[player.index].text = nil + end + + local players = {} + for _, p in pairs(game.players) do + if p.index ~= player.index then + players[#players + 1] = p.index + end + end + if #players == 0 then return end + + rpg_t[player.index].text = rendering.draw_text{ + text = "lvl " .. rpg_t[player.index].level, + surface = player.surface, + target = player.character, + target_offset = {0, -3.25}, + color = { + r = player.color.r * 0.6 + 0.25, + g = player.color.g * 0.6 + 0.25, + b = player.color.b * 0.6 + 0.25, + a = 1 + }, + players = players, + scale = 1.00, + font = "default-large-semibold", + alignment = "center", + scale_with_zoom = false + } +end + +local function level_up(player) + local distribute_points_gain = 0 + for i = rpg_t[player.index].level + 1, #experience_levels, 1 do + if rpg_t[player.index].xp > experience_levels[i] then + rpg_t[player.index].level = i + distribute_points_gain = distribute_points_gain + 5 + else + break + end + end + if distribute_points_gain == 0 then return end + draw_level_text(player) + rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute + distribute_points_gain + update_char_button(player) + table.shuffle_table(rpg_frame_icons) + if player.gui.left.rpg then draw_gui(player, true) end + level_up_effects(player) +end + +local function gain_xp(player, amount) + amount = math.round(amount, 2) + rpg_t[player.index].xp = rpg_t[player.index].xp + amount + rpg_t[player.index].xp_since_last_floaty_text = rpg_t[player.index].xp_since_last_floaty_text + amount + if player.gui.left.rpg then draw_gui(player, false) end + if not experience_levels[rpg_t[player.index].level + 1] then return end + if rpg_t[player.index].xp >= experience_levels[rpg_t[player.index].level + 1] then + level_up(player) + return + end + if rpg_t[player.index].last_floaty_text > game.tick then return end + player.create_local_flying_text{text="+" .. rpg_t[player.index].xp_since_last_floaty_text .. " xp", position=player.position, color=xp_floating_text_color, time_to_live=120, speed=2} + rpg_t[player.index].xp_since_last_floaty_text = 0 + rpg_t[player.index].last_floaty_text = game.tick + visuals_delay +end + +function Public.rpg_reset_player(player) + if player.gui.left.rpg then player.gui.left.rpg.destroy() end + if not player.character then + player.set_controller({type=defines.controllers.god}) + player.create_character() + end + rpg_t[player.index] = { + level = 1, xp = 0, strength = 10, magic = 10, dexterity = 10, vitality = 10, points_to_distribute = 0, + last_floaty_text = visuals_delay, xp_since_last_floaty_text = 0, + rotated_entity_delay = 0, gui_refresh_delay = 0, last_mined_entity_position = {x = 0, y = 0}, + } + draw_gui_char_button(player) + draw_level_text(player) + update_char_button(player) + update_player_stats(player) +end + +function Public.rpg_reset_all_players() + for _, p in pairs(game.players) do + rpg_t[p.index] = nil + end + for _, p in pairs(game.connected_players) do + Public.rpg_reset_player(p) + end +end + +local function on_gui_click(event) + if not event.element then return end + if not event.element.valid then return end + local element = event.element + + if element.type ~= "sprite-button" then return end + + if element.caption == "CHAR" then + if element.name == "rpg" then + local player = game.players[event.player_index] + if player.gui.left.rpg then + player.gui.left.rpg.destroy() + return + end + draw_gui(player, true) + end + end + + if element.caption ~= "✚" then return end + if element.sprite ~= "virtual-signal/signal-red" then return end + + local index = element.name + local player = game.players[event.player_index] + if not rpg_t[player.index][index] then return end + if not player.character then return end + + if event.button == defines.mouse_button_type.right then + for a = 1, 5, 1 do + if rpg_t[player.index].points_to_distribute <= 0 then draw_gui(player, true) return end + rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute - 1 + rpg_t[player.index][index] = rpg_t[player.index][index] + 1 + update_player_stats(player) + end + draw_gui(player, true) + return + end + + if rpg_t[player.index].points_to_distribute <= 0 then draw_gui(player, true) return end + rpg_t[player.index].points_to_distribute = rpg_t[player.index].points_to_distribute - 1 + rpg_t[player.index][index] = rpg_t[player.index][index] + 1 + update_player_stats(player) + draw_gui(player, true) +end + +local xp_yield = { + ["behemoth-biter"] = 16, + ["behemoth-spitter"] = 16, + ["behemoth-worm-turret"] = 64, + ["big-biter"] = 8, + ["big-spitter"] = 8, + ["big-worm-turret"] = 48, + ["biter-spawner"] = 64, + ["character"] = 16, + ["gun-turret"] = 8, + ["laser-turret"] = 16, + ["medium-biter"] = 4, + ["medium-spitter"] = 4, + ["medium-worm-turret"] = 32, + ["small-biter"] = 1, + ["small-spitter"] = 1, + ["small-worm-turret"] = 16, + ["spitter-spawner"] = 64, +} + +local function train_type_cause(cause) + local players = {} + if cause.train.passengers then + for _, player in pairs(cause.train.passengers) do + players[#players + 1] = player + end + end + return players +end + +local get_cause_player = { + ["character"] = function(cause) + if not cause.player then return end + return {cause.player} + end, + ["combat-robot"] = function(cause) + if not cause.last_user then return end + if not game.players[cause.last_user.index] then return end + return {game.players[cause.last_user.index]} + end, + ["car"] = function(cause) + local players = {} + local driver = cause.get_driver() + if driver then + if driver.player then players[#players + 1] = driver.player end + end + local passenger = cause.get_passenger() + if passenger then + if passenger.player then players[#players + 1] = passenger.player end + end + return players + end, + ["locomotive"] = train_type_cause, + ["cargo-wagon"] = train_type_cause, + ["artillery-wagon"] = train_type_cause, + ["fluid-wagon"] = train_type_cause, +} + +local function on_entity_died(event) + if not event.entity.valid then return end + + --Grant XP for hand placed land mines + if event.entity.last_user then + if event.entity.type == "land-mine" then + if event.cause then + if event.cause.valid then + if event.cause.force.index == event.entity.force.index then return end + end + end + gain_xp(event.entity.last_user, 1) + return + end + end + + if not event.cause then return end + if not event.cause.valid then return end + if event.cause.force.index == event.entity.force.index then return end + if not get_cause_player[event.cause.type] then return end + + local players = get_cause_player[event.cause.type](event.cause) + if not players then return end + if not players[1] then return end + + --Grant modified XP for health boosted units + if global.biter_health_boost then + if event.entity.type == "unit" then + for _, player in pairs(players) do + if xp_yield[event.entity.name] then + gain_xp(player, xp_yield[event.entity.name] * global.biter_health_boost) + else + gain_xp(player, 0.5 * global.biter_health_boost) + end + end + return + end + end + + --Grant normal XP + for _, player in pairs(players) do + if xp_yield[event.entity.name] then + gain_xp(player, xp_yield[event.entity.name]) + else + gain_xp(player, 0.5) + end + end +end + +--Melee damage modifier +local function one_punch(character, target, damage) + local base_vector = {target.position.x - character.position.x, target.position.y - character.position.y} + + local vector = {base_vector[1], base_vector[2]} + vector[1] = vector[1] * 1000 + vector[2] = vector[2] * 1000 + + character.surface.create_entity({name = "flying-text", position = {character.position.x + base_vector[1] * 0.5, character.position.y + base_vector[2] * 0.5}, text = "ONE PUNCH", color = {255, 0, 0}}) + character.surface.create_entity({name = "blood-explosion-huge", position = target.position}) + character.surface.create_entity({name = "big-artillery-explosion", position = {target.position.x + vector[1] * 0.5, target.position.y + vector[2] * 0.5}}) + + if math.abs(vector[1]) > math.abs(vector[2]) then + local d = math.abs(vector[1]) + if math.abs(vector[1]) > 0 then vector[1] = vector[1] / d end + if math.abs(vector[2]) > 0 then vector[2] = vector[2] / d end + else + local d = math.abs(vector[2]) + if math.abs(vector[2]) > 0 then vector[2] = vector[2] / d end + if math.abs(vector[1]) > 0 and d > 0 then vector[1] = vector[1] / d end + end + + vector[1] = vector[1] * 1.5 + vector[2] = vector[2] * 1.5 + + local a = 0.25 + + 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 = {character.position.x + x + vector[1] * i, character.position.y + y + vector[2] * i} + character.surface.create_trivial_smoke({name="train-smoke", position=p}) + for _, e in pairs(character.surface.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 e.force.index ~= 3 then + if e.force.index ~= character.force.index then + e.health = e.health - damage * 0.05 + if e.health <= 0 then + e.die(e.force.name, character) + end + end + end + end + end + end + end + end + end +end + +local function on_entity_damaged(event) + if not event.cause then return end + if not event.cause.valid then return end + if event.cause.force.index == 2 then return end + if event.cause.name ~= "character" then return end + if event.damage_type.name ~= "physical" then return end + if not event.entity.valid then return end + if event.cause.get_inventory(defines.inventory.character_ammo)[event.cause.selected_gun_index].valid_for_read + and event.cause.get_inventory(defines.inventory.character_guns)[event.cause.selected_gun_index].valid_for_read then return end + if not event.cause.player then return end + + --Grant the player life-on-hit. + event.cause.health = event.cause.health + get_life_on_hit(event.cause.player) + + --Calculate modified damage. + local damage = event.original_damage_amount + event.original_damage_amount * get_melee_modifier(event.cause.player) + if event.entity.prototype.resistances then + if event.entity.prototype.resistances.physical then + damage = damage - event.entity.prototype.resistances.physical.decrease + damage = damage - damage * event.entity.prototype.resistances.physical.percent + end + end + damage = math.round(damage, 3) + if damage < 1 then damage = 1 end + + --Cause a one punch. + if math_random(0,999) < get_one_punch_chance(event.cause.player) * 10 then + one_punch(event.cause, event.entity, damage) + if event.entity.valid then + event.entity.die(event.entity.force.name, event.cause) + end + return + end + + --Floating messages and particle effects. + if math_random(1,7) == 1 then + damage = damage * math_random(250, 350) * 0.01 + event.cause.surface.create_entity({name = "flying-text", position = event.entity.position, text = "‼" .. math.floor(damage), color = {255, 0, 0}}) + event.cause.surface.create_entity({name = "blood-explosion-huge", position = event.entity.position}) + else + damage = damage * math_random(100, 125) * 0.01 + event.cause.player.create_local_flying_text({text = math.floor(damage), position = event.entity.position, color = {150, 150, 150}, time_to_live = 90, speed = 2}) + end + + --Handle the custom health pool of the biter health booster, if it is used in the map. + if global.biter_health_boost then + local health_pool = global.biter_health_boost_units[event.entity.unit_number] + if health_pool then + health_pool[1] = health_pool[1] + event.final_damage_amount + health_pool[1] = health_pool[1] - damage + + --Set entity health relative to health pool + event.entity.health = health_pool[1] * health_pool[2] + + if health_pool[1] <= 0 then + global.biter_health_boost_units[event.entity.unit_number] = nil + event.entity.die(event.entity.force.name, event.cause) + end + return + end + end + + --Handle vanilla damage. + event.entity.health = event.entity.health + event.final_damage_amount + event.entity.health = event.entity.health - damage + if event.entity.health <= 0 then + event.entity.die(event.entity.force.name, event.cause) + end +end + +local function on_player_repaired_entity(event) + if math_random(1, 4) ~= 1 then return end + local player = game.players[event.player_index] + if not player.character then return end + gain_xp(player, 0.40) +end + +local function on_player_rotated_entity(event) + local player = game.players[event.player_index] + if not player.character then return end + if rpg_t[player.index].rotated_entity_delay > game.tick then return end + rpg_t[player.index].rotated_entity_delay = game.tick + 20 + gain_xp(player, 0.20) +end + +local function on_player_changed_position(event) + if math_random(1, 64) ~= 1 then return end + local player = game.players[event.player_index] + if not player.character then return end + if player.character.driving then return end + gain_xp(player, 1.0) +end + +local building_and_mining_blacklist = { + ["tile-ghost"] = true, + ["entity-ghost"] = true, + ["item-entity"] = true, +} + +local function on_pre_player_mined_item(event) + local entity = event.entity + if not entity.valid then return end + if building_and_mining_blacklist[entity.type] then return end + if entity.force.index ~= 3 then return end + local player = game.players[event.player_index] + + if rpg_t[player.index].last_mined_entity_position.x == event.entity.position.x and rpg_t[player.index].last_mined_entity_position.y == event.entity.position.y then return end + rpg_t[player.index].last_mined_entity_position.x = entity.position.x + rpg_t[player.index].last_mined_entity_position.y = entity.position.y + + if entity.type == "resource" then gain_xp(player, 0.5) return end + --if entity.force.index == 3 then + gain_xp(player, 0.75 + event.entity.prototype.max_health * 0.0013) + --return + --end + --gain_xp(player, 0.1 + event.entity.prototype.max_health * 0.0005) +end + +local function on_player_crafted_item(event) + if not event.recipe.energy then return end + local player = game.players[event.player_index] + gain_xp(player, event.recipe.energy * 0.20) +end + +local function on_player_respawned(event) + local player = game.players[event.player_index] + if not rpg_t[player.index] then Public.rpg_reset_player(player) return end + update_player_stats(player) + draw_level_text(player) +end + +local function on_player_joined_game(event) + local player = game.players[event.player_index] + if not rpg_t[player.index] then Public.rpg_reset_player(player) end + for _, p in pairs(game.connected_players) do + draw_level_text(p) + end + draw_gui_char_button(player) + if not player.character then return end + update_player_stats(player) +end + +local function on_init(event) + table.shuffle_table(rpg_frame_icons) +end + +local event = require 'utils.event' +event.on_init(on_init) +event.add(defines.events.on_entity_damaged, on_entity_damaged) +event.add(defines.events.on_entity_died, on_entity_died) +event.add(defines.events.on_gui_click, on_gui_click) +event.add(defines.events.on_player_changed_position, on_player_changed_position) +event.add(defines.events.on_player_crafted_item, on_player_crafted_item) +event.add(defines.events.on_player_joined_game, on_player_joined_game) +event.add(defines.events.on_player_repaired_entity, on_player_repaired_entity) +event.add(defines.events.on_player_respawned, on_player_respawned) +event.add(defines.events.on_player_rotated_entity, on_player_rotated_entity) +event.add(defines.events.on_pre_player_mined_item, on_pre_player_mined_item) + +return Public \ No newline at end of file diff --git a/maps/scrapyard/table.lua b/maps/scrapyard/table.lua index 8237aa98..326f581e 100644 --- a/maps/scrapyard/table.lua +++ b/maps/scrapyard/table.lua @@ -16,10 +16,16 @@ function Public.reset_table() --for k, _ in pairs(this) do -- this[k] = nil --end + this.lo_energy = nil + this.ow_energy = nil this.game_lost = false this.game_won = false + this.energy = {} + this.wave_counter = 0 this.locomotive_health = 10000 this.locomotive_max_health = 10000 + this.cargo_health = 10000 + this.cargo_max_health = 10000 this.revealed_spawn = 0 end diff --git a/maps/scrapyard/terrain.lua b/maps/scrapyard/terrain.lua index 0696a19b..91690313 100644 --- a/maps/scrapyard/terrain.lua +++ b/maps/scrapyard/terrain.lua @@ -22,13 +22,15 @@ local scrap_buildings = {"nuclear-reactor", "centrifuge", "beacon", "chemical-pl local spawner_raffle = {"biter-spawner", "biter-spawner", "biter-spawner", "spitter-spawner"} local trees = {"dead-grey-trunk", "dead-grey-trunk", "dry-tree"} local colors = {"black", "orange", "red", "yellow"} +local more_colors = {"acid", "brown", "green", "blue"} local noises = { - ["no_rocks"] = {{modifier = 0.0033, weight = 1}, {modifier = 0.01, weight = 0.22}, {modifier = 0.05, weight = 0.05}, {modifier = 0.1, weight = 0.04}}, + ["no_rocks"] = {{modifier = 0.0044, weight = 1}, {modifier = 0.01, weight = 0.22}, {modifier = 0.05, weight = 0.05}, {modifier = 0.1, weight = 0.04}}, ["no_rocks_2"] = {{modifier = 0.013, weight = 1}, {modifier = 0.1, weight = 0.1}}, - ["large_caves"] = {{modifier = 0.0033, weight = 1}, {modifier = 0.01, weight = 0.22}, {modifier = 0.05, weight = 0.05}, {modifier = 0.1, weight = 0.04}}, + ["large_caves"] = {{modifier = 0.0044, weight = 1}, {modifier = 0.01, weight = 0.22}, {modifier = 0.05, weight = 0.05}, {modifier = 0.1, weight = 0.04}}, ["small_caves"] = {{modifier = 0.008, weight = 1}, {modifier = 0.03, weight = 0.15}, {modifier = 0.25, weight = 0.05}}, ["small_caves_2"] = {{modifier = 0.009, weight = 1}, {modifier = 0.05, weight = 0.25}, {modifier = 0.25, weight = 0.05}}, + ["cave_worms"] = {{modifier = 0.001, weight = 1}, {modifier = 0.1, weight = 0.06}}, ["cave_ponds"] = {{modifier = 0.01, weight = 1}, {modifier = 0.1, weight = 0.06}}, ["cave_rivers"] = {{modifier = 0.005, weight = 1}, {modifier = 0.01, weight = 0.25}, {modifier = 0.05, weight = 0.01}}, ["cave_rivers_2"] = {{modifier = 0.003, weight = 1}, {modifier = 0.01, weight = 0.21}, {modifier = 0.05, weight = 0.01}}, @@ -175,12 +177,55 @@ local function wall(surface, left_top, seed) end end +local function process_level_6_position(surface, p, seed, tiles, entities, fishes, r_area, markets, treasure) + local large_caves = get_noise("large_caves", p, seed) + local noise_cave_ponds = get_noise("cave_ponds", p, seed) + + if large_caves > -0.14 and large_caves < 0.14 then + tiles[#tiles + 1] = {name = "dirt-7", position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} + if math_random(1,768) == 1 then treasure[#treasure + 1] = p end + if math_random(1,3) > 1 then entities[#entities + 1] = {name = "mineable-wreckage", position = p} end + return + end + + if large_caves < -0.47 or large_caves > 0.47 then + insert(r_area, {x = p.x, y = p.y}) + tiles[#tiles + 1] = {name = "deepwater-green", position = p} + if math_random(1,128) == 1 then entities[#entities + 1] = {name="fish", position=p} end + if math_random(1,128) == 1 then + Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier) + create_inner_content(surface, p, noise_cave_ponds) + entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"} + end + return + end + + if large_caves > -0.30 and large_caves < 0.30 then + if noise_cave_ponds > 0.35 then + tiles[#tiles + 1] = {name = "dirt-" .. math_random(1, 4), position = p} + --tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} + if math_random(1,256) == 1 then treasure[#treasure + 1] = p end + if math_random(1,256) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end + return + end + if noise_cave_ponds > 0.25 then + tiles[#tiles + 1] = {name = "dirt-7", position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} + if math_random(1,512) == 1 then treasure[#treasure + 1] = p end + if math_random(1,2) > 1 then entities[#entities + 1] = {name = "mineable-wreckage", position = p} end + return + end + end +end + local function process_level_5_position(surface, p, seed, tiles, entities, fishes, r_area, markets, treasure) local small_caves = get_noise("small_caves", p, seed) local noise_cave_ponds = get_noise("cave_ponds", p, seed) if small_caves > -0.14 and small_caves < 0.14 then tiles[#tiles + 1] = {name = "dirt-7", position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} if math_random(1,768) == 1 then treasure[#treasure + 1] = p end if math_random(1,3) > 1 then entities[#entities + 1] = {name = "mineable-wreckage", position = p} end return @@ -201,12 +246,14 @@ local function process_level_5_position(surface, p, seed, tiles, entities, fishe if small_caves > -0.30 and small_caves < 0.30 then if noise_cave_ponds > 0.35 then tiles[#tiles + 1] = {name = "dirt-" .. math_random(1, 4), position = p} + --tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} if math_random(1,256) == 1 then treasure[#treasure + 1] = p end if math_random(1,256) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end return end if noise_cave_ponds > 0.25 then tiles[#tiles + 1] = {name = "dirt-7", position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} if math_random(1,512) == 1 then treasure[#treasure + 1] = p end if math_random(1,2) > 1 then entities[#entities + 1] = {name = "mineable-wreckage", position = p} end return @@ -243,6 +290,7 @@ local function process_level_4_position(surface, p, seed, tiles, entities, fishe end if math_abs(noise_large_caves) > 0.475 then tiles[#tiles + 1] = {name = "dirt-7", position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} if math_random(1,3) > 1 then entities[#entities + 1] = {name = "mineable-wreckage", position = p} end if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end return @@ -262,6 +310,7 @@ local function process_level_4_position(surface, p, seed, tiles, entities, fishe if small_caves > -0.15 and small_caves < 0.15 then tiles[#tiles + 1] = {name = "dirt-7", position = p} + --tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} if math_random(1,5) > 1 then entities[#entities + 1] = {name = "mineable-wreckage", position = p} end if math_random(1, 1024) == 1 then treasure[#treasure + 1] = p end return @@ -272,6 +321,7 @@ local function process_level_4_position(surface, p, seed, tiles, entities, fishe --Main Terrain local no_rocks_2 = get_noise("no_rocks_2", p, seed + 75000) if no_rocks_2 > 0.80 or no_rocks_2 < -0.80 then + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} tiles[#tiles + 1] = {name = "dirt-" .. math_floor(no_rocks_2 * 8) % 2 + 5, position = p} if math_random(1,512) == 1 then treasure[#treasure + 1] = p end return @@ -279,6 +329,7 @@ local function process_level_4_position(surface, p, seed, tiles, entities, fishe if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end tiles[#tiles + 1] = {name = "dirt-7", position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} if math_random(1,100) > 30 then entities[#entities + 1] = {name = "mineable-wreckage", position = p} end return end @@ -294,6 +345,7 @@ local function process_level_3_position(surface, p, seed, tiles, entities, fishe if noise_cave_ponds < -0.77 then if noise_cave_ponds > -0.79 then tiles[#tiles + 1] = {name = "dirt-7", position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} entities[#entities + 1] = {name = "mineable-wreckage", position = p} else tiles[#tiles + 1] = {name = "grass-" .. math_floor(noise_cave_ponds * 32) % 3 + 1, position = p} @@ -343,6 +395,7 @@ local function process_level_3_position(surface, p, seed, tiles, entities, fishe if noise_cave_ponds > 0.775 then tiles[#tiles + 1] = {name = "dirt-" .. math_random(4, 6), position = p} + --tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} return end @@ -351,6 +404,7 @@ local function process_level_3_position(surface, p, seed, tiles, entities, fishe if no_rocks < 0.15 and no_rocks > -0.15 then if small_caves > 0.35 then insert(r_area, {x = p.x, y = p.y}) + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} tiles[#tiles + 1] = {name = "dirt-" .. math_floor(noise_cave_ponds * 32) % 7 + 1, position = p} if math_random(1,320) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end if math_random(1,50) == 1 then @@ -368,12 +422,14 @@ local function process_level_3_position(surface, p, seed, tiles, entities, fishe local no_rocks_2 = get_noise("no_rocks_2", p, seed + 75000) if no_rocks_2 > 0.80 or no_rocks_2 < -0.80 then tiles[#tiles + 1] = {name = "dirt-" .. math_floor(no_rocks_2 * 8) % 2 + 5, position = p} + --tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} if math_random(1,512) == 1 then treasure[#treasure + 1] = p end return end if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end tiles[#tiles + 1] = {name = "dirt-7", position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} if math_random(1,2048) == 1 then place_random_scrap_entity(surface, p) end if math_random(1,100) > 30 then entities[#entities + 1] = {name = "mineable-wreckage", position = p} end return @@ -420,6 +476,7 @@ local function process_level_2_position(surface, p, seed, tiles, entities, fishe if noise_cave_ponds > 0.76 then tiles[#tiles + 1] = {name = "dirt-" .. math_random(4, 6), position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} return end @@ -439,6 +496,7 @@ local function process_level_2_position(surface, p, seed, tiles, entities, fishe if small_caves > 0.35 then insert(r_area, {x = p.x, y = p.y}) tiles[#tiles + 1] = {name = "dirt-" .. math_floor(noise_cave_ponds * 32) % 7 + 1, position = p} + --tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} if math_random(1,450) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end if math_random(1,64) == 1 then Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier) @@ -454,11 +512,13 @@ local function process_level_2_position(surface, p, seed, tiles, entities, fishe local no_rocks_2 = get_noise("no_rocks_2", p, seed + 75000) if no_rocks_2 > 0.80 or no_rocks_2 < -0.80 then tiles[#tiles + 1] = {name = "dirt-" .. math_floor(no_rocks_2 * 8) % 2 + 5, position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} if math_random(1,512) == 1 then treasure[#treasure + 1] = p end return end if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} tiles[#tiles + 1] = {name = "dirt-7", position = p} if math_random(1,2048) == 1 then place_random_scrap_entity(surface, p) end if math_random(1,100) > 30 then entities[#entities + 1] = {name = "mineable-wreckage", position = p} end @@ -472,7 +532,9 @@ local function process_level_1_position(surface, p, seed, tiles, entities, fishe local noise_cave_ponds = get_noise("cave_ponds", p, seed) - if noise_cave_ponds < 0.12 and noise_cave_ponds > -0.12 then + local cave_worms = get_noise("cave_worms", p, seed) + + if cave_worms < 0.12 and cave_worms > -0.12 then if small_caves > 0.55 then tiles[#tiles + 1] = {name = "water-shallow", position = p} return @@ -499,8 +561,8 @@ local function process_level_1_position(surface, p, seed, tiles, entities, fishe end if noise_cave_ponds > 0.76 then - tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} - --tiles[#tiles + 1] = {name = "dirt-" .. math_random(4, 6), position = p} + --tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} + tiles[#tiles + 1] = {name = "dirt-" .. math_random(4, 6), position = p} return end @@ -520,8 +582,8 @@ local function process_level_1_position(surface, p, seed, tiles, entities, fishe if no_rocks < 0.08 and no_rocks > -0.08 then if small_caves > 0.35 then insert(r_area, {x = p.x, y = p.y}) - tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} - --tiles[#tiles + 1] = {name = "dirt-" .. math_floor(noise_cave_ponds * 32) % 7 + 1, position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} + tiles[#tiles + 1] = {name = "dirt-" .. math_floor(noise_cave_ponds * 32) % 7 + 1, position = p} if math_random(1,450) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end if math_random(1,96) == 1 then Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier) @@ -537,17 +599,17 @@ local function process_level_1_position(surface, p, seed, tiles, entities, fishe --Main Terrain local no_rocks_2 = get_noise("no_rocks_2", p, seed + 75000) if no_rocks_2 > 0.70 or no_rocks_2 < -0.70 then - tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} - --tiles[#tiles + 1] = {name = "dirt-" .. math_floor(no_rocks_2 * 8) % 2 + 5, position = p} + --tiles[#tiles + 1] = {name = more_colors[math_random(1, #more_colors)].. "-refined-concrete", position = p} + tiles[#tiles + 1] = {name = "dirt-" .. math_floor(no_rocks_2 * 8) % 2 + 5, position = p} if math_random(1,32) == 1 then entities[#entities + 1] = {name = trees[math_random(1, #trees)], position=p} end if math_random(1,512) == 1 then treasure[#treasure + 1] = p end return end if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end - tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} - -- tiles[#tiles + 1] = {name = "dirt-7", position = p} - if math_random(1,2048) == 1 then place_random_scrap_entity(surface, p) end + --tiles[#tiles + 1] = {name = colors[math_random(1, #colors)].. "-refined-concrete", position = p} + tiles[#tiles + 1] = {name = "dirt-7", position = p} + if math_random(1,4028) == 1 then place_random_scrap_entity(surface, p) end if math_random(1,100) > 30 then entities[#entities + 1] = {name = "mineable-wreckage", position = p} end end @@ -687,25 +749,25 @@ local function generate_spawn_area(surface, position_left_top) for k, v in pairs(circles[r]) do local pos = {x = position_left_top.x + v.x, y = position_left_top.y+20 + v.y} if pos.x > -15 and pos.x < 15 and pos.y < 40 then - insert(tiles, {name = colors[math_random(1, #colors)].. "-refined-concrete", position = pos}) + insert(tiles, {name = "black-refined-concrete", position = pos}) end if pos.x > -30 and pos.x < 30 and pos.y < 40 then - insert(tiles, {name = colors[math_random(1, #colors)].. "-refined-concrete", position = pos}) + insert(tiles, {name = "black-refined-concrete", position = pos}) end if pos.x > -60 and pos.x < 60 and pos.y < 40 then - insert(tiles, {name = colors[math_random(1, #colors)].. "-refined-concrete", position = pos}) + insert(tiles, {name = "black-refined-concrete", position = pos}) end if pos.x > -90 and pos.x < 90 and pos.y < 40 then - insert(tiles, {name = colors[math_random(1, #colors)].. "-refined-concrete", position = pos}) + insert(tiles, {name = "black-refined-concrete", position = pos}) end if pos.x > -120 and pos.x < 120 and pos.y < 40 then - insert(tiles, {name = colors[math_random(1, #colors)].. "-refined-concrete", position = pos}) + insert(tiles, {name = "black-refined-concrete", position = pos}) end if pos.x > -150 and pos.x < 150 and pos.y < 40 then - insert(tiles, {name = colors[math_random(1, #colors)].. "-refined-concrete", position = pos}) + insert(tiles, {name = "black-refined-concrete", position = pos}) end if pos.x > -180 and pos.x < 180 and pos.y < 40 then - insert(tiles, {name = colors[math_random(1, #colors)].. "-refined-concrete", position = pos}) + insert(tiles, {name = "black-refined-concrete", position = pos}) end --if t_insert then -- insert(tiles, {name = t_insert, position = pos}) diff --git a/modules/burden.lua b/modules/burden.lua index ef15bb9f..f6c71863 100644 --- a/modules/burden.lua +++ b/modules/burden.lua @@ -34,8 +34,8 @@ local function check_burden(event) local player = game.players[event.player_index] validate_player(player) local fullness = compute_fullness(player) - player_modifiers[player.index].character_running_speed_modifier["scrapyard"] = 0.5 - fullness - player_modifiers[player.index].character_mining_speed_modifier["scrapyard"] = 0.5 - fullness + player_modifiers[player.index].character_running_speed_modifier["overworld"] = 0.5 - fullness + player_modifiers[player.index].character_mining_speed_modifier["overworld"] = 0.5 - fullness Modifier.update_player_modifiers(player) if fullness >= 0.5 and fullness <= 0.51 then player.print("You feel all of a sudden burden.", Color.yellow) diff --git a/modules/collapse.lua b/modules/collapse.lua new file mode 100644 index 00000000..3b8bac94 --- /dev/null +++ b/modules/collapse.lua @@ -0,0 +1,159 @@ +local Global = require 'utils.global' +local Public = {} + +local math_floor = math.floor +local table_shuffle_table = table.shuffle_table + +local collapse = {} +Global.register( + collapse, + function(tbl) + collapse = tbl + end +) + +local directions = { + ["north"] = function(position) + local width = collapse.surface.map_gen_settings.width + if width > collapse.max_line_size then width = collapse.max_line_size end + local a = width * 0.5 + 1 + collapse.vector = {0, -1} + collapse.area = {{position.x - a, position.y - 1}, {position.x + a, position.y}} + end, + ["south"] = function(position) + local width = collapse.surface.map_gen_settings.width + if width > collapse.max_line_size then width = collapse.max_line_size end + local a = width * 0.5 + 1 + collapse.vector = {0, 1} + collapse.area = {{position.x - a, position.y}, {position.x + a, position.y + 1}} + end, + ["west"] = function(position) + local width = collapse.surface.map_gen_settings.height + if width > collapse.max_line_size then width = collapse.max_line_size end + local a = width * 0.5 + 1 + collapse.vector = {-1, 0} + collapse.area = {{position.x - 1, position.y - a}, {position.x, position.y + a}} + end, + ["east"] = function(position) + local width = collapse.surface.map_gen_settings.height + if width > collapse.max_line_size then width = collapse.max_line_size end + local a = width * 0.5 + 1 + collapse.vector = {1, 0} + collapse.area = {{position.x, position.y - a}, {position.x + 1, position.y + a}} + end, +} + +local function print_debug(a) + print("Collapse error #" .. a) +end + +local function set_collapse_tiles() + game.forces.player.chart(collapse.surface, collapse.area) + collapse.tiles = collapse.surface.find_tiles_filtered({area = collapse.area}) + if not collapse.tiles then return end + collapse.size_of_tiles = #collapse.tiles + if collapse.size_of_tiles > 0 then table_shuffle_table(collapse.tiles) end + collapse.position = {x = collapse.position.x + collapse.vector[1], y = collapse.position.y + collapse.vector[2]} + local v = collapse.vector + local area = collapse.area + collapse.area = {{area[1][1] + v[1], area[1][2] + v[2]}, {area[2][1] + v[1], area[2][2] + v[2]}} +end + +local function progress() + local tiles = collapse.tiles + if not tiles then + set_collapse_tiles() + tiles = collapse.tiles + end + if not tiles then return end + + local surface = collapse.surface + for _ = 1, collapse.amount, 1 do + local tile = tiles[collapse.size_of_tiles] + if not tile then collapse.tiles = nil return end + collapse.size_of_tiles = collapse.size_of_tiles - 1 + if collapse.kill then + local position = {tile.position.x + 0.5, tile.position.y + 0.5} + for _, e in pairs(surface.find_entities_filtered({area = {{position[1] - 2, position[2] - 2}, {position[1] + 2, position[2] + 2}}})) do + if e.valid and e.health then e.die() end + end + end + surface.set_tiles({{name = "out-of-map", position = tile.position}}, true) + end +end + +function Public.set_surface(surface) + if not surface then print_debug(1) return end + if not surface.valid then print_debug(2) return end + if not game.surfaces[surface.index] then print_debug(3) return end + collapse.surface = surface +end + +function Public.set_direction(direction) + if not directions[direction] then print_debug(11) return end + directions[direction](collapse.position) +end + +function Public.set_speed(speed) + if not speed then print_debug(8) return end + speed = math_floor(speed) + if speed < 1 then speed = 1 end + collapse.speed = speed +end + +function Public.set_amount(amount) + if not amount then print_debug(9) return end + amount = math_floor(amount) + if amount < 0 then amount = 0 end + collapse.amount = amount +end + +function Public.set_position(position) + if not position then print_debug(4) return end + if not position.x and not position[1] then print_debug(5) return end + if not position.y and not position[2] then print_debug(6) return end + local x = 0 + local y = 0 + if position[1] then x = position[1] end + if position[2] then y = position[2] end + if position.x then x = position.x end + if position.y then y = position.y end + collapse.position = {x = x, y = y} +end + +function Public.get_position() + return collapse.position +end + +function Public.set_max_line_size(size) + if not size then print_debug(22) return end + size = math_floor(size) + if size <= 0 then print_debug(21) return end + collapse.max_line_size = size +end + +function Public.set_kill_entities(a) + collapse.kill = a +end + +local function on_init() + Public.set_surface(game.surfaces.nauvis) + Public.set_position({0, 32}) + Public.set_max_line_size(256) + Public.set_direction("north") + Public.set_kill_entities(true) + collapse.tiles = nil + collapse.speed = 1 + collapse.amount = 8 +end + +local function on_tick() + if game.tick % collapse.speed ~= 0 then return end + progress() +end + +local Event = require 'utils.event' +Event.on_init(on_init) +Event.add(defines.events.on_tick, on_tick) + +return Public \ No newline at end of file diff --git a/modules/immersive_cargo_wagons/functions.lua b/modules/immersive_cargo_wagons/functions.lua index e76fc896..660cc259 100644 --- a/modules/immersive_cargo_wagons/functions.lua +++ b/modules/immersive_cargo_wagons/functions.lua @@ -35,33 +35,30 @@ local function connect_power_pole(entity, wagon_area_left_top_y) end end +local function equal_fluid(source_tank, target_tank) + local source_fluid = source_tank.fluidbox[1] + if not source_fluid then return end + + local target_fluid = target_tank.fluidbox[1] + local source_fluid_amount = source_fluid.amount + + local amount + if target_fluid then + amount = source_fluid_amount - ((target_fluid.amount + source_fluid_amount) * 0.5) + else + amount = source_fluid.amount * 0.5 + end + + if amount <= 0 then return end + + local inserted_amount = target_tank.insert_fluid({name = source_fluid.name, amount = amount, temperature = source_fluid.temperature}) + if inserted_amount > 0 then source_tank.remove_fluid({name = source_fluid.name, amount = inserted_amount}) end +end + local function divide_fluid(wagon, storage_tank) - local wagon_fluidbox = wagon.entity.fluidbox - local fluid_wagon = wagon.entity - local wagon_fluid = wagon_fluidbox[1] - local tank_fluidbox = storage_tank.fluidbox - local tank_fluid = tank_fluidbox[1] - if not wagon_fluid and not tank_fluid then return end - if wagon_fluid and tank_fluid then - if wagon_fluid.name ~= tank_fluid.name then return end - end - if not wagon_fluid then - wagon_fluidbox[1] = {name = tank_fluid.name, amount = tank_fluid.amount * 0.5, temperature = tank_fluid.temperature} - storage_tank.remove_fluid({name = tank_fluid.name, amount = tank_fluid.amount * 0.5}) - return - end - if not tank_fluid then - tank_fluidbox[1] = {name = wagon_fluid.name, amount = wagon_fluid.amount * 0.5, temperature = wagon_fluid.temperature} - fluid_wagon.remove_fluid({name = wagon_fluid.name, amount = wagon_fluid.amount * 0.5}) - return - end - - local a = (wagon_fluid.amount + tank_fluid.amount) * 0.5 - local n = wagon_fluid.name - local t = wagon_fluid.temperature - - wagon_fluidbox[1] = {name = n, amount = a, temperature = t} - tank_fluidbox[1] = {name = n, amount = a, temperature = t} + local fluid_wagon = wagon.entity + equal_fluid(fluid_wagon, storage_tank) + equal_fluid(storage_tank, fluid_wagon) end local function input_filtered(wagon_inventory, chest, chest_inventory, free_slots) @@ -327,7 +324,7 @@ function Public.create_wagon_room(icw, wagon) if wagon.entity.type == "cargo-wagon" then local vectors = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}} local v = vectors[math_random(1, 4)] - local position = {math_random(area.left_top.x + 4, area.right_bottom.x - 4), math_random(area.left_top.y + 6, area.right_bottom.y - 6)} + local position = {math_random(area.left_top.x + 2, area.right_bottom.x - 3), math_random(area.left_top.y + 5, area.right_bottom.y - 6)} local e = surface.create_entity({ name = "logistic-chest-requester", @@ -434,7 +431,7 @@ function Public.use_cargo_wagon_door(icw, player, door) end end -function Public.move_room_to_train(icw, train, wagon) +local function move_room_to_train(icw, train, wagon) if not wagon then return end table_insert(train.wagons, wagon.entity.unit_number) @@ -507,7 +504,7 @@ function Public.construct_train(icw, carriages) icw.trains[unit_number] = train for k, carriage in pairs(carriages) do - Public.move_room_to_train(icw, train, icw.wagons[carriage.unit_number]) + move_room_to_train(icw, train, icw.wagons[carriage.unit_number]) end end diff --git a/modules/immersive_cargo_wagons/main.lua b/modules/immersive_cargo_wagons/main.lua index 0b9bc8c9..525ab1a6 100644 --- a/modules/immersive_cargo_wagons/main.lua +++ b/modules/immersive_cargo_wagons/main.lua @@ -66,16 +66,11 @@ local function on_player_driving_changed_state(event) local player = game.players[event.player_index] Functions.use_cargo_wagon_door(icw, player, event.entity) end ---[[ -local function on_player_created(event) - local player = game.players[event.player_index] - player.insert({name = "cargo-wagon", count = 5}) - player.insert({name = "artillery-wagon", count = 5}) - player.insert({name = "fluid-wagon", count = 5}) - player.insert({name = "locomotive", count = 5}) - player.insert({name = "rail", count = 100}) + +local function on_player_left_game(event) + Functions.kill_minimap(game.players[event.player_index]) end -]] + local function on_gui_closed(event) local entity = event.entity if not entity then return end @@ -138,7 +133,7 @@ Event.add(defines.events.on_built_entity, on_built_entity) Event.add(defines.events.on_train_created, on_train_created) Event.add(defines.events.on_robot_built_entity, on_robot_built_entity) Event.add(defines.events.on_player_died, on_player_died) ---Event.add(defines.events.on_player_created, on_player_created) +Event.add(defines.events.on_player_left_game, on_player_left_game) Event.add(defines.events.on_gui_click, on_gui_click) Event.add(defines.events.on_gui_closed, on_gui_closed) Event.add(defines.events.on_gui_opened, on_gui_opened) diff --git a/modules/rpg.lua b/modules/rpg.lua index 0549b84d..24ce23e7 100644 --- a/modules/rpg.lua +++ b/modules/rpg.lua @@ -16,6 +16,8 @@ Modified by Gerkiz *-* require "player_modifiers" local math_random = math.random +local math_sqrt = math.sqrt +local math_floor = math.floor local Global = require 'utils.global' local Tabs = require "comfy_panel.main" local P = require "player_modifiers" @@ -793,12 +795,16 @@ local function on_pre_player_mined_item(event) rpg_t[player.index].last_mined_entity_position.x = entity.position.x rpg_t[player.index].last_mined_entity_position.y = entity.position.y - if entity.type == "resource" then gain_xp(player, 0.5) return end - --if entity.force.index == 3 then - gain_xp(player, 1.5 + event.entity.prototype.max_health * 0.0035) - --return - --end - --gain_xp(player, 0.1 + event.entity.prototype.max_health * 0.0005) + local distance_multiplier = math_floor(math_sqrt(entity.position.x ^ 2 + entity.position.y ^ 2)) * 0.0005 + 1 + + local xp_amount + if entity.type == "resource" then + xp_amount = 0.5 * distance_multiplier + else + xp_amount = (1.5 + event.entity.prototype.max_health * 0.0035) * distance_multiplier + end + + gain_xp(player, xp_amount) end local function on_player_crafted_item(event) diff --git a/readme.md b/readme.md index 7b4be4ed..0f80fcbb 100644 --- a/readme.md +++ b/readme.md @@ -1,6 +1,6 @@