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

Shivers: Add events and fix require puzzle hints logic #4018

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
9da0e95
Adds some events, renames things, fails for many players.
korydondzila Jul 22, 2024
6833fed
Adds entrance rules for requires hints.
korydondzila Jul 23, 2024
feb4608
Cleanup and add goal item.
korydondzila Jul 25, 2024
9d01dca
Cleanup.
korydondzila Jul 25, 2024
8a2f53e
Add additional rule.
korydondzila Jul 25, 2024
5b04610
Event and regions additions.
korydondzila Jul 28, 2024
a0e518a
Merge branch 'refs/heads/main' into add-events
korydondzila Aug 6, 2024
1e3ed5f
Updates from merge.
korydondzila Aug 6, 2024
865640f
Adds collect behavior option.
korydondzila Aug 6, 2024
cb7ea1b
Fix missing generator location.
korydondzila Aug 6, 2024
1c56c62
Fix whitespace and optimize imports.
korydondzila Aug 6, 2024
b72c9dc
Merge branch 'main' into add-events-and-collect-behavior
korydondzila Aug 17, 2024
9c49e4b
Switch location order back.
korydondzila Aug 30, 2024
37157de
Merge branch 'main' into add-events
korydondzila Aug 31, 2024
82f3781
Merge branch 'main' into add-events
korydondzila Sep 30, 2024
e0279cf
Add name replacement for storage.
korydondzila Sep 30, 2024
c5a6cd0
Fix test failure.
korydondzila Sep 30, 2024
8cdecd1
Improve puzzle hints required.
korydondzila Oct 1, 2024
878e3e0
Add missing locations and cleanup indirect conditions.
korydondzila Oct 1, 2024
d2e3099
Fix naming.
korydondzila Oct 1, 2024
574a02e
PR feedback.
korydondzila Oct 2, 2024
bfa7788
Missed comment.
korydondzila Oct 2, 2024
59a36f2
Cleanup imports, use strings for option equivalence, and update optio…
korydondzila Oct 3, 2024
d9d78d3
Fix rule.
korydondzila Oct 4, 2024
872dbe5
Create rolling buffer goal items and remove goal items and location f…
korydondzila Oct 28, 2024
53a8fab
Cleanup.
korydondzila Oct 28, 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 @@ -140,7 +140,7 @@
/worlds/ror2/ @kindasneaki

# Shivers
/worlds/shivers/ @GodlFire
/worlds/shivers/ @GodlFire @korydondzila

# A Short Hike
/worlds/shorthike/ @chandler05
Expand Down
14 changes: 8 additions & 6 deletions worlds/shivers/Constants.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import os
import json
import os
import pkgutil
from datetime import datetime

from dateutil.relativedelta import relativedelta


def load_data_file(*args) -> dict:
fname = os.path.join("data", *args)
return json.loads(pkgutil.get_data(__name__, fname).decode())

location_id_offset: int = 27000

location_id_offset: int = 27000
location_info = load_data_file("locations.json")
location_name_to_id = {name: location_id_offset + index \
for index, name in enumerate(location_info["all_locations"])}

location_name_to_id = {name: location_id_offset + index for index, name in enumerate(location_info["all_locations"])}
exclusion_info = load_data_file("excluded_locations.json")

region_info = load_data_file("regions.json")
years_since_sep_30_1980 = relativedelta(datetime.now(), datetime.fromisoformat("1980-09-30")).years
306 changes: 186 additions & 120 deletions worlds/shivers/Items.py

Large diffs are not rendered by default.

100 changes: 96 additions & 4 deletions worlds/shivers/Options.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from Options import Choice, DefaultOnToggle, Toggle, PerGameCommonOptions, Range
from dataclasses import dataclass

from Options import (
Choice, DefaultOnToggle, ItemDict, ItemSet, LocationSet, OptionGroup, PerGameCommonOptions, Range, Toggle,
)
from worlds.shivers import ItemType, item_table
from worlds.shivers.Constants import location_info

korydondzila marked this conversation as resolved.
Show resolved Hide resolved

class IxupiCapturesNeeded(Range):
"""
Expand All @@ -11,62 +16,72 @@ class IxupiCapturesNeeded(Range):
range_end = 10
default = 10


class LobbyAccess(Choice):
"""
Chooses how keys needed to reach the lobby are placed.
- Normal: Keys are placed anywhere
- Early: Keys are placed early
- Local: Keys are placed locally
- Local: Keys are placed locally and early
"""
display_name = "Lobby Access"
option_normal = 0
option_early = 1
option_local = 2
default = 1


class PuzzleHintsRequired(DefaultOnToggle):
"""
If turned on puzzle hints/solutions will be available before the corresponding puzzle is required.

For example: The Red Door puzzle will be logically required only after access to the Beth's Address Book which gives you the solution.
For example: The Red Door puzzle will be logically required only after obtaining access to Beth's Address Book
which gives you the solution.

