1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-24 03:47:58 +02:00

Merge pull request #223 from hanakocz/master

Quarters map fix + Towny module fix + updated scrap layout + localizations
This commit is contained in:
Gerkiz 2021-01-26 19:12:24 +01:00 committed by GitHub
commit 816a4a51cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 827 additions and 394 deletions

View File

@ -126,7 +126,7 @@ require 'modules.autostash'
--require 'maps.overgrowth'
--![[Wave Defense Map split in 4 Quarters]]--
--'maps.quarters'
--require 'maps.quarters'
--![[Flee from the collapsing map with portable base inside train]]--
--require 'maps.railway_troopers_v2.main'
@ -222,6 +222,7 @@ require 'modules.autostash'
--require 'terrain_layouts.cone_to_east'
--require 'terrain_layouts.biters_and_resources_east'
--require 'terrain_layouts.scrap_01'
--require 'terrain_layouts.scrap_02'
--require 'terrain_layouts.watery_world'
--require 'terrain_layouts.tree_01'
---------------------------------------------------------------

View File

@ -1,2 +1,58 @@
[modules]
charging_station_tooltip=Charge your armor equipment from nearby accumulators!\nWorks only with those that have more than 3MJ of power.
difficulty_vote_message=__1__ has voted for __2__ difficulty!
difficulty_vote_gui_tooltip=Current difficulty of the map is __1__.
difficulty_vote_diff_change=>> Map difficulty has changed to __1__ difficulty!
difficulty_vote_closed1ago=Votes have closed __1__ minute ago.
difficulty_vote_closed2ago=Votes have closed __1__ minutes ago.
difficulty_vote_close_button=Close (__1__ minutes left)
difficulty_vote_vote=Vote difficulty:
[modules_towny]
map_info=__1__\n\n__2__\n\n__3__\n\n__4__\n\n__5__
map_info1=To ally or settle with another town, drop a fish on their market or character. (Default Hotkey Z)\nThey will have to do the same to you to complete the request.\nCoal yields the opposite result, as it will make foes or banish settlers.
map_info2=To found a town, place down a stone furnace at a valid location.\nThis will only trigger, if New Town button on top of screen is green. You can click it to toggle.\nTown buildings can only be placed close to it's other buildings.\nBeware, biters are more aggressive towards towns that are advanced in research.\nTheir evolution will scale around the average technology progress all towns.
map_info3=Only one town center can be owned at a time.\nOnly the owner can banish members.\nMembers can invite other players and teams.\nMembers can leave their town with a piece of coal.\nThe Market can only repaired manually.\nOutlanders can not build close to it.
map_info4=All towns are opponents to each other, if no alliance is formed with a raw fish.\nIf a center falls, the whole team will fall with it and all buildings will turn neutral and lootable.\nThe town center also acts as the team's respawn point.
map_info5=There are very little rules. Have fun and be comfy ^.^
map_info_header=Instructions:
show_info=Show Info
towny=Towny
new_town=New Town
new_town_caption=Click to toggle that placing furnace creates the new town.\nCurrent mode: __1__
new_town_on=Creating Town
new_town_off=Building Furnace
active_factions=Active Factions:
outlander=Outlander(__1__)
force=__1__(__2__)
message_error_building=Building is not connected to town!
message_error_tile=Tile is not connected to town!
message_error_close_town=Building too close to a town center!
message_error_close_spawn=Building too close to spawn!
message_error_cooldown=Town founding is on cooldown for __1__ minutes.
message_error_obstructed=Position is obstructed!
message_error_toomany=Too many town centers on the map!
message_error_close_spawn_town=Town location is too close to spawn!
message_error_close_other_town=Town location is too close to another town center!
message_error_neutral_entities=Area has too many non-neutral entities!
message_town_found=>> __1__ has founded a new town!
message_too_many_players=>> Town __1__ has too many settlers! Current limit (__2__)
message_settled=>> __1__ has settled in __2__'s Town!
message_settling=>> __1__ wants to settle in __2__ Town!
message_accepted_own=>> __1__ has accepted __2__ into their Town!
message_accepted=>> __1__ has accepted __2__ into __3__'s Town!
message_invite=>> __1__ is inviting __2__ into __3__'s Town!
message_invite_own=>> __1__ is inviting __2__ into their Town!
message_friend=>> Town __1__ has set __2__ as their friend!
message_alliance=>> The towns __1__ and __2__ have formed an alliance!
message_abandon=>> __1__ has abandoned __2__'s Town!
message_banish=>> __1__ has banished __2__ from their Town!
message_war=>> __1__ has dropped the coal! Town __2__ and __3__ are now at war!
message_destroyed=>> __1__'s town has fallen! __2__
upgrade_hp=Upgrade Town Center Health
upgrade_hp_max=Maximum Health upgrades reached!
upgrade_backpack=Upgrade Backpack +5 Slot
upgrade_backpack_max=Maximum Backpack upgrades reached!
upgrade_mining=Upgrade Mining Productivity +10%
upgrade_mining_max=Maximum Mining upgrades reached!

View File

