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

TUNIC: Shuffle Ladders option #2919

Merged
merged 89 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from 79 commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
47649b2
New branch to fix git being git
ScipioWright Feb 28, 2024
ea9fb31
Some minor updates
ScipioWright Feb 29, 2024
5f07a92
Renumber ladders
ScipioWright Feb 29, 2024
89b95d5
Rename frog ladder
ScipioWright Feb 29, 2024
148cd39
Rename frog ladders
ScipioWright Feb 29, 2024
9df3be5
Add description for ladder rando
ScipioWright Feb 29, 2024
3c29793
Some renames, and more ladders
ScipioWright Mar 1, 2024
c78622a
Rename swamp ladder
ScipioWright Mar 2, 2024
dea35af
Most of the way through ER, just need to do rules
ScipioWright Mar 2, 2024
5108369
Finished with ER except for ladder storage rules
ScipioWright Mar 2, 2024
ac8a3eb
Wrote up ladder storage rules, need to merge in the hint changes here…
ScipioWright Mar 2, 2024
06ab1a8
Ported hint branch over
ScipioWright Mar 2, 2024
ebaf64d
Updated ls er rules
ScipioWright Mar 2, 2024
ce22375
Fix for hints
ScipioWright Mar 2, 2024
412f180
Simplify has_ladder (thanks medic)
ScipioWright Mar 4, 2024
a8fdf12
Change name of west overworld ladders
ScipioWright Mar 5, 2024
709819f
Add beneath the vault ladder
ScipioWright Mar 5, 2024
a1ef58e
Rename west bell ladders
ScipioWright Mar 5, 2024
96a84e5
Revise remove filler to remove traps if there's no filler left
ScipioWright Mar 5, 2024
a180470
Rename ladder rando to shuffle ladders
ScipioWright Mar 6, 2024
4c0c4a4
Shuffle options around a bit
ScipioWright Mar 6, 2024
0b322b8
Make the ladder logic actually get loaded in properly
ScipioWright Mar 6, 2024
4ed177b
Make location groups less dumb, add more, remove some
ScipioWright Mar 6, 2024
9ca4f73
Update docs to match new groups
ScipioWright Mar 6, 2024
235ab77
Several logic fixes
ScipioWright Mar 6, 2024
f3feb6b
Re-fix that quarry bug
ScipioWright Mar 6, 2024
dd788bc
Update option description
ScipioWright Mar 6, 2024
56d544e
Fix overworld -> atoll again
ScipioWright Mar 6, 2024
13fc2c3
Add missing HC rules
ScipioWright Mar 7, 2024
e725d65
Fix more broken rules
ScipioWright Mar 7, 2024
b6c4380
More fixesssss
ScipioWright Mar 7, 2024
5e4fbd7
Reorganize temple access
ScipioWright Mar 7, 2024
e8a7345
Couple more fixes, add a todo
ScipioWright Mar 7, 2024
0d3cfca
LS from atoll upper entry if you have the ladder
ScipioWright Mar 7, 2024
bed7d87
Add note
ScipioWright Mar 7, 2024
56e43b2
Add note to er scripts for later
ScipioWright Mar 7, 2024
6596092
Big refactor, ladder rando just uses the ER now with vanilla connections
ScipioWright Mar 8, 2024
c25ed09
Remove above ruined passage -> east overworld with laurels, cause it …
ScipioWright Mar 8, 2024
7ecb2ab
Fix cathedral door logic bug
ScipioWright Mar 8, 2024
9853ff5
Merge branch 'main' into tunc-ladders
ScipioWright Mar 8, 2024
9e2000e
emdash
ScipioWright Mar 8, 2024
daf5caf
Update LS rules
ScipioWright Mar 8, 2024
e50f835
Simplify LS rules slightly
ScipioWright Mar 8, 2024
222a6e4
Remove unused helper
ScipioWright Mar 8, 2024
2316e7d
Updating comments
ScipioWright Mar 8, 2024
80239f8
Some pep8ing
ScipioWright Mar 9, 2024
97f3d11
Clear todo after doing the todo thing
ScipioWright Mar 9, 2024
b863b45
Add missed grapple connection from main Overworld to the beach
ScipioWright Mar 9, 2024
0c5da9d
Fix rules for the chest beneath the quarry gate
ScipioWright Mar 9, 2024
a63bbb4
Several unrestricted logic fixes (how many more until I remove the op…
ScipioWright Mar 9, 2024
c5f84d0
Add atoll to overworld lower LS
ScipioWright Mar 10, 2024
b5d6715
Remove data version, since it is not necessary and will be removed ev…
ScipioWright Mar 10, 2024
40f6e94
Add new region to deal with logic bug with ladders and ER together
ScipioWright Mar 10, 2024
9e32d9e
Rename ladder items to more consistent names
ScipioWright Mar 10, 2024
51a50ff
Address review comments, also fix a tiny region issue
ScipioWright Mar 11, 2024
d02b13e
Add me to codeowners (Silent said it was okay)
ScipioWright Mar 11, 2024
340360d
Add another ladder group
ScipioWright Mar 11, 2024
0a2da8a
Add Silvris's suggestion
ScipioWright Mar 11, 2024
f0711fb
Add another suggested ladder
ScipioWright Mar 11, 2024
4fef2c1
Renaming ladders, combining two into one. Also update docs to include…
ScipioWright Mar 11, 2024
deb6ba5
Another edge case ls rule (why ls why)
ScipioWright Mar 11, 2024
350f579
Fix a few more edge cases
ScipioWright Mar 11, 2024
99590a3
maybe you shouldn't code when you're very tired? nahhhhh
ScipioWright Mar 11, 2024
14a435c
what if we kissed on the roof of the library. haha, unless...
ScipioWright Mar 11, 2024
da719f5
so many little interactions between ER and ladders
ScipioWright Mar 11, 2024
49ebdb5
lmao we blocked the tiny library lab ladder
ScipioWright Mar 11, 2024
7e04b6b
incorrect region on a few locations
ScipioWright Mar 12, 2024
943955d
Updating a few comments
ScipioWright Mar 12, 2024
af39a7a
Merge branch 'main' into tunc-ladders
ScipioWright Mar 12, 2024
c0433d0
Reorder ladder item IDs
ScipioWright Mar 12, 2024
66d506f
Add sword 4 can get you past envoy rule
ScipioWright Mar 14, 2024
adf0638
Remove debug print
ScipioWright Mar 15, 2024
9db5c2e
Merge branch 'main' into tunc-ladders
ScipioWright Mar 15, 2024
c2f2dd2
Change a few lists to sets to be slightly faster
ScipioWright Mar 15, 2024
fc97b73
Merge branch 'main' into tunc-ladders
ScipioWright Mar 15, 2024
84e8f76
Merge branch 'main' into tunc-ladders
ScipioWright Mar 15, 2024
7d6b681
Fix missing tags
ScipioWright Mar 15, 2024
3de0214
Fix portal region name
ScipioWright Mar 15, 2024
eca1593
Merge branch 'main' into tunc-ladders
ScipioWright Mar 15, 2024
cc1d1eb
Un-pep8 option descriptions so the new lines don't make it look stupi…
ScipioWright Mar 16, 2024
3786849
Add more ladder storage logic, deplete brain cells
ScipioWright Mar 16, 2024
2d3138b
ladders ladders ladders ladders
ScipioWright Mar 16, 2024
6bdd00f
ice grapples are nice grapples (no they aren't)
ScipioWright Mar 16, 2024
92c22db
Change entrance_rando value in slot_data to an int(bool(value)) so it…
ScipioWright Mar 17, 2024
d214b9c
Remove a rule on a chest that we felt didn't really need to be there
ScipioWright Mar 17, 2024
0d5a67d
Update logicrules option description
ScipioWright Mar 17, 2024
4745ccc
Update entrance rando option description for clarity
ScipioWright Mar 18, 2024
29badc9
Update entrance rando option description again
ScipioWright Mar 18, 2024
a41785a
Merge branch 'main' into tunc-ladders
ScipioWright Mar 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@
/worlds/tloz/ @Rosalie-A @t3hf1gm3nt

# TUNIC
/worlds/tunic/ @silent-destroyer
/worlds/tunic/ @silent-destroyer @ScipioWright

# Undertale
/worlds/undertale/ @jonloveslegos
Expand Down
94 changes: 70 additions & 24 deletions worlds/tunic/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .er_rules import set_er_location_rules
from .regions import tunic_regions
from .er_scripts import create_er_regions
from .er_data import portal_mapping
from .options import TunicOptions
from worlds.AutoWorld import WebWorld, World
from decimal import Decimal, ROUND_HALF_UP
Expand Down Expand Up @@ -44,7 +45,6 @@ class TunicWorld(World):
game = "TUNIC"
web = TunicWeb()

data_version = 2
options: TunicOptions
options_dataclass = TunicOptions
item_name_groups = item_name_groups
Expand Down Expand Up @@ -72,6 +72,7 @@ def generate_early(self) -> None:
self.options.maskless.value = passthrough["maskless"]
self.options.hexagon_quest.value = passthrough["hexagon_quest"]
self.options.entrance_rando.value = passthrough["entrance_rando"]
self.options.shuffle_ladders.value = passthrough["shuffle_ladders"]

def create_item(self, name: str) -> TunicItem:
item_data = item_table[name]
Expand Down Expand Up @@ -119,36 +120,55 @@ def create_items(self) -> None:
items_to_create[rgb_hexagon] = 0
items_to_create[gold_hexagon] -= 3

# Filler items in the item pool
available_filler: List[str] = [filler for filler in items_to_create if items_to_create[filler] > 0 and
item_table[filler].classification == ItemClassification.filler]

# Remove filler to make room for other items
def remove_filler(amount: int):
for _ in range(0, amount):
if not available_filler:
fill = "Fool Trap"
else:
fill = self.random.choice(available_filler)
if items_to_create[fill] == 0:
raise Exception("No filler items left to accommodate options selected. Turn down fool trap amount.")
items_to_create[fill] -= 1
if items_to_create[fill] == 0:
available_filler.remove(fill)

if self.options.shuffle_ladders:
ladder_count = 0
for item_name, item_data in item_table.items():
if item_data.item_group == "ladders":
items_to_create[item_name] = 1
ladder_count += 1
remove_filler(ladder_count)

if hexagon_quest:
# Calculate number of hexagons in item pool
hexagon_goal = self.options.hexagon_goal
extra_hexagons = self.options.extra_hexagon_percentage
items_to_create[gold_hexagon] += int((Decimal(100 + extra_hexagons) / 100 * hexagon_goal).to_integral_value(rounding=ROUND_HALF_UP))

ScipioWright marked this conversation as resolved.
Show resolved Hide resolved
# Replace pages and normal hexagons with filler
for replaced_item in list(filter(lambda item: "Pages" in item or item in hexagon_locations, items_to_create)):
items_to_create[self.get_filler_item_name()] += items_to_create[replaced_item]
filler_name = self.get_filler_item_name()
items_to_create[filler_name] += items_to_create[replaced_item]
if items_to_create[filler_name] >= 1 and filler_name not in available_filler:
available_filler.append(filler_name)
items_to_create[replaced_item] = 0

# Filler items that are still in the item pool to swap out
available_filler: List[str] = [filler for filler in items_to_create if items_to_create[filler] > 0 and
item_table[filler].classification == ItemClassification.filler]

# Remove filler to make room for extra hexagons
for i in range(0, items_to_create[gold_hexagon]):
fill = self.random.choice(available_filler)
items_to_create[fill] -= 1
if items_to_create[fill] == 0:
available_filler.remove(fill)
remove_filler(items_to_create[gold_hexagon])

if self.options.maskless:
mask_item = TunicItem("Scavenger Mask", ItemClassification.useful, self.item_name_to_id["Scavenger Mask"], self.player)
tunic_items.append(mask_item)
items_to_create["Scavenger Mask"] = 0

if self.options.lanternless:
mask_item = TunicItem("Lantern", ItemClassification.useful, self.item_name_to_id["Lantern"], self.player)
tunic_items.append(mask_item)
lantern_item = TunicItem("Lantern", ItemClassification.useful, self.item_name_to_id["Lantern"], self.player)
tunic_items.append(lantern_item)
items_to_create["Lantern"] = 0

for item, quantity in items_to_create.items():
Expand All @@ -172,15 +192,16 @@ def create_regions(self) -> None:
self.ability_unlocks["Pages 24-25 (Prayer)"] = passthrough["Hexagon Quest Prayer"]
self.ability_unlocks["Pages 42-43 (Holy Cross)"] = passthrough["Hexagon Quest Holy Cross"]
self.ability_unlocks["Pages 52-53 (Icebolt)"] = passthrough["Hexagon Quest Icebolt"]

if self.options.entrance_rando:
portal_pairs, portal_hints = create_er_regions(self)
for portal1, portal2 in portal_pairs.items():
self.tunic_portal_pairs[portal1.scene_destination()] = portal2.scene_destination()

self.er_portal_hints = portal_hints

# ladder rando uses ER with vanilla connections, so that we're not managing more rules files
if self.options.entrance_rando or self.options.shuffle_ladders:
portal_pairs = create_er_regions(self)
if self.options.entrance_rando:
# these get interpreted by the game to tell it which entrances to connect
for portal1, portal2 in portal_pairs.items():
self.tunic_portal_pairs[portal1.scene_destination()] = portal2.scene_destination()
else:
# for non-ER, non-ladders
for region_name in tunic_regions:
region = Region(region_name, self.player, self.multiworld)
self.multiworld.regions.append(region)
Expand All @@ -201,7 +222,7 @@ def create_regions(self) -> None:
victory_region.locations.append(victory_location)

def set_rules(self) -> None:
if self.options.entrance_rando:
if self.options.entrance_rando or self.options.shuffle_ladders:
set_er_location_rules(self, self.ability_unlocks)
else:
set_region_rules(self, self.ability_unlocks)
Expand All @@ -212,7 +233,31 @@ def get_filler_item_name(self) -> str:

def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]):
if self.options.entrance_rando:
hint_data[self.player] = self.er_portal_hints
hint_data.update({self.player: {}})
# all state seems to have efficient paths
all_state = self.multiworld.get_all_state(True)
all_state.update_reachable_regions(self.player)
paths = all_state.path
portal_names = [portal.name for portal in portal_mapping]
for location in self.multiworld.get_locations(self.player):
# skipping event locations
if not location.address:
continue
path_to_loc = []
previous_name = "placeholder"
name, connection = paths[location.parent_region]
while connection != ("Menu", None):
name, connection = connection
# for LS entrances, we just want to give the portal name
if "(LS)" in name:
name, _ = name.split(" (LS) ")
# was getting some cases like Library Grave -> Library Grave -> other place
if name in portal_names and name != previous_name:
previous_name = name
path_to_loc.append(name)
hint_text = " -> ".join(reversed(path_to_loc))
if hint_text:
hint_data[self.player][location.address] = hint_text