Turning this off allows for greater randomization.
"""
display_name = "Puzzle Hints Required"


class InformationPlaques(Toggle):
"""
Adds Information Plaques as checks.
(40 Locations)
"""
display_name = "Include Information Plaques"


class FrontDoorUsable(Toggle):
"""
Adds a key to unlock the front door of the museum.
"""
display_name = "Front Door Usable"


class ElevatorsStaySolved(DefaultOnToggle):
"""
Adds elevators as checks and will remain open upon solving them.
(3 Locations)
"""
display_name = "Elevators Stay Solved"


class EarlyBeth(DefaultOnToggle):
"""
Beth's body is open at the start of the game. This allows any pot piece to be placed in the slide and early checks on the second half of the final riddle.
Beth's body is open at the start of the game.
This allows any pot piece to be placed in the slide and early checks on the second half of the final riddle.
"""
display_name = "Early Beth"


class EarlyLightning(Toggle):
"""
Allows lightning to be captured at any point in the game. You will still need to capture all ten Ixupi for victory.
(1 Location)
"""
display_name = "Early Lightning"


class LocationPotPieces(Choice):
"""
Chooses where pot pieces will be located within the multiworld.
Expand All @@ -78,6 +93,8 @@ class LocationPotPieces(Choice):
option_own_world = 0
option_different_world = 1
option_any_world = 2
default = 2


class FullPots(Choice):
"""
Expand Down Expand Up @@ -107,6 +124,61 @@ class PuzzleCollectBehavior(Choice):
default = 1


# Need to override the default options to remove the goal items and goal locations so that they do not show on web.
valid_item_keys = [name for name, data in item_table.items() if data.type != ItemType.GOAL and data.code is not None]
Copy link
Collaborator

Choose a reason for hiding this comment

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

This whole process doesn't really fix everything. Plando still exists, among other things, so it's still going to run into problems, it's also kind of "hacky" to overwrite all of these. Can you really not do anything else?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I mean this is what was suggested, if there's a better way I would love to know.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just using an event?

Copy link
Collaborator

Choose a reason for hiding this comment

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

As far as I can tell, the only thing this is being used for is the completion_condition, so I'm not sure why this isn't just an event (ID None)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I mentioned it before but I was trying to be weird and have an in joke goal item that displays when you beat the game. Event items will not do that.

However something like the Map Complete items in the Dooms/Heretic would be similar and display in these options when they probably should not. afaik this is the only game so far attempting do this, but nothing says it can't. Plando is of course still a problem, but that requires deeper knowledge, the web based options is at least something that can be mitagated.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can't you just make the client display the item anyway? Just fake one, basically?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Idk, I'll still leave my approval, but I'm starting to like less and less all the weird things worlds are doing with non-event "events" XD

Copy link
Contributor Author

Choose a reason for hiding this comment

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

At least this cleans up all the other stuff that should actually have been events but weren't and added events to clean up rule logic. I just want my one small weird thing lol.

valid_location_keys = [name for name in location_info["all_locations"] if name != "Mystery Solved"]


class LocalItems(ItemSet):
"""Forces these items to be in their native world."""
display_name = "Local Items"
rich_text_doc = True
valid_keys = valid_item_keys


class NonLocalItems(ItemSet):
"""Forces these items to be outside their native world."""
display_name = "Non-local Items"
rich_text_doc = True
valid_keys = valid_item_keys


class StartInventory(ItemDict):
"""Start with these items."""
verify_item_name = True
display_name = "Start Inventory"
rich_text_doc = True
valid_keys = valid_item_keys


class StartHints(ItemSet):
"""Start with these item's locations prefilled into the ``!hint`` command."""
display_name = "Start Hints"
rich_text_doc = True
valid_keys = valid_item_keys


class StartLocationHints(LocationSet):
"""Start with these locations and their item prefilled into the ``!hint`` command."""
display_name = "Start Location Hints"
rich_text_doc = True
valid_keys = valid_location_keys


class ExcludeLocations(LocationSet):
"""Prevent these locations from having an important item."""
display_name = "Excluded Locations"
rich_text_doc = True
valid_keys = valid_location_keys


class PriorityLocations(LocationSet):
"""Prevent these locations from having an unimportant item."""
display_name = "Priority Locations"
rich_text_doc = True
valid_keys = valid_location_keys


@dataclass
class ShiversOptions(PerGameCommonOptions):
ixupi_captures_needed: IxupiCapturesNeeded
Expand All @@ -120,3 +192,23 @@ class ShiversOptions(PerGameCommonOptions):
location_pot_pieces: LocationPotPieces
full_pots: FullPots
puzzle_collect_behavior: PuzzleCollectBehavior
local_items: LocalItems
non_local_items: NonLocalItems
start_inventory: StartInventory
start_hints: StartHints
start_location_hints: StartLocationHints
exclude_locations: ExcludeLocations
priority_locations: PriorityLocations


shivers_option_groups = [
OptionGroup("Item & Location Options", [
LocalItems,
NonLocalItems,
StartInventory,
StartHints,
StartLocationHints,
ExcludeLocations,
PriorityLocations
], True),
]
Loading
Loading