@ -5,6 +5,19 @@ local WD = require "modules.wave_defense.table"
local simplex_noise = require 'utils.simplex_noise'.d2
local spawn_size = 96
local wall_thickness = 3
local small_scraps = {
"crash-site-spaceship-wreck-small-1",
"crash-site-spaceship-wreck-small-1",
"crash-site-spaceship-wreck-small-2",
"crash-site-spaceship-wreck-small-2",
"crash-site-spaceship-wreck-small-3",
"crash-site-spaceship-wreck-small-3",
"crash-site-spaceship-wreck-small-4",
"crash-site-spaceship-wreck-small-4",
"crash-site-spaceship-wreck-small-5",
"crash-site-spaceship-wreck-small-5",
"crash-site-spaceship-wreck-small-6"
}
local function clone_chunk(event, source_surface_name)
local source_surface = game.surfaces[source_surface_name]
@ -60,7 +73,7 @@ local function spawn_area(event)
if math.random(1, 3) ~= 1 then
local noise = simplex_noise(p.x * 0.015, p.y * 0.015, game.surfaces[1].map_gen_settings.seed) + simplex_noise(p.x * 0.055, p.y * 0.055, game.surfaces[1].map_gen_settings.seed) * 0.5
if noise > 0.6 then
event.surface.create_entity({name = "mineable-wreckage", position = p, force = "neutral"})
event.surface.create_entity({name = small_scraps[math.random(1, #small_scraps)], position = p, force = "neutral"})
end
if noise < -0.75 then
if math.random(1, 16) == 1 then
@ -73,9 +86,9 @@ local function spawn_area(event)
end
end
end
if left_top.x == -64 and left_top.y == -64 then
local wreck = event.surface.create_entity({name = "big-ship-wreck-1", position = {0, -4}, force = "player"})
if left_top.x == -64 and left_top.y == -64 then
local wreck = event.surface.create_entity({name = "crash-site-spaceship", position = {0, -6}, force = "player"})
wreck.insert({name = "submachine-gun", count = 3})
wreck.insert({name = "firearm-magazine", count = 32})
wreck.insert({name = "grenade", count = 8})
@ -249,4 +262,4 @@ event.add(defines.events.on_chunk_generated, on_chunk_generated)
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_player_left_game, on_player_left_game)
--require "modules.difficulty_vote"
--require "modules.difficulty_vote"

View File

@ -8,43 +8,50 @@ local this = {
name = 'Peaceful',
value = 0.25,
color = {r = 0.00, g = 0.45, b = 0.00},
print_color = {r = 0.00, g = 0.8, b = 0.00}
print_color = {r = 0.00, g = 0.8, b = 0.00},
enabled = true
},
[2] = {
name = 'Piece of cake',
value = 0.5,
color = {r = 0.00, g = 0.35, b = 0.00},
print_color = {r = 0.00, g = 0.6, b = 0.00}
print_color = {r = 0.00, g = 0.6, b = 0.00},
enabled = true
},
[3] = {
name = 'Easy',
value = 0.75,
color = {r = 0.00, g = 0.25, b = 0.00},
print_color = {r = 0.00, g = 0.4, b = 0.00}
print_color = {r = 0.00, g = 0.4, b = 0.00},
enabled = true
},
[4] = {
name = 'Normal',
value = 1,
color = {r = 0.00, g = 0.00, b = 0.25},
print_color = {r = 0.0, g = 0.0, b = 0.5}
print_color = {r = 0.0, g = 0.0, b = 0.5},
enabled = true
},
[5] = {
name = 'Hard',
value = 1.5,
color = {r = 0.25, g = 0.00, b = 0.00},
print_color = {r = 0.4, g = 0.0, b = 0.00}
print_color = {r = 0.4, g = 0.0, b = 0.00},
enabled = true
},
[6] = {
name = 'Nightmare',
value = 3,
color = {r = 0.35, g = 0.00, b = 0.00},
print_color = {r = 0.6, g = 0.0, b = 0.00}
print_color = {r = 0.6, g = 0.0, b = 0.00},
enabled = true
},
[7] = {
name = 'Impossible',
value = 5,
color = {r = 0.45, g = 0.00, b = 0.00},
print_color = {r = 0.8, g = 0.0, b = 0.00}
print_color = {r = 0.8, g = 0.0, b = 0.00},
enabled = true
}
},
tooltip = {
@ -106,7 +113,7 @@ function Public.get_difficulty_vote_index()
end
function Public.difficulty_gui()
local tooltip = 'Current difficulty of the map is ' .. this.name .. '.'
local tooltip = {'modules.difficulty_vote_gui_tooltip', this.name}
for _, player in pairs(game.connected_players) do
if player.gui.top['difficulty_gui'] then
@ -130,40 +137,39 @@ function Public.difficulty_gui()
end
local function poll_difficulty(player)
if player.gui.center['difficulty_poll'] then
player.gui.center['difficulty_poll'].destroy()
if player.gui.screen['difficulty_poll'] then
player.gui.screen['difficulty_poll'].destroy()
return
end
if game.tick > this.difficulty_poll_closing_timeout then
if player.online_time ~= 0 then
local t = math.abs(math.floor((this.difficulty_poll_closing_timeout - game.tick) / 3600))
local str = 'Votes have closed ' .. t
str = str .. ' minute'
local str = {'modules.difficulty_vote_closed1ago', t}
if t > 1 then
str = str .. 's'
str = {'modules.difficulty_vote_closed2ago', t}
end
str = str .. ' ago.'
player.print(str)
end
return
end
local frame =
player.gui.center.add {
player.gui.screen.add {
type = 'frame',
caption = 'Vote difficulty:',
caption = {'modules.difficulty_vote_vote'},
name = 'difficulty_poll',
direction = 'vertical'
}
frame.location = {x = 850, y = 400}
for i = 1, #this.difficulties, 1 do
local b = frame.add({type = 'button', name = tostring(i), caption = this.difficulties[i].name})
b.style.font_color = this.difficulties[i].color
b.style.font = 'heading-2'
b.style.minimal_width = 160
b.tooltip = this.tooltip[i]
--[[ if this.difficulties[i].disabled then
b.enabled = false
end ]]
if this.difficulties[i].enabled == false then
b.visible = false
end
end
local b = frame.add({type = 'label', caption = '- - - - - - - - - - - - - - - - - -'})
local b =
@ -171,7 +177,7 @@ local function poll_difficulty(player)
{
type = 'button',
name = 'close',
caption = 'Close (' .. math.floor((this.difficulty_poll_closing_timeout - game.tick) / 3600) .. ' minutes left)'
caption = {'modules.difficulty_vote_close_button', math.floor((this.difficulty_poll_closing_timeout - game.tick) / 3600)}
}
)
b.style.font_color = {r = 0.66, g = 0.0, b = 0.66}
@ -192,9 +198,9 @@ local function set_difficulty()
a = a / vote_count
local new_index = math.round(a, 0)
if this.difficulty_vote_index ~= new_index then
local message = table.concat({'>> Map difficulty has changed to ', this.difficulties[new_index].name, ' difficulty!'})
local message = {'modules.difficulty_vote_diff_change', this.difficulties[new_index].name}
game.print(message, this.difficulties[new_index].print_color)
Server.to_discord_embed(message)
Server.to_discord_embed(message, true)
end
this.difficulty_vote_index = new_index
this.difficulty_vote_value = this.difficulties[new_index].value
@ -209,8 +215,8 @@ function Public.reset_difficulty_poll(tbl)
this.difficulty_player_votes = {}
this.difficulty_poll_closing_timeout = tbl.difficulty_poll_closing_timeout or game.tick + 54000
for _, p in pairs(game.connected_players) do
if p.gui.center['difficulty_poll'] then
p.gui.center['difficulty_poll'].destroy()
if p.gui.screen['difficulty_poll'] then
p.gui.screen['difficulty_poll'].destroy()
end
poll_difficulty(p)
end
@ -223,8 +229,8 @@ function Public.reset_difficulty_poll(tbl)
this.difficulty_player_votes = {}
this.difficulty_poll_closing_timeout = game.tick + 54000
for _, p in pairs(game.connected_players) do
if p.gui.center['difficulty_poll'] then
p.gui.center['difficulty_poll'].destroy()
if p.gui.screen['difficulty_poll'] then
p.gui.screen['difficulty_poll'].destroy()
end
poll_difficulty(p)
end
@ -239,8 +245,8 @@ local function on_player_joined_game(event)
poll_difficulty(player)
end
else
if player.gui.center['difficulty_poll'] then
player.gui.center['difficulty_poll'].destroy()
if player.gui.screen['difficulty_poll'] then
player.gui.screen['difficulty_poll'].destroy()
end
end
Public.difficulty_gui()
@ -289,7 +295,7 @@ local function on_gui_click(event)
return
end
local i = tonumber(event.element.name)
game.print(player.name .. ' has voted for ' .. this.difficulties[i].name .. ' difficulty!', this.difficulties[i].print_color)
game.print({'modules.difficulty_vote_message', player.name, this.difficulties[i].name}, this.difficulties[i].print_color)
this.difficulty_player_votes[player.name] = i
set_difficulty()
Public.difficulty_gui()

View File

@ -3,34 +3,34 @@
local event = require 'utils.event'
local message_color = {r = 200, g = 200, b = 0}
local function on_gui_click(event)
if not event.element then return end
local function on_gui_click(event)
if not event.element then return end
if not event.element.valid then return end
if not event.element.name then return end
if event.element.name ~= "flashlight_toggle" then return end
local player = game.players[event.player_index]
if global.flashlight_enabled[player.name] == true then
player.character.disable_flashlight()
player.print("Flashlight disabled.", message_color)
global.flashlight_enabled[player.name] = false
return
end
if global.flashlight_enabled[player.name] == false then
player.character.enable_flashlight()
player.print("Flashlight enabled.", message_color)
global.flashlight_enabled[player.name] = true
return
end
end
end
local function on_player_respawned(event)
local player = game.players[event.player_index]
local player = game.players[event.player_index]
if global.flashlight_enabled[player.name] == false then
player.character.disable_flashlight()
return
end
end
if global.flashlight_enabled[player.name] == true then
player.character.enable_flashlight()
return
@ -41,9 +41,10 @@ local function on_player_joined_game(event)
if not global.flashlight_enabled then global.flashlight_enabled = {} end
local player = game.players[event.player_index]
global.flashlight_enabled[player.name] = true
if player.gui.top["flashlight_toggle"] then return end
if player.gui.top["flashlight_toggle"] then return end
local b = player.gui.top.add({type = "sprite-button", name = "flashlight_toggle", sprite = "item/small-lamp", tooltip = "Toggle flashlight" })
b.style.minimal_height = 38
b.style.maximal_height = 38
b.style.minimal_width = 38
b.style.top_padding = 2
b.style.left_padding = 4
@ -53,4 +54,4 @@ end
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_player_respawned, on_player_respawned)
event.add(defines.events.on_gui_click, on_gui_click)
event.add(defines.events.on_gui_click, on_gui_click)

View File

@ -1,4 +1,5 @@
local Public = {}
local Table = require "modules.towny.table"
local math_random = math.random
local math_floor = math.floor
local math_sqrt = math.sqrt
@ -46,9 +47,10 @@ local function get_commmands(target, group)
end
local function roll_market()
local townytable = Table.get_table()
local r_max = 0
local town_centers = global.towny.town_centers
local town_centers = townytable.town_centers
--Skip Towns that are too low in reserach for the current biter evolution.
local research_threshold = game.forces.enemy.evolution_factor * #game.technology_prototypes * 0.175
@ -57,9 +59,9 @@ local function roll_market()
r_max = r_max + town_center.research_counter
end
end
if r_max == 0 then return end
if r_max == 0 then return end
local r = math_random(0, r_max)
local chance = 0
for k, town_center in pairs(town_centers) do
if town_center.research_counter >= research_threshold then
@ -88,17 +90,18 @@ local function is_swarm_valid(swarm)
local group = swarm.group
if not group then return end
if not group.valid then return end
if game.tick >= swarm.timeout then
group.destroy()
if game.tick >= swarm.timeout then
group.destroy()
return
end
return true
end
function Public.validate_swarms()
for k, swarm in pairs(global.towny.swarms) do
local townytable = Table.get_table()
for k, swarm in pairs(townytable.swarms) do
if not is_swarm_valid(swarm) then
table_remove(global.towny.swarms, k)
table_remove(townytable.swarms, k)
end
end
end
@ -106,18 +109,18 @@ end
--Destroy biters that are out of the current evolution range.
function Public.wipe_units_out_of_evo_range()
local units_to_wipe = {}
local evo = game.forces.enemy.evolution_factor
local evo = game.forces.enemy.evolution_factor
if evo > 0.80 then return end
units_to_wipe[#units_to_wipe + 1] = "behemoth-biter"
units_to_wipe[#units_to_wipe + 1] = "behemoth-spitter"
if evo < 0.40 then
if evo < 0.40 then
units_to_wipe[#units_to_wipe + 1] = "big-biter"
units_to_wipe[#units_to_wipe + 1] = "big-spitter"
end
if evo < 0.10 then
if evo < 0.10 then
units_to_wipe[#units_to_wipe + 1] = "medium-biter"
units_to_wipe[#units_to_wipe + 1] = "medium-spitter"
end
end
for k, surface in pairs(game.surfaces) do
for k2, unit in pairs(surface.find_entities_filtered({name = units_to_wipe, force = "enemy"})) do
unit.destroy()
@ -133,7 +136,8 @@ function Public.clear_spawn_for_player(player)
end
function Public.unit_groups_start_moving()
for k, swarm in pairs(global.towny.swarms) do
local townytable = Table.get_table()
for k, swarm in pairs(townytable.swarms) do
if swarm.group then
if swarm.group.valid then
swarm.group.start_moving()
@ -143,18 +147,19 @@ function Public.unit_groups_start_moving()
end
function Public.swarm()
local townytable = Table.get_table()
local count = 0
for k, swarm in pairs(global.towny.swarms) do
for k, swarm in pairs(townytable.swarms) do
count = count + 1
end
end
if count > 6 then return end
local town_center = roll_market()
if not town_center then return end
local market = town_center.market
local surface = market.surface
local spawner = get_random_close_spawner(surface, market)
if not spawner then return end
if not spawner then return end
local units = spawner.surface.find_enemy_units(spawner.position, 160, market.force)
if not units[1] then return end
local unit_group_position = surface.find_non_colliding_position("market", units[1].position, 256, 1)
@ -163,34 +168,35 @@ function Public.swarm()
local count = (town_center.research_counter * 1.5) + 4
for key, unit in pairs(units) do
if key > count then break end
unit_group.add_member(unit)
unit_group.add_member(unit)
end
unit_group.set_command({
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
commands = get_commmands(market, unit_group)
})
table_insert(global.towny.swarms, {group = unit_group, timeout = game.tick + 36000})
table_insert(townytable.swarms, {group = unit_group, timeout = game.tick + 36000})
end
function Public.set_evolution()
local town_center_count = global.towny.size_of_town_centers
if town_center_count == 0 then
local townytable = Table.get_table()
local town_center_count = townytable.size_of_town_centers
if town_center_count == 0 then
game.forces.enemy.evolution_factor = 0
return
return
end
local max_research_count = math_floor(#game.technology_prototypes * 0.30)
local evo = 0
for _, town_center in pairs(global.towny.town_centers) do
for _, town_center in pairs(townytable.town_centers) do
evo = evo + town_center.research_counter
end
evo = evo / town_center_count
evo = evo / max_research_count
if evo > 1 then evo = 1 end
game.forces.enemy.evolution_factor = evo
end
return Public
return Public

View File

@ -56,23 +56,23 @@ local function is_position_isolated(surface, force, position)
local position_y = position.y
local area = {{position_x - connection_radius, position_y - connection_radius}, {position_x + connection_radius, position_y + connection_radius}}
local count = 0
for _, e in pairs(surface.find_entities_filtered({area = area, force = force.name})) do
if entity_type_whitelist[e.type] then
count = count + 1
if count > 1 then return end
end
end
return true
end
local function refund_item(event, item_name)
if event.player_index then
if event.player_index then
game.players[event.player_index].insert({name = item_name, count = 1})
return
end
return
end
if event.robot then
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
inventory.insert({name = item_name, count = 1})
@ -105,35 +105,35 @@ function Public.prevent_isolation(event)
if entity.force.index == 1 then return end
if not entity_type_whitelist[entity.type] then return end
local surface = event.created_entity.surface
if is_position_isolated(surface, entity.force, entity.position) then
error_floaty(surface, entity.position, "Building is not connected to town!")
refund_item(event, event.stack.name)
error_floaty(surface, entity.position, {"modules_towny.message_error_building"})
refund_item(event, event.stack.name)
entity.destroy()
return true
end
end
end
function Public.prevent_isolation_landfill(event)
if event.item.name ~= "landfill" then return end
local surface = game.surfaces[event.surface_index]
local tiles = event.tiles
local force
if event.player_index then
force = game.players[event.player_index].force
else
force = event.robot.force
end
for _, placed_tile in pairs(tiles) do
local position = placed_tile.position
if is_position_isolated(surface, force, position) then
error_floaty(surface, position, "Tile is not connected to town!")
surface.set_tiles({{name = "water", position = position}}, true)
refund_item(event, "landfill")
error_floaty(surface, position, {"modules_towny.message_error_tile"})
surface.set_tiles({{name = "water", position = position}}, true)
refund_item(event, "landfill")
end
end
end
end
local square_min_distance_to_spawn = 80 ^ 2
@ -141,21 +141,21 @@ local square_min_distance_to_spawn = 80 ^ 2
function Public.restrictions(event)
local entity = event.created_entity
if not entity.valid then return end
if entity.force.index == 1 then
if is_town_market_nearby(entity) then
refund_item(event, event.stack.name)
error_floaty(entity.surface, entity.position, "Building too close to a town center!")
error_floaty(entity.surface, entity.position, {"modules_towny.message_error_close_town"})
entity.destroy()
end
return
end
return
end
if not entity_type_whitelist[entity.type] then return end
if entity.position.x ^ 2 + entity.position.y ^ 2 > square_min_distance_to_spawn then return end
refund_item(event, event.stack.name)
error_floaty(entity.surface, entity.position, "Building too close to spawn!")
error_floaty(entity.surface, entity.position, {"modules_towny.message_error_close_spawn"})
entity.destroy()
end
return Public
return Public

View File

@ -1,35 +1,14 @@
local Public = {}
local info = [[To ally or settle with another town, drop a fish on their market or character. (Default Hotkey Z)
They will have to do the same to you to complete the request.
Coal yields the opposite result, as it will make foes or banish settlers.
To found a town, place down a stone furnace at a valid location.
This will only trigger, if your character is in possession a "small-plane" token item!
Town buildings can only be placed close to it's other buildings.
Beware, biters are more aggressive towards towns that are advanced in research.
Their evolution will scale around the average technology progress all towns.
Only one town center can be owned at a time.
Only the owner can banish members.
Members can invite other players and teams.
Members can leave their town with a piece of coal.
The Market can only repaired manually.
Outlanders can not build close to it.
All towns are opponents to each other, if no alliance is formed with a raw fish.
If a center falls, the whole team will fall with it and all buildings will turn neutral and lootable.
The town center also acts as the team's respawn point.
There are very little rules. Have fun and be comfy ^.^]]
local Table = require "modules.towny.table"
function Public.toggle_button(player)
if player.gui.top["towny_map_intro_button"] then return end
local b = player.gui.top.add({type = "sprite-button", caption = "Towny", name = "towny_map_intro_button", tooltip = "Show Info"})
local b = player.gui.top.add({type = "sprite-button", caption = {"modules_towny.towny"}, name = "towny_map_intro_button", tooltip = {"modules_towny.show_info"}})
b.style.font_color = {r=0.5, g=0.3, b=0.99}
b.style.font = "heading-1"
b.style.minimal_height = 38
b.style.minimal_width = 60
b.style.maximal_height = 38
b.style.minimal_width = 100
b.style.top_padding = 1
b.style.left_padding = 1
b.style.right_padding = 1
@ -37,42 +16,76 @@ function Public.toggle_button(player)
end
function Public.show(player)
local townytable = Table.get_table()
if player.gui.center["towny_map_intro_frame"] then player.gui.center["towny_map_intro_frame"].destroy() end
local frame = player.gui.center.add {type = "frame", name = "towny_map_intro_frame"}
local frame = frame.add {type = "frame", direction = "vertical"}
local t = frame.add {type = "table", column_count = 2}
local label = t.add {type = "label", caption = "Active Factions:"}
local label = t.add {type = "label", caption = {"modules_towny.active_factions"}}
label.style.font = "heading-1"
label.style.font_color = {r=0.85, g=0.85, b=0.85}
label.style.right_padding = 8
local t = t.add {type = "table", column_count = 4}
local label = t.add {type = "label", caption = "Outlander" .. "(" .. #game.forces.player.connected_players .. ")"}
local label = t.add {type = "label", caption = {"modules_towny.outlander", #game.forces.player.connected_players}}
label.style.font_color = {170, 170, 170}
label.style.font = "heading-3"
label.style.minimal_width = 80
for _, town_center in pairs(global.towny.town_centers) do
for _, town_center in pairs(townytable.town_centers) do
local force = town_center.market.force
local label = t.add {type = "label", caption = force.name .. "(" .. #force.connected_players .. ")"}
local label = t.add {type = "label", caption = {"modules_towny.force", force.name, #force.connected_players}}
label.style.font = "heading-3"
label.style.minimal_width = 80
label.style.font_color = town_center.color
end
end
frame.add {type = "line"}
local l = frame.add {type = "label", caption = "Instructions:"}
local l = frame.add {type = "label", caption = {"modules_towny.map_info_header"}}
l.style.font = "heading-1"
l.style.font_color = {r=0.85, g=0.85, b=0.85}
local l = frame.add {type = "label", caption = info}
local caption = {"modules_towny.map_info", {"modules_towny.map_info1"}, {"modules_towny.map_info2"},{"modules_towny.map_info3"},{"modules_towny.map_info4"},{"modules_towny.map_info5"}}
local l = frame.add {type = "label", caption = caption}
l.style.single_line = false
l.style.font = "heading-2"
l.style.font_color = {r=0.8, g=0.7, b=0.99}
l.style.font_color = {r=0.8, g=0.7, b=0.99}
end
function Public.new_town_button(player)
if player.gui.top["towny_new_town_button"] then return end
local b = player.gui.top.add({type = "sprite-button", caption = "New Town", name = "towny_new_town_button", tooltip = {"modules_towny.new_town_caption", {"modules_towny.new_town_off"}}})
b.style.font_color = {r = 0.88, g = 0.02, b = 0.02}
b.style.font = "heading-1"
b.style.minimal_height = 38
b.style.maximal_height = 38
b.style.minimal_width = 100
b.style.top_padding = 1
b.style.left_padding = 1
b.style.right_padding = 1
b.style.bottom_padding = 1
end
function Public.update_new_town_button(player)
local townytable = Table.get_table()
local button = player.gui.top["towny_new_town_button"]
if not button or not button.valid then return end
if player.force == game.forces.player then
button.visible = true
if townytable.town_buttons[player.index] == true then
button.tooltip = {"modules_towny.new_town_caption", {"modules_towny.new_town_on"}}
button.style.font_color = {r = 0.02, g = 0.88, b = 0.02}
else
button.tooltip = {"modules_towny.new_town_caption", {"modules_towny.new_town_off"}}
button.style.font_color = {r = 0.88, g = 0.02, b = 0.02}
end
else
button.visible = false
end
end
function Public.close(event)
@ -81,23 +94,38 @@ function Public.close(event)
local parent = event.element.parent
for _ = 1, 4, 1 do
if not parent then return end
if parent.name == "towny_map_intro_frame" then parent.destroy() return end
parent = parent.parent
if parent.name == "towny_map_intro_frame" then parent.destroy() return end
parent = parent.parent
end
end
function Public.toggle(event)
if not event.element then return end
if not event.element.valid then return end
if not event.element.valid then return end
if event.element.name == "towny_map_intro_button" then
local player = game.players[event.player_index]
if player.gui.center["towny_map_intro_frame"] then
player.gui.center["towny_map_intro_frame"].destroy()
else
Public.show(player)
end
end
end
end
end
function Public.toggle_town(event)
local townytable = Table.get_table()
if not event.element then return end
if not event.element.valid then return end
if event.element.name == "towny_new_town_button" then
local player = game.players[event.player_index]
if townytable.town_buttons[player.index] then
townytable.town_buttons[player.index] = false
else
townytable.town_buttons[player.index] = true
end
Public.update_new_town_button(player)
end
end
return Public
return Public

View File

@ -23,39 +23,42 @@ local Info = require "modules.towny.info"
local Market = require "modules.towny.market"
local Team = require "modules.towny.team"
local Town_center = require "modules.towny.town_center"
local Table = require "modules.towny.table"
require "modules.custom_death_messages"
require "modules.flashlight_toggle_button"
require "modules.global_chat_toggle"
require "modules.biters_yield_coins"
local function on_player_joined_game(event)
local townytable = Table.get_table()
local player = game.players[event.player_index]
Info.toggle_button(player)
Info.show(player)
Info.new_town_button(player)
Team.set_player_color(player)
if player.force.index ~= 1 then return end
Team.set_player_to_outlander(player)
Team.set_player_to_outlander(player)
if player.online_time == 0 then
Team.give_outlander_items(player)
return
end
if not global.towny.requests[player.index] then return end
if global.towny.requests[player.index] ~= "kill-character" then return end
if not townytable.requests[player.index] then return end
if townytable.requests[player.index] ~= "kill-character" then return end
if player.character then
if player.character.valid then
player.character.die()
end
end
global.towny.requests[player.index] = nil
townytable.requests[player.index] = nil
end
local function on_player_respawned(event)
local player = game.players[event.player_index]
local player = game.players[event.player_index]
if player.force.index ~= 1 then return end
Team.set_player_to_outlander(player)
Team.give_outlander_items(player)
@ -85,21 +88,21 @@ local function on_robot_built_tile(event)
Building.prevent_isolation_landfill(event)
end
local function on_entity_died(event)
local function on_entity_died(event)
local entity = event.entity
if entity.name == "market" then
Team.kill_force(entity.force.name)
end
end
local function on_entity_damaged(event)
local function on_entity_damaged(event)
local entity = event.entity
if entity.name == "market" then
Town_center.set_market_health(entity, event.final_damage_amount)
end
end
local function on_player_repaired_entity(event)
local function on_player_repaired_entity(event)
local entity = event.entity
if entity.name == "market" then
Town_center.set_market_health(entity, -4)
@ -108,12 +111,12 @@ end
local function on_player_dropped_item(event)
local player = game.players[event.player_index]
local entity = event.entity
if entity.stack.name == "raw-fish" then
local entity = event.entity
if entity.stack.name == "raw-fish" then
Team.ally_town(player, entity)
return
end
if entity.stack.name == "coal" then
if entity.stack.name == "coal" then
Team.declare_war(player, entity)
return
end
@ -135,11 +138,13 @@ end
local function on_gui_click(event)
Info.close(event)
Info.toggle(event)
Info.toggle_town(event)
end
local function on_research_finished(event)
Combat_balance.research(event)
local town_center = global.towny.town_centers[event.research.force.name]
local townytable = Table.get_table()
local town_center = townytable.town_centers[event.research.force.name]
if not town_center then return end
town_center.research_counter = town_center.research_counter + 1
end
@ -151,6 +156,10 @@ local function on_player_died(event)
Team.reveal_entity_to_all(player.character)
end
local function on_player_changed_force(event)
Info.update_new_town_button(game.players[event.player_index])
end
local tick_actions = {
[60 * 5] = Team.update_town_chart_tags,
[60 * 10] = Team.set_all_player_colors,
@ -162,27 +171,19 @@ local tick_actions = {
}
local function on_nth_tick(event)
local tick = game.tick % 3600
if not tick_actions[tick] then return end
local tick = game.tick % 3600
if not tick_actions[tick] then return end
tick_actions[tick]()
end
local function on_init()
global.towny = {}
global.towny.requests = {}
global.towny.request_cooldowns = {}
global.towny.town_centers = {}
global.towny.cooldowns = {}
global.towny.size_of_town_centers = 0
global.towny.swarms = {}
game.difficulty_settings.technology_price_multiplier = 0.30
game.map_settings.enemy_evolution.time_factor = 0
game.map_settings.enemy_evolution.destroy_factor = 0
game.map_settings.enemy_evolution.pollution_factor = 0
game.map_settings.pollution.enabled = false
game.map_settings.enemy_expansion.enabled = true
game.map_settings.enemy_expansion.enabled = true
Team.setup_player_force()
end
@ -205,4 +206,5 @@ Event.add(defines.events.on_player_used_capsule, on_player_used_capsule)
Event.add(defines.events.on_research_finished, on_research_finished)
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
Event.add(defines.events.on_robot_built_tile, on_robot_built_tile)
Event.add(defines.events.on_player_built_tile, on_player_built_tile)
Event.add(defines.events.on_player_built_tile, on_player_built_tile)
Event.add(defines.events.on_player_changed_force, on_player_changed_force)

View File

@ -1,4 +1,5 @@
local Town_center = require "modules.towny.town_center"
local Table = require "modules.towny.table"
local Public = {}
local upgrade_functions = {
@ -12,12 +13,12 @@ local upgrade_functions = {
--Upgrade Backpack
[2] = function(town_center)
local force = town_center.market.force
if force.character_inventory_slots_bonus > 100 then return end
if force.character_inventory_slots_bonus >= 100 then return end
force.character_inventory_slots_bonus = force.character_inventory_slots_bonus + 5
end,
--Upgrade Backpack
[3] = function(town_center)
local force = town_center.market.force
local force = town_center.market.force
if town_center.upgrades.mining_prod >= 10 then return end
town_center.upgrades.mining_prod = town_center.upgrades.mining_prod + 1
force.mining_drill_productivity_bonus = force.mining_drill_productivity_bonus + 0.1
@ -34,30 +35,30 @@ end
local function set_offers(town_center)
local market = town_center.market
local force = market.force
local special_offers = {}
if town_center.max_health < 500000 then
special_offers[1] = {{{"coin", town_center.max_health * 0.1}}, "Upgrade Town Center Health"}
local special_offers = {}
if town_center.max_health < 500000 then
special_offers[1] = {{{"coin", town_center.max_health * 0.1}}, {"modules_towny.upgrade_hp"}}
else
special_offers[1] = {{{"computer", 1}}, "Maximum Health upgrades reached!"}
special_offers[1] = {{{"infinity-chest", 1}}, {"modules_towny.upgrade_hp_max"}}
end
if force.character_inventory_slots_bonus <= 100 then
special_offers[2] = {{{"coin", (force.character_inventory_slots_bonus / 5 + 1) * 50}}, "Upgrade Backpack +5 Slot"}
if force.character_inventory_slots_bonus < 100 then
special_offers[2] = {{{"coin", (force.character_inventory_slots_bonus / 5 + 1) * 50}}, {"modules_towny.upgrade_backpack"}}
else
special_offers[2] = {{{"computer", 1}}, "Maximum Backpack upgrades reached!"}
special_offers[2] = {{{"infinity-chest", 1}}, {"modules_towny.upgrade_backpack_max"}}
end
if town_center.upgrades.mining_prod < 10 then
special_offers[3] = {{{"coin", (town_center.upgrades.mining_prod + 1) * 400}}, "Upgrade Mining Productivity +10%"}
special_offers[3] = {{{"coin", (town_center.upgrades.mining_prod + 1) * 400}}, {"modules_towny.upgrade_mining"}}
else
special_offers[3] = {{{"computer", 1}}, "Maximum Backpack upgrades reached!"}
special_offers[3] = {{{"infinity-chest", 1}}, {"modules_towny.upgrade_mining_max"}}
end
local market_items = {}
local market_items = {}
for _, v in pairs(special_offers) do
table.insert(market_items, {price = v[1], offer = {type = 'nothing', effect_description = v[2]}})
end
table.insert(market_items, {price = {{"coin", 1}}, offer = {type = 'give-item', item = 'raw-fish', count = 1}})
table.insert(market_items, {price = {{"coin", 8}}, offer = {type = 'give-item', item = 'wood', count = 50}})
table.insert(market_items, {price = {{"coin", 8}}, offer = {type = 'give-item', item = 'iron-ore', count = 50}})
@ -71,38 +72,40 @@ local function set_offers(town_center)
table.insert(market_items, {price = {{'stone', 7}}, offer = {type = 'give-item', item = "coin"}})
table.insert(market_items, {price = {{'coal', 7}}, offer = {type = 'give-item', item = "coin"}})
table.insert(market_items, {price = {{'uranium-ore', 5}}, offer = {type = 'give-item', item = "coin"}})
table.insert(market_items, {price = {{"coin", 300}}, offer = {type = 'give-item', item = 'loader', count = 1}})
table.insert(market_items, {price = {{"coin", 600}}, offer = {type = 'give-item', item = 'fast-loader', count = 1}})
table.insert(market_items, {price = {{"coin", 900}}, offer = {type = 'give-item', item = 'express-loader', count = 1}})
for _, item in pairs(market_items) do
market.add_market_item(item)
end
end
function Public.refresh_offers(event)
local townytable = Table.get_table()
local market = event.entity or event.market
if not market then return end
if not market.valid then return end
if market.name ~= "market" then return end
local town_center = global.towny.town_centers[market.force.name]
local town_center = townytable.town_centers[market.force.name]
if not town_center then return end
clear_offers(market)
set_offers(town_center)
end
function Public.offer_purchased(event)
local townytable = Table.get_table()
local offer_index = event.offer_index
if not upgrade_functions[offer_index] then return end
local market = event.market
local town_center = global.towny.town_centers[market.force.name]
local town_center = townytable.town_centers[market.force.name]
if not town_center then return end
upgrade_functions[offer_index](town_center)
count = event.count
if count > 1 then
local offers = market.get_market_items()
@ -112,4 +115,3 @@ function Public.offer_purchased(event)
end
return Public

38
modules/towny/table.lua Normal file
View File

@ -0,0 +1,38 @@
-- one table to rule them all!
local Global = require 'utils.global'
local Event = require 'utils.event'
local townytable = {}
local Public = {}
Global.register(
townytable,
function(tbl)
townytable = tbl
end
)
function Public.reset_table()
for k, _ in pairs(townytable) do
townytable[k] = nil
end
townytable.requests = {}
townytable.request_cooldowns = {}
townytable.town_centers = {}
townytable.cooldowns = {}
townytable.size_of_town_centers = 0
townytable.swarms = {}
townytable.town_buttons = {}
end
function Public.get_table()
return townytable
end
local on_init = function ()
Public.reset_table()
end
Event.on_init(on_init)
return Public

View File

@ -1,54 +1,58 @@
local Public = {}
local Table = require "modules.towny.table"
local outlander_color = {150, 150, 150}
local outlander_chat_color = {170, 170, 170}
local item_drop_radius = 1.65
local function can_force_accept_member(force)
local town_centers = global.towny.town_centers
local size_of_town_centers = global.towny.size_of_town_centers
local townytable = Table.get_table()
local town_centers = townytable.town_centers
local size_of_town_centers = townytable.size_of_town_centers
local member_limit = 0
if size_of_town_centers <= 1 then return true end
if size_of_town_centers <= 1 then return true end
for _, town in pairs(town_centers) do
member_limit = member_limit + #town.market.force.connected_players
end
member_limit = math.floor(member_limit / size_of_town_centers) + 4
if #force.connected_players >= member_limit then
game.print(">> Town " .. force.name .. " has too many settlers! Current limit (" .. member_limit .. ")" , {255, 255, 0})
return
if #force.connected_players >= member_limit then
game.print({"modules_towny.message_too_many_players", force.name, member_limit}, {255, 255, 0})
return
end
return true
end
function Public.set_player_color(player)
local townytable = Table.get_table()
if player.force.index == 1 then
player.color = outlander_color
player.chat_color = outlander_chat_color
return
end
local town_center = global.towny.town_centers[player.force.name]
local town_center = townytable.town_centers[player.force.name]
if not town_center then return end
player.color = town_center.color
player.chat_color= town_center.color
end
function Public.set_town_color(event)
local townytable = Table.get_table()
if event.command ~= "color" then return end
local player = game.players[event.player_index]
local player = game.players[event.player_index]
if player.force.index == 1 then
player.color = outlander_color
player.chat_color = outlander_chat_color
return
end
local town_center = global.towny.town_centers[player.name]
local town_center = townytable.town_centers[player.name]
if not town_center then
Public.set_player_color(player)
return
end
end
town_center.color = {player.color.r, player.color.g, player.color.b}
rendering.set_color(town_center.town_caption, town_center.color)
for _, p in pairs(player.force.players) do
@ -66,12 +70,11 @@ function Public.add_player_to_town(player, town_center)
player.force = town_center.market.force
game.permissions.get_group("Default").add_player(player)
player.tag = ""
Public.set_player_color(player)
Public.set_player_color(player)
end
function Public.give_outlander_items(player)
player.insert({name = "stone-furnace", count = 1})
player.insert({name = "small-plane", count = 1})
player.insert({name = "raw-fish", count = 3})
player.insert({name = "coal", count = 3})
end
@ -84,62 +87,63 @@ function Public.set_player_to_outlander(player)
end
local function ally_outlander(player, target)
local townytable = Table.get_table()
local requesting_force = player.force
local target_force = target.force
if requesting_force.index ~= 1 and target_force.index ~= 1 then return end
if requesting_force.index == 1 and target_force.index == 1 then return true end
if requesting_force.index == 1 then
global.towny.requests[player.index] = target_force.name
townytable.requests[player.index] = target_force.name
local target_player = false
if target.type == "character" then
if target.type == "character" then
target_player = target.player
else
target_player = game.players[target_force.name]
end
if target_player then
if global.towny.requests[target_player.index] then
if global.towny.requests[target_player.index] == player.name then
if global.towny.town_centers[target_force.name] then
if townytable.requests[target_player.index] then
if townytable.requests[target_player.index] == player.name then
if townytable.town_centers[target_force.name] then
if not can_force_accept_member(target_force) then return true end
game.print(">> " .. player.name .. " has settled in " .. target_force.name .. "'s Town!", {255, 255, 0})
Public.add_player_to_town(player, global.towny.town_centers[target_force.name])
game.print({"modules_towny.message_settled", player.name, target_force.name}, {255, 255, 0})
Public.add_player_to_town(player, townytable.town_centers[target_force.name])
return true
end
end
end
end
game.print(">> " .. player.name .. " wants to settle in " .. target_force.name .. " Town!", {255, 255, 0})
game.print({"modules_towny.message_settling", player.name, target_force.name}, {255, 255, 0})
return true
end
if target_force.index == 1 then
if target_force.index == 1 then
if target.type ~= "character" then return true end
local target_player = target.player
if not target_player then return true end
global.towny.requests[player.index] = target_player.name
if global.towny.requests[target_player.index] then
if global.towny.requests[target_player.index] == player.force.name then
if not can_force_accept_member(player.force) then return true end
townytable.requests[player.index] = target_player.name
if townytable.requests[target_player.index] then
if townytable.requests[target_player.index] == player.force.name then
if not can_force_accept_member(player.force) then return true end
if player.force.name == player.name then
game.print(">> " .. player.name .. " has accepted " .. target_player.name .. " into their Town!", {255, 255, 0})
game.print({"modules_towny.message_accepted_own", player.name, target_player.name}, {255, 255, 0})
else
game.print(">> " .. player.name .. " has accepted " .. target_player.name .. " into" .. player.force.name .. "'s Town!", {255, 255, 0})
game.print({"modules_towny.message_accepted_own", player.name, target_player.name, player.force.name}, {255, 255, 0})
end
Public.add_player_to_town(target_player, global.towny.town_centers[player.force.name])
Public.add_player_to_town(target_player, townytable.town_centers[player.force.name])
return true
end
end
end
if player.force.name == player.name then
game.print(">> " .. player.name .. " is inviting " .. target_player.name .. " into their Town!", {255, 255, 0})
game.print({"modules_towny.message_invite_own", player.name, target_player.name}, {255, 255, 0})
else
game.print(">> " .. player.name .. " is inviting " .. target_player.name .. " into " .. player.force.name .. "'s Town!", {255, 255, 0})
game.print({"modules_towny.message_invite", player.name, target_player.name, player.force.name}, {255, 255, 0})
end
return true
end
@ -148,14 +152,14 @@ end
local function ally_neighbour_towns(player, target)
local requesting_force = player.force
local target_force = target.force
if target_force.get_friend(requesting_force) and requesting_force.get_friend(target_force) then return end
requesting_force.set_friend(target_force, true)
game.print(">> Town " .. requesting_force.name .. " has set " .. target_force.name .. " as their friend!", {255, 255, 0})
game.print({"modules_towny.message_friend", requesting_force.name, target_force.name}, {255, 255, 0})
if target_force.get_friend(requesting_force) then
game.print(">> The towns " .. requesting_force.name .. " and " .. target_force.name .. " have formed an alliance!", {255, 255, 0})
game.print({"modules_towny.message_alliance", requesting_force.name, target_force.name}, {255, 255, 0})
end
end
@ -165,22 +169,23 @@ function Public.ally_town(player, item)
local area = {{position.x - item_drop_radius, position.y - item_drop_radius}, {position.x + item_drop_radius, position.y + item_drop_radius}}
local requesting_force = player.force
local target = false
for _, e in pairs(surface.find_entities_filtered({type = {"character", "market"}, area = area})) do
if e.force.name ~= requesting_force.name then
target = e
break
end
end
if not target then return end
if target.force.index == 2 or target.force.index == 3 then return end
if ally_outlander(player, target) then return end
if ally_outlander(player, target) then return end
ally_neighbour_towns(player, target)
end
function Public.declare_war(player, item)
local townytable = Table.get_table()
local position = item.position
local surface = player.surface
local area = {{position.x - item_drop_radius, position.y - item_drop_radius}, {position.x + item_drop_radius, position.y + item_drop_radius}}
@ -191,31 +196,31 @@ function Public.declare_war(player, item)
if not target then return end
local target_force = target.force
if target_force.index <= 3 then return end
if requesting_force.name == target_force.name then
if player.name ~= target.force.name then
Public.set_player_to_outlander(player)
game.print(">> " .. player.name .. " has abandoned " .. target_force.name .. "'s Town!", {255, 255, 0})
global.towny.requests[player.index] = nil
end
game.print({"modules_towny.message_abandon", player.name, target_force.name}, {255, 255, 0})
townytable.requests[player.index] = nil
end
if player.name == target.force.name then
if target.type ~= "character" then return end
local target_player = target.player
if not target_player then return end
if target_player.index == player.index then return end
Public.set_player_to_outlander(target_player)
game.print(">> " .. player.name .. " has banished " .. target_player.name .. " from their Town!", {255, 255, 0})
global.towny.requests[player.index] = nil
game.print({"modules_towny.message_banish", player.name, target_player.name}, {255, 255, 0})
townytable.requests[player.index] = nil
end
return
end
if requesting_force.index == 1 then return end
requesting_force.set_friend(target_force, false)
target_force.set_friend(requesting_force, false)
game.print(">> " .. player.name .. " has dropped the coal! Town " .. target_force.name .. " and " .. requesting_force.name .. " are now at war!", {255, 255, 0})
game.print({"modules_towny.message_war", player.name, target_force.name, requesting_force.name}, {255, 255, 0})
end
local radius = 96
@ -229,9 +234,9 @@ end
local function delete_chart_tag_for_all_forces(market)
local forces = game.forces
local position = market.position
local position = market.position
local surface = market.surface
for _, force in pairs(forces) do
for _, force in pairs(forces) do
local tags = force.find_chart_tags(surface, {{position.x - 0.1, position.y - 0.1}, {position.x + 0.1, position.y + 0.1}})
local tag = tags[1]
if tag then
@ -246,11 +251,12 @@ function Public.add_chart_tag(force, market)
local position = market.position
local tags = force.find_chart_tags(market.surface, {{position.x - 0.1, position.y - 0.1}, {position.x + 0.1, position.y + 0.1}})
if tags[1] then return end
force.add_chart_tag(market.surface, {icon = {type = 'item', name = 'stone-furnace'}, position = position, text = market.force.name .. "'s Town"})
force.add_chart_tag(market.surface, {icon = {type = 'item', name = 'stone-furnace'}, position = position, text = market.force.name .. "'s Town"})
end
function Public.update_town_chart_tags()
local town_centers = global.towny.town_centers
local townytable = Table.get_table()
local town_centers = townytable.town_centers
local forces = game.forces
for _, town_center in pairs(town_centers) do
local market = town_center.market
@ -258,39 +264,41 @@ function Public.update_town_chart_tags()
if force.is_chunk_visible(market.surface, town_center.chunk_position) then
Public.add_chart_tag(force, market)
end
end
end
end
end
end
function Public.add_new_force(force_name)
local force = game.create_force(force_name)
force.research_queue_enabled = true
force.research_queue_enabled = true
force.share_chart = true
force.technologies["atomic-bomb"].enabled = false
force.technologies["explosive-rocketry"].enabled = false
force.technologies["rocketry"].enabled = false
force.technologies["artillery-shell-range-1"].enabled = false
force.technologies["artillery-shell-range-1"].enabled = false
force.technologies["artillery-shell-speed-1"].enabled = false
force.set_ammo_damage_modifier("landmine", -0.6)
force.set_ammo_damage_modifier("artillery-shell", -0.75)
force.manual_mining_speed_modifier = 1
end
function Public.kill_force(force_name)
local townytable = Table.get_table()
local force = game.forces[force_name]
local market = global.towny.town_centers[force_name].market
local market = townytable.town_centers[force_name].market
local surface = market.surface
surface.create_entity({name = "big-artillery-explosion", position = market.position})
for _, player in pairs(force.players) do
if player.character then
player.character.die()
else
global.towny.requests[player.index] = "kill-character"
townytable.requests[player.index] = "kill-character"
end
player.force = game.forces.player
end
for _, e in pairs(surface.find_entities_filtered({force = force_name})) do
if e.valid then
if e.type == "wall" or e.type == "gate" then
@ -300,14 +308,14 @@ function Public.kill_force(force_name)
end
game.merge_forces(force_name, "neutral")
global.towny.town_centers[force_name] = nil
global.towny.size_of_town_centers = global.towny.size_of_town_centers - 1
townytable.town_centers[force_name] = nil
townytable.size_of_town_centers = townytable.size_of_town_centers - 1
delete_chart_tag_for_all_forces(market)
Public.reveal_entity_to_all(market)
game.print(">> " .. force_name .. "'s town has fallen! [gps=" .. math.floor(market.position.x) .. "," .. math.floor(market.position.y) .. "]", {255, 255, 0})
game.print({"modules_towny.message_destroyed", force_name, "[gps=" .. math.floor(market.position.x) .. "," .. math.floor(market.position.y) .. "]"}, {255, 255, 0})
end
local player_force_disabled_recipes = {"lab", "automation-science-pack", "stone-brick"}
@ -322,19 +330,19 @@ function Public.setup_player_force()
defines.input_action.start_research,
}
for _, d in pairs(defs) do p.set_allows_action(d, false) end
local force = game.forces.player
local recipes = force.recipes
for k, recipe_name in pairs(player_force_disabled_recipes) do
recipes[recipe_name].enabled = false
end
for k, recipe_name in pairs(player_force_enabled_recipes) do
recipes[recipe_name].enabled = true
end
force.set_ammo_damage_modifier("landmine", -0.6)
force.set_ammo_damage_modifier("artillery-shell", -0.75)
end
return Public
return Public

View File

@ -1,4 +1,5 @@
local Team = require "modules.towny.team"
local Table = require "modules.towny.table"
local Public = {}
local math_random = math.random
@ -62,7 +63,7 @@ end
local resource_vectors = {}
resource_vectors[1] = {}
for x = 7, 24, 1 do
for y = 7, 24, 1 do
for y = 7, 24, 1 do
table_insert(resource_vectors[1], {x, y})
end
end
@ -76,7 +77,7 @@ for _, vector in pairs(resource_vectors[1]) do table_insert(resource_vectors[4],
local additional_resource_vectors = {}
additional_resource_vectors[1] = {}
for x = 10, 22, 1 do
for y = -4, 4, 1 do
for y = -4, 4, 1 do
table_insert(additional_resource_vectors[1], {x, y})
end
end
@ -84,7 +85,7 @@ additional_resource_vectors[2] = {}
for _, vector in pairs(additional_resource_vectors[1]) do table_insert(additional_resource_vectors[2], {vector[1] * -1, vector[2]}) end
additional_resource_vectors[3] = {}
for y = 10, 22, 1 do
for x = -4, 4, 1 do
for x = -4, 4, 1 do
table_insert(additional_resource_vectors[3], {x, y})
end
end
@ -111,7 +112,7 @@ local starter_supplies = {
{name = "shotgun-shell", count = 8},
{name = "firearm-magazine", count = 16},
{name = "firearm-magazine", count = 16},
{name = "gun-turret", count = 2},
{name = "gun-turret", count = 2},
}
local function count_nearby_ore(surface, position, ore_name)
@ -124,27 +125,28 @@ local function count_nearby_ore(surface, position, ore_name)
end
local function draw_town_spawn(player_name)
local market = global.towny.town_centers[player_name].market
local townytable = Table.get_table()
local market = townytable.town_centers[player_name].market
local position = market.position
local surface = market.surface
local area = {{position.x - (town_radius + 1), position.y - (town_radius + 1)}, {position.x + (town_radius + 1), position.y + (town_radius + 1)}}
for _, e in pairs(surface.find_entities_filtered({area = area, force = "neutral"})) do
if not clear_blacklist_types[e.type] then
e.destroy()
end
end
for _, vector in pairs(gate_vectors_horizontal) do
local p = {position.x + vector[1], position.y + vector[2]}
local p = {position.x + vector[1], position.y + vector[2]}
p = surface.find_non_colliding_position("gate", p, 64, 1)
if p then
surface.create_entity({name = "gate", position = p, force = player_name, direction = 2})
end
end
for _, vector in pairs(gate_vectors_vertical) do
local p = {position.x + vector[1], position.y + vector[2]}
local p = {position.x + vector[1], position.y + vector[2]}
p = surface.find_non_colliding_position("gate", p, 64, 1)
if p then
surface.create_entity({name = "gate", position = p, force = player_name, direction = 0})
@ -158,16 +160,16 @@ local function draw_town_spawn(player_name)
surface.create_entity({name = "stone-wall", position = p, force = player_name})
end
end
local ores = {"iron-ore", "copper-ore", "stone", "coal"}
table.shuffle_table(ores)
for i = 1, 4, 1 do
if count_nearby_ore(surface, position, ores[i]) < 200000 then
for _, vector in pairs(resource_vectors[i]) do
local p = {position.x + vector[1], position.y + vector[2]}
local p = {position.x + vector[1], position.y + vector[2]}
p = surface.find_non_colliding_position(ores[i], p, 64, 1)
if p then
if p then
surface.create_entity({name = ores[i], position = p, amount = ore_amount})
end
end
@ -176,30 +178,30 @@ local function draw_town_spawn(player_name)
for _, item_stack in pairs(starter_supplies) do
local m1 = -8 + math_random(0, 16)
local m2 = -8 + math_random(0, 16)
local m2 = -8 + math_random(0, 16)
local p = {position.x + m1, position.y + m2}
p = surface.find_non_colliding_position("wooden-chest", p, 64, 1)
if p then
if p then
local e = surface.create_entity({name = "wooden-chest", position = p, force = player_name})
local inventory = e.get_inventory(defines.inventory.chest)
inventory.insert(item_stack)
end
end
local vector_indexes = {1,2,3,4}
table.shuffle_table(vector_indexes)
local tree = "tree-0" .. math_random(1, 9)
for _, vector in pairs(additional_resource_vectors[vector_indexes[1]]) do
if math_random(1, 6) == 1 then
local p = {position.x + vector[1], position.y + vector[2]}
local p = {position.x + vector[1], position.y + vector[2]}
p = surface.find_non_colliding_position(tree, p, 64, 1)
if p then
if p then
surface.create_entity({name = tree, position = p})
end
end
end
local area = {{position.x - town_radius * 1.5, position.y - town_radius * 1.5}, {position.x + town_radius * 1.5, position.y + town_radius * 1.5}}
if surface.count_tiles_filtered({name = {"water", "deepwater"}, area = area}) < 8 then
for _, vector in pairs(additional_resource_vectors[vector_indexes[2]]) do
@ -210,71 +212,60 @@ local function draw_town_spawn(player_name)
end
end
if count_nearby_ore(surface, position, "uranium-ore") < 100000 then
for _, vector in pairs(additional_resource_vectors[vector_indexes[3]]) do
local p = {position.x + vector[1], position.y + vector[2]}
for _, vector in pairs(additional_resource_vectors[vector_indexes[3]]) do
local p = {position.x + vector[1], position.y + vector[2]}
p = surface.find_non_colliding_position("uranium-ore", p, 64, 1)
if p then
if p then
surface.create_entity({name = "uranium-ore", position = p, amount = ore_amount * 2})
end
end
end
end
local vectors = additional_resource_vectors[vector_indexes[4]]
for _ = 1, 3, 1 do
local vector = vectors[math_random(1, #vectors)]
local p = {position.x + vector[1], position.y + vector[2]}
local vector = vectors[math_random(1, #vectors)]
local p = {position.x + vector[1], position.y + vector[2]}
p = surface.find_non_colliding_position("crude-oil", p, 64, 1)
if p then
if p then
surface.create_entity({name = "crude-oil", position = p, amount = 500000})
end
end
end
end
local function is_valid_location(surface, entity)
local function flying_text(surface, position, text, color)
surface.create_entity({
name = "flying-text",
position = {position.x, position.y - 0.5},
text = text,
color = color
})
end
local function is_valid_location(surface, entity)
local townytable = Table.get_table()
for _, vector in pairs(market_collide_vectors) do
local p = {entity.position.x + vector[1], entity.position.y + vector[2]}
local p = {entity.position.x + vector[1], entity.position.y + vector[2]}
if not surface.can_place_entity({name = "iron-chest", position = p}) then
surface.create_entity({
name = "flying-text",
position = entity.position,
text = "Position is obstructed!",
color = {r=0.77, g=0.0, b=0.0}
})
return
flying_text(surface, entity.position, {"modules_towny.message_error_obstructed"}, {r=0.77, g=0.0, b=0.0})
return
end
end
if global.towny.size_of_town_centers > 48 then
surface.create_entity({
name = "flying-text",
position = entity.position,
text = "Too many town centers on the map!",
color = {r=0.77, g=0.0, b=0.0}
})
return
if townytable.size_of_town_centers > 48 then
flying_text(surface, entity.position, {"modules_towny.message_error_toomany"}, {r=0.77, g=0.0, b=0.0})
return
end
if entity.position.x ^ 2 + entity.position.y ^ 2 < square_min_distance_to_spawn then
surface.create_entity({
name = "flying-text",
position = entity.position,
text = "Town location is too close to spawn!",
color = {r=0.77, g=0.0, b=0.0}
})
return
end
local area = {{entity.position.x - radius_between_towns, entity.position.y - radius_between_towns}, {entity.position.x + radius_between_towns, entity.position.y + radius_between_towns}}
if surface.count_entities_filtered({area = area, name = "market"}) > 0 then
surface.create_entity({
name = "flying-text",
position = entity.position,
text = "Town location is too close to another town center!",
color = {r=0.77, g=0.0, b=0.0}
})
flying_text(surface, entity.position, {"modules_towny.message_error_close_spawn_town"}, {r=0.77, g=0.0, b=0.0})
return
end
local area = {{entity.position.x - radius_between_towns, entity.position.y - radius_between_towns}, {entity.position.x + radius_between_towns, entity.position.y + radius_between_towns}}
if surface.count_entities_filtered({area = area, name = "market"}) > 0 then
flying_text(surface, entity.position, {"modules_towny.message_error_close_other_town"}, {r=0.77, g=0.0, b=0.0})
return
end
local area = {{entity.position.x - town_radius, entity.position.y - town_radius}, {entity.position.x + town_radius, entity.position.y + town_radius}}
local count = 0
for _, e in pairs(surface.find_entities_filtered({area = area})) do
@ -283,26 +274,22 @@ local function is_valid_location(surface, entity)
end
end
if count > 2 then
surface.create_entity({
name = "flying-text",
position = entity.position,
text = "Area has too many non-neutral entities!",
color = {r=0.77, g=0.0, b=0.0}
})
return
if count > 2 then
flying_text(surface, entity.position, {"modules_towny.message_error_neutral_entities"}, {r=0.77, g=0.0, b=0.0})
return
end
return true
end
function Public.set_market_health(entity, final_damage_amount)
local town_center = global.towny.town_centers[entity.force.name]
local townytable = Table.get_table()
local town_center = townytable.town_centers[entity.force.name]
town_center.health = math_floor(town_center.health - final_damage_amount)
if town_center.health > town_center.max_health then town_center.health = town_center.max_health end
local m = town_center.health / town_center.max_health
entity.health = 150 * m
rendering.set_text(town_center.health_text, "HP: " .. town_center.health .. " / " .. town_center.max_health)
rendering.set_text(town_center.health_text, "HP: " .. town_center.health .. " / " .. town_center.max_health)
end
local function is_color_used(color, town_centers)
@ -314,60 +301,55 @@ local function is_color_used(color, town_centers)
end
local function get_color()
local town_centers = global.towny.town_centers
local townytable = Table.get_table()
local town_centers = townytable.town_centers
local c
local shuffle_index = {}
for i = 1, #colors, 1 do shuffle_index[i] = i end
table.shuffle_table(shuffle_index)
for i = 1, #colors, 1 do
c = {r = colors[shuffle_index[i]][1], g = colors[shuffle_index[i]][2], b = colors[shuffle_index[i]][3],}
if not is_color_used(c, town_centers) then return c end
if not is_color_used(c, town_centers) then return c end
end
return c
end
function Public.found(event)
local townytable = Table.get_table()
local entity = event.created_entity
if entity.force.index ~= 1 then return end
if entity.name ~= "stone-furnace" then return end
if entity.name ~= "stone-furnace" then return end
local player = game.players[event.player_index]
local player_name = tostring(player.name)
if game.forces[player_name] then return end
local inventory = player.get_main_inventory()
if inventory.get_item_count("small-plane") < 1 then return end
if not townytable.town_buttons[player.index] then return end
local surface = entity.surface
if global.towny.cooldowns[player.index] then
if game.tick < global.towny.cooldowns[player.index] then
surface.create_entity({
name = "flying-text",
position = entity.position,
text = "Town founding is on cooldown for " .. math.ceil((global.towny.cooldowns[player.index] - game.tick) / 3600) .. " minutes.",
color = {r=0.77, g=0.0, b=0.0}
})
if townytable.cooldowns[player.index] then
if game.tick < townytable.cooldowns[player.index] then
flying_text(surface, entity.position, {"modules_towny.message_error_cooldown", math.ceil((townytable.cooldowns[player.index] - game.tick) / 3600)}, {r=0.77, g=0.0, b=0.0})
player.insert({name = "stone-furnace", count = 1})
entity.destroy()
return true
end
end
end
if not is_valid_location(surface, entity) then
player.insert({name = "stone-furnace", count = 1})
entity.destroy()
return true
end
Team.add_new_force(player_name)
global.towny.town_centers[player_name] = {}
local town_center = global.towny.town_centers[player_name]
townytable.town_centers[player_name] = {}
local town_center = townytable.town_centers[player_name]
town_center.market = surface.create_entity({name = "market", position = entity.position, force = player_name})
town_center.chunk_position = {math.floor(town_center.market.position.x / 32), math.floor(town_center.market.position.y / 32)}
town_center.max_health = 1000
@ -376,7 +358,7 @@ function Public.found(event)
town_center.research_counter = 1
town_center.upgrades = {}
town_center.upgrades.mining_prod = 0
town_center.health_text = rendering.draw_text{
text = "HP: " .. town_center.health .. " / " .. town_center.max_health,
surface = surface,
@ -388,7 +370,7 @@ function Public.found(event)
alignment = "center",
scale_with_zoom = false
}
town_center.town_caption = rendering.draw_text{
text = player.name .. "'s Town",
surface = surface,
@ -400,25 +382,25 @@ function Public.found(event)
alignment = "center",
scale_with_zoom = false
}
global.towny.size_of_town_centers = global.towny.size_of_town_centers + 1
townytable.size_of_town_centers = townytable.size_of_town_centers + 1
entity.destroy()
draw_town_spawn(player_name)
Team.add_player_to_town(player, town_center)
Team.add_chart_tag(game.forces.player, town_center.market)
local force = player.force
force.set_spawn_position({x = town_center.market.position.x, y = town_center.market.position.y + 4}, surface)
global.towny.cooldowns[player.index] = game.tick + 3600 * 15
if inventory.valid then inventory.remove({name = "small-plane", count = 1}) end
game.print(">> " .. player.name .. " has founded a new town!", {255, 255, 0})
force.set_spawn_position({x = town_center.market.position.x, y = town_center.market.position.y + 4}, surface)
townytable.cooldowns[player.index] = game.tick + 3600 * 15
townytable.town_buttons[player.index] = false
game.print({"modules_towny.message_town_found", player.name}, {255, 255, 0})
return true
end
return Public
return Public

View File

@ -0,0 +1,290 @@
require "modules.no_deconstruction_of_neutral_entities"
local get_noise = require "utils.get_noise"
local math_random = math.random
local math_floor = math.floor
local math_abs = math.abs
local small_scraps = {
"crash-site-spaceship-wreck-small-1",
"crash-site-spaceship-wreck-small-1",
"crash-site-spaceship-wreck-small-2",
"crash-site-spaceship-wreck-small-2",
"crash-site-spaceship-wreck-small-3",
"crash-site-spaceship-wreck-small-3",
"crash-site-spaceship-wreck-small-4",
"crash-site-spaceship-wreck-small-4",
"crash-site-spaceship-wreck-small-5",
"crash-site-spaceship-wreck-small-5",
"crash-site-spaceship-wreck-small-6"
}
local scraps_inv = {
"crash-site-spaceship",
"crash-site-spaceship-wreck-big-1",
"crash-site-spaceship-wreck-big-1",
"crash-site-spaceship-wreck-big-2",
"crash-site-spaceship-wreck-big-2",
"crash-site-spaceship-wreck-medium-1",
"crash-site-spaceship-wreck-medium-1",
"crash-site-spaceship-wreck-medium-1",
"crash-site-spaceship-wreck-medium-2",
"crash-site-spaceship-wreck-medium-2",
"crash-site-spaceship-wreck-medium-2",
"crash-site-spaceship-wreck-medium-3",
"crash-site-spaceship-wreck-medium-3",
"crash-site-spaceship-wreck-medium-3",
"crash-site-chest-1",
"crash-site-chest-1",
"crash-site-chest-2",
"crash-site-chest-2",
}
local function is_scrap(name)
for i = 1, #small_scraps, 1 do
if name == small_scraps[i] then return true end
end
for i = 1, #scraps_inv, 1 do
if name == scraps_inv[i] then return true end
end
return false
end
local scrap_entities = {"crash-site-assembling-machine-1-broken", "crash-site-assembling-machine-2-broken", "crash-site-lab-broken",
"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",
"big-ship-wreck-1", "big-ship-wreck-2", "big-ship-wreck-3", "big-ship-wreck-1", "big-ship-wreck-2", "big-ship-wreck-3", "big-ship-wreck-1", "big-ship-wreck-2", "big-ship-wreck-3",
}
local scrap_entities_index = #scrap_entities
local mining_chance_weights = {
{name = "iron-plate", chance = 1000},
{name = "iron-gear-wheel", chance = 750},
{name = "copper-plate", chance = 750},
{name = "copper-cable", chance = 500},
{name = "electronic-circuit", chance = 300},
{name = "steel-plate", chance = 200},
{name = "solid-fuel", chance = 150},
{name = "pipe", chance = 100},
{name = "iron-stick", chance = 50},
{name = "battery", chance = 20},
{name = "empty-barrel", chance = 10},
{name = "crude-oil-barrel", chance = 30},
{name = "lubricant-barrel", chance = 20},
{name = "petroleum-gas-barrel", chance = 15},
{name = "sulfuric-acid-barrel", chance = 15},
{name = "heavy-oil-barrel", chance = 15},
{name = "light-oil-barrel", chance = 15},
{name = "water-barrel", chance = 10},
{name = "green-wire", chance = 10},
{name = "red-wire", chance = 10},
{name = "explosives", chance = 5},
{name = "advanced-circuit", chance = 5},
{name = "nuclear-fuel", chance = 1},
{name = "pipe-to-ground", chance = 10},
{name = "plastic-bar", chance = 5},
{name = "processing-unit", chance = 2},
{name = "used-up-uranium-fuel-cell", chance = 1},
{name = "uranium-fuel-cell", chance = 1},
{name = "rocket-fuel", chance = 3},
{name = "rocket-control-unit", chance = 1},
{name = "low-density-structure", chance = 1},
{name = "heat-pipe", chance = 1},
{name = "engine-unit", chance = 4},
{name = "electric-engine-unit", chance = 2},
{name = "logistic-robot", chance = 1},
{name = "construction-robot", chance = 1},
{name = "land-mine", chance = 3},
{name = "grenade", chance = 10},
{name = "rocket", chance = 3},
{name = "explosive-rocket", chance = 3},
{name = "cannon-shell", chance = 2},
{name = "explosive-cannon-shell", chance = 2},
{name = "uranium-cannon-shell", chance = 1},
{name = "explosive-uranium-cannon-shell", chance = 1},
{name = "artillery-shell", chance = 1},
{name = "cluster-grenade", chance = 2},
{name = "defender-capsule", chance = 5},
{name = "destroyer-capsule", chance = 1},
{name = "distractor-capsule", chance = 2}
}
local scrap_yield_amounts = {
["iron-plate"] = 16,
["iron-gear-wheel"] = 8,
["iron-stick"] = 16,
["copper-plate"] = 16,
["copper-cable"] = 24,
["electronic-circuit"] = 8,
["steel-plate"] = 4,
["pipe"] = 8,
["solid-fuel"] = 4,
["empty-barrel"] = 3,
["crude-oil-barrel"] = 3,
["lubricant-barrel"] = 3,
["petroleum-gas-barrel"] = 3,
["sulfuric-acid-barrel"] = 3,
["heavy-oil-barrel"] = 3,
["light-oil-barrel"] = 3,
["water-barrel"] = 3,
["battery"] = 2,
["explosives"] = 4,
["advanced-circuit"] = 2,
["nuclear-fuel"] = 0.1,
["pipe-to-ground"] = 1,
["plastic-bar"] = 4,
["processing-unit"] = 1,
["used-up-uranium-fuel-cell"] = 1,
["uranium-fuel-cell"] = 0.3,
["rocket-fuel"] = 0.3,
["rocket-control-unit"] = 0.3,
["low-density-structure"] = 0.3,
["heat-pipe"] = 1,
["green-wire"] = 8,
["red-wire"] = 8,
["engine-unit"] = 2,
["electric-engine-unit"] = 2,
["logistic-robot"] = 0.3,
["construction-robot"] = 0.3,
["land-mine"] = 1,
["grenade"] = 2,
["rocket"] = 2,
["explosive-rocket"] = 2,
["cannon-shell"] = 2,
["explosive-cannon-shell"] = 2,
["uranium-cannon-shell"] = 2,
["explosive-uranium-cannon-shell"] = 2,
["artillery-shell"] = 0.3,
["cluster-grenade"] = 0.3,
["defender-capsule"] = 2,
["destroyer-capsule"] = 0.3,
["distractor-capsule"] = 0.3
}
local scrap_raffle = {}
for _, t in pairs (mining_chance_weights) do
for x = 1, t.chance, 1 do
table.insert(scrap_raffle, t.name)
end
end
local size_of_scrap_raffle = #scrap_raffle
local function place_scrap(surface, position)
if math_random(1, 700) == 1 then
if position.x ^ 2 + position.x ^ 2 > 4096 then
local e = surface.create_entity({name = "gun-turret", position = position, force = "enemy"})
e.insert({name = "piercing-rounds-magazine", count = 100})
return
end
end
if math_random(1, 128) == 1 then
local e = surface.create_entity({name = scraps_inv[math_random(1, #scraps_inv)], position = position, force = "neutral"})
local i = e.get_inventory(defines.inventory.chest)
if i then
for x = 1, math_random(6,18), 1 do
local loot = scrap_raffle[math_random(1, size_of_scrap_raffle)]
i.insert({name = loot, count = math_floor(scrap_yield_amounts[loot] * math_random(5, 35) * 0.1) + 1})
end
end
return
end
surface.create_entity({name = small_scraps[math_random(1, #small_scraps)], position = position, force = "neutral"})
end
local function is_scrap_area(noise)
if noise > 0.25 then return true end
if noise < -0.25 then return true end
end
local function move_away_biteys(surface, area)
for _, e in pairs(surface.find_entities_filtered({type = {"unit-spawner", "turret", "unit"}, area = area})) do
local position = surface.find_non_colliding_position(e.name, e.position, 96, 4)
if position then
surface.create_entity({name = e.name, position = position, force = "enemy"})
e.destroy()
end
end
end
local vectors = {{0,0}, {1,0}, {-1,0}, {0,1}, {0,-1}}
local function replace_ground(entity)
local surface = entity.surface
for _, v in pairs(vectors) do
local position = {entity.position.x + v[1], entity.position.y + v[2]}
if not surface.get_tile(position).collides_with("resource-layer") then
surface.set_tiles({{name = "landfill", position = position}}, true)
end
end
end
local function on_player_mined_entity(event)
local entity = event.entity
if not entity.valid then return end
if not is_scrap(entity.name) then return end
replace_ground(entity)
event.buffer.clear()
local scrap = scrap_raffle[math.random(1, size_of_scrap_raffle)]
local amount_bonus = (game.forces.enemy.evolution_factor * 2) + (game.forces.player.mining_drill_productivity_bonus * 2)
local r1 = math.ceil(scrap_yield_amounts[scrap] * (0.3 + (amount_bonus * 0.3)))
local r2 = math.ceil(scrap_yield_amounts[scrap] * (1.7 + (amount_bonus * 1.7)))
local amount = math.random(r1, r2)
local player = game.players[event.player_index]
local inserted_count = player.insert({name = scrap, count = amount})
if inserted_count ~= amount then
local amount_to_spill = amount - inserted_count
entity.surface.spill_item_stack(entity.position,{name = scrap, count = amount_to_spill}, true)
end
entity.surface.create_entity({
name = "flying-text",
position = entity.position,
text = "+" .. amount .. " [img=item/" .. scrap .. "]",
color = {r=0.98, g=0.66, b=0.22}
})
end
local function on_entity_died(event)
if not event.entity.valid then return end
if not is_scrap(event.entity.name) then return end
replace_ground(event.entity)
end
local function on_chunk_generated(event)
local surface = event.surface
local seed = surface.map_gen_settings.seed
local left_top_x = event.area.left_top.x
local left_top_y = event.area.left_top.y
local position
local noise
for x = 0, 31, 1 do
for y = 0, 31, 1 do
if math_random(1, 3) > 1 then
position = {x = left_top_x + x, y = left_top_y + y}
if not surface.get_tile(position).collides_with("resource-layer") then
noise = get_noise("scrapyard", position, seed)
if is_scrap_area(noise) then
surface.set_tiles({{name = "dirt-" .. math_floor(math_abs(noise) * 6) % 6 + 2, position = position}}, true)
place_scrap(surface, position)
end
end
end
end
end
move_away_biteys(surface, event.area)
end
local Event = require 'utils.event'
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
Event.add(defines.events.on_entity_died, on_entity_died)