Skip to content

Commit 1cd4175

Browse files
authored
Merge pull request #1 from neocerber/feature-addSpiritSelection
Ender lilies: Feature add spirit selection
2 parents 63928aa + 8739704 commit 1cd4175

File tree

3 files changed

+93
-5
lines changed

3 files changed

+93
-5
lines changed

worlds/enderlilies/Options.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from typing import Dict, FrozenSet, Union
2+
from Options import Choice, Option, Toggle
3+
from BaseClasses import MultiWorld
4+
5+
6+
class ShuffleSlots(Toggle):
7+
display_name = "Shuffle Slots"
8+
9+
class ShuffleBGM(Toggle):
10+
display_name = "Shuffle Background Music"
11+
12+
class ShuffleEnemies(Toggle):
13+
display_name = "Shuffle Enemies"
14+
15+
class NewGamePlus(Toggle):
16+
display_name = "New Game Plus"
17+
18+
class ForceAncientSouls(Toggle):
19+
display_name = "Ancient Souls on starting spirit"
20+
21+
class MiniBossIncrementsChapter(Toggle):
22+
display_name = "Sub Spirits Increment Chapter"
23+
24+
class ShuffleUpgrades(Toggle):
25+
display_name = "Shuffle Upgrades"
26+
27+
class StartingSpirit(Choice):
28+
"""Defines which spirit you might start with. The starting spirit has infinite usage. Default option is Umbral Knight.
29+
30+
Vanilla: Umbral knight.
31+
Main: One of the main spirit (Gerrod, Silva, Julius, Ulv, Eleine, Hoenir, Faden, Siegrid
32+
Any: Any of the spirits.
33+
None: You will receive an item at the start but it can from any world.
34+
Warning: the logic currently assumes that you start with a spirit. It might make a world impossible. """
35+
display_name = "Starting spirits"
36+
option_vanilla = 0
37+
option_main = 1
38+
option_any = 2
39+
default = option_vanilla
40+
41+
el_options: Dict[str, type(Option)] = {
42+
# # Not added since not sure if the client can read it right now.
43+
# "shuffle_slots": ShuffleSlots,
44+
# "shuffle_bgm": ShuffleBGM,
45+
# "shuffle_enemies": ShuffleEnemies,
46+
# "new_game_plus": NewGamePlus,
47+
# "force_ancient_souls": ForceAncientSouls,
48+
# "mini_boss_incrememnts_chapter": MiniBossIncrementsChapter,
49+
# "shuffle_upgrades": ShuffleUpgrades,
50+
"starting_spirit": StartingSpirit,
51+
}
52+
53+
54+
def get_option_value(multiworld: MultiWorld, player: int, name: str) -> Union[int, FrozenSet]:
55+
if multiworld is None:
56+
return el_options[name].default
57+
58+
player_option = getattr(multiworld, name)[player]
59+
60+
return player_option.value

worlds/enderlilies/Rules.py

-1
Original file line numberDiff line numberDiff line change
@@ -777,7 +777,6 @@ def get_rules(p : int) -> Tuple[Dict[str, CollectionRule], Dict[str, ItemRule]]:
777777
}
778778

779779
items_rules : Dict[str, ItemRule] = {
780-
'starting_weapon' : lambda item : item.player == p and item.name.startswith('Spirit.'),
781780
}
782781

783782
return (locations_rules, items_rules)

worlds/enderlilies/__init__.py

+33-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
import os
33

44
from worlds.AutoWorld import World
5-
from BaseClasses import ItemClassification, Region, Item, Location
5+
from BaseClasses import ItemClassification, Region, Item, Location, MultiWorld
66
from worlds.generic.Rules import set_rule, add_item_rule
7-
from typing import Any, Dict
7+
from typing import Any, Dict, List
88

99
from .Items import items
1010
from .Locations import locations
1111
from .Rules import get_rules
1212
from .Names import names as el
13+
from .Options import el_options, get_option_value
1314

1415
ENDERLILIES = "Ender Lilies"
1516

@@ -24,6 +25,7 @@ class EnderLiliesWorld(World):
2425
Ender Lilies: QUIETUS OF THE KNIGHTS
2526
"""
2627
game = ENDERLILIES
28+
option_definitions = el_options
2729
location_name_to_id = { name: data.address for name, data in locations.items() }
2830
item_name_to_id = { name: data.code for name, data in items.items() }
2931

@@ -34,9 +36,12 @@ def create_item(self, item: str) -> EnderLiliesItem:
3436
return EnderLiliesItem(item, ItemClassification.progression, None, self.player)
3537

3638
def create_items(self) -> None:
39+
starting_item = assign_starting_item(self.multiworld, self.player, items)
40+
3741
for item, data in items.items():
38-
for i in range(data.count):
39-
self.multiworld.itempool.append(self.create_item(item))
42+
if item != starting_item:
43+
for i in range(data.count):
44+
self.multiworld.itempool.append(self.create_item(item))
4045

4146
def create_regions(self) -> None:
4247
regions = {
@@ -90,3 +95,27 @@ def fill_slot_data(self) -> Dict[str, Any]:
9095
else:
9196
slot_data[location.name] = f"AP.{location.address}"
9297
return slot_data
98+
99+
def assign_starting_item(multiworld: MultiWorld, player: int, items) -> str:
100+
non_local_items = multiworld.non_local_items[player].value
101+
102+
val = get_option_value(multiworld, player, "starting_spirit")
103+
if val == 0:
104+
spirit_list = ['Spirit.s5000']
105+
elif val == 1:
106+
spirit_list = [x for x in list(items.keys()) if x.startswith('Spirit.s5')]
107+
elif val == 2:
108+
spirit_list = [x for x in list(items.keys()) if x.startswith('Spirit.s')]
109+
110+
avail_spirit = sorted(item for item in spirit_list if item not in non_local_items)
111+
if not avail_spirit:
112+
raise Exception("At least one spirit must be local")
113+
114+
spirit_name = multiworld.random.choice(avail_spirit)
115+
116+
item = EnderLiliesItem(spirit_name, items[spirit_name].classification,
117+
items[spirit_name].code, player)
118+
119+
multiworld.get_location('starting_weapon', player).place_locked_item(item)
120+
121+
return spirit_name

0 commit comments

Comments
 (0)