mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-03-03 14:53:01 +02:00
Merge branch 'develop' of https://github.com/SimonFlapse/RedMew into Chat-Mention-Fix2
This commit is contained in:
commit
0541682b1a
@ -2,22 +2,8 @@
|
||||
|
||||
local Game = require 'utils.game'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local prefix = '## - '
|
||||
|
||||
global.mention_enabled = true
|
||||
|
||||
local hodor_messages = {
|
||||
{'Hodor.', 16},
|
||||
{'Hodor?', 16},
|
||||
{'Hodor!', 16},
|
||||
{'Hodor! Hodor! Hodor! Hodor!', 4},
|
||||
{'Hodor :(', 4},
|
||||
{'Hodor :)', 4},
|
||||
{'HOOOODOOOR!', 4},
|
||||
{'( ͡° ͜ʖ ͡°)', 1},
|
||||
{'☉ ‿ ⚆', 1}
|
||||
}
|
||||
require 'utils.list_utils'
|
||||
local Hodor = require 'resources.hodor_messages'
|
||||
|
||||
local auto_replies = {
|
||||
['discord'] = {'Did you ask about our discord server?', 'You can find it here: redmew.com/discord'},
|
||||
@ -69,24 +55,12 @@ global.naughty_words = {
|
||||
['yikes'] = true
|
||||
}
|
||||
|
||||
local message_weight_sum = 0
|
||||
for _, w in pairs(hodor_messages) do
|
||||
message_weight_sum = message_weight_sum + w[2]
|
||||
end
|
||||
|
||||
local function hodor(event)
|
||||
local message = event.message:lower()
|
||||
|
||||
if message:match('hodor') then
|
||||
local index = math.random(1, message_weight_sum)
|
||||
local message_weight_sum = 0
|
||||
for _, m in pairs(hodor_messages) do
|
||||
message_weight_sum = message_weight_sum + m[2]
|
||||
if message_weight_sum >= index then
|
||||
game.print('Hodor: ' .. m[1])
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
game.print('Hodor: ' .. table.get_random_weighted(Hodor, 1, 2))
|
||||
end
|
||||
|
||||
-- player_index is nil if the message came from the server,
|
||||
@ -100,7 +74,7 @@ local function hodor(event)
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
if not player.admin then
|
||||
for trigger, replies in pairs(auto_replies) do
|
||||
if message:match(trigger) then
|
||||
|
@ -142,17 +142,28 @@ local pages = {
|
||||
centered_label(
|
||||
parent,
|
||||
[[
|
||||
Redmew is community for players of all skill levels committed to pushing the limits of Factorio
|
||||
Multiplayer through custom scripts and crazy map designs.
|
||||
Redmew is community for players of all skill levels committed to pushing the limits of Factorio Multiplayer through custom scripts and crazy map designs.
|
||||
|
||||
We are a friendly bunch, our objective is to have as much fun as possible and we hope you
|
||||
will too.
|
||||
]]
|
||||
We are a friendly bunch, our objective is to have as much fun as possible and we hope you will too.
|
||||
]]
|
||||
)
|
||||
|
||||
|
||||
|
||||
header_label(parent, 'How To Chat')
|
||||
centered_label(
|
||||
parent,
|
||||
[[
|
||||
To chat with other players, press the "grave" key on your keyboard.
|
||||
It is below the ESC key on English keyboards and looks like ~ or `
|
||||
This can be changed in options -> controls -> "toggle lua console".
|
||||
]]
|
||||
)
|
||||
|
||||
|
||||
|
||||
header_label(parent, 'Useful Links')
|
||||
centered_label(parent, [[
|
||||
Check out our discord for new map info and to suggest new maps / ideas.]])
|
||||
centered_label(parent, [[Check out our discord for new map info and to suggest new maps / ideas.]])
|
||||
local discord_textbox_flow = parent.add {type = 'flow'}
|
||||
local discord_textbox_flow_style = discord_textbox_flow.style
|
||||
discord_textbox_flow_style.align = 'center'
|
||||
@ -189,15 +200,6 @@ Check out our discord for new map info and to suggest new maps / ideas.]])
|
||||
|
||||
parent.add({type = 'flow'}).style.height = 24
|
||||
|
||||
header_label(parent, 'How To Chat')
|
||||
centered_label(
|
||||
parent,
|
||||
[[
|
||||
To chat with other players, press the "grave" key on your keyboard. It is below the ESC key on
|
||||
English keyboards and looks like ~ or `
|
||||
This can be changed in options -> controls -> "toggle lua console".
|
||||
]]
|
||||
)
|
||||
end
|
||||
},
|
||||
{
|
||||
@ -215,164 +217,11 @@ Have fun and play nice. Remember we are all just here to have fun so let’s kee
|
||||
|
||||
No hateful content or personal attacks.
|
||||
|
||||
If you suspect someone is griefing, notify the admin team by using /report or by clicking the report
|
||||
button next to the player in the player list.]]
|
||||
If you suspect someone is griefing, notify the admin team by using /report or by clicking the report button next to the player in the player list.
|
||||
]]
|
||||
)
|
||||
end
|
||||
},
|
||||
{
|
||||
tab_button = function(parent, player)
|
||||
local button = parent.add {type = 'button', name = tab_button_name, caption = 'Scenario Mods'}
|
||||
return button
|
||||
end,
|
||||
content = function(parent, player)
|
||||
local parent_style = parent.style
|
||||
parent_style.right_padding = 2
|
||||
|
||||
parent =
|
||||
parent.add {
|
||||
type = 'scroll-pane',
|
||||
vertical_scroll_policy = 'auto-and-reserve-space',
|
||||
horizontal_scroll_policy = 'never'
|
||||
}
|
||||
parent_style = parent.style
|
||||
parent_style.vertically_stretchable = true
|
||||
|
||||
header_label(parent, 'Soft Mods and Server Plugins')
|
||||
|
||||
local grid = parent.add {type = 'table', column_count = 3}
|
||||
local grid_style = grid.style
|
||||
grid_style.vertical_spacing = 24
|
||||
grid_style.horizontal_spacing = 8
|
||||
grid_style.top_padding = 8
|
||||
grid_style.bottom_padding = 16
|
||||
|
||||
grid.add {type = 'label'}
|
||||
local ranks = grid.add {type = 'label', caption = 'Ranks'}
|
||||
ranks.style.font = 'default-listbox'
|
||||
local ranks_flow = grid.add {type = 'flow', direction = 'vertical'}
|
||||
local ranks_label =
|
||||
ranks_flow.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
We have a basic rank system to prevent griefing. You can't use nukes or the
|
||||
deconstruction planner if you are a guest. If you play for a couple of hours an
|
||||
admin will promote you to regular. You may also ask an admin for a promotion if
|
||||
you're working on a project which requires it.]]
|
||||
}
|
||||
local ranks_label_style = ranks_label.style
|
||||
ranks_label_style.single_line = false
|
||||
local player_rank_flow = ranks_flow.add {type = 'flow', direction = 'horizontal'}
|
||||
player_rank_flow.add {type = 'label', caption = 'Your rank is:'}
|
||||
if player.admin then
|
||||
local label = player_rank_flow.add {type = 'label', caption = 'Admin'}
|
||||
label.style.font_color = rank_colors[4]
|
||||
elseif UserGroups.is_donator(player.name) then
|
||||
local label = player_rank_flow.add {type = 'label', caption = 'Donator'}
|
||||
label.style.font_color = rank_colors[3]
|
||||
elseif UserGroups.is_regular(player.name) then
|
||||
local label = player_rank_flow.add {type = 'label', caption = 'Regular'}
|
||||
label.style.font_color = rank_colors[2]
|
||||
else
|
||||
local label = player_rank_flow.add {type = 'label', caption = 'Guest'}
|
||||
label.style.font_color = rank_colors[1]
|
||||
end
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'entity/market'}
|
||||
local market = grid.add {type = 'label', caption = 'Market'}
|
||||
market.style.font = 'default-listbox'
|
||||
local market_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
On most maps you will find a market near spawn where you can use coins to
|
||||
make purchases. Coins are acquired by chopping trees, hand crafting items and
|
||||
destroying biter nests. Most items in the market are constant but some are
|
||||
map-specific (usually landfill) and will rotate in and out from time to time.]]
|
||||
}
|
||||
market_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'entity/player'}
|
||||
local player_list = grid.add {type = 'label', caption = 'Player list'}
|
||||
player_list.style.font = 'default-listbox'
|
||||
local player_list_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
Lists all players on the server and shows some stats. You can sort the list by
|
||||
clicking on the column headers. You can also poke people, which throws a random
|
||||
noun in the chat.]]
|
||||
}
|
||||
player_list_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'item/programmable-speaker'}
|
||||
local poll = grid.add {type = 'label', caption = 'Polls'}
|
||||
poll.style.font = 'default-listbox'
|
||||
local poll_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
Polls help players get consensus for major actions. Want to improve an important
|
||||
build? Make a poll to check everyone is ok with that. You need to be a regular
|
||||
to make new polls.]]
|
||||
}
|
||||
poll_label.style.single_line = false
|
||||
|
||||
local tag_button = grid.add {type = 'label', caption = 'tag'}
|
||||
local tag_button_style = tag_button.style
|
||||
tag_button_style.font = 'default-listbox'
|
||||
tag_button_style.font_color = {r = 0, g = 0, b = 0}
|
||||
local tag = grid.add {type = 'label', caption = 'Tags'}
|
||||
tag.style.font = 'default-listbox'
|
||||
local tag_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
You can assign yourself a role with tags to let other players know what you are
|
||||
doing. Or just use the tag as decoration. Regulars can create new custom tags,
|
||||
be sure to show off your creatively.]]
|
||||
}
|
||||
tag_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'item/repair-pack'}
|
||||
local task = grid.add {type = 'label', caption = 'Tasks'}
|
||||
task.style.font = 'default-listbox'
|
||||
local task_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
Not sure what you should be working on, why not look at the tasks and see what
|
||||
needs doing. Regulars can add new tasks.]]
|
||||
}
|
||||
task_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'item/blueprint'}
|
||||
local blueprint = grid.add {type = 'label', caption = 'Blueprint\nhelper'}
|
||||
local blueprint_style = blueprint.style
|
||||
blueprint_style.font = 'default-listbox'
|
||||
blueprint_style.single_line = false
|
||||
blueprint_style.width = 64
|
||||
local blueprint_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
The Blueprint helper™ lets you flip blueprints horizontally or vertically and lets you
|
||||
converter the entities used in the blueprint e.g. turn yellow belts into red belts.]]
|
||||
}
|
||||
blueprint_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'item/rocket-silo'}
|
||||
local score = grid.add {type = 'label', caption = 'Score'}
|
||||
score.style.font = 'default-listbox'
|
||||
local score_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
Shows number of rockets launched and biters liberated.]]
|
||||
}
|
||||
score_label.style.single_line = false
|
||||
end
|
||||
},
|
||||
{
|
||||
tab_button = function(parent, player)
|
||||
local button = parent.add {type = 'button', name = tab_button_name, caption = 'Map Info'}
|
||||
@ -444,6 +293,176 @@ Shows number of rockets launched and biters liberated.]]
|
||||
Gui.set_data(map_extra_info_textbox, map_extra_info_key)
|
||||
end
|
||||
},
|
||||
{
|
||||
tab_button = function(parent, player)
|
||||
local button = parent.add {type = 'button', name = tab_button_name, caption = 'Scenario Mods'}
|
||||
return button
|
||||
end,
|
||||
content = function(parent, player)
|
||||
local parent_style = parent.style
|
||||
parent_style.right_padding = 2
|
||||
|
||||
parent =
|
||||
parent.add {
|
||||
type = 'scroll-pane',
|
||||
vertical_scroll_policy = 'auto-and-reserve-space',
|
||||
horizontal_scroll_policy = 'never'
|
||||
}
|
||||
parent_style = parent.style
|
||||
parent_style.vertically_stretchable = true
|
||||
|
||||
header_label(parent, 'Soft Mods and Server Plugins')
|
||||
|
||||
local grid = parent.add {type = 'table', column_count = 3}
|
||||
local grid_style = grid.style
|
||||
grid_style.vertical_spacing = 24
|
||||
grid_style.horizontal_spacing = 8
|
||||
grid_style.top_padding = 8
|
||||
grid_style.bottom_padding = 16
|
||||
|
||||
grid.add {type = 'label'}
|
||||
local ranks = grid.add {type = 'label', caption = 'Ranks'}
|
||||
ranks.style.font = 'default-listbox'
|
||||
local ranks_flow = grid.add {type = 'flow', direction = 'vertical'}
|
||||
local ranks_label =
|
||||
ranks_flow.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
We have a basic rank system to prevent griefing. You can't use nukes or the
|
||||
deconstruction planner if you are a guest. If you play for a couple of hours an
|
||||
admin will promote you to regular. You may also ask an admin for a promotion if
|
||||
you're working on a project which requires it.]]
|
||||
}
|
||||
local ranks_label_style = ranks_label.style
|
||||
ranks_label_style.single_line = false
|
||||
local player_rank_flow = ranks_flow.add {type = 'flow', direction = 'horizontal'}
|
||||
player_rank_flow.add {type = 'label', caption = 'Your rank is:'}
|
||||
if player.admin then
|
||||
local label = player_rank_flow.add {type = 'label', caption = 'Admin'}
|
||||
label.style.font_color = rank_colors[4]
|
||||
elseif UserGroups.is_donator(player.name) then
|
||||
local label = player_rank_flow.add {type = 'label', caption = 'Donator'}
|
||||
label.style.font_color = rank_colors[3]
|
||||
elseif UserGroups.is_regular(player.name) then
|
||||
local label = player_rank_flow.add {type = 'label', caption = 'Regular'}
|
||||
label.style.font_color = rank_colors[2]
|
||||
else
|
||||
local label = player_rank_flow.add {type = 'label', caption = 'Guest'}
|
||||
label.style.font_color = rank_colors[1]
|
||||
end
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'entity/market'}
|
||||
local market = grid.add {type = 'label', caption = 'Market'}
|
||||
market.style.font = 'default-listbox'
|
||||
local market_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
On most maps you will find a market near spawn where you can use coins to
|
||||
make purchases. Coins are acquired by chopping trees, hand crafting items and
|
||||
destroying biter nests. Most items in the market are constant but some are
|
||||
map-specific (usually landfill) and will rotate in and out from time to time.]]
|
||||
}
|
||||
market_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'item/small-plane'}
|
||||
local train_savior = grid.add {type = 'label', caption = 'Train\nsavior'}
|
||||
local train_savior_style = train_savior.style
|
||||
train_savior_style.font = 'default-listbox'
|
||||
train_savior_style.single_line = false
|
||||
local train_savior_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
Trains are a factorio players' worst enemy. If you have at least one small plane
|
||||
in your inventory and would be killed by a train, your life will be spared
|
||||
but you will lose a small plane. You can get planes from the market.
|
||||
]]
|
||||
}
|
||||
train_savior_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'entity/player'}
|
||||
local player_list = grid.add {type = 'label', caption = 'Player\nlist'}
|
||||
player_list.style.font = 'default-listbox'
|
||||
player_list.style.single_line = false
|
||||
local player_list_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
Lists all players on the server and shows some stats. You can sort the list by
|
||||
clicking on the column headers. You can also poke people, which throws a random
|
||||
noun in the chat.]]
|
||||
}
|
||||
player_list_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'item/programmable-speaker'}
|
||||
local poll = grid.add {type = 'label', caption = 'Polls'}
|
||||
poll.style.font = 'default-listbox'
|
||||
local poll_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
Polls help players get consensus for major actions. Want to improve an important
|
||||
build? Make a poll to check everyone is ok with that. You need to be a regular
|
||||
to make new polls.]]
|
||||
}
|
||||
poll_label.style.single_line = false
|
||||
|
||||
local tag_button = grid.add {type = 'label', caption = 'tag'}
|
||||
local tag_button_style = tag_button.style
|
||||
tag_button_style.font = 'default-listbox'
|
||||
tag_button_style.font_color = {r = 0, g = 0, b = 0}
|
||||
local tag = grid.add {type = 'label', caption = 'Tags'}
|
||||
tag.style.font = 'default-listbox'
|
||||
local tag_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
You can assign yourself a role with tags to let other players know what you are
|
||||
doing. Or just use the tag as decoration. Regulars can create new custom tags,
|
||||
be sure to show off your creatively.]]
|
||||
}
|
||||
tag_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'item/repair-pack'}
|
||||
local task = grid.add {type = 'label', caption = 'Tasks'}
|
||||
task.style.font = 'default-listbox'
|
||||
local task_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
Not sure what you should be working on, why not look at the tasks and see what
|
||||
needs doing. Regulars can add new tasks.]]
|
||||
}
|
||||
task_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'item/blueprint'}
|
||||
local blueprint = grid.add {type = 'label', caption = 'BP\nhelper'}
|
||||
local blueprint_style = blueprint.style
|
||||
blueprint_style.font = 'default-listbox'
|
||||
blueprint_style.single_line = false
|
||||
blueprint_style.width = 55
|
||||
local blueprint_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
The Blueprint helper™ lets you flip blueprints horizontally or vertically and lets you
|
||||
converter the entities used in the blueprint e.g. turn yellow belts into red belts.]]
|
||||
}
|
||||
blueprint_label.style.single_line = false
|
||||
|
||||
grid.add {type = 'sprite', sprite = 'item/rocket-silo'}
|
||||
local score = grid.add {type = 'label', caption = 'Score'}
|
||||
score.style.font = 'default-listbox'
|
||||
local score_label =
|
||||
grid.add {
|
||||
type = 'label',
|
||||
caption = [[
|
||||
Shows number of rockets launched and biters liberated.]]
|
||||
}
|
||||
score_label.style.single_line = false
|
||||
end
|
||||
},
|
||||
{
|
||||
tab_button = function(parent, player)
|
||||
local button = parent.add {type = 'button', name = tab_button_name, caption = "What's New"}
|
||||
@ -452,7 +471,7 @@ Shows number of rockets launched and biters liberated.]]
|
||||
content = function(parent, player)
|
||||
local read_only = not player.admin
|
||||
|
||||
header_label(parent, 'New Scenario Features')
|
||||
header_label(parent, 'New Features')
|
||||
|
||||
local new_info_flow = parent.add {type = 'flow'}
|
||||
new_info_flow.style.align = 'center'
|
||||
@ -470,64 +489,6 @@ Shows number of rockets launched and biters liberated.]]
|
||||
new_info_textbox_style.height = 150
|
||||
|
||||
Gui.set_data(new_info_textbox, new_info_key)
|
||||
|
||||
centered_label(
|
||||
parent,
|
||||
[[
|
||||
Help us maintain the servers and develop new features by contributing to our Patreon.
|
||||
Our donators will receive special perks.]]
|
||||
)
|
||||
|
||||
local patreon_flow = parent.add {type = 'flow', direction = 'horizontal'}
|
||||
local patreon_flow_style = patreon_flow.style
|
||||
patreon_flow_style.align = 'center'
|
||||
patreon_flow_style.horizontally_stretchable = true
|
||||
|
||||
patreon_flow.add({type = 'label', caption = 'Patreon:'}).style.font = 'default-bold'
|
||||
local patreon_textbox = patreon_flow.add {type = 'text-box', text = 'patreon.com/redmew '}
|
||||
patreon_textbox.read_only = true
|
||||
|
||||
centered_label(
|
||||
parent,
|
||||
[[
|
||||
Suggest new maps / features and see what we are working on by joining our discord.]]
|
||||
)
|
||||
|
||||
local discord_flow = parent.add {type = 'flow', direction = 'horizontal'}
|
||||
local discord_flow_style = discord_flow.style
|
||||
discord_flow_style.align = 'center'
|
||||
discord_flow_style.horizontally_stretchable = true
|
||||
|
||||
discord_flow.add({type = 'label', caption = 'Discord:'}).style.font = 'default-bold'
|
||||
local discord_textbox = discord_flow.add {type = 'text-box', text = 'redmew.com/discord '}
|
||||
discord_textbox.read_only = true
|
||||
end
|
||||
},
|
||||
{
|
||||
tab_button = function(parent, player)
|
||||
local button = parent.add {type = 'button', name = tab_button_name, caption = 'Other Servers'}
|
||||
return button
|
||||
end,
|
||||
content = function(parent, player)
|
||||
header_label(parent, 'Other Servers')
|
||||
|
||||
centered_label(
|
||||
parent,
|
||||
[[
|
||||
|
||||
We also host a modded server.
|
||||
|
||||
Check out the modded channel on our discord for details.]]
|
||||
)
|
||||
|
||||
local discord_flow = parent.add {type = 'flow', direction = 'horizontal'}
|
||||
local discord_flow_style = discord_flow.style
|
||||
discord_flow_style.align = 'center'
|
||||
discord_flow_style.horizontally_stretchable = true
|
||||
|
||||
discord_flow.add({type = 'label', caption = 'Discord:'}).style.font = 'default-bold'
|
||||
local discord_textbox = discord_flow.add {type = 'text-box', text = 'redmew.com/discord '}
|
||||
discord_textbox.read_only = true
|
||||
end
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ local Game = require 'utils.game'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local info = require 'features.gui.info'
|
||||
local join_msgs = require 'resources.join_messages'
|
||||
|
||||
local function player_created(event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
@ -16,8 +17,10 @@ local function player_created(event)
|
||||
player.insert {name = 'iron-gear-wheel', count = 8}
|
||||
player.insert {name = 'iron-plate', count = 16}
|
||||
|
||||
player.print('Trouble chatting? Change the keybinding in:')
|
||||
player.print('Options -> Controls -> Toggle Lua console')
|
||||
player.print('Welcome to this map created by the RedMew team. You can join our discord at: redmew.com/discord')
|
||||
player.print('Click the question mark in the top left corner for server infomation and map details.')
|
||||
|
||||
game.print(table.get_random_weighted(join_msgs, 1, 2))
|
||||
|
||||
local gui = player.gui
|
||||
gui.top.style = 'slot_table_spacing_horizontal_flow'
|
||||
|
@ -80,6 +80,7 @@ local Config = {
|
||||
['market'] = 9,
|
||||
['stone-wall'] = 3,
|
||||
['sand-rock-big'] = 2,
|
||||
['rock-huge'] = 2.5,
|
||||
['out-of-map'] = 1,
|
||||
['stone-path'] = 0.03,
|
||||
['concrete'] = 0.04,
|
||||
@ -167,67 +168,15 @@ local Config = {
|
||||
{name = 'dirt', min = 0.39, max = 0.53},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
-- responsible for resource spawning
|
||||
ScatteredResources = {
|
||||
enabled = true,
|
||||
|
||||
-- creates clusters of ore with higher yields and frequency instead of evenly scattered ore
|
||||
-- lowers max resource max_resource_probability to 50% of the original value
|
||||
cluster_mode = true,
|
||||
|
||||
-- value between 0 and 1, higher value means stronger variance between coordinates
|
||||
noise_variance = 0.04,
|
||||
|
||||
-- a value between 0 and 1 that triggers the spawning of resource based on noise
|
||||
noise_resource_threshold = 0.40,
|
||||
|
||||
-- raw multiplier for ore content in cluster mode
|
||||
cluster_yield_multiplier = 1.7,
|
||||
|
||||
-- shows where resources are located
|
||||
display_resource_fields = false,
|
||||
|
||||
-- percentage of resource added to the sum. 100 tiles means
|
||||
-- 10% more resources with a distance_richness_modifier of 10
|
||||
-- 20% more resources with a distance_richness_modifier of 5
|
||||
distance_richness_modifier = 7,
|
||||
|
||||
-- defines the increased chance of spawning resources
|
||||
-- calculated_probability = resource_probability + ((distance / distance_probability_modifier) / 100)
|
||||
distance_probability_modifier = 10,
|
||||
|
||||
-- increases the amount of liquids that need pumping
|
||||
liquid_value_modifiers = {
|
||||
['crude-oil'] = 750,
|
||||
},
|
||||
|
||||
-- min percentage of chance that resources will spawn after mining
|
||||
resource_probability = 0.01,
|
||||
|
||||
-- max chance of spawning resources based on resource_probability + calculated distance_probability_modifier
|
||||
max_resource_probability = 0.30,
|
||||
|
||||
-- weights per resource of spawning
|
||||
resource_weights = {
|
||||
['coal'] = 160,
|
||||
['copper-ore'] = 215,
|
||||
['iron-ore'] = 389,
|
||||
['stone'] = 212,
|
||||
['uranium-ore'] = 21,
|
||||
['crude-oil'] = 3,
|
||||
},
|
||||
|
||||
-- minimum distance from the spawn point required before it spawns
|
||||
minimum_resource_distance = {
|
||||
['coal'] = 16,
|
||||
['copper-ore'] = 18,
|
||||
['iron-ore'] = 18,
|
||||
['stone'] = 15,
|
||||
['uranium-ore'] = 86,
|
||||
['crude-oil'] = 57,
|
||||
},
|
||||
|
||||
|
||||
-- determines how distance is measured
|
||||
distance = function (x, y) return math.abs(x) + math.abs(y) end,
|
||||
--distance = function (x, y) return math.sqrt(x * x + y * y) end,
|
||||
|
||||
-- defines the weights of which resource_richness_value to spawn
|
||||
resource_richness_weights = {
|
||||
['scarce'] = 440,
|
||||
@ -247,6 +196,81 @@ local Config = {
|
||||
['plenty'] = {1201, 2000},
|
||||
['jackpot'] = {2001, 5000},
|
||||
},
|
||||
|
||||
-- increases the amount of resources by flat multiplication to initial amount
|
||||
-- highly suggested to use for fluids so their yield is reasonable
|
||||
resource_type_scalar = {
|
||||
['crude-oil'] = 1500,
|
||||
['uranium-ore'] = 1.25,
|
||||
},
|
||||
|
||||
-- ==============
|
||||
-- Debug settings
|
||||
-- ==============
|
||||
|
||||
-- shows the ore locations, only use when debugging (compound_cluster_mode)
|
||||
display_ore_clusters = false,
|
||||
|
||||
-- =======================
|
||||
-- Scattered mode settings
|
||||
-- =======================
|
||||
|
||||
-- creates scattered ore (single tiles) at random locations
|
||||
scattered_mode = false,
|
||||
|
||||
-- defines the increased chance of spawning resources
|
||||
-- calculated_probability = resource_probability + ((distance / scattered_distance_probability_modifier) / 100)
|
||||
-- this means the chance increases by 1% every DISTANCE tiles up to the max_probability
|
||||
scattered_distance_probability_modifier = 10,
|
||||
|
||||
-- min percentage of chance that resources will spawn after mining
|
||||
scattered_min_probability = 0.01,
|
||||
|
||||
-- max chance of spawning resources based on resource_probability + calculated scattered_distance_probability_modifier
|
||||
scattered_max_probability = 0.10,
|
||||
|
||||
-- percentage of resource added to the sum. 100 tiles means
|
||||
-- 10% more resources with a distance_richness_modifier of 10
|
||||
-- 20% more resources with a distance_richness_modifier of 5
|
||||
scattered_distance_richness_modifier = 7,
|
||||
|
||||
-- multiplies probability only if cluster mode is enabled
|
||||
scattered_cluster_probability_multiplier = 0.5,
|
||||
|
||||
-- multiplies yield only if cluster mode is enabled
|
||||
scattered_cluster_yield_multiplier = 1.7,
|
||||
|
||||
-- weights per resource of spawning
|
||||
scattered_resource_weights = {
|
||||
['coal'] = 160,
|
||||
['copper-ore'] = 215,
|
||||
['iron-ore'] = 389,
|
||||
['stone'] = 212,
|
||||
['uranium-ore'] = 21,
|
||||
['crude-oil'] = 3,
|
||||
},
|
||||
|
||||
-- minimum distance from the spawn point required before it spawns
|
||||
scattered_minimum_resource_distance = {
|
||||
['coal'] = 16,
|
||||
['copper-ore'] = 18,
|
||||
['iron-ore'] = 18,
|
||||
['stone'] = 15,
|
||||
['uranium-ore'] = 86,
|
||||
['crude-oil'] = 57,
|
||||
},
|
||||
|
||||
-- ==============================
|
||||
-- Compound cluster mode settings
|
||||
-- ==============================
|
||||
|
||||
-- creates compound clusters of ores defined by a layered ore-gen
|
||||
cluster_mode = true,
|
||||
|
||||
-- location of file to find the cluster definition file
|
||||
cluster_file_location = 'map_gen.Diggy.Orepattern.Tendrils',
|
||||
--cluster_file_location = 'map_gen.Diggy.Orepattern.Clusters',
|
||||
|
||||
},
|
||||
|
||||
-- controls the alien spawning mechanic
|
||||
@ -284,27 +308,38 @@ local Config = {
|
||||
-- format: {unlock_at_level, price, prototype_name},
|
||||
unlockables = require('map_gen.Diggy.FormatMarketItems').initialize_unlockables(
|
||||
{
|
||||
{level = 1, price = 50, name = 'raw-fish'},
|
||||
{level = 1, price = 50, name = 'steel-axe'},
|
||||
{level = 1, price = 20, name = 'raw-wood'},
|
||||
{level = 2, price = 50, name = 'small-lamp'},
|
||||
{level = 2, price = 25, name = 'stone-brick'},
|
||||
{level = 2, price = 125, name = 'stone-wall'},
|
||||
{level = 3, price = 850, name = 'submachine-gun'},
|
||||
{level = 3, price = 850, name = 'shotgun'},
|
||||
{level = 3, price = 50, name = 'firearm-magazine'},
|
||||
{level = 3, price = 50, name = 'shotgun-shell'},
|
||||
{level = 3, price = 500, name = 'light-armor'},
|
||||
{level = 11, price = 750, name = 'heavy-armor'},
|
||||
{level = 13, price = 100, name = 'piercing-rounds-magazine'},
|
||||
{level = 13, price = 100, name = 'piercing-shotgun-shell'},
|
||||
{level = 13, price = 1500, name = 'modular-armor'},
|
||||
{level = 16, price = 1000, name = 'landfill'},
|
||||
{level = 30, price = 250, name = 'uranium-rounds-magazine'},
|
||||
{level = 30, price = 1000, name = 'combat-shotgun'},
|
||||
{level = 1, price = 50, name = 'raw-wood'},
|
||||
{level = 2, price = 20, name = 'raw-fish'},
|
||||
{level = 3, price = 50, name = 'stone-brick'},
|
||||
{level = 5, price = 125, name = 'stone-wall'},
|
||||
{level = 7, price = 25, name = 'small-lamp'},
|
||||
{level = 9, price = 50, name = 'firearm-magazine'},
|
||||
{level = 9, price = 250, name = 'pistol'},
|
||||
{level = 11, price = 850, name = 'shotgun'},
|
||||
{level = 11, price = 50, name = 'shotgun-shell'},
|
||||
{level = 14, price = 500, name = 'light-armor'},
|
||||
{level = 16, price = 850, name = 'submachine-gun'},
|
||||
{level = 16, price = 50, name = 'steel-axe'},
|
||||
{level = 19, price = 100, name = 'piercing-rounds-magazine'},
|
||||
{level = 19, price = 100, name = 'piercing-shotgun-shell'},
|
||||
{level = 21, price = 750, name = 'heavy-armor'},
|
||||
{level = 25, price = 1500, name = 'modular-armor'},
|
||||
{level = 25, price = 1000, name = 'landfill'},
|
||||
{level = 28, price = {{"stone", 900}, {"coin", 25}}, name = 'personal-roboport-equipment'},
|
||||
{level = 28, price = {{"stone", 250}, {"coin", 10}}, name = 'construction-robot'},
|
||||
{level = 32, price = {{"stone", 2500}, {"coin", 100}}, name = 'power-armor'},
|
||||
{level = 34, price = {{"stone", 150}, {"coin", 10}}, name = 'battery-equipment'},
|
||||
{level = 33, price = {{"stone", 2000}, {"coin", 75}}, name = 'fusion-reactor-equipment'},
|
||||
{level = 36, price = {{"stone", 750}, {"coin", 20}}, name = 'energy-shield-equipment'},
|
||||
{level = 42, price = 1000, name = 'combat-shotgun'},
|
||||
{level = 46, price = 250, name = 'uranium-rounds-magazine'},
|
||||
{level = 58, price = {{"stone", 1500}, {"coin", 25}}, name = 'rocket-launcher'},
|
||||
{level = 58, price = {{"stone", 500}, {"coin", 5}}, name = 'rocket'},
|
||||
{level = 66, price = {{"stone", 1000}, {"coin", 10}}, name = 'explosive-rocket'},
|
||||
{level = 73, price = {{"stone", 1000}, {"coin", 200}}, name = 'satellite'},
|
||||
{level = 100, price = {{"stone", 5000}, {"coin", 9999}}, name = 'atomic-bomb'},
|
||||
}
|
||||
),
|
||||
|
||||
buffs = { --Define new buffs here
|
||||
{prototype = {name = 'mining_speed', value = 5}},
|
||||
{prototype = {name = 'inventory_slot', value = 1}},
|
||||
@ -319,4 +354,4 @@ local Config = {
|
||||
},
|
||||
}
|
||||
|
||||
return Config
|
||||
return Config
|
@ -7,7 +7,6 @@ require 'utils.list_utils'
|
||||
local Event = require 'utils.event'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local ScoreTable = require 'map_gen.Diggy.ScoreTable'
|
||||
local ArtefactHunting = require 'map_gen.Diggy.Feature.ArtefactHunting'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Task = require 'utils.Task'
|
||||
local Token = require 'utils.global_token'
|
||||
|
@ -8,23 +8,49 @@ local Event = require 'utils.event'
|
||||
local Scanner = require 'map_gen.Diggy.Scanner'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local ScoreTable = require 'map_gen.Diggy.ScoreTable'
|
||||
local ArtefactHunting = require 'map_gen.Diggy.Feature.ArtefactHunting'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local insert = table.insert
|
||||
local random = math.random
|
||||
|
||||
--BT's additions
|
||||
local Config = require 'map_gen.Diggy.Config'
|
||||
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Simplex = require 'map_gen.shared.simplex_noise'
|
||||
|
||||
local sqrt = math.sqrt
|
||||
local ceil = math.ceil
|
||||
local floor = math.floor
|
||||
|
||||
-- this
|
||||
local DiggyHole = {}
|
||||
|
||||
--[[--
|
||||
Triggers a diggy diggy hole for a given sand-rock-big.
|
||||
Triggers a diggy diggy hole for a given sand-rock-big or rock-huge.
|
||||
|
||||
Will return true even if the tile behind it is immune.
|
||||
|
||||
@param entity LuaEntity
|
||||
]]
|
||||
local function diggy_hole(entity)
|
||||
if (entity.name ~= 'sand-rock-big') then
|
||||
--[BT's additions, copied from ScatteredResources.lua
|
||||
local function get_name_by_weight(collection, sum)
|
||||
local pre_calculated = random()
|
||||
local current = 0
|
||||
local target = pre_calculated * sum
|
||||
|
||||
for name, weight in pairs(collection) do
|
||||
current = current + weight
|
||||
if (current >= target) then
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
Debug.print('Current \'' .. current .. '\' should be higher or equal to random \'' .. target .. '\'')
|
||||
end
|
||||
--]
|
||||
|
||||
if ((entity.name ~= 'sand-rock-big') and (entity.name ~= 'rock-huge')) then
|
||||
return
|
||||
end
|
||||
|
||||
@ -34,9 +60,162 @@ local function diggy_hole(entity)
|
||||
|
||||
local out_of_map_found = Scanner.scan_around_position(surface, entity.position, 'out-of-map');
|
||||
|
||||
local position = entity.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
local surface = entity.surface
|
||||
|
||||
|
||||
local distance = Config.features.ScatteredResources.distance(x, y)
|
||||
|
||||
-- source of noise for resource generation
|
||||
-- index determines offset
|
||||
-- '-1' is reserved for cluster mode
|
||||
-- compound clusters use as many indexes as needed > 1
|
||||
local base_seed
|
||||
local function seeded_noise(surface, x, y, index, sources)
|
||||
base_seed = base_seed or surface.map_gen_settings.seed + surface.index + 4000
|
||||
local noise = 0
|
||||
for _, settings in ipairs(sources) do
|
||||
settings.type = settings.type or 'perlin'
|
||||
settings.offset = settings.offset or 0
|
||||
if settings.type == 'zero' then
|
||||
noise = noise + 0
|
||||
elseif settings.type == 'one' then
|
||||
noise = noise + settings.weight * 1
|
||||
elseif settings.type == 'perlin' then
|
||||
noise = noise + settings.weight * Perlin.noise(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
elseif settings.type == 'simplex' then
|
||||
noise = noise + settings.weight * Simplex.d2(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
else
|
||||
Debug.print('noise type \'' .. settings.type .. '\' not recognized')
|
||||
end
|
||||
|
||||
end
|
||||
return noise
|
||||
end
|
||||
|
||||
-- local c_clusters = Config.features.ScatteredResources.clusters
|
||||
-- local c_mode = Config.features.ScatteredResources.cluster_mode
|
||||
|
||||
-- global config values
|
||||
|
||||
local resource_richness_weights = Config.features.ScatteredResources.resource_richness_weights
|
||||
local resource_richness_weights_sum = 0
|
||||
for _, weight in pairs(resource_richness_weights) do
|
||||
resource_richness_weights_sum = resource_richness_weights_sum + weight
|
||||
end
|
||||
local resource_richness_values = Config.features.ScatteredResources.resource_richness_values
|
||||
local resource_type_scalar = Config.features.ScatteredResources.resource_type_scalar
|
||||
|
||||
-- scattered config values
|
||||
local s_mode = Config.features.ScatteredResources.scattered_mode
|
||||
local s_dist_mod = Config.features.ScatteredResources.scattered_distance_probability_modifier
|
||||
local s_min_prob = Config.features.ScatteredResources.scattered_min_probability
|
||||
local s_max_prob = Config.features.ScatteredResources.scattered_max_probability
|
||||
local s_dist_richness = Config.features.ScatteredResources.scattered_distance_richness_modifier
|
||||
local s_cluster_prob = Config.features.ScatteredResources.scattered_cluster_probability_multiplier
|
||||
local s_cluster_mult = Config.features.ScatteredResources.scattered_cluster_yield_multiplier
|
||||
|
||||
local s_resource_weights = Config.features.ScatteredResources.scattered_resource_weights
|
||||
local s_resource_weights_sum = 0
|
||||
for _, weight in pairs(s_resource_weights) do
|
||||
s_resource_weights_sum = s_resource_weights_sum + weight
|
||||
end
|
||||
local s_min_dist = Config.features.ScatteredResources.scattered_minimum_resource_distance
|
||||
|
||||
-- cluster config values
|
||||
local cluster_mode = Config.features.ScatteredResources.cluster_mode
|
||||
|
||||
-- compound cluster spawning
|
||||
local c_mode = Config.features.ScatteredResources.cluster_mode
|
||||
-- local c_clusters = Config.features.ScatteredResources.clusters
|
||||
local c_clusters = require(Config.features.ScatteredResources.cluster_file_location)
|
||||
if ('table' ~= type(c_clusters)) then
|
||||
error('cluster_file_location invalid')
|
||||
end
|
||||
|
||||
local c_count = 0
|
||||
for _, cluster in ipairs(c_clusters) do
|
||||
c_count = c_count + 1
|
||||
cluster.weights_sum = 0
|
||||
for _, weight in pairs(cluster.weights) do
|
||||
cluster.weights_sum = cluster.weights_sum + weight
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_cluster_resource(surface, x, y, cluster_index, cluster)
|
||||
local distance = sqrt(x * x + y * y)
|
||||
local resource_name = get_name_by_weight(cluster.weights, cluster.weights_sum)
|
||||
if resource_name == 'skip' then
|
||||
return false
|
||||
end
|
||||
if cluster.distances[resource_name] then
|
||||
if distance < cluster.distances[resource_name] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local range = resource_richness_values[get_name_by_weight(resource_richness_weights, resource_richness_weights_sum)]
|
||||
local amount = random(range[1], range[2])
|
||||
amount = amount * (1 + ((distance / cluster.distance_richness) * 0.01))
|
||||
amount = amount * cluster.yield
|
||||
|
||||
if resource_type_scalar[resource_name] then
|
||||
amount = amount * resource_type_scalar[resource_name]
|
||||
end
|
||||
|
||||
Template.resources(surface, {{name = resource_name, position = {x = x, y = y}, amount = ceil(amount)}})
|
||||
return true
|
||||
end
|
||||
|
||||
local huge_rock_inserted = false
|
||||
for _, position in pairs(out_of_map_found) do
|
||||
insert(tiles, {name = 'dirt-' .. random(1, 7), position = position})
|
||||
-- if (random() > 0.50) then
|
||||
-- insert(rocks, {name = 'rock-huge', position = position})
|
||||
|
||||
|
||||
if c_mode then
|
||||
for index,cluster in ipairs(c_clusters) do
|
||||
if distance >= cluster.min_distance and cluster.noise_settings.type ~= 'skip' then
|
||||
if cluster.noise_settings.type == "connected_tendril" then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if -1 * cluster.noise_settings.threshold < noise and noise < cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
elseif cluster.noise_settings.type == "fragmented_tendril" then
|
||||
local noise1 = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
local noise2 = seeded_noise(surface, x, y, index, cluster.noise_settings.discriminator)
|
||||
if -1 * cluster.noise_settings.threshold < noise1 and noise1 < cluster.noise_settings.threshold
|
||||
and -1 * cluster.noise_settings.discriminator_threshold < noise2
|
||||
and noise2 < cluster.noise_settings.discriminator_threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
else
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if noise >= cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (huge_rock_inserted == false) then
|
||||
insert(rocks, {name = 'sand-rock-big', position = position})
|
||||
end
|
||||
end
|
||||
|
||||
Template.insert(surface, tiles, rocks)
|
||||
|
@ -142,12 +142,21 @@ local function update_market_contents(market)
|
||||
|
||||
local name = unlockable.prototype.name
|
||||
local price = unlockable.prototype.price
|
||||
print('Mining Foreman: New wares at the market! Come get your ' .. name .. ' for only ' .. price .. ' ' .. config.currency_item .. '!')
|
||||
print(type(price))
|
||||
if type(price) == 'number' then
|
||||
print('Mining Foreman: New wares at the market! Come get your ' .. name .. ' for only ' .. price .. ' ' .. config.currency_item .. '!')
|
||||
add_market_item({
|
||||
price = {{config.currency_item, price}},
|
||||
offer = {type = 'give-item', item = name, count = 1}
|
||||
})
|
||||
elseif type(price) == 'table' then
|
||||
print('Mining Foreman: New wares at the market! Come get your ' .. name .. '!')
|
||||
add_market_item({
|
||||
price = price,
|
||||
offer = {type = 'give-item', item = name, count = 1}
|
||||
})
|
||||
end
|
||||
|
||||
add_market_item({
|
||||
price = {{config.currency_item, price}},
|
||||
offer = {type = 'give-item', item = name, count = 1}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -7,6 +7,7 @@ local Event = require 'utils.event'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Simplex = require 'map_gen.shared.simplex_noise'
|
||||
local random = math.random
|
||||
local sqrt = math.sqrt
|
||||
local ceil = math.ceil
|
||||
@ -34,97 +35,218 @@ end
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function ScatteredResources.register(config)
|
||||
local noise_resource_threshold = config.noise_resource_threshold
|
||||
local noise_variance = config.noise_variance
|
||||
local cluster_mode = config.cluster_mode
|
||||
local distance_probability_modifier = config.distance_probability_modifier
|
||||
local resource_probability = config.resource_probability
|
||||
local max_resource_probability = config.max_resource_probability
|
||||
local resource_weights = config.resource_weights
|
||||
local resource_richness_weights = config.resource_richness_weights
|
||||
local distance_richness_modifier = config.distance_richness_modifier
|
||||
local liquid_value_modifiers = config.liquid_value_modifiers
|
||||
local resource_richness_values = config.resource_richness_values
|
||||
local minimum_resource_distance = config.minimum_resource_distance
|
||||
local cluster_yield_multiplier = config.cluster_yield_multiplier
|
||||
|
||||
local resource_weights_sum = 0
|
||||
for _, weight in pairs(resource_weights) do
|
||||
resource_weights_sum = resource_weights_sum + weight
|
||||
|
||||
-- source of noise for resource generation
|
||||
-- index determines offset
|
||||
-- '-1' is reserved for cluster mode
|
||||
-- compound clusters use as many indexes as needed > 1
|
||||
local base_seed
|
||||
local function seeded_noise(surface, x, y, index, sources)
|
||||
base_seed = base_seed or surface.map_gen_settings.seed + surface.index + 4000
|
||||
local noise = 0
|
||||
for _, settings in ipairs(sources) do
|
||||
settings.type = settings.type or 'perlin'
|
||||
settings.offset = settings.offset or 0
|
||||
if settings.type == 'zero' then
|
||||
noise = noise + 0
|
||||
elseif settings.type == 'one' then
|
||||
noise = noise + settings.weight * 1
|
||||
elseif settings.type == 'perlin' then
|
||||
noise = noise + settings.weight * Perlin.noise(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
elseif settings.type == 'simplex' then
|
||||
noise = noise + settings.weight * Simplex.d2(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
else
|
||||
Debug.print('noise type \'' .. settings.type .. '\' not recognized')
|
||||
end
|
||||
|
||||
end
|
||||
return noise
|
||||
end
|
||||
|
||||
-- global config values
|
||||
|
||||
local resource_richness_weights = config.resource_richness_weights
|
||||
local resource_richness_weights_sum = 0
|
||||
for _, weight in pairs(resource_richness_weights) do
|
||||
resource_richness_weights_sum = resource_richness_weights_sum + weight
|
||||
end
|
||||
|
||||
local function spawn_resource(surface, x, y, distance)
|
||||
local resource_name = get_name_by_weight(resource_weights, resource_weights_sum)
|
||||
|
||||
if (minimum_resource_distance[resource_name] > distance) then
|
||||
return
|
||||
end
|
||||
|
||||
local min_max = resource_richness_values[get_name_by_weight(resource_richness_weights, resource_richness_weights_sum)]
|
||||
local amount = ceil(random(min_max[1], min_max[2]) * (1 + ((distance / distance_richness_modifier) * 0.01)))
|
||||
|
||||
if liquid_value_modifiers[resource_name] then
|
||||
amount = amount * liquid_value_modifiers[resource_name]
|
||||
end
|
||||
|
||||
if (cluster_mode) then
|
||||
amount = amount * cluster_yield_multiplier
|
||||
end
|
||||
|
||||
local position = {x = x, y = y}
|
||||
|
||||
Template.resources(surface, {{name = resource_name, position = position, amount = amount}})
|
||||
local resource_richness_values = config.resource_richness_values
|
||||
local resource_type_scalar = config.resource_type_scalar
|
||||
|
||||
-- scattered config values
|
||||
local s_mode = config.scattered_mode
|
||||
local s_dist_mod = config.scattered_distance_probability_modifier
|
||||
local s_min_prob = config.scattered_min_probability
|
||||
local s_max_prob = config.scattered_max_probability
|
||||
local s_dist_richness = config.scattered_distance_richness_modifier
|
||||
local s_cluster_prob = config.scattered_cluster_probability_multiplier
|
||||
local s_cluster_mult = config.scattered_cluster_yield_multiplier
|
||||
|
||||
local s_resource_weights = config.scattered_resource_weights
|
||||
local s_resource_weights_sum = 0
|
||||
for _, weight in pairs(s_resource_weights) do
|
||||
s_resource_weights_sum = s_resource_weights_sum + weight
|
||||
end
|
||||
local s_min_dist = config.scattered_minimum_resource_distance
|
||||
|
||||
local seed
|
||||
local function get_noise(surface, x, y)
|
||||
seed = seed or surface.map_gen_settings.seed + surface.index + 200
|
||||
return Perlin.noise(x * noise_variance, y * noise_variance, seed)
|
||||
-- cluster config values
|
||||
local cluster_mode = config.cluster_mode
|
||||
|
||||
-- compound cluster spawning
|
||||
local c_mode = config.cluster_mode
|
||||
local c_clusters = require(config.cluster_file_location)
|
||||
if ('table' ~= type(c_clusters)) then
|
||||
error('cluster_file_location invalid')
|
||||
end
|
||||
local c_count = 0
|
||||
for _, cluster in ipairs(c_clusters) do
|
||||
c_count = c_count + 1
|
||||
cluster.weights_sum = 0
|
||||
-- ensure the cluster colors are valid otherwise it fails silently
|
||||
-- and breaks things elsewhere
|
||||
if cluster.color then
|
||||
local c = cluster.color
|
||||
if (not c.r) or (not c.g) or (not c.b) then
|
||||
cluster.color = nil
|
||||
elseif c.r < 0 or c.r > 1 or c.g < 0 or c.g > 1 or c.b < 0 or c.b > 1 then
|
||||
cluster.color = nil
|
||||
end
|
||||
end
|
||||
for _, weight in pairs(cluster.weights) do
|
||||
cluster.weights_sum = cluster.weights_sum + weight
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_cluster_resource(surface, x, y, cluster_index, cluster)
|
||||
local distance = sqrt(x * x + y * y)
|
||||
local resource_name = get_name_by_weight(cluster.weights, cluster.weights_sum)
|
||||
if resource_name == 'skip' then
|
||||
return false
|
||||
end
|
||||
if cluster.distances[resource_name] then
|
||||
if distance < cluster.distances[resource_name] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local range = resource_richness_values[get_name_by_weight(resource_richness_weights, resource_richness_weights_sum)]
|
||||
local amount = random(range[1], range[2])
|
||||
amount = amount * (1 + ((distance / cluster.distance_richness) * 0.01))
|
||||
amount = amount * cluster.yield
|
||||
|
||||
if resource_type_scalar[resource_name] then
|
||||
amount = amount * resource_type_scalar[resource_name]
|
||||
end
|
||||
|
||||
Template.resources(surface, {{name = resource_name, position = {x = x, y = y}, amount = ceil(amount)}})
|
||||
return true
|
||||
end
|
||||
|
||||
-- event registration
|
||||
Event.add(Template.events.on_void_removed, function (event)
|
||||
local position = event.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
local surface = event.surface
|
||||
|
||||
local distance = floor(sqrt(x * x + y * y))
|
||||
|
||||
if (cluster_mode and get_noise(surface, x, y) > noise_resource_threshold) then
|
||||
spawn_resource(surface, x, y, distance)
|
||||
return
|
||||
local distance = config.distance(x, y)
|
||||
|
||||
if c_mode then
|
||||
for index,cluster in ipairs(c_clusters) do
|
||||
if distance >= cluster.min_distance and cluster.noise_settings.type ~= 'skip' then
|
||||
if cluster.noise_settings.type == "connected_tendril" then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if -1 * cluster.noise_settings.threshold < noise and noise < cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
return -- resource spawned
|
||||
end
|
||||
end
|
||||
elseif cluster.noise_settings.type == "fragmented_tendril" then
|
||||
local noise1 = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
local noise2 = seeded_noise(surface, x, y, index, cluster.noise_settings.discriminator)
|
||||
if -1 * cluster.noise_settings.threshold < noise1 and noise1 < cluster.noise_settings.threshold
|
||||
and -1 * cluster.noise_settings.discriminator_threshold < noise2
|
||||
and noise2 < cluster.noise_settings.discriminator_threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
return -- resource spawned
|
||||
end
|
||||
end
|
||||
else
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if noise >= cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
return -- resource spawned
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if s_mode then
|
||||
local probability = math.min(s_max_prob, s_min_prob + 0.01 * (distance / s_dist_mod))
|
||||
|
||||
local calculated_probability = resource_probability + ((distance / distance_probability_modifier) * 0.01)
|
||||
local probability = max_resource_probability
|
||||
if (cluster_mode) then
|
||||
probability = probability * s_cluster_prob
|
||||
end
|
||||
|
||||
if (calculated_probability < probability) then
|
||||
probability = calculated_probability
|
||||
end
|
||||
if (probability > random()) then
|
||||
-- spawn single resource point for scatter mode
|
||||
local resource_name = get_name_by_weight(s_resource_weights, s_resource_weights_sum)
|
||||
if resource_name == 'skip' or s_min_dist[resource_name] > distance then
|
||||
return
|
||||
end
|
||||
|
||||
-- cluster mode reduces the max probability to reduce max spread
|
||||
if (cluster_mode) then
|
||||
probability = probability * 0.5
|
||||
end
|
||||
local range = resource_richness_values[get_name_by_weight(resource_richness_weights, resource_richness_weights_sum)]
|
||||
local amount = random(range[1], range[2])
|
||||
amount = amount * (1 + ((distance / s_dist_richness) * 0.01))
|
||||
|
||||
if (probability > random()) then
|
||||
spawn_resource(surface, x, y, distance)
|
||||
if resource_type_scalar[resource_name] then
|
||||
amount = amount * resource_type_scalar[resource_name]
|
||||
end
|
||||
|
||||
if (cluster_mode) then
|
||||
amount = amount * s_cluster_mult
|
||||
end
|
||||
|
||||
Template.resources(surface, {{name = resource_name, position={x=x,y=y}, amount = ceil(amount)}})
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if (config.display_resource_fields) then
|
||||
|
||||
if (config.display_ore_clusters) then
|
||||
local color = {}
|
||||
Event.add(defines.events.on_chunk_generated, function (event)
|
||||
local surface = event.surface
|
||||
local area = event.area
|
||||
|
||||
for x = area.left_top.x, area.left_top.x + 31 do
|
||||
for y = area.left_top.y, area.left_top.y + 31 do
|
||||
if get_noise(surface, x, y) >= noise_resource_threshold then
|
||||
Debug.print_grid_value('ore', surface, {x = x, y = y}, nil, nil, true)
|
||||
for index,cluster in ipairs(c_clusters) do
|
||||
if cluster.noise_settings.type == "connected_tendril" then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if -1 * cluster.noise_settings.threshold < noise and noise < cluster.noise_settings.threshold then
|
||||
color[index] = color[index] or cluster.color or {r=random(), g=random(), b=random()}
|
||||
Debug.print_colored_grid_value('o' .. index, surface, {x = x, y = y}, nil, nil, true, 0, color[index])
|
||||
end
|
||||
elseif cluster.noise_settings.type == "fragmented_tendril" then
|
||||
local noise1 = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
local noise2 = seeded_noise(surface, x, y, index, cluster.noise_settings.discriminator)
|
||||
if -1 * cluster.noise_settings.threshold < noise1 and noise1 < cluster.noise_settings.threshold
|
||||
and -1 * cluster.noise_settings.discriminator_threshold < noise2
|
||||
and noise2 < cluster.noise_settings.discriminator_threshold then
|
||||
color[index] = color[index] or cluster.color or {r=random(), g=random(), b=random()}
|
||||
Debug.print_colored_grid_value('o' .. index, surface, {x = x, y = y}, nil, nil, true, 0, color[index])
|
||||
end
|
||||
elseif cluster.noise_settings.type ~= 'skip' then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if noise >= cluster.noise_settings.threshold then
|
||||
color[index] = color[index] or cluster.color or {r=random(), g=random(), b=random()}
|
||||
Debug.print_colored_grid_value('o' .. index, surface, {x = x, y = y}, nil, nil, true, 0, color[index])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -18,7 +18,7 @@ local do_spawn_tile = Token.register(function(params)
|
||||
end)
|
||||
|
||||
local do_mine = Token.register(function(params)
|
||||
local sand_rocks = params.surface.find_entities_filtered({position = params.position, name = 'sand-rock-big'})
|
||||
local sand_rocks = params.surface.find_entities_filtered({position = params.position, name = {'sand-rock-big','rock-huge'}})
|
||||
|
||||
if (0 == #sand_rocks) then
|
||||
Debug.print_position(params.position, 'missing rock when trying to mine.')
|
||||
|
51
map_gen/Diggy/Orepattern/Clusters.lua
Normal file
51
map_gen/Diggy/Orepattern/Clusters.lua
Normal file
@ -0,0 +1,51 @@
|
||||
|
||||
-- defines all ore patches to be generated. Add as many clusters as
|
||||
-- needed. Clusters listed first have a higher placement priority over
|
||||
-- the latter clusters
|
||||
--
|
||||
-- TODO update and document all configuration settings
|
||||
--
|
||||
-- noise types:
|
||||
-- cluster: same as vanilla factorio generation
|
||||
-- skip: skips this cluster
|
||||
-- connected_tendril: long ribbons of ore
|
||||
-- fragmented_tendril: long ribbons of ore that occur when inside another
|
||||
-- region of ribbons
|
||||
--
|
||||
-- noise source types and configurations
|
||||
-- perlin: same as vanilla factorio generation
|
||||
-- variance: increase to make patches closer together and smaller
|
||||
-- note that this is the inverse of the cluster_mode variance
|
||||
-- threshold: increase to shrink size of patches
|
||||
-- simplex: similar to perlin
|
||||
-- zero: does nothing with this source
|
||||
-- one: adds the weight directly to the noise calculation
|
||||
clusters = {
|
||||
{
|
||||
yield=1.0,
|
||||
min_distance=30,
|
||||
distance_richness=7,
|
||||
noise_settings = {
|
||||
type = "cluster",
|
||||
threshold = 0.40,
|
||||
sources = {
|
||||
{variance=25, weight = 1, offset = 000, type="perlin"},
|
||||
}
|
||||
},
|
||||
weights = {
|
||||
['coal'] = 160,
|
||||
['copper-ore'] = 215,
|
||||
['iron-ore'] = 389,
|
||||
['stone'] = 212,
|
||||
['uranium-ore'] = 21,
|
||||
['crude-oil'] = 3,
|
||||
},
|
||||
distances = {
|
||||
['coal'] = 16,
|
||||
['copper-ore'] = 18,
|
||||
['iron-ore'] = 18,
|
||||
['stone'] = 15,
|
||||
['uranium-ore'] = 86,
|
||||
['crude-oil'] = 57,
|
||||
}, },
|
||||
}
|
220
map_gen/Diggy/Orepattern/Tendrils.lua
Normal file
220
map_gen/Diggy/Orepattern/Tendrils.lua
Normal file
@ -0,0 +1,220 @@
|
||||
|
||||
-- defines all ore patches to be generated. Add as many clusters as
|
||||
-- needed. Clusters listed first have a higher placement priority over
|
||||
-- the latter clusters
|
||||
--
|
||||
-- TODO update and document all configuration settings
|
||||
--
|
||||
-- noise types:
|
||||
-- cluster: same as vanilla factorio generation
|
||||
-- skip: skips this cluster
|
||||
-- connected_tendril: long ribbons of ore
|
||||
-- fragmented_tendril: long ribbons of ore that occur when inside another
|
||||
-- region of ribbons
|
||||
--
|
||||
-- noise source types and configurations
|
||||
-- perlin: same as vanilla factorio generation
|
||||
-- variance: increase to make patches closer together and smaller
|
||||
-- note that this is the inverse of the cluster_mode variance
|
||||
-- threshold: increase to shrink size of patches
|
||||
-- simplex: similar to perlin
|
||||
-- zero: does nothing with this source
|
||||
-- one: adds the weight directly to the noise calculation
|
||||
|
||||
return {
|
||||
{ -- tendril default large
|
||||
yield=1.5,
|
||||
min_distance=40,
|
||||
distance_richness=7,
|
||||
color={r=255/255, g=0/255, b=255/255},
|
||||
noise_settings = {
|
||||
type = "connected_tendril",
|
||||
threshold = 0.05,
|
||||
sources = {
|
||||
{variance=350*2, weight = 1.000, offset = 000, type="simplex"},
|
||||
{variance=200*2, weight = 0.350, offset = 150, type="simplex"},
|
||||
{variance=050*2, weight = 0.050, offset = 300, type="simplex"},
|
||||
{variance=020*2, weight = 0.015, offset = 450, type="simplex"},
|
||||
}
|
||||
},
|
||||
weights = {
|
||||
['coal'] = 160,
|
||||
['copper-ore'] = 215,
|
||||
['iron-ore'] = 389,
|
||||
['stone'] = 212,
|
||||
['uranium-ore'] = 21,
|
||||
},
|
||||
distances = {
|
||||
['coal'] = 16,
|
||||
['copper-ore'] = 18,
|
||||
['iron-ore'] = 18,
|
||||
['stone'] = 15,
|
||||
['uranium-ore'] = 86,
|
||||
}, },
|
||||
{ -- tendril default small
|
||||
yield=1.0,
|
||||
min_distance=25,
|
||||
distance_richness=7,
|
||||
color={r=255/255, g=255/255, b=0/255},
|
||||
noise_settings = {
|
||||
type = "connected_tendril",
|
||||
threshold = 0.05,
|
||||
sources = {
|
||||
{variance=120, weight = 1.000, offset = 000, type="simplex"},
|
||||
{variance=060, weight = 0.300, offset = 150, type="simplex"},
|
||||
{variance=040, weight = 0.200, offset = 300, type="simplex"},
|
||||
{variance=020, weight = 0.090, offset = 450, type="simplex"},
|
||||
}
|
||||
},
|
||||
weights = {
|
||||
['coal'] = 160,
|
||||
['copper-ore'] = 215,
|
||||
['iron-ore'] = 389,
|
||||
['stone'] = 212,
|
||||
['uranium-ore'] = 21,
|
||||
},
|
||||
distances = {
|
||||
['coal'] = 16,
|
||||
['copper-ore'] = 18,
|
||||
['iron-ore'] = 18,
|
||||
['stone'] = 15,
|
||||
['uranium-ore'] = 86,
|
||||
},
|
||||
},
|
||||
{ -- tendril default fragments coal
|
||||
yield=0.25,
|
||||
min_distance=10,
|
||||
distance_richness=7,
|
||||
color={r=0/255, g=0/255, b=0/255},
|
||||
noise_settings = {
|
||||
type = "fragmented_tendril",
|
||||
threshold = 0.05,
|
||||
discriminator_threshold = 0.4,
|
||||
sources = {
|
||||
{variance=050, weight = 1.000, offset = 600, type="simplex"},
|
||||
{variance=030, weight = 0.500, offset = 750, type="simplex"},
|
||||
{variance=020, weight = 0.250, offset = 900, type="simplex"},
|
||||
{variance=010, weight = 0.100, offset =1050, type="simplex"},
|
||||
},
|
||||
discriminator = {
|
||||
{variance=120, weight = 1.000, offset = 000, type="simplex"},
|
||||
{variance=060, weight = 0.300, offset = 150, type="simplex"},
|
||||
{variance=040, weight = 0.200, offset = 300, type="simplex"},
|
||||
{variance=020, weight = 0.090, offset = 450, type="simplex"},
|
||||
},
|
||||
},
|
||||
weights = {
|
||||
['coal'] = 1,
|
||||
},
|
||||
distances = {
|
||||
['coal'] = 16,
|
||||
},
|
||||
},
|
||||
{ -- tendril default fragments iron
|
||||
yield=0.25,
|
||||
min_distance=10,
|
||||
distance_richness=7,
|
||||
color={r=0/255, g=140/255, b=255/255},
|
||||
noise_settings = {
|
||||
type = "fragmented_tendril",
|
||||
threshold = 0.05,
|
||||
discriminator_threshold = 0.4,
|
||||
sources = {
|
||||
{variance=050, weight = 1.000, offset = 600, type="simplex"},
|
||||
{variance=030, weight = 0.500, offset = 750, type="simplex"},
|
||||
{variance=020, weight = 0.250, offset = 900, type="simplex"},
|
||||
{variance=010, weight = 0.100, offset =1050, type="simplex"},
|
||||
},
|
||||
discriminator = {
|
||||
{variance=120, weight = 1.000, offset = 000, type="simplex"},
|
||||
{variance=060, weight = 0.300, offset = 150, type="simplex"},
|
||||
{variance=040, weight = 0.200, offset = 300, type="simplex"},
|
||||
{variance=020, weight = 0.090, offset = 450, type="simplex"},
|
||||
},
|
||||
},
|
||||
weights = {
|
||||
['iron-ore'] = 389,
|
||||
},
|
||||
distances = {
|
||||
['iron-ore'] = 18,
|
||||
},
|
||||
},
|
||||
{ -- tendril default fragments copper
|
||||
yield=0.25,
|
||||
min_distance=10,
|
||||
distance_richness=7,
|
||||
color={r=255/255, g=55/255, b=0/255},
|
||||
noise_settings = {
|
||||
type = "fragmented_tendril",
|
||||
threshold = 0.05,
|
||||
discriminator_threshold = 0.4,
|
||||
sources = {
|
||||
{variance=050, weight = 1.000, offset = 600, type="simplex"},
|
||||
{variance=030, weight = 0.500, offset = 750, type="simplex"},
|
||||
{variance=020, weight = 0.250, offset = 900, type="simplex"},
|
||||
{variance=010, weight = 0.100, offset =1050, type="simplex"},
|
||||
},
|
||||
discriminator = {
|
||||
{variance=120, weight = 1.000, offset = 000, type="simplex"},
|
||||
{variance=060, weight = 0.300, offset = 150, type="simplex"},
|
||||
{variance=040, weight = 0.200, offset = 300, type="simplex"},
|
||||
{variance=020, weight = 0.090, offset = 450, type="simplex"},
|
||||
},
|
||||
},
|
||||
weights = {
|
||||
['copper-ore'] = 215,
|
||||
},
|
||||
distances = {
|
||||
['copper-ore'] = 18,
|
||||
},
|
||||
},
|
||||
{ -- tendril default fragments stone
|
||||
yield=0.25,
|
||||
min_distance=10,
|
||||
distance_richness=7,
|
||||
color={r=100/255, g=100/255, b=100/255},
|
||||
noise_settings = {
|
||||
type = "fragmented_tendril",
|
||||
threshold = 0.05,
|
||||
discriminator_threshold = 0.4,
|
||||
sources = {
|
||||
{variance=050, weight = 1.000, offset = 600, type="simplex"},
|
||||
{variance=030, weight = 0.500, offset = 750, type="simplex"},
|
||||
{variance=020, weight = 0.250, offset = 900, type="simplex"},
|
||||
{variance=010, weight = 0.100, offset =1050, type="simplex"},
|
||||
},
|
||||
discriminator = {
|
||||
{variance=120, weight = 1.000, offset = 000, type="simplex"},
|
||||
{variance=060, weight = 0.300, offset = 150, type="simplex"},
|
||||
{variance=040, weight = 0.200, offset = 300, type="simplex"},
|
||||
{variance=020, weight = 0.090, offset = 450, type="simplex"},
|
||||
},
|
||||
},
|
||||
weights = {
|
||||
['stone'] = 1,
|
||||
},
|
||||
distances = {
|
||||
['stone'] = 15,
|
||||
},
|
||||
},
|
||||
{ -- crude oil
|
||||
yield=1.7,
|
||||
min_distance=57,
|
||||
distance_richness=7,
|
||||
color={r=0/255, g=255/255, b=255/255},
|
||||
noise_settings = {
|
||||
type = "cluster",
|
||||
threshold = 0.40,
|
||||
sources = {
|
||||
{variance=25, weight = 1, offset = 000, type="perlin"},
|
||||
},
|
||||
},
|
||||
weights = {
|
||||
['skip'] = 997,
|
||||
['crude-oil'] = 3,
|
||||
},
|
||||
distances = {
|
||||
['crude-oil'] = 57,
|
||||
},
|
||||
},
|
||||
}
|
170
map_gen/presets/grid_islands_rotated.lua
Normal file
170
map_gen/presets/grid_islands_rotated.lua
Normal file
@ -0,0 +1,170 @@
|
||||
-- Map by grilledham, modified by Jayefuu
|
||||
-- This map uses custom ore gen. When generating the map, under the resource settings tab use Size = 'None' for all resources.
|
||||
-- This variation on grid_islands.lua has 1) Greater island separation 2) 4 not 2 rail tracks 3) Whole map rotated 45 degrees
|
||||
|
||||
-- For best balance run the following commands after map generation:
|
||||
-- /market
|
||||
-- /silent-command game.forces["player"].technologies["landfill"].enabled = false
|
||||
-- /silent-command game.forces.player.character_running_speed_modifier = 1.5
|
||||
-- /silent-command game.difficulty_settings.technology_price_multiplier=2
|
||||
|
||||
local b = require 'map_gen.shared.builders'
|
||||
local Random = require 'map_gen.shared.random'
|
||||
local ore_seed1 = 1000
|
||||
local ore_seed2 = ore_seed1 * 2
|
||||
local island_separation = 350
|
||||
local math = require "utils.math"
|
||||
local degrees = math.rad
|
||||
|
||||
local track = {
|
||||
b.translate(b.line_x(3), 0, -3),
|
||||
b.translate(b.line_x(3), 0, 3),
|
||||
b.translate(b.line_x(3), 0, -9),
|
||||
b.translate(b.line_x(3), 0, 9),
|
||||
b.rectangle(3, 22)
|
||||
}
|
||||
|
||||
h_track = b.any(track)
|
||||
h_track = b.single_x_pattern(h_track, 15)
|
||||
v_track = b.rotate(h_track,degrees(90))
|
||||
|
||||
local square = b.rectangle(190, 190)
|
||||
local circle = b.circle(80)
|
||||
|
||||
local leg = b.rectangle(32, 480)
|
||||
local head = b.translate(b.oval(32, 64), 0, -64)
|
||||
local body = b.translate(b.circle(64), 0, 64)
|
||||
|
||||
local count = 10
|
||||
local angle = 360 / count
|
||||
local list = {head, body}
|
||||
for i = 1, (count / 2) - 1 do
|
||||
local shape = b.rotate(leg, degrees(i * angle))
|
||||
table.insert(list, shape)
|
||||
end
|
||||
|
||||
local spider = b.any(list)
|
||||
local ore_spider = b.scale(spider, 0.125, 0.125)
|
||||
|
||||
local function value(base, mult, pow)
|
||||
return function(x, y)
|
||||
local d_sq = x * x + y * y
|
||||
return base + mult * d_sq ^ ( pow / 2 ) -- d ^ pow
|
||||
end
|
||||
end
|
||||
|
||||
local function non_transform(shape)
|
||||
return shape
|
||||
end
|
||||
|
||||
local function uranium_transform(shape)
|
||||
return b.scale(shape, 0.5)
|
||||
end
|
||||
|
||||
local function oil_transform(shape)
|
||||
shape = b.scale(shape, 0.5)
|
||||
return shape
|
||||
end
|
||||
|
||||
local ores = {
|
||||
{transform = non_transform, resource = 'iron-ore', value = value(500, 0.75, 1.1), weight = 16},
|
||||
{transform = non_transform, resource = 'copper-ore', value = value(400, 0.75, 1.1), weight = 10},
|
||||
{transform = non_transform, resource = 'stone', value = value(250, 0.3, 1.05), weight = 3},
|
||||
{transform = non_transform, resource = 'coal', value = value(400, 0.8, 1.075), weight = 5},
|
||||
{transform = uranium_transform, resource = 'uranium-ore', value = value(200, 0.3, 1.025), weight = 3},
|
||||
{transform = oil_transform, resource = 'crude-oil', value = value(60000, 50, 1.025), weight = 6}
|
||||
}
|
||||
|
||||
local total_ore_weights = {}
|
||||
local ore_t = 0
|
||||
for _, v in ipairs(ores) do
|
||||
ore_t = ore_t + v.weight
|
||||
table.insert(total_ore_weights, ore_t)
|
||||
end
|
||||
|
||||
local random_ore = Random.new(ore_seed1, ore_seed2)
|
||||
local pattern = {}
|
||||
|
||||
for r = 1, 50 do
|
||||
local row = {}
|
||||
pattern[r] = row
|
||||
local odd_r = (r % 2) == 1
|
||||
for c = 1, 50 do
|
||||
local odd_c = (c % 2) == 1
|
||||
|
||||
if odd_r == odd_c then
|
||||
row[c] = square
|
||||
else
|
||||
local i = random_ore:next_int(1, ore_t)
|
||||
index = table.binary_search(total_ore_weights, i)
|
||||
if (index < 0) then
|
||||
index = bit32.bnot(index)
|
||||
end
|
||||
local ore_data = ores[index]
|
||||
|
||||
local ore_shape = ore_data.transform(ore_spider)
|
||||
local ore = b.resource(ore_shape, ore_data.resource, ore_data.value)
|
||||
|
||||
local shape = circle
|
||||
shape = b.apply_entity(shape, ore)
|
||||
|
||||
row[c] = shape
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local start_patch = b.scale(spider, 0.0625, 0.0625)
|
||||
local start_iron_patch =
|
||||
b.resource(
|
||||
b.translate(start_patch, 64, 0),
|
||||
'iron-ore',
|
||||
function()
|
||||
return 1500
|
||||
end
|
||||
)
|
||||
local start_copper_patch =
|
||||
b.resource(
|
||||
b.translate(start_patch, 0, -64),
|
||||
'copper-ore',
|
||||
function()
|
||||
return 1200
|
||||
end
|
||||
)
|
||||
local start_stone_patch =
|
||||
b.resource(
|
||||
b.translate(start_patch, -64, 0),
|
||||
'stone',
|
||||
function()
|
||||
return 600
|
||||
end
|
||||
)
|
||||
local start_coal_patch =
|
||||
b.resource(
|
||||
b.translate(start_patch, 0, 64),
|
||||
'coal',
|
||||
function()
|
||||
return 1350
|
||||
end
|
||||
)
|
||||
|
||||
local start_resources = b.any({start_iron_patch, start_copper_patch, start_stone_patch, start_coal_patch})
|
||||
local start = b.apply_entity(b.square_diamond(254), start_resources)
|
||||
|
||||
local map = b.grid_pattern(pattern, 50, 50, island_separation, island_separation)
|
||||
map = b.choose(b.rectangle(350, 350), start, map)
|
||||
|
||||
local paths =
|
||||
b.any {
|
||||
b.single_y_pattern(h_track, island_separation),
|
||||
b.single_x_pattern(v_track, island_separation)
|
||||
}
|
||||
|
||||
local sea = b.tile('deepwater')
|
||||
sea = b.fish(sea, 0.0025)
|
||||
|
||||
map = b.any {map, paths, sea}
|
||||
|
||||
map = b.change_map_gen_collision_tile(map, 'water-tile', 'grass-1')
|
||||
map = b.rotate(map,degrees(45))
|
||||
|
||||
return map
|
@ -46,6 +46,7 @@ local tiles_per_tick = 32
|
||||
--shape = require "map_gen.presets.venice"
|
||||
--shape = require "map_gen.presets.goats_on_goats"
|
||||
--shape = require "map_gen.presets.grid_islands"
|
||||
--shape = require "map_gen.presets.grid_islands_rotated"
|
||||
--shape = require "map_gen.presets.crosses"
|
||||
--shape = require "map_gen.presets.crosses3"
|
||||
--shape = require "map_gen.presets.broken_web"
|
||||
|
12
resources/hodor_messages.lua
Normal file
12
resources/hodor_messages.lua
Normal file
@ -0,0 +1,12 @@
|
||||
-- List of hodor's responses and their weights
|
||||
return {
|
||||
{'Hodor.', 16},
|
||||
{'Hodor?', 16},
|
||||
{'Hodor!', 16},
|
||||
{'Hodor! Hodor! Hodor! Hodor!', 4},
|
||||
{'Hodor :(', 4},
|
||||
{'Hodor :)', 4},
|
||||
{'HOOOODOOOR!', 4},
|
||||
{'( ͡° ͜ʖ ͡°)', 1},
|
||||
{'☉ ‿ ⚆', 1}
|
||||
}
|
9
resources/join_messages.lua
Normal file
9
resources/join_messages.lua
Normal file
@ -0,0 +1,9 @@
|
||||
-- List of join messages and their weights. Default is 10.
|
||||
return {
|
||||
{'And remember.. Keep Calm And Spaghetti!', 50},
|
||||
{'Not sure what to do? Ask Newcott.', 1},
|
||||
{'Press F to pay respects and loot their items', 10},
|
||||
{'Stick and move, stick and move', 10},
|
||||
{'Fly like a butterfly, sting like a bee', 10},
|
||||
{'These are not the bots you\'re looking for', 10}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,5 @@
|
||||
-- Functions that perform actions on tables
|
||||
|
||||
local function assert_argument_valid(a, arg_type)
|
||||
arg_type = arg_type or "table"
|
||||
if type(a) ~= arg_type then
|
||||
@ -78,35 +80,63 @@ table.get = function (t, index)
|
||||
error("Index out of bounds", 2)
|
||||
end
|
||||
|
||||
-- Chooses a random entry from a table
|
||||
table.get_random = function(this_table)
|
||||
return this_table[math.random(#this_table)]
|
||||
end
|
||||
|
||||
--- Chooses a random entry from a weighted table
|
||||
-- @param weight_table a table of tables with items and their weights
|
||||
-- @param item_index the index of the items
|
||||
-- @param weight_index the index of the weights
|
||||
-- @returns a random item with weighting
|
||||
-- @see features.chat_triggers.hodor
|
||||
table.get_random_weighted = function(weighted_table, item_index, weight_index)
|
||||
local total_weight = 0
|
||||
|
||||
for _, w in pairs(weighted_table) do
|
||||
total_weight = total_weight + w[weight_index]
|
||||
end
|
||||
|
||||
local index = math.random(total_weight)
|
||||
local weight_sum = 0
|
||||
for _, w in pairs(weighted_table) do
|
||||
weight_sum = weight_sum + w[weight_index]
|
||||
if weight_sum >= index then
|
||||
return w[item_index]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[
|
||||
Returns the index where t[index] == target.
|
||||
If there is no such index, returns a negative vaule such that bit32.bnot(value) is
|
||||
Returns the index where t[index] == target.
|
||||
If there is no such index, returns a negative vaule such that bit32.bnot(value) is
|
||||
the index that the vaule should be inserted to keep the list ordered.
|
||||
t must be a list in ascending order for the return value to be valid.
|
||||
t must be a list in ascending order for the return value to be valid.
|
||||
|
||||
Usage example:
|
||||
local t = {1,3,5,7,9}
|
||||
local x = 5
|
||||
local index = table.binary_search(t, x)
|
||||
if index < 0 then
|
||||
game.print("value not found, smallest index where t[index] > x is: " .. bit32.bnot(index))
|
||||
local index = table.binary_search(t, x)
|
||||
if index < 0 then
|
||||
game.print("value not found, smallest index where t[index] > x is: " .. bit32.bnot(index))
|
||||
else
|
||||
game.print("value found at index: " .. index)
|
||||
end
|
||||
end
|
||||
]]
|
||||
table.binary_search = function(t, target)
|
||||
--For some reason bit32.bnot doesn't return negative numbers so I'm using ~x = -1 - x instead.
|
||||
assert_argument_valid(t)
|
||||
assert_argument_valid(target, "number")
|
||||
|
||||
|
||||
local lower = 1
|
||||
local upper = #t
|
||||
|
||||
|
||||
if upper == 0 then
|
||||
return -2 -- ~1
|
||||
end
|
||||
|
||||
repeat
|
||||
|
||||
repeat
|
||||
local mid = math.floor( (lower + upper) / 2 )
|
||||
local value = t[mid]
|
||||
if value == target then
|
||||
@ -115,9 +145,9 @@ table.binary_search = function(t, target)
|
||||
lower = mid + 1
|
||||
else
|
||||
upper = mid - 1
|
||||
end
|
||||
end
|
||||
until lower > upper
|
||||
|
||||
|
||||
return -1 - lower -- ~lower
|
||||
|
||||
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user