Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The GUI lies about volcanus overclocks (update: it does not) #39

Merged
merged 10 commits into from
Sep 20, 2024
22 changes: 17 additions & 5 deletions src/gtnh/overclocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def modifyGTpp(self, recipe, MAX_PARALLEL=None, eut_discount=None):
# Attempt to GT OC the entire parallel set until no energy is left
while TOTAL_EUT < available_eut:
OC_EUT = TOTAL_EUT * 4
OC_DUR = NEW_RECIPE_TIME / 2
OC_DUR = NEW_RECIPE_TIME / 2
if OC_EUT <= available_eut:
if OC_DUR < 1:
break
Expand Down Expand Up @@ -218,7 +218,7 @@ def modifyTGS(self, recipe):
return recipe


def modifyUtupu(self, recipe):
def modifyUtupu(self, recipe, override_max_parallel = None):
require(
recipe,
[
Expand All @@ -237,8 +237,8 @@ def modifyUtupu(self, recipe):

# Calculate base parallel count and clip time to 1 tick
available_eut = self.voltage_cutoffs[self.voltages.index(recipe.user_voltage)]
MAX_PARALLEL = (self.voltages.index(recipe.user_voltage) + 1) * PARALLELS_PER_TIER
NEW_RECIPE_TIME = max(recipe.dur * SPEED_BOOST, 1)
MAX_PARALLEL = override_max_parallel if override_max_parallel else ((self.voltages.index(recipe.user_voltage) + 1) * PARALLELS_PER_TIER)
NEW_RECIPE_TIME = max(recipe.dur * SPEED_BOOST, 1/20)

# Calculate current EU/t spend
x = recipe.eut * EU_DISCOUNT
Expand All @@ -263,9 +263,20 @@ def modifyUtupu(self, recipe):
recipe.dur = NEW_RECIPE_TIME / 2**oc_count / 2**max(min(perfect_ocs, oc_count), 0)
recipe.I *= y
recipe.O *= y
recipe.parallel = y

return recipe


# Volcanus is like a combo of EBF and GTpp math, however:
# gtpp-style bonuses to speed, eut are applied *before* parallels are calculated
# there there are 8 parallels *maximum*, not per-tier (some other gtpp machines are like this)
# ebf bonuses to power, perfect OCs apply *after* parallels are calculated
# no heat-per-tier bonuses
# This makes it match Utupu, except for the parallel maximum
def modifyVolcanus(self, recipe):
SPEED_BOOST, EU_DISCOUNT, MAX_PARALLEL = self.overclock_data['GTpp_stats'][recipe.machine]
return self.modifyUtupu(recipe, MAX_PARALLEL)


def modifyFusion(self, recipe):
# Ignore "tier" and just use "mk" argument for OCs
Expand Down Expand Up @@ -470,6 +481,7 @@ def getOverclockFunction(self, recipe):
'industrial dehydrator': self.modifyUtupu,
'flotation cell regulator': self.modifyPerfect,
'isamill grinding machine': self.modifyPerfect,
"volcanus": self.modifyVolcanus,
"digester": self.modifyPerfect,
}

Expand Down
93 changes: 93 additions & 0 deletions tests/test_overclocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,99 @@ def test_EBFOverclock(recipe, expected_eut, expected_dur, overclock_handler):
overclocked = overclock_handler.overclockRecipe(recipe)
assert overclocked.eut == expected_eut
assert overclocked.dur == expected_dur


recipe_volcanus = mod_recipe(recipe_ebf, machine="volcanus")
recipe_samarium = Recipe(
"volcanus",
"ev",
IngCol(
Ing("Dephosphated Samarium Concentrate Dust", 1),
),
IngCol(
Ing("Samarium Oxide Dust", 1),
Ing("Gangue Dust", 1),
),
514,
2,
coils="HSS-G",
heat=1200,
)

# Based on in-game measurements
@pytest.mark.parametrize(
"recipe,expected_eut,expected_dur,expected_parallel",
[
(
# No Overclocks (800K over recipe - no bonuses)
mod_recipe(recipe_volcanus, user_voltage="mv", coils="cupronickel"), # 1801K
120 * 0.9,
25 / 2.2,
1,
),
(
# No Overclocks (1700K over recipe - one 5% heat bonus)
mod_recipe(recipe_volcanus, user_voltage="mv", coils="kanthal"), # 2701K
120 * 0.9 * 0.95,
25 / 2.2,
1,
),
# 4x voltage for volcanus is 4x parallels
(
mod_recipe(recipe_volcanus, user_voltage="hv", coils="cupronickel"), # 1801K
120 * 4 * 0.9,
25 / 2.2,
4,
),
# EBF heat bonuses are applied after parallels are calculated (so still only 4 parallels)
(
mod_recipe(recipe_volcanus, user_voltage="hv", coils="HSS-G"), # 5401K
Copy link

@joegnis joegnis Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"HSS-G" should be lowercase since mod_recipe directly modifies value without taking care of cases. Right now, the cases are handled by Recipe's __init__ which is skipped when we use mod_recipe. I should've made it handle cases better.

120 * 4 * 0.9 * 0.95**4,
25 / 2.2,
4
),
# EV is enough for 16x parallels but capped to 8x. Not enough for overclock.
(
mod_recipe(recipe_volcanus, user_voltage="ev", coils="cupronickel"), # 1801K
120 * 8 * 0.9,
25 / 2.2,
8,
),
# IV is enough for 8 parallels and 1 normal overclock.
(
mod_recipe(recipe_volcanus, user_voltage="iv", coils="cupronickel"), # 1801K
120 * 8 * 4 * 0.9,
25 / 2.2 / 2,
8,
),
# 8 Parallel, 1 perfect oc (two 5% heat eut bonuses)
(
mod_recipe(recipe_volcanus, user_voltage="iv", coils="nichrome"), # 3601K
120 * 8 * 4 * 0.9 * 0.95**2,
25 / 2.2 / 4,
8,
),
# 8 Parallel, 1 perfect oc, 1 normal oc (two 5% heat eut bonuses)
(
mod_recipe(recipe_volcanus, user_voltage="luv", coils="nichrome"), # 3601K
120 * 8 * 4 * 4 * 0.9 * 0.95**2,
25 / 2.2 / 4 / 2,
8,
),
# Recipe shows gtpp eut discount applied before parallels (would be 3 parallels otherwise)
(
recipe_samarium, # 3601K
514 * 4 * 0.9 * 0.95**4,
2 / 2.2,
4,
),
],
)
def test_volcanusOverclock(recipe, expected_eut, expected_dur, expected_parallel, overclock_handler):
overclocked = overclock_handler.overclockRecipe(recipe)
assert overclocked.eut == expected_eut
assert overclocked.dur == expected_dur
assert overclocked.parallel == expected_parallel


recipe_pyrolyse_oven = Recipe(
Expand Down