SoE: update to v0.46.1
* install via pypi, pin hashes * add OoB logic option * add sequence break logic option * fix turd ball texts * add option to fix OoB * better textbox handling when turning in energy core fragments
This commit is contained in:
parent
58642edc17
commit
e87d5d5ac2
|
@ -3,7 +3,7 @@ from typing import Protocol, Set
|
|||
from BaseClasses import MultiWorld
|
||||
from worlds.AutoWorld import LogicMixin
|
||||
from . import pyevermizer
|
||||
from .Options import EnergyCore
|
||||
from .Options import EnergyCore, OutOfBounds, SequenceBreaks
|
||||
|
||||
# TODO: Options may preset certain progress steps (i.e. P_ROCK_SKIP), set in generate_early?
|
||||
|
||||
|
@ -61,4 +61,10 @@ class SecretOfEvermoreLogic(LogicMixin):
|
|||
if w.energy_core == EnergyCore.option_fragments:
|
||||
progress = pyevermizer.P_CORE_FRAGMENT
|
||||
count = w.required_fragments
|
||||
elif progress == pyevermizer.P_ALLOW_OOB:
|
||||
if world.worlds[player].out_of_bounds == OutOfBounds.option_logic:
|
||||
return True
|
||||
elif progress == pyevermizer.P_ALLOW_SEQUENCE_BREAKS:
|
||||
if world.worlds[player].sequence_breaks == SequenceBreaks.option_logic:
|
||||
return True
|
||||
return self._soe_count(progress, world, player, count) >= count
|
||||
|
|
|
@ -38,6 +38,12 @@ class OffOnFullChoice(Choice):
|
|||
alias_chaos = 2
|
||||
|
||||
|
||||
class OffOnLogicChoice(Choice):
|
||||
option_off = 0
|
||||
option_on = 1
|
||||
option_logic = 2
|
||||
|
||||
|
||||
# actual options
|
||||
class Difficulty(EvermizerFlags, Choice):
|
||||
"""Changes relative spell cost and stuff"""
|
||||
|
@ -93,10 +99,18 @@ class ExpModifier(Range):
|
|||
default = 200
|
||||
|
||||
|
||||
class FixSequence(EvermizerFlag, DefaultOnToggle):
|
||||
"""Fix some sequence breaks"""
|
||||
display_name = "Fix Sequence"
|
||||
flag = '1'
|
||||
class SequenceBreaks(EvermizerFlags, OffOnLogicChoice):
|
||||
"""Disable, enable some sequence breaks or put them in logic"""
|
||||
display_name = "Sequence Breaks"
|
||||
default = 0
|
||||
flags = ['', 'j', 'J']
|
||||
|
||||
|
||||
class OutOfBounds(EvermizerFlags, OffOnLogicChoice):
|
||||
"""Disable, enable the out-of-bounds glitch or put it in logic"""
|
||||
display_name = "Out Of Bounds"
|
||||
default = 0
|
||||
flags = ['', 'u', 'U']
|
||||
|
||||
|
||||
class FixCheats(EvermizerFlag, DefaultOnToggle):
|
||||
|
@ -240,7 +254,8 @@ soe_options: typing.Dict[str, AssembleOptions] = {
|
|||
"available_fragments": AvailableFragments,
|
||||
"money_modifier": MoneyModifier,
|
||||
"exp_modifier": ExpModifier,
|
||||
"fix_sequence": FixSequence,
|
||||
"sequence_breaks": SequenceBreaks,
|
||||
"out_of_bounds": OutOfBounds,
|
||||
"fix_cheats": FixCheats,
|
||||
"fix_infinite_ammo": FixInfiniteAmmo,
|
||||
"fix_atlas_glitch": FixAtlasGlitch,
|
||||
|
|
|
@ -10,12 +10,8 @@ from worlds.generic.Rules import add_item_rule, set_rule
|
|||
from BaseClasses import Entrance, Item, ItemClassification, Location, LocationProgressType, Region, Tutorial
|
||||
from Utils import output_path
|
||||
|
||||
try:
|
||||
import pyevermizer # from package
|
||||
except ImportError:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
from . import pyevermizer # as part of the source tree
|
||||
import pyevermizer # from package
|
||||
# from . import pyevermizer # as part of the source tree
|
||||
|
||||
from . import Logic # load logic mixin
|
||||
from .Options import soe_options, Difficulty, EnergyCore, RequiredFragments, AvailableFragments
|
||||
|
@ -179,6 +175,8 @@ class SoEWorld(World):
|
|||
evermizer_seed: int
|
||||
connect_name: str
|
||||
energy_core: int
|
||||
sequence_breaks: int
|
||||
out_of_bounds: int
|
||||
available_fragments: int
|
||||
required_fragments: int
|
||||
|
||||
|
@ -191,6 +189,8 @@ class SoEWorld(World):
|
|||
def generate_early(self) -> None:
|
||||
# store option values that change logic
|
||||
self.energy_core = self.multiworld.energy_core[self.player].value
|
||||
self.sequence_breaks = self.multiworld.sequence_breaks[self.player].value
|
||||
self.out_of_bounds = self.multiworld.out_of_bounds[self.player].value
|
||||
self.required_fragments = self.multiworld.required_fragments[self.player].value
|
||||
if self.required_fragments > self.multiworld.available_fragments[self.player].value:
|
||||
self.multiworld.available_fragments[self.player].value = self.required_fragments
|
||||
|
|
|
@ -1,18 +1,36 @@
|
|||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp38-cp38-win_amd64.whl#0.44.0 ; sys_platform == 'win32' and platform_machine == 'AMD64' and python_version == '3.8'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp39-cp39-win_amd64.whl#0.44.0 ; sys_platform == 'win32' and platform_machine == 'AMD64' and python_version == '3.9'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp310-cp310-win_amd64.whl#0.44.0 ; sys_platform == 'win32' and platform_machine == 'AMD64' and python_version == '3.10'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp311-cp311-win_amd64.whl#0.44.0 ; sys_platform == 'win32' and platform_machine == 'AMD64' and python_version == '3.11'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#0.44.0 ; sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.8'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#0.44.0 ; sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.9'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#0.44.0 ; sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.10'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl#0.44.0 ; sys_platform == 'linux' and platform_machine == 'x86_64' and python_version == '3.11'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#0.44.0 ; sys_platform == 'linux' and platform_machine == 'aarch64' and python_version == '3.8'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#0.44.0 ; sys_platform == 'linux' and platform_machine == 'aarch64' and python_version == '3.9'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#0.44.0 ; sys_platform == 'linux' and platform_machine == 'aarch64' and python_version == '3.10'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl#0.44.0 ; sys_platform == 'linux' and platform_machine == 'aarch64' and python_version == '3.11'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp38-cp38-macosx_10_9_x86_64.whl#0.44.0 ; sys_platform == 'darwin' and python_version == '3.8'
|
||||
#pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp39-cp39-macosx_10_9_x86_64.whl#0.44.0 ; sys_platform == 'darwin' and python_version == '3.9'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp39-cp39-macosx_10_9_universal2.whl#0.44.0 ; sys_platform == 'darwin' and python_version == '3.9'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp310-cp310-macosx_10_9_universal2.whl#0.44.0 ; sys_platform == 'darwin' and python_version == '3.10'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-cp311-cp311-macosx_10_9_universal2.whl#0.44.0 ; sys_platform == 'darwin' and python_version == '3.11'
|
||||
pyevermizer @ https://github.com/black-sliver/pyevermizer/releases/download/v0.44.0/pyevermizer-0.44.0-1.tar.gz#0.44.0 ; python_version < '3.8' or python_version > '3.11' or (sys_platform != 'win32' and sys_platform != 'linux' and sys_platform != 'darwin') or (platform_machine != 'AMD64' and platform_machine != 'x86_64' and platform_machine != 'aarch64' and platform_machine != 'universal2' and platform_machine != 'arm64')
|
||||
pyevermizer==0.46.1 \
|
||||
--hash=sha256:9fd71b5e4af26a5dd24a9cbf5320bf0111eef80320613401a1c03011b1515806 \
|
||||
--hash=sha256:23f553ed0509d9a238b2832f775e0b5abd7741b38ab60d388294ee8a7b96c5fb \
|
||||
--hash=sha256:7189b67766418a3e7e6c683f09c5e758aa1a5c24316dd9b714984bac099c4b75 \
|
||||
--hash=sha256:befa930711e63d5d5892f67fd888b2e65e746363e74599c53e71ecefb90ae16a \
|
||||
--hash=sha256:202933ce21e0f33859537bf3800d9a626c70262a9490962e3f450171758507ca \
|
||||
--hash=sha256:c20ca69311c696528e1122ebc7d33775ee971f538c0e3e05dd3bfd4de10b82d4 \
|
||||
--hash=sha256:74dc689a771ae5ffcd5257e763f571ee890e3e87bdb208233b7f451522c00d66 \
|
||||
--hash=sha256:072296baef464daeb6304cf58827dcbae441ad0803039aee1c0caa10d56e0674 \
|
||||
--hash=sha256:7921baf20d52d92d6aeb674125963c335b61abb7e1298bde4baf069d11a2d05e \
|
||||
--hash=sha256:ca098034a84007038c2bff004582e6e6ac2fa9cc8b9251301d25d7e2adcee6da \
|
||||
--hash=sha256:22ddb29823c19be9b15e1b3627db1babfe08b486aede7d5cc463a0a1ae4c75d8 \
|
||||
--hash=sha256:bf1c441b49026d9000166be6e2f63fc351a3fda170aa3fdf18d44d5e5d044640 \
|
||||
--hash=sha256:9710aa7957b4b1f14392006237eb95803acf27897377df3e85395f057f4316b9 \
|
||||
--hash=sha256:8feb676c198bee17ab991ee015828345ac3f87c27dfdb3061d92d1fe47c184b4 \
|
||||
--hash=sha256:597026dede72178ff3627a4eb3315de8444461c7f0f856f5773993c3f9790c53 \
|
||||
--hash=sha256:70f9b964bdfb5191e8f264644c5d1af3041c66fe15261df8a99b3d719dc680d6 \
|
||||
--hash=sha256:74655c0353ffb6cda30485091d0917ce703b128cd824b612b3110a85c79a93d0 \
|
||||
--hash=sha256:0e9c74d105d4ec3af12404e85bb8776931c043657add19f798ee69465f92b999 \
|
||||
--hash=sha256:d3c13446d3d482b9cce61ac73b38effd26fcdcf7f693a405868d3aaaa4d18ca6 \
|
||||
--hash=sha256:371ac3360640ef439a5920ddfe11a34e9d2e546ed886bb8c9ed312611f9f4655 \
|
||||
--hash=sha256:6e5cf63b036f24d2ae4375a88df8d0bc93208352939521d1fcac3c829ef2c363 \
|
||||
--hash=sha256:edf28f5c4d1950d17343adf6d8d40d12c7e982d1e39535d55f7915e122cd8b0e \
|
||||
--hash=sha256:b5ef6f3b4e04f677c296f60f7f4c320ac22cd5bc09c05574460116c8641c801a \
|
||||
--hash=sha256:dd651f66720af4abe2ddae29944e299a57ff91e6fca1739e6dc1f8fd7a8c2b39 \
|
||||
--hash=sha256:4e278f5f72c27f9703bce5514d2fead8c00361caac03e94b0bf9ad8a144f1eeb \
|
||||
--hash=sha256:38f36ea1f545b835c3ecd6e081685a233ac2e3cf0eec8916adc92e4d791098a6 \
|
||||
--hash=sha256:0a2e58ed6e7c42f006cc17d32cec1f432f01b3fe490e24d71471b36e0d0d8742 \
|
||||
--hash=sha256:c1b658db76240596c03571c60635abe953f36fb55b363202971831c2872ea9a0 \
|
||||
--hash=sha256:deb5a84a6a56325eb6701336cdbf70f72adaaeab33cbe953d0e551ecf2592f20 \
|
||||
--hash=sha256:b1425c793e0825f58b3726e7afebaf5a296c07cb0d28580d0ee93dbe10dcdf63 \
|
||||
--hash=sha256:11995fb4dfd14b5c359591baee2a864c5814650ba0084524d4ea0466edfaf029 \
|
||||
--hash=sha256:5d2120b5c93ae322fe2a85d48e3eab4168a19e974a880908f1ac291c0300940f \
|
||||
--hash=sha256:254912ea4bfaaffb0abe366e73bd9ecde622677d6afaf2ce8a0c330df99fefd9 \
|
||||
--hash=sha256:540d8e4525f0b5255c1554b4589089dc58e15df22f343e9545ea00f7012efa07 \
|
||||
--hash=sha256:f69b8ebded7eed181fabe30deabae89fd10c41964f38abb26b19664bbe55c1ae
|
||||
|
|
|
@ -1,5 +1,20 @@
|
|||
from test.TestBase import WorldTestBase
|
||||
from typing import Iterable
|
||||
|
||||
|
||||
class SoETestBase(WorldTestBase):
|
||||
game = "Secret of Evermore"
|
||||
|
||||
def assertLocationReachability(self, reachable: Iterable[str] = (), unreachable: Iterable[str] = (),
|
||||
satisfied=True) -> None:
|
||||
"""
|
||||
Tests that unreachable can't be reached. Tests that reachable can be reached if satisfied=True.
|
||||
Usage: test with satisfied=False, collect requirements into state, test again with satisfied=True
|
||||
"""
|
||||
for location in reachable:
|
||||
self.assertEqual(self.can_reach_location(location), satisfied,
|
||||
f"{location} is unreachable but should be" if satisfied else
|
||||
f"{location} is reachable but shouldn't be")
|
||||
for location in unreachable:
|
||||
self.assertFalse(self.can_reach_location(location),
|
||||
f"{location} is reachable but shouldn't be")
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import typing
|
||||
from . import SoETestBase
|
||||
|
||||
|
||||
class OoBTest(SoETestBase):
|
||||
"""Tests that 'on' doesn't put out-of-bounds in logic. This is also the test base for OoB in logic."""
|
||||
options: typing.Dict[str, typing.Any] = {"out_of_bounds": "on"}
|
||||
|
||||
def testOoBAccess(self):
|
||||
in_logic = self.options["out_of_bounds"] == "logic"
|
||||
|
||||
# some locations that just need a weapon + OoB
|
||||
oob_reachable = [
|
||||
"Aquagoth", "Sons of Sth.", "Mad Monk", "Magmar", # OoB can use volcano shop to skip rock skip
|
||||
"Levitate", "Fireball", "Drain", "Speed",
|
||||
"E. Crustacia #107", "Energy Core #285", "Vanilla Gauge #57",
|
||||
]
|
||||
# some locations that should still be unreachable
|
||||
oob_unreachable = [
|
||||
"Tiny", "Rimsala",
|
||||
"Barrier", "Call Up", "Reflect", "Force Field", "Stop", # Stop guy doesn't spawn for the other entrances
|
||||
"Pyramid bottom #118", "Tiny's hideout #160", "Tiny's hideout #161", "Greenhouse #275",
|
||||
]
|
||||
# OoB + Diamond Eyes
|
||||
de_reachable = [
|
||||
"Tiny's hideout #160",
|
||||
]
|
||||
# still unreachable
|
||||
de_unreachable = [
|
||||
"Tiny",
|
||||
"Tiny's hideout #161",
|
||||
]
|
||||
|
||||
self.assertLocationReachability(reachable=oob_reachable, unreachable=oob_unreachable, satisfied=False)
|
||||
self.collect_by_name("Gladiator Sword")
|
||||
self.assertLocationReachability(reachable=oob_reachable, unreachable=oob_unreachable, satisfied=in_logic)
|
||||
self.collect_by_name("Diamond Eye")
|
||||
self.assertLocationReachability(reachable=de_reachable, unreachable=de_unreachable, satisfied=in_logic)
|
||||
|
||||
def testOoBGoal(self):
|
||||
# still need Energy Core with OoB if sequence breaks are not in logic
|
||||
for item in ["Gladiator Sword", "Diamond Eye", "Wheel", "Gauge"]:
|
||||
self.collect_by_name(item)
|
||||
self.assertBeatable(False)
|
||||
self.collect_by_name("Energy Core")
|
||||
self.assertBeatable(True)
|
||||
|
||||
|
||||
class OoBInLogicTest(OoBTest):
|
||||
"""Tests that stuff that should be reachable/unreachable with out-of-bounds actually is."""
|
||||
options: typing.Dict[str, typing.Any] = {"out_of_bounds": "logic"}
|
|
@ -0,0 +1,45 @@
|
|||
import typing
|
||||
from . import SoETestBase
|
||||
|
||||
|
||||
class SequenceBreaksTest(SoETestBase):
|
||||
"""Tests that 'on' doesn't put sequence breaks in logic. This is also the test base for in-logic."""
|
||||
options: typing.Dict[str, typing.Any] = {"sequence_breaks": "on"}
|
||||
|
||||
def testSequenceBreaksAccess(self):
|
||||
in_logic = self.options["sequence_breaks"] == "logic"
|
||||
|
||||
# some locations that just need any weapon + sequence break
|
||||
break_reachable = [
|
||||
"Sons of Sth.", "Mad Monk", "Magmar",
|
||||
"Fireball",
|
||||
"Volcano Room1 #73", "Pyramid top #135",
|
||||
]
|
||||
# some locations that should still be unreachable
|
||||
break_unreachable = [
|
||||
"Aquagoth", "Megataur", "Tiny", "Rimsala",
|
||||
"Barrier", "Call Up", "Levitate", "Stop", "Drain", "Escape",
|
||||
"Greenhouse #275", "E. Crustacia #107", "Energy Core #285", "Vanilla Gauge #57",
|
||||
]
|
||||
|
||||
self.assertLocationReachability(reachable=break_reachable, unreachable=break_unreachable, satisfied=False)
|
||||
self.collect_by_name("Gladiator Sword")
|
||||
self.assertLocationReachability(reachable=break_reachable, unreachable=break_unreachable, satisfied=in_logic)
|
||||
self.collect_by_name("Spider Claw") # Gauge now just needs non-sword
|
||||
self.assertEqual(self.can_reach_location("Vanilla Gauge #57"), in_logic)
|
||||
self.collect_by_name("Bronze Spear") # Escape now just needs either Megataur or Rimsala dead
|
||||
self.assertEqual(self.can_reach_location("Escape"), in_logic)
|
||||
|
||||
def testSequenceBreaksGoal(self):
|
||||
in_logic = self.options["sequence_breaks"] == "logic"
|
||||
|
||||
# don't need Energy Core with sequence breaks in logic
|
||||
for item in ["Gladiator Sword", "Diamond Eye", "Wheel", "Gauge"]:
|
||||
self.assertBeatable(False)
|
||||
self.collect_by_name(item)
|
||||
self.assertBeatable(in_logic)
|
||||
|
||||
|
||||
class SequenceBreaksInLogicTest(SequenceBreaksTest):
|
||||
"""Tests that stuff that should be reachable/unreachable with sequence breaks actually is."""
|
||||
options: typing.Dict[str, typing.Any] = {"sequence_breaks": "logic"}
|
Loading…
Reference in New Issue