The Witness: The Secret Feature (#4370)

* Secret Feature

* Fixes

* Fixes and unit tests

* renaming some variables

* Fix the thing

* unit test for elevator egg

* Docstring

* reword

* Fix duplicate locations I think?

* Remove debug thing

* Add the tests back lol

* Make it so that you can exclude an egg to disable it

* Improve hint text for easter eggs

* Update worlds/witness/options.py

Co-authored-by: Scipio Wright <scipiowright@gmail.com>

* Update worlds/witness/player_logic.py

Co-authored-by: Scipio Wright <scipiowright@gmail.com>

* Update worlds/witness/options.py

Co-authored-by: Scipio Wright <scipiowright@gmail.com>

* Update worlds/witness/player_logic.py

Co-authored-by: Scipio Wright <scipiowright@gmail.com>

* Update worlds/witness/rules.py

Co-authored-by: Scipio Wright <scipiowright@gmail.com>

* Update test_easter_egg_shuffle.py

* This was actually not necessary, since this is the Egg requirements, nothing to do with location names

* Move one of them

* Improve logic

* Lol

* Moar

* Adjust unit tests

* option docstring adjustment

* Recommend door shuffle

* Don't overlap IDs

* Option description idk

* Change the way the difficulties work to reward playing higher modes

* Fix merge

* add some stuff to generate_data_file (this file is not imported during gen, don't review it :D)

* oop

* space

* This can be earlier than I thought, apparently.

* buffer

* Comment

* Make sure the option is VERY visible

* Some mypy stuff

* apparently ruff wants this

* .

* durinig

* Update options.py

* Explain the additional effects of each difficulty

* Fix logic of flood room secret

* Add Southern Peninsula Area

* oop

---------

Co-authored-by: Scipio Wright <scipiowright@gmail.com>
This commit is contained in:
NewSoupVi
2025-03-08 01:44:06 +01:00
committed by GitHub
parent bc61221ec6
commit 08b3b3ecf5
18 changed files with 651 additions and 73 deletions

View File

@@ -1,4 +1,6 @@
from dataclasses import dataclass
from datetime import datetime
from typing import Tuple
from schema import And, Schema
@@ -18,6 +20,7 @@ from Options import (
from .data import static_logic as static_witness_logic
from .data.item_definition_classes import ItemCategory, WeightedItemDefinition
from .data.utils import is_easter_time
from .entity_hunt import ALL_HUNTABLE_PANELS
@@ -142,6 +145,53 @@ class ShuffleEnvironmentalPuzzles(Choice):
option_obelisk_sides = 2
class EasterEggHunt(Choice):
"""
Adds up to 120 Easter Eggs to the game, placed by NewSoupVi, Exempt-Medic, hatkirby, Scipio, and Rever.
These can be collected by simply clicking on them.
The difficulty options differ by how many Eggs you need to collect for each check and how many are logically required for each check.
- "Easy": 3 / 8
- "Normal": 3 / 6
- "Hard": 4 / 6
- "Very Hard": 4 / 5
- "Extreme": 4 / 4 (You are expected to collect every Easter Egg)
Checks that require more Eggs than logically available still exist, but are excluded.
For example, on "Easy", the "63 Eggs Collected" check can physically be obtained, but would logically require 125 Easter Eggs, which is impossible. Thus, it is excluded.
On "Easy", "Normal", and "Hard", you will start with an "Egg Radar" that you can activate using the Puzzle Skip key.
On every difficulty except "Extreme", there will be a message when you've collected all Easter Eggs in an area.
On "Easy", there will be an additional message after every Easter Egg telling you how many Easter Eggs are remaining in the area.
It is recommended that you play this mode together with Door Shuffle. Without it, more than half of the Easter Eggs will be in sphere 1.
"""
visibility = Visibility.all if is_easter_time() else Visibility.none
display_name = "Easter Egg Hunt"
option_off = 0
# Number represents the amount of eggs needed per check
option_easy = 1
option_normal = 2
option_hard = 3
option_very_hard = 4
option_extreme = 5
default = 2 if is_easter_time() else 0
def get_step_and_logical_step(self) -> Tuple[int, int]:
if self == "easy":
return 3, 8
if self == "normal":
return 3, 6
if self == "hard":
return 4, 6
if self == "very_hard":
return 4, 5
return 4, 4
class ShuffleDog(Choice):
"""
Adds petting the dog statue in Town into the location pool.
@@ -504,6 +554,7 @@ class TheWitnessOptions(PerGameCommonOptions):
death_link_amnesty: DeathLinkAmnesty
puzzle_randomization_seed: PuzzleRandomizationSeed
shuffle_dog: ShuffleDog
easter_egg_hunt: EasterEggHunt
witness_option_groups = [
@@ -561,3 +612,13 @@ witness_option_groups = [
ShuffleDog,
])
]
# Make sure that Easter Egg Hunt is VERY visible during easter time (when it's enabled by default)
if is_easter_time():
easter_special_option_group = OptionGroup("EASTER SPECIAL", [
EasterEggHunt,
])
witness_option_groups = [easter_special_option_group, *witness_option_groups]
else:
silly_options_group = next(group for group in witness_option_groups if group.name == "Silly Options")
silly_options_group.options.append(EasterEggHunt)