def fill_slot_data(self) -> Dict[str, Any]:
slot_data: Dict[str, Any] = {
Expand All @@ -227,6 +272,7 @@ def fill_slot_data(self) -> Dict[str, Any]:
"lanternless": self.options.lanternless.value,
"maskless": self.options.maskless.value,
"entrance_rando": bool(self.options.entrance_rando.value),
"shuffle_ladders": self.options.shuffle_ladders.value,
"Hexagon Quest Prayer": self.ability_unlocks["Pages 24-25 (Prayer)"],
"Hexagon Quest Holy Cross": self.ability_unlocks["Pages 42-43 (Holy Cross)"],
"Hexagon Quest Icebolt": self.ability_unlocks["Pages 52-53 (Icebolt)"],
Expand Down
2 changes: 1 addition & 1 deletion worlds/tunic/docs/en_TUNIC.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ For the Entrance Randomizer:
Bombs, consumables (non-bomb ones), weapons, melee weapons (stick and sword), keys, hexagons, offerings, hero relics, cards, golden treasures, money, pages, and abilities (the three ability pages). There are also a few groups being used for singular items: laurels, orb, dagger, magic rod, holy cross, prayer, icebolt, and progressive sword.

## What location groups are there?
Holy cross (for all holy cross checks), fairies (for the two fairy checks), well (for the coin well checks), and shop. Additionally, for checks that do not fall into the above categories, the name of the region is the name of the location group.
Holy cross (for all holy cross checks), fairies (for the two fairy checks), well (for the coin well checks), shop, bosses (for the bosses with checks associated with them), hero relic (for the 6 hero grave checks), and ladders (for the ladder items when you have shuffle ladders enabled).

## Is Connection Plando supported?
Yes. The host needs to enable it in their `host.yaml`, and the player's yaml needs to contain a plando_connections block.
Expand Down
Loading
Loading