1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2025-03-05 15:05:57 +02:00

Infinite levels, Configuable calculations and fixes

Added true infinite levels and the ability to configure the stone requirements calculation from the config.lua file.

Moved MarketUnlockables out ouf Diggy.feature, but needed to create another file to handle the formating of adding market items. Could maybe revert back to the longer format to remove the need for it. (Only possible now because I removed the stone setting from items and made MarketExhange calculate it everytime.)
This commit is contained in:
SimonFlapse 2018-11-13 23:33:39 +01:00
parent e559187d87
commit c87511d0c0
5 changed files with 112 additions and 96 deletions

View File

@ -282,9 +282,9 @@ local Config = {
-- add or remove a table entry to add or remove a unlockable item from the mall.
-- format: {unlock_at_level, price, prototype_name},
unlockables = require('map_gen.Diggy.Feature.MarketUnlockables').initalize_unlockables(
unlockables = require('map_gen.Diggy.FormatMarketItems').initalize_unlockables(
{
{level = 1, price = 50, name = 'raw-fish'}, -- unlocks at level 1, price is 50 and the prototype name for fish is raw-fish.
{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'},
@ -310,6 +310,11 @@ local Config = {
{prototype = {name = 'inventory_slot', value = 1}},
{prototype = {name = 'stone_automation', value = 3}},
},
-- controls the formula for calculating level up costs in stone sent to surface
difficulity_scale = 25, -- Diggy default 25. Higher increases difficulity, lower decreases (Only affects the stone requirement/cost to level up) (Only integers has been tested succesful)
start_stone = 50, -- Diggy default 50. This sets the price for the first level.
cost_precision = 2, -- Diggy default 2. This sets the precision of the stone requirements to level up. E.g. 1234 becomes 1200 with precision 2 and 1230 with precision 3.
},
},
}

View File

@ -11,6 +11,8 @@ local Debug = require 'map_gen.Diggy.Debug'
local Template = require 'map_gen.Diggy.Template'
local Global = require 'utils.global'
local Game = require 'utils.game'
local MarketUnlockables = require 'map_gen.Diggy.MarketUnlockables'
local calculate_level = MarketUnlockables.calculate_level
local insert = table.insert
local max = math.max
@ -120,10 +122,17 @@ local function update_market_contents(market)
local print = game.print
for _, unlockable in pairs(config.unlockables) do
local is_in_range = unlockable.stone > stone_tracker.previous_stone_sent_to_surface and unlockable.stone <= stone_tracker.stone_sent_to_surface
local stone_unlock = calculate_level(unlockable.level)
local is_in_range = stone_unlock > stone_tracker.previous_stone_sent_to_surface and stone_unlock <= stone_tracker.stone_sent_to_surface
if (is_in_range and stone_tracker.current_level == old_level) then
stone_tracker.current_level = stone_tracker.current_level + 1
while (calculate_level(stone_tracker.current_level) < stone_tracker.stone_sent_to_surface) do
if (calculate_level(stone_tracker.current_level+1) < stone_tracker.stone_sent_to_surface) then
stone_tracker.current_level = stone_tracker.current_level + 1
else
break
end
end
end
-- only add the item to the market if it's between the old and new stone range
@ -215,7 +224,7 @@ local function get_data(unlocks, stone, type)
local result = {}
for _, data in pairs(unlocks) do
if data.stone == stone and data.type == type then
if calculate_level(data.level) == stone and data.type == type then
insert(result, data)
end
end
@ -223,24 +232,6 @@ local function get_data(unlocks, stone, type)
return result
end
local function get_stone_level(unlocks, stone)
local count = 1
local ret = {act = 0, next = 0}
for _, data in pairs(unlocks) do
if data.stone > stone then
ret.next = data.stone
break
end
count = count + 1
end
if count < 2 then
ret.act = 0 -- predefine with 0 if nothing sent yet (at beginning)
else
ret.act = unlocks[count - 1].stone
end
return ret
end
local tag_label_stone = Gui.uid_name()
local tag_label_buff = Gui.uid_name()
local tag_label_item = Gui.uid_name()
@ -251,8 +242,9 @@ local function apply_heading_style(style, width)
end
local function redraw_heading(data, header)
local frame = (header == 1) and data.market_list_heading or data.buff_list_heading
local header_caption = (header == 1) and 'Reward Item' or 'Reward Buff'
local head_condition = (header == 1)
local frame = (head_condition) and data.market_list_heading or data.buff_list_heading
local header_caption = (head_condition) and 'Reward Item' or 'Reward Buff'
Gui.clear(frame)
local heading_table = frame.add({type = 'table', column_count = 2})
@ -266,16 +258,15 @@ local function redraw_progressbar(data)
Gui.clear(flow)
-- progress bar for next level
local stone_level = get_stone_level(config.unlockables, stone_tracker.stone_sent_to_surface)
local act_stone = stone_level.act
local next_stone = stone_level.next
local act_stone = (stone_tracker.current_level ~= 0) and calculate_level(stone_tracker.current_level) or 0
local next_stone = calculate_level(stone_tracker.current_level+1)
local range = next_stone - act_stone
local sent = stone_tracker.stone_sent_to_surface - act_stone
local percentage = (math.floor((sent / range)*10^4))/10^4
local percentage = (math.floor((sent / range)*1000))*0.001
percentage = (percentage < 0) and (percentage*-1) or percentage
apply_heading_style(flow.add({type = 'label', tooltip = 'Current at level ' .. stone_tracker.current_level, name = 'Diggy.MarketExchange.Frame.Progress.Level', caption = 'Progress to next level:'}).style)
apply_heading_style(flow.add({type = 'label', tooltip = 'Currently at level: ' .. stone_tracker.current_level .. '\nNext level at: ' .. comma_value(next_stone) ..'\nRemaining stone: ' .. comma_value(range - sent), name = 'Diggy.MarketExchange.Frame.Progress.Level', caption = 'Progress to next level:'}).style)
local level_progressbar = flow.add({type = 'progressbar', tooltip = percentage * 100 .. '% stone to next level'})
level_progressbar.style.width = 350
level_progressbar.value = percentage
@ -299,11 +290,10 @@ local function redraw_table(data)
-- create table
for i = 1, #config.unlockables do
if config.unlockables[i].stone ~= last_stone then
if calculate_level(config.unlockables[i].level) ~= last_stone then
-- get items and buffs for each stone value
buffs = get_data(config.unlockables, config.unlockables[i].stone, 'buff')
items = get_data(config.unlockables, config.unlockables[i].stone, 'market')
items = get_data(config.unlockables, calculate_level(config.unlockables[i].level), 'market')
-- get number of rows
number_of_rows = max(#buffs, #items)
@ -311,13 +301,15 @@ local function redraw_table(data)
-- loop through buffs and items for number of rows
for j = 1, number_of_rows do
local result = {}
local item = items[j]
local level = item.level
-- 1st column
result[6] = items[j].stone
result[1] = 'Level ' ..items[j].level
result[6] = calculate_level(level)
result[1] = 'Level ' ..level
-- 3rd column
if items[j] ~= nil then
result[3] = '+ ' .. items[j].prototype.name
result[3] = '+ ' .. item.prototype.name
else
result[3] = ''
end
@ -339,7 +331,7 @@ local function redraw_table(data)
end
-- save lastStone
last_stone = config.unlockables[i].stone
last_stone = calculate_level(config.unlockables[i].level)
end
-- print table

View File

@ -1,58 +0,0 @@
-- dependencise
-- this
local MarketUnlockables = {}
local marked_prototype_items = {}
local insert = table.insert
local floor = math.floor
local ceil = math.ceil
local log10 = math.log10
function MarketUnlockables.add(self_level, self_price, self_name)
if (not marked_prototype_items[self_level]) then
insert(marked_prototype_items, self_level, {})
end
insert(marked_prototype_items[self_level], {price = self_price, name = self_name})
end
function MarketUnlockables.initalize_unlockables(items)
local levelcost = {}
local unlockables = {}
local prev_number = 0
for i = 1,100 do
local b = 20 -- Default 20 <-- Controls how much stone is needed.
local start_value = 50 -- The start value/the first level cost
local formula = b*(i^3)+(start_value-b)
local precision = 2 -- Sets the precision
--Truncates to the precision and prevents dublicates by incrementing with 5 in the third highest place
local number = formula
local numberlen = floor(log10(number)+1)
precision = (numberlen >= 8) and (precision+1) or precision
number = number/10^(numberlen-precision)
number = floor(number)*10^(numberlen-precision)
while (prev_number >= number) do
number = (prev_number > number) and number or number + ceil(5*10^(numberlen-3))
end
levelcost[i] = number
prev_number = number
end
-- handles the unlockables from Config.lua in map_gen.Diggy
for _, item in pairs(items) do
MarketUnlockables.add(item.level, item.price, item.name)
end
for lvl, v in pairs(marked_prototype_items) do
for _, w in ipairs(v) do
insert(unlockables, {level = lvl, stone = levelcost[lvl], type = 'market', prototype = w})
end
end
return unlockables
end
return MarketUnlockables

View File

@ -0,0 +1,32 @@
-- dependencies
-- this
local FormatMarketItems = {}
local market_prototype_items = {}
local insert = table.insert
function FormatMarketItems.add(self_level, self_price, self_name)
if (not market_prototype_items[self_level]) then
insert(market_prototype_items, self_level, {})
end
insert(market_prototype_items[self_level], {price = self_price, name = self_name})
end
function FormatMarketItems.initalize_unlockables(items)
local unlockables = {}
-- handles the unlockables from Config.lua in map_gen.Diggy
for _, item in ipairs(items) do
FormatMarketItems.add(item.level, item.price, item.name)
end
for lvl, v in pairs(market_prototype_items) do
for _, w in ipairs(v) do
insert(unlockables, {level = lvl, type = 'market', prototype = w})
end
end
return unlockables
end
return FormatMarketItems

View File

@ -0,0 +1,45 @@
-- dependencies
local Config = require 'map_gen.Diggy.config'.features.MarketExchange
-- this
local MarketUnlockables = {}
local marked_prototype_items = {}
local insert = table.insert
local floor = math.floor
local ceil = math.ceil
local log10 = math.log10
local function truncate(precision, formula)
local number = formula
local numberlen = floor(log10(number)+1)
precision = (numberlen >= 8) and (precision+1) or precision
local exponent = numberlen-precision
number = number/10^exponent
number = floor(number)*10^exponent
return number, numberlen
end
function MarketUnlockables.calculate_level(level) -- all configurable variables must be integers.
local b = floor(Config.difficulity_scale) or 25 -- Default 25 <-- Controls how much stone is needed.
local start_value = floor(Config.start_stone) or 50 -- The start value/the first level cost
local formula = b*(level^3)+(start_value-b)
local precision = floor(Config.cost_precision) or 2 -- Sets the precision
-- Truncates to the precision and prevents dublicates by incrementing with 5 in the third highest place.
-- First evaluates loosly if the previous level requirement would return same number after truncating.
-- If true evaluates down all levels to level 1 for the precise number
-- (In case itself got incremented)
-- Only useful if three or more values turns out to be the same after truncating, thus the loosly evaluation to save an expensive recursive function
local number, numberlen = truncate(precision, formula)
local prev_number = truncate(precision, b*((level-1)^3)+(start_value-b))
if (level ~= 1 and number == prev_number) then
local prev_number = MarketUnlockables.calculate_level((level-1))
while (prev_number >= number) do
number = (prev_number < number) and number or ceil(number + (5*10^(numberlen-3)))
end
end
return number
end
return MarketUnlockables