mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-10 00:43:27 +02:00
411 lines
14 KiB
Lua
411 lines
14 KiB
Lua
--luacheck: ignore
|
|
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 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
|
|
|
|
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({'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 = 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]
|
|
if player.force.index == 1 then
|
|
player.color = outlander_color
|
|
player.chat_color = outlander_chat_color
|
|
return
|
|
end
|
|
local town_center = townytable.town_centers[player.name]
|
|
if not town_center then
|
|
Public.set_player_color(player)
|
|
return
|
|
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
|
|
Public.set_player_color(p)
|
|
end
|
|
end
|
|
|
|
function Public.set_all_player_colors()
|
|
for _, p in pairs(game.connected_players) do
|
|
Public.set_player_color(p)
|
|
end
|
|
end
|
|
|
|
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)
|
|
end
|
|
|
|
function Public.give_outlander_items(player)
|
|
player.insert({name = 'stone-furnace', count = 1})
|
|
player.insert({name = 'raw-fish', count = 3})
|
|
player.insert({name = 'coal', count = 3})
|
|
end
|
|
|
|
function Public.set_player_to_outlander(player)
|
|
player.force = game.forces.player
|
|
game.permissions.get_group('outlander').add_player(player)
|
|
player.tag = '[Outlander]'
|
|
Public.set_player_color(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
|
|
townytable.requests[player.index] = target_force.name
|
|
|
|
local target_player = false
|
|
if target.type == 'character' then
|
|
target_player = target.player
|
|
else
|
|
target_player = game.players[target_force.name]
|
|
end
|
|
|
|
if target_player 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({'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({'modules_towny.message_settling', player.name, target_force.name}, {255, 255, 0})
|
|
return true
|
|
end
|
|
|
|
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
|
|
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({'modules_towny.message_accepted_own', player.name, target_player.name}, {255, 255, 0})
|
|
else
|
|
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, townytable.town_centers[player.force.name])
|
|
return true
|
|
end
|
|
end
|
|
|
|
if player.force.name == player.name then
|
|
game.print({'modules_towny.message_invite_own', player.name, target_player.name}, {255, 255, 0})
|
|
else
|
|
game.print({'modules_towny.message_invite', player.name, target_player.name, player.force.name}, {255, 255, 0})
|
|
end
|
|
return true
|
|
end
|
|
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({'modules_towny.message_friend', requesting_force.name, target_force.name}, {255, 255, 0})
|
|
|
|
if target_force.get_friend(requesting_force) then
|
|
game.print({'modules_towny.message_alliance', requesting_force.name, target_force.name}, {255, 255, 0})
|
|
end
|
|
end
|
|
|
|
function Public.ally_town(player, item)
|
|
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}}
|
|
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
|
|
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}}
|
|
|
|
local requesting_force = player.force
|
|
local target = surface.find_entities_filtered({type = {'character', 'market'}, area = area})[1]
|
|
|
|
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({'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({'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({'modules_towny.message_war', player.name, target_force.name, requesting_force.name}, {255, 255, 0})
|
|
end
|
|
|
|
local radius = 96
|
|
function Public.reveal_entity_to_all(entity)
|
|
local chart_area = {{entity.position.x - radius, entity.position.y - radius}, {entity.position.x + radius, entity.position.y + radius}}
|
|
local surface = entity.surface
|
|
for _, force in pairs(game.forces) do
|
|
force.chart(surface, chart_area)
|
|
end
|
|
end
|
|
|
|
local function delete_chart_tag_for_all_forces(market)
|
|
local forces = game.forces
|
|
local position = market.position
|
|
local surface = market.surface
|
|
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
|
|
if tag.icon.name == 'stone-furnace' then
|
|
tag.destroy()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
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"})
|
|
end
|
|
|
|
function Public.update_town_chart_tags()
|
|
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
|
|
for _, force in pairs(forces) do
|
|
if force.is_chunk_visible(market.surface, town_center.chunk_position) then
|
|
Public.add_chart_tag(force, market)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function Public.add_new_force(force_name)
|
|
local force = game.create_force(force_name)
|
|
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-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 = 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
|
|
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
|
|
e.die()
|
|
end
|
|
end
|
|
end
|
|
|
|
game.merge_forces(force_name, 'neutral')
|
|
|
|
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({'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'}
|
|
local player_force_enabled_recipes = {
|
|
'submachine-gun',
|
|
'assembling-machine-1',
|
|
'small-lamp',
|
|
'shotgun',
|
|
'shotgun-shell',
|
|
'underground-belt',
|
|
'splitter',
|
|
'steel-plate',
|
|
'car',
|
|
'cargo-wagon',
|
|
'constant-combinator',
|
|
'engine-unit',
|
|
'green-wire',
|
|
'locomotive',
|
|
'rail',
|
|
'train-stop',
|
|
'arithmetic-combinator',
|
|
'decider-combinator'
|
|
}
|
|
|
|
function Public.setup_player_force()
|
|
local p = game.permissions.create_group('outlander')
|
|
for action_name, _ in pairs(defines.input_action) do
|
|
p.set_allows_action(defines.input_action[action_name], true)
|
|
end
|
|
local defs = {
|
|
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
|