1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-11-27 22:38:18 +02:00

Mtn v3 - adjust goals, buffs

This commit is contained in:
Gerkiz
2023-10-05 22:53:29 +02:00
parent 5620534ad6
commit 3b8ace461a
7 changed files with 186 additions and 263 deletions

View File

@@ -151,12 +151,9 @@ rocks_mined=[font=default-bold]Rocks mined: [/font]
trees_mined=[font=default-bold]Trees mined: [/font]
production=[font=default-bold]Produce the following items: [/font]
production_single=[font=default-bold]Produce the following item: [/font]
market_spent=[font=default-bold]Spend coins in market: [/font]
research=[font=default-bold]Research __1__: [/font]
locomotive_market_pickaxe=[font=default-bold]Pickaxe upgrades from market: [/font]
locomotive_market_health=[font=default-bold]Health upgrades from market: [/font]
locomotive_market_xp_points=[font=default-bold]XP points from market: [/font]
rounds_survived_tooltip=Winning the game increases this number by 1.\nThis number resets as of now each month.
buff_tooltip=Each buff that is given to the players is listed here.\nHover over the icon to the right to view the buffs.
zone_tooltip=Complete this objective by breaching/moving forward until you've reached the given zone.
@@ -164,7 +161,6 @@ wave_tooltip=Complete this objective by surviving until the given wave.
linked_tooltip=Complete this objective by converting the given amount of chests to linked chests.
linked_static_tooltip=Complete this objective by purchasing the given amount of linked chests.
production_tooltip=Complete this objective by producing the given item(s).
locomotive_tooltip=Complete this objective by purchasing the following item X times.
time_until_attack_tooltip=Time in either minutes or seconds until the biters attack.
generic_tooltip=Complete this and this objective will be marked as complete.
win_conditions_tooltip=In order to win the game, you must complete all these objectives that are listed below! [img=utility/force_editor_icon]
@@ -195,3 +191,4 @@ warp=[font=default-bold]Time until boss arena: [/font]
reset=[color=blue]Mapkeeper:[/color] Reset date has been reached. The buffs and rounds survived has been reset!
reset_discord=Reset date has been reached. The buffs and rounds survived has been reset!
warn_biters_boosted=Attention! Biters have been increased in health and damage over __1__ times. They grant more XP but are harder to kill!

View File

@@ -194,6 +194,9 @@ end
local function do_place_treasure(data)
local surface = data.surface
if not surface or not surface.valid then
return
end
local treasure = data.treasure
if #treasure == 0 then
@@ -211,6 +214,9 @@ end
local function do_place_markets(data)
local markets = data.markets
local surface = data.surface
if not surface or not surface.valid then
return
end
if #markets == 0 then
return
@@ -231,16 +237,25 @@ end
local function do_place_tiles(data)
local surface = data.surface
if not surface or not surface.valid then
return
end
surface.set_tiles(data.tiles, true)
end
local function do_place_hidden_tiles(data)
local surface = data.surface
if not surface or not surface.valid then
return
end
surface.set_tiles(data.hidden_tiles, true)
end
local function do_place_decoratives(data)
local surface = data.surface
if not surface or not surface.valid then
return
end
if regen_decoratives then
surface.regenerate_decorative(nil, {{data.top_x / 32, data.top_y / 32}})
end
@@ -253,6 +268,9 @@ end
local function do_place_buildings(data)
local surface = data.surface
if not surface or not surface.valid then
return
end
local entity
local callback
for _, e in ipairs(data.buildings) do
@@ -334,6 +352,9 @@ end
local function do_place_entities(data)
local surface = data.surface
if not surface or not surface.valid then
return
end
local entity
local callback
for _, e in ipairs(data.entities) do

View File

@@ -291,6 +291,7 @@ function Public.reset_map()
Public.stateful.enable(true)
Public.stateful.create()
Public.stateful.reset_stateful()
Public.stateful.increase_enemy_damage_and_health()
Public.stateful.apply_startup_settings()
if _DEV_MODE then

View File

