1
0
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:
SimonFlapse 2018-11-17 13:47:33 +01:00
commit 0541682b1a
17 changed files with 2331 additions and 1566 deletions

View File

@ -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

View File

@ -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
}
}

View File

@ -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'

View File

@ -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

View File

@ -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'

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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.')

View 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,
}, },
}

View 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,
},
},
}

View 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

View File

@ -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"

View 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}
}

View 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

View File

@ -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