Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
9c2bccc
add ignore file
PinkSwitch Apr 13, 2026
c5fd07d
Set up init file
PinkSwitch Apr 13, 2026
c4cc3c3
Start on items
PinkSwitch Apr 14, 2026
f03d4de
Finish adding items
PinkSwitch Apr 14, 2026
cbbb2cd
Adjust amounts and classes
PinkSwitch Apr 15, 2026
a57f9c7
Add the options file
PinkSwitch Apr 15, 2026
b6e6aa8
More init
PinkSwitch Apr 15, 2026
5bdaeb1
Add some things, get generator stable
PinkSwitch Apr 15, 2026
75ac7ea
Loc logging
PinkSwitch Apr 15, 2026
a1c6b27
Tower of death p1
PinkSwitch Apr 15, 2026
3857098
Throne room
PinkSwitch Apr 15, 2026
8ddc1d6
City of haze
PinkSwitch Apr 15, 2026
add70db
Add 13th street
PinkSwitch Apr 15, 2026
17c396d
Sandy grave
PinkSwitch Apr 16, 2026
b62480f
Forgor city
PinkSwitch Apr 16, 2026
25a5521
Nation of fools
PinkSwitch Apr 16, 2026
d9006ff
Burnt paradise
PinkSwitch Apr 16, 2026
7d0c3b3
Forest of doom
PinkSwitch Apr 16, 2026
6038f59
Dark academy
PinkSwitch Apr 16, 2026
2a6c4a4
add quests
PinkSwitch Apr 16, 2026
284279c
Add regions
PinkSwitch Apr 20, 2026
0edc676
Add great stairs locations
PinkSwitch Apr 26, 2026
43433eb
Map checks for city of haze
PinkSwitch Apr 26, 2026
be5ca41
Map checks for sandy grave
PinkSwitch Apr 27, 2026
198042a
Check mapping for forgotten city
PinkSwitch Apr 27, 2026
810a918
Finish Base Check Mapping
PinkSwitch Apr 27, 2026
2a418b2
huh
PinkSwitch Apr 27, 2026
4879ea9
refactor region building
PinkSwitch Apr 27, 2026
0e3cfac
,
PinkSwitch Apr 27, 2026
ed96c31
Finish location mapping
PinkSwitch Apr 27, 2026
fa16d81
Fill the item pool
PinkSwitch Apr 27, 2026
c981867
Place static items
PinkSwitch Apr 28, 2026
5d4ad9a
Add logic for castle checks
PinkSwitch Apr 28, 2026
0a8621b
City of haze rules
PinkSwitch Apr 28, 2026
7f8a067
Add more rules
PinkSwitch Apr 28, 2026
4e0ef6c
Finish building rules
PinkSwitch Apr 28, 2026
d6f3aa4
ort
PinkSwitch Apr 28, 2026
6acb8e9
add basepatch
PinkSwitch Apr 29, 2026
2223335
Setup a file writing system
PinkSwitch Apr 29, 2026
8ca8bc1
add options handling to ROM
PinkSwitch Apr 29, 2026
ec65181
start logging check data
PinkSwitch Apr 29, 2026
9314a92
More loc checks
PinkSwitch Apr 29, 2026
e705baa
more data getting
PinkSwitch Apr 29, 2026
f201888
Desert locs
PinkSwitch Apr 29, 2026
82ec02d
Circus locs
PinkSwitch Apr 29, 2026
f367a20
Simple areas
PinkSwitch Apr 29, 2026
923c4f2
Forest locs
PinkSwitch Apr 29, 2026
0884314
Finish getting loc daa
PinkSwitch Apr 29, 2026
1e1fc62
Define item types and IDs
PinkSwitch Apr 29, 2026
5aad6ed
Add stuff
PinkSwitch Apr 30, 2026
71a1fa5
Fix item links
PinkSwitch Apr 30, 2026
69eb348
Adjust check pos
PinkSwitch Apr 30, 2026
70b3d06
Fix quests
PinkSwitch Apr 30, 2026
b49cf54
Update the ASM file to make quests use the new format
PinkSwitch Apr 30, 2026
2b6d44b
Implement EXP Multiplier
PinkSwitch May 1, 2026
c1816b7
Update patch
PinkSwitch May 1, 2026
4a5d634
Fill slot stuff
PinkSwitch May 1, 2026
3577220
fix item link issue
EmilyV99 May 1, 2026
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: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
*.apsave
*.BIN
*.puml
*.nds
*.apcvpor

setups
build
Expand Down
25 changes: 25 additions & 0 deletions worlds/cv_por/Client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from typing import TYPE_CHECKING
import worlds._bizhawk as bizhawk
from worlds._bizhawk.client import BizHawkClient
from .Rom import world_version

if TYPE_CHECKING:
from worlds._bizhawk.context import BizHawkClientContext


class PoRClient(BizHawkClient):
game = "Castlevania: Portrait of Ruin"
system = ("NDS")
patch_suffix = ".apcvpor"
most_recent_connect: str = ""
client_version: str = world_version

def __init__(self) -> None:
super().__init__()

async def validate_rom(self, ctx: "BizHawkClientContext") -> bool:
return False