@@ -288,28 +288,6 @@ local function objective_frames(stateful, player_frame, objective, data)
return
end
if objective_name == 'locomotive_market_selection' then
local callback_token = stateful.objectives.locomotive_market_selection[1]
local callback_data = stateful.objectives.locomotive_market_selection[2]
local callback = Token.get(callback_token)
local _, locale_left, locale_right, tooltip = callback(callback_data)
local tbl = player_frame.add {type = 'table', column_count = 2}
tbl.style.horizontally_stretchable = true
local left_flow = tbl.add({type = 'flow'})
left_flow.style.horizontal_align = 'left'
left_flow.style.horizontally_stretchable = true
left_flow.add({type = 'label', caption = locale_left, tooltip = {'stateful.locomotive_tooltip'}})
local right_flow = tbl.add({type = 'flow'})
right_flow.style.horizontal_align = 'right'
right_flow.style.horizontally_stretchable = true
local locomotive_market = right_flow.add({type = 'label', caption = locale_right, tooltip = tooltip})
data.locomotive_market = locomotive_market
return
end
local callback = Token.get(objective.token)
local _, objective_locale_left, objective_locale_right, tooltip_left, tooltip_right = callback()
@@ -618,28 +596,6 @@ main_frame = function(player)
data.randomized_wave_label = wave_right_flow.add({type = 'label', caption = wave_number .. '/' .. stateful.objectives.randomized_wave .. ' [img=utility/not_available]', tooltip = {'stateful.tooltip_not_completed'}})
end
-- new frame
local linked_left_flow = objective_tbl.add({type = 'flow'})
linked_left_flow.style.horizontal_align = 'left'
linked_left_flow.style.horizontally_stretchable = true
local convert_enabled = LinkedChests.get('convert_enabled')
if convert_enabled then
linked_left_flow.add({type = 'label', caption = {'stateful.linked'}, tooltip = {'stateful.linked_tooltip'}})
else
linked_left_flow.add({type = 'label', caption = {'stateful.linked_static'}, tooltip = {'stateful.linked_static_tooltip'}})
end
frame.add({type = 'line', direction = 'vertical'})
local linked_right_flow = objective_tbl.add({type = 'flow'})
linked_right_flow.style.horizontal_align = 'right'
linked_right_flow.style.horizontally_stretchable = true
if converted_chests >= stateful.objectives.randomized_linked_chests then
data.randomized_linked_label = linked_right_flow.add({type = 'label', caption = converted_chests .. '/' .. stateful.objectives.randomized_linked_chests .. ' [img=utility/check_mark_green]', tooltip = {'stateful.tooltip_completed'}})
else
data.randomized_linked_label = linked_right_flow.add({type = 'label', caption = converted_chests .. '/' .. stateful.objectives.randomized_linked_chests .. ' [img=utility/not_available]', tooltip = {'stateful.tooltip_not_completed'}})
end
--dynamic conditions
data.random_objectives = {}
@@ -710,15 +666,6 @@ local function update_data()
end
end
if data.randomized_linked_label and data.randomized_linked_label.valid and stateful.objectives.randomized_linked_chests then
if converted_chests >= stateful.objectives.randomized_linked_chests then
data.randomized_linked_label.caption = converted_chests .. '/' .. stateful.objectives.randomized_linked_chests .. ' [img=utility/check_mark_green]'
data.randomized_linked_label.tooltip = {'stateful.tooltip_completed'}
else
data.randomized_linked_label.caption = converted_chests .. '/' .. stateful.objectives.randomized_linked_chests .. ' [img=utility/not_available]'
end
end
if data.supply and next(data.supply) then
local items_done = 0
local supplies = stateful.objectives.supplies
@@ -778,16 +725,6 @@ local function update_data()
end
end
if data.locomotive_market and data.locomotive_market.valid then
if stateful.objectives.locomotive_market_selection then
local callback_token = stateful.objectives.locomotive_market_selection[1]
local callback_data = stateful.objectives.locomotive_market_selection[2]
local callback_locomotive = Token.get(callback_token)
local _, _, locale_right = callback_locomotive(callback_data)
data.locomotive_market.caption = locale_right
end
end
if stateful.collection.gather_time and data.gather_time_label and data.gather_time_label.valid then
local time_left = floor(stateful.collection.gather_time / 60 / 60) .. 'm'
@@ -890,17 +827,6 @@ local function update_raw()
end
end
if stateful.objectives.randomized_linked_chests then
if converted_chests >= stateful.objectives.randomized_linked_chests then
if not stateful.objectives_completed.randomized_linked_chests then
stateful.objectives_completed.randomized_linked_chests = true
play_achievement_unlocked()
Server.to_discord_embed('Objective: **convert chests** has been complete!')
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
end
end
end
if stateful.objectives.supplies and next(stateful.objectives.supplies) then
local items_done = 0
for index = 1, #stateful.objectives.supplies do
@@ -1006,21 +932,6 @@ local function update_raw()
end
end
if stateful.objectives.locomotive_market_selection then
local callback_token = stateful.objectives.locomotive_market_selection[1]
local callback_data = stateful.objectives.locomotive_market_selection[2]
local callback_locomotive = Token.get(callback_token)
local locomotive_completed, _, _ = callback_locomotive(callback_data)
if locomotive_completed then
if not stateful.objectives_completed.locomotive_market then
stateful.objectives_completed.locomotive_market = true
Server.to_discord_embed('Objective: **locomotive purchase** has been completed!')
play_achievement_unlocked()
stateful.objectives_completed_count = stateful.objectives_completed_count + 1
end
end
end
for objective_index = 1, #stateful.selected_objectives do
local objective = stateful.selected_objectives[objective_index]
local objective_name = objective.name
@@ -1034,7 +945,7 @@ local function update_raw()
end
end
if stateful.objectives_completed_count == 6 and not stateful.objectives_completed.boss_time then
if stateful.objectives_completed_count == stateful.tasks_required_to_win and not stateful.objectives_completed.boss_time then
stateful.objectives_completed.boss_time = true
Server.to_discord_embed('All objectives has been completed!')

