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

View File

@ -1,2 +1,58 @@
[modules] [modules]
charging_station_tooltip=Charge your armor equipment from nearby accumulators!\nWorks only with those that have more than 3MJ of power. 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 simplex_noise = require 'utils.simplex_noise'.d2
local spawn_size = 96 local spawn_size = 96
local wall_thickness = 3 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 function clone_chunk(event, source_surface_name)
local source_surface = game.surfaces[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 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 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 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 end
if noise < -0.75 then if noise < -0.75 then
if math.random(1, 16) == 1 then if math.random(1, 16) == 1 then
@ -75,7 +88,7 @@ local function spawn_area(event)
end end
if left_top.x == -64 and left_top.y == -64 then 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"}) 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 = "submachine-gun", count = 3})
wreck.insert({name = "firearm-magazine", count = 32}) wreck.insert({name = "firearm-magazine", count = 32})
wreck.insert({name = "grenade", count = 8}) wreck.insert({name = "grenade", count = 8})

View File

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

View File

@ -44,6 +44,7 @@ local function on_player_joined_game(event)
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" }) 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.minimal_height = 38
b.style.maximal_height = 38
b.style.minimal_width = 38 b.style.minimal_width = 38
b.style.top_padding = 2 b.style.top_padding = 2
b.style.left_padding = 4 b.style.left_padding = 4

View File

@ -1,4 +1,5 @@
local Public = {} local Public = {}
local Table = require "modules.towny.table"
local math_random = math.random local math_random = math.random
local math_floor = math.floor local math_floor = math.floor
local math_sqrt = math.sqrt local math_sqrt = math.sqrt
@ -46,8 +47,9 @@ local function get_commmands(target, group)
end end
local function roll_market() local function roll_market()
local townytable = Table.get_table()
local r_max = 0 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. --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 local research_threshold = game.forces.enemy.evolution_factor * #game.technology_prototypes * 0.175
@ -96,9 +98,10 @@ local function is_swarm_valid(swarm)
end end
function Public.validate_swarms() 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 if not is_swarm_valid(swarm) then
table_remove(global.towny.swarms, k) table_remove(townytable.swarms, k)
end end
end end
end end
@ -133,7 +136,8 @@ function Public.clear_spawn_for_player(player)
end end
function Public.unit_groups_start_moving() 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 then
if swarm.group.valid then if swarm.group.valid then
swarm.group.start_moving() swarm.group.start_moving()
@ -143,8 +147,9 @@ function Public.unit_groups_start_moving()
end end
function Public.swarm() function Public.swarm()
local townytable = Table.get_table()
local count = 0 local count = 0
for k, swarm in pairs(global.towny.swarms) do for k, swarm in pairs(townytable.swarms) do
count = count + 1 count = count + 1
end end
if count > 6 then return end if count > 6 then return end
@ -170,11 +175,12 @@ function Public.swarm()
structure_type = defines.compound_command.return_last, structure_type = defines.compound_command.return_last,
commands = get_commmands(market, unit_group) 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 end
function Public.set_evolution() function Public.set_evolution()
local town_center_count = global.towny.size_of_town_centers local townytable = Table.get_table()
local town_center_count = townytable.size_of_town_centers
if town_center_count == 0 then if town_center_count == 0 then
game.forces.enemy.evolution_factor = 0 game.forces.enemy.evolution_factor = 0
return return
@ -183,7 +189,7 @@ function Public.set_evolution()
local max_research_count = math_floor(#game.technology_prototypes * 0.30) local max_research_count = math_floor(#game.technology_prototypes * 0.30)
local evo = 0 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 evo = evo + town_center.research_counter
end end
evo = evo / town_center_count evo = evo / town_center_count

View File

@ -107,7 +107,7 @@ function Public.prevent_isolation(event)
local surface = event.created_entity.surface local surface = event.created_entity.surface
if is_position_isolated(surface, entity.force, entity.position) then if is_position_isolated(surface, entity.force, entity.position) then
error_floaty(surface, entity.position, "Building is not connected to town!") error_floaty(surface, entity.position, {"modules_towny.message_error_building"})
refund_item(event, event.stack.name) refund_item(event, event.stack.name)
entity.destroy() entity.destroy()
return true return true
@ -129,7 +129,7 @@ function Public.prevent_isolation_landfill(event)
for _, placed_tile in pairs(tiles) do for _, placed_tile in pairs(tiles) do
local position = placed_tile.position local position = placed_tile.position
if is_position_isolated(surface, force, position) then if is_position_isolated(surface, force, position) then
error_floaty(surface, position, "Tile is not connected to town!") error_floaty(surface, position, {"modules_towny.message_error_tile"})
surface.set_tiles({{name = "water", position = position}}, true) surface.set_tiles({{name = "water", position = position}}, true)
refund_item(event, "landfill") refund_item(event, "landfill")
end end
@ -145,7 +145,7 @@ function Public.restrictions(event)
if entity.force.index == 1 then if entity.force.index == 1 then
if is_town_market_nearby(entity) then if is_town_market_nearby(entity) then
refund_item(event, event.stack.name) 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() entity.destroy()
end end
return return
@ -154,7 +154,7 @@ function Public.restrictions(event)
if not entity_type_whitelist[entity.type] then 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 if entity.position.x ^ 2 + entity.position.y ^ 2 > square_min_distance_to_spawn then return end
refund_item(event, event.stack.name) 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() entity.destroy()
end end

View File

@ -1,35 +1,14 @@
local Public = {} local Public = {}
local Table = require "modules.towny.table"
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 ^.^]]
function Public.toggle_button(player) function Public.toggle_button(player)
if player.gui.top["towny_map_intro_button"] then return end 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_color = {r=0.5, g=0.3, b=0.99}
b.style.font = "heading-1" b.style.font = "heading-1"
b.style.minimal_height = 38 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.top_padding = 1
b.style.left_padding = 1 b.style.left_padding = 1
b.style.right_padding = 1 b.style.right_padding = 1
@ -37,27 +16,28 @@ function Public.toggle_button(player)
end end
function Public.show(player) 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 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 = player.gui.center.add {type = "frame", name = "towny_map_intro_frame"}
local frame = frame.add {type = "frame", direction = "vertical"} local frame = frame.add {type = "frame", direction = "vertical"}
local t = frame.add {type = "table", column_count = 2} 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 = "heading-1"
label.style.font_color = {r=0.85, g=0.85, b=0.85} label.style.font_color = {r=0.85, g=0.85, b=0.85}
label.style.right_padding = 8 label.style.right_padding = 8
local t = t.add {type = "table", column_count = 4} 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_color = {170, 170, 170}
label.style.font = "heading-3" label.style.font = "heading-3"
label.style.minimal_width = 80 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 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.font = "heading-3"
label.style.minimal_width = 80 label.style.minimal_width = 80
label.style.font_color = town_center.color label.style.font_color = town_center.color
@ -65,16 +45,49 @@ function Public.show(player)
frame.add {type = "line"} 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 = "heading-1"
l.style.font_color = {r=0.85, g=0.85, b=0.85} l.style.font_color = {r=0.85, g=0.85, b=0.85}
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 = info} local l = frame.add {type = "label", caption = caption}
l.style.single_line = false l.style.single_line = false
l.style.font = "heading-2" 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 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) function Public.close(event)
if not event.element then return end if not event.element then return end
if not event.element.valid then return end if not event.element.valid then return end
@ -99,5 +112,20 @@ function Public.toggle(event)
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,15 +23,18 @@ local Info = require "modules.towny.info"
local Market = require "modules.towny.market" local Market = require "modules.towny.market"
local Team = require "modules.towny.team" local Team = require "modules.towny.team"
local Town_center = require "modules.towny.town_center" local Town_center = require "modules.towny.town_center"
local Table = require "modules.towny.table"
require "modules.custom_death_messages" require "modules.custom_death_messages"
require "modules.flashlight_toggle_button" require "modules.flashlight_toggle_button"
require "modules.global_chat_toggle" require "modules.global_chat_toggle"
require "modules.biters_yield_coins" require "modules.biters_yield_coins"
local function on_player_joined_game(event) local function on_player_joined_game(event)
local townytable = Table.get_table()
local player = game.players[event.player_index] local player = game.players[event.player_index]
Info.toggle_button(player) Info.toggle_button(player)
Info.show(player) Info.show(player)
Info.new_town_button(player)
Team.set_player_color(player) Team.set_player_color(player)
@ -44,14 +47,14 @@ local function on_player_joined_game(event)
return return
end end
if not global.towny.requests[player.index] then return end if not townytable.requests[player.index] then return end
if global.towny.requests[player.index] ~= "kill-character" then return end if townytable.requests[player.index] ~= "kill-character" then return end
if player.character then if player.character then
if player.character.valid then if player.character.valid then
player.character.die() player.character.die()
end end
end end
global.towny.requests[player.index] = nil townytable.requests[player.index] = nil
end end
local function on_player_respawned(event) local function on_player_respawned(event)
@ -135,11 +138,13 @@ end
local function on_gui_click(event) local function on_gui_click(event)
Info.close(event) Info.close(event)
Info.toggle(event) Info.toggle(event)
Info.toggle_town(event)
end end
local function on_research_finished(event) local function on_research_finished(event)
Combat_balance.research(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 if not town_center then return end
town_center.research_counter = town_center.research_counter + 1 town_center.research_counter = town_center.research_counter + 1
end end
@ -151,6 +156,10 @@ local function on_player_died(event)
Team.reveal_entity_to_all(player.character) Team.reveal_entity_to_all(player.character)
end end
local function on_player_changed_force(event)
Info.update_new_town_button(game.players[event.player_index])
end
local tick_actions = { local tick_actions = {
[60 * 5] = Team.update_town_chart_tags, [60 * 5] = Team.update_town_chart_tags,
[60 * 10] = Team.set_all_player_colors, [60 * 10] = Team.set_all_player_colors,
@ -168,14 +177,6 @@ local function on_nth_tick(event)
end end
local function on_init() 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.difficulty_settings.technology_price_multiplier = 0.30
game.map_settings.enemy_evolution.time_factor = 0 game.map_settings.enemy_evolution.time_factor = 0
game.map_settings.enemy_evolution.destroy_factor = 0 game.map_settings.enemy_evolution.destroy_factor = 0
@ -206,3 +207,4 @@ 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_entity, on_robot_built_entity)
Event.add(defines.events.on_robot_built_tile, on_robot_built_tile) 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 Town_center = require "modules.towny.town_center"
local Table = require "modules.towny.table"
local Public = {} local Public = {}
local upgrade_functions = { local upgrade_functions = {
@ -12,7 +13,7 @@ local upgrade_functions = {
--Upgrade Backpack --Upgrade Backpack
[2] = function(town_center) [2] = function(town_center)
local force = town_center.market.force 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 force.character_inventory_slots_bonus = force.character_inventory_slots_bonus + 5
end, end,
--Upgrade Backpack --Upgrade Backpack
@ -37,19 +38,19 @@ local function set_offers(town_center)
local special_offers = {} local special_offers = {}
if town_center.max_health < 500000 then if town_center.max_health < 500000 then
special_offers[1] = {{{"coin", town_center.max_health * 0.1}}, "Upgrade Town Center Health"} special_offers[1] = {{{"coin", town_center.max_health * 0.1}}, {"modules_towny.upgrade_hp"}}
else else
special_offers[1] = {{{"computer", 1}}, "Maximum Health upgrades reached!"} special_offers[1] = {{{"infinity-chest", 1}}, {"modules_towny.upgrade_hp_max"}}
end end
if force.character_inventory_slots_bonus <= 100 then if force.character_inventory_slots_bonus < 100 then
special_offers[2] = {{{"coin", (force.character_inventory_slots_bonus / 5 + 1) * 50}}, "Upgrade Backpack +5 Slot"} special_offers[2] = {{{"coin", (force.character_inventory_slots_bonus / 5 + 1) * 50}}, {"modules_towny.upgrade_backpack"}}
else else
special_offers[2] = {{{"computer", 1}}, "Maximum Backpack upgrades reached!"} special_offers[2] = {{{"infinity-chest", 1}}, {"modules_towny.upgrade_backpack_max"}}
end end
if town_center.upgrades.mining_prod < 10 then 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 else
special_offers[3] = {{{"computer", 1}}, "Maximum Backpack upgrades reached!"} special_offers[3] = {{{"infinity-chest", 1}}, {"modules_towny.upgrade_mining_max"}}
end end
@ -82,23 +83,25 @@ local function set_offers(town_center)
end end
function Public.refresh_offers(event) function Public.refresh_offers(event)
local townytable = Table.get_table()
local market = event.entity or event.market local market = event.entity or event.market
if not market then return end if not market then return end
if not market.valid then return end if not market.valid then return end
if market.name ~= "market" 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 if not town_center then return end
clear_offers(market) clear_offers(market)
set_offers(town_center) set_offers(town_center)
end end
function Public.offer_purchased(event) function Public.offer_purchased(event)
local townytable = Table.get_table()
local offer_index = event.offer_index local offer_index = event.offer_index
if not upgrade_functions[offer_index] then return end if not upgrade_functions[offer_index] then return end
local market = event.market 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 if not town_center then return end
upgrade_functions[offer_index](town_center) upgrade_functions[offer_index](town_center)
@ -112,4 +115,3 @@ function Public.offer_purchased(event)
end end
return Public 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,12 +1,14 @@
local Public = {} local Public = {}
local Table = require "modules.towny.table"
local outlander_color = {150, 150, 150} local outlander_color = {150, 150, 150}
local outlander_chat_color = {170, 170, 170} local outlander_chat_color = {170, 170, 170}
local item_drop_radius = 1.65 local item_drop_radius = 1.65
local function can_force_accept_member(force) local function can_force_accept_member(force)
local town_centers = global.towny.town_centers local townytable = Table.get_table()
local size_of_town_centers = global.towny.size_of_town_centers local town_centers = townytable.town_centers
local size_of_town_centers = townytable.size_of_town_centers
local member_limit = 0 local member_limit = 0
if size_of_town_centers <= 1 then return true end if size_of_town_centers <= 1 then return true end
@ -17,25 +19,27 @@ local function can_force_accept_member(force)
member_limit = math.floor(member_limit / size_of_town_centers) + 4 member_limit = math.floor(member_limit / size_of_town_centers) + 4
if #force.connected_players >= member_limit then if #force.connected_players >= member_limit then
game.print(">> Town " .. force.name .. " has too many settlers! Current limit (" .. member_limit .. ")" , {255, 255, 0}) game.print({"modules_towny.message_too_many_players", force.name, member_limit}, {255, 255, 0})
return return
end end
return true return true
end end
function Public.set_player_color(player) function Public.set_player_color(player)
local townytable = Table.get_table()
if player.force.index == 1 then if player.force.index == 1 then
player.color = outlander_color player.color = outlander_color
player.chat_color = outlander_chat_color player.chat_color = outlander_chat_color
return return
end 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 if not town_center then return end
player.color = town_center.color player.color = town_center.color
player.chat_color= town_center.color player.chat_color= town_center.color
end end
function Public.set_town_color(event) function Public.set_town_color(event)
local townytable = Table.get_table()
if event.command ~= "color" then return end 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 if player.force.index == 1 then
@ -43,7 +47,7 @@ function Public.set_town_color(event)
player.chat_color = outlander_chat_color player.chat_color = outlander_chat_color
return return
end end
local town_center = global.towny.town_centers[player.name] local town_center = townytable.town_centers[player.name]
if not town_center then if not town_center then
Public.set_player_color(player) Public.set_player_color(player)
return return
@ -71,7 +75,6 @@ end
function Public.give_outlander_items(player) function Public.give_outlander_items(player)
player.insert({name = "stone-furnace", count = 1}) player.insert({name = "stone-furnace", count = 1})
player.insert({name = "small-plane", count = 1})
player.insert({name = "raw-fish", count = 3}) player.insert({name = "raw-fish", count = 3})
player.insert({name = "coal", count = 3}) player.insert({name = "coal", count = 3})
end end
@ -84,6 +87,7 @@ function Public.set_player_to_outlander(player)
end end
local function ally_outlander(player, target) local function ally_outlander(player, target)
local townytable = Table.get_table()
local requesting_force = player.force local requesting_force = player.force
local target_force = target.force local target_force = target.force
@ -91,7 +95,7 @@ local function ally_outlander(player, target)
if requesting_force.index == 1 and target_force.index == 1 then return true end if requesting_force.index == 1 and target_force.index == 1 then return true end
if requesting_force.index == 1 then 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 local target_player = false
if target.type == "character" then if target.type == "character" then
@ -101,19 +105,19 @@ local function ally_outlander(player, target)
end end
if target_player then if target_player then
if global.towny.requests[target_player.index] then if townytable.requests[target_player.index] then
if global.towny.requests[target_player.index] == player.name then if townytable.requests[target_player.index] == player.name then
if global.towny.town_centers[target_force.name] then if townytable.town_centers[target_force.name] then
if not can_force_accept_member(target_force) then return true end 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}) game.print({"modules_towny.message_settled", player.name, target_force.name}, {255, 255, 0})
Public.add_player_to_town(player, global.towny.town_centers[target_force.name]) Public.add_player_to_town(player, townytable.town_centers[target_force.name])
return true return true
end end
end end
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 return true
end end
@ -121,25 +125,25 @@ local function ally_outlander(player, target)
if target.type ~= "character" then return true end if target.type ~= "character" then return true end
local target_player = target.player local target_player = target.player
if not target_player then return true end if not target_player then return true end
global.towny.requests[player.index] = target_player.name townytable.requests[player.index] = target_player.name
if global.towny.requests[target_player.index] then if townytable.requests[target_player.index] then
if global.towny.requests[target_player.index] == player.force.name then if townytable.requests[target_player.index] == player.force.name then
if not can_force_accept_member(player.force) then return true end if not can_force_accept_member(player.force) then return true end
if player.force.name == player.name then 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 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 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 return true
end end
end end
if player.force.name == player.name then 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 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 end
return true return true
end end
@ -152,10 +156,10 @@ local function ally_neighbour_towns(player, target)
if target_force.get_friend(requesting_force) and requesting_force.get_friend(target_force) then return end if target_force.get_friend(requesting_force) and requesting_force.get_friend(target_force) then return end
requesting_force.set_friend(target_force, true) 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 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
end end
@ -181,6 +185,7 @@ function Public.ally_town(player, item)
end end
function Public.declare_war(player, item) function Public.declare_war(player, item)
local townytable = Table.get_table()
local position = item.position local position = item.position
local surface = player.surface 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}} local area = {{position.x - item_drop_radius, position.y - item_drop_radius}, {position.x + item_drop_radius, position.y + item_drop_radius}}
@ -195,8 +200,8 @@ function Public.declare_war(player, item)
if requesting_force.name == target_force.name then if requesting_force.name == target_force.name then
if player.name ~= target.force.name then if player.name ~= target.force.name then
Public.set_player_to_outlander(player) Public.set_player_to_outlander(player)
game.print(">> " .. player.name .. " has abandoned " .. target_force.name .. "'s Town!", {255, 255, 0}) game.print({"modules_towny.message_abandon", player.name, target_force.name}, {255, 255, 0})
global.towny.requests[player.index] = nil townytable.requests[player.index] = nil
end end
if player.name == target.force.name then if player.name == target.force.name then
if target.type ~= "character" then return end if target.type ~= "character" then return end
@ -204,8 +209,8 @@ function Public.declare_war(player, item)
if not target_player then return end if not target_player then return end
if target_player.index == player.index then return end if target_player.index == player.index then return end
Public.set_player_to_outlander(target_player) Public.set_player_to_outlander(target_player)
game.print(">> " .. player.name .. " has banished " .. target_player.name .. " from their Town!", {255, 255, 0}) game.print({"modules_towny.message_banish", player.name, target_player.name}, {255, 255, 0})
global.towny.requests[player.index] = nil townytable.requests[player.index] = nil
end end
return return
end end
@ -215,7 +220,7 @@ function Public.declare_war(player, item)
requesting_force.set_friend(target_force, false) requesting_force.set_friend(target_force, false)
target_force.set_friend(requesting_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 end
local radius = 96 local radius = 96
@ -250,7 +255,8 @@ function Public.add_chart_tag(force, market)
end end
function Public.update_town_chart_tags() 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 local forces = game.forces
for _, town_center in pairs(town_centers) do for _, town_center in pairs(town_centers) do
local market = town_center.market local market = town_center.market
@ -273,11 +279,13 @@ function Public.add_new_force(force_name)
force.technologies["artillery-shell-speed-1"].enabled = false force.technologies["artillery-shell-speed-1"].enabled = false
force.set_ammo_damage_modifier("landmine", -0.6) force.set_ammo_damage_modifier("landmine", -0.6)
force.set_ammo_damage_modifier("artillery-shell", -0.75) force.set_ammo_damage_modifier("artillery-shell", -0.75)
force.manual_mining_speed_modifier = 1
end end
function Public.kill_force(force_name) function Public.kill_force(force_name)
local townytable = Table.get_table()
local force = game.forces[force_name] 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 local surface = market.surface
surface.create_entity({name = "big-artillery-explosion", position = market.position}) surface.create_entity({name = "big-artillery-explosion", position = market.position})
@ -286,7 +294,7 @@ function Public.kill_force(force_name)
if player.character then if player.character then
player.character.die() player.character.die()
else else
global.towny.requests[player.index] = "kill-character" townytable.requests[player.index] = "kill-character"
end end
player.force = game.forces.player player.force = game.forces.player
end end
@ -301,13 +309,13 @@ function Public.kill_force(force_name)
game.merge_forces(force_name, "neutral") game.merge_forces(force_name, "neutral")
global.towny.town_centers[force_name] = nil townytable.town_centers[force_name] = nil
global.towny.size_of_town_centers = global.towny.size_of_town_centers - 1 townytable.size_of_town_centers = townytable.size_of_town_centers - 1
delete_chart_tag_for_all_forces(market) delete_chart_tag_for_all_forces(market)
Public.reveal_entity_to_all(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 end
local player_force_disabled_recipes = {"lab", "automation-science-pack", "stone-brick"} local player_force_disabled_recipes = {"lab", "automation-science-pack", "stone-brick"}

View File

@ -1,4 +1,5 @@
local Team = require "modules.towny.team" local Team = require "modules.towny.team"
local Table = require "modules.towny.table"
local Public = {} local Public = {}
local math_random = math.random local math_random = math.random
@ -124,7 +125,8 @@ local function count_nearby_ore(surface, position, ore_name)
end end
local function draw_town_spawn(player_name) 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 position = market.position
local surface = market.surface local surface = market.surface
@ -229,49 +231,38 @@ local function draw_town_spawn(player_name)
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 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 if not surface.can_place_entity({name = "iron-chest", position = p}) then
surface.create_entity({ flying_text(surface, entity.position, {"modules_towny.message_error_obstructed"}, {r=0.77, g=0.0, b=0.0})
name = "flying-text",
position = entity.position,
text = "Position is obstructed!",
color = {r=0.77, g=0.0, b=0.0}
})
return return
end end
end end
if global.towny.size_of_town_centers > 48 then if townytable.size_of_town_centers > 48 then
surface.create_entity({ flying_text(surface, entity.position, {"modules_towny.message_error_toomany"}, {r=0.77, g=0.0, b=0.0})
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 return
end end
if entity.position.x ^ 2 + entity.position.y ^ 2 < square_min_distance_to_spawn then if entity.position.x ^ 2 + entity.position.y ^ 2 < square_min_distance_to_spawn then
surface.create_entity({ flying_text(surface, entity.position, {"modules_towny.message_error_close_spawn_town"}, {r=0.77, g=0.0, b=0.0})
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 return
end 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}} 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 if surface.count_entities_filtered({area = area, name = "market"}) > 0 then
surface.create_entity({ flying_text(surface, entity.position, {"modules_towny.message_error_close_other_town"}, {r=0.77, g=0.0, b=0.0})
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}
})
return return
end end
@ -284,12 +275,7 @@ local function is_valid_location(surface, entity)
end end
if count > 2 then if count > 2 then
surface.create_entity({ flying_text(surface, entity.position, {"modules_towny.message_error_neutral_entities"}, {r=0.77, g=0.0, b=0.0})
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 return
end end
@ -297,7 +283,8 @@ local function is_valid_location(surface, entity)
end end
function Public.set_market_health(entity, final_damage_amount) 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) 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 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 local m = town_center.health / town_center.max_health
@ -314,7 +301,8 @@ local function is_color_used(color, town_centers)
end end
local function get_color() 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 c
local shuffle_index = {} local shuffle_index = {}
@ -330,6 +318,7 @@ local function get_color()
end end
function Public.found(event) function Public.found(event)
local townytable = Table.get_table()
local entity = event.created_entity local entity = event.created_entity
if entity.force.index ~= 1 then return end if entity.force.index ~= 1 then return end
if entity.name ~= "stone-furnace" then return end if entity.name ~= "stone-furnace" then return end
@ -338,20 +327,13 @@ function Public.found(event)
local player_name = tostring(player.name) local player_name = tostring(player.name)
if game.forces[player_name] then return end if game.forces[player_name] then return end
if not townytable.town_buttons[player.index] then return end
local inventory = player.get_main_inventory()
if inventory.get_item_count("small-plane") < 1 then return end
local surface = entity.surface local surface = entity.surface
if global.towny.cooldowns[player.index] then if townytable.cooldowns[player.index] then
if game.tick < global.towny.cooldowns[player.index] then if game.tick < townytable.cooldowns[player.index] then
surface.create_entity({ 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})
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}
})
player.insert({name = "stone-furnace", count = 1}) player.insert({name = "stone-furnace", count = 1})
entity.destroy() entity.destroy()
return true return true
@ -366,8 +348,8 @@ function Public.found(event)
Team.add_new_force(player_name) Team.add_new_force(player_name)
global.towny.town_centers[player_name] = {} townytable.town_centers[player_name] = {}
local town_center = global.towny.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.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.chunk_position = {math.floor(town_center.market.position.x / 32), math.floor(town_center.market.position.y / 32)}
town_center.max_health = 1000 town_center.max_health = 1000
@ -401,7 +383,7 @@ function Public.found(event)
scale_with_zoom = false 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() entity.destroy()
@ -413,11 +395,11 @@ function Public.found(event)
local force = player.force local force = player.force
force.set_spawn_position({x = town_center.market.position.x, y = town_center.market.position.y + 4}, surface) 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 townytable.cooldowns[player.index] = game.tick + 3600 * 15
if inventory.valid then inventory.remove({name = "small-plane", count = 1}) end townytable.town_buttons[player.index] = false
game.print(">> " .. player.name .. " has founded a new town!", {255, 255, 0}) game.print({"modules_towny.message_town_found", player.name}, {255, 255, 0})
return true return true
end end

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)