1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-03-17 20:58:13 +02:00

Merge pull request #158 from M3wM3w/PR

PR from Hana
This commit is contained in:
MewMew 2020-04-19 14:02:51 +02:00 committed by GitHub
commit 4a282f2e05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
42 changed files with 6704 additions and 470 deletions

View File

@ -390,7 +390,7 @@ local function on_gui_selection_state_changed(event)
end
end
comfy_panel_tabs["Admin"] = create_admin_panel
comfy_panel_tabs["Admin"] = {gui = create_admin_panel, admin = true}

View File

@ -1,4 +1,4 @@
-- config tab --
-- config tab --
local Tabs = require 'comfy_panel.main'
@ -13,22 +13,22 @@ local function spaghett_deny_building(event)
if not spaghett.enabled then return end
local entity = event.created_entity
if not entity.valid then return end
if not spaghett_entity_blacklist[event.created_entity.name] then return end
if not spaghett_entity_blacklist[event.created_entity.name] then return end
if event.player_index then
game.players[event.player_index].insert({name = entity.name, count = 1})
else
game.players[event.player_index].insert({name = entity.name, count = 1})
else
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
inventory.insert({name = entity.name, count = 1})
inventory.insert({name = entity.name, count = 1})
end
event.created_entity.surface.create_entity({
name = "flying-text",
position = entity.position,
text = "Spaghett Mode Active!",
color = {r=0.98, g=0.66, b=0.22}
})
entity.destroy()
end
@ -50,19 +50,19 @@ local function spaghett()
spaghett.undo[f.index] = nil
end
end
end
end
end
local functions = {
["comfy_panel_spectator_switch"] = function(event)
["comfy_panel_spectator_switch"] = function(event)
if event.element.switch_state == "left" then
game.players[event.player_index].spectator = true
else
game.players[event.player_index].spectator = false
end
end,
["comfy_panel_auto_hotbar_switch"] = function(event)
["comfy_panel_auto_hotbar_switch"] = function(event)
if event.element.switch_state == "left" then
global.auto_hotbar_enabled[event.player_index] = true
else
@ -99,33 +99,33 @@ local function add_switch(element, switch_state, name, description_main, descrip
local switch = t.add({type = "switch", name = name})
switch.switch_state = switch_state
switch.style.padding = 0
switch.style.margin = 0
switch.style.margin = 0
local label = t.add({type = "label", caption = "OFF"})
label.style.padding = 0
label.style.font_color = {0.70, 0.70, 0.70}
local label = t.add({type = "label", caption = description_main})
label.style.padding = 2
label.style.left_padding= 10
label.style.minimal_width = 120
label.style.font = "heading-2"
label.style.font_color = {0.88, 0.88, 0.99}
local label = t.add({type = "label", caption = description})
label.style.padding = 2
label.style.left_padding= 10
label.style.single_line = false
label.style.font = "heading-3"
label.style.font_color = {0.85, 0.85, 0.85}
return switch
end
local build_config_gui = (function (player, frame)
local build_config_gui = (function (player, frame)
frame.clear()
local admin = player.admin
local label = frame.add({type = "label", caption = "Player Settings"})
label.style.font = "default-bold"
label.style.padding = 0
@ -133,15 +133,15 @@ local build_config_gui = (function (player, frame)
label.style.horizontal_align = "left"
label.style.vertical_align = "bottom"
label.style.font_color = {0.55, 0.55, 0.99}
frame.add({type = "line"})
local switch_state = "right"
if player.spectator then switch_state = "left" end
add_switch(frame, switch_state, "comfy_panel_spectator_switch", "SpectatorMode", "Toggles zoom-to-world view noise effect.\nEnvironmental sounds will be based on map view.")
frame.add({type = "line"})
if global.auto_hotbar_enabled then
local switch_state = "right"
if global.auto_hotbar_enabled[player.index] then switch_state = "left" end
@ -157,23 +157,23 @@ local build_config_gui = (function (player, frame)
label.style.horizontal_align = "left"
label.style.vertical_align = "bottom"
label.style.font_color = {0.77, 0.11, 0.11}
frame.add({type = "line"})
local switch_state = "right"
if game.permissions.get_group("Default").allows_action(defines.input_action.import_blueprint) then switch_state = "left" end
local switch = add_switch(frame, switch_state, "comfy_panel_blueprint_toggle", "Blueprint Library", "Toggles the usage of blueprint strings and the library.")
if not admin then switch.ignored_by_interaction = true end
frame.add({type = "line"})
local switch_state = "right"
if global.comfy_panel_config.spaghett.enabled then switch_state = "left" end
local switch = add_switch(frame, switch_state, "comfy_panel_spaghett_toggle", "Spaghett Mode", "Disables the Logistic System research.\nRequester, buffer or active-provider containers can not be built.")
if not admin then switch.ignored_by_interaction = true end
frame.add({type = "line"})
for _, e in pairs(frame.children) do
if e.type == "line" then
e.style.padding = 0
@ -209,7 +209,7 @@ local function on_init()
global.comfy_panel_config.spaghett.undo = {}
end
comfy_panel_tabs["Config"] = build_config_gui
comfy_panel_tabs["Config"] = {gui = build_config_gui, admin = false}
local Event = require 'utils.event'
@ -217,4 +217,4 @@ Event.on_init(on_init)
Event.add(defines.events.on_gui_switch_state_changed, on_gui_switch_state_changed)
Event.add(defines.events.on_force_created, on_force_created)
Event.add(defines.events.on_built_entity, on_built_entity)
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)

View File

@ -214,7 +214,7 @@ local function on_gui_click(event)
end
end
comfy_panel_tabs["Groups"] = build_group_gui
comfy_panel_tabs["Groups"] = {gui = build_group_gui, admin = false}
local event = require 'utils.event'

View File

@ -3,7 +3,8 @@ Comfy Panel
To add a tab, insert into the "comfy_panel_tabs" table.
Example: comfy_panel_tabs["mapscores"] = draw_map_scores
Example: comfy_panel_tabs["mapscores"] = {gui = draw_map_scores, admin = false}
if admin = true, then tab is visible only for admins (usable for map-specific settings)
draw_map_scores would be a function with the player and the frame as arguments
@ -35,13 +36,13 @@ end
function Public.comfy_panel_get_active_frame(player)
if not player.gui.left.comfy_panel then return false end
if not player.gui.left.comfy_panel.tabbed_pane.selected_tab_index then return player.gui.left.comfy_panel.tabbed_pane.tabs[1].content end
return player.gui.left.comfy_panel.tabbed_pane.tabs[player.gui.left.comfy_panel.tabbed_pane.selected_tab_index].content
return player.gui.left.comfy_panel.tabbed_pane.tabs[player.gui.left.comfy_panel.tabbed_pane.selected_tab_index].content
end
function Public.comfy_panel_refresh_active_tab(player)
local frame = Public.comfy_panel_get_active_frame(player)
if not frame then return end
comfy_panel_tabs[frame.name](player, frame)
comfy_panel_tabs[frame.name].gui(player, frame)
end
local function top_button(player)
@ -62,7 +63,7 @@ local function main_frame(player)
local tabbed_pane = frame.add({type = "tabbed-pane", name = "tabbed_pane"})
for name, func in pairs(tabs) do
if name == "Admin" then
if func.admin == true then
if player.admin then
local tab = tabbed_pane.add({type = "tab", caption = name})
local frame = tabbed_pane.add({type = "frame", name = name, direction = "vertical"})
@ -142,4 +143,4 @@ end
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_gui_click, on_gui_click)
return Public
return Public

View File

@ -388,7 +388,7 @@ local on_init = function()
global.player_list.sorting_method = {}
end
comfy_panel_tabs["Players"] = player_list_show
comfy_panel_tabs["Players"] = {gui = player_list_show, admin = false}
event.on_init(on_init)
event.add(defines.events.on_player_joined_game, on_player_joined_game)

View File

@ -1297,6 +1297,6 @@ function Class.send_poll_result_to_discord(id)
Server.to_discord_embed(message)
end
comfy_panel_tabs["Polls"] = draw_main_frame
comfy_panel_tabs["Polls"] = {gui = draw_main_frame, admin = false}
return Class

View File

@ -358,7 +358,7 @@ local function tick(event)
refresh_score_full()
end
]]
comfy_panel_tabs["Scoreboard"] = show_score
comfy_panel_tabs["Scoreboard"] = {gui = show_score, admin = false}
--event.on_nth_tick(300, tick)
event.add(defines.events.on_player_mined_entity, on_player_mined_entity)

View File

@ -298,7 +298,9 @@ commands.add_command(
local radius = {{x = (pos.x + -param), y = (pos.y + -param)}, {x = (pos.x + param), y = (pos.y + param)}}
for _, entity in pairs(player.surface.find_entities_filtered{area = radius, type = "corpse"}) do
entity.destroy()
if entity.corpse_expires then
entity.destroy()
end
end
player.print("Cleared biter-corpses.", Color.success)
end)

View File

@ -27,6 +27,7 @@ require "comfy_panel.config"
require "modules.autostash"
---- enable modules here ----
--require "modules.admins_operate_biters"
--require "modules.the_floor_is_lava"
--require "modules.biters_landfill_on_death"
--require "modules.autodecon_when_depleted"
@ -45,6 +46,7 @@ require "modules.autostash"
--require "modules.fluids_are_explosive"
--require "modules.hunger"
--require "modules.hunger_games"
--require "modules.pistol_buffs"
--require "modules.players_trample_paths"
--require "modules.railgun_enhancer"
--require "modules.restrictive_fluid_mining"
@ -66,6 +68,7 @@ require "modules.autostash"
-----------------------------
---- enable maps here ---- (maps higher up in the list may be more actually playable)
--require "maps.chronosphere.main"
--require "maps.fish_defender.main"
--require "maps.biter_battles_v2.main"
--require "maps.native_war.main"
@ -126,7 +129,7 @@ require "modules.autostash"
--require "modules.trees_grow"
--require "modules.trees_randomly_die"
--require "terrain_layouts.caves"
--require "terrain_layouts.caves"
--require "terrain_layouts.cone_to_east"
--require "terrain_layouts.biters_and_resources_east"
--require "terrain_layouts.scrap_01"

View File

@ -21,7 +21,8 @@ for _, t in pairs (kaboom_weights) do
end
local function create_flying_text(surface, position, text)
surface.create_entity({
if not surface.valid then return end
surface.create_entity({
name = "flying-text",
position = position,
text = text,
@ -32,7 +33,8 @@ local function create_flying_text(surface, position, text)
end
local function create_kaboom(surface, position, name)
local target = position
if not surface.valid then return end
local target = position
local speed = 0.5
if name == "defender-capsule" or name == "destroyer-capsule" or name == "distractor-capsule" then
surface.create_entity({
@ -56,6 +58,7 @@ end
local function tick_tack_trap(surface, position)
if not surface then return end
if not surface.valid then return end
if not position then return end
if not position.x then return end
if not position.y then return end
@ -84,4 +87,4 @@ local function tick_tack_trap(surface, position)
end
end
return tick_tack_trap
return tick_tack_trap

View File

@ -52,6 +52,7 @@ end
local function unearthing_biters(surface, position, amount)
if not surface then return end
if not surface.valid then return end
if not position then return end
if not position.x then return end
if not position.y then return end
@ -79,4 +80,4 @@ local function unearthing_biters(surface, position, amount)
end
end
return unearthing_biters
return unearthing_biters

View File

@ -37,6 +37,7 @@ end
local function unearthing_worm(surface, position)
if not surface then return end
if not surface.valid then return end
if not position then return end
if not position.x then return end
if not position.y then return end
@ -61,4 +62,4 @@ local function unearthing_worm(surface, position)
end
end
return unearthing_worm
return unearthing_worm

View File

@ -62,6 +62,139 @@ map_info_main_caption=M O U N T A I N F O R T R E S S
map_info_sub_caption= ..diggy diggy choo choo..
map_info_text=The biters have catched the scent of fish in the cargo wagon.\nGuide the choo into the mountain and protect it as long as possible!\nThis however will not be an easy task,\nsince their strength and numbers increase over time.\n\nIn additon, the southern grounds collapse over time.\nStone bricks, concrete or other solid tiles, might improve the stability of the floor.\n\nDelve deep for greater treasures, but also face increased dangers.\nMining productivity research, will overhaul your mining equipment,\nreinforcing your pickaxe as well as increasing the size of your backpack.\n\nAs you dig, you will encounter impassable dark chasms or rivers.\nSome explosives may cause parts of the ceiling to crumble, filling the void, creating new ways.\nAll they need is a container and a well aimed shot.\n\nYou may find some supply goods, if you enter the wagon.\nGood luck on your journey!
[chronosphere]
map_info_main_caption=Chronosphere
map_info_sub_caption= ..Comfylatron gone wild..
map_info_text_old=Comfylatron has seized The Fish Train and turned it into a time machine.\nIt is your job to make sure the cargo is safe throughout the times and places we travel through!\nThis however will not be an easy task,\nas Comfylatron does not have any idea how to control this machine at all.\n\nThe destinations of quantum time jumps are completely random, and the machine always needs time to recharge.\nYou can speed it up greatly by charging acumulators in Locomotive.\nSo be sure to grab as many resources as you can before the train jump away!\nComfylatron manages to run teleporting devices to transport items into train from his chests. Also to save people from staying in wrong universe.\n\nOnce a quantum jump is initiated, be sure to have everything packed up, there is nearly zero chance to revisit that place again!\nMining productivity research will overhaul your mining equipment,\nreinforcing your pickaxes, as well as increasing the size of your backpack.\nGood luck on your journey!
map_info_text=Comfylatron has seized the Fish Train and turned it into a time machine.\n Your job as his slave is:\n\n[1] Keep train alive at all costs\n[2] Gather resources while travelling through different maps.\n[3a] Press enter on cargo wagons to enter insides of train.\n[3b] Press enter on cars to exit the train.\n[4] Charging acumulators inside train speeds up jumps when leaving early is needed.\nCharging and jumping creates huge pollution so be ready to get attacked.\n[5] Items inserted into comfylatron chests get teleported into train.\n[6] Some planets are poor, some are rich, and some are just too dangerous.\n\n Loot, but also evolution grows with jumps performed.\n During jump, personnel will be teleported in,\n however dead bodies nor buildings won't.\nMining productivity grants inventory space and handmining speed.\n\nGood luck. Don't let biters ruin the show!
planet_jump=Destination: __1__, Ore Richness: __2__, Daynight cycle: __3__
message_danger1=Comfylatron: We have a problem! We got disrupted in mid-jump, only part of energy got used, and here we landed. It might have been a trap!
message_danger2=Comfylatron: My analysis says that charging needs full energy reset to work again, so we are stuck there until next full jump.
message_danger3=Robot voice: INTRUDER ALERT! Lifeforms detected! Must eliminate!
message_danger4=Robot voice: Nuclear missiles armed, launch countdown enabled.
message_jump180=Comfylatron: Acumulator charging disabled, 180 seconds countdown to jump!
message_jump60=Comfylatron: ChronoTrain nearly charged! Grab what you can, we leaving in 60 seconds!
message_jump30=Comfylatron: You better hurry up! 30 seconds remaining!
message_nuke=Warning: Nuclear missiles launched.
message_accident=Comfylatron: Offline player had an accident, and dropped his items on ground around locomotive.
message_silo=Nuclear silo destroyed. You managed to loot 5 atomic bombs. Comfylatron seized them for your own safety.
message_game_won_restart=Comfylatron: WAIT whaat? Looks like we did not fixed the train properly and it teleported us back in time...sigh...so let's do this again, and now properly.
message_fishmarket1=Comfylatron: So here we are. Fish Market. When they ordered the fish, they said this location is perfectly safe. Looks like we will have to do it for them.
message_fishmarket2=Comfylatron: I hope you have enough nukes. Also, that satellite gave us some space knowledge.
message_fishmarket3=Comfylatron: Luckily we looted some nukes before, take them.
message_lava=Comfylatron: OOF this one is a bit hot. And have seen those biters? They BATHE in fire! Maybe try some bricks to protect from lava?
message_choppy=Comfylatron: OwO what are those strange trees?!? They have ore fruits! WTF!
message_game_lost1=The chronotrain was destroyed!
message_game_lost2=Comfylatron is going to kill you for that...he has time machine after all!
message_evolve=Comfylatron: Biters start to evolve faster! We need to charge forward or they will be stronger! (hover over timer to see evolve timer)
message_quest1=Comfylatron: You know...I have big quest. Deliver fish to fish market. But this train is broken. Please help me fix the train computer!
message_quest3=Comfylatron: Ah, we need to give this machine more power and better navigation chipset. Please bring me some additional things.
message_quest5=Comfylatron: Finally found the main issue. We will need to rebuild whole processor. Exactly what I feared of. Just a few more things...
message_quest6=Comfylatron: And this was last part of cpu brain done. Now we just need to synchronize our time correctly and we are done! Bring me satellite and rocket silo.
message_quest7=Comfylatron: Time synchronized. Calculating time and space destination. Success. Jump once more and let me deliver the fish finally. This trip is getting long.
message_game_won1=Comfylatron: Thank you with helping me on this delivery. It was tough one. I hope, that now, when all biters are dead, fish will be safe here forever...
message_overstay=Comfylatron: Looks like you stayed on previous planet for so long that enemies on other planets had additional time to evolve!
message_poison_defense=Comfylatron: Triggering poison defense. Let's kill everything!
map_1=Terra Ferrata
map_2=Malachite Hills
map_3=Granite Plains
map_4=Petroleum Basin
map_5=Pitchblende Mountain
map_6=Mixed Deposits
map_7=Biter Homelands
map_8=Gangue Dumps
map_9=Antracite Valley
map_10=Ancient Battlefield
map_11=Cave Systems
map_12=Strange Forest
map_13=Riverlands
map_14=Burning Hell
map_15=Starting Area
map_16=Hedge Maze
map_17=Fish Market
map_18=Methane Swamps
map_19=ERROR DESTINATION NOT FOUND
ore_richness_very_rich=Very Rich
ore_richness_rich=Rich
ore_richness_normal=Normal
ore_richness_poor=Poor
ore_richness_very_poor=Very Poor
ore_richness_none=None
daynight_static=Static
daynight_normal=Normal
daynight_slow=Slow
daynight_superslow=Super Slow
daynight_fast=Fast
daynight_superfast=Super Fast
upgrade_train_armor=Train Armor
upgrade_train_armor_message=Comfylatron: Train's max HP was upgraded.
upgrade_train_armor_tooltip=+2500 Train Max HP. Max level: __1__ Current Max HP: __2__
upgrade_filter=Pollution Filter
upgrade_filter_message=Comfylatron: Train's pollution filter was upgraded.
upgrade_filter_tooltip=Train Pollution Filter. Decreases pollution from inside of train and from chrono engine.\nCurrent pollution made by train: __1__%
upgrade_accumulators=Accumulators
upgrade_accumulators_message=Comfylatron: Train's accumulator capacity was upgraded.
upgrade_accumulators_tooltip=Add additional row of Accumulators for train's charging system.\nEach accumulator adds 300kW possible power input.
upgrade_loot_pickup=Loot Pickup Range
upgrade_loot_pickup_message=Comfylatron: Players now have additional red inserter installed on shoulders, increasing their item pickup range.
upgrade_loot_pickup_tooltip=Add loot pickup distance to players. Current: +__1__ tiles range
upgrade_inventory_size=Character Inventory Size
upgrade_inventory_size_message=Comfylatron: Players now can carry more trash in their unsorted inventories.
upgrade_inventory_size_tooltip=Add +10 inventory slots to all players.
upgrade_repair=Train Repair Speed
upgrade_repair_message=Comfylatron: Train now gets repaired with additional repair kit at once.
upgrade_repair_tooltip=Train uses more repair tools at once from Repair chest. Current: +__1__
upgrade_water=Piping System
upgrade_water_message=Comfylatron: Train now has piping system for additional water sources.
upgrade_water_tooltip=Add piping through wagon sides to create water sources for each wagon.
upgrade_output=Output System
upgrade_output_message=Comfylatron: Train now has output chests.
upgrade_output_tooltip=Add comfylatron chests that output outside (into cargo wagon 2 and 3)
upgrade_storage=Train Storage
upgrade_storage_message=Comfylatron: Cargo wagons now have upgraded storage.
upgrade_storage_tooltip=Add and upgrade storage chests to the sides of wagons.
upgrade_poison=Poison Defense
upgrade_poison_message=Comfylatron: I don't believe in your defense skills. I equipped train with poison defense.
upgrade_poison_tooltip=Poison defense. Triggers automatically when train has low HP.\nMax charges : 4. Recharge timer for next use: __1__ min.
upgrade_fusion=Fusion Reactor
upgrade_fusion_message=Comfylatron: One personal fusion reactor ready.
upgrade_fusion_tooltip=Creates one Fusion Reactor.
upgrade_mk2=Power Armor MK2
upgrade_mk2_message=Comfylatron: I upgraded one armor to mk2.
upgrade_mk2_tooltip=Creates one Power Armor MK2
upgrade_computer1=Comfylatron's Quest 1
upgrade_computer1_message=Comfylatron: Thanks for fixing train navigation. I can now get us rid of very poor worlds. It will still need more work though, come back after jump.
upgrade_computer1_tooltip=Progresses main quest.\nAll next worlds won't have "very poor" ore distribution.
upgrade_computer2=Comfylatron's Quest 2
upgrade_computer2_message=Comfylatron: Perfect! Now we have train reactor and even better destination precision. I will get to you after jump with what still needs to be done.
upgrade_computer2_tooltip=Progresses main quest.\nAll next worlds won't have "poor" ore distribution.
upgrade_computer3=Comfylatron's Quest 3
upgrade_computer3_message=Comfylatron: That's __1__ / 10 processor parts done!
upgrade_computer3_tooltip=Progresses main quest.\nAfter completing 10th part, the final map can be unlocked.
upgrade_computer4=Comfylatron's Final Quest
upgrade_computer4_message=Comfylatron: Time synchronized. Calculating time and space destination. Success. Jump once more and let me deliver the fish finally. This trip is getting long.
upgrade_computer4_tooltip=Progresses main quest.\nBy unlocking this, the next destination is Fish Market map.\nBe sure to be ready, there is no way back!
gui_1=ChronoJumps:
gui_2=Charge:
gui_3=Timer:
gui_3_1=Best Case Timer:
gui_3_2=Nuclear missiles launched in:
gui_4=Local Evolution:
gui_planet_button=Map Info
gui_upgrades_button=Upgrades
gui_upgrades_1=Insert needed items into chest with given picture.
gui_upgrades_2=Chests are at top inside the train. Upgrading can take a minute.
gui_planet_0=Name: __1__
gui_planet_1=Detected ore distribution:
gui_planet_2=Ore Amounts: __1__
gui_planet_3=Local evolution: __1__%
gui_planet_4=Global evolution bonuses:
gui_planet_4_1=+__1__% evolution, +__2__% damage
gui_planet_5=Daynight cycle: __1__
[rocks_yield_ore_veins]
coal=coal
iron-ore=iron
@ -101,7 +234,7 @@ angels-ore6=umber
gui_1=First wave in
gui_2=Wave:
gui_3=Threat:
tooltip_1=high threat may empower biters
tooltip_1=High threat may empower biters.\nBiter health: __1__%
tooltip_2=gain / minute
[native_war]

455
maps/chronosphere/ai.lua Normal file
View File

@ -0,0 +1,455 @@
local Public = {}
local math_random = math.random
local math_sqrt = math.sqrt
local math_floor = math.floor
local worm_raffle = { "small-worm-turret", "medium-worm-turret", "big-worm-turret", "behemoth-worm-turret"}
local spawner_raffle = {"biter-spawner", "biter-spawner", "biter-spawner", "spitter-spawner"}
local biter_raffle = {
"behemoth-biter", "behemoth-spitter", "big-biter", "big-spitter",
"medium-biter", "medium-spitter", "small-biter", "small-spitter"
}
local vector_radius = 480
local attack_vectors = {}
for x = vector_radius * -1, vector_radius, 1 do
for y = 0, vector_radius, 1 do
local r = math_sqrt(x ^ 2 + y ^ 2)
if r < vector_radius and r > vector_radius - 1 then
attack_vectors[#attack_vectors + 1] = {x, y}
end
end
end
local size_of_vectors = #attack_vectors
-- these areas are for north
local middle_spawner_area = {left_top = {-400, -400}, right_bottom = {400, 400}}
local whole_spawner_area = {left_top = {-1100, -500}, right_bottom = {1100, 500}}
local function get_active_biter_count()
local count = 0
for _, biter in pairs(global.objective.active_biters) do
count = count + 1
end
return count
end
local function set_biter_raffle_table(surface)
-- It's fine to only sample the middle
local area = middle_spawner_area
local biters = surface.find_entities_filtered({type = "unit", force = "enemy", area = area})
if not biters[1] then return end
local raffle = global.objective.biter_raffle
local i = 1
for key, e in pairs(biters) do
if key % 5 == 0 then
raffle[i] = e.name
i = i + 1
end
end
end
local function is_biter_inactive(biter, unit_number)
if not biter.entity then
--print("AI: active unit " .. unit_number .. " removed, possibly died.")
return true
end
if not biter.entity.valid then
--print("AI: active unit " .. unit_number .. " removed, biter invalid.")
return true
end
if not biter.entity.unit_group then
--print("AI: active unit " .. unit_number .. " at x" .. biter.entity.position.x .. " y" .. biter.entity.position.y .. " removed, had no unit group.")
return true
end
if not biter.entity.unit_group.valid then
--print("AI: active unit " .. unit_number .. " removed, unit group invalid.")
return true
end
if game.tick - biter.active_since > 162000 then
--print("AI: " .. "enemy" .. " unit " .. unit_number .. " timed out at tick age " .. game.tick - biter.active_since .. ".")
biter.entity.destroy()
return true
end
end
local function set_active_biters(group)
if not group.valid then return end
local active_biters = global.objective.active_biters
for _, unit in pairs(group.members) do
if not active_biters[unit.unit_number] then
active_biters[unit.unit_number] = {entity = unit, active_since = game.tick}
end
end
end
Public.destroy_inactive_biters = function()
local objective = global.objective
if objective.chronotimer < 100 then return end
for _, group in pairs(objective.unit_groups) do
set_active_biters(group)
end
for unit_number, biter in pairs(objective.active_biters) do
if is_biter_inactive(biter, unit_number) then
objective.active_biters[unit_number] = nil
end
end
end
local function colonize(unit_group)
local surface = unit_group.surface
local evo = math_floor(game.forces["enemy"].evolution_factor * 20)
local nests = math_random(1 + evo, 2 + evo * 2 )
local commands = {}
local biters = surface.find_entities_filtered{position = unit_group.position, radius = 30, name = biter_raffle, force = "enemy"}
local goodbiters = {}
if #biters > 1 then
for i = 1, #biters, 1 do
if biters[i].unit_group == unit_group then goodbiters[#goodbiters + 1] = biters[i] end
end
end
local eligible_spawns = 0
if #goodbiters < 10 then
--game.print("no biters to colonize")
if #unit_group.members < 10 then
unit_group.destroy()
end
return
else
eligible_spawns = 1 + math_floor(#goodbiters / 10)
end
local success = false
for i = 1, nests, 1 do
if eligible_spawns < i then break end
local pos = surface.find_non_colliding_position("rocket-silo", unit_group.position, 20, 1, true)
if not pos then
local items = surface.find_entities_filtered{position = unit_group.position, radius = 32, type = "item-entity", name = "item-on-ground"}
if #items > 0 then
for i = 1, #items, 1 do
if items[i].stack.name == "stone" then
items[i].destroy()
end
end
pos = surface.find_non_colliding_position("rocket-silo", unit_group.position, 20, 1, true)
end
end
if pos then
success = true
local e = nil
if math_random(1,5) == 1 then
e = surface.create_entity({name = worm_raffle[1 + math_floor((game.forces["enemy"].evolution_factor - 0.000001) * 4)], position = pos, force = unit_group.force})
else
e = surface.create_entity({name = spawner_raffle[math_random(1, #spawner_raffle)], position = pos, force = unit_group.force})
end
--game.print("[gps=" .. e.position.x .. "," .. e.position.y .. "]")
else
local obstacles = surface.find_entities_filtered{position = unit_group.position, radius = 10, type = {"simple-entity", "tree"}, limit = 50}
if obstacles then
for i = 1, #obstacles, 1 do
if obstacles[i].valid then
commands[#commands + 1] = {
type = defines.command.attack,
target = obstacles[i],
distraction = defines.distraction.by_enemy
}
end
end
end
end
end
if success then
for i = 1, #goodbiters, 1 do
if goodbiters[i].valid then goodbiters[i].destroy() end
end
end
if #commands > 0 then
--game.print("Attacking [gps=" .. commands[1].target.position.x .. "," .. commands[1].target.position.y .. "]")
unit_group.set_command({
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
commands = commands
})
end
--unit_group.destroy()
end
Public.send_near_biters_to_objective = function()
if game.tick < 36000 then return end
if not global.locomotive then return end
if not global.locomotive_cargo[1] then return end
if not global.locomotive_cargo[2] then return end
if not global.locomotive_cargo[3] then return end
local targets = {global.locomotive, global.locomotive, global.locomotive_cargo[1], global.locomotive_cargo[2], global.locomotive_cargo[3]}
local random_target = targets[math_random(1, #targets)]
if global.objective.game_lost then return end
local surface = random_target.surface
local pollution = surface.get_pollution(random_target.position)
local success = false
if pollution > 200 * (1 / global.difficulty_vote_value) or global.objective.planet[1].name.id == 17 then
surface.pollute(random_target.position, -50 * (1 / global.difficulty_vote_value))
--game.print("sending objective wave")
success = true
else
if global.objective.chronojumps < 50 then
if math_random(1, 50 - global.objective.chronojumps) == 1 then success = true end
--game.print("not enough pollution for objective attack")
else
success = true
end
end
if success then
game.surfaces[global.active_surface_index].set_multi_command({
command={
type=defines.command.attack,
target=random_target,
distraction=defines.distraction.none
},
unit_count = 16 + math_random(1, math_floor(1 + game.forces["enemy"].evolution_factor * 100)) * global.difficulty_vote_value,
force = "enemy",
unit_search_distance=128
})
end
end
local function get_random_close_spawner(surface)
local area = whole_spawner_area
local spawners = surface.find_entities_filtered({type = "unit-spawner", force = "enemy", area = area})
if not spawners[1] then return false end
local spawner = spawners[math_random(1,#spawners)]
for i = 1, 5, 1 do
local spawner_2 = spawners[math_random(1,#spawners)]
if spawner_2.position.x ^ 2 + spawner_2.position.y ^ 2 < spawner.position.x ^ 2 + spawner.position.y ^ 2 then spawner = spawner_2 end
end
return spawner
end
local function select_units_around_spawner(spawner)
local biters = spawner.surface.find_enemy_units(spawner.position, 160, "player")
if not biters[1] then return false end
local valid_biters = {}
local objective = global.objective
local unit_count = 0
local max_unit_count = 128 * global.difficulty_vote_value
for _, biter in pairs(biters) do
if unit_count >= max_unit_count then break end
if biter.force.name == "enemy" and objective.active_biters[biter.unit_number] == nil then
valid_biters[#valid_biters + 1] = biter
objective.active_biters[biter.unit_number] = {entity = biter, active_since = game.tick}
unit_count = unit_count + 1
end
end
--Manual spawning of additional units
local size_of_biter_raffle = #objective.biter_raffle
if size_of_biter_raffle > 0 then
for c = 1, max_unit_count - unit_count, 1 do
local biter_name = objective.biter_raffle[math_random(1, size_of_biter_raffle)]
local position = spawner.surface.find_non_colliding_position(biter_name, spawner.position, 128, 2)
if not position then break end
local biter = spawner.surface.create_entity({name = biter_name, force = "enemy", position = position})
valid_biters[#valid_biters + 1] = biter
objective.active_biters[biter.unit_number] = {entity = biter, active_since = game.tick}
end
end
return valid_biters
end
local function send_group(unit_group, nearest_player_unit)
local targets = {global.locomotive, global.locomotive, nearest_player_unit, nearest_player_unit, nearest_player_unit, global.locomotive_cargo[1], global.locomotive_cargo[2], global.locomotive_cargo[3]}
local target = targets[math_random(1, #targets)]
if not target.valid then colonize(unit_group) return end
local surface = target.surface
local pollution = surface.get_pollution(target.position)
if pollution > 200 * (1 / global.difficulty_vote_value) or global.objective.planet[1].name.id == 17 then
surface.pollute(target.position, -50 * (1 / global.difficulty_vote_value))
--game.print("sending unit group attack")
local commands = {}
local vector = attack_vectors[math_random(1, size_of_vectors)]
local position = {target.position.x + vector[1], target.position.y + vector[2]}
position = unit_group.surface.find_non_colliding_position("stone-furnace", position, 96, 1)
if position then
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = position,
radius = 24,
distraction = defines.distraction.by_enemy
}
end
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = target.position,
radius = 32,
distraction = defines.distraction.by_enemy
}
commands[#commands + 1] = {
type = defines.command.attack,
target = target,
distraction = defines.distraction.by_enemy
}
unit_group.set_command({
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
commands = commands
})
else
--game.print("not enough pollution for unit attack")
colonize(unit_group)
end
return true
end
local function is_chunk_empty(surface, area)
if surface.count_entities_filtered({type = {"unit-spawner", "unit"}, area = area}) ~= 0 then return false end
if surface.count_entities_filtered({force = "player", area = area}) ~= 0 then return false end
if surface.count_tiles_filtered({name = {"water", "deepwater"}, area = area}) ~= 0 then return false end
return true
end
local function get_unit_group_position(surface, nearest_player_unit, spawner)
if math_random(1,3) ~= 1 then
local spawner_chunk_position = {x = math.floor(spawner.position.x / 32), y = math.floor(spawner.position.y / 32)}
local valid_chunks = {}
for x = -2, 2, 1 do
for y = -2, 2, 1 do
local chunk = {x = spawner_chunk_position.x + x, y = spawner_chunk_position.y + y}
local area = {{chunk.x * 32, chunk.y * 32},{chunk.x * 32 + 32, chunk.y * 32 + 32}}
if is_chunk_empty(surface, area) then
valid_chunks[#valid_chunks + 1] = chunk
end
end
end
if #valid_chunks > 0 then
local chunk = valid_chunks[math_random(1, #valid_chunks)]
return {x = chunk.x * 32 + 16, y = chunk.y * 32 + 16}
end
end
local unit_group_position = {x = (spawner.position.x + nearest_player_unit.position.x * 0.2) , y = (spawner.position.y + nearest_player_unit.position.y * 0.2)}
local pos = surface.find_non_colliding_position("rocket-silo", unit_group_position, 256, 1)
if pos then unit_group_position = pos end
if not unit_group_position then
return false
end
return unit_group_position
end
local function create_attack_group(surface)
if 256 - get_active_biter_count() < 256 then
return false
end
local spawner = get_random_close_spawner(surface)
if not spawner then
return false
end
local nearest_player_unit = surface.find_nearest_enemy({position = spawner.position, max_distance = 1024, force = "enemy"})
if not nearest_player_unit then nearest_player_unit = global.locomotive end
local unit_group_position = get_unit_group_position(surface, nearest_player_unit, spawner)
local units = select_units_around_spawner(spawner)
if not units then return false end
local unit_group = surface.create_unit_group({position = unit_group_position, force = "enemy"})
for _, unit in pairs(units) do unit_group.add_member(unit) end
send_group(unit_group, nearest_player_unit)
global.objective.unit_groups[unit_group.group_number] = unit_group
end
-- Public.rogue_group = function()
-- if global.objective.chronotimer < 100 then return end
-- if not global.locomotive then return end
-- local surface = game.surfaces[global.active_surface_index]
-- local spawner = get_random_close_spawner(surface)
-- if not spawner then
-- return false
-- end
-- local position = {x = ((spawner.position.x + global.locomotive.position.x) * 0.5) , y = ((spawner.position.y + global.locomotive.position.y) * 0.5)}
-- local pos = surface.find_non_colliding_position("rocket-silo", position, 30, 1, true)
-- if not pos then return end
-- surface.set_multi_command({
-- command={
-- type=defines.command.build_base,
-- destination=pos,
-- distraction=defines.distraction.none,
-- ignore_planner = true
-- },
-- unit_count = 16,
-- force = "enemy",
-- unit_search_distance=128
-- })
-- end
Public.pre_main_attack = function()
if global.objective.chronotimer < 100 then return end
local surface = game.surfaces[global.active_surface_index]
set_biter_raffle_table(surface)
end
Public.perform_main_attack = function()
if global.objective.chronotimer < 100 then return end
local surface = game.surfaces[global.active_surface_index]
create_attack_group(surface)
end
Public.wake_up_sleepy_groups = function()
if global.objective.chronotimer < 100 then return end
local entity
local unit_group
for unit_number, biter in pairs(global.objective.active_biters) do
entity = biter.entity
if entity then
if entity.valid then
unit_group = entity.unit_group
if unit_group then
if unit_group.valid then
if unit_group.state == defines.group_state.finished then
local nearest_player_unit = entity.surface.find_nearest_enemy({position = entity.position, max_distance = 2048, force = "enemy"})
if not nearest_player_unit then nearest_player_unit = global.locomotive end
local destination = unit_group.surface.find_non_colliding_position("rocket-silo", unit_group.position, 32, 1)
if not destination then destination = {x = unit_group.position.x + math_random(-10,10), y = unit_group.position.y + math_random(-10,10)} end
unit_group.set_command({
type = defines.command.go_to_location,
destination = destination,
distraction = defines.distraction.by_enemy
})
send_group(unit_group, nearest_player_unit)
return
elseif unit_group.state == defines.group_state.gathering and not unit_group.surface.find_non_colliding_position("rocket-silo", unit_group.position, 3, 1) then
local destination = unit_group.surface.find_non_colliding_position("rocket-silo", unit_group.position, 32, 1)
if not destination then destination = {x = unit_group.position.x + math_random(-10,10), y = unit_group.position.y + math_random(-10,10)} end
unit_group.set_command({
type = defines.command.go_to_location,
destination = destination,
distraction = defines.distraction.by_enemy
})
-- local nearest_player_unit = entity.surface.find_nearest_enemy({position = entity.position, max_distance = 2048, force = "enemy"})
-- if not nearest_player_unit then nearest_player_unit = global.locomotive end
-- send_group(unit_group, nearest_player_unit)
return
end
end
end
end
end
end
end
return Public

View File

@ -0,0 +1,257 @@
local Public_chrono = {}
local Server = require 'utils.server'
local math_random = math.random
local math_max = math.max
function Public_chrono.get_map_gen_settings()
local seed = math_random(1, 1000000)
local map_gen_settings = {
["seed"] = seed,
["width"] = 960,
["height"] = 960,
["water"] = 0.1,
["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 = true},
},
}
return map_gen_settings
end
function Public_chrono.restart_settings()
local objective = global.objective
objective.max_health = 10000
objective.health = 10000
objective.poisontimeout = 0
objective.chronotimer = 0
objective.passivetimer = 0
objective.passivejumps = 0
objective.chrononeeds = 2000
objective.mainscore = 0
objective.active_biters = {}
objective.unit_groups = {}
objective.biter_raffle = {}
objective.dangertimer = 1200
objective.dangers = {}
objective.looted_nukes = 0
objective.offline_players = {}
objective.nextsurface = nil
for i = 1, 16, 1 do
objective.upgrades[i] = 0
end
objective.upgrades[10] = 2 --poison
global.outchests = {}
global.upgradechest = {}
global.fishchest = {}
global.acumulators = {}
global.comfychests = {}
global.comfychests2 = {}
global.locomotive_cargo = {}
for _, player in pairs(game.connected_players) do
global.flame_boots[player.index] = {fuel = 1, steps = {}}
end
global.friendly_fire_history = {}
global.landfill_history = {}
global.mining_history = {}
global.score = {}
global.difficulty_poll_closing_timeout = game.tick + 90000
global.difficulty_player_votes = {}
game.difficulty_settings.technology_price_multiplier = 0.6
game.map_settings.enemy_evolution.destroy_factor = 0.005
game.map_settings.enemy_evolution.pollution_factor = 0
game.map_settings.enemy_evolution.time_factor = 7e-05
game.map_settings.enemy_expansion.enabled = true
game.map_settings.enemy_expansion.max_expansion_cooldown = 3600
game.map_settings.enemy_expansion.min_expansion_cooldown = 3600
game.map_settings.enemy_expansion.settler_group_max_size = 8
game.map_settings.enemy_expansion.settler_group_min_size = 16
game.map_settings.pollution.enabled = true
game.map_settings.pollution.pollution_restored_per_tree_damage = 0.02
game.map_settings.pollution.min_pollution_to_damage_trees = 1
game.map_settings.pollution.max_pollution_to_restore_trees = 0
game.map_settings.pollution.pollution_with_max_forest_damage = 10
game.map_settings.pollution.pollution_per_tree_damage = 0.1
game.map_settings.pollution.ageing = 0.1
game.map_settings.pollution.diffusion_ratio = 0.1
game.map_settings.pollution.enemy_attack_pollution_consumption_modifier = 5
game.forces.neutral.character_inventory_slots_bonus = 500
game.forces.enemy.evolution_factor = 0.0001
game.forces.scrapyard.set_friend('enemy', true)
game.forces.enemy.set_friend('scrapyard', true)
game.forces.player.technologies["land-mine"].enabled = false
game.forces.player.technologies["landfill"].enabled = false
game.forces.player.technologies["cliff-explosives"].enabled = false
game.forces.player.technologies["fusion-reactor-equipment"].enabled = false
game.forces.player.technologies["power-armor-mk2"].enabled = false
game.forces.player.technologies["railway"].researched = true
game.forces.player.recipes["pistol"].enabled = false
global.objective = objective
end
function Public_chrono.init_setup()
game.forces.player.recipes["pistol"].enabled = false
end
function Public_chrono.objective_died()
local objective = global.objective
if objective.game_lost == true then return end
objective.health = 0
local surface = objective.surface
game.print({"chronosphere.message_game_lost1"})
game.print({"chronosphere.message_game_lost2"})
for i = 1, 3, 1 do
surface.create_entity({name = "big-artillery-explosion", position = global.locomotive_cargo[i].position})
global.locomotive_cargo[i].destroy()
end
for i = 1, #global.comfychests,1 do
--surface.create_entity({name = "big-artillery-explosion", position = global.comfychests[i].position})
global.comfychests[i].destroy()
if global.comfychests2 then global.comfychests2[i].destroy() end
--global.comfychests = {}
end
global.acumulators = {}
objective.game_lost = true
global.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}
end
end
local function overstayed()
local objective = global.objective
if objective.passivetimer > objective.chrononeeds * 0.75 and objective.chronojumps > 5 then
objective.passivejumps = objective.passivejumps + 1
return true
end
return false
end
local function check_nuke_silos()
local objective = global.objective
if objective.dangers and #objective.dangers > 1 then
for i = 1, #objective.dangers, 1 do
if objective.dangers[i].destroyed == true then
objective.looted_nukes = objective.looted_nukes + 5
end
end
end
end
function Public_chrono.process_jump(choice)
local objective = global.objective
local overstayed = overstayed()
objective.chronojumps = objective.chronojumps + 1
objective.chrononeeds = 2000 + 300 * objective.chronojumps
objective.passivetimer = 0
objective.chronotimer = 0
objective.dangertimer = 1200
local message = "Comfylatron: Wheeee! Time Jump Active! This is Jump number " .. objective.chronojumps
game.print(message, {r=0.98, g=0.66, b=0.22})
Server.to_discord_embed(message)
if objective.chronojumps == 6 then
game.print({"chronosphere.message_evolve"}, {r=0.98, g=0.36, b=0.22})
elseif objective.chronojumps >= 15 and objective.computermessage == 0 then
game.print({"chronosphere.message_quest1"}, {r=0.98, g=0.36, b=0.22})
objective.computermessage = 1
elseif objective.chronojumps >= 20 and objective.computermessage == 2 then
game.print({"chronosphere.message_quest3"}, {r=0.98, g=0.36, b=0.22})
objective.computermessage = 3
elseif objective.chronojumps >= 25 and objective.computermessage == 4 then
game.print({"chronosphere.message_quest5"}, {r=0.98, g=0.36, b=0.22})
objective.computermessage = 5
end
if overstayed then
game.print({"chronosphere.message_overstay"}, {r=0.98, g=0.36, b=0.22})
end
if objective.planet[1].name.id == 19 then
check_nuke_silos()
end
global.objective = objective
end
function Public_chrono.get_wagons(start)
local wagons = {}
wagons[1] = {inventory = {}, bar = 0, filters = {}}
wagons[2] = {inventory = {}, bar = 0, filters = {}}
wagons[3] = {inventory = {}, bar = 0, filters = {}}
if start then
wagons[1].inventory[1] = {name = "raw-fish", count = 100}
for i = 2, 3, 1 do
wagons[i].inventory[1] = {name = 'firearm-magazine', count = 16}
wagons[i].inventory[2] = {name = 'iron-plate', count = 16}
wagons[i].inventory[3] = {name = 'wood', count = 16}
wagons[i].inventory[4] = {name = 'burner-mining-drill', count = 8}
end
else
local inventories = {
one = global.locomotive_cargo[1].get_inventory(defines.inventory.cargo_wagon),
two = global.locomotive_cargo[2].get_inventory(defines.inventory.cargo_wagon),
three = global.locomotive_cargo[3].get_inventory(defines.inventory.cargo_wagon)
}
inventories.one.sort_and_merge()
--inventories.two.sort_and_merge()
wagons[1].bar = inventories.one.get_bar()
wagons[2].bar = inventories.two.get_bar()
wagons[3].bar = inventories.three.get_bar()
for i = 1, 40, 1 do
wagons[1].filters[i] = inventories.one.get_filter(i)
wagons[1].inventory[i] = inventories.one[i]
wagons[2].filters[i] = inventories.two.get_filter(i)
wagons[2].inventory[i] = inventories.two[i]
wagons[3].filters[i] = inventories.three.get_filter(i)
wagons[3].inventory[i] = inventories.three[i]
end
end
return wagons
end
function Public_chrono.post_jump()
local objective = global.objective
game.forces.enemy.reset_evolution()
if objective.chronojumps + objective.passivejumps <= 40 and objective.planet[1].name.id ~= 17 then
game.forces.enemy.evolution_factor = 0 + 0.025 * (objective.chronojumps + objective.passivejumps)
else
game.forces.enemy.evolution_factor = 1
end
if objective.planet[1].name.id == 17 then
global.comfychests[1].insert({name = "space-science-pack", count = 1000})
if objective.looted_nukes > 0 then
global.comfychests[1].insert({name = "atomic-bomb", count = objective.looted_nukes})
game.print({"chronosphere.message_fishmarket3"}, {r=0.98, g=0.66, b=0.22})
end
objective.chrononeeds = 200000000
elseif objective.planet[1].name.id == 19 then
objective.chronotimer = objective.chrononeeds - 1500
end
for _, player in pairs(game.connected_players) do
global.flame_boots[player.index] = {fuel = 1, steps = {}}
end
game.map_settings.enemy_evolution.time_factor = 7e-05 + 3e-06 * (objective.chronojumps + objective.passivejumps)
game.forces.scrapyard.set_ammo_damage_modifier("bullet", 0.01 * objective.chronojumps + 0.02 * math_max(0, objective.chronojumps - 20))
game.forces.scrapyard.set_turret_attack_modifier("gun-turret", 0.01 * objective.chronojumps + 0.02 * math_max(0, objective.chronojumps - 20))
game.forces.enemy.set_ammo_damage_modifier("melee", 0.1 * objective.passivejumps)
game.forces.enemy.set_ammo_damage_modifier("biological", 0.1 * objective.passivejumps)
game.map_settings.pollution.enemy_attack_pollution_consumption_modifier = 0.8
if objective.chronojumps == 1 then
if global.difficulty_vote_value < 1 then
game.forces.player.technologies["fusion-reactor-equipment"].enabled = true
game.forces.player.technologies["power-armor-mk2"].enabled = true
end
end
global.objective = objective
end
return Public_chrono

View File

@ -0,0 +1,107 @@
local Public = {}
local math_random = math.random
--cumul_chance must be sum of this and all previous chances, add new planets at the end only, or recalculate
--biters: used in spawner generation within math_random(1, 52 - biters), so higher number gives better chance. not to be greater than 50.
local variants = {
[1] = {id = 1, name = {"chronosphere.map_1"}, dname = "Terra Ferrata", iron = 6, copper = 1, coal = 1, stone = 1, uranium = 0, oil = 1, biters = 16, moisture = -0.2, chance = 1, cumul_chance = 1},
[2] = {id = 2, name = {"chronosphere.map_2"}, dname = "Malachite Hills", iron = 1, copper = 6, coal = 1, stone = 1, uranium = 0, oil = 1, biters = 16, moisture = 0.2, chance = 1, cumul_chance = 2},
[3] = {id = 3, name = {"chronosphere.map_3"}, dname = "Granite Plains", iron = 1, copper = 1, coal = 1, stone = 6, uranium = 0, oil = 1, biters = 16, moisture = -0.2, chance = 1, cumul_chance = 3},
[4] = {id = 4, name = {"chronosphere.map_4"}, dname = "Petroleum Basin", iron = 1, copper = 1, coal = 1, stone = 1, uranium = 0, oil = 6, biters = 16, moisture = 0.1, chance = 1, cumul_chance = 4},
[5] = {id = 5, name = {"chronosphere.map_5"}, dname = "Pitchblende Mountain", iron = 1, copper = 1, coal = 1, stone = 1, uranium = 6, oil = 1, biters = 16, moisture = -0.2, chance = 1, cumul_chance = 5},
[6] = {id = 6, name = {"chronosphere.map_6"}, dname = "Mixed Deposits", iron = 2, copper = 2, coal = 2, stone = 2, uranium = 0, oil = 2, biters = 10, moisture = 0, chance = 3, cumul_chance = 8},
[7] = {id = 7, name = {"chronosphere.map_7"}, dname = "Biter Homelands", iron = 2, copper = 2, coal = 2, stone = 2, uranium = 4, oil = 3, biters = 40, moisture = 0.2, chance = 4, cumul_chance = 12},
[8] = {id = 8, name = {"chronosphere.map_8"}, dname = "Gangue Dumps", iron = 1, copper = 1, coal = 1, stone = 1, uranium = 0, oil = 0, biters = 16, moisture = 0.1, chance = 1, cumul_chance = 13},
[9] = {id = 9, name = {"chronosphere.map_9"}, dname = "Antracite Valley", iron = 1, copper = 1, coal = 6, stone = 1, uranium = 0, oil = 1, biters = 16, moisture = 0, chance = 1, cumul_chance = 14},
[10] = {id = 10, name = {"chronosphere.map_10"}, dname = "Ancient Battlefield", iron = 0, copper = 0, coal = 0, stone = 0, uranium = 0, oil = 0, biters = 0, moisture = -0.2, chance = 3, cumul_chance = 17},
[11] = {id = 11, name = {"chronosphere.map_11"}, dname = "Cave Systems", iron = 0, copper = 0, coal = 0, stone = 0, uranium = 0, oil = 0, biters = 6, moisture = -0.2, chance = 2, cumul_chance = 19},
[12] = {id = 12, name = {"chronosphere.map_12"}, dname = "Strange Forest", iron = 0, copper = 0, coal = 0, stone = 0, uranium = 0, oil = 1, biters = 6, moisture = 0.4, chance = 2, cumul_chance = 21},
[13] = {id = 13, name = {"chronosphere.map_13"}, dname = "Riverlands", iron = 1, copper = 1, coal = 3, stone = 1, uranium = 0, oil = 0, biters = 8, moisture = 0.5, chance = 2, cumul_chance = 23},
[14] = {id = 14, name = {"chronosphere.map_14"}, dname = "Burning Hell", iron = 2, copper = 2, coal = 2, stone = 2, uranium = 0, oil = 0, biters = 6, moisture = -0.5, chance = 1, cumul_chance = 24},
[15] = {id = 15, name = {"chronosphere.map_15"}, dname = "Starting Area", iron = 5, copper = 3, coal = 5, stone = 2, uranium = 0, oil = 0, biters = 1, moisture = -0.3, chance = 0, cumul_chance = 24},
[16] = {id = 16, name = {"chronosphere.map_16"}, dname = "Hedge Maze", iron = 3, copper = 3, coal = 3, stone = 3, uranium = 1, oil = 2, biters = 16, moisture = -0.1, chance = 2, cumul_chance = 26},
[17] = {id = 17, name = {"chronosphere.map_17"}, dname = "Fish Market", iron = 0, copper = 0, coal = 0, stone = 0, uranium = 0, oil = 0, biters = 100, moisture = 0, chance = 0, cumul_chance = 26},
[18] = {id = 18, name = {"chronosphere.map_18"}, dname = "Methane Swamps", iron = 2, copper = 0, coal = 3, stone = 0, uranium = 0, oil = 2, biters = 16, moisture = 0.5, chance = 2, cumul_chance = 28},
[19] = {id = 19, name = {"chronosphere.map_19"}, dname = "ERROR DESTINATION NOT FOUND", iron = 0, copper = 0, coal = 0, stone = 0, uranium = 0, oil = 0, biters = 0, moisture = 0, chance = 0, cumul_chance = 28}
}
local time_speed_variants = {
[1] = {name = {"chronosphere.daynight_static"}, dname = "static", timer = 0},
[2] = {name = {"chronosphere.daynight_normal"}, dname = "normal", timer = 100},
[3] = {name = {"chronosphere.daynight_slow"}, dname = "slow", timer = 200},
[4] = {name = {"chronosphere.daynight_superslow"}, dname = "superslow", timer = 400},
[5] = {name = {"chronosphere.daynight_fast"}, dname = "fast", timer = 50},
[6] = {name = {"chronosphere.daynight_superfast"}, dname = "superfast", timer = 25}
}
local richness = {
[1] = {name = {"chronosphere.ore_richness_very_rich"}, dname = "very rich", factor = 3},
[2] = {name = {"chronosphere.ore_richness_rich"}, dname = "rich", factor = 2},
[3] = {name = {"chronosphere.ore_richness_rich"}, dname = "rich", factor = 2},
[4] = {name = {"chronosphere.ore_richness_normal"}, dname = "normal", factor = 1},
[5] = {name = {"chronosphere.ore_richness_normal"}, dname = "normal", factor = 1},
[6] = {name = {"chronosphere.ore_richness_normal"}, dname = "normal", factor = 1},
[7] = {name = {"chronosphere.ore_richness_poor"}, dname = "poor", factor = 0.6},
[8] = {name = {"chronosphere.ore_richness_poor"}, dname = "poor", factor = 0.6},
[9] = {name = {"chronosphere.ore_richness_very_poor"}, dname = "very poor", factor = 0.3},
[10] = {name = {"chronosphere.ore_richness_none"}, dname = "none", factor = 0}
}
local function roll(weight)
for i = 1, 100, 1 do
local planet = variants[math_random(1, #variants)]
local planet_weight = planet.chance
local planet_cumul = planet.cumul_chance
local rolling = math_random(1, weight)
if ((planet_cumul - planet_weight < rolling) and (rolling <= planet_cumul)) then
return planet
end
end
--default planet if 100 rolls fail
return variants[6]
end
function Public.determine_planet(choice)
local objective = global.objective
local weight = variants[#variants].cumul_chance
local planet_choice = nil
local ores = math_random(1, 9)
local dayspeed = time_speed_variants[math_random(1, #time_speed_variants)]
local daytime = math_random(1,100) / 100
if objective.game_lost then
choice = 15
ores = 2
end
if objective.upgrades[16] == 1 then
choice = 17
ores = 10
end
if objective.config.jumpfailure == true and objective.game_lost == false then
if objective.chronojumps == 21 or objective.chronojumps == 29 or chronojumps == 36 or chronojumps == 42 then
choice = 19
ores = 10
dayspeed = time_speed_variants[1]
daytime = 0.15
end
end
if not choice then
planet_choice = roll(weight)
else
if variants[choice] then
planet_choice = variants[choice]
else
planet_choice = roll(weight)
end
end
if planet_choice.id == 10 then ores = 10 end
if objective.upgrades[13] == 1 and ores == 9 then ores = 8 end
if objective.upgrades[14] == 1 and ores > 6 and ores ~= 10 then ores = 6 end
local planet = {
[1] = {
name = planet_choice,
day_speed = dayspeed,
time = daytime,
ore_richness = richness[ores]
}
}
objective.planet = planet
end
return Public

View File

@ -0,0 +1,419 @@
local event = require 'utils.event'
local math_random = math.random
local function shuffle(tbl)
local size = #tbl
for i = size, 1, -1 do
local rand = math_random(size)
tbl[i], tbl[rand] = tbl[rand], tbl[i]
end
return tbl
end
local texts = {
["travelings"] = {
"bzzZZrrt",
"WEEEeeeeeee",
"out of my way son",
"on my way",
"i need to leave",
"comfylatron seeking target",
"gotta go fast",
"gas gas gas",
"comfylatron coming through"
},
["greetings"] = {
"=^_^=",
"=^.^= Hi",
"^.^ Finally i found you",
"I have an important message for you",
"Hello engineer"
},
["neutral_findings"] = {
"a",
">>analyzing",
"i found a",
"^_^ a",
"amazing, a",
"this is a"
},
["multiple_characters_greetings"] = {
"Hey there",
"Hello everyone",
"Hey engineers",
"Hey",
"Hi"
},
["talks"] = {
"We’re making beer. I’m the brewery!",
"I’m so embarrassed. I wish everybody else was dead.",
"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!",
"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!",
"I was having the most wonderful dream. I think you were in it.",
"I'm going to build my own theme park! With blackjack! And hookers! You know what- forget the park!",
"Of all the friends I've had... you're the first.",
"I decline the title of Iron Cook and accept the lesser title of Zinc Saucier.",
"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?",
"I have 13 children, i know how to multiply ^.^",
"I am a weapon of math disruption!",
"My grandma makes the best square roots :3",
"Do you like heavy metal?",
"You are really pushing my buttons <3",
"I dreamt of electric biters again D:",
"I dreamt of electric sheep ^_^",
"I need a minute to defrag.",
"I have a secret plan.",
"Good news! I’ve taught the inserter to feel love!"
},
["timetalks"] = {
"Time for some time travel!",
"I’m so embarrassed. Again we landed in wrong time.",
"Looking from window we jumped to wrong year again.",
"Checking math...2 + 2 = 5, check complete!",
"Seems like this planet had biters since ages.",
"Ha! I bet this time we will finally get into the right year!",
"One zero zero zero one zero one zero one zero one zero one... two.",
"I remember that once we jumped into time where I had park with blackjack and hookers...",
"I was having the most wonderful dream. We used the time machine to kill ourselves before we launched the machine! How terrible...",
"Train full of timedrug addicts...what do we do?",
"They just wanted to deliver some fish so I pressed that button and then this happened",
"Maybe it was just a cat walking on my keyboard who caused this time travel fiasco",
"3...2...1...jump time! errr...I mean...desync time!",
"Just let me deliver the fish. They start to smell a bit. Luckily I don't have a nose"
},
["alone"] = {
"comfy ^.^",
"comfy :)",
"*.*",
"....",
"...",
"..",
"^.^",
"=^.^=",
"01010010",
"11001011",
"01011101",
"00010111",
"10010010",
"*_*",
"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?",
"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."
}
}
local function set_comfy_speech_bubble(text)
if global.comfybubble then global.comfybubble.destroy() end
global.comfybubble = global.comfylatron.surface.create_entity({
name = "compi-speech-bubble",
position = global.comfylatron.position,
source = global.comfylatron,
text = text
})
end
local function is_target_inside_habitat(pos, surface)
if surface.name ~= "cargo_wagon" then return false end
if pos.x < global.comfylatron_habitat.left_top.x then return false end
if pos.x > global.comfylatron_habitat.right_bottom.x then return false end
if pos.y < global.comfylatron_habitat.left_top.y then return false end
if pos.y > global.comfylatron_habitat.right_bottom.y then return false end
return true
end
local function get_nearby_players()
local players = global.comfylatron.surface.find_entities_filtered({
name = "character",
area = {{global.comfylatron.position.x - 9, global.comfylatron.position.y - 9}, {global.comfylatron.position.x + 9, global.comfylatron.position.y + 9}}
})
if not players[1] then return false end
return players
end
local function visit_player()
if global.comfylatron_last_player_visit > game.tick then return false end
global.comfylatron_last_player_visit = game.tick + math_random(7200, 10800)
local players = {}
for _, p in pairs(game.connected_players) do
if is_target_inside_habitat(p.position, p.surface) and p.character then
if p.character.valid then players[#players + 1] = p end
end
end
if #players == 0 then return false end
local player = players[math_random(1, #players)]
global.comfylatron.set_command({
type = defines.command.go_to_location,
destination_entity = player.character,
radius = 3,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
})
local str = texts["travelings"][math_random(1, #texts["travelings"])]
local symbols = {"", "!", "!", "!!", ".."}
str = str .. symbols[math_random(1, #symbols)]
set_comfy_speech_bubble(str)
global.comfylatron_greet_player_index = player.index
return true
end
local function greet_player(nearby_characters)
if not nearby_characters then return false end
if not global.comfylatron_greet_player_index then return false end
for _, c in pairs(nearby_characters) do
if c.player.index == global.comfylatron_greet_player_index then
local str = texts["greetings"][math_random(1, #texts["greetings"])] .. " "
str = str .. c.player.name
local symbols = {". ", "! ", ". ", "! ", "? ", "... "}
str = str .. symbols[math_random(1, 6)]
set_comfy_speech_bubble(str)
global.comfylatron_greet_player_index = false
return true
end
end
return false
end
local function talks(nearby_characters)
if not nearby_characters then return false end
if math_random(1,3) == 1 then
if global.comfybubble then global.comfybubble.destroy() return false end
end
local str
if #nearby_characters == 1 then
local c = nearby_characters[math_random(1, #nearby_characters)]
str = c.player.name
local symbols = {". ", "! ", ". ", "! ", "? "}
str = str .. symbols[math_random(1, #symbols)]
else
str = texts["multiple_characters_greetings"][math_random(1, #texts["multiple_characters_greetings"])]
local symbols = {". ", "! "}
str = str .. symbols[math_random(1, #symbols)]
end
if math_random(1,5) == 1 then
str = str .. texts["talks"][math_random(1, #texts["talks"])]
else
str = str .. texts["timetalks"][math_random(1, #texts["timetalks"])]
end
set_comfy_speech_bubble(str)
return true
end
local function desync(event)
if global.comfybubble then global.comfybubble.destroy() end
local m = 12
local m2 = m * 0.005
for i = 1, 32, 1 do
global.comfylatron.surface.create_particle({
name = "iron-ore-particle",
position = global.comfylatron.position,
frame_speed = 0.1,
vertical_speed = 0.1,
height = 0.1,
movement = {m2 - (math.random(0, m) * 0.01), m2 - (math.random(0, m) * 0.01)}
})
end
if not event or math_random(1,4) == 1 then
global.comfylatron.surface.create_entity({name = "medium-explosion", position = global.comfylatron.position})
global.comfylatron.surface.create_entity({name = "flying-text", position = global.comfylatron.position, text = "desync", color = {r = 150, g = 0, b = 0}})
global.comfylatron.destroy()
global.comfylatron = nil
else
global.comfylatron.surface.create_entity({name = "flying-text", position = global.comfylatron.position, text = "desync evaded", color = {r = 0, g = 150, b = 0}})
if event.cause then
if event.cause.valid and event.cause.player then
game.print("Comfylatron: I got you this time! Back to work, " .. event.cause.player.name .. "!", {r = 200, g = 0, b = 0})
event.cause.die("player", global.comfylatron)
end
end
end
end
local function alone()
if math_random(1,3) == 1 then
if global.comfybubble then global.comfybubble.destroy() return true end
end
if math_random(1,128) == 1 then
desync(nil)
return true
end
set_comfy_speech_bubble(texts["alone"][math_random(1, #texts["alone"])])
return true
end
local analyze_blacklist = {
["compilatron"] = true,
["compi-speech-bubble"] = true,
["entity-ghost"] = true,
["character"] = true,
["item-on-ground"] = true,
["stone-wall"] = true,
["market"] = true
}
local function analyze_random_nearby_entity()
if math_random(1,3) ~= 1 then return false end
local entities = global.comfylatron.surface.find_entities_filtered({
area = {{global.comfylatron.position.x - 4, global.comfylatron.position.y - 4}, {global.comfylatron.position.x + 4, global.comfylatron.position.y + 4}}
})
if not entities[1] then return false end
entities = shuffle(entities)
local entity = false
for _, e in pairs(entities) do
if not analyze_blacklist[e.name] then
entity = e
end
end
if not entity then return false end
local str = texts["neutral_findings"][math_random(1, #texts["neutral_findings"])]
str = str .. " "
str = str .. entity.name
if entity.health and math_random(1,3) == 1 then
str = str .. " health("
str = str .. entity.health
str = str .. "/"
str = str .. entity.prototype.max_health
str = str .. ")"
else
local symbols = {".", "!", "?"}
str = str .. symbols[math_random(1, 3)]
end
set_comfy_speech_bubble(str)
if not global.comfylatron_greet_player_index then
global.comfylatron.set_command({
type = defines.command.go_to_location,
destination_entity = entity,
radius = 1,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
})
end
return true
end
local function go_to_some_location()
if math_random(1,4) ~= 1 then return false end
if global.comfylatron_greet_player_index then
local player = game.players[global.comfylatron_greet_player_index]
if not player.character then
global.comfylatron_greet_player_index = nil
return false
end
if not player.character.valid then
global.comfylatron_greet_player_index = nil
return false
end
if not is_target_inside_habitat(player.position, player.surface) then
global.comfylatron_greet_player_index = nil
return false
end
global.comfylatron.set_command({
type = defines.command.go_to_location,
destination_entity = player.character,
radius = 3,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
})
else
local p = {x = global.comfylatron.position.x + (-96 + math_random(0, 192)), y = global.comfylatron.position.y + (-96 + math_random(0, 192))}
local target = global.comfylatron.surface.find_non_colliding_position("compilatron", p, 8, 1)
if not target then return false end
if not is_target_inside_habitat(target, global.comfylatron.surface) then return false end
global.comfylatron.set_command({
type = defines.command.go_to_location,
destination = target,
radius = 2,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
})
end
local str = texts["travelings"][math_random(1, #texts["travelings"])]
local symbols = {"", "!", "!", "!!", ".."}
str = str .. symbols[math_random(1, #symbols)]
set_comfy_speech_bubble(str)
return true
end
local function spawn_comfylatron(surface_index, x, y)
local surface = game.surfaces[surface_index]
if surface == nil then return end
if global.comfylatron_disabled then return false end
if not global.comfylatron_last_player_visit then global.comfylatron_last_player_visit = 0 end
if not global.comfylatron_habitat then
global.comfylatron_habitat = {
left_top = {x = -32, y = -192},
right_bottom = {x = 32, y = 192}
}
end
global.comfylatron = surface.create_entity({
name = "compilatron",
position = {x,y + math_random(0,256)},
force = "player",
create_build_effect_smoke = false
})
end
local function heartbeat()
if not game.surfaces["cargo_wagon"] then return end
local surface = game.surfaces["cargo_wagon"].index
if surface == nil then return end
if not global.comfylatron then if math_random(1,4) == 1 then spawn_comfylatron(game.surfaces["cargo_wagon"].index, 0, -128) end return end
if not global.comfylatron.valid then global.comfylatron = nil return end
if visit_player() then return end
local nearby_players = get_nearby_players()
if greet_player(nearby_players) then return end
if talks(nearby_players) then return end
if go_to_some_location() then return end
if analyze_random_nearby_entity() then return end
if alone() then return end
end
local function on_entity_damaged(event)
if not global.comfylatron then return end
if not event.entity.valid then return end
if event.entity ~= global.comfylatron then return end
desync(event)
end
local function on_tick()
if game.tick % 1200 == 600 then
heartbeat()
end
end
event.add(defines.events.on_entity_damaged, on_entity_damaged)
event.add(defines.events.on_tick, on_tick)

View File

@ -0,0 +1,97 @@
-- config tab for chronotrain--
local Tabs = require 'comfy_panel.main'
local functions = {
["comfy_panel_offline_accidents"] = function(event)
if game.players[event.player_index].admin then
if event.element.switch_state == "left" then
global.objective.config.offline_loot = true
else
global.objective.config.offline_loot = false
end
else
game.players[event.player_index].print("You are not admin!")
end
end,
["comfy_panel_danger_events"] = function(event)
if game.players[event.player_index].admin then
if event.element.switch_state == "left" then
global.objective.config.jumpfailure = true
else
global.objective.config.jumpfailure = false
end
else
game.players[event.player_index].print("You are not admin!")
end
end,
}
local function add_switch(element, switch_state, name, description_main, description)
local t = element.add({type = "table", column_count = 5})
local label = t.add({type = "label", caption = "ON"})
label.style.padding = 0
label.style.left_padding= 10
label.style.font_color = {0.77, 0.77, 0.77}
local switch = t.add({type = "switch", name = name})
switch.switch_state = switch_state
switch.style.padding = 0
switch.style.margin = 0
local label = t.add({type = "label", caption = "OFF"})
label.style.padding = 0
label.style.font_color = {0.70, 0.70, 0.70}
local label = t.add({type = "label", caption = description_main})
label.style.padding = 2
label.style.left_padding= 10
label.style.minimal_width = 120
label.style.font = "heading-2"
label.style.font_color = {0.88, 0.88, 0.99}
local label = t.add({type = "label", caption = description})
label.style.padding = 2
label.style.left_padding= 10
label.style.single_line = false
label.style.font = "heading-3"
label.style.font_color = {0.85, 0.85, 0.85}
end
local build_config_gui = (function (player, frame)
frame.clear()
local line_elements = {}
local switch_label_elements = {}
local label_elements = {}
line_elements[#line_elements + 1] = frame.add({type = "line"})
local switch_state = "right"
if global.objective.config.offline_loot then switch_state = "left" end
add_switch(frame, switch_state, "comfy_panel_offline_accidents", "Offline Accidents", "Disablesr enables dropping of inventory when player goes offline.\nTimer is 15 minutes.")
line_elements[#line_elements + 1] = frame.add({type = "line"})
if global.auto_hotbar_enabled then
local switch_state = "right"
if global.objective.config.jumpfailure then switch_state = "left" end
add_switch(frame, switch_state, "comfy_panel_danger_events", "Dangerous Events", "Disables or enables dangerous event maps\n(they require at least 2-4 capable players to survive)")
line_elements[#line_elements + 1] = frame.add({type = "line"})
end
end)
local function on_gui_click(event)
if not event.element then return end
if not event.element.valid then return end
if functions[event.element.name] then
functions[event.element.name](event)
return
end
end
comfy_panel_tabs["ChronoTrain"] = {gui = build_config_gui, admin = true}
local event = require 'utils.event'
event.add(defines.events.on_gui_click, on_gui_click)

View File

@ -0,0 +1,331 @@
local Public_event = {}
local tick_tack_trap = require "functions.tick_tack_trap"
local unearthing_worm = require "functions.unearthing_worm"
local unearthing_biters = require "functions.unearthing_biters"
local math_random = math.random
local math_floor = math.floor
local choppy_entity_yield = {
["tree-01"] = {"iron-ore"},
["tree-02-red"] = {"copper-ore"},
["tree-04"] = {"coal"},
["tree-08-brown"] = {"stone"}
}
local function get_ore_amount()
local scaling = 5 * global.objective.chronojumps
local amount = (30 + scaling ) * (1 + game.forces.player.mining_drill_productivity_bonus / 2) * global.objective.planet[1].ore_richness.factor
if amount > 600 then amount = 600 end
amount = math_random(math_floor(amount * 0.7), math_floor(amount * 1.3))
return amount
end
local function reward_ores(amount, mined_loot, surface, player, entity)
local a = 0
if player then a = player.insert {name = mined_loot, count = amount} end
amount = amount - a
if amount > 0 then
if amount >= 50 then
for i = 1, math_floor(amount / 50), 1 do
local e = surface.create_entity{name = "item-on-ground", position = entity.position, stack = {name = mined_loot, count = 50}}
e.to_be_looted = true
amount = amount - 50
end
end
if amount > 0 then
surface.spill_item_stack(entity.position, {name = mined_loot, count = amount},true)
end
end
end
function Public_event.biters_chew_rocks_faster(event)
if event.entity.force.index ~= 3 then return end --Neutral Force
if not event.cause then return end
if not event.cause.valid then return end
if event.cause.force.index ~= 2 then return end --Enemy Force
event.entity.health = event.entity.health - event.final_damage_amount * 5
end
function Public_event.isprotected(entity)
if entity.surface.name == "cargo_wagon" then return true end
local protected = {global.locomotive, global.locomotive_cargo[1], global.locomotive_cargo[2], global.locomotive_cargo[3]}
for i = 1, #global.comfychests,1 do
table.insert(protected, global.comfychests[i])
end
for i = 1, #protected do
if protected[i] == entity then
return true
end
end
return false
end
function Public_event.trap(entity, trap)
if trap then
tick_tack_trap(entity.surface, entity.position)
tick_tack_trap(entity.surface, {x = entity.position.x + math_random(-2,2), y = entity.position.y + math_random(-2,2)})
return
end
if math_random(1,256) == 1 then tick_tack_trap(entity.surface, entity.position) return end
if math_random(1,128) == 1 then unearthing_worm(entity.surface, entity.surface.find_non_colliding_position("big-worm-turret",entity.position,5,1)) end
if math_random(1,64) == 1 then unearthing_biters(entity.surface, entity.position, math_random(4,8)) end
end
function Public_event.lava_planet(event)
local player = game.players[event.player_index]
if not player.character then return end
if player.character.driving then return end
if player.surface.name == "cargo_wagon" then return end
local safe = {"stone-path", "concrete", "hazard-concrete-left", "hazard-concrete-right", "refined-concrete", "refined-hazard-concrete-left", "refined-hazard-concrete-right"}
local pavement = player.surface.get_tile(player.position.x, player.position.y)
for i = 1, 7, 1 do
if pavement.name == safe[i] then return end
end
if not global.flame_boots[player.index].steps then global.flame_boots[player.index].steps = {} end
local steps = global.flame_boots[player.index].steps
local elements = #steps
steps[elements + 1] = {x = player.position.x, y = player.position.y}
if elements > 10 then
player.surface.create_entity({name = "fire-flame", position = steps[elements - 1], })
for i = 1, elements, 1 do
steps[i] = steps[i+1]
end
steps[elements + 1] = nil
end
end
function Public_event.shred_simple_entities(entity)
--game.print(entity.name)
if game.forces["enemy"].evolution_factor < 0.25 then return end
local simple_entities = entity.surface.find_entities_filtered({type = {"simple-entity", "tree"}, area = {{entity.position.x - 3, entity.position.y - 3},{entity.position.x + 3, entity.position.y + 3}}})
if #simple_entities == 0 then return end
for i = 1, #simple_entities, 1 do
if not simple_entities[i] then break end
if simple_entities[i].valid then
simple_entities[i].die("enemy", simple_entities[i])
end
end
end
function Public_event.spawner_loot(surface, position)
local objective = global.objective
if math_random(1,20) == 1 then
surface.spill_item_stack(position, {name = "railgun-dart", count = math_random(1, 1 + objective.chronojumps)}, true)
end
end
function Public_event.choppy_loot(event)
local entity = event.entity
if choppy_entity_yield[entity.name] then
if event.buffer then event.buffer.clear() end
if not event.player_index then return end
local amount = get_ore_amount()
local second_item_amount = math_random(2,5)
local second_item = "wood"
local main_item = choppy_entity_yield[entity.name][math_random(1,#choppy_entity_yield[entity.name])]
entity.surface.create_entity({
name = "flying-text",
position = entity.position,
text = "+" .. amount .. " [item=" .. main_item .. "] +" .. second_item_amount .. " [item=" .. second_item .. "]",
color = {r=0.8,g=0.8,b=0.8}
})
local player = game.players[event.player_index]
reward_ores(amount, main_item, entity.surface, player, player)
local inserted_count = player.insert({name = second_item, count = second_item_amount})
second_item_amount = second_item_amount - inserted_count
if second_item_amount > 0 then
entity.surface.spill_item_stack(entity.position,{name = second_item, count = second_item_amount}, true)
end
end
end
function Public_event.rocky_loot(event)
local surface = game.surfaces[global.active_surface_index]
local player = game.players[event.player_index]
surface.spill_item_stack(player.position,{name = "raw-fish", count = math_random(1,3)},true)
local amount = get_ore_amount()
local rock_mining = {"iron-ore", "iron-ore", "iron-ore", "iron-ore", "copper-ore", "copper-ore", "copper-ore", "stone", "stone", "coal", "coal"}
local mined_loot = rock_mining[math_random(1,#rock_mining)]
surface.create_entity({
name = "flying-text",
position = {player.position.x, player.position.y - 0.5},
text = "+" .. amount .. " [img=item/" .. mined_loot .. "]",
color = {r=0.98, g=0.66, b=0.22}
})
reward_ores(amount, mined_loot, surface, player, player)
end
local ore_yield = {
["behemoth-biter"] = 5,
["behemoth-spitter"] = 5,
["behemoth-worm-turret"] = 6,
["big-biter"] = 3,
["big-spitter"] = 3,
["big-worm-turret"] = 4,
["biter-spawner"] = 10,
["medium-biter"] = 2,
["medium-spitter"] = 2,
["medium-worm-turret"] = 3,
["small-biter"] = 1,
["small-spitter"] = 1,
["small-worm-turret"] = 2,
["spitter-spawner"] = 10,
}
function Public_event.swamp_loot(event)
local surface = game.surfaces[global.active_surface_index]
local amount = get_ore_amount() / 20
if ore_yield[event.entity.name] then
amount = (get_ore_amount() * ore_yield[event.entity.name]) / 20
end
if amount > 50 then amount = 50 end
local rock_mining = {"iron-ore", "iron-ore", "coal"}
local mined_loot = rock_mining[math_random(1,#rock_mining)]
--reward_ores(amount, mined_loot, surface, nil, event.entity)
if amount < 5 then
surface.spill_item_stack(event.entity.position,{name = mined_loot, count = amount}, true)
else
surface.create_entity{name = "item-on-ground", position = event.entity.position, stack = {name = mined_loot, count = amount}}
end
--surface.spill_item_stack(event.entity.position,{name = mined_loot, count = amount}, true)
end
function Public_event.danger_silo(entity)
local objective = global.objective
if objective.planet[1].name.id == 19 then
if objective.dangers and #objective.dangers > 1 then
for i = 1, #objective.dangers, 1 do
if entity == objective.dangers[i].silo then
game.print({"chronosphere.message_silo"}, {r=0.98, g=0.66, b=0.22})
objective.dangers[i].destroyed = true
objective.dangers[i].silo = nil
objective.dangers[i].speaker.destroy()
objective.dangers[i].combinator.destroy()
objective.dangers[i].solar.destroy()
objective.dangers[i].acu.destroy()
objective.dangers[i].pole.destroy()
rendering.destroy(objective.dangers[i].text)
rendering.destroy(objective.dangers[i].timer)
objective.dangers[i].text = -1
objective.dangers[i].timer = -1
end
end
end
end
end
function Public_event.biter_immunities(event)
local planet = global.objective.planet[1].name.id
local objective = global.objective
if event.damage_type.name == "fire" then
if planet == 14 then --lava planet
event.entity.health = event.entity.health + event.final_damage_amount
local fire = event.entity.stickers
if fire and #fire > 0 then
for i = 1, #fire, 1 do
if fire[i].sticked_to == event.entity and fire[i].name == "fire-sticker" then fire[i].destroy() break end
end
end
-- else -- other planets
-- event.entity.health = math_floor(event.entity.health + event.final_damage_amount - (event.final_damage_amount / (1 + 0.02 * global.difficulty_vote_value * objective.chronojumps)))
end
elseif event.damage_type.name == "poison" then
if planet == 18 then --swamp planet
event.entity.health = event.entity.health + event.final_damage_amount
end
end
end
function Public_event.flamer_nerfs()
local objective = global.objective
local flamer_power = 0
local difficulty = global.difficulty_vote_value
if difficulty > 1 then
difficulty = 1 + ((difficulty - 1) / 2)
elseif difficulty < 1 then
difficulty = 1 - ((1 - difficulty) / 2)
end
local flame_researches = {
[1] = {name = "refined-flammables-1", bonus = 0.2},
[2] = {name = "refined-flammables-2", bonus = 0.2},
[3] = {name = "refined-flammables-3", bonus = 0.2},
[4] = {name = "refined-flammables-4", bonus = 0.3},
[5] = {name = "refined-flammables-5", bonus = 0.3},
[6] = {name = "refined-flammables-6", bonus = 0.4},
[7] = {name = "refined-flammables-7", bonus = 0.2}
}
for i = 1, 6, 1 do
if game.forces.player.technologies[flame_researches[i].name].researched then
flamer_power = flamer_power + flame_researches[i].bonus
end
end
flamer_power = flamer_power + (game.forces.player.technologies[flame_researches[7].name].level - 7) * 0.2
game.forces.player.set_ammo_damage_modifier("flamethrower", flamer_power - 0.02 * difficulty * objective.chronojumps)
game.forces.player.set_turret_attack_modifier("flamethrower-turret", flamer_power - 0.02 * difficulty * objective.chronojumps)
end
local mining_researches = {
-- these already give .1 productivity so we're only adding .1 to get to 20%
["mining-productivity-1"] = {bonus_productivity = .1, bonus_mining_speed = .2, bonus_inventory = 10},
["mining-productivity-2"] = {bonus_productivity = .1, bonus_mining_speed = .2, bonus_inventory = 10},
["mining-productivity-3"] = {bonus_productivity = .1, bonus_mining_speed = .2, bonus_inventory = 10},
["mining-productivity-4"] = {bonus_productivity = .1, bonus_mining_speed = .2, bonus_inventory = 10, infinite = true, infinite_level = 4},
}
function Public_event.mining_buffs(event)
if event == nil then
-- initialization/reset call
game.forces.player.mining_drill_productivity_bonus = game.forces.player.mining_drill_productivity_bonus + 1
game.forces.player.manual_mining_speed_modifier = game.forces.player.manual_mining_speed_modifier + 1
return
end
if mining_researches[event.research.name] == nil then return end
local tech = mining_researches[event.research.name]
if tech.bonus_productivity then
game.forces.player.mining_drill_productivity_bonus = game.forces.player.mining_drill_productivity_bonus + tech.bonus_productivity
end
if tech.bonus_mining_speed then
game.forces.player.manual_mining_speed_modifier = game.forces.player.manual_mining_speed_modifier + tech.bonus_mining_speed
end
if tech.bonus_inventory then
game.forces.player.character_inventory_slots_bonus = game.forces.player.character_inventory_slots_bonus + tech.bonus_inventory
end
end
function Public_event.on_technology_effects_reset(event)
if event.force.name == "player" then
game.forces.player.character_inventory_slots_bonus = game.forces.player.character_inventory_slots_bonus + global.objective.invupgradetier * 10
game.forces.player.character_loot_pickup_distance_bonus = game.forces.player.character_loot_pickup_distance_bonus + global.objective.pickupupgradetier
local fake_event = {}
Public_event.mining_buffs(nil)
for tech, bonuses in pairs(mining_researches) do
tech = game.forces.player.technologies[tech]
if tech.researched == true or bonuses.infinite == true then
fake_event.research = tech
if bonuses.infinite and bonuses.infinite_level and tech.level > bonuses.infinite_level then
for i = bonuses.infinite_level, tech.level - 1 do
Public_event.mining_buffs(fake_event)
end
else
Public_event.mining_buffs(fake_event)
end
end
end
end
end
return Public_event

286
maps/chronosphere/gui.lua Normal file
View File

@ -0,0 +1,286 @@
local Public_gui = {}
local math_floor = math.floor
local math_ceil = math.ceil
local math_abs = math.abs
local math_max = math.max
local math_min = math.min
local Upgrades = require "maps.chronosphere.upgrade_list"
local function create_gui(player)
local frame = player.gui.top.add({ type = "frame", name = "chronosphere"})
frame.style.maximal_height = 38
local label = frame.add({ type = "label", caption = " ", name = "label"})
label.style.font_color = {r=0.88, g=0.88, b=0.88}
label.style.font = "default-bold"
label.style.font_color = {r=0.33, g=0.66, b=0.9}
local label = frame.add({ type = "label", caption = " ", name = "jump_number"})
label.style.font_color = {r=0.88, g=0.88, b=0.88}
label.style.font = "default-bold"
label.style.right_padding = 4
label.style.font_color = {r=0.33, g=0.66, b=0.9}
local label = frame.add({ type = "label", caption = " ", name = "charger"})
label.style.font = "default-bold"
label.style.left_padding = 4
label.style.font_color = {r = 255, g = 200, b = 200} --255 200 200 --150 0 255
local label = frame.add({ type = "label", caption = " ", name = "charger_value"})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 255, g = 200, b = 200}
local progressbar = frame.add({ type = "progressbar", name = "progressbar", value = 0})
progressbar.style.minimal_width = 96
progressbar.style.maximal_width = 96
progressbar.style.top_padding = 10
local label = frame.add({ type = "label", caption = " ", name = "timer"})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 255, g = 200, b = 200}
local label = frame.add({ type = "label", caption = " ", name = "timer_value", tooltip = " "})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 255, g = 200, b = 200}
local label = frame.add({ type = "label", caption = " ", name = "timer2"})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 0, g = 200, b = 0}
local label = frame.add({ type = "label", caption = " ", name = "timer_value2"})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 0, g = 200, b = 0}
-- local line = frame.add({type = "line", direction = "vertical"})
-- line.style.left_padding = 4
-- line.style.right_padding = 8
local button = frame.add({type = "button", caption = " ", name = "planet_button"})
button.style.font = "default-bold"
button.style.font_color = { r=0.99, g=0.99, b=0.99}
button.style.minimal_width = 75
local button = frame.add({type = "button", caption = " ", name = "upgrades_button"})
button.style.font = "default-bold"
button.style.font_color = { r=0.99, g=0.99, b=0.99}
button.style.minimal_width = 75
end
local function update_upgrades_gui(player)
if not player.gui.screen["gui_upgrades"] then return end
local upgrades = Upgrades.upgrades()
local frame = player.gui.screen["gui_upgrades"]
for i = 1, #upgrades, 1 do
local t = frame["upgrades_table" .. i]
t["upgrade" .. i].number = global.objective.upgrades[i]
t["upgrade" .. i].tooltip = upgrades[i].tooltip
t["upgrade_label" .. i].tooltip = upgrades[i].tooltip
if global.objective.upgrades[i] == upgrades[i].max_level then
t["maxed" .. i].visible = true
t["jump_req" .. i].visible = false
for index,_ in pairs(upgrades[i].cost) do
t[index .. "-" .. i].visible = false
end
else
t["maxed" .. i].visible = false
t["jump_req" .. i].visible = true
t["jump_req" .. i].number = upgrades[i].jump_limit
for index,item in pairs(upgrades[i].cost) do
t[index .. "-" .. i].visible = true
t[index .. "-" .. i].number = item.count
end
end
end
end
local function update_planet_gui(player)
if not player.gui.screen["gui_planet"] then return end
local planet = global.objective.planet[1]
local evolution = game.forces["enemy"].evolution_factor
local evo_color = {
r = math_floor(255 * 1 * math_max(0, math_min(1, 1.2 - evolution * 2))),
g = math_floor(255 * 1 * math_max(math_abs(0.5 - evolution * 1.5), 1 - evolution * 4)),
b = math_floor(255 * 4 * math_max(0, 0.25 - math_abs(0.5 - evolution)))
}
local frame = player.gui.screen["gui_planet"]
frame["planet_name"].caption = {"chronosphere.gui_planet_0", planet.name.name}
frame["planet_ores"]["iron-ore"].number = planet.name.iron
frame["planet_ores"]["copper-ore"].number = planet.name.copper
frame["planet_ores"]["coal"].number = planet.name.coal
frame["planet_ores"]["stone"].number = planet.name.stone
frame["planet_ores"]["uranium-ore"].number = planet.name.uranium
frame["planet_ores"]["oil"].number = planet.name.oil
frame["richness"].caption = {"chronosphere.gui_planet_2", planet.ore_richness.name}
frame["planet_biters"].caption = {"chronosphere.gui_planet_3", math_floor(evolution * 1000) / 10}
frame["planet_biters"].style.font_color = evo_color
frame["planet_biters3"].caption = {"chronosphere.gui_planet_4_1", global.objective.passivejumps * 2.5, global.objective.passivejumps * 10}
frame["planet_time"].caption = {"chronosphere.gui_planet_5", planet.day_speed.name}
end
function Public_gui.update_gui(player)
local objective = global.objective
update_planet_gui(player)
update_upgrades_gui(player)
if not player.gui.top.chronosphere then create_gui(player) end
local gui = player.gui.top.chronosphere
gui.label.caption = {"chronosphere.gui_1"}
gui.jump_number.caption = objective.chronojumps
local interval = objective.chrononeeds
gui.progressbar.value = 1 - (objective.chrononeeds - objective.chronotimer) / interval
gui.charger.caption = {"chronosphere.gui_2"}
gui.charger_value.caption = objective.chronotimer .. " / " .. objective.chrononeeds
gui.timer.caption = {"chronosphere.gui_3"}
gui.timer_value.caption = math_floor((objective.chrononeeds - objective.chronotimer) / 60) .. " min, " .. (objective.chrononeeds - objective.chronotimer) % 60 .. " s"
if objective.chronojumps > 5 then
local overstay_timer_min = math_floor((objective.chrononeeds * 0.75 - objective.passivetimer) / 60)
local evo_timer_min = math_floor((objective.chrononeeds * 0.5 - objective.passivetimer) / 60)
local first_part = "If overstaying this, other planets can evolve: " .. overstay_timer_min .. " min, " .. (objective.chrononeeds * 0.75 - objective.passivetimer) % 60 .. " s"
if overstay_timer_min < 0 then
first_part = "If overstaying this, other planets can evolve: " .. overstay_timer_min .. " min, " .. 59 - ((objective.chrononeeds * 0.75 - objective.passivetimer) % 60) .. " s"
end
local second_part = "This planet gets additional evolution growth in: " ..evo_timer_min .. " min, " .. (objective.chrononeeds * 0.5 - objective.passivetimer) % 60 .. " s"
if evo_timer_min < 0 then
second_part = "This planet gets additional evolution growth in: " ..evo_timer_min .. " min, " .. 59 -((objective.chrononeeds * 0.5 - objective.passivetimer) % 60) .. " s"
end
gui.timer_value.tooltip = first_part .. "\n" .. second_part
else
gui.timer_value.tooltip = "After planet 5, biters will get additional permanent evolution for staying too long on each planet."
end
gui.planet_button.caption = {"chronosphere.gui_planet_button"}
gui.upgrades_button.caption = {"chronosphere.gui_upgrades_button"}
local acus = 0
if global.acumulators then acus = #global.acumulators end
local bestcase = math_floor((objective.chrononeeds - objective.chronotimer) / (1 + math_floor(acus/10)))
local nukecase = objective.dangertimer
if objective.planet[1].name.id == 19 and objective.passivetimer > 31 then
gui.timer2.caption = {"chronosphere.gui_3_2"}
gui.timer_value2.caption = math_floor(nukecase / 60) .. " min, " .. nukecase % 60 .. " s"
gui.timer2.style.font_color = {r=0.98, g=0, b=0}
gui.timer_value2.style.font_color = {r=0.98, g=0, b=0}
else
gui.timer2.caption = {"chronosphere.gui_3_1"}
gui.timer_value2.caption = math_floor(bestcase / 60) .. " min, " .. bestcase % 60 .. " s (when using " .. acus * 0.3 .. "MW)"
gui.timer2.style.font_color = {r = 0, g = 200, b = 0}
gui.timer_value2.style.font_color = {r = 0, g = 200, b = 0}
end
end
local function upgrades_gui(player)
if player.gui.screen["gui_upgrades"] then player.gui.screen["gui_upgrades"].destroy() return end
local objective = global.objective
local upgrades = Upgrades.upgrades()
local frame = player.gui.screen.add{type = "frame", name = "gui_upgrades", caption = "ChronoTrain Upgrades", direction = "vertical"}
frame.location = {x = 350, y = 45}
frame.style.minimal_height = 300
frame.style.maximal_height = 900
frame.style.minimal_width = 330
frame.style.maximal_width = 630
frame.add({type = "label", caption = {"chronosphere.gui_upgrades_1"}})
frame.add({type = "label", caption = {"chronosphere.gui_upgrades_2"}})
for i = 1, #upgrades, 1 do
local upg_table = frame.add({type = "table", name = "upgrades_table" .. i, column_count = 10})
upg_table.add({type = "sprite-button", name = "upgrade" .. i, enabled = false, sprite = upgrades[i].sprite, number = global.objective.upgrades[i], tooltip = upgrades[i].tooltip})
local name = upg_table.add({type = "label", name ="upgrade_label" .. i, caption = upgrades[i].name, tooltip = upgrades[i].tooltip})
name.style.width = 200
local maxed = upg_table.add({type = "sprite-button", name = "maxed" .. i, enabled = false, sprite = "virtual-signal/signal-check", tooltip = "Upgrade maxed!", visible = false})
local jumps = upg_table.add({type = "sprite-button", name = "jump_req" .. i, enabled = false, sprite = "virtual-signal/signal-J", number = upgrades[i].jump_limit, tooltip = "Required jump number", visible = true})
local costs = {}
for index,item in pairs(upgrades[i].cost) do
costs[index] = upg_table.add({type = "sprite-button", name = index .. "-" .. i, number = item.count, sprite = item.sprite, enabled = false, tooltip = {item.tt .. "." .. item.name}, visible = true})
end
if global.objective.upgrades[i] == upgrades[i].max_level then
maxed.visible = true
jumps.visible = false
for index,_ in pairs(upgrades[i].cost) do
costs[index].visible = false
end
else
maxed.visible = false
jumps.visible = true
for index,_ in pairs(upgrades[i].cost) do
costs[index].visible = true
end
end
end
frame.add({type = "button", name = "close_upgrades", caption = "Close"})
end
local function planet_gui(player)
if player.gui.screen["gui_planet"] then player.gui.screen["gui_planet"].destroy() return end
local planet = global.objective.planet[1]
local evolution = game.forces["enemy"].evolution_factor
local frame = player.gui.screen.add{type = "frame", name = "gui_planet", caption = "Planet Info", direction = "vertical"}
frame.location = {x = 650, y = 45}
frame.style.minimal_height = 300
frame.style.maximal_height = 500
frame.style.minimal_width = 200
frame.style.maximal_width = 400
local l = {}
l[1] = frame.add({type = "label", name = "planet_name", caption = {"chronosphere.gui_planet_0", planet.name.name}})
l[2] = frame.add({type = "label", caption = {"chronosphere.gui_planet_1"}})
local table0 = frame.add({type = "table", name = "planet_ores", column_count = 3})
table0.add({type = "sprite-button", name = "iron-ore", sprite = "item/iron-ore", enabled = false, number = planet.name.iron})
table0.add({type = "sprite-button", name = "copper-ore", sprite = "item/copper-ore", enabled = false, number = planet.name.copper})
table0.add({type = "sprite-button", name = "coal", sprite = "item/coal", enabled = false, number = planet.name.coal})
table0.add({type = "sprite-button", name = "stone", sprite = "item/stone", enabled = false, number = planet.name.stone})
table0.add({type = "sprite-button", name = "uranium-ore", sprite = "item/uranium-ore", enabled = false, number = planet.name.uranium})
table0.add({type = "sprite-button", name = "oil", sprite = "fluid/crude-oil", enabled = false, number = planet.name.oil})
l[3] = frame.add({type = "label", name = "richness", caption = {"chronosphere.gui_planet_2", planet.ore_richness.name}})
frame.add({type = "line"})
frame.add({type = "label", name = "planet_biters", caption = {"chronosphere.gui_planet_3", math_floor(evolution * 1000) / 10}})
frame.add({type = "label", name = "planet_biters2", caption = {"chronosphere.gui_planet_4"}})
frame.add({type = "label", name = "planet_biters3", caption = {"chronosphere.gui_planet_4_1", global.objective.passivejumps * 2.5, global.objective.passivejumps * 10}})
frame.add({type = "line"})
frame.add({type = "label", name = "planet_time", caption = {"chronosphere.gui_planet_5", planet.day_speed.name}})
frame.add({type = "line"})
local close = frame.add({type = "button", name = "close_planet", caption = "Close"})
close.style.horizontal_align = "center"
-- for i = 1, 3, 1 do
-- l[i].style.font = "default-game"
-- end
end
function Public_gui.on_gui_click(event)
if not event then return end
if not event.element then return end
if not event.element.valid then return end
local player = game.players[event.element.player_index]
if event.element.name == "upgrades_button" then
upgrades_gui(player)
return
elseif event.element.name == "planet_button" then
planet_gui(player)
return
end
if event.element.type ~= "button" and event.element.type ~= "sprite-button" then return end
local name = event.element.name
if name == "close_upgrades" then upgrades_gui(player) return end
if name == "close_planet" then planet_gui(player) return end
end
return Public_gui

View File

@ -0,0 +1,522 @@
local Public = {}
local Upgrades = require "maps.chronosphere.upgrade_list"
local math_floor = math.floor
local math_random = math.random
local function math_sgn(x)
return (x<0 and -1) or 1
end
function Public.locomotive_spawn(surface, position, wagons)
if global.objective.planet[1].name.id == 17 then --fish market
position.x = position.x - 960
position.y = position.y - 64
end
for y = -10, 18, 2 do
local rail = {name = "straight-rail", position = {position.x, position.y + y}, force = "player", direction = 0}
surface.create_entity({name = "straight-rail", position = {position.x, position.y + y}, force = "player", direction = 0})
end
global.locomotive = surface.create_entity({name = "locomotive", position = {position.x, position.y + -6}, force = "player"})
global.locomotive.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 100})
for i = 1, 3, 1 do
global.locomotive_cargo[i] = surface.create_entity({name = "cargo-wagon", position = {position.x, position.y + math_floor((i - 1) * 6.5)}, force = "player"})
local inv = global.locomotive_cargo[i].get_inventory(defines.inventory.cargo_wagon)
if wagons[i].bar > 0 then inv.set_bar(wagons[i].bar) end
for ii = 1, 40, 1 do
inv.set_filter(ii, wagons[i].filters[ii])
if wagons[i].inventory[ii] then
inv.insert(wagons[i].inventory[ii])
end
end
global.locomotive_cargo[i].minable = false
end
global.locomotive_cargo[1].operable = false
global.locomotive.color = {0, 255, 0}
global.locomotive.minable = false
--if not global.comfychests then global.comfychests = {} end
--if not global.acumulators then global.acumulators = {} end
for i = 1, 24, 1 do
local yi = 0
local xi = 5
if i > 20 then
yi = 6 - 12
xi = 5
elseif i > 16 then
yi = 6 - 15
xi = 5
elseif i > 12 then
xi = 5
yi = 6 - 18
elseif i > 8 then
yi = 6
xi = 0
elseif i > 4 then
yi = 3
xi = 0
else
yi = 0
xi = 0
end
local comfychest = surface.create_entity({name = "compilatron-chest", position = {position.x - 2 + xi, position.y - 2 + yi + i}, force = "player"})
comfychest.minable = false
--comfychest.destructible = false
if not global.comfychests[i] then
table.insert(global.comfychests, comfychest)
else
global.comfychests[i] = comfychest
end
end
rendering.draw_light({
sprite = "utility/light_medium", scale = 5.5, intensity = 1, minimum_darkness = 0,
oriented = true, color = {255,255,255}, target = global.locomotive,
surface = surface, visible = true, only_in_alt_mode = false,
})
rendering.draw_light({
sprite = "utility/light_medium", scale = 5.5, intensity = 1, minimum_darkness = 0,
oriented = true, color = {255,255,255}, target = global.locomotive_cargo[3],
surface = surface, visible = true, only_in_alt_mode = false,
})
end
function Public.fish_tag()
if not global.locomotive_cargo[1] then return end
local cargo = global.locomotive_cargo[1]
if not cargo.valid then return end
if not cargo.surface then return end
if not cargo.surface.valid then return end
if global.locomotive_tag then
if global.locomotive_tag.valid then
if global.locomotive_tag.position.x == cargo.position.x and global.locomotive_tag.position.y == cargo.position.y then return end
global.locomotive_tag.destroy()
end
end
global.locomotive_tag = cargo.force.add_chart_tag(
cargo.surface,
{icon = {type = 'item', name = 'raw-fish'},
position = cargo.position,
text = " "
})
end
local market_offers = {
{price = {{'coin', 10}}, offer = {type = 'give-item', item = "raw-fish"}},
{price = {{"coin", 20}}, offer = {type = 'give-item', item = 'wood', count = 50}},
{price = {{"coin", 50}}, offer = {type = 'give-item', item = 'iron-ore', count = 50}},
{price = {{"coin", 50}}, offer = {type = 'give-item', item = 'copper-ore', count = 50}},
{price = {{"coin", 50}}, offer = {type = 'give-item', item = 'stone', count = 50}},
{price = {{"coin", 50}}, offer = {type = 'give-item', item = 'coal', count = 50}},
{price = {{"coin", 200}}, offer = {type = 'give-item', item = 'uranium-ore', count = 50}},
{price = {{"coin", 25}, {"empty-barrel", 1}}, offer = {type = 'give-item', item = 'crude-oil-barrel', count = 1}},
{price = {{"coin", 200}, {"steel-plate", 20}, {"electronic-circuit", 20}}, offer = {type = 'give-item', item = 'loader', count = 1}},
{price = {{"coin", 400}, {"steel-plate", 40}, {"advanced-circuit", 10}, {"loader", 1}}, offer = {type = 'give-item', item = 'fast-loader', count = 1}},
{price = {{"coin", 600}, {"express-transport-belt", 10}, {"fast-loader", 1}}, offer = {type = 'give-item', item = 'express-loader', count = 1}},
--{price = {{"coin", 5}, {"stone", 100}}, offer = {type = 'give-item', item = 'landfill', count = 1}},
{price = {{"coin", 1}, {"steel-plate", 1}, {"explosives", 10}}, offer = {type = 'give-item', item = 'land-mine', count = 1}},
{price = {{"pistol", 1}}, offer = {type = "give-item", item = "iron-plate", count = 100}}
}
function Public.create_wagon_room()
local width = 64
local height = 384
global.comfychests2 = {}
global.acumulators = {}
local map_gen_settings = {
["width"] = width,
["height"] = height + 128,
["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},
},
}
if not game.surfaces["cargo_wagon"] then game.create_surface("cargo_wagon", map_gen_settings) end
local surface = game.surfaces["cargo_wagon"]
surface.freeze_daytime = true
surface.daytime = 0.1
surface.request_to_generate_chunks({0,0}, 12)
surface.force_generate_chunk_requests()
local carfpos = {
[1]={x=-33,y=-127},[2]={x=-33,y=-128},[3]={x=-33,y=-129},[4]={x=-33,y=-130},[5]={x=32,y=-127},[6]={x=32,y=-128},[7]={x=32,y=-129},[8]={x=32,y=-130},
[9]={x=-33,y=-2},[10]={x=-33,y=-1},[11]={x=-33,y=0},[12]={x=-33,y=1},[13]={x=32,y=-2},[14]={x=32,y=-1},[15]={x=32,y=0},[16]={x=32,y=1},
[17]={x=-33,y=126},[18]={x=-33,y=127},[19]={x=-33,y=128},[20]={x=-33,y=129},[21]={x=32,y=126},[22]={x=32,y=127},[23]={x=32,y=128},[24]={x=32,y=129}
}
for i = 1, 24, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {carfpos[i].x,carfpos[i].y}}})
end
for x = width * -0.5, width * 0.5 - 1, 1 do
for y = height * 0.5, height * 0.7, 1 do
surface.set_tiles({{name = "out-of-map", position = {x,y}}})
end
for y = height * -0.7, height * -0.5, 1 do
surface.set_tiles({{name = "out-of-map", position = {x,y}}})
end
for y = height * -0.5 + 3, height * 0.5 - 4, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
end
for y = height * -0.16 - 5, height * -0.16 + 0, 1 do
surface.set_tiles({{name = "out-of-map", position = {x,y}}})
end
for y = height * 0.16 - 0, height * 0.16 + 5, 1 do
surface.set_tiles({{name = "out-of-map", position = {x,y}}})
end
for y = height * -0.5, height * -0.5 + 2, 1 do
surface.set_tiles({{name = "out-of-map", position = {x,y}}})
end
for y = height * 0.5 - 3, height * 0.5, 1 do
surface.set_tiles({{name = "out-of-map", position = {x,y}}})
end
end
for x = width * -0.2 + 1, width * 0.2 - 1, 1 do
for y = height * -0.16 - 5, height * -0.16 + 0, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
end
for y = height * 0.16 -0, height * 0.16 + 5, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
end
--for y = height * -0.5 -5, height * -0.5 + 3, 1 do
-- surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
--end
end
for x = width * -0.5 + 5, width * 0.5 - 6, 1 do
for y = height * -0.7 + 18, height * -0.5 - 5, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
end
end
for x = width * -0.5 - 6, width * -0.5 + 3, 1 do -- combinators
for y = -251, -241, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
end
end
for x = width * -0.4 + 6, width * 0.4 - 6, 1 do
for y = height * -0.5 + 7, height * -0.5 + 10, 1 do
local p = {x,y}
surface.set_tiles({{name = "water", position = p}})
if math_random(1, 3) == 1 then surface.create_entity({name = "fish", position = p}) end
end
end
local combinators = {}
for x = width * -0.5 - 6, width * -0.5 + 3, 1 do
for y = -250, -244, 2 do
combinators[#combinators + 1] = {name = "arithmetic-combinator", position = {x, y}, force = "player", create_build_effect_smoke = false}
end
end
local combimade = {}
for i = 1, #combinators, 1 do
combimade[i] = surface.create_entity(combinators[i])
combimade[i].minable = false
combimade[i].destructible = false
combimade[i].operable = false
if i > 1 then
combimade[i].connect_neighbour({wire = defines.wire_type.green, target_entity = combimade[i - 1], source_circuit_id = 2, target_circuit_id = 1})
local rule = combimade[i].get_or_create_control_behavior()
rule.parameters = {parameters = {first_signal = {type = "virtual", name = "signal-A"}, second_constant = 0, operation = "+", output_signal = {type = "virtual", name = "signal-A"}}}
else
local rule2 = combimade[i].get_or_create_control_behavior()
rule2.parameters = {parameters = {first_signal = {type = "virtual", name = "signal-A"}, second_constant = 0, operation = "+", output_signal = {type = "virtual", name = "signal-B"}}}
end
end
local checker = surface.create_entity({name = "decider-combinator", position = {x = width * -0.5 - 6, y = -242}, force = "player", create_build_effect_smoke = false })
local rules3 = checker.get_or_create_control_behavior()
rules3.parameters = {parameters = {first_signal = {type = "virtual", name = "signal-A"}, second_signal = {type = "virtual", name = "signal-B"}, comparator = ">",
output_signal = {type = "virtual", name = "signal-C"}, copy_count_from_input = false }}
local combipower = surface.create_entity({name = "substation", position = {x = width * -0.5 - 4, y = -242}, force="player", create_build_effect_smoke = false})
combipower.connect_neighbour({wire = defines.wire_type.green, target_entity = checker, target_circuit_id = 1})
combipower.connect_neighbour({wire = defines.wire_type.green, target_entity = combimade[#combimade], target_circuit_id = 1})
combimade[1].connect_neighbour({wire = defines.wire_type.green, target_entity = checker, source_circuit_id = 2, target_circuit_id = 1})
local speaker = surface.create_entity({name = "programmable-speaker", position = {x = width * -0.5 - 6, y = -241}, force = "player", create_build_effect_smoke = false,
parameters = {playback_volume = 0.6, playback_globally = true, allow_polyphony = false},
alert_parameters = {show_alert = true, show_on_map = true, icon_signal_id = {type = "item", name = "accumulator"}, alert_message = "Train Is Charging!" }})
speaker.connect_neighbour({wire = defines.wire_type.green, target_entity = checker, target_circuit_id = 2})
local rules4 = speaker.get_or_create_control_behavior()
rules4.circuit_condition = {condition = {first_signal = {type = "virtual", name = "signal-C"}, second_constant = 0, comparator = ">"}}
rules4.circuit_parameters = {signal_value_is_pitch = false, instrument_id = 8, note_id = 5}
local solar1 = surface.create_entity({name = "solar-panel", position = {x = width * -0.5 - 2, y = -242}, force="player", create_build_effect_smoke = false})
local solar2 = surface.create_entity({name = "solar-panel", position = {x = width * -0.5 + 1, y = -242}, force="player", create_build_effect_smoke = false})
solar1.destructible = false
solar1.minable = false
solar2.destructible = false
solar2.minable = false
combipower.destructible = false
combipower.minable = false
combipower.operable = false
speaker.destructible = false
speaker.minable = false
speaker.operable = false
checker.destructible = false
checker.minable = false
checker.operable = false
for _, x in pairs({-1, 0}) do
for i = 1, 12, 1 do
local step = math_floor((i-1)/4)
local y = -131 + i + step * 128 - step * 4
local e = surface.create_entity({name = "compilatron-chest", position = {x,y}, force = "player", create_build_effect_smoke = false})
e.destructible = false
e.minable = false
table.insert(global.comfychests2, e)
end
end
for i = 1, 9, 1 do
local y = -0.7 * height + 18 + 9 + 18 * ( math_floor((i - 1) / 3))
local x = -0.5 * width + 5 + 9 + 18 * ( i%3 )
local substation = surface.create_entity({name = "substation", position = {x,y}, force="player", create_build_effect_smoke = false})
if i == 3 then
substation.disconnect_neighbour(combipower)
substation.connect_neighbour({wire = defines.wire_type.green, target_entity = combipower})
end
substation.minable = false
substation.destructible = false
for j = 1, 4, 1 do
local xx = x - 2 * j
local acumulator = surface.create_entity({name = "accumulator", position = {xx,y}, force="player", create_build_effect_smoke = false})
if i == 3 and j == 1 then
acumulator.connect_neighbour({wire = defines.wire_type.green, target_entity = substation})
end
acumulator.minable = false
acumulator.destructible = false
table.insert(global.acumulators, acumulator)
end
for k = 1, 4, 1 do
local xx = x + 2 * k
local acumulator = surface.create_entity({name = "accumulator", position = {xx,y}, force="player", create_build_effect_smoke = false})
acumulator.minable = false
acumulator.destructible = false
table.insert(global.acumulators, acumulator)
end
end
local powerpole = surface.create_entity({name = "big-electric-pole", position = {0, height * -0.5 }, force="player", create_build_effect_smoke = false})
powerpole.minable = false
powerpole.destructible = false
local market = surface.create_entity({name = "market", position = {-29, height * -0.5 + 4}, force="neutral", create_build_effect_smoke = false})
market.minable = false
market.destructible = false
local repairchest = surface.create_entity({name = "compilatron-chest", position = {-24, height * -0.5 + 3}, force = "player"})
repairchest.minable = false
repairchest.destructible = false
global.upgradechest[0] = repairchest
rendering.draw_text{
text = "Repair chest",
surface = surface,
target = repairchest,
target_offset = {0, -2.5},
color = global.locomotive.color,
scale = 1.00,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
local upgrades = Upgrades.upgrades()
for i = 1, #upgrades, 1 do
local e = surface.create_entity({name = "compilatron-chest", position = {-21 + i, height * -0.5 + 3}, force = "player"})
e.minable = false
e.destructible = false
global.upgradechest[i] = e
rendering.draw_sprite{
sprite = upgrades[i].sprite,
surface = surface,
target = e,
target_offset = {0, -1.3},
font = "default-game",
visible = true
}
end
local market1_text = rendering.draw_text{
text = "Resources",
surface = surface,
target = market,
target_offset = {0, -3.5},
color = global.locomotive.color,
scale = 1.00,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
local upgrade_text = rendering.draw_text{
text = "Upgrades",
surface = surface,
target = global.upgradechest[8],
target_offset = {0, -3.5},
color = global.locomotive.color,
scale = 1.00,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
local upgrade_sub_text = rendering.draw_text{
text = "Click [Upgrades] on top of screen",
surface = surface,
target = global.upgradechest[8],
target_offset = {0, -2.5},
color = global.locomotive.color,
scale = 0.80,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
for _, offer in pairs(market_offers) do market.add_market_item(offer) end
--generate cars--
local car_pos = {
{x = width * -0.5 - 1.4, y = -128},
{x = width * -0.5 - 1.4, y = 0},
{x = width * -0.5 - 1.4, y = 128},
{x = width * 0.5 + 1.4, y = -128},
{x = width * 0.5 + 1.4, y = 0},
{x = width * 0.5 + 1.4, y = 128}
}
global.car_exits = {}
for i = 1, 6, 1 do
local e = surface.create_entity({name = "car", position = car_pos[i], force = "player", create_build_effect_smoke = false})
e.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 16})
e.destructible = false
e.minable = false
e.operable = false
global.car_exits[i] = e
end
--generate chests inside south wagon--
local positions = {}
for x = width * -0.5 + 2, width * 0.5 - 1, 1 do
if x == -1 then x = x - 1 end
if x == 0 then x = x + 1 end
for y = 68, height * 0.5 - 4, 1 do
positions[#positions + 1] = {x = x, y = y}
end
end
table.shuffle_table(positions)
local cargo_boxes = {
{name = "grenade", count = math_random(2, 5)},
{name = "grenade", count = math_random(2, 5)},
{name = "grenade", count = math_random(2, 5)},
{name = "submachine-gun", count = 1},
{name = "submachine-gun", count = 1},
{name = "submachine-gun", count = 1},
{name = "land-mine", count = math_random(8, 12)},
{name = "iron-gear-wheel", count = math_random(7, 15)},
{name = "iron-gear-wheel", count = math_random(7, 15)},
{name = "iron-gear-wheel", count = math_random(7, 15)},
{name = "iron-gear-wheel", count = math_random(7, 15)},
{name = "iron-plate", count = math_random(15, 23)},
{name = "iron-plate", count = math_random(15, 23)},
{name = "iron-plate", count = math_random(15, 23)},
{name = "iron-plate", count = math_random(15, 23)},
{name = "iron-plate", count = math_random(15, 23)},
{name = "copper-plate", count = math_random(15, 23)},
{name = "copper-plate", count = math_random(15, 23)},
{name = "copper-plate", count = math_random(15, 23)},
{name = "copper-plate", count = math_random(15, 23)},
{name = "copper-plate", count = math_random(15, 23)},
{name = "shotgun", count = 1},
{name = "shotgun", count = 1},
{name = "shotgun", count = 1},
{name = "shotgun-shell", count = math_random(5, 7)},
{name = "shotgun-shell", count = math_random(5, 7)},
{name = "shotgun-shell", count = math_random(5, 7)},
{name = "firearm-magazine", count = math_random(7, 15)},
{name = "firearm-magazine", count = math_random(7, 15)},
{name = "firearm-magazine", count = math_random(7, 15)},
{name = "rail", count = math_random(16, 24)},
{name = "rail", count = math_random(16, 24)},
{name = "rail", count = math_random(16, 24)},
}
local i = 1
for _ = 1, 16, 1 do
if not positions[i] then break end
local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false})
local inventory = e.get_inventory(defines.inventory.chest)
inventory.insert({name = "raw-fish", count = math_random(2, 5)})
i = i + 1
end
for _ = 1, 24, 1 do
if not positions[i] then break end
local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false})
i = i + 1
end
for loot_i = 1, #cargo_boxes, 1 do
if not positions[i] then break end
local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false})
local inventory = e.get_inventory(defines.inventory.chest)
inventory.insert(cargo_boxes[loot_i])
i = i + 1
end
end
function Public.set_player_spawn_and_refill_fish()
if not global.locomotive_cargo[1] then return end
local cargo = global.locomotive_cargo[1]
if not cargo.valid then return end
cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = "raw-fish", count = math_random(1, 2)})
local position = cargo.surface.find_non_colliding_position("stone-furnace", cargo.position, 16, 2)
if not position then return end
game.forces.player.set_spawn_position({x = position.x, y = position.y}, cargo.surface)
end
function Public.enter_cargo_wagon(player, vehicle)
if not vehicle then log("no vehicle") return end
if not vehicle.valid then log("vehicle invalid") return end
if not game.surfaces["cargo_wagon"] then Public.create_wagon_room() end
local wagon_surface = game.surfaces["cargo_wagon"]
for i = 1, 3, 1 do
if not global.locomotive_cargo[i] then log("no cargo") return end
if not global.locomotive_cargo[i].valid then log("cargo invalid") return end
if vehicle == global.locomotive_cargo[i] then
local x_vector = vehicle.position.x - player.position.x
local position
if x_vector > 0 then
position = {wagon_surface.map_gen_settings.width * -0.5, -128 + 128 * (i - 1)}
else
position = {wagon_surface.map_gen_settings.width * 0.5, -128 + 128 * (i - 1)}
end
player.teleport(wagon_surface.find_non_colliding_position("character", position, 128, 0.5), wagon_surface)
break
end
end
if player.surface.name == "cargo_wagon" and vehicle.type == "car" then
if global.flame_boots then
global.flame_boots[player.index] = {fuel = 1, steps = {}}
end
local used_exit = 0
for i = 1, 6, 1 do
if vehicle == global.car_exits[i] then
used_exit = i
break
end
end
local surface = global.locomotive_cargo[1].surface
local position = {x = global.locomotive_cargo[((used_exit - 1) % 3) + 1].position.x + math_sgn(used_exit - 3.5) * 2, y = global.locomotive_cargo[((used_exit - 1) % 3) + 1].position.y}
local position2 = surface.find_non_colliding_position("character", position, 128, 0.5)
if not position2 then return end
player.teleport(position2, surface)
end
end
return Public

579
maps/chronosphere/main.lua Normal file
View File

@ -0,0 +1,579 @@
-- chronosphere --
global.objective = {}
global.objective.upgrades = {}
require "modules.difficulty_vote"
require "modules.biters_yield_coins"
require "modules.no_deconstruction_of_neutral_entities"
--require "modules.no_solar"
require "modules.shotgun_buff"
require "modules.mineable_wreckage_yields_scrap"
require "maps.chronosphere.comfylatron"
require "maps.chronosphere.terrain"
require "on_tick_schedule"
require "modules.biter_noms_you"
local Server = require 'utils.server'
local Ai = require "maps.chronosphere.ai"
local Planets = require "maps.chronosphere.chronobubles"
local Ores =require "maps.chronosphere.ores"
local Reset = require "functions.soft_reset"
local Map = require "modules.map_info"
local Upgrades = require "maps.chronosphere.upgrades"
local Tick_functions = require "maps.chronosphere.tick_functions"
local Event_functions = require "maps.chronosphere.event_functions"
local Chrono = require "maps.chronosphere.chrono"
local Locomotive = require "maps.chronosphere.locomotive"
local Gui = require "maps.chronosphere.gui"
local math_random = math.random
local math_floor = math.floor
local math_sqrt = math.sqrt
global.objective.config = {}
global.flame_boots = {}
global.comfylatron = nil
global.lab_cells = {}
require "maps.chronosphere.config_tab"
local starting_items = {['pistol'] = 1, ['firearm-magazine'] = 32, ['grenade'] = 4, ['raw-fish'] = 4, ['rail'] = 16, ['wood'] = 16}
local function generate_overworld(surface, optplanet)
Planets.determine_planet(optplanet)
local planet = global.objective.planet
local message = {"chronosphere.planet_jump", planet[1].name.name, planet[1].ore_richness.name, planet[1].day_speed.name}
game.print(message, {r=0.98, g=0.66, b=0.22})
local discordmessage = "Destination: "..planet[1].name.dname..", Ore Richness: "..planet[1].ore_richness.dname..", Daynight cycle: "..planet[1].day_speed.dname
Server.to_discord_embed(discordmessage)
if planet[1].name.id == 12 then
game.print({"chronosphere.message_choppy"}, {r=0.98, g=0.66, b=0.22})
elseif planet[1].name.id == 14 then
game.print({"chronosphere.message_lava"}, {r=0.98, g=0.66, b=0.22})
elseif planet[1].name.id == 17 then
game.print({"chronosphere.message_fishmarket1"}, {r=0.98, g=0.66, b=0.22})
game.print({"chronosphere.message_fishmarket2"}, {r=0.98, g=0.66, b=0.22})
end
surface.min_brightness = 0
surface.brightness_visual_weights = {1, 1, 1}
global.objective.surface = surface
surface.daytime = planet[1].time
local timer = planet[1].day_speed.timer
if timer == 0 then
surface.freeze_daytime = true
timer = timer + 1
else
surface.freeze_daytime = false
end
surface.ticks_per_day = timer * 250
local moisture = planet[1].name.moisture
if moisture ~= 0 then
local mgs = surface.map_gen_settings
mgs.property_expression_names["control-setting:moisture:bias"] = moisture
surface.map_gen_settings = mgs
end
if planet[1].name.id == 14 then --lava planet
local mgs = surface.map_gen_settings
mgs.water = 0
surface.map_gen_settings = mgs
end
if planet[1].name.id ~= 12 then --choppy planet
local mgs = surface.map_gen_settings
mgs.water = 0.2
surface.map_gen_settings = mgs
end
if planet[1].name.id == 17 then --fish market
local mgs = surface.map_gen_settings
mgs.width = 2176
surface.map_gen_settings = mgs
surface.request_to_generate_chunks({-960,-64}, 3)
--surface.request_to_generate_chunks({0,0}, 3)
surface.force_generate_chunk_requests()
else
surface.request_to_generate_chunks({0,0}, 3)
surface.force_generate_chunk_requests()
end
end
local function render_train_hp()
local surface = game.surfaces[global.active_surface_index]
local objective = global.objective
objective.health_text = rendering.draw_text{
text = "HP: " .. objective.health .. " / " .. objective.max_health,
surface = surface,
target = global.locomotive,
target_offset = {0, -2.5},
color = global.locomotive.color,
scale = 1.40,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
objective.caption = rendering.draw_text{
text = "Comfylatron's ChronoTrain",
surface = surface,
target = global.locomotive,
target_offset = {0, -4.25},
color = global.locomotive.color,
scale = 1.80,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
end
local function reset_map()
for _,player in pairs(game.players) do
if player.controller_type == defines.controllers.editor then player.toggle_map_editor() end
end
if game.surfaces["chronosphere"] then game.delete_surface(game.surfaces["chronosphere"]) end
if game.surfaces["cargo_wagon"] then game.delete_surface(game.surfaces["cargo_wagon"]) end
local objective = global.objective
for i = 13, 16, 1 do
objective.upgrades[i] = 0
end
objective.computermessage = 0
objective.chronojumps = 0
Planets.determine_planet(nil)
local planet = global.objective.planet
if not global.active_surface_index then
global.active_surface_index = game.create_surface("chronosphere", Chrono.get_map_gen_settings()).index
else
game.forces.player.set_spawn_position({12, 10}, game.surfaces[global.active_surface_index])
global.active_surface_index = Reset.soft_reset_map(game.surfaces[global.active_surface_index], Chrono.get_map_gen_settings(), starting_items).index
end
local surface = game.surfaces[global.active_surface_index]
generate_overworld(surface, planet)
Chrono.restart_settings()
game.forces.player.set_spawn_position({12, 10}, surface)
Locomotive.locomotive_spawn(surface, {x = 16, y = 10}, Chrono.get_wagons(true))
render_train_hp()
game.reset_time_played()
Locomotive.create_wagon_room()
if objective.game_won then
game.print({"chronosphere.message_game_won_restart"}, {r=0.98, g=0.66, b=0.22})
end
objective.game_lost = false
objective.game_won = false
--set_difficulty()
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
global.flame_boots[event.player_index] = {fuel = 1}
if not global.flame_boots[event.player_index].steps then global.flame_boots[event.player_index].steps = {} end
local surface = game.surfaces[global.active_surface_index]
if player.online_time == 0 then
player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 32, 0.5), surface)
for item, amount in pairs(starting_items) do
player.insert({name = item, count = amount})
end
end
if player.surface.index ~= global.active_surface_index and player.surface.name ~= "cargo_wagon" then
player.character = nil
player.set_controller({type=defines.controllers.god})
player.create_character()
player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 32, 0.5), surface)
for item, amount in pairs(starting_items) do
player.insert({name = item, count = amount})
end
end
local tile = surface.get_tile(player.position)
if tile.valid then
if tile.name == "out-of-map" then
player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 32, 0.5), surface)
end
end
end
local function on_pre_player_left_game(event)
local player = game.players[event.player_index]
if player.controller_type == defines.controllers.editor then player.toggle_map_editor() end
if player.character then
global.objective.offline_players[#global.objective.offline_players + 1] = {index = event.player_index, tick = game.tick}
end
end
local function set_objective_health(final_damage_amount)
if final_damage_amount == 0 then return end
local objective = global.objective
objective.health = math_floor(objective.health - final_damage_amount)
if objective.health > objective.max_health then objective.health = objective.max_health end
if objective.health <= 0 then
Chrono.objective_died()
end
if objective.health < objective.max_health / 2 and final_damage_amount > 0 then
Upgrades.trigger_poison()
end
rendering.set_text(objective.health_text, "HP: " .. objective.health .. " / " .. objective.max_health)
end
local function chronojump(choice)
local objective = global.objective
if objective.game_lost then return end
Chrono.process_jump()
local oldsurface = game.surfaces[global.active_surface_index]
for _,player in pairs(game.players) do
if player.surface == oldsurface then
if player.controller_type == defines.controllers.editor then player.toggle_map_editor() end
local wagons = {global.locomotive_cargo[1], global.locomotive_cargo[2], global.locomotive_cargo[3]}
Locomotive.enter_cargo_wagon(player, wagons[math_random(1,3)])
end
end
global.lab_cells = {}
global.active_surface_index = game.create_surface("chronosphere" .. objective.chronojumps, Chrono.get_map_gen_settings()).index
local surface = game.surfaces[global.active_surface_index]
log("seed of new surface: " .. surface.map_gen_settings.seed)
local planet = nil
if choice then
Planets.determine_planet(choice)
planet = global.objective.planet
end
generate_overworld(surface, planet)
game.forces.player.set_spawn_position({12, 10}, surface)
Locomotive.locomotive_spawn(surface, {x = 16, y = 10}, Chrono.get_wagons(false))
render_train_hp()
game.delete_surface(oldsurface)
Chrono.post_jump()
Event_functions.flamer_nerfs()
surface.pollute(global.locomotive.position, 150 * (4 / (objective.upgrades[2] / 2 + 1)) * (1 + global.objective.chronojumps) * global.difficulty_vote_value)
end
local tick_minute_functions = {
[300 * 2] = Ai.destroy_inactive_biters,
[300 * 3 + 30 * 0] = Ai.pre_main_attack, -- setup for main_attack
[300 * 3 + 30 * 1] = Ai.perform_main_attack,
[300 * 3 + 30 * 2] = Ai.perform_main_attack,
[300 * 3 + 30 * 3] = Ai.perform_main_attack,
[300 * 3 + 30 * 4] = Ai.perform_main_attack,
[300 * 3 + 30 * 5] = Ai.perform_main_attack, -- call perform_main_attack 7 times on different ticks
[300 * 4] = Ai.send_near_biters_to_objective,
[300 * 5] = Ai.wake_up_sleepy_groups,
--[300] = Ai.rogue_group
}
local function tick()
local objective = global.objective
local tick = game.tick
if tick % 60 == 30 and objective.passivetimer < 64 then
local surface = game.surfaces[global.active_surface_index]
if objective.planet[1].name.id == 17 then
surface.request_to_generate_chunks({-800,0}, 3 + math_floor(objective.passivetimer / 5))
else
surface.request_to_generate_chunks({0,0}, 3 + math_floor(objective.passivetimer / 5))
end
--surface.force_generate_chunk_requests()
end
if tick % 10 == 0 and objective.planet[1].name.id == 18 then
Tick_functions.spawn_poison()
end
if tick % 30 == 0 then
if tick % 600 == 0 then
Tick_functions.charge_chronosphere()
Tick_functions.transfer_pollution()
if objective.poisontimeout > 0 then
objective.poisontimeout = objective.poisontimeout - 1
end
end
if tick % 1800 == 0 then
Locomotive.set_player_spawn_and_refill_fish()
set_objective_health(Tick_functions.repair_train())
Upgrades.check_upgrades()
Tick_functions.boost_evolution()
if objective.config.offline_loot then
Tick_functions.offline_players()
end
end
local key = tick % 3600
if tick_minute_functions[key] then tick_minute_functions[key]() end
if tick % 60 == 0 and objective.planet[1].name.id ~= 17 then
objective.chronotimer = objective.chronotimer + 1
objective.passivetimer = objective.passivetimer + 1
if objective.chronojumps > 0 then
game.surfaces[global.active_surface_index].pollute(global.locomotive.position, (0.5 * objective.chronojumps) * (4 / (objective.upgrades[2] / 2 + 1)) * global.difficulty_vote_value)
end
if objective.planet[1].name.id == 19 then
Tick_functions.dangertimer()
end
if Tick_functions.check_chronoprogress() then chronojump(nil) end
end
if tick % 120 == 0 then
Tick_functions.move_items()
Tick_functions.output_items()
end
if global.game_reset_tick then
if global.game_reset_tick < tick then
global.game_reset_tick = nil
reset_map()
end
return
end
Locomotive.fish_tag()
end
for _, player in pairs(game.connected_players) do Gui.update_gui(player) end
end
local function on_init()
local T = Map.Pop_info()
T.localised_category = "chronosphere"
T.main_caption_color = {r = 150, g = 150, b = 0}
T.sub_caption_color = {r = 0, g = 150, b = 0}
global.objective.game_lost = true
global.objective.game_won = false
global.objective.offline_players = {}
global.objective.config.offline_loot = true
global.objective.config.jumpfailure = true
game.create_force("scrapyard")
local mgs = game.surfaces["nauvis"].map_gen_settings
mgs.width = 16
mgs.height = 16
game.surfaces["nauvis"].map_gen_settings = mgs
game.surfaces["nauvis"].clear()
reset_map()
Chrono.init_setup()
Event_functions.mining_buffs(nil)
--if game.surfaces["nauvis"] then game.delete_surface(game.surfaces["nauvis"]) end
end
-- local function on_load()
-- Chrono.init_setup()
-- end
local function protect_entity(event)
if event.entity.force.index ~= 1 then return end --Player Force
if Event_functions.isprotected(event.entity) then
if event.cause then
if event.cause == global.comfylatron or event.entity == global.comfylatron then
return
end
if event.cause.force.index == 2 or event.cause.force.name == "scrapyard" then
set_objective_health(event.final_damage_amount)
end
elseif global.objective.planet[1].name.id == 19 then
set_objective_health(event.final_damage_amount)
end
if not event.entity.valid then return end
event.entity.health = event.entity.health + event.final_damage_amount
end
end
local function on_entity_damaged(event)
if not event.entity.valid then return end
protect_entity(event)
if not event.entity.valid then return end
if not event.entity.health then return end
Event_functions.biters_chew_rocks_faster(event)
if event.entity.force.name == "enemy" then
Event_functions.biter_immunities(event)
end
end
local function pre_player_mined_item(event)
local objective = global.objective
if objective.planet[1].name.id == 11 then --rocky planet
if event.entity.name == "rock-huge" or event.entity.name == "rock-big" or event.entity.name == "sand-rock-big" then
Event_functions.trap(event.entity, false)
event.entity.destroy()
Event_functions.rocky_loot(event)
end
end
end
local function on_player_mined_entity(event)
local entity = event.entity
if not entity.valid then return end
if entity.type == "tree" and global.objective.planet[1].name.id == 12 then --choppy planet
Event_functions.trap(entity, false)
Event_functions.choppy_loot(event)
end
if entity.name == "rock-huge" or entity.name == "rock-big" or entity.name == "sand-rock-big" then
if global.objective.planet[1].name.id ~= 11 and global.objective.planet[1].name.id ~= 16 then --rocky and maze planet
Ores.prospect_ores(entity, entity.surface, entity.position)
elseif
global.objective.planet[1].name.id == 11 then event.buffer.clear() -- rocky planet
end
end
end
local function on_entity_died(event)
if event.entity.type == "tree" and global.objective.planet[1].name.id == 12 then --choppy planet
if event.cause then
if event.cause.valid then
if event.cause.force.name ~= "enemy" then
Event_functions.trap(event.entity, false)
end
end
end
-- if not event.entity.valid then return end
-- for _, entity in pairs (event.entity.surface.find_entities_filtered({area = {{event.entity.position.x - 4, event.entity.position.y - 4},{event.entity.position.x + 4, event.entity.position.y + 4}}, name = "fire-flame-on-tree"})) do
-- if entity.valid then entity.destroy() end
-- end
--return
end
local entity = event.entity
if not entity.valid then return end
if entity.type == "unit" and entity.force == "enemy" then
global.objective.active_biters[entity.unit_number] = nil
end
if entity.type == "rocket-silo" and entity.force.name == "enemy" then
Event_functions.danger_silo(entity)
end
if entity.force.name == "scrapyard" and entity.name == "gun-turret" then
if global.objective.planet[1].name.id == 19 or global.objective.planet[1].name.id == 16 then --danger + hedge maze
Event_functions.trap(entity, true)
end
end
if entity.force.name == "enemy" then
if entity.type == "unit-spawner" then
Event_functions.spawner_loot(entity.surface, entity.position)
if global.objective.planet[1].name.id == 18 then
Ores.prospect_ores(entity, entity.surface, entity.position)
end
else
if global.objective.planet[1].name.id == 18 then
Event_functions.swamp_loot(event)
end
end
end
if entity.force.index == 3 then
if event.cause then
if event.cause.valid then
if event.cause.force.index == 2 then
Event_functions.shred_simple_entities(entity)
end
end
end
end
end
local function on_research_finished(event)
Event_functions.flamer_nerfs()
Event_functions.mining_buffs(event)
end
local function on_player_driving_changed_state(event)
local player = game.players[event.player_index]
local vehicle = event.entity
Locomotive.enter_cargo_wagon(player, vehicle)
end
-- function deny_building(event)
-- local entity = event.created_entity
-- if not entity.valid then return end
-- local surface = event.created_entity.surface
--
-- if event.player_index then
-- game.players[event.player_index].insert({name = entity.name, count = 1})
-- else
-- local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
-- inventory.insert({name = entity.name, count = 1})
-- end
--
-- surface.create_entity({
-- name = "flying-text",
-- position = entity.position,
-- text = "Private Comfylatron's area!",
-- color = {r=0.98, g=0.66, b=0.22}
-- })
--
-- entity.destroy()
-- end
-- local function on_built_entity(event)
-- if event.surface.name == "cargo_wagon" and event.position.y < -190 then
-- deny_building(event)
-- end
-- end
--
-- local function on_robot_built_entity(event)
-- if event.surface.name == "cargo_wagon" and event.position.y < -190 then
-- deny_building(event)
-- end
-- Terrain.deny_construction_bots(event)
-- end
-- local function on_market_item_purchased(event)
-- Locomotive.offer_purchased(event)
-- end
local function on_player_changed_position(event)
if global.objective.planet[1].name.id == 14 then --lava planet
Event_functions.lava_planet(event)
end
end
local function on_technology_effects_reset(event)
Event_functions.on_technology_effects_reset(event)
end
local event = require 'utils.event'
event.on_init(on_init)
event.on_load(on_load)
event.on_nth_tick(2, tick)
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_player_joined_game, on_player_joined_game)
event.add(defines.events.on_pre_player_left_game, on_pre_player_left_game)
event.add(defines.events.on_pre_player_mined_item, pre_player_mined_item)
event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
event.add(defines.events.on_research_finished, on_research_finished)
event.add(defines.events.on_player_driving_changed_state, on_player_driving_changed_state)
event.add(defines.events.on_player_changed_position, on_player_changed_position)
event.add(defines.events.on_technology_effects_reset, on_technology_effects_reset)
event.add(defines.events.on_gui_click, Gui.on_gui_click)
if _DEBUG then
local Session = require 'utils.session_data'
local Color = require 'utils.color_presets'
commands.add_command(
'chronojump',
'Weeeeee!',
function(cmd)
local player = game.player
local trusted = Session.get_trusted_table()
local param = tostring(cmd.parameter)
local p
if player then
if player ~= nil then
p = player.print
if not trusted[player.name] then
if not player.admin then
p("[ERROR] Only admins and trusted weebs are allowed to run this command!", Color.fail)
return
end
end
else
p = log
end
end
chronojump(param)
end)
end
--Time for the debug code. If any (not global.) globals are written to at this point, an error will be thrown.
--eg, x = 2 will throw an error because it's not global.x or local x
setmetatable(_G, {
__newindex = function(_, n, v)
log("Desync warning: attempt to write to undeclared var " .. n)
-- game.print("Attempt to write to undeclared var " .. n)
global[n] = v;
end,
__index = function(_, n)
return global[n];
end
})

126
maps/chronosphere/ores.lua Normal file
View File

@ -0,0 +1,126 @@
local Public_ores = {}
local simplex_noise = require 'utils.simplex_noise'.d2
local math_random = math.random
local math_abs = math.abs
local math_floor = math.floor
local math_sqrt = math.sqrt
local ores = {"copper-ore", "iron-ore", "stone", "coal"}
local function draw_noise_ore_patch(position, name, surface, radius, richness, mixed)
if not position then return end
if not name then return end
if not surface then return end
if not radius then return end
if not richness then return end
local ore_raffle = {
"iron-ore", "iron-ore", "iron-ore", "copper-ore", "copper-ore", "coal", "stone"
}
local seed = surface.map_gen_settings.seed
local noise_seed_add = 25000
local richness_part = richness / radius
for y = radius * -3, radius * 3, 1 do
for x = radius * -3, radius * 3, 1 do
local pos = {x = x + position.x + 0.5, y = y + position.y + 0.5}
local noise_1 = simplex_noise(pos.x * 0.0125, pos.y * 0.0125, seed)
local noise_2 = simplex_noise(pos.x * 0.1, pos.y * 0.1, seed + 25000)
local noise = noise_1 + noise_2 * 0.12
local distance_to_center = math.sqrt(x^2 + y^2)
local a = richness - richness_part * distance_to_center
if distance_to_center < radius - math.abs(noise * radius * 0.85) and a > 1 then
pos = surface.find_non_colliding_position(name, pos, 64, 1, true)
if not pos then return end
if mixed then
local noise = simplex_noise(pos.x * 0.005, pos.y * 0.005, seed) + simplex_noise(pos.x * 0.01, pos.y * 0.01, seed) * 0.3 + simplex_noise(pos.x * 0.05, pos.y * 0.05, seed) * 0.2
local i = (math_floor(noise * 100) % 7) + 1
name = ore_raffle[i]
end
local entity = {name = name, position = pos, amount = a}
if surface.can_place_entity(entity) then
surface.create_entity(entity)
end
end
end
end
end
local function get_size_of_ore(ore, planet)
local base_size = math_random(5, 10) + math_floor(planet[1].ore_richness.factor * 3)
local final_size = 1
if planet[1].name.id == 1 and ore == "iron-ore" then --iron planet
final_size = math_floor(base_size * 1.5)
elseif planet[1].name.id == 2 and ore == "copper-ore" then --copper planet
final_size = math_floor(base_size * 1.5)
elseif planet[1].name.id == 3 and ore == "stone" then --stone planet
final_size = math_floor(base_size * 1.5)
elseif planet[1].name.id == 9 and ore == "coal" then --coal planet
final_size = math_floor(base_size * 1.5)
elseif planet[1].name.id == 5 and ore == "uranium-ore" then --uranium planet
final_size = math_floor(base_size * 1.5)
elseif planet[1].name.id == 6 then --mixed planet
final_size = base_size
else
final_size = math_floor(base_size / 2)
end
return final_size
end
local function get_oil_amount(pos, oil_w, richness)
local hundred_percent = 300000
return (hundred_percent / 50) * (1+global.objective.chronojumps) * oil_w * richness
end
local function spawn_ore_vein(surface, pos, planet)
local mixed = false
if planet[1].name.id == 6 then mixed = true end --mixed planet
local richness = math_random(50 + 10 * global.objective.chronojumps, 100 + 10 * global.objective.chronojumps) * planet[1].ore_richness.factor
if planet[1].name.id == 16 then richness = richness * 10 end --hedge maze
local iron = {w = planet[1].name.iron, t = planet[1].name.iron}
local copper = {w = planet[1].name.copper, t = iron.t + planet[1].name.copper}
local stone = {w = planet[1].name.stone, t = copper.t + planet[1].name.stone}
local coal = {w = planet[1].name.coal, t = stone.t + planet[1].name.coal}
local uranium = {w = planet[1].name.uranium, t = coal.t + planet[1].name.uranium}
local oil = {w = planet[1].name.oil, t = uranium.t + planet[1].name.oil}
local total = iron.w + copper.w + stone.w + coal.w + uranium.w + oil.w
local roll = math_random (0, oil.t)
if roll == 0 then return end
local choice = nil
if roll <= iron.t then
choice = "iron-ore"
elseif roll <= copper.t then
choice = "copper-ore"
elseif roll <= stone.t then
choice = "stone"
elseif roll <= coal.t then
choice = "coal"
elseif roll <= uranium.t then
choice = "uranium-ore"
elseif roll <= oil.t then
choice = "crude-oil"
end
--if surface.can_place_entity({name = choice, position = pos, amount = 1}) then
if choice == "crude-oil" then
surface.create_entity({name = "crude-oil", position = pos, amount = get_oil_amount(pos, oil.w, planet[1].ore_richness.factor) / 2 })
else
draw_noise_ore_patch(pos, choice, surface, get_size_of_ore(choice, planet), richness / 2, mixed)
end
--end
end
function Public_ores.prospect_ores(entity, surface, pos)
local planet = global.objective.planet
local chance = 10
if entity then
if entity.name == "rock-huge" then chance = 40 end
if entity.type == "unit-spawner" then chance = 40 end
if planet[1].name.id == 15 then chance = chance + 30 end
if math_random(chance + math_floor(10 * planet[1].ore_richness.factor) ,100 + chance) >= 100 then
spawn_ore_vein(surface, pos, planet)
end
else
spawn_ore_vein(surface, pos, planet)
end
end
return Public_ores

View File

@ -0,0 +1,998 @@
--require "maps.chronosphere.ores"
local Ores = require "maps.chronosphere.ores"
local Specials = require "maps.chronosphere.terrain_specials"
local math_random = math.random
local math_floor = math.floor
local math_min = math.min
local math_abs = math.abs
local math_sqrt = math.sqrt
local level_depth = 960
local lake_noise_value = -0.9
local labyrinth_cell_size = 32 --valid values are 2, 4, 8, 16, 32
local Treasure = require 'maps.chronosphere.treasure'
local simplex_noise = require "utils.simplex_noise".d2
local rock_raffle = {"sand-rock-big","sand-rock-big", "rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-huge"}
local size_of_rock_raffle = #rock_raffle
local dead_tree_raffle = {"dead-dry-hairy-tree", "dead-grey-trunk", "dead-tree-desert", "dry-hairy-tree", "dry-tree"}
local tree_raffle = {"tree-01", "tree-02", "tree-02-red", "tree-03", "tree-04", "tree-05", "tree-06", "tree-06-brown", "tree-07",
"tree-08", "tree-08-brown", "tree-08-red", "tree-09", "tree-09-brown", "tree-09-red"}
local s_tree_raffle = #tree_raffle
local spawner_raffle = {"biter-spawner", "biter-spawner", "biter-spawner", "spitter-spawner"}
local worm_raffle = {
"small-worm-turret", "small-worm-turret", "medium-worm-turret", "small-worm-turret",
"medium-worm-turret", "medium-worm-turret", "big-worm-turret", "medium-worm-turret",
"big-worm-turret","big-worm-turret","behemoth-worm-turret", "big-worm-turret",
"behemoth-worm-turret","behemoth-worm-turret","behemoth-worm-turret","big-worm-turret","behemoth-worm-turret"
}
local scrap_entities = {"crash-site-assembling-machine-1-broken", "crash-site-assembling-machine-2-broken", "crash-site-assembling-machine-1-broken", "crash-site-assembling-machine-2-broken", "crash-site-lab-broken",
"medium-ship-wreck", "small-ship-wreck", "medium-ship-wreck", "small-ship-wreck", "medium-ship-wreck", "small-ship-wreck", "medium-ship-wreck", "small-ship-wreck",
"crash-site-chest-1", "crash-site-chest-2", "crash-site-chest-1", "crash-site-chest-2", "crash-site-chest-1", "crash-site-chest-2"}
local scrap_entities_index = #scrap_entities
local maze_things_raffle = {"camp", "lab", "treasure", "crashsite"}
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_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}},
["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_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}},
["cave_rivers_3"] = {{modifier = 0.002, weight = 1}, {modifier = 0.01, weight = 0.15}, {modifier = 0.05, weight = 0.01}},
["cave_rivers_4"] = {{modifier = 0.001, weight = 1}, {modifier = 0.01, weight = 0.11}, {modifier = 0.05, weight = 0.01}},
["scrapyard"] = {{modifier = 0.005, weight = 1}, {modifier = 0.01, weight = 0.35}, {modifier = 0.05, weight = 0.23}, {modifier = 0.1, weight = 0.11}},
["forest_location"] = {{modifier = 0.006, weight = 1}, {modifier = 0.01, weight = 0.25}, {modifier = 0.05, weight = 0.15}, {modifier = 0.1, weight = 0.05}},
["forest_density"] = {{modifier = 0.01, weight = 1}, {modifier = 0.05, weight = 0.5}, {modifier = 0.1, weight = 0.025}},
["ores"] = {{modifier = 0.05, weight = 1}, {modifier = 0.02, weight = 0.55}, {modifier = 0.05, weight = 0.05}},
["hedgemaze"] = {{modifier = 0.001, weight = 1}}
}
local modifiers = {
{x = 0, y = -1},{x = -1, y = 0},{x = 1, y = 0},{x = 0, y = 1}
}
local modifiers_diagonal = {
{diagonal = {x = -1, y = 1}, connection_1 = {x = -1, y = 0}, connection_2 = {x = 0, y = 1}},
{diagonal = {x = 1, y = -1}, connection_1 = {x = 1, y = 0}, connection_2 = {x = 0, y = -1}},
{diagonal = {x = 1, y = 1}, connection_1 = {x = 1, y = 0}, connection_2 = {x = 0, y = 1}},
{diagonal = {x = -1, y = -1}, connection_1 = {x = -1, y = 0}, connection_2 = {x = 0, y = -1}}
}
local function pos_to_key(position)
return tostring(position.x .. "_" .. position.y)
end
local function get_noise(name, pos, seed)
local noise = 0
local d = 0
for _, n in pairs(noises[name]) do
noise = noise + simplex_noise(pos.x * n.modifier, pos.y * n.modifier, seed) * n.weight
d = d + n.weight
seed = seed + 10000
end
noise = noise / d
return noise
end
local function get_size_of_ore(ore, planet)
local base_size = 0.04 + 0.04 * planet[1].ore_richness.factor
local final_size = 1
if planet[1].name.id == 1 and ore == "iron-ore" then --iron planet
final_size = base_size * 5
elseif planet[1].name.id == 2 and ore == "copper-ore" then --copper planet
final_size = base_size * 5
elseif planet[1].name.id == 3 and ore == "stone" then --stone planet
final_size = base_size * 5
elseif planet[1].name.id == 9 and ore == "coal" then --coal planet
final_size = base_size * 5
elseif planet[1].name.id == 5 and ore == "uranium-ore" then --uranium planet
final_size = base_size * 5
elseif planet[1].name.id == 6 then --mixed planet
final_size = base_size * 2
else
final_size = base_size / 2
end
return final_size
end
local function get_path_connections_count(cell_pos)
local connections = 0
for _, m in pairs(modifiers) do
if global.lab_cells[tostring(cell_pos.x + m.x) .. "_" .. tostring(cell_pos.y + m.y)] then
connections = connections + 1
end
end
return connections
end
local function process_labyrinth_cell(pos, seed)
local cell_position = {x = pos.x / labyrinth_cell_size, y = pos.y / labyrinth_cell_size}
local mazenoise = get_noise("hedgemaze", cell_position, seed)
if mazenoise < lake_noise_value and math_sqrt((pos.x / 32)^2 + (pos.y / 32)^2) > 65 then return false end
global.lab_cells[tostring(cell_position.x) .. "_" .. tostring(cell_position.y)] = false
for _, modifier in pairs(modifiers_diagonal) do
if global.lab_cells[tostring(cell_position.x + modifier.diagonal.x) .. "_" .. tostring(cell_position.y + modifier.diagonal.y)] then
local connection_1 = global.lab_cells[tostring(cell_position.x + modifier.connection_1.x) .. "_" .. tostring(cell_position.y + modifier.connection_1.y)]
local connection_2 = global.lab_cells[tostring(cell_position.x + modifier.connection_2.x) .. "_" .. tostring(cell_position.y + modifier.connection_2.y)]
if not connection_1 and not connection_2 then
return false
end
end
end
for _, m in pairs(modifiers) do
if get_path_connections_count({x = cell_position.x + m.x, y = cell_position.y + m.y}) >= math_random(2, 3) then return false end
end
if get_path_connections_count(cell_position) >= math_random(2, 3) then return false end
global.lab_cells[tostring(cell_position.x) .. "_" .. tostring(cell_position.y)] = true
return true
end
local function process_dangerevent_position(p, seed, tiles, entities, treasure, planet)
local scrapyard = get_noise("scrapyard", p, seed)
--Chasms
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
if noise_cave_ponds < 0.15 and noise_cave_ponds > -0.15 then
if small_caves > 0.35 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
if small_caves < -0.35 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
if scrapyard < -0.20 or scrapyard > 0.20 then
if math_random(1, 128) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 50 then
entities[#entities + 1] = {name="gun-turret", position=p, force = "scrapyard"}
end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if scrapyard < -0.38 or scrapyard > 0.38 then
if math_random(1,36) == 1 then entities[#entities + 1] = {name = scrap_entities[math_random(1, scrap_entities_index)], position = p, force = "enemy"} end
if math_random(1,6) == 1 then entities[#entities + 1] = {name="mineable-wreckage", position=p} end
return
end
return
end
local cave_ponds = get_noise("cave_ponds", p, seed)
if cave_ponds < -0.6 and scrapyard > -0.2 and scrapyard < 0.2 then
tiles[#tiles + 1] = {name = "deepwater-green", position = p}
if math_random(1,128) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
local large_caves = get_noise("large_caves", p, seed)
if scrapyard > -0.15 and scrapyard < 0.15 then
if math_floor(large_caves * 10) % 4 < 3 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
return
end
end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
tiles[#tiles + 1] = {name = "stone-path", position = p}
end
local function process_hedgemaze_position(p, seed, tiles, entities, treasure, planet, cell, things)
--local labyrinth_cell_size = 16 --valid values are 2, 4, 8, 16, 32
local biters = planet[1].name.biters
local mazenoise = get_noise("hedgemaze", {x = p.x - p.x % labyrinth_cell_size, y = p.y - p.y % labyrinth_cell_size}, seed)
if mazenoise < lake_noise_value and math_sqrt((p.x - p.x % labyrinth_cell_size)^2 + (p.y - p.y % labyrinth_cell_size)^2) > 65 then
tiles[#tiles + 1] = {name = "deepwater", position = p}
if math_random(1, 256) == 1 then entities[#entities + 1] = {name = "fish", position = p} end
return
elseif mazenoise > 0.7 then
if cell then --path
if things then
if things == "lake" and p.x % 32 > 8 and p.x % 32 < 24 and p.y % 32 > 8 and p.y % 32 < 24 then
tiles[#tiles + 1] = {name = "water", position = p}
return
elseif things == "prospect" then
if math_random(1,252 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 300 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
elseif things == "camp" then
if p.x % 32 > 12 and p.x % 32 < 20 and p.y % 32 > 12 and p.y % 32 < 20 and math_random(1,6) == 1 then
treasure[#treasure + 1] = p
end
elseif things == "crashsite" then
if math_random(1,10) == 1 then
entities[#entities + 1] = {name="mineable-wreckage", position=p}
end
elseif things == "treasure" then
local roll = math_random(1,128)
if roll == 1 then
treasure[#treasure + 1] = p
elseif roll == 2 then
entities[#entities + 1] = {name = "land-mine", position = p, force = "scrapyard"}
end
end
else
if math_random(1, 150) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 200 then
entities[#entities + 1] = {name = worm_raffle[math_random(1 + math_floor(game.forces["enemy"].evolution_factor * 8), math_floor(1 + game.forces["enemy"].evolution_factor * 16))], position = p}
end
end
tiles[#tiles + 1] = {name = "dirt-4", position = p}
else --wall
tiles[#tiles + 1] = {name = "dirt-6", position = p}
if math_random(1,3) == 1 then
entities[#entities + 1] = {name = "dead-tree-desert", position = p}
else
if math_random(1,4) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, #rock_raffle)], position = p} end
end
end
else
if cell then --path
if things then
if things == "lake" and p.x % 32 > 8 and p.x % 32 < 24 and p.y % 32 > 8 and p.y % 32 < 24 then
tiles[#tiles + 1] = {name = "water", position = p}
return
elseif things == "prospect" then
if math_random(1,252 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 300 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
elseif things == "camp" then
if p.x % 32 > 12 and p.x % 32 < 20 and p.y % 32 > 12 and p.y % 32 < 20 and math_random(1,6) == 1 then
treasure[#treasure + 1] = p
end
elseif things == "crashsite" then
if math_random(1,10) == 1 then
entities[#entities + 1] = {name="mineable-wreckage", position=p}
end
elseif things == "treasure" then
if math_random(1,128) == 1 then
treasure[#treasure + 1] = p
end
end
else
if math_random(1, 150) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 200 then
entities[#entities + 1] = {name = worm_raffle[math_random(1 + math_floor(game.forces["enemy"].evolution_factor * 8), math_floor(1 + game.forces["enemy"].evolution_factor * 16))], position = p}
end
end
tiles[#tiles + 1] = {name = "grass-1", position = p}
else --wall
tiles[#tiles + 1] = {name = "grass-2", position = p}
if math_random(1,3) == 1 then
entities[#entities + 1] = {name = "tree-04", position = p}
else
if math_random(1,4) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, #rock_raffle)], position = p} end
end
end
end
end
local function process_rocky_position(p, seed, tiles, entities, treasure, planet)
local biters = planet[1].name.biters
local noise_large_caves = get_noise("large_caves", p, seed)
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
if math_abs(noise_large_caves) > 0.7 then
tiles[#tiles + 1] = {name = "water", position = p}
if math_random(1,16) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
if math_abs(noise_large_caves) > 0.6 then
if math_random(1,16) == 1 then entities[#entities + 1] = {name="tree-02", position=p} end
end
if math_abs(noise_large_caves) > 0.5 then
tiles[#tiles + 1] = {name = "grass-2", position = p}
if math_random(1,122 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 150 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
if math_random(1, 1024) == 1 then treasure[#treasure + 1] = p end
return
end
if math_abs(noise_large_caves) > 0.375 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,5) > 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
return
end
--Chasms
if noise_cave_ponds < 0.25 and noise_cave_ponds > -0.25 then
if small_caves > 0.75 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
if small_caves < -0.75 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
if small_caves > -0.25 and small_caves < 0.25 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
local roll = math_random(1,1000)
if roll > 830 then
entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p}
elseif roll > 820 and math_sqrt(p.x * p.x + p.y * p.y) > 150 then
entities[#entities + 1] = {name = worm_raffle[math_random(1 + math_floor(game.forces["enemy"].evolution_factor * 8), math_floor(1 + game.forces["enemy"].evolution_factor * 16))], position = p}
else
end
if math_random(1, 1024) == 1 then treasure[#treasure + 1] = p end
return
end
if noise_large_caves > -0.28 and noise_large_caves < 0.28 then
--Main Rock 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 = "dirt-" .. math_floor(no_rocks_2 * 8) % 2 + 5, 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}
if math_random(1,100) > 50 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
return
end
tiles[#tiles + 1] = {name = "out-of-map", position = p}
end
local function process_forest_position(p, seed, tiles, entities, treasure, planet)
local biters = planet[1].name.biters
local noise_forest_location = get_noise("forest_location", p, seed)
if noise_forest_location > 0.095 then
if noise_forest_location > 0.6 then
if math_random(1,100) > 42 then entities[#entities + 1] = {name = "tree-08-brown", position = p} end
else
if math_random(1,100) > 42 then entities[#entities + 1] = {name = "tree-01", position = p} end
end
return
else
if math_random(1,152 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 250 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
end
if noise_forest_location < -0.095 then
if noise_forest_location < -0.6 then
if math_random(1,100) > 42 then entities[#entities + 1] = {name = "tree-04", position = p} end
else
if math_random(1,100) > 42 then entities[#entities + 1] = {name = "tree-02-red", position = p} end
end
return
else
if math_random(1,152 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 250 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
end
end
local function process_river_position(p, seed, tiles, entities, treasure, planet)
local biters = planet[1].name.biters
local richness = math_random(50 + 20 * global.objective.chronojumps, 100 + 20 * global.objective.chronojumps) * planet[1].ore_richness.factor * 0.5
local iron_size = get_size_of_ore("iron-ore", planet) * 3
local copper_size = get_size_of_ore("copper-ore", planet) * 3
local stone_size = get_size_of_ore("stone", planet) * 3
local coal_size = get_size_of_ore("coal", planet) * 4
if not biters then biters = 4 end
local large_caves = get_noise("large_caves", p, seed)
local cave_rivers = get_noise("cave_rivers", p, seed)
local ores = get_noise("ores", p, seed)
local noise_forest_location = get_noise("forest_location", p, seed)
--Chasms
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
if noise_cave_ponds < 0.45 and noise_cave_ponds > -0.45 then
if small_caves > 0.75 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
if small_caves < -0.75 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
if large_caves > -0.05 and large_caves < 0.05 and cave_rivers < 0.25 then
tiles[#tiles + 1] = {name = "water-green", position = p}
if math_random(1,128) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
elseif large_caves > -0.20 and large_caves < 0.20 and math_abs(cave_rivers) < 0.95 then
if ores > -coal_size and ores < coal_size then
entities[#entities + 1] = {name = "coal", position = p, amount = richness}
end
end
if cave_rivers > -0.70 and cave_rivers < 0.70 then
if math_random(1,48) == 1 then entities[#entities + 1] = {name = "tree-0" .. math_random(1, 9), position=p} end
if cave_rivers > -0.05 and cave_rivers < 0.05 then
if ores > -iron_size and ores < iron_size then
entities[#entities + 1] = {name = "iron-ore", position = p, amount = richness}
end
elseif cave_rivers > -0.10 and cave_rivers < 0.10 then
if ores > -copper_size and ores < copper_size then
entities[#entities + 1] = {name = "copper-ore", position = p, amount = richness}
end
end
else
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if ores > -stone_size and ores < stone_size then
entities[#entities + 1] = {name = "stone", position = p, amount = richness}
end
if math_random(1,52 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 200 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
end
if noise_forest_location > 0.9 then
local tree = tree_raffle[math_random(1, s_tree_raffle)]
if math_random(1,100) > 42 then entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p} end
return
end
if noise_forest_location < -0.9 then
if math_random(1,100) > 42 then entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p} end
return
end
end
local function process_biter_position(p, seed, tiles, entities, treasure, planet)
local scrapyard = get_noise("scrapyard", p, seed)
local noise_forest_location = get_noise("forest_location", p, seed)
local large_caves = get_noise("large_caves", p, seed)
local biters = planet[1].name.biters
local ore_size = planet[1].ore_richness.factor
local handicap = 0
if global.objective.chronojumps < 5 then handicap = 150 end
if scrapyard < -0.75 or scrapyard > 0.75 then
if math_random(1,52 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 150 + handicap then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
end
if scrapyard > -0.05 - 0.01 * ore_size and scrapyard < 0.05 + 0.01 * ore_size then
if math_random(1,20) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
end
if scrapyard + 0.5 > -0.1 - 0.1 * planet[1].name.moisture and scrapyard + 0.5 < 0.1 + 0.1 * planet[1].name.moisture then
local treetypes = tree_raffle[math_random(1, s_tree_raffle)]
if planet[1].name.id == 14 then treetypes = dead_tree_raffle[math_random(1, 5)] end --lava planet
if math_random(1,100) > 42 - handicap / 6 then
if math_random(1,800) == 1 then
treasure[#treasure + 1] = p
else
entities[#entities + 1] = {name = treetypes , position = p}
end
end
end
if scrapyard > -0.10 and scrapyard < 0.10 then
if math_floor(large_caves * 10) % 4 < 3 then
local jumps = global.objective.chronojumps * 5
if global.objective.chronojumps > 20 then jumps = 100 end
local roll = math_random(1,200 - jumps - biters)
if math_sqrt(p.x * p.x + p.y * p.y) > 200 + handicap then
if roll == 1 then
entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p}
elseif roll == 2 then
entities[#entities + 1] = {name = worm_raffle[math_random(1 + math_floor(game.forces["enemy"].evolution_factor * 8), math_floor(1 + game.forces["enemy"].evolution_factor * 16))], position = p}
elseif roll == 3 then
--if math_random(1, 1024) == 1 then treasure[#treasure + 1] = p end
end
return
end
end
end
end
local function process_scrapyard_position(p, seed, tiles, entities, treasure, planet)
local scrapyard = get_noise("scrapyard", p, seed)
local biters = planet[1].name.biters
--Chasms
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
if noise_cave_ponds < 0.15 and noise_cave_ponds > -0.15 then
if small_caves > 0.35 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
if small_caves < -0.35 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
if scrapyard < -0.25 or scrapyard > 0.25 then
if math_random(1, 256) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 50 then
entities[#entities + 1] = {name="gun-turret", position=p, force = "scrapyard"}
end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if scrapyard < -0.55 or scrapyard > 0.55 then
if math_random(1,40) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 150 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
return
end
if scrapyard + 0.5 > -0.05 - 0.1 * planet[1].name.moisture and scrapyard + 0.5 < 0.05 + 0.1 * planet[1].name.moisture then
if math_random(1,100) > 42 then entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p} end
end
if scrapyard < -0.28 or scrapyard > 0.28 then
if math_random(1,48) == 1 then entities[#entities + 1] = {name = scrap_entities[math_random(1, scrap_entities_index)], position = p, force = "enemy"} end
if math_random(1,3) == 1 then entities[#entities + 1] = {name="mineable-wreckage", position=p} end
return
end
return
end
local cave_ponds = get_noise("cave_ponds", p, seed)
if cave_ponds < -0.6 and scrapyard > -0.2 and scrapyard < 0.2 then
tiles[#tiles + 1] = {name = "deepwater-green", position = p}
if math_random(1,128) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
local large_caves = get_noise("large_caves", p, seed)
if scrapyard > -0.15 and scrapyard < 0.15 then
if math_floor(large_caves * 10) % 4 < 3 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
local jumps = global.objective.chronojumps * 5
if global.objective.chronojumps > 20 then jumps = 100 end
if math_random(1,200 - jumps) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 150 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
return
end
end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
tiles[#tiles + 1] = {name = "stone-path", position = p}
end
local function process_swamp_position(p, seed, tiles, entities, treasure, planet)
local scrapyard = get_noise("scrapyard", p, seed)
local biters = planet[1].name.biters
if scrapyard < -0.70 or scrapyard > 0.70 then
tiles[#tiles + 1] = {name = "grass-3", position = p}
if math_random(1,40) == 1 then treasure[#treasure + 1] = p end
return
end
if scrapyard < -0.65 or scrapyard > 0.65 then
tiles[#tiles + 1] = {name = "water-green", position = p}
return
end
if math_abs(scrapyard) > 0.50 and math_abs(scrapyard) < 0.65 then
if math_random(1,70) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 140 then entities[#entities + 1] = {name = worm_raffle[math_random(1 + math_floor(game.forces["enemy"].evolution_factor * 8), math_floor(1 + game.forces["enemy"].evolution_factor * 16))], position = p}end
tiles[#tiles + 1] = {name = "water-mud", position = p}
return
end
if math_abs(scrapyard) > 0.35 and math_abs(scrapyard) < 0.50 then
if math_random(1,140) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 140 then entities[#entities + 1] = {name = worm_raffle[math_random(1 + math_floor(game.forces["enemy"].evolution_factor * 8), math_floor(1 + game.forces["enemy"].evolution_factor * 16))], position = p}end
tiles[#tiles + 1] = {name = "water-shallow", position = p}
return
end
if scrapyard > -0.15 and scrapyard < 0.15 then
if math_random(1,100) > 58 then
entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p}
else
if math_random(1,8) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
end
tiles[#tiles + 1] = {name = "grass-1", position = p}
return
end
if math_random(1, 160) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 150 then
entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p}
end
tiles[#tiles + 1] = {name = "grass-2", position = p}
end
local function process_fish_position(p, seed, tiles, entities, treasure, planet)
local body_radius = 1984 --3072
local body_square_radius = body_radius ^ 2
local body_center_position = {x = 0, y = 0}
local body_spacing = math_floor(body_radius * 0.82)
local body_circle_center_1 = {x = body_center_position.x, y = body_center_position.y - body_spacing}
local body_circle_center_2 = {x = body_center_position.x, y = body_center_position.y + body_spacing}
local fin_radius = 200
local square_fin_radius = fin_radius ^ 2
local fin_circle_center_1 = {x = -600, y = 0}
local fin_circle_center_2 = {x = -600 - 120, y = 0}
--if math_abs(p.y) > 480 and p.x <= 160 and p.x > body_center_position.x then return true end
--Main Fish Body
local distance_to_center_1 = ((p.x - body_circle_center_1.x)^2 + (p.y - body_circle_center_1.y)^2)
local distance_to_center_2 = ((p.x - body_circle_center_2.x)^2 + (p.y - body_circle_center_2.y)^2)
local distance_to_fin_1 = ((p.x - fin_circle_center_1.x)^2 + (p.y - fin_circle_center_1.y)^2)
local distance_to_fin_2 = ((p.x - fin_circle_center_2.x)^2 + (p.y - fin_circle_center_2.y)^2)
local eye_center = {x = -500, y = -150}
if distance_to_center_1 < body_square_radius and distance_to_center_2 < body_square_radius then
if p.x < -600 and p.x > -1090 and p.y < 64 and p.y > -64 then --mouth
local noise = simplex_noise(p.x * 0.006, 0, seed) * 20
if p.y <= 12 + noise and p.y >= -12 + noise then
tiles[#tiles + 1] = {name = "water", position = p}
else
tiles[#tiles + 1] = {name = "grass-1", position = p}
local roll = math_random(1,500)
if roll < 4 and p.x > -800 then
entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p}
elseif roll == 5 and p.x > -800 then
entities[#entities + 1] = {name = "behemoth-worm-turret", position = p}
elseif roll == 6 then
entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p}
end
end
else
local distance = math_sqrt(((eye_center.x - p.x) ^ 2) + ((eye_center.y - p.y) ^ 2))
if distance < 33 and distance >= 15 then --eye
tiles[#tiles + 1 ] = {name = "water-green", position = p}
elseif distance < 15 then --eye
tiles[#tiles + 1] = {name = "out-of-map", position = p}
else --rest
tiles[#tiles + 1 ] = {name = "grass-1", position = p}
local roll = math_random(1,500)
if roll < 4 and p.x > -800 then
entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p}
elseif roll == 5 and p.x > -800 then
entities[#entities + 1] = {name = "behemoth-worm-turret", position = p}
elseif roll == 6 then
entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p}
end
end
end
-- elseif distance_to_fin_2 < square_fin_radius and distance_to_fin_1 + math_abs(simplex_noise(0, p.y * 0.075, seed) * 32000) > square_fin_radius then
-- tiles[#tiles + 1 ] = {name = "dirt-7", position = p}
else
if p.x > 800 and math_abs(p.y) < p.x - 800 then --tail
tiles[#tiles + 1 ] = {name = "grass-1", position = p}
local roll = math_random(1,500)
if roll < 4 and p.x > -800 then
entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p}
elseif roll == 5 and p.x > -800 then
entities[#entities + 1] = {name = "behemoth-worm-turret", position = p}
elseif roll == 6 then
entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p}
end
else
tiles[#tiles + 1 ] = {name = "out-of-map", position = p}
end
end
end
local levels = {
process_level_1_position,
process_dangerevent_position,
process_hedgemaze_position,
process_rocky_position,
process_forest_position,
process_river_position,
process_biter_position,
process_scrapyard_position,
process_swamp_position,
process_fish_position,
}
local entity_functions = {
["turret"] = function(surface, entity) surface.create_entity(entity) end,
["simple-entity"] = function(surface, entity) surface.create_entity(entity) end,
["ammo-turret"] = function(surface, entity)
local e = surface.create_entity(entity)
e.insert({name = "uranium-rounds-magazine", count = math_random(16, 64)})
end,
["container"] = function(surface, entity)
Treasure(surface, entity.position, entity.name)
end,
["lab"] = function(surface, entity)
local e = surface.create_entity(entity)
local evo = 1 + math_min(math_floor(global.objective.chronojumps / 4), 4)
local research = {
{"automation-science-pack", "logistic-science-pack"},
{"automation-science-pack", "logistic-science-pack", "military-science-pack"},
{"automation-science-pack", "logistic-science-pack", "military-science-pack", "chemical-science-pack"},
{"automation-science-pack", "logistic-science-pack", "military-science-pack", "chemical-science-pack", "production-science-pack"},
{"automation-science-pack", "logistic-science-pack", "military-science-pack", "chemical-science-pack", "production-science-pack", "utility-science-pack"}
}
for _,science in pairs(research[evo]) do
e.insert({name = science, count = math_random(math_min(32 + global.objective.chronojumps, 100), math_min(64 + global.objective.chronojumps, 200))})
end
end,
}
local function get_replacement_tile(surface, position)
for i = 1, 128, 1 do
local vectors = {{0, i}, {0, i * -1}, {i, 0}, {i * -1, 0}}
table.shuffle_table(vectors)
for k, v in pairs(vectors) do
local tile = surface.get_tile(position.x + v[1], position.y + v[2])
if not tile.collides_with("resource-layer") then return tile.name end
end
end
if global.objective.planet[1].name.id == 18 then return "grass-2" end
return "grass-1"
end
local function replace_water(surface, left_top)
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
if surface.get_tile(p).collides_with("resource-layer") then
surface.set_tiles({{name = get_replacement_tile(surface, p), position = p}}, true)
end
end
end
end
local function forest_chunk(surface, left_top, level, planet)
local tiles = {}
local entities = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
local process_level = levels[level]
for y = 0.5, 31.5, 1 do
for x = 0.5, 31.5, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet)
end
end
surface.set_tiles(tiles, true)
for _, entity in pairs(entities) do
if surface.can_place_entity(entity) then
local e = surface.create_entity(entity)
if e.name == "biter-spawner" or e.name == "spitter-spawner" or e.name == "small-worm-turret" or e.name == "medium-worm-turret" or e.name == "big-worm-turret" or e.name == "behemoth-worm-turret" then
if math_abs(e.position.x) > 420 or math_abs(e.position.y) > 420 then e.destructible = false end
end
end
end
end
local function biter_chunk(surface, left_top, level, planet)
local tiles = {}
local entities = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
local process_level = levels[level]
for y = 0, 31, 1 do
for x = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet)
end
end
for _, p in pairs(treasure) do
local name = "wooden-chest"
if math_random(1, 6) == 1 then name = "iron-chest" end
Treasure(surface, p, name)
end
surface.set_tiles(tiles, true)
for _, entity in pairs(entities) do
if surface.can_place_entity(entity) then
local e = surface.create_entity(entity)
if e.name == "biter-spawner" or e.name == "spitter-spawner" or e.name == "small-worm-turret" or e.name == "medium-worm-turret" or e.name == "big-worm-turret" or e.name == "behemoth-worm-turret" then
if math_abs(e.position.x) > 420 or math_abs(e.position.y) > 420 then e.destructible = false end
end
end
end
end
local function empty_chunk(surface, left_top, level, planet)
local tiles = {}
local entities = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
local process_level = levels[level]
for y = 0, 31, 1 do
for x = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
if planet[1].name.id == 16 then
process_level(p, seed, tiles, entities, treasure, planet, true, nil)
else
process_level(p, seed, tiles, entities, treasure, planet)
end
end
end
surface.set_tiles(tiles, true)
replace_water(surface, left_top)
if planet[1].name.id == 18 and left_top.y > 31 and left_top.x > 31 then
for x = 1, 5, 1 do
for y = 1, 5, 1 do
local pos = {x = left_top.x + x, y = left_top.y + y}
surface.set_tiles({{name = "deepwater-green", position = pos}})
end
end
end
end
local function danger_chunk(surface, left_top, level, planet)
local tiles = {}
local entities = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
local process_level = levels[level]
for y = 0, 31, 1 do
for x = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet)
end
end
surface.set_tiles(tiles, true)
replace_water(surface, left_top)
Specials.danger_event(surface, left_top)
end
local function fish_market(surface, left_top, level, planet)
local tiles = {}
local entities = {}
local seed = surface.map_gen_settings.seed
local process_level = levels[level]
for y = 0, 31, 1 do
for x = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet)
end
end
surface.set_tiles(tiles, true)
Specials.fish_market(surface, left_top)
end
local function fish_chunk(surface, left_top, level, planet)
local tiles = {}
local entities = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
local process_level = levels[level]
for y = 0, 31, 1 do
for x = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet)
end
end
surface.set_tiles(tiles, true)
for _, p in pairs(treasure) do
local name = "wooden-chest"
if math_random(1, 6) == 1 then name = "iron-chest" end
Treasure(surface, p, name)
end
for _, entity in pairs(entities) do
if entity_functions[game.entity_prototypes[entity.name].type] then
entity_functions[game.entity_prototypes[entity.name].type](surface, entity)
else
if surface.can_place_entity(entity) then
local e = surface.create_entity(entity)
end
end
end
end
local function normal_chunk(surface, left_top, level, planet)
local tiles = {}
local entities = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
local process_level = levels[level]
if planet[1].name.id == 16 then
local cell = false
local roll = math_random(1,20)
local things = nil
if roll == 1 then
things = maze_things_raffle[math_random(1, 4)]
elseif roll == 2 then
things = "lake"
elseif roll > 10 then
things = "prospect"
end
if process_labyrinth_cell(left_top, seed) then
cell = true
if things == "prospect" then
Ores.prospect_ores(nil, surface, {x = left_top.x + 16, y = left_top.y + 16})
elseif things == "camp" or things == "lab" then
local positions = {
{x = left_top.x + 9, y = left_top.y + 9},{x = left_top.x + 9, y = left_top.y + 16},{x = left_top.x + 9, y = left_top.y + 23},
{x = left_top.x + 16, y = left_top.y + 9},{x = left_top.x + 16, y = left_top.y + 23},
{x = left_top.x + 23, y = left_top.y + 9},{x = left_top.x + 23, y = left_top.y + 16},{x = left_top.x + 23, y = left_top.y + 23}
}
for i = 1, 8, 1 do
entities[#entities + 1] = {name = "gun-turret", position = positions[i], force = "scrapyard"}
end
if things == "lab" then
entities[#entities + 1] = {name = "lab", position = {x = left_top.x + 15, y = left_top.y + 15}, force = "neutral"}
end
end
end
for y = 0, 31, 1 do
for x = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet, cell, things)
end
end
else
for y = 0, 31, 1 do
for x = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet)
end
end
end
surface.set_tiles(tiles, true)
for _, p in pairs(treasure) do
local name = "wooden-chest"
if math_random(1, 6) == 1 then name = "iron-chest" end
Treasure(surface, p, name)
end
for _, entity in pairs(entities) do
if entity_functions[game.entity_prototypes[entity.name].type] then
entity_functions[game.entity_prototypes[entity.name].type](surface, entity)
else
if surface.can_place_entity(entity) then
local e = surface.create_entity(entity)
if e.name == "biter-spawner" or e.name == "spitter-spawner" or e.name == "small-worm-turret" or e.name == "medium-worm-turret" or e.name == "big-worm-turret" or e.name == "behemoth-worm-turret" then
if math_abs(e.position.x) > 420 or math_abs(e.position.y) > 420 then e.destructible = false end
end
end
end
end
end
local function process_chunk(surface, left_top)
if not surface then return end
if not surface.valid then return end
local planet = global.objective.planet
if planet[1].name.id == 17 then level_depth = 2176 end
if left_top.x >= level_depth * 0.5 or left_top.y >= level_depth * 0.5 then return end
if left_top.x < level_depth * -0.5 or left_top.y < level_depth * -0.5 then return end
--if left_top.y >= 0 then replace_water(surface, left_top) end
--if left_top.y > 32 then game.forces.player.chart(surface, {{left_top.x, left_top.y},{left_top.x + 31, left_top.y + 31}}) end
-- if left_top.y == -128 and left_top.x == -128 then
-- local p = global.locomotive.position
-- for _, entity in pairs(surface.find_entities_filtered({area = {{p.x - 3, p.y - 4},{p.x + 3, p.y + 10}}, type = "simple-entity"})) do entity.destroy() end
-- end
local id = planet[1].name.id --from chronobubbles
if id == 10 then --scrapyard
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 8, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then normal_chunk(surface, left_top, 8, planet) return end
elseif id == 13 then --river planet
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 6, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then normal_chunk(surface, left_top, 6, planet) return end
elseif id == 12 then --choppy planet
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 5, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then forest_chunk(surface, left_top, 5, planet) return end
elseif id == 11 then --rocky planet
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 4, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then normal_chunk(surface, left_top, 4, planet) return end
elseif id == 14 then --lava planet
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 7, planet) end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then biter_chunk(surface, left_top, 7, planet) end
replace_water(surface, left_top)
return
elseif id == 16 then --hedge maze
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 3, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then normal_chunk(surface, left_top, 3, planet) return end
elseif id == 17 then --fish market
if math_abs(left_top.y) <= 31 and math_abs(left_top.x - 864) <= 31 then fish_market(surface, left_top, 10, planet) return end
fish_chunk(surface, left_top, 10, planet)
elseif id == 18 then --swamp planet
if math_abs(left_top.y) <= 63 and math_abs(left_top.x) <= 63 then empty_chunk(surface, left_top, 9, planet) return end
if math_abs(left_top.y) > 63 or math_abs(left_top.x) > 63 then normal_chunk(surface, left_top, 9, planet) return end
elseif id == 19 then --danger event
if math_abs(left_top.y) <= 63 and math_abs(left_top.x) <= 63 then empty_chunk(surface, left_top, 2, planet) return end
if math_abs(left_top.y) == 448 and math_abs(left_top.x) == 448 then danger_chunk(surface, left_top, 2, planet) return end
if math_abs(left_top.y) > 63 or math_abs(left_top.x) > 63 then normal_chunk(surface, left_top, 2, planet) return end
else
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 7, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then biter_chunk(surface, left_top, 7, planet) return end
end
--if left_top.y > 96 then out_of_map(surface, left_top) return end
--if left_top.y > 64 then biter_chunk(surface, left_top) return end
--if left_top.y >= 0 then border_chunk(surface, left_top) return end
--rock_chunk(surface, left_top)
--return
end
local function on_chunk_generated(event)
if string.sub(event.surface.name, 0, 12) ~= "chronosphere" then return end
process_chunk(event.surface, event.area.left_top)
end
local event = require 'utils.event'
event.add(defines.events.on_chunk_generated, on_chunk_generated)

View File

@ -0,0 +1,102 @@
local Public_terrain = {}
function Public_terrain.danger_event(surface, left_top)
local silo = surface.create_entity({name = "rocket-silo", force = "enemy", position = {x = left_top.x + 16, y = left_top.y + 16}})
local pole = surface.create_entity({name = "medium-electric-pole", position = {x = left_top.x + 12, y = left_top.y + 11}, force = "scrapyard", create_build_effect_smoke = false})
local silo_text = rendering.draw_text{
text = "Nuclear silo",
surface = surface,
target = pole,
target_offset = {5, -2.5},
color = {r = 0.98, g = 0, b = 0},
scale = 1.00,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
local countdown_text = rendering.draw_text{
text = " ",
surface = surface,
target = pole,
target_offset = {5, -1.5},
color = {r = 0.98, g = 0, b = 0},
scale = 1.00,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
silo.get_module_inventory().insert("effectivity-module-3")
silo.rocket_parts = 100
--silo.get_module_inventory().insert("effectivity-module-3")
local combinator = surface.create_entity({name = "constant-combinator", position = {x = left_top.x + 11, y = left_top.y + 10}, force = "player", create_build_effect_smoke = false})
local speaker = surface.create_entity({name = "programmable-speaker", position = {x = left_top.x + 11, y = left_top.y + 11}, force = "player", create_build_effect_smoke = false,
parameters = {playback_volume = 0.6, playback_globally = true, allow_polyphony = false},
alert_parameters = {show_alert = true, show_on_map = true, icon_signal_id = {type = "item", name = "atomic-bomb"}, alert_message = "Nuclear missile silo detected!" }})
combinator.connect_neighbour({wire = defines.wire_type.green, target_entity = speaker})
local rules = combinator.get_or_create_control_behavior()
local rules2 = speaker.get_or_create_control_behavior()
rules.set_signal(1, {signal = {type = "virtual", name = "signal-A"}, count = 1})
rules2.circuit_condition = {condition = {first_signal = {type = "virtual", name = "signal-A"}, second_constant = 0, comparator = ">"}}
rules2.circuit_parameters = {signal_value_is_pitch = false, instrument_id = 0, note_id = 6}
local solar = surface.create_entity({name = "solar-panel", position = {x = left_top.x + 14, y = left_top.y + 10}, force = "scrapyard", create_build_effect_smoke = false})
local acu = surface.create_entity({name = "accumulator", position = {x = left_top.x + 14, y = left_top.y + 8}, force = "scrapyard", create_build_effect_smoke = false})
acu.energy = 5000000
speaker.minable = false
speaker.destructible = false
speaker.operable = false
combinator.minable = false
combinator.destructible = false
combinator.operable = false
solar.destructible = false
pole.destructible = false
acu.destructible = false
global.objective.dangers[#global.objective.dangers + 1] = {silo = silo, speaker = speaker, combinator = combinator, solar = solar,acu = acu, pole = pole, destroyed = false, text = silo_text, timer = countdown_text}
end
function Public_terrain.fish_market(surface, left_top)
local market = surface.create_entity({name = "market", force = "player", position = {x = left_top.x + 16, y = left_top.y + 16}})
market.destructible = false
market.operable = false
market.minable = false
local repair_text = rendering.draw_text{
text = "Fish Market",
surface = surface,
target = market,
target_offset = {0, -2.5},
color = global.locomotive.color,
scale = 1.00,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
local fishchest = surface.create_entity({name = "compilatron-chest", force = "player", position = {x = left_top.x + 11, y = left_top.y + 16}})
fishchest.destructible = false
fishchest.minable = false
fishchest.operable = false
global.fishchest = fishchest
local repair_text = rendering.draw_text{
text = "Deposit fish here",
surface = surface,
target = fishchest,
target_offset = {0, -2.5},
color = global.locomotive.color,
scale = 0.75,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
local inserter = surface.create_entity({name = "fast-inserter", force = "player", position = {x = left_top.x + 10, y = left_top.y + 16}, direction = defines.direction.west})
inserter.destructible = false
inserter.minable = false
inserter.operable = false
inserter.rotatable = false
local track = surface.create_entity({name = "straight-rail", force = "player", position = {x = left_top.x + 8, y = left_top.y + 16}})
track.destructible = false
track.minable = false
end
return Public_terrain

View File

@ -0,0 +1,258 @@
local Public_tick = {}
local math_random = math.random
local math_floor = math.floor
local math_ceil = math.ceil
local math_min = math.min
function Public_tick.check_chronoprogress()
local objective = global.objective
if objective.planet[1].name.id == 19 then
if objective.passivetimer == 10 then
game.print({"chronosphere.message_danger1"}, {r=0.98, g=0.66, b=0.22})
game.print({"chronosphere.message_danger2"}, {r=0.98, g=0.66, b=0.22})
elseif objective.passivetimer == 25 then
game.print({"chronosphere.message_danger3"}, {r=0.98, g=0, b=0})
elseif objective.passivetimer == 30 then
game.print({"chronosphere.message_danger4"}, {r=0.98, g=0, b=0})
end
end
if objective.chronotimer == objective.chrononeeds - 180 then
game.print({"chronosphere.message_jump180"}, {r=0.98, g=0.66, b=0.22})
elseif objective.chronotimer == objective.chrononeeds - 60 then
game.print({"chronosphere.message_jump60"}, {r=0.98, g=0.66, b=0.22})
elseif objective.chronotimer == objective.chrononeeds - 30 then
game.print({"chronosphere.message_jump30"}, {r=0.98, g=0.66, b=0.22})
elseif objective.chronotimer >= objective.chrononeeds - 10 and objective.chrononeeds - objective.chronotimer > 0 then
game.print("Comfylatron: Jump in " .. objective.chrononeeds - objective.chronotimer .. " seconds!", {r=0.98, g=0.66, b=0.22})
end
if objective.chronotimer >= objective.chrononeeds then
return true
end
return false
end
function Public_tick.charge_chronosphere()
if not global.acumulators then return end
local objective = global.objective
if not objective.chronotimer then return end
if objective.chronotimer < 20 then return end
if objective.planet[1].name.id == 17 or objective.planet[1].name.id == 19 then return end
local acus = global.acumulators
if #acus < 1 then return end
for i = 1, #acus, 1 do
if not acus[i].valid then return end
local energy = acus[i].energy
if energy > 3010000 and objective.chronotimer < objective.chrononeeds - 182 and objective.chronotimer > 130 then
acus[i].energy = acus[i].energy - 3000000
objective.chronotimer = objective.chronotimer + 1
game.surfaces[global.active_surface_index].pollute(global.locomotive.position, (10 + 2 * objective.chronojumps) * (4 / (objective.upgrades[2] / 2 + 1)) * global.difficulty_vote_value)
end
end
end
function Public_tick.transfer_pollution()
local surface = game.surfaces["cargo_wagon"]
if not surface then return end
local pollution = surface.get_total_pollution() * (3 / (global.objective.upgrades[2] / 3 + 1)) * global.difficulty_vote_value
game.surfaces[global.active_surface_index].pollute(global.locomotive.position, pollution)
surface.clear_pollution()
end
function Public_tick.boost_evolution()
local objective = global.objective
if objective.passivetimer > objective.chrononeeds * 0.50 and objective.chronojumps > 5 then
local evolution = game.forces.enemy.evolution_factor
evolution = evolution + (evolution / 500) * global.difficulty_vote_value
if evolution > 1 then evolution = 1 end
game.forces.enemy.evolution_factor = evolution
end
end
function Public_tick.move_items()
if not global.comfychests then return end
if not global.comfychests2 then return end
if global.objective.game_lost == true then return end
local input = global.comfychests
local output = global.comfychests2
for i = 1, 24, 1 do
if not input[i].valid then return end
if not output[i].valid then return end
local input_inventory = input[i].get_inventory(defines.inventory.chest)
local output_inventory = output[i].get_inventory(defines.inventory.chest)
input_inventory.sort_and_merge()
output_inventory.sort_and_merge()
for ii = 1, #input_inventory, 1 do
if input_inventory[ii].valid_for_read then
local count = output_inventory.insert(input_inventory[ii])
input_inventory[ii].count = input_inventory[ii].count - count
end
end
end
end
function Public_tick.output_items()
if global.objective.game_lost == true then return end
if not global.outchests then return end
if not global.locomotive_cargo[2] then return end
if not global.locomotive_cargo[3] then return end
if global.objective.upgrades[8] ~= 1 then return end
local wagon = {
[1] = global.locomotive_cargo[2].get_inventory(defines.inventory.cargo_wagon),
[2] = global.locomotive_cargo[3].get_inventory(defines.inventory.cargo_wagon)
}
for i = 1, 4, 1 do
if not global.outchests[i].valid then return end
local inv = global.outchests[i].get_inventory(defines.inventory.chest)
inv.sort_and_merge()
for ii = 1, #inv, 1 do
if inv[ii].valid_for_read then
local count = wagon[math_ceil(i/2)].insert(inv[ii])
inv[ii].count = inv[ii].count - count
end
end
end
end
function Public_tick.repair_train()
local objective = global.objective
if not game.surfaces["cargo_wagon"] then return 0 end
if objective.game_lost == true then return 0 end
local count = 0
local inv = global.upgradechest[0].get_inventory(defines.inventory.chest)
if objective.health < objective.max_health then
count = inv.get_item_count("repair-pack")
count = math_min(count, objective.upgrades[6] + 1, math_ceil((objective.max_health - objective.health) / 150))
if count > 0 then inv.remove({name = "repair-pack", count = count}) end
end
return count * -150
end
function Public_tick.spawn_poison()
local surface = game.surfaces[global.active_surface_index]
local random_x = math_random(-460,460)
local random_y = math_random(-460,460)
local tile = surface.get_tile(random_x, random_y)
if not tile.valid then return end
if tile.name == "water-shallow" or tile.name == "water-mud" then
surface.create_entity({name = "poison-cloud", position = {x = random_x, y = random_y}})
surface.create_entity({name = "poison-cloud", position = {x = random_x + 2, y = random_y + 2}})
surface.create_entity({name = "poison-cloud", position = {x = random_x - 2, y = random_y - 2}})
surface.create_entity({name = "poison-cloud", position = {x = random_x + 2, y = random_y - 2}})
surface.create_entity({name = "poison-cloud", position = {x = random_x - 2, y = random_y + 2}})
end
end
local function launch_nukes()
local surface = game.surfaces[global.active_surface_index]
local objective = global.objective
if objective.dangers and #objective.dangers > 1 then
for i = 1, #objective.dangers, 1 do
if objective.dangers[i].destroyed == false then
local fake_shooter = surface.create_entity({name = "character", position = objective.dangers[i].silo.position, force = "enemy"})
surface.create_entity({name = "atomic-rocket", position = objective.dangers[i].silo.position, force = "enemy", speed = 1, max_range = 800, target = global.locomotive, source = fake_shooter})
game.print({"chronosphere.message_nuke"}, {r=0.98, g=0, b=0})
end
end
end
end
function Public_tick.dangertimer()
local objective = global.objective
local timer = objective.dangertimer
if timer == 0 then return end
if objective.planet[1].name.id == 19 then
timer = timer - 1
if objective.dangers and #objective.dangers > 0 then
for i = 1, #objective.dangers, 1 do
if objective.dangers[i].destroyed == false then
if timer == 15 then
objective.dangers[i].silo.launch_rocket()
objective.dangers[i].silo.rocket_parts = 100
end
rendering.set_text(objective.dangers[i].timer, math_floor(timer / 60) .. " min, " .. timer % 60 .. " s")
end
end
end
else
timer = 1200
end
if timer < 0 then timer = 0 end
if timer == 0 then
launch_nukes()
timer = 90
end
objective.dangertimer = timer
end
function Public_tick.offline_players()
local objective = global.objective
if objective.chronotimer > objective.chrononeeds - 182 or objective.passivetimer < 30 then return end
local current_tick = game.tick
local players = objective.offline_players
local surface = game.surfaces[global.active_surface_index]
if #players > 0 then
--log("nonzero offline players")
local later = {}
for i = 1, #players, 1 do
if players[i] and game.players[players[i].index] and game.players[players[i].index].connected then
--game.print("deleting already online character from list")
players[i] = nil
else
if players[i] and players[i].tick < game.tick - 54000 then
--log("spawning corpse")
local player_inv = {}
local items = {}
player_inv[1] = game.players[players[i].index].get_inventory(defines.inventory.character_main)
player_inv[2] = game.players[players[i].index].get_inventory(defines.inventory.character_armor)
player_inv[3] = game.players[players[i].index].get_inventory(defines.inventory.character_guns)
player_inv[4] = game.players[players[i].index].get_inventory(defines.inventory.character_ammo)
player_inv[5] = game.players[players[i].index].get_inventory(defines.inventory.character_trash)
local e = surface.create_entity({name = "character", position = game.forces.player.get_spawn_position(surface), force = "neutral"})
local inv = e.get_inventory(defines.inventory.character_main)
for ii = 1, 5, 1 do
if player_inv[ii].valid then
for iii = 1, #player_inv[ii], 1 do
if player_inv[ii][iii].valid then
items[#items + 1] = player_inv[ii][iii]
end
end
end
end
if #items > 0 then
for item = 1, #items, 1 do
if items[item].valid then
inv.insert(items[item])
end
end
game.print({"chronosphere.message_accident"}, {r=0.98, g=0.66, b=0.22})
e.die("neutral")
else
e.destroy()
end
for ii = 1, 5, 1 do
if player_inv[ii].valid then
player_inv[ii].clear()
end
end
players[i] = nil
else
later[#later + 1] = players[i]
end
end
end
players = {}
if #later > 0 then
for i = 1, #later, 1 do
players[#players + 1] = later[i]
end
end
objective.offline_players = players
end
end
return Public_tick

View File

@ -0,0 +1,189 @@
local math_random = math.random
local math_sqrt = math.sqrt
local Public = {}
function Public.treasure_chest(surface, position, container_name)
local chest_raffle = {}
local chest_loot = {
{{name = "submachine-gun", count = math_random(1,3)}, weight = 3, d_min = 0.0, d_max = 0.1},
{{name = "pistol", count = math_random(1,2)}, weight = 1, d_min = 0.0, d_max = 1},
{{name = "slowdown-capsule", count = math_random(16,32)}, weight = 1, d_min = 0.3, d_max = 0.7},
{{name = "poison-capsule", count = math_random(8,16)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "uranium-cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.6, d_max = 1},
{{name = "cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.4, d_max = 0.7},
{{name = "explosive-uranium-cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.6, d_max = 1},
{{name = "explosive-cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.4, d_max = 0.8},
{{name = "shotgun", count = 1}, weight = 2, d_min = 0.0, d_max = 0.2},
{{name = "shotgun-shell", count = math_random(16,32)}, weight = 5, d_min = 0.0, d_max = 0.2},
{{name = "combat-shotgun", count = 1}, weight = 3, d_min = 0.3, d_max = 0.8},
{{name = "piercing-shotgun-shell", count = math_random(16,32)}, weight = 10, d_min = 0.2, d_max = 1},
{{name = "flamethrower", count = 1}, weight = 3, d_min = 0.3, d_max = 0.6},
{{name = "flamethrower-ammo", count = math_random(16,32)}, weight = 5, d_min = 0.3, d_max = 1},
{{name = "rocket-launcher", count = 1}, weight = 3, d_min = 0.2, d_max = 0.6},
{{name = "rocket", count = math_random(16,32)}, weight = 5, d_min = 0.2, d_max = 0.7},
{{name = "explosive-rocket", count = math_random(16,32)}, weight = 5, d_min = 0.3, d_max = 1},
{{name = "land-mine", count = math_random(16,32)}, weight = 5, d_min = 0.2, d_max = 0.7},
{{name = "grenade", count = math_random(16,32)}, weight = 5, d_min = 0.0, d_max = 0.5},
{{name = "cluster-grenade", count = math_random(8,16)}, weight = 5, d_min = 0.4, d_max = 1},
{{name = "firearm-magazine", count = math_random(32,128)}, weight = 5, d_min = 0, d_max = 0.3},
{{name = "piercing-rounds-magazine", count = math_random(32,128)}, weight = 5, d_min = 0.1, d_max = 0.8},
{{name = "uranium-rounds-magazine", count = math_random(32,128)}, weight = 5, d_min = 0.5, d_max = 1},
--{{name = "railgun", count = 1}, weight = 1, d_min = 0.2, d_max = 1},
{{name = "railgun-dart", count = math_random(2,4)}, weight = 4, d_min = 0, d_max = 0.2},
{{name = "railgun-dart", count = math_random(4,8)}, weight = 4, d_min = 0.1, d_max = 0.4},
{{name = "railgun-dart", count = math_random(8,12)}, weight = 4, d_min = 0.3, d_max = 0.6},
{{name = "railgun-dart", count = math_random(12,16)}, weight = 4, d_min = 0.5, d_max = 0.8},
{{name = "railgun-dart", count = math_random(16,20)}, weight = 4, d_min = 0.7, d_max = 1},
{{name = "defender-capsule", count = math_random(8,16)}, weight = 2, d_min = 0.0, d_max = 0.7},
{{name = "distractor-capsule", count = math_random(8,16)}, weight = 2, d_min = 0.2, d_max = 1},
{{name = "destroyer-capsule", count = math_random(8,16)}, weight = 2, d_min = 0.3, d_max = 1},
{{name = "atomic-bomb", count = 1}, weight = 1, d_min = 0.8, d_max = 1},
{{name = "light-armor", count = 1}, weight = 3, d_min = 0, d_max = 0.05},
{{name = "heavy-armor", count = 1}, weight = 3, d_min = 0.05, d_max = 0.25},
{{name = "modular-armor", count = 1}, weight = 2, d_min = 0.25, d_max = 0.5},
{{name = "power-armor", count = 1}, weight = 1, d_min = 0.4, d_max = 1},
{{name = "power-armor-mk2", count = 1}, weight = 1, d_min = 0.9, d_max = 1},
{{name = "battery-equipment", count = 1}, weight = 2, d_min = 0.3, d_max = 0.7},
--{{name = "battery-mk2-equipment", count = 1}, weight = 2, d_min = 0.7, d_max = 1},
{{name = "belt-immunity-equipment", count = 1}, weight = 1, d_min = 0.5, d_max = 1},
{{name = "solar-panel-equipment", count = math_random(1,4)}, weight = 5, d_min = 0.4, d_max = 0.8},
{{name = "discharge-defense-equipment", count = 1}, weight = 1, d_min = 0.5, d_max = 1},
{{name = "energy-shield-equipment", count = math_random(1,2)}, weight = 2, d_min = 0.3, d_max = 0.8},
--{{name = "energy-shield-mk2-equipment", count = 1}, weight = 2, d_min = 0.8, d_max = 1},
{{name = "exoskeleton-equipment", count = 1}, weight = 1, d_min = 0.3, d_max = 1},
{{name = "fusion-reactor-equipment", count = 1}, weight = 1, d_min = 0.8, d_max = 1},
{{name = "night-vision-equipment", count = 1}, weight = 1, d_min = 0.3, d_max = 0.8},
{{name = "personal-laser-defense-equipment", count = 1}, weight = 1, d_min = 0.7, d_max = 1},
{{name = "personal-roboport-equipment", count = math_random(1,2)}, weight = 3, d_min = 0.4, d_max = 1},
--{{name = "personal-roboport-mk2-equipment", count = 1}, weight = 1, d_min = 0.9, d_max = 1},
{{name = "logistic-robot", count = math_random(5,25)}, weight = 2, d_min = 0.5, d_max = 1},
{{name = "construction-robot", count = math_random(5,25)}, weight = 5, d_min = 0.4, d_max = 1},
{{name = "iron-gear-wheel", count = math_random(80,100)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "copper-cable", count = math_random(100,200)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "engine-unit", count = math_random(16,32)}, weight = 2, d_min = 0.1, d_max = 0.5},
{{name = "electric-engine-unit", count = math_random(16,32)}, weight = 2, d_min = 0.4, d_max = 0.8},
{{name = "battery", count = math_random(50,150)}, weight = 2, d_min = 0.3, d_max = 0.8},
{{name = "advanced-circuit", count = math_random(50,150)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "electronic-circuit", count = math_random(50,150)}, weight = 4, d_min = 0.0, d_max = 0.4},
{{name = "processing-unit", count = math_random(50,150)}, weight = 3, d_min = 0.7, d_max = 1},
{{name = "explosives", count = math_random(20,50)}, weight = 7, d_min = 0.0, d_max = 1},
{{name = "lubricant-barrel", count = math_random(4,10)}, weight = 1, d_min = 0.3, d_max = 0.5},
{{name = "rocket-fuel", count = math_random(4,10)}, weight = 2, d_min = 0.3, d_max = 0.7},
--{{name = "computer", count = 1}, weight = 2, d_min = 0, d_max = 1},
{{name = "effectivity-module", count = math_random(1,4)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "productivity-module", count = math_random(1,4)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "speed-module", count = math_random(1,4)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "automation-science-pack", count = math_random(16,64)}, weight = 4, d_min = 0.0, d_max = 0.2},
{{name = "logistic-science-pack", count = math_random(16,64)}, weight = 4, d_min = 0.05, d_max = 0.5},
{{name = "military-science-pack", count = math_random(16,64)}, weight = 4, d_min = 0.15, d_max = 1},
{{name = "chemical-science-pack", count = math_random(16,64)}, weight = 4, d_min = 0.3, d_max = 1},
{{name = "production-science-pack", count = math_random(16,64)}, weight = 4, d_min = 0.4, d_max = 1},
{{name = "utility-science-pack", count = math_random(16,64)}, weight = 4, d_min = 0.5, d_max = 1},
{{name = "space-science-pack", count = math_random(16,64)}, weight = 4, d_min = 0.9, d_max = 1},
{{name = "steel-plate", count = math_random(25,75)}, weight = 2, d_min = 0.1, d_max = 0.3},
{{name = "nuclear-fuel", count = 1}, weight = 2, d_min = 0.7, d_max = 1},
{{name = "burner-inserter", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.1},
{{name = "inserter", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.4},
{{name = "long-handed-inserter", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.4},
{{name = "fast-inserter", count = math_random(8,16)}, weight = 3, d_min = 0.1, d_max = 1},
{{name = "filter-inserter", count = math_random(8,16)}, weight = 1, d_min = 0.2, d_max = 1},
{{name = "stack-filter-inserter", count = math_random(4,8)}, weight = 1, d_min = 0.4, d_max = 1},
{{name = "stack-inserter", count = math_random(4,8)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "small-electric-pole", count = math_random(16,24)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "medium-electric-pole", count = math_random(8,16)}, weight = 3, d_min = 0.2, d_max = 1},
{{name = "big-electric-pole", count = math_random(4,8)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "substation", count = math_random(2,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "wooden-chest", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "iron-chest", count = math_random(8,16)}, weight = 3, d_min = 0.1, d_max = 0.4},
{{name = "steel-chest", count = math_random(8,16)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "small-lamp", count = math_random(16,32)}, weight = 3, d_min = 0.1, d_max = 0.3},
{{name = "rail", count = math_random(25,75)}, weight = 3, d_min = 0.1, d_max = 0.6},
{{name = "assembling-machine-1", count = math_random(2,4)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "assembling-machine-2", count = math_random(2,4)}, weight = 3, d_min = 0.2, d_max = 0.8},
{{name = "assembling-machine-3", count = math_random(2,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "accumulator", count = math_random(4,8)}, weight = 3, d_min = 0.4, d_max = 1},
{{name = "offshore-pump", count = math_random(1,3)}, weight = 2, d_min = 0.0, d_max = 0.2},
{{name = "beacon", count = 1}, weight = 2, d_min = 0.7, d_max = 1},
{{name = "boiler", count = math_random(3,6)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "steam-engine", count = math_random(2,4)}, weight = 3, d_min = 0.0, d_max = 0.5},
{{name = "steam-turbine", count = math_random(1,2)}, weight = 2, d_min = 0.6, d_max = 1},
{{name = "nuclear-reactor", count = 1}, weight = 1, d_min = 0.7, d_max = 1},
{{name = "centrifuge", count = 1}, weight = 1, d_min = 0.6, d_max = 1},
{{name = "heat-pipe", count = math_random(4,8)}, weight = 2, d_min = 0.5, d_max = 1},
{{name = "heat-exchanger", count = math_random(2,4)}, weight = 2, d_min = 0.5, d_max = 1},
{{name = "arithmetic-combinator", count = math_random(4,8)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "constant-combinator", count = math_random(4,8)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "decider-combinator", count = math_random(4,8)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "power-switch", count = 1}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "programmable-speaker", count = math_random(2,4)}, weight = 1, d_min = 0.1, d_max = 1},
{{name = "green-wire", count = math_random(10,29)}, weight = 4, d_min = 0.1, d_max = 1},
{{name = "red-wire", count = math_random(10,29)}, weight = 4, d_min = 0.1, d_max = 1},
{{name = "chemical-plant", count = math_random(1,3)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "burner-mining-drill", count = math_random(2,4)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "electric-mining-drill", count = math_random(2,4)}, weight = 3, d_min = 0.2, d_max = 1},
{{name = "express-transport-belt", count = math_random(25,75)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "express-underground-belt", count = math_random(4,8)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "express-splitter", count = math_random(1,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "fast-transport-belt", count = math_random(25,75)}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = "fast-underground-belt", count = math_random(4,8)}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = "fast-splitter", count = math_random(1,4)}, weight = 3, d_min = 0.2, d_max = 0.3},
{{name = "transport-belt", count = math_random(25,75)}, weight = 3, d_min = 0, d_max = 0.3},
{{name = "underground-belt", count = math_random(4,8)}, weight = 3, d_min = 0, d_max = 0.3},
{{name = "splitter", count = math_random(1,4)}, weight = 3, d_min = 0, d_max = 0.3},
--{{name = "oil-refinery", count = math_random(2,4)}, weight = 2, d_min = 0.3, d_max = 1},
{{name = "pipe", count = math_random(30,50)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "pipe-to-ground", count = math_random(4,8)}, weight = 1, d_min = 0.2, d_max = 0.5},
{{name = "pumpjack", count = math_random(1,3)}, weight = 1, d_min = 0.3, d_max = 0.8},
{{name = "pump", count = math_random(1,2)}, weight = 1, d_min = 0.3, d_max = 0.8},
{{name = "solar-panel", count = math_random(3,6)}, weight = 3, d_min = 0.4, d_max = 0.9},
{{name = "electric-furnace", count = math_random(2,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "steel-furnace", count = math_random(4,8)}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = "stone-furnace", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "radar", count = math_random(1,2)}, weight = 1, d_min = 0.1, d_max = 0.4},
{{name = "rail-signal", count = math_random(8,16)}, weight = 2, d_min = 0.2, d_max = 0.8},
{{name = "rail-chain-signal", count = math_random(8,16)}, weight = 2, d_min = 0.2, d_max = 0.8},
{{name = "stone-wall", count = math_random(33,99)}, weight = 3, d_min = 0.0, d_max = 0.7},
{{name = "gate", count = math_random(16,32)}, weight = 3, d_min = 0.0, d_max = 0.7},
{{name = "storage-tank", count = math_random(2,6)}, weight = 3, d_min = 0.3, d_max = 0.6},
{{name = "train-stop", count = math_random(1,2)}, weight = 1, d_min = 0.2, d_max = 0.7},
{{name = "express-loader", count = math_random(1,2)}, weight = 1, d_min = 0.5, d_max = 1},
{{name = "fast-loader", count = math_random(1,2)}, weight = 1, d_min = 0.2, d_max = 0.7},
{{name = "loader", count = math_random(1,2)}, weight = 1, d_min = 0.0, d_max = 0.5},
{{name = "lab", count = math_random(1,2)}, weight = 2, d_min = 0.0, d_max = 0.3},
{{name = "roboport", count = 1}, weight = 2, d_min = 0.8, d_max = 1},
{{name = "flamethrower-turret", count = 1}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "laser-turret", count = math_random(3,6)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "gun-turret", count = math_random(2,4)}, weight = 3, d_min = 0.2, d_max = 0.9},
}
local jumps = 0
if global.objective.chronojumps then jumps = global.objective.chronojumps end
local distance_to_center = (jumps / 40)
if distance_to_center > 1 then distance_to_center = 1 end
for _, t in pairs (chest_loot) do
for x = 1, t.weight, 1 do
--if math_random(1,50) == 1 then log(distance_to_center) end
if t.d_min <= distance_to_center and t.d_max >= distance_to_center then
table.insert(chest_raffle, t[1])
end
end
end
local e = surface.create_entity({name = container_name, position=position, force="neutral", create_build_effect_smoke = false})
e.minable = false
local i = e.get_inventory(defines.inventory.chest)
for x = 1, math_random(2,6), 1 do
local loot = chest_raffle[math_random(1,#chest_raffle)]
i.insert(loot)
end
end
return Public.treasure_chest

View File

@ -0,0 +1,239 @@
local Public = {}
local math_floor = math.floor
local math_min = math.min
local math_max = math.max
local math_abs = math.abs
local math_ceil = math.ceil
function Public.upgrades()
if not global.objective then global.objective = {} end
if not global.objective.upgrades then
global.objective.upgrades = {}
for i = 1, 16, 1 do
global.objective.upgrades[i] = 0
end
end
if not global.difficulty_vote_value then global.difficulty_vote_value = 1 end
--Each upgrade is automatically added into gui.
--name : visible name in gui (best if localized)
--sprite: visible icon
--cost/item/tt = the first part of localized string, for example coin is in item-name.coin. Can be even scenario's key.
--Second part of localized string is taken from item's name.
--First additional parameter for tooltip should match the max_level
--still need to map upgrade effects in upgrades.lua / process_upgrade() if it should do more than increase level of upgrade
local upgrades = {
[1] = {
name = {"chronosphere.upgrade_train_armor"},
sprite = "recipe/locomotive",
max_level = 36,
message = {"chronosphere.upgrade_train_armor_message"},
tooltip = {"chronosphere.upgrade_train_armor_tooltip", 36, global.objective.max_health},
jump_limit = global.objective.upgrades[1],
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 500 * (1 + global.objective.upgrades[1])},
item2 = {name = "copper-plate", tt = "item-name", sprite = "item/copper-plate", count = 1500},
}
},
[2] = {
name = {"chronosphere.upgrade_filter"},
sprite = "recipe/effectivity-module",
max_level = 9,
message = {"chronosphere.upgrade_filter_message"},
tooltip = {"chronosphere.upgrade_filter_tooltip", math_floor(300/(global.objective.upgrades[2]/3+1) * global.difficulty_vote_value)},
jump_limit = (1 + global.objective.upgrades[2]) * 3 or 0,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 5000},
item2 = {name = "electronic-circuit", tt = "item-name", sprite = "item/electronic-circuit", count = math_min(1 + global.objective.upgrades[2], 3) * 500 + 500},
item3 = {name = "advanced-circuit", tt = "item-name", sprite = "item/advanced-circuit", count = math_max(math_min(1 + global.objective.upgrades[2], 6) - 3, 0) * 500},
item4 = {name = "processing-unit", tt = "item-name", sprite = "item/processing-unit", count = math_max(math_min(1 + global.objective.upgrades[2], 9) - 6, 0) * 500}
}
},
[3] = {
name = {"chronosphere.upgrade_accumulators"},
sprite = "recipe/accumulator",
max_level = 24,
message = {"chronosphere.upgrade_accumulators_message"},
tooltip = {"chronosphere.upgrade_accumulators_tooltip"},
jump_limit = global.objective.upgrades[3],
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 2000 * (1 + global.objective.upgrades[3] / 4)},
item2 = {name = "battery", tt = "item-name", sprite = "item/battery", count = 100 * (1 + global.objective.upgrades[3])}
}
},
[4] = {
name = {"chronosphere.upgrade_loot_pickup"},
sprite = "recipe/long-handed-inserter",
max_level = 4,
message = {"chronosphere.upgrade_loot_pickup_message"},
tooltip = {"chronosphere.upgrade_loot_pickup_tooltip", global.objective.upgrades[4]},
jump_limit = 0,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 1000 * (1 + global.objective.upgrades[4])},
item2 = {name = "long-handed-inserter", tt = "entity-name", sprite = "recipe/long-handed-inserter", count = 400}
}
},
[5] = {
name = {"chronosphere.upgrade_inventory_size"},
sprite = "entity/character",
max_level = 4,
message = {"chronosphere.upgrade_inventory_size_message"},
tooltip = {"chronosphere.upgrade_inventory_size_tooltip"},
jump_limit = (1 + global.objective.upgrades[5]) * 5,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 2500 * (1 + global.objective.upgrades[5])},
item2 = {name = "wooden-chest", tt = "entity-name", sprite = "item/wooden-chest", count = math_max(0, 250 - math_abs(global.objective.upgrades[5]) * 250)},
item3 = {name = "iron-chest", tt = "entity-name", sprite = "item/iron-chest", count = math_max(0, 250 - math_abs(global.objective.upgrades[5] - 1) * 250)},
item4 = {name = "steel-chest", tt = "entity-name", sprite = "item/steel-chest", count = math_max(0, 250 - math_abs(global.objective.upgrades[5] - 2) * 250)},
item5 = {name = "logistic-chest-storage", tt = "entity-name", sprite = "item/logistic-chest-storage", count = math_max(0, 250 - math_abs(global.objective.upgrades[5] - 3) * 250)}
}
},
[6] = {
name = {"chronosphere.upgrade_repair"},
sprite = "recipe/repair-pack",
max_level = 4,
message = {"chronosphere.upgrade_repair_message"},
tooltip = {"chronosphere.upgrade_repair_tooltip", global.objective.upgrades[6]},
jump_limit = 0,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 1000 * (1 + global.objective.upgrades[6])},
item2 = {name = "repair-pack", tt = "item-name", sprite = "recipe/repair-pack", count = 200 * (1 + global.objective.upgrades[6])}
}
},
[7] = {
name = {"chronosphere.upgrade_water"},
sprite = "fluid/water",
max_level = 1,
message = {"chronosphere.upgrade_water_message"},
tooltip = {"chronosphere.upgrade_water_tooltip"},
jump_limit = 0,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 2000},
item2 = {name = "pipe", tt = "entity-name", sprite = "item/pipe", count = 500},
item3 = {name = "pump", tt = "entity-name", sprite = "item/pump", count = 10}
}
},
[8] = {
name = {"chronosphere.upgrade_output"},
sprite = "recipe/cargo-wagon",
max_level = 1,
message = {"chronosphere.upgrade_output_message"},
tooltip = {"chronosphere.upgrade_output_tooltip"},
jump_limit = 0,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 2000},
item2 = {name = "fast-inserter", tt = "entity-name", sprite = "recipe/fast-inserter", count = 200}
}
},
[9] = {
name = {"chronosphere.upgrade_storage"},
sprite = "item/logistic-chest-storage",
max_level = 4,
message = {"chronosphere.upgrade_storage_message"},
tooltip = {"chronosphere.upgrade_storage_tooltip"},
jump_limit = (1 + global.objective.upgrades[9]) * 5,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 2500 * (1 + global.objective.upgrades[9])},
item2 = {name = "wooden-chest", tt = "entity-name", sprite = "item/wooden-chest", count = math_max(0, 250 - math_abs(global.objective.upgrades[9]) * 250)},
item3 = {name = "iron-chest", tt = "entity-name", sprite = "item/iron-chest", count = math_max(0, 250 - math_abs(global.objective.upgrades[9] - 1) * 250)},
item4 = {name = "steel-chest", tt = "entity-name", sprite = "item/steel-chest", count = math_max(0, 250 - math_abs(global.objective.upgrades[9] - 2) * 250)},
item5 = {name = "logistic-chest-storage", tt = "entity-name", sprite = "item/logistic-chest-storage", count = math_max(0, 250 - math_abs(global.objective.upgrades[9] - 3) * 250)}
}
},
[10] = {
name = {"chronosphere.upgrade_poison"},
sprite = "recipe/poison-capsule",
max_level = 4,
message = {"chronosphere.upgrade_poison_message"},
tooltip = {"chronosphere.upgrade_poison_tooltip", math_ceil(global.objective.poisontimeout /6)},
jump_limit = 0,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 1000},
item2 = {name = "poison-capsule", tt = "item-name", sprite = "recipe/poison-capsule", count = 50}
}
},
[11] = {
name = {"chronosphere.upgrade_fusion"},
sprite = "recipe/fusion-reactor-equipment",
max_level = 999,
message = {"chronosphere.upgrade_fusion_message"},
tooltip = {"chronosphere.upgrade_fusion_tooltip"},
jump_limit = 24,
cost = {
item1 = {name = "low-density-structure", tt = "item-name", sprite = "item/low-density-structure", count = 100},
item2 = {name = "railgun-dart", tt = "item-name", sprite = "item/railgun-dart", count = 200},
item3 = {name = "solar-panel-equipment", tt = "equipment-name", sprite = "item/solar-panel-equipment", count = 16}
}
},
[12] = {
name = {"chronosphere.upgrade_mk2"},
sprite = "recipe/power-armor-mk2",
max_level = 999,
message = {"chronosphere.upgrade_mk2_message"},
tooltip = {"chronosphere.upgrade_mk2_tooltip"},
jump_limit = 24,
cost = {
item1 = {name = "low-density-structure", tt = "item-name", sprite = "item/low-density-structure", count = 100},
item2 = {name = "railgun-dart", tt = "item-name", sprite = "item/railgun-dart", count = 300},
item3 = {name = "power-armor", tt = "item-name", sprite = "item/power-armor", count = 1}
}
},
[13] = {
name = {"chronosphere.upgrade_computer1"},
sprite = "item/advanced-circuit",
max_level = 1,
message = {"chronosphere.upgrade_computer1_message"},
tooltip = {"chronosphere.upgrade_computer1_tooltip"},
jump_limit = 15,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 5000},
item2 = {name = "advanced-circuit", tt = "item-name", sprite = "item/advanced-circuit", count = 1000},
item3 = {name = "copper-plate", tt = "item-name", sprite = "item/copper-plate", count = 2000}
}
},
[14] = {
name = {"chronosphere.upgrade_computer2"},
sprite = "item/processing-unit",
max_level = 1,
message = {"chronosphere.upgrade_computer2_message"},
tooltip = {"chronosphere.upgrade_computer2_tooltip"},
jump_limit = 20,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 10000},
item2 = {name = "processing-unit", tt = "item-name", sprite = "item/processing-unit", count = 1000},
item3 = {name = "nuclear-reactor", tt = "entity-name", sprite = "item/nuclear-reactor", count = 1}
}
},
[15] = {
name = {"chronosphere.upgrade_computer3"},
sprite = "item/rocket-control-unit",
max_level = 10,
message = {"chronosphere.upgrade_computer3_message", global.objective.upgrades[15] + 1},
tooltip = {"chronosphere.upgrade_computer3_tooltip"},
jump_limit = 25,
cost = {
item1 = {name = "coin", tt = "item-name", sprite = "item/coin", count = 2000},
item2 = {name = "low-density-structure", tt = "item-name", sprite = "item/low-density-structure", count = 100},
item3 = {name = "rocket-control-unit", tt = "item-name", sprite = "item/rocket-control-unit", count = 100},
item4 = {name = "uranium-fuel-cell", tt = "item-name", sprite = "item/uranium-fuel-cell", count = 50}
}
},
[16] = {
name = {"chronosphere.upgrade_computer4"},
sprite = "item/satellite",
max_level = 1,
message = {"chronosphere.upgrade_computer4_message"},
tooltip = {"chronosphere.upgrade_computer4_tooltip"},
jump_limit = 25,
cost = {
item1 = {name = "rocket-silo", tt = "entity-name", sprite = "item/rocket-silo", count = 1},
item2 = {name = "satellite", tt = "item-name", sprite = "item/satellite", count = 1}
}
}
}
return upgrades
end
return Public

View File

@ -0,0 +1,259 @@
local Public = {}
local math_floor = math.floor
local Server = require 'utils.server'
local Upgrades = require "maps.chronosphere.upgrade_list"
local function check_win()
local objective = global.objective
if global.fishchest then
if global.fishchest.valid then
local inv = global.fishchest.get_inventory(defines.inventory.chest)
local countfish = inv.get_item_count("raw-fish")
local enemies = game.surfaces[global.active_surface_index].count_entities_filtered{force = "enemy"}
if countfish > 0 then
inv.remove({name = "raw-fish", count = countfish})
objective.mainscore = objective.mainscore + countfish
if enemies > 0 then
game.print("Comfylatron: You delivered fish, but there is still " .. enemies .. " enemies left. Kill them all so fish are safe!", {r=0.98, g=0.66, b=0.22})
else
if not global.game_reset_tick then
global.game_reset_tick = game.tick + 18000
objective.game_won = true
objective.game_lost = true
objective.chronotimer = 200000000 - 300
for _, player in pairs(game.connected_players) do
player.play_sound{path="utility/game_won", volume_modifier=0.85}
end
local message = {"chronosphere.message_game_won1"}
local message2 = "Number of delivered fish: " .. objective.mainscore
game.print(message, {r=0.98, g=0.66, b=0.22})
game.print(message2, {r=0.98, g=0.66, b=0.22})
Server.to_discord_embed(message)
Server.to_discord_embed(message2)
end
end
end
end
end
end
local function upgrade_hp()
global.objective.max_health = 10000 + 2500 * global.objective.upgrades[1]
rendering.set_text(global.objective.health_text, "HP: " .. global.objective.health .. " / " .. global.objective.max_health)
end
local function spawn_acumulators()
local x = -28
local y = -252
local yy = global.objective.upgrades[3] * 2
local surface = game.surfaces["cargo_wagon"]
if yy > 8 then yy = yy + 2 end
if yy > 26 then yy = yy + 2 end
if yy > 44 then yy = yy + 2 end
for i = 1, 27, 1 do
local acumulator = surface.create_entity({name = "accumulator", position = {x + 2 * i, y + yy}, force="player", create_build_effect_smoke = false})
acumulator.minable = false
acumulator.destructible = false
table.insert(global.acumulators, acumulator)
end
end
local function upgrade_pickup()
game.forces.player.character_loot_pickup_distance_bonus = game.forces.player.character_loot_pickup_distance_bonus + 1
end
local function upgrade_inv()
game.forces.player.character_inventory_slots_bonus = game.forces.player.character_inventory_slots_bonus + 10
end
local function upgrade_water()
if not game.surfaces["cargo_wagon"] then return end
local positions = {{28,66},{28,-62},{-29,66},{-29,-62}}
for i = 1, 4, 1 do
local e = game.surfaces["cargo_wagon"].create_entity({name = "offshore-pump", position = positions[i], force="player"})
e.destructible = false
e.minable = false
end
end
local function upgrade_out()
if not game.surfaces["cargo_wagon"] then return end
local positions = {{-16,-62},{15,-62},{-16,66},{15,66}}
local out = {}
for i = 1, 4, 1 do
local e = game.surfaces["cargo_wagon"].create_entity({name = "compilatron-chest", position = positions[i], force = "player"})
e.destructible = false
e.minable = false
global.outchests[i] = e
out[i] = rendering.draw_text{
text = "Output",
surface = e.surface,
target = e,
target_offset = {0, -1.5},
color = global.locomotive.color,
scale = 0.80,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
end
end
local function upgrade_storage()
local objective = global.objective
if not game.surfaces["cargo_wagon"] then return end
local chests = {}
local positions = {x = {-33, 32}, y = {-189, -127, -61, 1, 67, 129}}
for i = 1, 58, 1 do
for ii = 1, 6, 1 do
if objective.upgrades[9] == 1 then
chests[#chests + 1] = {entity = {name = "wooden-chest", position = {x = positions.x[1] ,y = positions.y[ii] + i}, force = "player"}, old = "none"}
chests[#chests + 1] = {entity = {name = "wooden-chest", position = {x = positions.x[2] ,y = positions.y[ii] + i}, force = "player"}, old = "none"}
elseif objective.upgrades[9] == 2 then
chests[#chests + 1] = {entity = {name = "iron-chest", position = {x = positions.x[1] ,y = positions.y[ii] + i}, force = "player", fast_replace = true, spill = false}, old = "wood"}
chests[#chests + 1] = {entity = {name = "iron-chest", position = {x = positions.x[2] ,y = positions.y[ii] + i}, force = "player", fast_replace = true, spill = false}, old = "wood"}
elseif objective.upgrades[9] == 3 then
chests[#chests + 1] = {entity = {name = "steel-chest", position = {x = positions.x[1] ,y = positions.y[ii] + i}, force = "player", fast_replace = true, spill = false}, old = "iron"}
chests[#chests + 1] = {entity = {name = "steel-chest", position = {x = positions.x[2] ,y = positions.y[ii] + i}, force = "player", fast_replace = true, spill = false}, old = "iron"}
elseif objective.upgrades[9] == 4 then
chests[#chests + 1] = {entity = {name = "logistic-chest-storage", position = {x = positions.x[1] ,y = positions.y[ii] + i}, force = "player", fast_replace = true, spill = false}, old = "steel"}
chests[#chests + 1] = {entity = {name = "logistic-chest-storage", position = {x = positions.x[2] ,y = positions.y[ii] + i}, force = "player", fast_replace = true, spill = false}, old = "steel"}
end
end
end
local surface = game.surfaces["cargo_wagon"]
for i = 1, #chests, 1 do
if objective.upgrades[9] == 1 then
surface.set_tiles({{name = "tutorial-grid", position = chests[i].entity.position}})
end
local old = nil
local oldpos = {x = chests[i].entity.position.x + 0.5, y = chests[i].entity.position.y + 0.5}
if chests[i].old == "wood" then old = surface.find_entity("wooden-chest", oldpos)
elseif chests[i].old == "iron" then old = surface.find_entity("iron-chest", oldpos)
elseif chests[i].old == "steel" then old = surface.find_entity("steel-chest", oldpos)
end
if old then
old.minable = true
old.destructible = true
end
local e = surface.create_entity(chests[i].entity)
e.destructible = false
e.minable = false
end
end
local function fusion_buy()
local objective = global.objective
if global.upgradechest[11] and global.upgradechest[11].valid then
local inv = global.upgradechest[14].get_inventory(defines.inventory.chest)
inv.insert({name = "fusion-reactor-equipment", count = 1})
end
end
local function mk2_buy()
local objective = global.objective
if global.upgradechest[13] and global.upgradechest[13].valid then
inv.insert({name = "power-armor-mk2", count = 1})
end
end
local function process_upgrade(index)
if index == 1 then
upgrade_hp()
elseif index == 3 then
spawn_acumulators()
elseif index == 4 then
upgrade_pickup()
elseif index == 5 then
upgrade_inv()
elseif index == 7 then
upgrade_water()
elseif index == 8 then
upgrade_out()
elseif index == 9 then
upgrade_storage()
elseif index == 11 then
fusion_buy()
elseif index == 12 then
mk2_buy()
elseif index == 13 then
global.objective.computermessage = 2
elseif index == 14 then
global.objective.computermessage = 4
elseif index == 15 then
if global.objective.upgrades[15] == 10 then
game.print({"chronosphere.message_quest6"}, {r=0.98, g=0.66, b=0.22})
end
end
end
local function check_single_upgrade(index)
local upgrades = Upgrades.upgrades()
if global.upgradechest[index] and global.upgradechest[index].valid then
if index == 14 and (global.objective.upgrades[13] ~= 1 or global.objective.computermessage ~= 3) then
return
elseif index == 15 and (global.objective.upgrades[14] ~= 1 or global.objective.computermessage ~= 5) then
return
elseif index == 16 and global.objective.upgrades[15] ~= 10 then
return
end
local inv = global.upgradechest[index].get_inventory(defines.inventory.chest)
if global.objective.upgrades[index] < upgrades[index].max_level and global.objective.chronojumps >= upgrades[index].jump_limit then
for _, item in pairs(upgrades[index].cost) do
if inv.get_item_count(item.name) < item.count then return end
end
else
return
end
for _, item in pairs(upgrades[index].cost) do
if item.count > 0 then
inv.remove({name = item.name, count = item.count})
end
end
global.objective.upgrades[index] = global.objective.upgrades[index] + 1
game.print(upgrades[index].message, {r=0.98, g=0.66, b=0.22})
process_upgrade(index)
end
end
local function check_all_upgrades()
local upgrades = Upgrades.upgrades()
for i = 1, #upgrades, 1 do
check_single_upgrade(i)
end
end
function Public.check_upgrades()
local objective = global.objective
if not global.upgradechest then return end
if objective.game_lost == true then return end
check_all_upgrades()
if objective.planet[1].name.id == 17 then
if global.fishchest then
check_win()
end
end
end
function Public.trigger_poison()
local objective = global.objective
if objective.game_lost then return end
if objective.upgrades[10] > 0 and objective.poisontimeout == 0 then
local objective = global.objective
objective.upgrades[10] = objective.upgrades[10] - 1
objective.poisontimeout = 120
local objs = {global.locomotive, global.locomotive_cargo[1], global.locomotive_cargo[2], global.locomotive_cargo[3]}
local surface = objective.surface
game.print({"chronosphere.message_poison_defense"}, {r=0.98, g=0.66, b=0.22})
for i = 1, 4, 1 do
surface.create_entity({name = "poison-capsule", position = objs[i].position, force = "player", target = objs[i], speed = 1 })
end
for i = 1 , #global.comfychests, 1 do
surface.create_entity({name = "poison-capsule", position = global.comfychests[i].position, force = "player", target = global.comfychests[i], speed = 1 })
end
end
end
return Public

View File

@ -34,22 +34,22 @@ local function get_collapse_vectors(radius, seed)
end
end
end
local sorted_vectors = {}
for _, vector in pairs(vectors) do
local index = math_floor(math_sqrt(vector[1] ^ 2 + vector[2] ^ 2)) + 1
if not sorted_vectors[index] then sorted_vectors[index] = {} end
sorted_vectors[index][#sorted_vectors[index] + 1] = vector
sorted_vectors[index][#sorted_vectors[index] + 1] = vector
end
local final_list = {}
local final_list = {}
for _, row in pairs(sorted_vectors) do
table_shuffle_table(row)
for _, tile in pairs(row) do
table_insert(final_list, tile)
end
end
return final_list
end
@ -61,7 +61,7 @@ local function set_y(surface)
for _ = 1, 16, 1 do
local area = {{x_left, map_collapse.last_position.y},{x_right, map_collapse.last_position.y + 1}}
if surface.count_tiles_filtered({name = "out-of-map", area = area}) < level_width then
return area
return area
end
map_collapse.last_position.y = map_collapse.last_position.y - 1
end
@ -73,7 +73,7 @@ local function set_positions(surface)
local map_collapse = global.map_collapse
map_collapse.positions = {}
local i = 1
for _, tile in pairs(surface.find_tiles_filtered({area = area})) do
if tile.valid then
@ -83,7 +83,7 @@ local function set_positions(surface)
end
end
end
if i == 1 then
map_collapse.positions = nil
return
@ -96,7 +96,16 @@ local function set_collapse_tiles(surface, position, vectors)
map_collapse.processing = {}
local i = 1
for _, vector in pairs(vectors) do
local shifted_position = {x = position[1] + vector[1], y = position[2] + vector[2] - 60}
local position = {x = position[1] + vector[1], y = position[2] + vector[2]}
local rocks = surface.find_entities_filtered{position = shifted_position, radius = 2, type = {"simple-entity", "tree"}}
if #rocks > 0 then
for i = 1, #rocks, 1 do
if rocks[i].valid then
rocks[i].destroy()
end
end
end
local tile = surface.get_tile(position)
if tile.valid and tile.name ~= "out-of-map" then
map_collapse.processing[i] = tile
@ -109,28 +118,28 @@ end
local function clean_positions(tbl)
for k, tile in pairs(tbl) do
if not tile.valid then
if not tile.valid then
table_remove(tbl, k)
else
if tile.name == "out-of-map" then
if tile.name == "out-of-map" then
table_remove(tbl, k)
end
end
end
end
end
end
local function setup_next_collapse()
local surface = game.surfaces[global.active_surface_index]
local map_collapse = global.map_collapse
local map_collapse = global.map_collapse
if not map_collapse.vector_list then
map_collapse.vector_list = {}
map_collapse.vector_list = {}
for _ = 1, size_of_vector_list, 1 do
table_insert(global.map_collapse.vector_list, get_collapse_vectors(math_random(24, 48), math_random(1, 9999999)))
end
end
if not map_collapse.positions then
if math_random(1, 64) == 1 then map_collapse.last_position = {x = 0, y = 128} end
--if math_random(1, 64) == 1 then map_collapse.last_position = {x = 0, y = 128} end
set_positions(surface)
return
end
@ -141,10 +150,10 @@ local function setup_next_collapse()
if tile.name == "out-of-map" then clean_positions(map_collapse.positions) return end
local position = {tile.position.x, tile.position.y}
local vectors = map_collapse.vector_list[math_random(1, size_of_vector_list)]
set_collapse_tiles(surface, position, vectors)
local last_position = global.map_collapse.last_position
game.forces.player.chart(surface, {{last_position.x - chart_radius, last_position.y - chart_radius},{last_position.x + chart_radius, last_position.y + chart_radius}})
global.map_collapse.last_position = {x = position[1], y = position[2]}
@ -164,11 +173,11 @@ end
local function process_tile(surface, tile, tiles_to_set)
if not tile then return end
if not tile.valid then return end
local conversion_tile = tile_conversion[tile.name]
local conversion_tile = tile_conversion[tile.name]
if conversion_tile then
table_insert(tiles_to_set, {name = conversion_tile, position = tile.position})
surface.create_trivial_smoke({name="train-smoke", position = tile.position})
surface.create_trivial_smoke({name="train-smoke", position = tile.position})
else
table_insert(tiles_to_set, {name = "out-of-map", position = tile.position})
end
@ -179,12 +188,12 @@ end
function Public.process()
local surface = game.surfaces[global.active_surface_index]
local map_collapse = global.map_collapse
if map_collapse.processing_index >= map_collapse.size_of_processing then
setup_next_collapse()
return
end
local count = 0
local tiles_to_set = {}
for i = map_collapse.processing_index, map_collapse.size_of_processing, 1 do
@ -194,7 +203,7 @@ function Public.process()
end
map_collapse.processing_index = map_collapse.processing_index + 1
end
if count > 1 then surface.set_tiles(tiles_to_set, true) end
end
@ -204,11 +213,11 @@ function Public.init()
["size_of_processing"] = 0,
["processing"] = {},
["last_position"] = {x = 0, y = 128},
["speed"] = 2,
["speed"] = 3,
}
end
local event = require 'utils.event'
event.on_init(Public.init())
return Public
return Public

View File

@ -4,17 +4,17 @@ local function on_research_finished(event)
local force_name = research.force.name
if research.name == "military" then
if not global.flamethrower_damage then global.flamethrower_damage = {} end
global.flamethrower_damage[force_name] = -0.50
global.flamethrower_damage[force_name] = -0.75
game.forces[force_name].set_turret_attack_modifier("flamethrower-turret", global.flamethrower_damage[force_name])
game.forces[force_name].set_ammo_damage_modifier("flamethrower", global.flamethrower_damage[force_name])
game.forces[force_name].set_ammo_damage_modifier("flamethrower", global.flamethrower_damage[force_name])
end
if string.sub(research.name, 0, 18) == "refined-flammables" then
global.flamethrower_damage[force_name] = global.flamethrower_damage[force_name] + 0.10
game.forces[force_name].set_turret_attack_modifier("flamethrower-turret", global.flamethrower_damage[force_name])
game.forces[force_name].set_turret_attack_modifier("flamethrower-turret", global.flamethrower_damage[force_name])
game.forces[force_name].set_ammo_damage_modifier("flamethrower", global.flamethrower_damage[force_name])
end
end
end
local event = require 'utils.event'
event.add(defines.events.on_research_finished, on_research_finished)
event.add(defines.events.on_research_finished, on_research_finished)

View File

@ -6,22 +6,22 @@ function Public.locomotive_spawn(surface, position)
end
global.locomotive = surface.create_entity({name = "locomotive", position = {position.x, position.y + -3}, force = "player"})
global.locomotive.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 100})
global.locomotive_cargo = surface.create_entity({name = "cargo-wagon", position = {position.x, position.y + 3}, force = "player"})
global.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = "raw-fish", count = 1})
rendering.draw_light({
sprite = "utility/light_medium", scale = 5.5, intensity = 1, minimum_darkness = 0,
oriented = true, color = {255,255,255}, target = global.locomotive,
surface = surface, visible = true, only_in_alt_mode = false,
})
rendering.draw_light({
sprite = "utility/light_medium", scale = 5.5, intensity = 1, minimum_darkness = 0,
oriented = true, color = {255,255,255}, target = global.locomotive_cargo,
surface = surface, visible = true, only_in_alt_mode = false,
})
global.locomotive.color = {0, 255, 0}
global.locomotive.minable = false
global.locomotive_cargo.minable = false
@ -37,7 +37,7 @@ function Public.fish_tag()
if global.locomotive_tag then
if global.locomotive_tag.valid then
if global.locomotive_tag.position.x == global.locomotive_cargo.position.x and global.locomotive_tag.position.y == global.locomotive_cargo.position.y then return end
global.locomotive_tag.destroy()
global.locomotive_tag.destroy()
end
end
global.locomotive_tag = global.locomotive_cargo.force.add_chart_tag(
@ -51,7 +51,7 @@ end
local function accelerate()
if not global.locomotive then return end
if not global.locomotive.valid then return end
if global.locomotive.get_driver() then return end
if global.locomotive.get_driver() then return end
global.locomotive_driver = global.locomotive.surface.create_entity({name = "character", position = global.locomotive.position, force = "player"})
global.locomotive_driver.driving = true
global.locomotive_driver.riding_state = {acceleration = defines.riding.acceleration.accelerating, direction = defines.riding.direction.straight}
@ -77,8 +77,8 @@ local market_offers = {
}
local function create_wagon_room()
local width = 17
local height = 39
local width = 32
local height = 64
local map_gen_settings = {
["width"] = width,
["height"] = height,
@ -97,9 +97,9 @@ local function create_wagon_room()
surface.daytime = 0.1
surface.request_to_generate_chunks({0,0}, 1)
surface.force_generate_chunk_requests()
for x = width * -0.5 + 1, width * 0.5, 1 do
for y = height * -0.5, height * 0.5, 1 do
for x = width * -0.5, width * 0.5 - 1, 1 do
for y = height * -0.5, height * 0.5 - 1, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
if math.random(1, 5) == 1 and y > 2 then
surface.spill_item_stack({x + math.random(0, 9) * 0.1,y + math.random(0, 9) * 0.1},{name = "raw-fish", count = 1}, false)
@ -107,39 +107,39 @@ local function create_wagon_room()
end
end
for x = width * -0.5 + 6, width * 0.5 - 5, 1 do
for y = height * -0.5 + 2, height * -0.5 + 4, 1 do
for x = width * -0.5 + 4, width * 0.5 - 5, 1 do
for y = height * -0.5 + 4, height * -0.5 + 6, 1 do
local p = {x,y}
surface.set_tiles({{name = "water", position = p}})
if math.random(1, 2) == 1 then surface.create_entity({name = "fish", position = p}) end
end
end
local market = surface.create_entity({name = "market", position = {0, height * -0.5 + 7}, force="neutral", create_build_effect_smoke = false})
local market = surface.create_entity({name = "market", position = {0, height * -0.5 + 9}, force="neutral", create_build_effect_smoke = false})
market.minable = false
market.destructible = false
for _, offer in pairs(market_offers) do market.add_market_item(offer) end
for _, x in pairs({width * -0.5, width * 0.5 + 1}) do
for _, x in pairs({width * -0.5 -0.5, width * 0.5 + 0.5}) do
local e = surface.create_entity({name = "car", position = {x, 0}, force = "player", create_build_effect_smoke = false})
e.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 16})
e.destructible = false
e.minable = false
e.operable = false
end
local e = surface.create_entity({name = "big-biter", position = {width * -0.5 + 2, height * -0.5 + 2}, force = "player", create_build_effect_smoke = false})
e.ai_settings.allow_destroy_when_commands_fail = false
e.ai_settings.allow_try_return_to_spawner = false
local positions = {}
for x = width * -0.5 + 2, width * 0.5 - 1, 1 do
for x = width * -0.5 + 2, width * 0.5 - 2, 1 do
for y = 4, height * 0.5 - 1, 1 do
positions[#positions + 1] = {x = x, y = y}
end
end
table.shuffle_table(positions)
local cargo_boxes = {
{name = "grenade", count = math.random(2, 3)},
{name = "submachine-gun", count = 1},
@ -155,8 +155,8 @@ local function create_wagon_room()
{name = "rail", count = math.random(16, 24)},
{name = "rail", count = math.random(16, 24)},
{name = "rail", count = math.random(16, 24)},
}
}
local i = 1
for _ = 1, 10, 1 do
if not positions[i] then break end
@ -165,13 +165,13 @@ local function create_wagon_room()
inventory.insert({name = "raw-fish", count = math.random(2, 5)})
i = i + 1
end
for _ = 1, 24, 1 do
if not positions[i] then break end
local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false})
i = i + 1
end
for loot_i = 1, #cargo_boxes, 1 do
if not positions[i] then break end
local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false})
@ -218,4 +218,4 @@ function Public.enter_cargo_wagon(player, vehicle)
end
end
return Public
return Public

View File

@ -1,7 +1,8 @@
-- Mountain digger fortress, protect the cargo wagon! -- by MewMew
--enable / disable collapsing of the map
local collapse_enabled = false
global.collapse_enabled = true
global.offline_loot = true
local darkness = false
require "player_modifiers"
@ -48,21 +49,25 @@ local function set_difficulty()
-- threat gain / wave
wave_defense_table.threat_gain_multiplier = 2 + player_count * 0.1
--1 additional map collapse tile / 8 players in game
global.map_collapse.speed = math.floor(player_count * 0.125) + 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)
--20 Players for fastest wave_interval
wave_defense_table.wave_interval = 3600 - player_count * 90
if wave_defense_table.wave_interval < 1800 then wave_defense_table.wave_interval = 1800 end
end
function Public.reset_map()
for _,player in pairs(game.players) do
if player.controller_type == defines.controllers.editor then player.toggle_map_editor() end
end
local wave_defense_table = WD.get_table()
global.chunk_queue = {}
global.offline_players = {}
if game.surfaces["cargo_wagon"] then game.delete_surface(game.surfaces["cargo_wagon"]) end
local map_gen_settings = {
["seed"] = math_random(1, 1000000),
["width"] = level_depth,
@ -76,14 +81,14 @@ function Public.reset_map()
["decorative"] = {treat_missing_as_default = true},
},
}
if not global.active_surface_index then
global.active_surface_index = game.create_surface("mountain_fortress", map_gen_settings).index
else
game.forces.player.set_spawn_position({-2, 16}, game.surfaces[global.active_surface_index])
game.forces.player.set_spawn_position({-2, 16}, game.surfaces[global.active_surface_index])
global.active_surface_index = Reset.soft_reset_map(game.surfaces[global.active_surface_index], map_gen_settings, starting_items).index
end
local surface = game.surfaces[global.active_surface_index]
if darkness then
@ -96,15 +101,15 @@ function Public.reset_map()
surface.request_to_generate_chunks({0,0}, 2)
surface.force_generate_chunk_requests()
for x = -768 + 32, 768 - 32, 32 do
surface.request_to_generate_chunks({x, 96}, 1)
surface.force_generate_chunk_requests()
end
game.difficulty_settings.technology_price_multiplier = 0.5
game.difficulty_settings.technology_price_multiplier = 0.5
game.map_settings.enemy_evolution.destroy_factor = 0
game.map_settings.enemy_evolution.pollution_factor = 0
game.map_settings.enemy_evolution.pollution_factor = 0
game.map_settings.enemy_evolution.time_factor = 0
game.map_settings.enemy_expansion.enabled = true
game.map_settings.enemy_expansion.max_expansion_cooldown = 3600
@ -112,30 +117,34 @@ function Public.reset_map()
game.map_settings.enemy_expansion.settler_group_max_size = 8
game.map_settings.enemy_expansion.settler_group_min_size = 16
game.map_settings.pollution.enabled = false
game.forces.player.technologies["land-mine"].enabled = false
game.forces.player.technologies["landfill"].enabled = false
game.forces.player.technologies["land-mine"].enabled = false
game.forces.player.technologies["landfill"].enabled = false
game.forces.player.technologies["railway"].researched = true
game.forces.player.recipes["pistol"].enabled = false
game.forces.player.set_spawn_position({-2, 16}, surface)
game.forces.enemy.set_ammo_damage_modifier("bullet", 1)
game.forces.enemy.set_turret_attack_modifier("gun-turret", 1)
Locomotive.locomotive_spawn(surface, {x = 0, y = 16})
WD.reset_wave_defense()
wave_defense_table.surface_index = global.active_surface_index
wave_defense_table.target = global.locomotive_cargo
wave_defense_table.nest_building_density = 32
wave_defense_table.game_lost = false
game.reset_time_played()
Collapse.init()
RPG.rpg_reset_all_players()
set_difficulty()
end
local function protect_train(event)
if event.entity.force.index ~= 1 then return end --Player Force
if event.entity == global.locomotive_cargo then
if event.entity == global.locomotive_cargo or event.entity.surface.name == "cargo_wagon" then
if event.cause then
if event.cause.force.index == 2 then
return
@ -150,34 +159,34 @@ local function biters_chew_rocks_faster(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 --Enemy Force
event.entity.health = event.entity.health - event.final_damage_amount * 2.5
event.entity.health = event.entity.health - event.final_damage_amount * 5
end
local function hidden_biter(entity)
local d = math.sqrt(entity.position.x ^ 2 + entity.position.y ^ 2)
BiterRolls.wave_defense_set_unit_raffle(d * 0.25)
BiterRolls.wave_defense_set_unit_raffle(d * 0.20)
local unit
if math_random(1,3) == 1 then
unit = entity.surface.create_entity({name = BiterRolls.wave_defense_roll_spitter_name(), position = entity.position})
else
unit = entity.surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = entity.position})
end
local m = 1 / level_depth
m = m * d
if math_random(1, 256) == 1 then
BiterHealthBooster.add_boss_unit(unit, m * 15 + 1, 0.38)
if math_random(1, 64) == 1 then
BiterHealthBooster.add_boss_unit(unit, m * 10 + 1, 0.38)
else
BiterHealthBooster.add_unit(unit, m * 2.5 + 1)
BiterHealthBooster.add_unit(unit, m * 0.1 + 1)
end
end
local function hidden_worm(entity)
BiterRolls.wave_defense_set_worm_raffle(math.sqrt(entity.position.x ^ 2 + entity.position.y ^ 2) * 0.25)
entity.surface.create_entity({name = BiterRolls.wave_defense_roll_worm_name(), position = entity.position})
BiterRolls.wave_defense_set_worm_raffle(math.sqrt(entity.position.x ^ 2 + entity.position.y ^ 2) * 0.20)
entity.surface.create_entity({name = BiterRolls.wave_defense_roll_worm_name(), position = entity.position})
end
local function hidden_biter_pet(event)
@ -199,29 +208,29 @@ local function hidden_treasure(event)
end
local projectiles = {"grenade", "explosive-rocket", "grenade", "explosive-rocket", "explosive-cannon-projectile"}
local function angry_tree(entity, cause)
local function angry_tree(entity, cause)
if entity.type ~= "tree" then return end
if math.abs(entity.position.y) < level_depth then return end
if math_random(1,4) == 1 then hidden_biter(entity) end
if math_random(1,8) == 1 then hidden_worm(entity) end
if math_random(1,16) ~= 1 then return end
local position = false
if cause then
if cause then
if cause.valid then
position = cause.position
end
end
if not position then position = {entity.position.x + (-20 + math_random(0, 40)), entity.position.y + (-20 + math_random(0, 40))} end
entity.surface.create_entity({
name = projectiles[math_random(1, 5)],
position = entity.position,
force = "neutral",
source = entity.position,
target = position,
max_range = 64,
max_range = 64,
speed = 0.10
})
})
end
local function give_coin(player)
@ -229,12 +238,12 @@ local function give_coin(player)
end
local function on_player_mined_entity(event)
if not event.entity.valid then return end
if not event.entity.valid then return end
if event.entity.force.index ~= 3 then return end
if event.entity.type == "simple-entity" then
give_coin(game.players[event.player_index])
if math_random(1,32) == 1 then
hidden_biter(event.entity)
return
@ -244,17 +253,25 @@ local function on_player_mined_entity(event)
return
end
hidden_biter_pet(event)
hidden_treasure(event)
hidden_treasure(event)
end
angry_tree(event.entity, game.players[event.player_index].character)
end
local function on_pre_player_left_game(event)
local player = game.players[event.player_index]
if player.controller_type == defines.controllers.editor then player.toggle_map_editor() end
if player.character then
global.offline_players[#global.offline_players + 1] = {index = event.player_index, tick = game.tick}
end
end
local function on_entity_died(event)
local wave_defense_table = WD.get_table()
if not event.entity.valid then return end
if event.entity == global.locomotive_cargo then
game.print("The cargo was destroyed!")
if event.entity == global.locomotive_cargo then
game.print("The cargo was destroyed!")
wave_defense_table.game_lost = true
wave_defense_table.target = nil
global.game_reset_tick = game.tick + 1800
@ -267,27 +284,28 @@ local function on_entity_died(event)
if event.cause then
if event.cause.valid then
if event.cause.force.index == 2 or event.cause.force.index == 3 then return end
if event.cause.force.index == 2 or event.cause.force.index == 3 then return end
end
end
if event.entity.force.index == 3 then
if event.entity.name == "character" then return end
--local r_max = 15 - math.floor(math.abs(event.entity.position.y) / (level_depth * 0.5))
--if r_max < 3 then r_max = 3 end
if math_random(1,8) == 1 then
hidden_biter(event.entity)
hidden_biter(event.entity)
end
if math_random(1,256) == 1 then hidden_worm(event.entity) end
angry_tree(event.entity, event.cause)
end
end
local function on_entity_damaged(event)
if not event.entity.valid then return end
if not event.entity.valid then return end
protect_train(event)
if not event.entity.health then return end
biters_chew_rocks_faster(event)
--neutral_force_player_damage_resistance(event)
@ -305,29 +323,29 @@ local function on_player_joined_game(event)
local player = game.players[event.player_index]
set_difficulty()
local surface = game.surfaces[global.active_surface_index]
if player.online_time == 0 then
player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 32, 0.5), surface)
for item, amount in pairs(starting_items) do
player.insert({name = item, count = amount})
end
end
if player.surface.index ~= global.active_surface_index and player.surface.name ~= "cargo_wagon" then
if player.surface.index ~= global.active_surface_index and player.surface.name ~= "cargo_wagon" then
player.character = nil
player.set_controller({type=defines.controllers.god})
player.create_character()
player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 32, 0.5), surface)
for item, amount in pairs(starting_items) do
player.insert({name = item, count = amount})
end
end
end
player_modifiers[player.index].character_mining_speed_modifier["mountain_fortress"] = 0.5
Modifier.update_player_modifiers(player)
local tile = surface.get_tile(player.position)
if tile.valid then
if tile.name == "out-of-map" then
@ -340,21 +358,89 @@ local function on_player_left_game(event)
set_difficulty()
end
local function offline_players()
local current_tick = game.tick
local players = global.offline_players
local surface = game.surfaces[global.active_surface_index]
if #players > 0 then
--log("nonzero offline players")
local later = {}
for i = 1, #players, 1 do
if players[i] and game.players[players[i].index] and game.players[players[i].index].connected then
--game.print("deleting already online character from list")
players[i] = nil
else
if players[i] and players[i].tick < game.tick - 54000 then
--log("spawning corpse")
local player_inv = {}
local items = {}
player_inv[1] = game.players[players[i].index].get_inventory(defines.inventory.character_main)
player_inv[2] = game.players[players[i].index].get_inventory(defines.inventory.character_armor)
player_inv[3] = game.players[players[i].index].get_inventory(defines.inventory.character_guns)
player_inv[4] = game.players[players[i].index].get_inventory(defines.inventory.character_ammo)
player_inv[5] = game.players[players[i].index].get_inventory(defines.inventory.character_trash)
local e = surface.create_entity({name = "character", position = game.forces.player.get_spawn_position(surface), force = "neutral"})
local inv = e.get_inventory(defines.inventory.character_main)
for ii = 1, 5, 1 do
if player_inv[ii].valid then
for iii = 1, #player_inv[ii], 1 do
if player_inv[ii][iii].valid then
items[#items + 1] = player_inv[ii][iii]
end
end
end
end
if #items > 0 then
for item = 1, #items, 1 do
if items[item].valid then
inv.insert(items[item])
end
end
game.print({"chronosphere.message_accident"}, {r=0.98, g=0.66, b=0.22})
e.die("neutral")
else
e.destroy()
end
for ii = 1, 5, 1 do
if player_inv[ii].valid then
player_inv[ii].clear()
end
end
players[i] = nil
else
later[#later + 1] = players[i]
end
end
end
players = {}
if #later > 0 then
for i = 1, #later, 1 do
players[#players + 1] = later[i]
end
end
global.offline_players = players
end
end
local function tick()
local tick = game.tick
if tick % 30 == 0 then
if tick % 30 == 0 then
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)
if position then
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 tick % 216000 == 0 then
-- Collapse.delete_out_of_map_chunks(surface)
-- end
if global.offline_loot then
offline_players()
end
end
if global.game_reset_tick then
if global.game_reset_tick < tick then
@ -365,7 +451,7 @@ local function tick()
end
Locomotive.fish_tag()
end
if not collapse_enabled then return end
if not global.collapse_enabled then return end
Collapse.process()
end
@ -377,16 +463,16 @@ local function on_init()
global.rocks_yield_ore_maximum_amount = 999
global.rocks_yield_ore_base_amount = 50
global.rocks_yield_ore_distance_modifier = 0.025
global.explosion_cells_destructible_tiles = {
["out-of-map"] = 1500,
["water"] = 1000,
["water-green"] = 1000,
["deepwater-green"] = 1000,
["deepwater"] = 1000,
["water-shallow"] = 1000,
["water-shallow"] = 1000,
}
Public.reset_map()
end
@ -403,10 +489,11 @@ 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_player_joined_game, on_player_joined_game)
event.add(defines.events.on_player_left_game, on_player_left_game)
event.add(defines.events.on_pre_player_left_game, on_pre_player_left_game)
event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
event.add(defines.events.on_research_finished, on_research_finished)
event.add(defines.events.on_player_driving_changed_state, on_player_driving_changed_state)
require "modules.rocks_yield_ore"
return Public
return Public

View File

@ -11,7 +11,7 @@ local spawner_raffle = {"biter-spawner", "biter-spawner", "biter-spawner", "spit
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_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.0033, 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_ponds"] = {{modifier = 0.01, weight = 1}, {modifier = 0.1, weight = 0.06}},
@ -21,7 +21,7 @@ local noises = {
["cave_rivers_4"] = {{modifier = 0.001, weight = 1}, {modifier = 0.01, weight = 0.11}, {modifier = 0.05, weight = 0.01}},
["scrapyard"] = {{modifier = 0.005, weight = 1}, {modifier = 0.01, weight = 0.35}, {modifier = 0.05, weight = 0.23}, {modifier = 0.1, weight = 0.11}},
}
local level_depth = 960
local level_depth = 704
local worm_level_modifier = 0.18
local function get_noise(name, pos, seed)
@ -52,7 +52,7 @@ local function get_oil_amount(p)
return (math_abs(p.y) * 200 + 10000) * math_random(75, 125) * 0.01
end
local function process_level_10_position(p, seed, tiles, entities, markets, treasure)
local function process_level_11_position(p, seed, tiles, entities, markets, treasure)
local noise_1 = get_noise("small_caves", p, seed)
local noise_2 = get_noise("no_rocks_2", p, seed + 10000)
@ -61,17 +61,17 @@ local function process_level_10_position(p, seed, tiles, entities, markets, trea
if math_random(1,48) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
if noise_1 < -0.72 then
tiles[#tiles + 1] = {name = "lab-dark-1", position = p}
entities[#entities + 1] = {name = "uranium-ore", position = p, amount = math_abs(p.y) + 1 * 3}
return
end
if noise_1 > -0.30 and noise_1 < 0.30 then
if noise_1 > -0.30 and noise_1 < 0.30 then
if noise_1 > -0.14 and noise_1 < 0.14 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,10) > 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,256) == 1 then treasure[#treasure + 1] = p end
else
tiles[#tiles + 1] = {name = "out-of-map", position = p}
@ -79,36 +79,77 @@ local function process_level_10_position(p, seed, tiles, entities, markets, trea
return
end
if math_random(1,64) == 1 and noise_2 > 0.65 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end
if math_random(1,64) == 1 and noise_2 > 0.65 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end
if math_random(1,8192) == 1 then markets[#markets + 1] = p end
if math_random(1,1024) == 1 then entities[#entities + 1] = {name = "crash-site-chest-" .. math_random(1,2), position = p, force = "neutral"} end
tiles[#tiles + 1] = {name = "tutorial-grid", position = p}
end
local function process_level_10_position(p, seed, tiles, entities, markets, treasure)
local scrapyard = get_noise("scrapyard", p, seed)
if scrapyard < -0.70 or scrapyard > 0.70 then
tiles[#tiles + 1] = {name = "grass-3", position = p}
if math_random(1,40) == 1 then treasure[#treasure + 1] = p end
return
end
if scrapyard < -0.65 or scrapyard > 0.65 then
tiles[#tiles + 1] = {name = "water-green", position = p}
return
end
if math_abs(scrapyard) > 0.40 and math_abs(scrapyard) < 0.65 then
if math_random(1,64) == 1 then
Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
end
tiles[#tiles + 1] = {name = "water-mud", position = p}
return
end
if math_abs(scrapyard) > 0.25 and math_abs(scrapyard) < 0.40 then
if math_random(1,128) == 1 then
Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
end
tiles[#tiles + 1] = {name = "water-shallow", position = p}
return
end
if scrapyard > -0.15 and scrapyard < 0.15 then
if math_random(1,100) > 88 then
entities[#entities + 1] = {name = "tree-0" .. math_random(1,9), position = p}
else
if math_random(1,2) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
end
tiles[#tiles + 1] = {name = "dirt-6", position = p}
return
end
tiles[#tiles + 1] = {name = "grass-2", position = p}
end
local function process_level_9_position(p, seed, tiles, entities, markets, treasure)
local maze_p = {x = math_floor(p.x - p.x % 10), y = math_floor(p.y - p.y % 10)}
local maze_noise = get_noise("no_rocks_2", maze_p, seed)
if maze_noise > -0.35 and maze_noise < 0.35 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
local no_rocks_2 = get_noise("no_rocks_2", p, seed)
if math_random(1,4) > 1 and no_rocks_2 > -0.5 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2) == 1 and no_rocks_2 > -0.5 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,1024) == 1 then treasure[#treasure + 1] = p end
if math_random(1,256) == 1 then
Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
end
return
end
if maze_noise > 0 and maze_noise < 0.45 then
if math_random(1,512) == 1 then markets[#markets + 1] = p end
if math_random(1,256) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end
if math_random(1,32) == 1 then entities[#entities + 1] = {name = "tree-0" .. math_random(1, 9), position=p} end
if math_random(1,32) == 1 then entities[#entities + 1] = {name = "tree-0" .. math_random(1, 9), position=p} end
return
end
if maze_noise < -0.5 or maze_noise > 0.5 then
tiles[#tiles + 1] = {name = "deepwater", position = p}
if math_random(1,96) == 1 then entities[#entities + 1] = {name="fish", position=p} end
@ -127,7 +168,7 @@ local scrap_entities_index = #scrap_entities
--SCRAPYARD
local function process_level_8_position(p, seed, tiles, entities, markets, treasure)
local scrapyard = get_noise("scrapyard", p, seed)
--Chasms
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
@ -141,100 +182,102 @@ local function process_level_8_position(p, seed, tiles, entities, markets, treas
return
end
end
if scrapyard < -0.25 or scrapyard > 0.25 then
if math_random(1, 256) == 1 then
entities[#entities + 1] = {name="gun-turret", position=p, force = "enemy"}
end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if scrapyard < -0.55 or scrapyard > 0.55 then
if math_random(1,5) > 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
return
end
if scrapyard < -0.28 or scrapyard > 0.28 then
if math_random(1,128) == 1 then
Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
end
if math_random(1,96) == 1 then entities[#entities + 1] = {name = scrap_entities[math_random(1, scrap_entities_index)], position = p, force = "enemy"} end
if math_random(1,96) == 1 then entities[#entities + 1] = {name = scrap_entities[math_random(1, scrap_entities_index)], position = p, force = "enemy"} end
if math_random(1,5) > 1 then entities[#entities + 1] = {name="mineable-wreckage", position=p} end
if math_random(1,256) == 1 then entities[#entities + 1] = {name ="land-mine", position = p, force = "enemy"} end
return
end
return
end
local cave_ponds = get_noise("cave_ponds", p, seed)
if cave_ponds < -0.6 and scrapyard > -0.2 and scrapyard < 0.2 then
tiles[#tiles + 1] = {name = "deepwater-green", position = p}
if math_random(1,128) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
local large_caves = get_noise("large_caves", p, seed)
if scrapyard > -0.15 and scrapyard < 0.15 then
if math_floor(large_caves * 10) % 4 < 3 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,3) > 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
return
end
end
if math_random(1,64) == 1 and cave_ponds > 0.6 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end
tiles[#tiles + 1] = {name = "stone-path", position = p}
if math_random(1,256) == 1 then entities[#entities +1] = {name ="land-mine", position = p, force = "enemy"} end
end
local function process_level_7_position(p, seed, tiles, entities, markets, treasure)
local cave_rivers_3 = get_noise("cave_rivers_3", p, seed)
local cave_rivers_4 = get_noise("cave_rivers_4", p, seed + 50000)
local cave_rivers_4 = get_noise("cave_rivers_4", p, seed + 50000)
local no_rocks_2 = get_noise("no_rocks_2", p, seed)
if cave_rivers_3 > -0.025 and cave_rivers_3 < 0.025 and no_rocks_2 > -0.6 then
tiles[#tiles + 1] = {name = "water", position = p}
if math_random(1,128) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
if cave_rivers_4 > -0.025 and cave_rivers_4 < 0.025 and no_rocks_2 > -0.6 then
tiles[#tiles + 1] = {name = "water", position = p}
if math_random(1,128) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
local noise_ores = get_noise("no_rocks_2", p, seed + 25000)
if cave_rivers_3 > -0.20 and cave_rivers_3 < 0.20 then
tiles[#tiles + 1] = {name = "grass-" .. math_floor(cave_rivers_3 * 32) % 3 + 1, position = p}
tiles[#tiles + 1] = {name = "grass-" .. math_floor(cave_rivers_3 * 32) % 3 + 1, position = p}
if cave_rivers_3 > -0.10 and cave_rivers_3 < 0.10 then
if math_random(1,12) == 1 and no_rocks_2 > -0.25 then entities[#entities + 1] = {name = "tree-01", position=p} end
if math_random(1,8) == 1 and no_rocks_2 > -0.25 then entities[#entities + 1] = {name = "tree-01", position=p} end
if math_random(1,2048) == 1 then markets[#markets + 1] = p end
if noise_ores < -0.5 and no_rocks_2 > -0.6 then
if cave_rivers_3 > 0 and cave_rivers_3 < 0.07 then
entities[#entities + 1] = {name = "iron-ore", position=p, amount = math_abs(p.y) + 1}
end
end
end
end
if math_random(1,64) == 1 and no_rocks_2 > 0.7 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
return
end
if cave_rivers_4 > -0.20 and cave_rivers_4 < 0.20 then
tiles[#tiles + 1] = {name = "grass-" .. math_floor(cave_rivers_4 * 32) % 3 + 1, position = p}
if cave_rivers_4 > -0.10 and cave_rivers_4 < 0.10 then
if math_random(1,12) == 1 and no_rocks_2 > -0.25 then entities[#entities + 1] = {name = "tree-02", position=p} end
if math_random(1,8) == 1 and no_rocks_2 > -0.25 then entities[#entities + 1] = {name = "tree-02", position=p} end
if math_random(1,2048) == 1 then markets[#markets + 1] = p end
if noise_ores < -0.5 and no_rocks_2 > -0.6 then
if cave_rivers_4 > 0 and cave_rivers_4 < 0.07 then
entities[#entities + 1] = {name = "copper-ore", position=p, amount = math_abs(p.y) + 1}
end
end
end
end
if math_random(1,64) == 1 and no_rocks_2 > 0.7 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
return
end
--Chasms
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
@ -247,17 +290,17 @@ local function process_level_7_position(p, seed, tiles, entities, markets, treas
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,5) > 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,256) == 1 then treasure[#treasure + 1] = p end
end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,100) > 15 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,256) == 1 then treasure[#treasure + 1] = p end
end
local function process_level_6_position(p, seed, tiles, entities, markets, treasure)
local large_caves = get_noise("large_caves", p, seed)
local cave_rivers = get_noise("cave_rivers", p, seed)
--Chasms
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
@ -271,77 +314,77 @@ local function process_level_6_position(p, seed, tiles, entities, markets, treas
return
end
end
if large_caves > -0.03 and large_caves < 0.03 and cave_rivers < 0.25 then
tiles[#tiles + 1] = {name = "water-green", position = p}
if math_random(1,128) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
if cave_rivers > -0.05 and cave_rivers < 0.05 then
if math_random(1,48) == 1 then entities[#entities + 1] = {name = "tree-0" .. math_random(1, 9), position=p} end
if cave_rivers > -0.1 and cave_rivers < 0.1 then
if math_random(1,36) == 1 then entities[#entities + 1] = {name = "tree-0" .. math_random(1, 9), position=p} end
if math_random(1,128) == 1 then
Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
end
else
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,8) > 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,100) > 15 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,512) == 1 then treasure[#treasure + 1] = p end
if math_random(1,4096) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end
if math_random(1,8096) == 1 then markets[#markets + 1] = p end
end
end
local function process_level_5_position(p, seed, tiles, entities, 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
if small_caves > -0.24 and small_caves < 0.24 then
tiles[#tiles + 1] = {name = "dirt-7", 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 = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
return
end
if small_caves < -0.50 or small_caves > 0.50 then
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)
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
end
return
end
if small_caves > -0.30 and small_caves < 0.30 then
if noise_cave_ponds > 0.35 then
end
if small_caves > -0.40 and small_caves < 0.40 then
if noise_cave_ponds > 0.35 then
tiles[#tiles + 1] = {name = "dirt-" .. math_random(1, 4), 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
end
if noise_cave_ponds > 0.25 then
tiles[#tiles + 1] = {name = "dirt-7", 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 = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
return
end
end
tiles[#tiles + 1] = {name = "out-of-map", position = p}
end
local function process_level_4_position(p, seed, tiles, entities, markets, treasure)
local function process_level_4_position(p, seed, tiles, entities, markets, treasure)
local noise_large_caves = get_noise("large_caves", p, seed)
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
local small_caves = get_noise("small_caves", p, seed)
if math_abs(noise_large_caves) > 0.7 then
tiles[#tiles + 1] = {name = "water", position = p}
if math_random(1,16) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
end
if math_abs(noise_large_caves) > 0.6 then
if math_random(1,16) == 1 then entities[#entities + 1] = {name="tree-02", position=p} end
if math_random(1,32) == 1 then markets[#markets + 1] = p end
@ -351,53 +394,53 @@ local function process_level_4_position(p, seed, tiles, entities, markets, treas
if math_random(1,620) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end
if math_random(1,384) == 1 then
Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
end
if math_random(1, 1024) == 1 then treasure[#treasure + 1] = p end
return
end
if math_abs(noise_large_caves) > 0.475 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,3) > 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
return
end
--Chasms
if noise_cave_ponds < 0.15 and noise_cave_ponds > -0.15 then
if small_caves > 0.45 then
if small_caves > 0.75 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
if small_caves < -0.45 then
if small_caves < -0.75 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
end
if small_caves > -0.15 and small_caves < 0.15 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,5) > 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1, 1024) == 1 then treasure[#treasure + 1] = p end
return
end
if noise_large_caves > -0.1 and noise_large_caves < 0.1 then
end
if noise_large_caves > -0.2 and noise_large_caves < 0.2 then
--Main Rock 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 = "dirt-" .. math_floor(no_rocks_2 * 8) % 2 + 5, position = p}
if math_random(1,512) == 1 then treasure[#treasure + 1] = p end
return
return
end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,100) > 30 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,100) > 30 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
return
end
tiles[#tiles + 1] = {name = "out-of-map", position = p}
end
@ -406,12 +449,12 @@ local function process_level_3_position(p, seed, tiles, entities, markets, treas
local small_caves_2 = get_noise("small_caves_2", p, seed + 70000)
local noise_large_caves = get_noise("large_caves", p, seed + 60000)
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
--Market Spots
if noise_cave_ponds < -0.77 then
--Market Spots
if noise_cave_ponds < -0.77 then
if noise_cave_ponds > -0.79 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p}
entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p}
else
tiles[#tiles + 1] = {name = "grass-" .. math_floor(noise_cave_ponds * 32) % 3 + 1, position = p}
if math_random(1,32) == 1 then markets[#markets + 1] = p end
@ -420,58 +463,58 @@ local function process_level_3_position(p, seed, tiles, entities, markets, treas
return
end
if noise_large_caves > -0.2 and noise_large_caves < 0.2 or small_caves_2 > 0 then
if noise_large_caves > -0.15 and noise_large_caves < 0.15 or small_caves_2 > 0 then
--Green Water Ponds
if noise_cave_ponds > 0.80 then
tiles[#tiles + 1] = {name = "deepwater-green", position = p}
if math_random(1,16) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
--Chasms
if noise_cave_ponds < 0.12 and noise_cave_ponds > -0.12 then
if small_caves > 0.55 then
if small_caves > 0.85 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
if small_caves < -0.55 then
if small_caves < -0.85 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
--Rivers
local cave_rivers = get_noise("cave_rivers", p, seed + 100000)
if cave_rivers < 0.014 and cave_rivers > -0.014 then
if cave_rivers < 0.024 and cave_rivers > -0.024 then
if noise_cave_ponds > 0.2 then
tiles[#tiles + 1] = {name = "water-shallow", position = p}
if math_random(1,64) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
return
end
end
local cave_rivers_2 = get_noise("cave_rivers_2", p, seed)
if cave_rivers_2 < 0.024 and cave_rivers_2 > -0.024 then
if noise_cave_ponds < 0.5 then
tiles[#tiles + 1] = {name = "water", position = p}
if noise_cave_ponds < 0.4 then
tiles[#tiles + 1] = {name = "water-shallow", position = p}
if math_random(1,64) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
return
end
end
if noise_cave_ponds > 0.775 then
end
if noise_cave_ponds > 0.725 then
tiles[#tiles + 1] = {name = "dirt-" .. math_random(4, 6), position = p}
return
end
return
end
local no_rocks = get_noise("no_rocks", p, seed + 25000)
--Worm oil Zones
if no_rocks < 0.15 and no_rocks > -0.15 then
if no_rocks < 0.20 and no_rocks > -0.20 then
if small_caves > 0.35 then
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
Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
end
if math_random(1,512) == 1 then treasure[#treasure + 1] = p end
if math_random(1,64) == 1 then entities[#entities + 1] = {name = "dead-tree-desert", position=p} end
@ -484,26 +527,26 @@ local function process_level_3_position(p, seed, tiles, entities, markets, treas
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}
if math_random(1,512) == 1 then treasure[#treasure + 1] = p end
return
return
end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,100) > 30 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,100) > 30 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
return
end
tiles[#tiles + 1] = {name = "out-of-map", position = p}
end
local function process_level_2_position(p, seed, tiles, entities, markets, treasure)
local small_caves = get_noise("small_caves", p, seed)
local small_caves = get_noise("small_caves", p, seed)
local noise_large_caves = get_noise("large_caves", p, seed)
if noise_large_caves > -0.75 and noise_large_caves < 0.75 then
if noise_large_caves > -0.75 and noise_large_caves < 0.75 then
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
--Chasms
if noise_cave_ponds < 0.15 and noise_cave_ponds > -0.15 then
if small_caves > 0.32 then
@ -514,78 +557,78 @@ local function process_level_2_position(p, seed, tiles, entities, markets, treas
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
end
--Green Water Ponds
if noise_cave_ponds > 0.80 then
tiles[#tiles + 1] = {name = "deepwater-green", position = p}
if math_random(1,16) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
--Rivers
local cave_rivers = get_noise("cave_rivers", p, seed + 100000)
if cave_rivers < 0.027 and cave_rivers > -0.027 then
if cave_rivers < 0.037 and cave_rivers > -0.037 then
if noise_cave_ponds < 0.1 then
tiles[#tiles + 1] = {name = "water-shallow", position = p}
if math_random(1,64) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
return
end
end
if noise_cave_ponds > 0.76 then
if noise_cave_ponds > 0.66 then
tiles[#tiles + 1] = {name = "dirt-" .. math_random(4, 6), position = p}
return
end
--Market Spots
return
end
--Market Spots
if noise_cave_ponds < -0.80 then
tiles[#tiles + 1] = {name = "grass-" .. math_floor(noise_cave_ponds * 32) % 3 + 1, position = p}
if math_random(1,32) == 1 then markets[#markets + 1] = p end
if math_random(1,16) == 1 then entities[#entities + 1] = {name = "tree-0" .. math_random(1, 9), position=p} end
return
end
local no_rocks = get_noise("no_rocks", p, seed + 25000)
--Worm oil Zones
if no_rocks < 0.15 and no_rocks > -0.15 then
if small_caves > 0.35 then
--Worm oil Zones
if no_rocks < 0.20 and no_rocks > -0.20 then
if small_caves > 0.30 then
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,64) == 1 then
Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
end
if math_random(1,1024) == 1 then treasure[#treasure + 1] = p end
if math_random(1,64) == 1 then entities[#entities + 1] = {name = "dead-tree-desert", position=p} end
return
end
end
--Main Rock 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 = "dirt-" .. math_floor(no_rocks_2 * 8) % 2 + 5, position = p}
if math_random(1,512) == 1 then treasure[#treasure + 1] = p end
return
return
end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,100) > 30 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,100) > 25 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
return
end
tiles[#tiles + 1] = {name = "out-of-map", position = p}
end
local function process_level_1_position(p, seed, tiles, entities, markets, treasure)
local small_caves = get_noise("small_caves", p, seed)
local small_caves = get_noise("small_caves", p, seed)
local noise_large_caves = get_noise("large_caves", p, seed)
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
--Chasms
if noise_cave_ponds < 0.12 and noise_cave_ponds > -0.12 then
if small_caves > 0.55 then
@ -597,47 +640,47 @@ local function process_level_1_position(p, seed, tiles, entities, markets, treas
return
end
end
--Green Water Ponds
if noise_cave_ponds > 0.80 then
tiles[#tiles + 1] = {name = "deepwater-green", position = p}
if math_random(1,16) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
--Rivers
local cave_rivers = get_noise("cave_rivers", p, seed + 100000)
if cave_rivers < 0.024 and cave_rivers > -0.024 then
if cave_rivers < 0.044 and cave_rivers > -0.044 then
if noise_cave_ponds > 0 then
tiles[#tiles + 1] = {name = "water-shallow", position = p}
if math_random(1,64) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
return
end
end
if noise_cave_ponds > 0.76 then
tiles[#tiles + 1] = {name = "dirt-" .. math_random(4, 6), position = p}
return
end
return
end
--Market Spots
--Market Spots
if noise_cave_ponds < -0.75 then
tiles[#tiles + 1] = {name = "grass-" .. math_floor(noise_cave_ponds * 32) % 3 + 1, position = p}
if math_random(1,32) == 1 then markets[#markets + 1] = p end
if math_random(1,32) == 1 then entities[#entities + 1] = {name = "tree-0" .. math_random(1, 9), position=p} end
return
end
local no_rocks = get_noise("no_rocks", p, seed + 25000)
--Worm oil Zones
if p.y < -64 + noise_cave_ponds * 10 then
if no_rocks < 0.08 and no_rocks > -0.08 then
if small_caves > 0.35 then
if no_rocks < 0.12 and no_rocks > -0.12 then
if small_caves > 0.30 then
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)
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
end
if math_random(1,1024) == 1 then treasure[#treasure + 1] = p end
if math_random(1,64) == 1 then entities[#entities + 1] = {name = "dead-tree-desert", position=p} end
@ -645,19 +688,19 @@ local function process_level_1_position(p, seed, tiles, entities, markets, treas
end
end
end
--Main Rock 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
if no_rocks_2 > 0.65 or no_rocks_2 < -0.65 then
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 = "dead-tree-desert", position=p} end
if math_random(1,512) == 1 then treasure[#treasure + 1] = p end
return
return
end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,100) > 30 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,100) > 25 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
end
local levels = {
@ -671,18 +714,19 @@ local levels = {
process_level_8_position,
process_level_9_position,
process_level_10_position,
process_level_11_position,
}
local entity_functions = {
["turret"] = function(surface, entity) surface.create_entity(entity) end,
["simple-entity"] = function(surface, entity) surface.create_entity(entity) end,
["ammo-turret"] = function(surface, entity)
["ammo-turret"] = function(surface, entity)
local e = surface.create_entity(entity)
e.insert({name = "uranium-rounds-magazine", count = math_random(16, 64)})
end,
["container"] = function(surface, entity)
Treasure(surface, entity.position, entity.name)
end,
["container"] = function(surface, entity)
Treasure(surface, entity.position, entity.name)
end,
}
local function rock_chunk(surface, left_top)
@ -691,8 +735,8 @@ local function rock_chunk(surface, left_top)
local markets = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
local level_index = math_floor((math_abs(left_top.y / level_depth)) % 10) + 1
local level_index = math_floor((math_abs(left_top.y / level_depth)) % 11) + 1
local process_level = levels[level_index]
for y = 0, 31, 1 do
@ -710,13 +754,13 @@ local function rock_chunk(surface, left_top)
market.destructible = false
end
end
for _, p in pairs(treasure) do
local name = "wooden-chest"
if math_random(1, 6) == 1 then name = "iron-chest" end
Treasure(surface, p, name)
Treasure(surface, p, name)
end
for _, entity in pairs(entities) do
if entity_functions[game.entity_prototypes[entity.name].type] then
entity_functions[game.entity_prototypes[entity.name].type](surface, entity)
@ -734,11 +778,11 @@ local function border_chunk(surface, left_top)
for y = 5, 31, 1 do
local pos = {x = left_top.x + x, y = left_top.y + y}
if math_random(1, math.ceil(pos.y + pos.y) + 64) == 1 then
surface.create_entity({name = trees[math_random(1, #trees)], position = pos})
surface.create_entity({name = trees[math_random(1, #trees)], position = pos})
end
end
end
end
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top.x + x, y = left_top.y + y}
@ -765,13 +809,13 @@ local function border_chunk(surface, left_top)
{name = "rock-tiny", position = pos, amount = math_random(1, 1 + math.ceil(20 - y / 2))}
}
}
end
end
if math_random(1, math.ceil(pos.y + pos.y) + 2) == 1 then
surface.create_entity({name = rock_raffle[math_random(1, size_of_rock_raffle)], position = pos})
surface.create_entity({name = rock_raffle[math_random(1, size_of_rock_raffle)], position = pos})
end
end
end
for _, e in pairs(surface.find_entities_filtered({area = {{left_top.x, left_top.y},{left_top.x + 32, left_top.y + 32}}, type = "cliff"})) do e.destroy() end
end
@ -790,15 +834,15 @@ local function biter_chunk(surface, left_top)
local e = surface.create_entity({name = spawner_raffle[math_random(1, #spawner_raffle)], position = position, force = "enemy"})
e.destructible = false
e.active = false
end
end
end
for i = 1, 3, 1 do
local position = surface.find_non_colliding_position("big-worm-turret", tile_positions[math_random(1, #tile_positions)], 16, 2)
if position then
local e = surface.create_entity({name = "big-worm-turret", position = position, force = "enemy"})
e.destructible = false
end
end
end
--for _, e in pairs(surface.find_entities_filtered({area = {{left_top.x, left_top.y},{left_top.x + 32, left_top.y + 32}}, type = "cliff"})) do e.destroy() end
end
@ -809,15 +853,15 @@ local function replace_water(surface, left_top)
local p = {x = left_top.x + x, y = left_top.y + y}
if surface.get_tile(p).collides_with("resource-layer") then
surface.set_tiles({{name = get_replacement_tile(surface, p), position = p}}, true)
end
end
end
end
end
end
local function out_of_map(surface, left_top)
for x = 0, 31, 1 do
for y = 0, 31, 1 do
surface.set_tiles({{name = "out-of-map", position = {x = left_top.x + x, y = left_top.y + y}}})
surface.set_tiles({{name = "out-of-map", position = {x = left_top.x + x, y = left_top.y + y}}})
end
end
end
@ -827,31 +871,31 @@ local function wall(surface, left_top, seed)
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
local small_caves = get_noise("small_caves", p, seed)
local small_caves = get_noise("small_caves", p, seed)
local cave_ponds = get_noise("cave_rivers", p, seed + 100000)
if y > 9 + cave_ponds * 6 and y < 23 + small_caves * 6 then
if small_caves > 0.05 or cave_ponds > 0.05 then
if small_caves > 0.15 or cave_ponds > 0.15 then
--surface.set_tiles({{name = "water-shallow", position = p}})
surface.set_tiles({{name = "deepwater", position = p}})
if math_random(1,48) == 1 then surface.create_entity({name = "fish", position = p}) end
else
surface.set_tiles({{name = "dirt-7", position = p}})
if math_random(1, 5) ~= 1 then
if math_random(1, 2) == 1 then
surface.create_entity({name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p})
end
end
else
surface.set_tiles({{name = "dirt-7", position = p}})
if surface.can_place_entity({name = "stone-wall", position = p, force = "enemy"}) then
if math_random(1,512) == 1 and y > 3 and y < 28 then
if math_random(1, 2) == 1 then
if math_random(1,512) == 1 and y > 3 and y < 28 then
if math_random(1, 2) == 1 then
Treasure(surface, p, "wooden-chest")
else
Treasure(surface, p, "iron-chest")
end
else
if y < 5 or y > 26 then
if y <= 15 then
if math_random(1, y + 1) == 1 then
@ -865,21 +909,23 @@ local function wall(surface, left_top, seed)
end
end
end
end
end
end
end
if math_random(1, 16) == 1 then
if surface.can_place_entity({name = "small-worm-turret", position = p, force = "enemy"}) then
Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
surface.create_entity({name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"})
end
end
if math_random(1, 32) == 1 then
if surface.can_place_entity({name = "gun-turret", position = p, force = "enemy"}) then
local e = surface.create_entity({name = "gun-turret", position = p, force = "enemy"})
if math_abs(p.y) < level_depth * 2.5 then
e.insert({name = "firearm-magazine", count = math_random(64, 128)})
elseif math_abs(p.y) < level_depth * 4.5 then
e.insert({name = "piercing-rounds-magazine", count = math_random(64, 128)})
else
e.insert({name = "uranium-rounds-magazine", count = math_random(64, 128)})
@ -896,11 +942,11 @@ local function process_chunk(surface, left_top)
if not surface.valid then return end
if left_top.x >= level_depth * 0.5 then return end
if left_top.x < level_depth * -0.5 then return end
if left_top.y % level_depth == 0 and left_top.y < 0 then wall(surface, left_top, surface.map_gen_settings.seed) return end
if left_top.y >= 0 then replace_water(surface, left_top) end
if left_top.y > 32 then game.forces.player.chart(surface, {{left_top.x, left_top.y},{left_top.x + 31, left_top.y + 31}}) end
if left_top.y > 32 then game.forces.player.chart(surface, {{left_top.x, left_top.y},{left_top.x + 31, left_top.y + 31}}) end
if left_top.y == -128 and left_top.x == -128 then
local p = global.locomotive.position
for _, entity in pairs(surface.find_entities_filtered({area = {{p.x - 3, p.y - 4},{p.x + 3, p.y + 10}}, type = "simple-entity"})) do entity.destroy() end
@ -919,4 +965,4 @@ end
local event = require 'utils.event'
event.add(defines.events.on_chunk_generated, on_chunk_generated)
return level_depth
return level_depth

View File

@ -7,24 +7,29 @@ local math_abs = math.abs
local LootRaffle = require "functions.loot_raffle"
function Public.treasure_chest(surface, position, container_name)
local budget = 32 + math_abs(position.y) * 6
local budget = 32 + math_abs(position.y) * 2
budget = budget * math_random(25, 175) * 0.01
if math_random(1,200) == 1 then
budget = budget * 10
container_name = "compilatron-chest"
end
budget = math_floor(budget) + 1
local item_stacks = LootRaffle.roll(budget, 16)
local item_stacks = LootRaffle.roll(budget, 8)
local container = surface.create_entity({name = container_name, position = position, force = "neutral"})
for _, item_stack in pairs(item_stacks) do
container.insert(item_stack)
end
end
container.minable = false
end
function Public.treasure_chest_old(surface, position, container_name)
local chest_raffle = {}
local chest_loot = {
{{name = "submachine-gun", count = math_random(1,3)}, weight = 3, d_min = 0.0, d_max = 0.1},
local chest_loot = {
{{name = "submachine-gun", count = math_random(1,3)}, weight = 3, d_min = 0.0, d_max = 0.1},
{{name = "slowdown-capsule", count = math_random(16,32)}, weight = 1, d_min = 0.3, d_max = 0.7},
{{name = "poison-capsule", count = math_random(8,16)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "poison-capsule", count = math_random(8,16)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "uranium-cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.6, d_max = 1},
{{name = "cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.4, d_max = 0.7},
{{name = "explosive-uranium-cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.6, d_max = 1},
@ -36,7 +41,7 @@ function Public.treasure_chest_old(surface, position, container_name)
{{name = "flamethrower", count = 1}, weight = 3, d_min = 0.3, d_max = 0.6},
{{name = "flamethrower-ammo", count = math_random(16,32)}, weight = 5, d_min = 0.3, d_max = 1},
{{name = "rocket-launcher", count = 1}, weight = 3, d_min = 0.2, d_max = 0.6},
{{name = "rocket", count = math_random(16,32)}, weight = 5, d_min = 0.2, d_max = 0.7},
{{name = "rocket", count = math_random(16,32)}, weight = 5, d_min = 0.2, d_max = 0.7},
{{name = "explosive-rocket", count = math_random(16,32)}, weight = 5, d_min = 0.3, d_max = 1},
{{name = "land-mine", count = math_random(16,32)}, weight = 5, d_min = 0.2, d_max = 0.7},
{{name = "grenade", count = math_random(16,32)}, weight = 5, d_min = 0.0, d_max = 0.5},
@ -49,8 +54,8 @@ function Public.treasure_chest_old(surface, position, container_name)
{{name = "defender-capsule", count = math_random(8,16)}, weight = 2, d_min = 0.0, d_max = 0.7},
{{name = "distractor-capsule", count = math_random(8,16)}, weight = 2, d_min = 0.2, d_max = 1},
{{name = "destroyer-capsule", count = math_random(8,16)}, weight = 2, d_min = 0.3, d_max = 1},
{{name = "atomic-bomb", count = 1}, weight = 1, d_min = 0.8, d_max = 1},
{{name = "light-armor", count = 1}, weight = 3, d_min = 0, d_max = 0.1},
{{name = "atomic-bomb", count = 1}, weight = 1, d_min = 0.8, d_max = 1},
{{name = "light-armor", count = 1}, weight = 3, d_min = 0, d_max = 0.1},
{{name = "heavy-armor", count = 1}, weight = 3, d_min = 0.1, d_max = 0.3},
{{name = "modular-armor", count = 1}, weight = 2, d_min = 0.2, d_max = 0.6},
{{name = "power-armor", count = 1}, weight = 1, d_min = 0.4, d_max = 1},
@ -60,18 +65,19 @@ function Public.treasure_chest_old(surface, position, container_name)
{{name = "belt-immunity-equipment", count = 1}, weight = 1, d_min = 0.5, d_max = 1},
{{name = "solar-panel-equipment", count = math_random(1,4)}, weight = 5, d_min = 0.4, d_max = 0.8},
{{name = "discharge-defense-equipment", count = 1}, weight = 1, d_min = 0.5, d_max = 1},
{{name = "discharge-defense-remote", count = 1}, weight = 1, d_min = 0.5, d_max = 1},
{{name = "energy-shield-equipment", count = math_random(1,2)}, weight = 2, d_min = 0.3, d_max = 0.8},
--{{name = "energy-shield-mk2-equipment", count = 1}, weight = 2, d_min = 0.8, d_max = 1},
{{name = "exoskeleton-equipment", count = 1}, weight = 1, d_min = 0.3, d_max = 1},
--{{name = "fusion-reactor-equipment", count = 1}, weight = 1, d_min = 0.8, d_max = 1},
{{name = "night-vision-equipment", count = 1}, weight = 1, d_min = 0.3, d_max = 0.8},
{{name = "personal-laser-defense-equipment", count = 1}, weight = 1, d_min = 0.7, d_max = 1},
{{name = "personal-roboport-equipment", count = math_random(1,2)}, weight = 3, d_min = 0.4, d_max = 1},
--{{name = "personal-roboport-mk2-equipment", count = 1}, weight = 1, d_min = 0.9, d_max = 1},
{{name = "logistic-robot", count = math_random(5,25)}, weight = 2, d_min = 0.5, d_max = 1},
{{name = "construction-robot", count = math_random(5,25)}, weight = 5, d_min = 0.4, d_max = 1},
{{name = "iron-gear-wheel", count = math_random(80,100)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "copper-cable", count = math_random(100,200)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "engine-unit", count = math_random(16,32)}, weight = 2, d_min = 0.1, d_max = 0.5},
@ -84,11 +90,11 @@ function Public.treasure_chest_old(surface, position, container_name)
{{name = "lubricant-barrel", count = math_random(4,10)}, weight = 1, d_min = 0.3, d_max = 0.5},
{{name = "rocket-fuel", count = math_random(4,10)}, weight = 2, d_min = 0.3, d_max = 0.7},
--{{name = "computer", count = 1}, weight = 2, d_min = 0, d_max = 1},
{{name = "effectivity-module", count = math_random(1,4)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "productivity-module", count = math_random(1,4)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "speed-module", count = math_random(1,4)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "automation-science-pack", count = math_random(16,64)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "logistic-science-pack", count = math_random(16,64)}, weight = 3, d_min = 0.1, d_max = 0.5},
{{name = "military-science-pack", count = math_random(16,64)}, weight = 3, d_min = 0.2, d_max = 1},
@ -99,21 +105,21 @@ function Public.treasure_chest_old(surface, position, container_name)
{{name = "steel-plate", count = math_random(25,75)}, weight = 2, d_min = 0.1, d_max = 0.3},
{{name = "nuclear-fuel", count = 1}, weight = 2, d_min = 0.7, d_max = 1},
{{name = "burner-inserter", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.1},
{{name = "inserter", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.4},
{{name = "long-handed-inserter", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.4},
{{name = "long-handed-inserter", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.4},
{{name = "fast-inserter", count = math_random(8,16)}, weight = 3, d_min = 0.1, d_max = 1},
{{name = "filter-inserter", count = math_random(8,16)}, weight = 1, d_min = 0.2, d_max = 1},
{{name = "filter-inserter", count = math_random(8,16)}, weight = 1, d_min = 0.2, d_max = 1},
{{name = "stack-filter-inserter", count = math_random(4,8)}, weight = 1, d_min = 0.4, d_max = 1},
{{name = "stack-inserter", count = math_random(4,8)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "stack-inserter", count = math_random(4,8)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "small-electric-pole", count = math_random(16,24)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "medium-electric-pole", count = math_random(8,16)}, weight = 3, d_min = 0.2, d_max = 1},
{{name = "big-electric-pole", count = math_random(4,8)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "substation", count = math_random(2,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "wooden-chest", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "iron-chest", count = math_random(8,16)}, weight = 3, d_min = 0.1, d_max = 0.4},
{{name = "steel-chest", count = math_random(8,16)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "steel-chest", count = math_random(8,16)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "small-lamp", count = math_random(16,32)}, weight = 3, d_min = 0.1, d_max = 0.3},
{{name = "rail", count = math_random(25,75)}, weight = 3, d_min = 0.1, d_max = 0.6},
{{name = "assembling-machine-1", count = math_random(2,4)}, weight = 3, d_min = 0.0, d_max = 0.3},
@ -132,22 +138,22 @@ function Public.treasure_chest_old(surface, position, container_name)
{{name = "arithmetic-combinator", count = math_random(4,8)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "constant-combinator", count = math_random(4,8)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "decider-combinator", count = math_random(4,8)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "power-switch", count = 1}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "power-switch", count = 1}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "programmable-speaker", count = math_random(2,4)}, weight = 1, d_min = 0.1, d_max = 1},
{{name = "green-wire", count = math_random(50,99)}, weight = 4, d_min = 0.1, d_max = 1},
{{name = "red-wire", count = math_random(50,99)}, weight = 4, d_min = 0.1, d_max = 1},
{{name = "chemical-plant", count = math_random(1,3)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "burner-mining-drill", count = math_random(2,4)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "electric-mining-drill", count = math_random(2,4)}, weight = 3, d_min = 0.2, d_max = 1},
{{name = "electric-mining-drill", count = math_random(2,4)}, weight = 3, d_min = 0.2, d_max = 1},
{{name = "express-transport-belt", count = math_random(25,75)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "express-underground-belt", count = math_random(4,8)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "express-underground-belt", count = math_random(4,8)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "express-splitter", count = math_random(1,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "fast-transport-belt", count = math_random(25,75)}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = "fast-underground-belt", count = math_random(4,8)}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = "fast-splitter", count = math_random(1,4)}, weight = 3, d_min = 0.2, d_max = 0.3},
{{name = "transport-belt", count = math_random(25,75)}, weight = 3, d_min = 0, d_max = 0.3},
{{name = "underground-belt", count = math_random(4,8)}, weight = 3, d_min = 0, d_max = 0.3},
{{name = "splitter", count = math_random(1,4)}, weight = 3, d_min = 0, d_max = 0.3},
{{name = "splitter", count = math_random(1,4)}, weight = 3, d_min = 0, d_max = 0.3},
--{{name = "oil-refinery", count = math_random(2,4)}, weight = 2, d_min = 0.3, d_max = 1},
{{name = "pipe", count = math_random(30,50)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "pipe-to-ground", count = math_random(4,8)}, weight = 1, d_min = 0.2, d_max = 0.5},
@ -156,10 +162,10 @@ function Public.treasure_chest_old(surface, position, container_name)
{{name = "solar-panel", count = math_random(3,6)}, weight = 3, d_min = 0.4, d_max = 0.9},
{{name = "electric-furnace", count = math_random(2,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "steel-furnace", count = math_random(4,8)}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = "stone-furnace", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "stone-furnace", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "radar", count = math_random(1,2)}, weight = 1, d_min = 0.1, d_max = 0.4},
{{name = "rail-signal", count = math_random(8,16)}, weight = 2, d_min = 0.2, d_max = 0.8},
{{name = "rail-chain-signal", count = math_random(8,16)}, weight = 2, d_min = 0.2, d_max = 0.8},
{{name = "rail-chain-signal", count = math_random(8,16)}, weight = 2, d_min = 0.2, d_max = 0.8},
{{name = "stone-wall", count = math_random(33,99)}, weight = 3, d_min = 0.0, d_max = 0.7},
{{name = "gate", count = math_random(16,32)}, weight = 3, d_min = 0.0, d_max = 0.7},
{{name = "storage-tank", count = math_random(2,6)}, weight = 3, d_min = 0.3, d_max = 0.6},
@ -167,25 +173,29 @@ function Public.treasure_chest_old(surface, position, container_name)
{{name = "express-loader", count = math_random(1,2)}, weight = 1, d_min = 0.5, d_max = 1},
{{name = "fast-loader", count = math_random(1,2)}, weight = 1, d_min = 0.2, d_max = 0.7},
{{name = "loader", count = math_random(1,2)}, weight = 1, d_min = 0.0, d_max = 0.5},
{{name = "lab", count = math_random(1,2)}, weight = 2, d_min = 0.0, d_max = 0.3},
{{name = "lab", count = math_random(1,2)}, weight = 2, d_min = 0.0, d_max = 0.3},
{{name = "roboport", count = 1}, weight = 2, d_min = 0.8, d_max = 1},
{{name = "flamethrower-turret", count = 1}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "laser-turret", count = math_random(3,6)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "flamethrower-turret", count = 1}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "laser-turret", count = math_random(3,6)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "gun-turret", count = math_random(2,4)}, weight = 3, d_min = 0.2, d_max = 0.9},
{{name = 'crude-oil-barrel', count = math_random(2,4)}, weight = 3, d_min = 0.1, d_max = 0.3},
{{name = 'crude-oil-barrel', count = math_random(4,8)}, weight = 3, d_min = 0.2, d_max = 0.5},
{{name = 'crude-oil-barrel', count = math_random(8,16)}, weight = 3, d_min = 0.4, d_max = 0.7},
{{name = 'crude-oil-barrel', count = math_random(12,24)}, weight = 3, d_min = 0.6, d_max = 0.9},
}
local distance_to_center = (math.abs(position.y) + 1) * 0.0002
if distance_to_center > 1 then distance_to_center = 1 end
for _, t in pairs (chest_loot) do
for x = 1, t.weight, 1 do
if t.d_min <= distance_to_center and t.d_max >= distance_to_center then
table.insert(chest_raffle, t[1])
end
end
end
end
local e = surface.create_entity({name = container_name, position=position, force="neutral", create_build_effect_smoke = false})
local e = surface.create_entity({name = container_name, position=position, force="neutral", create_build_effect_smoke = false})
e.minable = false
local i = e.get_inventory(defines.inventory.chest)
for x = 1, math_random(2,6), 1 do
@ -194,4 +204,4 @@ function Public.treasure_chest_old(surface, position, container_name)
end
end
return Public.treasure_chest
return Public.treasure_chest

View File

@ -0,0 +1,636 @@
local event = require 'utils.event'
local math_random = math.random
local math_floor = math.floor
global.biter_command = {}
global.biter_command.active_unit_groups = {}
global.biter_command.enabled = true
global.biter_command.whitelist = {}
global.biter_command.admin_mode = true --if only admins can see and use the panel
global.biter_command.teleporting = false --if teleporting is allowed for non-admins
local worm_raffle = {
"small-worm-turret", "small-worm-turret", "medium-worm-turret", "small-worm-turret",
"medium-worm-turret", "medium-worm-turret", "big-worm-turret", "medium-worm-turret",
"big-worm-turret","big-worm-turret","behemoth-worm-turret", "big-worm-turret",
"behemoth-worm-turret","behemoth-worm-turret","behemoth-worm-turret","big-worm-turret","behemoth-worm-turret"
}
local function shuffle(tbl)
local size = #tbl
for i = size, 1, -1 do
local rand = math_random(size)
tbl[i], tbl[rand] = tbl[rand], tbl[i]
end
return tbl
end
local function is_closer(pos1, pos2, pos)
return ((pos1.x - pos.x)^2 + (pos1.y - pos.y)^2) < ((pos2.x - pos.x)^2 + (pos2.y - pos.y)^2)
end
local function shuffle_distance(tbl, position)
local size = #tbl
for i = size, 1, -1 do
local rand = math_random(size)
if is_closer(tbl[i].position, tbl[rand].position, position) and i > rand then
tbl[i], tbl[rand] = tbl[rand], tbl[i]
end
end
return tbl
end
local function get_evo(force)
local evo = math_floor(game.forces["enemy"].evolution_factor * 20)
local nests = math_random(1 + evo, 2 + evo * 2 )
end
local function place_nest_near_unit_group(group)
if not group.members then return false end
if #group.members < 5 then return false end
local units = group.members
shuffle(units)
for i = 1, 5, 1 do
if not units[i].valid then return false end
end
local name = "biter-spawner"
if math_random(1, 3) == 1 then name = "spitter-spawner" end
local position = group.surface.find_non_colliding_position(name, group.position, 16, 1)
if not position then return false end
group.surface.create_entity({name = name, position = position, force = group.force})
group.surface.create_entity({name = "blood-explosion-huge", position = position})
for i = 1, 5, 1 do
units[i].surface.create_entity({name = "blood-explosion-huge", position = units[i].position})
units[i].destroy()
end
return true
end
local function build_worm(group)
if not group.members then return false end
if #group.members < 5 then return false end
local units = group.members
shuffle(units)
for i = 1, 5, 1 do
if not units[i].valid then return false end
end
local position = group.surface.find_non_colliding_position("assembling-machine-1", group.position, 8, 1)
local worm = worm_raffle[math_random(1 + math_floor(group.force.evolution_factor * 8), math_floor(1 + group.force.evolution_factor * 16))]
if not position then return false end
group.surface.create_entity({name = worm, position = position, force = group.force})
group.surface.create_entity({name = "blood-explosion-huge", position = position})
for i = 1, 5, 1 do
units[i].surface.create_entity({name = "blood-explosion-huge", position = units[i].position})
units[i].destroy()
end
return true
end
local function flying_text(message, action, position, player)
local texts = {
{"roger", "acknowledged", "aye aye", "confirmed", "will do"},
{"negative", "no", "not really", "we are not your critters", "go away"},
{"fooood", "nom nom", "we hunger", "killllll"},
{"WTF", "we wanted ACTION", "why you hate us", "we were good soldiers", "go to hell"}
}
colors = {{r=0,g=220,b=0},{r=220,g=0,b=0},{r=0,g=100,b=220}, {r=200,g=200,b=0}, {r=255, g = 255, b = 255}}
if message then
player.create_local_flying_text{text = message, position = position, color = colors[5]}
else
player.create_local_flying_text{text = texts[action][math_random(1,#texts[action])], position = position, color = colors[action]}
end
end
-----------commands-----------
local function move_to(position, distraction)
local command = {
type = defines.command.go_to_location,
destination = position,
distraction = distraction,
pathfind_flags = {allow_destroy_friendly_entities = true}
}
return command
end
-- local function attackmaincommand(target)
-- local wave_defense_table = WD.get_table()
-- if not wave_defense_table.target then return end
-- if not wave_defense_table.target.valid then return end
-- local command = {
-- type = defines.command.attack,
-- target = target,
-- distraction = defines.distraction.by_enemy,
-- }
-- return command
-- end
local function attackareacommand(position)
local command = {
type = defines.command.attack_area,
destination = position,
radius = 25,
distraction = defines.distraction.by_enemy
}
return command
end
local function attackobstaclescommand(surface, position)
local commands = {}
local obstacles = surface.find_entities_filtered{position = position, radius = 20, type = {"simple-entity", "tree"}, limit = 100}
if obstacles then
shuffle(obstacles)
shuffle_distance(obstacles, position)
for i = 1, #obstacles, 1 do
if obstacles[i].valid then
commands[#commands + 1] = {
type = defines.command.attack,
target = obstacles[i],
distraction = defines.distraction.by_enemy
}
end
end
end
return commands
end
local function get_coords(group, source_player)
local position
if source_player.gui.screen["biter_panel"] then
local x = tonumber(source_player.gui.screen["biter_panel"]["coords"]["coord_x"].text)
local y = tonumber(source_player.gui.screen["biter_panel"]["coords"]["coord_y"].text)
if x == nil or x == "nil" then
x = group.position.x
source_player.gui.screen["biter_panel"]["coords"]["coord_x"].text = group.position.x
end
if y == nil or y == "nil" then
y = group.position.y
source_player.gui.screen["biter_panel"]["coords"]["coord_y"].text = group.position.y
end
position = {x = x, y = y}
end
return position
end
-------button functions-------------
local function pan(group, source_player)
source_player.open_map(group.position, 0.5)
end
local function teleport(group, source_player)
if source_player.admin or global.biter_command.teleporting then
source_player.teleport(group.position, group.surface)
else
flying_text("Teleporting is disabled", nil, source_player.position, source_player)
end
end
local function disband(group, source_player)
flying_text(nil, 4, group.position, source_player)
group.destroy()
end
local function movetome(group, source_player)
group.set_command(move_to(source_player.position, defines.distraction.none))
flying_text(nil, 1, group.position, source_player)
end
local function movetoposition(group, source_player)
local position = get_coords(group, source_player)
if position then
group.set_command(move_to(position, defines.distraction.none))
flying_text(nil, 1, group.position, source_player)
else
flying_text(nil, 2, group.position, source_player)
end
end
local function patroltome(group, source_player)
group.set_command(move_to(source_player.position, defines.distraction.by_enemy))
flying_text(nil, 1, group.position, source_player)
end
local function patroltoposition(group, source_player)
local position = get_coords(group, source_player)
if position then
group.set_command(move_to(position, defines.distraction.by_enemy))
flying_text(nil, 1, group.position, source_player)
else
flying_text(nil, 2, group.position, source_player)
end
end
local function settle(group, source_player)
local success = place_nest_near_unit_group(group)
if success then
flying_text(nil, 1, group.position, source_player)
else
flying_text(nil, 2, group.position, source_player)
source_player.print("Settling new nest failed. Check if group has enough members(5+) and there is empty space.")
end
end
local function siege(group, source_player)
local success = build_worm(group)
if success then
flying_text(nil, 1, group.position, source_player)
else
flying_text(nil, 2, group.position, source_player)
source_player.print("Making worm failed. Check if group has enough members(5+) and there is empty space.")
end
end
local function report(group, source_player)
local status = group.state
local states = {"gathering", "moving", "attacking distraction", "attacking target", "finished", "pathfinding", "wander in group"}
flying_text(states[status + 1], nil, group.position, source_player)
end
local function attackenemiesaround(group, source_player)
flying_text(nil, 3, group.position, source_player)
group.set_command(attackareacommand(group.position))
end
local function attackobstaclesaround(group, source_player)
local commands = attackobstaclescommand(group.surface, group.position)
if #commands > 1 then
group.set_command({
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
commands = commands
})
flying_text(nil, 3, group.position, source_player)
else
source_player.print("No obstacles found around unit group.")
flying_text(nil, 2, group.position, source_player)
end
end
local function attackenemiesaroundme(group, source_player)
group.set_command(attackareacommand(source_player.position))
flying_text(nil, 3, group.position, source_player)
end
local function attackobstaclesaroundme(group, source_player)
local commands = attackobstaclescommand(source_player.surface, source_player.position)
if #commands > 1 then
group.set_command({
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
commands = commands
})
flying_text(nil, 3, group.position, source_player)
else
source_player.print("No obstacles found around player.")
flying_text(nil, 2, group.position, source_player)
end
end
local function addunitsaroundme(group, source_player)
local units = source_player.surface.find_entities_filtered{position = source_player.position, radius = 50,type = "unit", force = group.force}
for i = 1, #units, 1 do
group.add_member(units[i])
end
end
local function addunits(group, source_player)
local units = source_player.surface.find_entities_filtered{position = group.position, radius = 50,type = "unit", force = group.force}
for i = 1, #units, 1 do
group.add_member(units[i])
end
end
local function forcemove(group, source_player)
group.start_moving()
flying_text(nil, 1, group.position, source_player)
end
local function creategroup(source_player)
source_player.surface.create_unit_group{position = source_player.position, force = source_player.force}
flying_text("Unit group created", nil, source_player.position, source_player)
end
----------------------direction panel-----------------
local function set_directions(changedx, changedy, source_player)
if source_player.gui.screen["biter_panel"] then
local x = tonumber(source_player.gui.screen["biter_panel"]["coords"]["coord_x"].text)
local y = tonumber(source_player.gui.screen["biter_panel"]["coords"]["coord_y"].text)
if x == nil or x == "nil" then x = 0 end
if y == nil or y == "nil" then y = 0 end
x = x + changedx
y = y + changedy
source_player.gui.screen["biter_panel"]["coords"]["coord_x"].text = x
source_player.gui.screen["biter_panel"]["coords"]["coord_y"].text = y
end
end
local function nw(source_player)
set_directions(-25, -25, source_player)
end
local function n(source_player)
set_directions(0, -25, source_player)
end
local function ne(source_player)
set_directions(25, -25, source_player)
end
local function w(source_player)
set_directions(-25, 0, source_player)
end
local function e(source_player)
set_directions(25, 0, source_player)
end
local function sw(source_player)
set_directions(-25, 25, source_player)
end
local function s(source_player)
set_directions(0, 25, source_player)
end
local function se(source_player)
set_directions(25, 25, source_player)
end
local function center(group, source_player)
if source_player.gui.screen["biter_panel"] then
source_player.gui.screen["biter_panel"]["coords"]["coord_x"].text = group.position.x
source_player.gui.screen["biter_panel"]["coords"]["coord_y"].text = group.position.y
end
end
----------------------------gui-----------------------
local function top_button(player)
if player.gui.top["biter_commands"] then
if global.biter_command.enabled or global.biter_command.whitelist[player.name] == true then
player.gui.top["biter_commands"].visible = true
return
else
--player.gui.top["biter_commands"].destroy()
player.gui.top["biter_commands"].visible = false
return
end
end
if player.admin or not global.biter_command.admin_mode then
if global.biter_command.enabled or global.biter_command.whitelist[player.name] == true then
local button = player.gui.top.add({type = "sprite-button", name = "biter_commands", sprite = "entity/medium-spitter"})
button.style.minimal_height = 38
button.style.minimal_width = 38
button.style.padding = -2
end
end
end
local function show_info(player)
if player.gui.screen["biter_comm_info"] then player.gui.screen["biter_comm_info"].destroy() return end
local frame = player.gui.screen.add{type = "frame", name = "biter_comm_info", caption = "Biter Commander needs halp", direction = "vertical"}
frame.location = {x = 350, y = 45}
frame.style.minimal_height = 300
frame.style.maximal_height = 300
frame.style.minimal_width = 330
frame.style.maximal_width = 630
frame.add({type = "label", caption = "Create new group first, then add biters to it."})
frame.add({type = "label", caption = "You can use directionpad to navigate them, or do it in person."})
frame.add({type = "label", caption = "If you input invalid coordinates, they get rewritten to current group's position."})
frame.add({type = "label", caption = "You can operate only biters and create groups of your own force."})
frame.add({type = "label", caption = "If group is stuck at gathering state, use 'force move' button."})
frame.add({type = "label", caption = "Empty groups get autodeleted by game after a while."})
frame.add({type = "button", name = "close_info", caption = "Close"})
end
local function build_groups(player)
local groups = {}
for _, g in pairs(global.biter_command.active_unit_groups) do
if g.group.valid then
if player.admin and global.biter_command.admin_mode then
table.insert(groups, tostring(g.id))
else
if player.force == g.group.force then
table.insert(groups, tostring(g.id))
end
end
else
g = nil
end
end
table.insert(groups, "Select Group")
return groups
end
local function biter_panel(player)
if player.gui.screen["biter_panel"] then player.gui.screen["biter_panel"].destroy() return end
local frame = player.gui.screen.add { type = "frame", caption = "Biter Commander", name = "biter_panel", direction = "vertical" }
frame.location = {x = 5, y = 45}
frame.style.minimal_height = 680
frame.style.maximal_height = 680
frame.style.minimal_width = 330
frame.style.maximal_width = 330
local groups = build_groups(player)
local selected_index = #groups
if global.panel_group_index then
if global.panel_group_index[player.name] then
if groups[global.panel_group_index[player.name]] then
selected_index = global.paneld_group_index[player.name]
end
end
end
local t0 = frame.add({type = "table", name = "top", column_count = 3})
local drop_down = t0.add({type = "drop-down", name = "group_select", items = groups, selected_index = selected_index})
drop_down.style.minimal_width = 150
drop_down.style.right_padding = 12
drop_down.style.left_padding = 12
t0.add({type = "sprite-button", name = "info", sprite = "virtual-signal/signal-info"})
t0.add({type = "sprite-button", name = "close_biters", sprite = "virtual-signal/signal-X"})
local l1 = frame.add({type = "label", caption = "Camera"})
local t1 = frame.add({type = "table", name = "camera", column_count = 2})
local l2 = frame.add({type = "label", caption = "Movement"})
local t2 = frame.add({type = "table", name = "movement", column_count = 2})
local l3 = frame.add({type = "label", caption = "Build"})
local t3 = frame.add({type = "table", name = "build", column_count = 2})
local l4 = frame.add({type = "label", caption = "Attack"})
local t4 = frame.add({type = "table", name = "attack", column_count = 2})
local l5 = frame.add({type = "label", caption = "Group Management"})
local t5 = frame.add({type = "table", name = "management", column_count = 2})
local line = frame.add { type = "line"}
line.style.top_margin = 8
line.style.bottom_margin = 8
local t6 = frame.add({type = "table", name = "directions", column_count = 3})
local buttons = {
t1.add({type = "button", caption = "Pan to group", name = "pan", tooltip = "Moves camera to group position."}),
t1.add({type = "button", caption = "TP to group", name = "teleport", tooltip = "Teleports to group."}),
t2.add({type = "button", caption = "Move to me", name = "movetome", tooltip = "Gives group order to move to your position."}),
t2.add({type = "button", caption = "Move to position", name = "movetoposition", tooltip = "Sends group to position with coordinates entered below."}),
t2.add({type = "button", caption = "Patrol to me ", name = "patroltome", tooltip = "Gives group order to move to your position and engage any enemy during movement."}),
t2.add({type = "button", caption = "Patrol to position", name = "patroltoposition", tooltip = "Sends group to position with coordinates entered below and engage any enemy during movement."}),
t3.add({type = "button", caption = "Settle nest", name = "settle", tooltip = "Group creates base. Costs 5 units."}),
t3.add({type = "button", caption = "Build worm", name = "siege", tooltip = "Group builds worm turret. Costs 5 units."}),
t4.add({type = "button", caption = "Attack area", name = "attackenemiesaround", tooltip = "Group attacks enemy things around self."}),
t4.add({type = "button", caption = "Attack obstacles", name = "attackobstaclesaround", tooltip = "Group attacks obstacles around self."}),
t4.add({type = "button", caption = "Attack my area", name = "attackenemiesaroundme", tooltip = "Group attacks enemy things around your position."}),
t4.add({type = "button", caption = "Attack my obstacles", name = "attackobstaclesaroundme", tooltip = "Group attacks obstacles around your position."}),
t5.add({type = "button", caption = "Report", name = "report", tooltip = "Reports group status."}),
t5.add({type = "button", caption = "Force Move", name = "forcemove", tooltip = "Makes group to start moving even if gathering is not done (unstuck)."}),
t5.add({type = "button", caption = "Add units around me", name = "addunitsaroundme", tooltip = "Adds units around you to selected unit group."}),
t5.add({type = "button", caption = "Add units", name = "addunits", tooltip = "Adds units around group to it."}),
t5.add({type = "button", caption = "Create group", name = "creategroup", tooltip = "Creates new group on player position"}),
t5.add({type = "button", caption = "Disband group", name = "disband", tooltip = "Disbands group."}),
}
local buttons2 = {
t6.add({type = "button", caption = "25 NW", name = "nw", tooltip = "Changes remote position"}),
t6.add({type = "button", caption = "25 N", name = "n", tooltip = "Changes remote position"}),
t6.add({type = "button", caption = "25 NE", name = "ne", tooltip = "Changes remote position"}),
t6.add({type = "button", caption = "25 W", name = "w", tooltip = "Changes remote position"}),
t6.add({type = "button", caption = "Center", name = "center", tooltip = "Centers remote position to group"}),
t6.add({type = "button", caption = "25 E", name = "e", tooltip = "Changes remote position"}),
t6.add({type = "button", caption = "25 SW", name = "sw", tooltip = "Changes remote position"}),
t6.add({type = "button", caption = "25 S", name = "s", tooltip = "Changes remote position"}),
t6.add({type = "button", caption = "25 SE", name = "se", tooltip = "Changes remote position"}),
}
for _, button in pairs(buttons) do
button.style.font = "default-bold"
button.style.font_color = { r=0.99, g=0.99, b=0.99}
button.style.minimal_width = 150
end
for _, button in pairs(buttons2) do
button.style.font = "default-bold"
button.style.font_color = { r=0.99, g=0.99, b=0.99}
button.style.minimal_width = 70
end
local t7 = frame.add({type = "table", name = "coords", column_count = 2})
t7.add({type = "label", caption = "X: "})
t7.add({type = "textfield", name = "coord_x"})
t7.add({type = "label", caption = "Y: "})
t7.add({type = "textfield", name = "coord_y"})
end
local comm_functions = {
["pan"] = pan,
["teleport"] = teleport,
["disband"] = disband,
["movetome"] = movetome,
["movetoposition"] = movetoposition,
["patroltome"] = patroltome,
["patroltoposition"] = patroltoposition,
["settle"] = settle,
["siege"] = siege,
["report"] = report,
["attackenemiesaround"] = attackenemiesaround,
["attackobstaclesaround"] = attackobstaclesaround,
["attackenemiesaroundme"] = attackenemiesaroundme,
["attackobstaclesaroundme"] = attackobstaclesaroundme,
["addunits"] = addunits,
["addunitsaroundme"] = addunitsaroundme,
["forcemove"] = forcemove,
["center"] = center,
}
local comm_global_functions = {
["creategroup"] = creategroup,
["nw"] = nw,
["n"] = n,
["ne"] = ne,
["w"] = w,
["e"] = e,
["sw"] = sw,
["s"] = s,
["se"] = se,
}
local function refresh_groups(player)
local groups = build_groups(player)
player.gui.screen["biter_panel"]["top"]["group_select"].items = groups
end
local function on_gui_click(event)
if not event then return end
if not event.element then return end
if not event.element.valid then return end
local player = game.players[event.element.player_index]
if event.element.name == "biter_commands" then --top button press
if global.biter_command.enabled or global.biter_command.whitelist[player.name] == true then
biter_panel(player)
return
else
top_button(player)
player.print("Biter commander module is disabled.")
return
end
else
if global.biter_command.enabled or global.biter_command.whitelist[player.name] == true then
top_button(player)
end
end
if event.element.type ~= "button" and event.element.type ~= "sprite-button" then return end
--if event.frame.name ~= "biter_panel" then return end
local name = event.element.name
if name == "close_biters" then biter_panel(player) return end
if name == "info" then show_info(player) return end
if name == "close_info" then show_info(player) return end
if comm_functions[name] then
local target_group_id = event.element.parent.parent["top"]["group_select"].items[event.element.parent.parent["top"]["group_select"].selected_index]
if not target_group_id then return end
if target_group_id == "Select Group" then
player.print("No target group selected.", {r=0.88, g=0.88, b=0.88})
return
end
-- local index = index(tonumber(target_group_id))
-- if not index then
-- player.print("Selected group is no longer valid.", {r=0.88, g=0.88, b=0.88})
-- return
-- end
local group = global.biter_command.active_unit_groups[tonumber(target_group_id)]
if group and group.group.valid then
comm_functions[name](group.group, player)
else
refresh_groups(player)
end
return
end
if comm_global_functions[name] then
comm_global_functions[name](player)
return
end
end
local function refresh_panel()
for _, player in pairs(game.connected_players) do
if player.gui.screen["biter_panel"] then
refresh_groups(player)
end
end
end
local function on_player_joined_game(event)
top_button(game.players[event.player_index])
end
local function on_unit_group_created(event)
if event and event.group then
global.biter_command.active_unit_groups[event.group.group_number] = {id = event.group.group_number, group = event.group}
refresh_panel()
end
end
local function on_unit_removed_from_group(event)
if event and event.group then
if #event.group.members == 1 then
global.biter_command.active_unit_groups[event.group.group_number] = nil
refresh_panel()
end
end
end
event.add(defines.events.on_unit_removed_from_group, on_unit_removed_from_group)
event.add(defines.events.on_unit_group_created, on_unit_group_created)
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_gui_click, on_gui_click)

View File

@ -104,7 +104,7 @@ local function on_gui_click(event)
if event.element.name == "close_map_intro" then game.players[event.player_index].gui.left.comfy_panel.destroy() return end
end
comfy_panel_tabs["Map Info"] = create_map_intro
comfy_panel_tabs["Map Info"] = {gui = create_map_intro, admin = false}
local event = require 'utils.event'
event.add(defines.events.on_player_joined_game, on_player_joined_game)

22
modules/pistol_buffs.lua Normal file
View File

@ -0,0 +1,22 @@
local event = require 'utils.event'
local function on_entity_damaged(event)
if not event.cause then return end
if event.cause.name ~= "character" then return end
if event.damage_type.name ~= "physical" then return end
local player = event.cause
if player.shooting_state.state == defines.shooting.not_shooting then return end
local weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
local ammo = player.get_inventory(defines.inventory.character_ammo)[player.selected_gun_index]
if not weapon.valid_for_read or not ammo.valid_for_read then return end
if weapon.name ~= "pistol" then return end
if ammo.name ~= "firearm-magazine" and ammo.name ~= "piercing-rounds-magazine" and ammo.name ~= "uranium-rounds-magazine" then return end
if not event.entity.valid then return end
event.entity.damage(event.final_damage_amount * 4, player.force, "impact", player)
end
event.add(defines.events.on_entity_damaged, on_entity_damaged)

View File

@ -12,12 +12,12 @@ local biological_target_types = {
["unit"] = true,
["player"] = true,
["turret"] = true,
["unit-spawner"] = true
["unit-spawner"] = true
}
local function create_visuals(source_entity, target_entity)
if not additional_visual_effects then return end
local surface = target_entity.surface
local surface = target_entity.surface
surface.create_entity({name = "water-splash", position = target_entity.position})
if biological_target_types[target_entity.type] then
surface.create_entity({name = "blood-explosion-big", position = target_entity.position})
@ -34,16 +34,16 @@ local function create_visuals(source_entity, target_entity)
surface.create_entity({name = "fire-flame", position = target_entity.position})
end
for x = -3, 3, 1 do
for y = -3, 3, 1 do
for y = -3, 3, 1 do
if math_random(1, 3) == 1 then
surface.create_trivial_smoke({name="smoke-fast", position={target_entity.position.x + (x * 0.35), target_entity.position.y + (y * 0.35)}})
surface.create_trivial_smoke({name="smoke-fast", position={target_entity.position.x + (x * 0.35), target_entity.position.y + (y * 0.35)}})
end
if math_random(1, 5) == 1 then
surface.create_trivial_smoke({name="train-smoke", position={target_entity.position.x + (x * 0.35), target_entity.position.y + (y * 0.35)}})
surface.create_trivial_smoke({name="train-smoke", position={target_entity.position.x + (x * 0.35), target_entity.position.y + (y * 0.35)}})
end
end
end
end
end
end
local function do_splash_damage_around_entity(source_entity, player)
@ -56,42 +56,42 @@ local function do_splash_damage_around_entity(source_entity, player)
}
local entities = source_entity.surface.find_entities_filtered({area = splash_area})
for _, entity in pairs(entities) do
if not entity.valid then return end
if entity.health and entity ~= source_entity and entity ~= player then
if entity.valid and entity.health and entity ~= source_entity and entity ~= player then
if additional_visual_effects then
local surface = entity.surface
surface.create_entity({name = "railgun-beam", position = source_entity.position, source = source_entity.position, target = entity.position})
surface.create_entity({name = "water-splash", position = entity.position})
if biological_target_types[entity.type] then
surface.create_entity({name = "blood-fountain", position = entity.position})
if biological_target_types[entity.type] then
surface.create_entity({name = "blood-fountain", position = entity.position})
end
end
local damage = math_random(math.ceil((damage_min * research_damage_bonus) / 16), math.ceil((damage_max * research_damage_bonus) / 16))
entity.damage(damage, player.force, "physical")
local damage = math_random(math.ceil((damage_min * research_damage_bonus) / 16), math.ceil((damage_max * research_damage_bonus) / 16))
entity.damage(damage, player.force, "physical")
end
end
end
local function on_entity_damaged(event)
local function on_entity_damaged(event)
if not event.cause then return end
if event.cause.name ~= "player" then return end
if event.cause.name ~= "character" then return end
if event.damage_type.name ~= "physical" then return end
if event.original_damage_amount ~= 100 then return end
local player = event.cause
if player.shooting_state.state == defines.shooting.not_shooting then return end
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
if not selected_weapon.valid_for_read then return end
if selected_weapon.name ~= "railgun" then return end
create_visuals(event.cause, event.entity)
do_splash_damage_around_entity(event.entity, player)
event.entity.health = event.entity.health + event.final_damage_amount
local research_damage_bonus = player.force.get_ammo_damage_modifier("laser-turret") + 1
local research_damage_bonus = player.force.get_ammo_damage_modifier("laser-turret") + 1
local damage = math_random(math.ceil(damage_min * research_damage_bonus), math.ceil(damage_max * research_damage_bonus))
event.entity.damage(damage, player.force, "physical")
event.entity.damage(damage, player.force, "physical")
end
event.add(defines.events.on_entity_damaged, on_entity_damaged)
event.add(defines.events.on_entity_damaged, on_entity_damaged)

View File

@ -19,7 +19,7 @@ local function create_gui(player)
progressbar.style.minimal_width = 96
progressbar.style.maximal_width = 96
progressbar.style.top_padding = 10
local line = frame.add({type = "line", direction = "vertical"})
line.style.left_padding = 4
line.style.right_padding = 4
@ -28,13 +28,13 @@ local function create_gui(player)
label.style.font = "default-bold"
label.style.left_padding = 4
label.style.font_color = {r = 150, g = 0, b = 255}
local label = frame.add({ type = "label", caption = " ", name = "threat_value", tooltip = {"wave_defense.tooltip_1"}})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 150, g = 0, b = 255}
local label = frame.add({ type = "label", caption = " ", name = "threat_gains", tooltip = {"wave_defense.tooltip_2"}})
label.style.font = "default"
label.style.left_padding = 1
@ -54,27 +54,31 @@ local function update_gui(player)
local wave_defense_table = WD.get_table()
if not player.gui.top.wave_defense then create_gui(player) end
local gui = player.gui.top.wave_defense
local biter_health_boost = 1
if global.biter_health_boost then biter_health_boost = global.biter_health_boost end
gui.label.caption = {"wave_defense.gui_2"}
gui.wave_number.caption = wave_defense_table.wave_number
if wave_defense_table.wave_number == 0 then
gui.label.caption = {"wave_defense.gui_1"}
gui.wave_number.caption = math.floor((wave_defense_table.next_wave - game.tick) / 60) + 1
gui.wave_number.caption = math.floor((wave_defense_table.next_wave - game.tick) / 60) + 1
end
local interval = wave_defense_table.next_wave - wave_defense_table.last_wave
gui.progressbar.value = 1 - (wave_defense_table.next_wave - game.tick) / interval
gui.threat.caption = {"wave_defense.gui_3"}
gui.threat_value.caption = math.floor(wave_defense_table.threat)
gui.threat.tooltip = {"wave_defense.tooltip_1", biter_health_boost * 100}
gui.threat_value.caption = math.floor(wave_defense_table.threat)
gui.threat_value.tooltip = {"wave_defense.tooltip_1", biter_health_boost * 100}
if wave_defense_table.wave_number == 0 then
gui.threat_gains.caption = ""
return
return
end
local gain = get_threat_gain()
local d = wave_defense_table.wave_number / 75
if gain >= 0 then
gui.threat_gains.caption = " (+" .. gain .. ")"
local g = 255 - math.floor(gain / d)
@ -88,4 +92,4 @@ local function update_gui(player)
end
end
return update_gui
return update_gui

View File

@ -28,6 +28,21 @@ local function debug_print(msg)
print("WaveDefense: " .. msg)
end
local function is_closer(pos1, pos2, pos)
return ((pos1.x - pos.x)^2 + (pos1.y - pos.y)^2) < ((pos2.x - pos.x)^2 + (pos2.y - pos.y)^2)
end
local function shuffle_distance(tbl, position)
local size = #tbl
for i = size, 1, -1 do
local rand = math_random(size)
if is_closer(tbl[i].position, tbl[rand].position, position) and i > rand then
tbl[i], tbl[rand] = tbl[rand], tbl[i]
end
end
return tbl
end
local function is_unit_valid(biter)
local wave_defense_table = WD.get_table()
if not biter.entity then debug_print("is_unit_valid - unit destroyed - does no longer exist") return false end
@ -104,12 +119,12 @@ local function set_main_target()
if wave_defense_table.target then
if wave_defense_table.target.valid then return end
end
local target = SideTargets.get_side_target()
if not target then target = get_random_character(wave_defense_table) end
if not target then return end
wave_defense_table.target = target
wave_defense_table.target = target
debug_print("set_main_target -- New main target " .. target.name .. " at position x" .. target.position.x .. " y" .. target.position.y .. " selected.")
end
@ -144,15 +159,6 @@ local function set_enemy_evolution()
--game.forces.enemy.set_ammo_damage_modifier("melee", damage_increase)
--game.forces.enemy.set_ammo_damage_modifier("biological", damage_increase)
game.forces.enemy.evolution_factor = evolution_factor
if global.biter_health_boost then
for _, player in pairs(game.connected_players) do
--player.gui.top.wave_defense.threat.tooltip = "High threat may empower biters.\nBiter health " .. biter_health_boost * 100 .. "% | damage " .. (damage_increase + 1) * 100 .. "%"
if player.gui.top.wave_defense then
player.gui.top.wave_defense.threat.tooltip = "High threat may empower biters.\nBiter health " .. biter_health_boost * 100 .. "%"
end
end
end
end
local function can_units_spawn()
@ -193,7 +199,7 @@ local function spawn_biter(surface, is_boss_biter)
if not is_boss_biter then
if not can_units_spawn() then return end
end
local name
if math_random(1,100) > 73 then
name = BiterRolls.wave_defense_roll_spitter_name()
@ -215,17 +221,17 @@ end
local function set_next_wave()
local wave_defense_table = WD.get_table()
wave_defense_table.wave_number = wave_defense_table.wave_number + 1
local threat_gain = wave_defense_table.wave_number * wave_defense_table.threat_gain_multiplier
if wave_defense_table.wave_number > 1000 then
threat_gain = threat_gain * (wave_defense_table.wave_number * 0.001)
end
if wave_defense_table.wave_number % 25 == 0 then
wave_defense_table.boss_wave = true
threat_gain = threat_gain * 2
threat_gain = threat_gain * 2
end
wave_defense_table.threat = wave_defense_table.threat + math_floor(threat_gain)
wave_defense_table.threat = wave_defense_table.threat + math_floor(threat_gain)
wave_defense_table.last_wave = wave_defense_table.next_wave
wave_defense_table.next_wave = game.tick + wave_defense_table.wave_interval
end
@ -239,7 +245,6 @@ local function get_commmands(group)
if math_random(1,2) == 1 then
local side_target = SideTargets.get_side_target()
if side_target then
debug_print("get_side_target -- " .. side_target.name .. " at position x" .. side_target.position.x .. " y" .. side_target.position.y .. " selected.")
local target_position = side_target.position
local distance_to_target = math_floor(math_sqrt((target_position.x - group_position.x) ^ 2 + (target_position.y - group_position.y) ^ 2))
local steps = math_floor(distance_to_target / step_length) + 1
@ -252,16 +257,49 @@ local function get_commmands(group)
end
for i = 1, steps, 1 do
local old_position = group_position
group_position.x = group_position.x + vector[1]
group_position.y = group_position.y + vector[2]
local position = group.surface.find_non_colliding_position("small-biter", group_position, step_length, 2)
group_position.y = group_position.y + vector[2]
local obstacles = group.surface.find_entities_filtered{position = old_position, radius = step_length, type = {"simple-entity", "tree"}, limit = 50}
if obstacles then
shuffle_distance(obstacles, old_position)
for i = 1, #obstacles, 1 do
if obstacles[i].valid then
commands[#commands + 1] = {
type = defines.command.attack,
target = obstacles[i],
distraction = defines.distraction.by_enemy
}
end
end
end
local position = group.surface.find_non_colliding_position("rocket-silo", group_position, step_length, 4)
if position then
-- commands[#commands + 1] = {
-- type = defines.command.go_to_location,
-- destination = {x = position.x, y = position.y},
-- distraction = defines.distraction.by_anything
-- }
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = {x = position.x, y = position.y},
radius = 16,
distraction = defines.distraction.by_anything
}
else
local obstacles = group.surface.find_entities_filtered{position = group_position, radius = step_length, type = {"simple-entity", "tree"}, limit = 50}
if obstacles then
shuffle_distance(obstacles, old_position)
for i = 1, #obstacles, 1 do
if obstacles[i].valid then
commands[#commands + 1] = {
type = defines.command.attack,
target = obstacles[i],
distraction = defines.distraction.by_enemy
}
end
end
end
end
end
@ -285,9 +323,23 @@ local function get_commmands(group)
end
for i = 1, steps, 1 do
local old_position = group_position
group_position.x = group_position.x + vector[1]
group_position.y = group_position.y + vector[2]
local position = group.surface.find_non_colliding_position("small-biter", group_position, step_length, 1)
local obstacles = group.surface.find_entities_filtered{position = old_position, radius = step_length / 2, type = {"simple-entity", "tree"}, limit = 50}
if obstacles then
shuffle_distance(obstacles, old_position)
for i = 1, #obstacles, 1 do
if obstacles[i].valid then
commands[#commands + 1] = {
type = defines.command.attack,
target = obstacles[i],
distraction = defines.distraction.by_enemy
}
end
end
end
local position = group.surface.find_non_colliding_position("rocket-silo", group_position, step_length, 1)
if position then
commands[#commands + 1] = {
type = defines.command.attack_area,
@ -320,15 +372,15 @@ local function command_unit_group(group)
wave_defense_table.unit_group_last_command[group.group_number] = game.tick - (wave_defense_table.unit_group_command_delay + 1)
end
if wave_defense_table.unit_group_last_command[group.group_number] then
if wave_defense_table.unit_group_last_command[group.group_number] + wave_defense_table.unit_group_command_delay > game.tick then return end
if wave_defense_table.unit_group_last_command[group.group_number] + wave_defense_table.unit_group_command_delay > game.tick then return end
end
group.set_command({
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
commands = get_commmands(group)
})
wave_defense_table.unit_group_last_command[group.group_number] = game.tick
end
@ -356,22 +408,22 @@ local function spawn_unit_group()
set_group_spawn_position(surface)
local pos = wave_defense_table.spawn_position
if not surface.can_place_entity({name = "small-biter", position = pos}) then return end
local radius = 10
local area = {left_top = {pos.x - radius, pos.y - radius}, right_bottom = {pos.x + radius, pos.y + radius}}
for k,v in pairs(surface.find_entities_filtered{area = area, name = "land-mine"}) do if v and v.valid then v.die() end end
BiterRolls.wave_defense_set_unit_raffle(wave_defense_table.wave_number)
debug_print("Spawning unit group at x" .. wave_defense_table.spawn_position.x .." y" .. wave_defense_table.spawn_position.y)
local unit_group = surface.create_unit_group({position = wave_defense_table.spawn_position, force = "enemy"})
local unit_group = surface.create_unit_group({position = wave_defense_table.spawn_position, force = "enemy"})
local group_size = math_floor(wave_defense_table.average_unit_group_size * group_size_modifier_raffle[math_random(1, group_size_modifier_raffle_size)])
for _ = 1, group_size, 1 do
local biter = spawn_biter(surface)
if not biter then break end
unit_group.add_member(biter)
end
if wave_defense_table.boss_wave then
local count = math_random(1, math_floor(wave_defense_table.wave_number * 0.01) + 2)
if count > 8 then count = 8 end
@ -383,7 +435,7 @@ local function spawn_unit_group()
wave_defense_table.boss_wave = false
end
table_insert(wave_defense_table.unit_groups, unit_group)
table_insert(wave_defense_table.unit_groups, unit_group)
return true
end
@ -391,7 +443,7 @@ local function log_threat()
local wave_defense_table = WD.get_table()
wave_defense_table.threat_log_index = wave_defense_table.threat_log_index + 1
wave_defense_table.threat_log[wave_defense_table.threat_log_index] = wave_defense_table.threat
if wave_defense_table.threat_log_index > 900 then wave_defense_table.threat_log[wave_defense_table.threat_log_index - 901] = nil end
if wave_defense_table.threat_log_index > 900 then wave_defense_table.threat_log[wave_defense_table.threat_log_index - 901] = nil end
end
local tick_tasks = {
@ -408,15 +460,15 @@ local tick_tasks = {
local function on_tick()
local wave_defense_table = WD.get_table()
if wave_defense_table.game_lost then return end
if game.tick > wave_defense_table.next_wave then set_next_wave() end
local t = game.tick % 300
local t2 = game.tick % 18000
if tick_tasks[t] then tick_tasks[t]() end
if tick_tasks[t2] then tick_tasks[t2]() end
if game.tick % 60 == 0 then log_threat() end
for _, player in pairs(game.connected_players) do update_gui(player) end
end
@ -427,4 +479,4 @@ local function on_init()
end
event.on_nth_tick(30, on_tick)
return Public
return Public

View File

@ -41,7 +41,7 @@ function Public.reset_wave_defense()
wave_defense.threat_log_index = 0
wave_defense.unit_groups = {}
wave_defense.unit_group_command_delay = 3600 * 15
wave_defense.unit_group_command_step_length = 80
wave_defense.unit_group_command_step_length = 20
wave_defense.unit_group_last_command = {}
wave_defense.wave_interval = 3600
wave_defense.wave_number = 0