View File

@@ -1,5 +1,6 @@
local Global = require 'utils.global'
local Event = require 'utils.event'
local Utils = require 'utils.utils'
local Server = require 'utils.server'
local Token = require 'utils.token'
local shuffle = table.shuffle_table
@@ -25,9 +26,11 @@ local this = {
}
local random = math.random
local round = math.round
local floor = math.floor
local dataset = 'scenario_settings'
local dataset_key = 'mtn_v3'
local dataset_key_dev = 'mtn_v3_dev'
Global.register(
this,
@@ -74,6 +77,7 @@ local buff_to_string = {
['mining_drill_productivity_bonus'] = 'Mining drill speed',
['character_health_bonus'] = 'Character health',
['character_reach_distance_bonus'] = 'Reach',
['distance'] = 'All distance modifiers',
['manual_crafting_speed_modifier'] = 'Crafting',
['xp_bonus'] = 'XP Bonus',
['xp_level'] = 'XP Level'
@@ -91,21 +95,6 @@ local function get_random_buff()
modifier = 'force',
state = 0.05
},
{
name = 'character_resource_reach_distance_bonus',
modifier = 'force',
state = 0.05
},
{
name = 'character_item_pickup_distance_bonus',
modifier = 'force',
state = 0.05
},
{
name = 'character_loot_pickup_distance_bonus',
modifier = 'force',
state = 0.05
},
{
name = 'laboratory_speed_modifier',
modifier = 'force',
@@ -142,9 +131,10 @@ local function get_random_buff()
state = 50
},
{
name = 'character_reach_distance_bonus',
modifier = 'force',
state = 1
name = 'distance',
modifier = 'rpg_distance',
modifiers = {'character_resource_reach_distance_bonus', 'character_item_pickup_distance_bonus', 'character_loot_pickup_distance_bonus', 'character_reach_distance_bonus'},
state = 0.05
},
{
name = 'manual_crafting_speed_modifier',
@@ -159,7 +149,7 @@ local function get_random_buff()
{
name = 'xp_level',
modifier = 'rpg',
state = 1
state = 4
},
{
name = 'starting_items',
@@ -331,42 +321,6 @@ local function on_pre_player_died(event)
Task.set_timeout_in_ticks(5, search_corpse_token, {player_index = player.index})
end
local locomotive_market_pickaxe_token =
Token.register(
function(count)
local upgrades = Public.get('upgrades')
if upgrades.pickaxe_tier >= count then
return true, {'stateful.locomotive_market_pickaxe'}, {'stateful.done', count, count}, {'stateful.tooltip_completed'}
end
return false, {'stateful.locomotive_market_pickaxe'}, {'stateful.not_done', upgrades.pickaxe_tier, count}, {'stateful.tooltip_not_completed'}
end
)
local locomotive_market_health_token =
Token.register(
function(count)
local upgrades = Public.get('upgrades')
if upgrades.health_upgrades >= count then
return true, {'stateful.locomotive_market_health'}, {'stateful.done', count, count}, {'stateful.tooltip_completed'}
end
return false, {'stateful.locomotive_market_health'}, {'stateful.not_done', upgrades.health_upgrades, count}, {'stateful.tooltip_not_completed'}
end
)
local locomotive_market_xp_points_token =
Token.register(
function(count)
local upgrades = Public.get('upgrades')
if upgrades.xp_points_upgrade >= count then
return true, {'stateful.locomotive_market_xp_points'}, {'stateful.done', count, count}, {'stateful.tooltip_completed'}
end
return false, {'stateful.locomotive_market_xp_points'}, {'stateful.not_done', upgrades.xp_points_upgrade, count}, {'stateful.tooltip_not_completed'}
end
)
local empty_token =
Token.register(
function()
@@ -386,17 +340,6 @@ local killed_enemies_token =
end
)
local complete_mystical_chest_amount_token =
Token.register(
function()
local mystical_chest_completed = Public.get('mystical_chest_completed')
if mystical_chest_completed >= this.objectives.complete_mystical_chest_amount then
return true, {'stateful.mystical_chest'}, {'stateful.done', this.objectives.complete_mystical_chest_amount, this.objectives.complete_mystical_chest_amount}, {'stateful.generic_tooltip'}, {'stateful.tooltip_completed'}
end
return false, {'stateful.mystical_chest'}, {'stateful.not_done', mystical_chest_completed, this.objectives.complete_mystical_chest_amount}, {'stateful.generic_tooltip'}, {'stateful.tooltip_not_completed'}
end
)
local research_level_selection_token =
Token.register(
function()
@@ -409,6 +352,19 @@ local research_level_selection_token =
end
)
local locomotive_market_coins_spent_token =
Token.register(
function()
local coins = this.objectives.locomotive_market_coins_spent
local actual = coins.spent
local expected = coins.required
if actual >= expected then
return true, {'stateful.market_spent'}, {'stateful.done', format_number(expected, true), format_number(expected, true)}, {'stateful.generic_tooltip'}, {'stateful.tooltip_completed'}
end
return false, {'stateful.market_spent'}, {'stateful.not_done', format_number(actual, true), format_number(expected, true)}, {'stateful.generic_tooltip'}, {'stateful.tooltip_not_completed'}
end
)
local trees_farmed_token =
Token.register(
function()
@@ -448,7 +404,9 @@ local function scale(setting, limit, factor)
if limit and scale_value >= limit then
return limit
end
return scale_value
local random_value = scale_value * 0.9
scale_value = random(random_value, scale_value)
return floor(scale_value)
end
local function get_random_items()
@@ -524,51 +482,7 @@ local function get_random_research_recipe()
return {name = research_level_list[1], count = 1}
end
return {name = research_level_list[1], count = scale(2, 40)}
end
local function get_random_locomotive_tier()
local tiers = {
'pickaxe',
'health',
'xp_point'
}
shuffle(tiers)
shuffle(tiers)
shuffle(tiers)
shuffle(tiers)
local pickaxe_count = scale(5, 59)
local health_count = scale(5, 100)
local xp_points_count = scale(5, 100)
if this.test_mode then
pickaxe_count = 1
health_count = 1
xp_points_count = 1
end
if tiers[1] == 'pickaxe' then
return {
locomotive_market_pickaxe_token,
pickaxe_count
}
end
if tiers[1] == 'health' then
return {
locomotive_market_health_token,
health_count
}
end
if tiers[1] == 'xp_point' then
return {
locomotive_market_xp_points_token,
xp_points_count
}
end
return {name = research_level_list[1], count = scale(2, 40, 1.08)}
end
local function get_random_objectives()
@@ -585,17 +499,13 @@ local function get_random_objectives()
name = 'killed_enemies',
token = killed_enemies_token
},
{
name = 'complete_mystical_chest_amount',
token = complete_mystical_chest_amount_token
},
{
name = 'research_level_selection',
token = research_level_selection_token
},
{
name = 'locomotive_market_selection',
token = empty_token
name = 'locomotive_market_coins_spent',
token = locomotive_market_coins_spent_token
},
{
name = 'trees_farmed',
@@ -629,6 +539,17 @@ local function apply_buffs(starting_items)
local force = game.forces.player
for _, buff in pairs(this.buffs) do
if buff then
if buff.modifier == 'rpg_distance' then
for _, buff_name in pairs(buff.modifiers) do
force[buff_name] = force[buff_name] + buff.state
if not this.buffs_collected[buff_name] then
this.buffs_collected[buff_name] = buff.state
else
this.buffs_collected[buff_name] = this.buffs_collected[buff_name] + buff.state
end
end
end
if buff.modifier == 'force' then
force[buff.name] = force[buff.name] + buff.state
@@ -694,32 +615,47 @@ local function apply_buffs(starting_items)
end
local function apply_startup_settings(settings)
local new_value = Server.get_current_date()
if not new_value then
local current_date = Server.get_current_date(false, true)
if not current_date then
return
end
local current_time = Server.get_current_time()
if not current_time then
return
end
current_date = round(Utils.convert_date(current_date.year, current_date.month, current_date.day))
local server_name_matches = Server.check_server_name('Mtn Fortress')
settings = settings or {}
local old_value = this.current_date
if old_value then
old_value = tonumber(old_value)
local time_to_reset = (new_value - old_value)
if time_to_reset then
if time_to_reset > this.reset_after then
settings.current_date = tonumber(new_value)
local stored_date = this.current_date
if not stored_date then
return
end
local stored_date_raw = Server.get_current_date(false, true, stored_date)
local converted_stored_date = round(Utils.convert_date(stored_date_raw.year, stored_date_raw.month, stored_date_raw.day))
local time_to_reset = (current_date - converted_stored_date)
if time_to_reset and time_to_reset > this.reset_after then
settings.current_date = current_time
settings.test_mode = false
settings.rounds_survived = 0
settings.buffs = {}
this.buffs = {}
this.buffs_collected = {}
this.rounds_survived = 0
this.current_date = tonumber(new_value)
this.current_date = current_time
local message = ({'stateful.reset'})
local message_discord = ({'stateful.reset_discord'})
game.print(message)
Server.to_discord_embed(message_discord, true)
if server_name_matches then
Server.set_data(dataset, dataset_key, settings)
end
else
Server.set_data(dataset, dataset_key_dev, settings)
end
end
@@ -732,18 +668,23 @@ end
local apply_settings_token =
Token.register(
function(data)
local server_name_matches = Server.check_server_name('Mtn Fortress')
local settings = data and data.value or nil
local new_value = Server.get_current_date()
if not new_value then
local current_time = Server.get_current_time()
if not current_time then
return
end
if not settings then
settings = {
rounds_survived = 0,
current_date = tonumber(new_value)
current_date = tonumber(current_time)
}
if server_name_matches then
Server.set_data(dataset, dataset_key, settings)
else
Server.set_data(dataset, dataset_key_dev, settings)
end
return
end
@@ -755,10 +696,6 @@ local apply_settings_token =
settings = apply_startup_settings(settings)
this.rounds_survived = settings.rounds_survived
Public.increase_enemy_damage_and_health()
Server.set_data(dataset, dataset_key, settings)
end
)
@@ -771,7 +708,12 @@ function Public.save_settings()
buffs = this.buffs
}
local server_name_matches = Server.check_server_name('Mtn Fortress')
if server_name_matches then
Server.set_data(dataset, dataset_key, settings)
else
Server.set_data(dataset, dataset_key_dev, settings)
end
end
function Public.reset_stateful(refresh_gui)
@@ -780,39 +722,41 @@ function Public.reset_stateful(refresh_gui)
this.objectives_completed_count = 0
this.final_battle = false
this.buffs_collected = {}
this.enemies_boosted = false
this.tasks_required_to_win = 5
this.selected_objectives = get_random_objectives()
if this.test_mode then
this.objectives = {
randomized_zone = 2,
randomized_wave = 2,
randomized_linked_chests = 2,
supplies = get_random_items(),
single_item = get_random_item(),
killed_enemies = 10,
complete_mystical_chest_amount = 1,
research_level_selection = get_random_research_recipe(),
research_level_count = 0,
locomotive_market_selection = get_random_locomotive_tier(),
locomotive_market_coins_spent = 0,
locomotive_market_coins_spent_required = 1,
trees_farmed = 10,
rocks_farmed = 10,
rockets_launched = 1
}
else
this.objectives = {
randomized_zone = scale(5, 30, 1.2),
randomized_wave = scale(300, 2000),
randomized_linked_chests = scale(2, 20),
randomized_zone = random(scale(4, 30, 1.08), scale(5, 30, 1.1)),
randomized_wave = random(scale(180, 1000), scale(200, 1000)),
supplies = get_random_items(),
single_item = get_random_item(),
killed_enemies = scale(125000, 10000000),
complete_mystical_chest_amount = scale(3, 20),
killed_enemies = random(scale(80000, 10000000), scale(100000, 10000000)),
research_level_selection = get_random_research_recipe(),
research_level_count = 0,
locomotive_market_selection = get_random_locomotive_tier(),
trees_farmed = scale(10000, 400000),
rocks_farmed = scale(50000, 4000000),
rockets_launched = scale(40, 700)
locomotive_market_coins_spent = {
spent = 0,
required = random(scale(10000, 400000), scale(15000, 400000))
},
trees_farmed = random(scale(9500, 400000), scale(10500, 400000)),
rocks_farmed = random(scale(45000, 4000000), scale(55000, 4000000)),
rockets_launched = random(scale(30, 700), scale(45, 700))
}
end
this.collection = {
@@ -828,7 +772,6 @@ function Public.reset_stateful(refresh_gui)
local t = {
['randomized_zone'] = this.objectives.randomized_zone,
['randomized_wave'] = this.objectives.randomized_wave,
['randomized_linked_chests'] = this.objectives.randomized_linked_chests,
['research_level_count'] = this.objectives.research_level_count
}
for index = 1, #this.selected_objectives do
@@ -978,15 +921,30 @@ function Public.set_target(target, icw_data)
end
function Public.increase_enemy_damage_and_health()
if this.enemies_boosted then
return
end
this.enemies_boosted = true
if this.rounds_survived == 1 then
Event.raise(WD.events.on_biters_evolved, {force = game.forces.enemy})
Event.raise(WD.events.on_biters_evolved, {force = game.forces.aggressors})
Event.raise(WD.events.on_biters_evolved, {force = game.forces.aggressors_frenzy})
else
for _ = 1, this.rounds_survived do
Event.raise(WD.events.on_biters_evolved, {force = game.forces.enemy})
Event.raise(WD.events.on_biters_evolved, {force = game.forces.aggressors})
Event.raise(WD.events.on_biters_evolved, {force = game.forces.aggressors_frenzy})
end
end
if this.rounds_survived == 0 then
return
end
local message_discord = ({'stateful.warn_biters_boosted', this.rounds_survived})
Server.to_discord_embed(message_discord, true)
end
function Public.get_stateful(key)
@@ -1033,9 +991,16 @@ Event.add(
return
end
local server_name_matches = Server.check_server_name('Mtn Fortress')
this.settings_applied = true
if server_name_matches then
Server.try_get_data(dataset, dataset_key, apply_settings_token)
else
Server.try_get_data(dataset, dataset_key_dev, apply_settings_token)
this.test_mode = true
end
end
)

View File

@@ -1323,9 +1323,11 @@ end
-- Returns the current date.
-- @param pretty<boolean>
-- @return date?
function Public.get_current_date(pretty)
local s = Public.get_current_time()
-- @param as_table<boolean>
-- @param current_time<number>
-- @return date|tuple?
function Public.get_current_date(pretty, as_table, current_time)
local s = current_time or Public.get_current_time()
if not s then
return false
end
@@ -1335,7 +1337,9 @@ function Public.get_current_date(pretty)
return
end
if pretty then
if as_table then
return {year = date.year, month = date.month, day = date.day}
elseif pretty then
return tonumber(date.year .. '-' .. date.month .. '-' .. date.day)
else
return tonumber(date.year .. date.month .. date.day)

View File

@@ -117,6 +117,30 @@ Module.format_time = function(ticks)
return table.concat(result, ' ')
end
-- Convert date from 1999/01/01
Module.convert_date = function(year, month, day)
year = tonumber(year)
month = tonumber(month)
day = tonumber(day)
local function sub(n, d)
local a, b = 1, 1
if n < 0 then
a = -1
end
if d < 0 then
b = -1
end
return a * b * (math.abs(n) / math.abs(d))
end
local d
if (year < 0) or (month < 1) or (month > 12) or (day < 1) or (day > 31) then
return
end
d = sub(month - 14, 12)
return (day - 32075 + sub(1461 * (year + 4800 + d), 4) + sub(367 * (month - 2 - d * 12), 12) - sub(3 * sub(year + 4900 + d, 100), 4)) - 2415021
end
--- Compares positions
---@param position table
---@param area table