async def game_watcher(self, ctx: "BizHawkClientContext") -> None:
print("NOT DONE YET")
571 changes: 571 additions & 0 deletions worlds/cv_por/Items.py

Large diffs are not rendered by default.

297 changes: 297 additions & 0 deletions worlds/cv_por/Locations.py

Large diffs are not rendered by default.

164 changes: 164 additions & 0 deletions worlds/cv_por/Options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
from dataclasses import dataclass
from Options import PerGameCommonOptions, Choice, DefaultOnToggle, Range, NamedRange, Toggle, ExcludeLocations, OptionGroup


class Goal(Choice):
"""The goal for your game.
Brauner: Defeat Brauner in the studio portrait.
Dracula: Defeat Dracula in the throne room."""
display_name = "Goal"
option_brauner = 0
option_dracula = 1
default = 1


class RevealMap(DefaultOnToggle):
"""Start with the entire map visible."""
display_name = "Reveal Map"


class RevealBreakableWalls(Toggle):
"""Automatically reveals all breakable walls/objects."""
display_name = "Reveal Hidden Walls"


class NestofEvil(Choice):
"""The state of the Nest of Evil.
Vanilla: Nest of Evil has its original rewards, the two tome pages and Greatest Five.
Randomized: The three items in the Nest of Evil are random, and added to the item pool.
Required: You are required to clear the Nest of Evil before you can access your final boss.
Removed: The three items are added to the item pool, and the Nest of Evil is inaccessible."""
display_name = "Nest of Evil State"
option_vanilla = 0
option_randomized = 1
option_required = 2
option_removed = 3
default = 0


class BraunerRequired(DefaultOnToggle):
"""If enabled, you will be required to fight Brauner before you can access the Throne Room,
Of course, this won't do anything if the goal is set to Brauner."""
display_name = "Brauner Required"


class NestPortraits(Range):
"""How many Portraits are required to be cleared to access the underground passage
at the castle entrance."""
display_name = "Passage Portraits"
range_start = 0
range_end = 8
default = 8


class BraunerPortraits(Range):
"""How many of ANY portraits are required to be cleared to access Brauner's portrait."""
display_name = "Brauner Portraits"
range_start = 0
range_end = 8
default = 4


class DraculaPortraits(Range):
"""How many portraits are required to be cleared to access the Throne Room."""
display_name = "Throne Portraits"
range_start = 0
range_end = 8
default = 0


class ExperiencePercent(NamedRange): # TODO!!! IMPLEMENT
"""What percentage of EXP enemies give you. This is a percent of their original EXP amount."""
display_name = "Experience Percentage"
range_start = 0
range_end = 500
default = 100
special_range_names = {
"none": 0,
"half": 50,
"normal": 100,
"double": 200,
"quadruple": 400
}


class ShuffleWhip(Toggle):
"""If enabled, the True Vampire Killer will be added to the item pool,
and the Whip's Memory fight will grant you a random item.
Otherwise, it will be at its normal location."""
display_name = "Shuffle True Vampire Killer"


class PoRExcludeLocations(ExcludeLocations):
"""Prevent these locations from having an important item."""
default = frozenset({"The Throne Room: Above Throne Left", "The Throne Room: Above Throne Right", "The Throne Room: Great Stairs Left",
"The Throne Room: Great Stairs Center", "The Throne Room: Great Stairs Under Stairs", "The Throne Room: Great Stairs Hidden"})


class StartWithChangeCube(Toggle):
"""If enabled, you'll start with the Change Cube by default"""
display_name = "Start with Change Cube"


class AddExtraItems(Toggle):
"""If enabled, some items and spells that are otherwise only obtainable
in other modes will be added to the item pool, such as Puppet Master."""
display_name = "Add Extra Items"


class ExcludeOwlMorph(Toggle):
"""If enabled, Owl Morph will not be added to the item pool."""
display_name = "Exclude Owl Morph"


@dataclass
class PoROptions(PerGameCommonOptions):
goal: Goal
brauner_portraits: BraunerPortraits
dracula_portraits: DraculaPortraits
nest_portraits: NestPortraits
brauner_required: BraunerRequired
nest_of_evil_state: NestofEvil
shuffle_whip: ShuffleWhip
reveal_map: RevealMap
reveal_hidden_walls: RevealBreakableWalls
experience_percentage: ExperiencePercent
exclude_locations: PoRExcludeLocations
start_with_change_cube: StartWithChangeCube
add_extra_items: AddExtraItems
exclude_owl_morph: ExcludeOwlMorph


por_option_groups = [
OptionGroup("Goal Options", [
Goal,
BraunerPortraits,
DraculaPortraits,
BraunerRequired,

]),

OptionGroup("Nest of Evil Options", [
NestofEvil,
NestPortraits

]),

OptionGroup("Item Options", [
ShuffleWhip,
StartWithChangeCube,
AddExtraItems,
ExcludeOwlMorph

]),

OptionGroup("Enemy Settings", [
ExperiencePercent

]),

OptionGroup("Quality of Life", [
RevealMap,
RevealBreakableWalls
])
]
Loading
Loading