1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-26 03:52:22 +02:00
ComfyFactorio/modules/towny/town_center.lua

375 lines
12 KiB
Lua
Raw Normal View History

2019-12-17 16:45:23 +01:00
local Team = require "modules.towny.team"
2019-12-17 18:06:56 +01:00
local Public = {}
2019-12-17 16:45:23 +01:00
2019-12-17 19:08:40 +01:00
local math_random = math.random
2019-12-17 16:45:23 +01:00
local table_insert = table.insert
2019-12-20 14:46:20 +01:00
local math_floor = math.floor
2019-12-17 16:45:23 +01:00
2019-12-20 14:46:20 +01:00
local min_distance_to_spawn = 128
2019-12-17 16:45:23 +01:00
local square_min_distance_to_spawn = min_distance_to_spawn ^ 2
2019-12-19 17:11:13 +01:00
local town_radius = 28
2019-12-18 19:08:09 +01:00
local radius_between_towns = 160
2019-12-17 16:45:23 +01:00
2019-12-17 22:40:16 +01:00
local colors = {}
local c1 = 250
2019-12-19 17:11:13 +01:00
local c2 = 200
2019-12-17 22:40:16 +01:00
local c3 = -25
for v = c1, c2, c3 do
table.insert(colors, {0, 0, v})
end
for v = c1, c2, c3 do
table.insert(colors, {0, v, 0})
end
for v = c1, c2, c3 do
table.insert(colors, {v, 0, 0})
end
for v = c1, c2, c3 do
table.insert(colors, {0, v, v})
end
for v = c1, c2, c3 do
table.insert(colors, {v, v, 0})
end
for v = c1, c2, c3 do
table.insert(colors, {v, 0, v})
end
2019-12-17 16:45:23 +01:00
local town_wall_vectors = {}
2019-12-17 19:08:40 +01:00
for x = town_radius * -1, town_radius, 1 do
table_insert(town_wall_vectors, {x, town_radius})
table_insert(town_wall_vectors, {x, town_radius * -1})
2019-12-17 16:45:23 +01:00
end
2019-12-17 19:08:40 +01:00
for y = (town_radius - 1) * -1, town_radius - 1, 1 do
table_insert(town_wall_vectors, {town_radius, y})
table_insert(town_wall_vectors, {town_radius * -1, y})
2019-12-17 16:45:23 +01:00
end
2019-12-17 19:08:40 +01:00
local gate_vectors_horizontal = {}
for x = -1, 1, 1 do
table_insert(gate_vectors_horizontal, {x, town_radius})
table_insert(gate_vectors_horizontal, {x, town_radius * -1})
end
local gate_vectors_vertical = {}
for y = -1, 1, 1 do
table_insert(gate_vectors_vertical, {town_radius, y})
table_insert(gate_vectors_vertical, {town_radius * -1, y})
end
local resource_vectors = {}
resource_vectors[1] = {}
for x = 7, 25, 1 do
for y = 7, 25, 1 do
table_insert(resource_vectors[1], {x, y})
end
end
resource_vectors[2] = {}
for _, vector in pairs(resource_vectors[1]) do table_insert(resource_vectors[2], {vector[1] * -1, vector[2]}) end
resource_vectors[3] = {}
for _, vector in pairs(resource_vectors[1]) do table_insert(resource_vectors[3], {vector[1] * -1, vector[2] * -1}) end
resource_vectors[4] = {}
for _, vector in pairs(resource_vectors[1]) do table_insert(resource_vectors[4], {vector[1], vector[2] * -1}) end
2019-12-18 12:25:51 +01:00
local additional_resource_vectors = {}
additional_resource_vectors[1] = {}
for x = 10, 22, 1 do
for y = -4, 4, 1 do
table_insert(additional_resource_vectors[1], {x, y})
end
end
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
table_insert(additional_resource_vectors[3], {x, y})
end
end
additional_resource_vectors[4] = {}
for _, vector in pairs(additional_resource_vectors[3]) do table_insert(additional_resource_vectors[4], {vector[1], vector[2] * -1}) end
local market_collide_vectors = {{-1, 1},{0, 1},{1, 1},{1, 0},{1, -1}}
2019-12-17 18:06:56 +01:00
local clear_blacklist_types = {
["simple-entity"] = true,
2019-12-18 12:25:51 +01:00
["resource"] = true,
2019-12-17 18:06:56 +01:00
["cliff"] = true,
}
2019-12-17 19:08:40 +01:00
local starter_supplies = {
2019-12-18 19:08:09 +01:00
{name = "raw-fish", count = 3},
2019-12-17 19:08:40 +01:00
{name = "grenade", count = 3},
{name = "stone", count = 32},
{name = "land-mine", count = 4},
{name = "iron-gear-wheel", count = 16},
{name = "iron-plate", count = 32},
{name = "copper-plate", count = 16},
{name = "shotgun", count = 1},
{name = "shotgun-shell", count = 8},
{name = "firearm-magazine", count = 16},
2019-12-20 14:46:20 +01:00
{name = "firearm-magazine", count = 16},
{name = "gun-turret", count = 2},
2019-12-17 19:08:40 +01:00
}
2019-12-17 16:45:23 +01:00
local function draw_town_spawn(player_name)
2019-12-17 20:07:00 +01:00
local market = global.towny.town_centers[player_name].market
2019-12-17 16:45:23 +01:00
local position = market.position
local surface = market.surface
2019-12-18 12:25:51 +01:00
local area = {{position.x - (town_radius + 1), position.y - (town_radius + 1)}, {position.x + (town_radius + 1), position.y + (town_radius + 1)}}
2019-12-17 18:06:56 +01:00
for _, e in pairs(surface.find_entities_filtered({area = area, force = "neutral"})) do
if not clear_blacklist_types[e.type] then
2019-12-18 14:31:50 +01:00
e.destroy()
2019-12-17 18:06:56 +01:00
end
end
2019-12-17 19:08:40 +01:00
for _, vector in pairs(gate_vectors_horizontal) do
local p = {position.x + vector[1], position.y + vector[2]}
if surface.can_place_entity({name = "gate", position = p, force = player_name}) 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]}
if surface.can_place_entity({name = "gate", position = p, force = player_name}) then
surface.create_entity({name = "gate", position = p, force = player_name, direction = 0})
end
end
2019-12-17 16:45:23 +01:00
for _, vector in pairs(town_wall_vectors) do
2019-12-17 19:08:40 +01:00
local p = {position.x + vector[1], position.y + vector[2]}
2019-12-17 16:45:23 +01:00
if surface.can_place_entity({name = "stone-wall", position = p, force = player_name}) then
surface.create_entity({name = "stone-wall", position = p, force = player_name})
end
end
2019-12-17 19:08:40 +01:00
local ores = {"iron-ore", "copper-ore", "stone", "coal"}
table.shuffle_table(ores)
for i = 1, 4, 1 do
for _, vector in pairs(resource_vectors[i]) do
2019-12-17 20:07:00 +01:00
local p = {position.x + vector[1], position.y + vector[2]}
2019-12-19 17:11:13 +01:00
p = surface.find_non_colliding_position(ores[i], p, 64, 1)
2019-12-18 12:25:51 +01:00
if p then
2019-12-17 20:07:00 +01:00
surface.create_entity({name = ores[i], position = p, amount = 1500})
end
2019-12-17 19:08:40 +01:00
end
end
2019-12-18 12:25:51 +01:00
2019-12-17 19:08:40 +01:00
for _, item_stack in pairs(starter_supplies) do
local m1 = -8 + math_random(0, 16)
local m2 = -8 + math_random(0, 16)
2019-12-17 20:07:00 +01:00
local p = {position.x + m1, position.y + m2}
2019-12-19 17:11:13 +01:00
p = surface.find_non_colliding_position("wooden-chest", p, 64, 1)
2019-12-17 19:08:40 +01:00
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
2019-12-18 12:25:51 +01:00
local vector_indexes = {1,2,3,4}
table.shuffle_table(vector_indexes)
2019-12-18 14:31:50 +01:00
local tree = "tree-0" .. math_random(1, 9)
2019-12-18 12:25:51 +01:00
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]}
2019-12-19 17:11:13 +01:00
p = surface.find_non_colliding_position(tree, p, 64, 1)
2019-12-18 12:25:51 +01:00
if p then
2019-12-18 14:31:50 +01:00
surface.create_entity({name = tree, position = p})
2019-12-18 12:25:51 +01:00
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}}
2019-12-18 14:31:50 +01:00
if surface.count_tiles_filtered({name = {"water", "deepwater"}, area = area}) < 8 then
2019-12-18 12:25:51 +01:00
for _, vector in pairs(additional_resource_vectors[vector_indexes[2]]) do
local p = {position.x + vector[1], position.y + vector[2]}
if surface.get_tile(p).name ~= "out-of-map" then
surface.set_tiles({{name = "water", position = p}})
end
end
end
for _, vector in pairs(additional_resource_vectors[vector_indexes[3]]) do
local p = {position.x + vector[1], position.y + vector[2]}
2019-12-19 17:11:13 +01:00
p = surface.find_non_colliding_position("uranium-ore", p, 64, 1)
2019-12-18 12:25:51 +01:00
if p then
surface.create_entity({name = "uranium-ore", position = p, amount = 1500})
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]}
2019-12-19 17:11:13 +01:00
p = surface.find_non_colliding_position("crude-oil", p, 64, 1)
2019-12-18 12:25:51 +01:00
if p then
surface.create_entity({name = "crude-oil", position = p, amount = 500000})
end
end
2019-12-17 16:45:23 +01:00
end
local function is_valid_location(surface, entity)
for _, vector in pairs(market_collide_vectors) do
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
end
2019-12-18 00:46:21 +01:00
end
2019-12-17 16:45:23 +01:00
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
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
2019-12-18 00:46:21 +01:00
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}
})
return
end
2019-12-17 16:45:23 +01:00
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
if e.force.index ~= 3 then
count = count + 1
end
end
2019-12-20 14:46:20 +01:00
if count > 2 then
2019-12-17 18:06:56 +01:00
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
end
return true
2019-12-17 16:45:23 +01:00
end
2019-12-17 20:07:00 +01:00
function Public.set_market_health(entity, final_damage_amount)
local town_center = global.towny.town_centers[entity.force.name]
2019-12-20 14:46:20 +01:00
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
2019-12-17 20:07:00 +01:00
local m = town_center.health / town_center.max_health
entity.health = 150 * m
2019-12-18 14:31:50 +01:00
rendering.set_text(town_center.health_text, "HP: " .. town_center.health .. " / " .. town_center.max_health)
2019-12-17 20:07:00 +01:00
end
2019-12-17 18:06:56 +01:00
function Public.found(event)
2019-12-17 16:45:23 +01:00
local entity = event.created_entity
2019-12-18 00:46:21 +01:00
if entity.force.index ~= 1 then return end
if entity.name ~= "stone-furnace" then return end
2019-12-17 16:45:23 +01:00
local player = game.players[event.player_index]
local player_name = tostring(player.name)
if game.forces[player_name] then return end
2019-12-20 23:10:03 +01:00
local inventory = player.get_main_inventory()
if inventory.get_item_count("small-plane") < 1 then return end
2019-12-17 16:45:23 +01:00
local surface = entity.surface
2019-12-18 12:25:51 +01:00
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}
})
player.insert({name = "stone-furnace", count = 1})
entity.destroy()
return true
end
end
2019-12-17 16:45:23 +01:00
if not is_valid_location(surface, entity) then
player.insert({name = "stone-furnace", count = 1})
entity.destroy()
2019-12-18 12:25:51 +01:00
return true
2019-12-17 16:45:23 +01:00
end
Team.add_new_force(player_name)
2019-12-17 20:07:00 +01:00
global.towny.town_centers[player_name] = {}
local town_center = global.towny.town_centers[player_name]
town_center.market = surface.create_entity({name = "market", position = entity.position, force = player_name})
2019-12-19 17:11:13 +01:00
town_center.chunk_position = {math.floor(town_center.market.position.x / 32), math.floor(town_center.market.position.y / 32)}
2019-12-18 14:31:50 +01:00
town_center.max_health = 1000
2019-12-17 20:07:00 +01:00
town_center.health = town_center.max_health
2019-12-17 22:40:16 +01:00
town_center.color = colors[math_random(1, #colors)]
2019-12-20 17:02:23 +01:00
town_center.research_counter = 1
2019-12-17 20:07:00 +01:00
town_center.health_text = rendering.draw_text{
text = "HP: " .. town_center.health .. " / " .. town_center.max_health,
surface = surface,
target = town_center.market,
target_offset = {0, -2.5},
color = {200, 200, 200},
scale = 1.00,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
town_center.town_caption = rendering.draw_text{
2019-12-18 12:25:51 +01:00
text = player.name .. "'s Town",
2019-12-17 20:07:00 +01:00
surface = surface,
target = town_center.market,
target_offset = {0, -3.25},
2019-12-17 22:40:16 +01:00
color = town_center.color,
2019-12-17 20:07:00 +01:00
scale = 1.30,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
2019-12-17 16:45:23 +01:00
global.towny.size_of_town_centers = global.towny.size_of_town_centers + 1
entity.destroy()
draw_town_spawn(player_name)
2019-12-17 22:40:16 +01:00
Team.add_player_to_town(player, town_center)
player.force.set_spawn_position({x = town_center.market.position.x, y = town_center.market.position.y + 4}, surface)
2019-12-17 18:06:56 +01:00
2019-12-18 12:25:51 +01:00
global.towny.cooldowns[player.index] = game.tick + 3600 * 15
2019-12-20 23:10:03 +01:00
inventory.remove({name = "small-plane", count = 1})
2019-12-18 12:25:51 +01:00
game.print(">> " .. player.name .. " has founded a new town!", {255, 255, 0})
2019-12-17 18:06:56 +01:00
return true
2019-12-17 16:45:23 +01:00
end
2019-12-17 18:06:56 +01:00
return Public