mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
id Tech Games: Customizable ammo capacity (#3565)
* Doom, Doom 2, Heretic: customizable ammo capacity * Do not progression balance capacity up items * Prog fill still doesn't agree, just go with our original idea * Clean up the new options a bit - Gave all options a consistent and easily readable naming scheme (`max_ammo_<type>` and `added_ammo_<type>`) - Don't show the new options in the spoiler log, as they do not affect logic - Fix the Doom games' Split Backpack option accidentally referring to Heretic's Bag of Holding The logging change across all three games is incidental, as at some point I did run into that condition by happenstance and it turns out that it throws an exception due to bad formatting if it's reached * Do the visibility change for Heretic as well * Update required client version * Remove spoiler log restriction on options * Remove Visibility import now made redundant
This commit is contained in:
@@ -650,8 +650,8 @@ item_table: Dict[int, ItemDict] = {
|
||||
'doom_type': 2006,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
350106: {'classification': ItemClassification.progression,
|
||||
'count': 1,
|
||||
350106: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Backpack',
|
||||
'doom_type': 8,
|
||||
'episode': -1,
|
||||
@@ -1160,6 +1160,30 @@ item_table: Dict[int, ItemDict] = {
|
||||
'doom_type': 2026,
|
||||
'episode': 4,
|
||||
'map': 9},
|
||||
350191: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Bullet capacity',
|
||||
'doom_type': 65001,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
350192: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Shell capacity',
|
||||
'doom_type': 65002,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
350193: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Energy cell capacity',
|
||||
'doom_type': 65003,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
350194: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Rocket capacity',
|
||||
'doom_type': 65004,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
from Options import PerGameCommonOptions, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool
|
||||
from Options import PerGameCommonOptions, Range, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@@ -144,6 +144,84 @@ class Episode4(Toggle):
|
||||
display_name = "Episode 4"
|
||||
|
||||
|
||||
class SplitBackpack(Toggle):
|
||||
"""Split the Backpack into four individual items, each one increasing ammo capacity for one type of weapon only."""
|
||||
display_name = "Split Backpack"
|
||||
|
||||
|
||||
class BackpackCount(Range):
|
||||
"""How many Backpacks will be available.
|
||||
If Split Backpack is set, this will be the number of each capacity upgrade available."""
|
||||
display_name = "Backpack Count"
|
||||
range_start = 0
|
||||
range_end = 10
|
||||
default = 1
|
||||
|
||||
|
||||
class MaxAmmoBullets(Range):
|
||||
"""Set the starting ammo capacity for bullets."""
|
||||
display_name = "Max Ammo - Bullets"
|
||||
range_start = 200
|
||||
range_end = 999
|
||||
default = 200
|
||||
|
||||
|
||||
class MaxAmmoShells(Range):
|
||||
"""Set the starting ammo capacity for shotgun shells."""
|
||||
display_name = "Max Ammo - Shells"
|
||||
range_start = 50
|
||||
range_end = 999
|
||||
default = 50
|
||||
|
||||
|
||||
class MaxAmmoRockets(Range):
|
||||
"""Set the starting ammo capacity for rockets."""
|
||||
display_name = "Max Ammo - Rockets"
|
||||
range_start = 50
|
||||
range_end = 999
|
||||
default = 50
|
||||
|
||||
|
||||
class MaxAmmoEnergyCells(Range):
|
||||
"""Set the starting ammo capacity for energy cells."""
|
||||
display_name = "Max Ammo - Energy Cells"
|
||||
range_start = 300
|
||||
range_end = 999
|
||||
default = 300
|
||||
|
||||
|
||||
class AddedAmmoBullets(Range):
|
||||
"""Set the amount of bullet capacity added when collecting a backpack or capacity upgrade."""
|
||||
display_name = "Added Ammo - Bullets"
|
||||
range_start = 20
|
||||
range_end = 999
|
||||
default = 200
|
||||
|
||||
|
||||
class AddedAmmoShells(Range):
|
||||
"""Set the amount of shotgun shell capacity added when collecting a backpack or capacity upgrade."""
|
||||
display_name = "Added Ammo - Shells"
|
||||
range_start = 5
|
||||
range_end = 999
|
||||
default = 50
|
||||
|
||||
|
||||
class AddedAmmoRockets(Range):
|
||||
"""Set the amount of rocket capacity added when collecting a backpack or capacity upgrade."""
|
||||
display_name = "Added Ammo - Rockets"
|
||||
range_start = 5
|
||||
range_end = 999
|
||||
default = 50
|
||||
|
||||
|
||||
class AddedAmmoEnergyCells(Range):
|
||||
"""Set the amount of energy cell capacity added when collecting a backpack or capacity upgrade."""
|
||||
display_name = "Added Ammo - Energy Cells"
|
||||
range_start = 30
|
||||
range_end = 999
|
||||
default = 300
|
||||
|
||||
|
||||
@dataclass
|
||||
class DOOM1993Options(PerGameCommonOptions):
|
||||
start_inventory_from_pool: StartInventoryPool
|
||||
@@ -163,3 +241,14 @@ class DOOM1993Options(PerGameCommonOptions):
|
||||
episode3: Episode3
|
||||
episode4: Episode4
|
||||
|
||||
split_backpack: SplitBackpack
|
||||
backpack_count: BackpackCount
|
||||
max_ammo_bullets: MaxAmmoBullets
|
||||
max_ammo_shells: MaxAmmoShells
|
||||
max_ammo_rockets: MaxAmmoRockets
|
||||
max_ammo_energy_cells: MaxAmmoEnergyCells
|
||||
added_ammo_bullets: AddedAmmoBullets
|
||||
added_ammo_shells: AddedAmmoShells
|
||||
added_ammo_rockets: AddedAmmoRockets
|
||||
added_ammo_energy_cells: AddedAmmoEnergyCells
|
||||
|
||||
|
@@ -42,7 +42,7 @@ class DOOM1993World(World):
|
||||
options: DOOM1993Options
|
||||
game = "DOOM 1993"
|
||||
web = DOOM1993Web()
|
||||
required_client_version = (0, 3, 9)
|
||||
required_client_version = (0, 5, 0) # 1.2.0-prerelease or higher
|
||||
|
||||
item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()}
|
||||
item_name_groups = Items.item_name_groups
|
||||
@@ -204,6 +204,15 @@ class DOOM1993World(World):
|
||||
count = item["count"] if item["name"] not in self.starting_level_for_episode else item["count"] - 1
|
||||
itempool += [self.create_item(item["name"]) for _ in range(count)]
|
||||
|
||||
# Backpack(s) based on options
|
||||
if self.options.split_backpack.value:
|
||||
itempool += [self.create_item("Bullet capacity") for _ in range(self.options.backpack_count.value)]
|
||||
itempool += [self.create_item("Shell capacity") for _ in range(self.options.backpack_count.value)]
|
||||
itempool += [self.create_item("Energy cell capacity") for _ in range(self.options.backpack_count.value)]
|
||||
itempool += [self.create_item("Rocket capacity") for _ in range(self.options.backpack_count.value)]
|
||||
else:
|
||||
itempool += [self.create_item("Backpack") for _ in range(self.options.backpack_count.value)]
|
||||
|
||||
# Place end level items in locked locations
|
||||
for map_name in Maps.map_names:
|
||||
loc_name = map_name + " - Exit"
|
||||
@@ -265,7 +274,7 @@ class DOOM1993World(World):
|
||||
# Was balanced for 3 episodes (We added 4th episode, but keep same ratio)
|
||||
count = min(remaining_loc, max(1, int(round(self.items_ratio[item_name] * ep_count / 3))))
|
||||
if count == 0:
|
||||
logger.warning("Warning, no ", item_name, " will be placed.")
|
||||
logger.warning(f"Warning, no {item_name} will be placed.")
|
||||
return
|
||||
|
||||
for i in range(count):
|
||||
@@ -281,4 +290,14 @@ class DOOM1993World(World):
|
||||
# an older version, the player would end up stuck.
|
||||
slot_data["two_ways_keydoors"] = True
|
||||
|
||||
# Send slot data for ammo capacity values; this must be generic because Heretic uses it too
|
||||
slot_data["ammo1start"] = self.options.max_ammo_bullets.value
|
||||
slot_data["ammo2start"] = self.options.max_ammo_shells.value
|
||||
slot_data["ammo3start"] = self.options.max_ammo_energy_cells.value
|
||||
slot_data["ammo4start"] = self.options.max_ammo_rockets.value
|
||||
slot_data["ammo1add"] = self.options.added_ammo_bullets.value
|
||||
slot_data["ammo2add"] = self.options.added_ammo_shells.value
|
||||
slot_data["ammo3add"] = self.options.added_ammo_energy_cells.value
|
||||
slot_data["ammo4add"] = self.options.added_ammo_rockets.value
|
||||
|
||||
return slot_data
|
||||
|
@@ -56,8 +56,8 @@ item_table: Dict[int, ItemDict] = {
|
||||
'doom_type': 82,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
360007: {'classification': ItemClassification.progression,
|
||||
'count': 1,
|
||||
360007: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Backpack',
|
||||
'doom_type': 8,
|
||||
'episode': -1,
|
||||
@@ -1058,6 +1058,30 @@ item_table: Dict[int, ItemDict] = {
|
||||
'doom_type': 2026,
|
||||
'episode': 4,
|
||||
'map': 2},
|
||||
360600: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Bullet capacity',
|
||||
'doom_type': 65001,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
360601: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Shell capacity',
|
||||
'doom_type': 65002,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
360602: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Energy cell capacity',
|
||||
'doom_type': 65003,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
360603: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Rocket capacity',
|
||||
'doom_type': 65004,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import typing
|
||||
|
||||
from Options import PerGameCommonOptions, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool
|
||||
from Options import PerGameCommonOptions, Range, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@@ -136,6 +136,84 @@ class SecretLevels(Toggle):
|
||||
display_name = "Secret Levels"
|
||||
|
||||
|
||||
class SplitBackpack(Toggle):
|
||||
"""Split the Backpack into four individual items, each one increasing ammo capacity for one type of weapon only."""
|
||||
display_name = "Split Backpack"
|
||||
|
||||
|
||||
class BackpackCount(Range):
|
||||
"""How many Backpacks will be available.
|
||||
If Split Backpack is set, this will be the number of each capacity upgrade available."""
|
||||
display_name = "Backpack Count"
|
||||
range_start = 0
|
||||
range_end = 10
|
||||
default = 1
|
||||
|
||||
|
||||
class MaxAmmoBullets(Range):
|
||||
"""Set the starting ammo capacity for bullets."""
|
||||
display_name = "Max Ammo - Bullets"
|
||||
range_start = 200
|
||||
range_end = 999
|
||||
default = 200
|
||||
|
||||
|
||||
class MaxAmmoShells(Range):
|
||||
"""Set the starting ammo capacity for shotgun shells."""
|
||||
display_name = "Max Ammo - Shells"
|
||||
range_start = 50
|
||||
range_end = 999
|
||||
default = 50
|
||||
|
||||
|
||||
class MaxAmmoRockets(Range):
|
||||
"""Set the starting ammo capacity for rockets."""
|
||||
display_name = "Max Ammo - Rockets"
|
||||
range_start = 50
|
||||
range_end = 999
|
||||
default = 50
|
||||
|
||||
|
||||
class MaxAmmoEnergyCells(Range):
|
||||
"""Set the starting ammo capacity for energy cells."""
|
||||
display_name = "Max Ammo - Energy Cells"
|
||||
range_start = 300
|
||||
range_end = 999
|
||||
default = 300
|
||||
|
||||
|
||||
class AddedAmmoBullets(Range):
|
||||
"""Set the amount of bullet capacity added when collecting a backpack or capacity upgrade."""
|
||||
display_name = "Added Ammo - Bullets"
|
||||
range_start = 20
|
||||
range_end = 999
|
||||
default = 200
|
||||
|
||||
|
||||
class AddedAmmoShells(Range):
|
||||
"""Set the amount of shotgun shell capacity added when collecting a backpack or capacity upgrade."""
|
||||
display_name = "Added Ammo - Shells"
|
||||
range_start = 5
|
||||
range_end = 999
|
||||
default = 50
|
||||
|
||||
|
||||
class AddedAmmoRockets(Range):
|
||||
"""Set the amount of rocket capacity added when collecting a backpack or capacity upgrade."""
|
||||
display_name = "Added Ammo - Rockets"
|
||||
range_start = 5
|
||||
range_end = 999
|
||||
default = 50
|
||||
|
||||
|
||||
class AddedAmmoEnergyCells(Range):
|
||||
"""Set the amount of energy cell capacity added when collecting a backpack or capacity upgrade."""
|
||||
display_name = "Added Ammo - Energy Cells"
|
||||
range_start = 30
|
||||
range_end = 999
|
||||
default = 300
|
||||
|
||||
|
||||
@dataclass
|
||||
class DOOM2Options(PerGameCommonOptions):
|
||||
start_inventory_from_pool: StartInventoryPool
|
||||
@@ -153,3 +231,14 @@ class DOOM2Options(PerGameCommonOptions):
|
||||
episode2: Episode2
|
||||
episode3: Episode3
|
||||
episode4: SecretLevels
|
||||
|
||||
split_backpack: SplitBackpack
|
||||
backpack_count: BackpackCount
|
||||
max_ammo_bullets: MaxAmmoBullets
|
||||
max_ammo_shells: MaxAmmoShells
|
||||
max_ammo_rockets: MaxAmmoRockets
|
||||
max_ammo_energy_cells: MaxAmmoEnergyCells
|
||||
added_ammo_bullets: AddedAmmoBullets
|
||||
added_ammo_shells: AddedAmmoShells
|
||||
added_ammo_rockets: AddedAmmoRockets
|
||||
added_ammo_energy_cells: AddedAmmoEnergyCells
|
||||
|
@@ -43,7 +43,7 @@ class DOOM2World(World):
|
||||
options: DOOM2Options
|
||||
game = "DOOM II"
|
||||
web = DOOM2Web()
|
||||
required_client_version = (0, 3, 9)
|
||||
required_client_version = (0, 5, 0) # 1.2.0-prerelease or higher
|
||||
|
||||
item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()}
|
||||
item_name_groups = Items.item_name_groups
|
||||
@@ -196,6 +196,15 @@ class DOOM2World(World):
|
||||
count = item["count"] if item["name"] not in self.starting_level_for_episode else item["count"] - 1
|
||||
itempool += [self.create_item(item["name"]) for _ in range(count)]
|
||||
|
||||
# Backpack(s) based on options
|
||||
if self.options.split_backpack.value:
|
||||
itempool += [self.create_item("Bullet capacity") for _ in range(self.options.backpack_count.value)]
|
||||
itempool += [self.create_item("Shell capacity") for _ in range(self.options.backpack_count.value)]
|
||||
itempool += [self.create_item("Energy cell capacity") for _ in range(self.options.backpack_count.value)]
|
||||
itempool += [self.create_item("Rocket capacity") for _ in range(self.options.backpack_count.value)]
|
||||
else:
|
||||
itempool += [self.create_item("Backpack") for _ in range(self.options.backpack_count.value)]
|
||||
|
||||
# Place end level items in locked locations
|
||||
for map_name in Maps.map_names:
|
||||
loc_name = map_name + " - Exit"
|
||||
@@ -258,11 +267,23 @@ class DOOM2World(World):
|
||||
# Was balanced based on DOOM 1993's first 3 episodes
|
||||
count = min(remaining_loc, max(1, int(round(self.items_ratio[item_name] * ep_count / 3))))
|
||||
if count == 0:
|
||||
logger.warning("Warning, no ", item_name, " will be placed.")
|
||||
logger.warning(f"Warning, no {item_name} will be placed.")
|
||||
return
|
||||
|
||||
for i in range(count):
|
||||
itempool.append(self.create_item(item_name))
|
||||
|
||||
def fill_slot_data(self) -> Dict[str, Any]:
|
||||
return self.options.as_dict("difficulty", "random_monsters", "random_pickups", "random_music", "flip_levels", "allow_death_logic", "pro", "death_link", "reset_level_on_death", "episode1", "episode2", "episode3", "episode4")
|
||||
slot_data = self.options.as_dict("difficulty", "random_monsters", "random_pickups", "random_music", "flip_levels", "allow_death_logic", "pro", "death_link", "reset_level_on_death", "episode1", "episode2", "episode3", "episode4")
|
||||
|
||||
# Send slot data for ammo capacity values; this must be generic because Heretic uses it too
|
||||
slot_data["ammo1start"] = self.options.max_ammo_bullets.value
|
||||
slot_data["ammo2start"] = self.options.max_ammo_shells.value
|
||||
slot_data["ammo3start"] = self.options.max_ammo_energy_cells.value
|
||||
slot_data["ammo4start"] = self.options.max_ammo_rockets.value
|
||||
slot_data["ammo1add"] = self.options.added_ammo_bullets.value
|
||||
slot_data["ammo2add"] = self.options.added_ammo_shells.value
|
||||
slot_data["ammo3add"] = self.options.added_ammo_energy_cells.value
|
||||
slot_data["ammo4add"] = self.options.added_ammo_rockets.value
|
||||
|
||||
return slot_data
|
||||
|
@@ -50,8 +50,8 @@ item_table: Dict[int, ItemDict] = {
|
||||
'doom_type': 2004,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
370006: {'classification': ItemClassification.progression,
|
||||
'count': 1,
|
||||
370006: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Bag of Holding',
|
||||
'doom_type': 8,
|
||||
'episode': -1,
|
||||
@@ -1592,6 +1592,42 @@ item_table: Dict[int, ItemDict] = {
|
||||
'doom_type': 35,
|
||||
'episode': 5,
|
||||
'map': 9},
|
||||
370600: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Crystal Capacity',
|
||||
'doom_type': 65001,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
370601: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Ethereal Arrow Capacity',
|
||||
'doom_type': 65002,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
370602: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Claw Orb Capacity',
|
||||
'doom_type': 65003,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
370603: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Rune Capacity',
|
||||
'doom_type': 65004,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
370604: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Flame Orb Capacity',
|
||||
'doom_type': 65005,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
370605: {'classification': ItemClassification.useful,
|
||||
'count': 0,
|
||||
'name': 'Mace Sphere Capacity',
|
||||
'doom_type': 65006,
|
||||
'episode': -1,
|
||||
'map': -1},
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
from Options import PerGameCommonOptions, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool
|
||||
from Options import PerGameCommonOptions, Range, Choice, Toggle, DeathLink, DefaultOnToggle, StartInventoryPool
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@@ -144,6 +144,116 @@ class Episode5(Toggle):
|
||||
display_name = "Episode 5"
|
||||
|
||||
|
||||
class SplitBagOfHolding(Toggle):
|
||||
"""Split the Bag of Holding into six individual items, each one increasing ammo capacity for one type of weapon only."""
|
||||
display_name = "Split Bag of Holding"
|
||||
|
||||
|
||||
class BagOfHoldingCount(Range):
|
||||
"""How many Bags of Holding will be available.
|
||||
If Split Bag of Holding is set, this will be the number of each capacity upgrade available."""
|
||||
display_name = "Bag of Holding Count"
|
||||
range_start = 0
|
||||
range_end = 10
|
||||
default = 1
|
||||
|
||||
|
||||
class MaxAmmoCrystals(Range):
|
||||
"""Set the starting ammo capacity for crystals (Elven Wand ammo)."""
|
||||
display_name = "Max Ammo - Crystals"
|
||||
range_start = 100
|
||||
range_end = 999
|
||||
default = 100
|
||||
|
||||
|
||||
class MaxAmmoArrows(Range):
|
||||
"""Set the starting ammo capacity for arrows (Ethereal Crossbow ammo)."""
|
||||
display_name = "Max Ammo - Arrows"
|
||||
range_start = 50
|
||||
range_end = 999
|
||||
default = 50
|
||||
|
||||
|
||||
class MaxAmmoClawOrbs(Range):
|
||||
"""Set the starting ammo capacity for claw orbs (Dragon Claw ammo)."""
|
||||
display_name = "Max Ammo - Claw Orbs"
|
||||
range_start = 200
|
||||
range_end = 999
|
||||
default = 200
|
||||
|
||||
|
||||
class MaxAmmoRunes(Range):
|
||||
"""Set the starting ammo capacity for runes (Hellstaff ammo)."""
|
||||
display_name = "Max Ammo - Runes"
|
||||
range_start = 200
|
||||
range_end = 999
|
||||
default = 200
|
||||
|
||||
|
||||
class MaxAmmoFlameOrbs(Range):
|
||||
"""Set the starting ammo capacity for flame orbs (Phoenix Rod ammo)."""
|
||||
display_name = "Max Ammo - Flame Orbs"
|
||||
range_start = 20
|
||||
range_end = 999
|
||||
default = 20
|
||||
|
||||
|
||||
class MaxAmmoSpheres(Range):
|
||||
"""Set the starting ammo capacity for spheres (Firemace ammo)."""
|
||||
display_name = "Max Ammo - Spheres"
|
||||
range_start = 150
|
||||
range_end = 999
|
||||
default = 150
|
||||
|
||||
|
||||
class AddedAmmoCrystals(Range):
|
||||
"""Set the amount of crystal capacity gained when collecting a bag of holding or a capacity upgrade."""
|
||||
display_name = "Added Ammo - Crystals"
|
||||
range_start = 10
|
||||
range_end = 999
|
||||
default = 100
|
||||
|
||||
|
||||
class AddedAmmoArrows(Range):
|
||||
"""Set the amount of arrow capacity gained when collecting a bag of holding or a capacity upgrade."""
|
||||
display_name = "Added Ammo - Arrows"
|
||||
range_start = 5
|
||||
range_end = 999
|
||||
default = 50
|
||||
|
||||
|
||||
class AddedAmmoClawOrbs(Range):
|
||||
"""Set the amount of claw orb capacity gained when collecting a bag of holding or a capacity upgrade."""
|
||||
display_name = "Added Ammo - Claw Orbs"
|
||||
range_start = 20
|
||||
range_end = 999
|
||||
default = 200
|
||||
|
||||
|
||||
class AddedAmmoRunes(Range):
|
||||
"""Set the amount of rune capacity gained when collecting a bag of holding or a capacity upgrade."""
|
||||
display_name = "Added Ammo - Runes"
|
||||
range_start = 20
|
||||
range_end = 999
|
||||
default = 200
|
||||
|
||||
|
||||
class AddedAmmoFlameOrbs(Range):
|
||||
"""Set the amount of flame orb capacity gained when collecting a bag of holding or a capacity upgrade."""
|
||||
display_name = "Added Ammo - Flame Orbs"
|
||||
range_start = 2
|
||||
range_end = 999
|
||||
default = 20
|
||||
|
||||
|
||||
class AddedAmmoSpheres(Range):
|
||||
"""Set the amount of sphere capacity gained when collecting a bag of holding or a capacity upgrade."""
|
||||
display_name = "Added Ammo - Spheres"
|
||||
range_start = 15
|
||||
range_end = 999
|
||||
default = 150
|
||||
|
||||
|
||||
@dataclass
|
||||
class HereticOptions(PerGameCommonOptions):
|
||||
start_inventory_from_pool: StartInventoryPool
|
||||
@@ -163,3 +273,18 @@ class HereticOptions(PerGameCommonOptions):
|
||||
episode3: Episode3
|
||||
episode4: Episode4
|
||||
episode5: Episode5
|
||||
|
||||
split_bag_of_holding: SplitBagOfHolding
|
||||
bag_of_holding_count: BagOfHoldingCount
|
||||
max_ammo_crystals: MaxAmmoCrystals
|
||||
max_ammo_arrows: MaxAmmoArrows
|
||||
max_ammo_claw_orbs: MaxAmmoClawOrbs
|
||||
max_ammo_runes: MaxAmmoRunes
|
||||
max_ammo_flame_orbs: MaxAmmoFlameOrbs
|
||||
max_ammo_spheres: MaxAmmoSpheres
|
||||
added_ammo_crystals: AddedAmmoCrystals
|
||||
added_ammo_arrows: AddedAmmoArrows
|
||||
added_ammo_claw_orbs: AddedAmmoClawOrbs
|
||||
added_ammo_runes: AddedAmmoRunes
|
||||
added_ammo_flame_orbs: AddedAmmoFlameOrbs
|
||||
added_ammo_spheres: AddedAmmoSpheres
|
||||
|
@@ -695,13 +695,11 @@ def set_episode5_rules(player, multiworld, pro):
|
||||
state.has("Phoenix Rod", player, 1) and
|
||||
state.has("Firemace", player, 1) and
|
||||
state.has("Hellstaff", player, 1) and
|
||||
state.has("Gauntlets of the Necromancer", player, 1) and
|
||||
state.has("Bag of Holding", player, 1))
|
||||
state.has("Gauntlets of the Necromancer", player, 1))
|
||||
|
||||
# Skein of D'Sparil (E5M9)
|
||||
set_rule(multiworld.get_entrance("Hub -> Skein of D'Sparil (E5M9) Main", player), lambda state:
|
||||
state.has("Skein of D'Sparil (E5M9)", player, 1) and
|
||||
state.has("Bag of Holding", player, 1) and
|
||||
state.has("Hellstaff", player, 1) and
|
||||
state.has("Phoenix Rod", player, 1) and
|
||||
state.has("Dragon Claw", player, 1) and
|
||||
|
@@ -41,7 +41,7 @@ class HereticWorld(World):
|
||||
options: HereticOptions
|
||||
game = "Heretic"
|
||||
web = HereticWeb()
|
||||
required_client_version = (0, 3, 9)
|
||||
required_client_version = (0, 5, 0) # 1.2.0-prerelease or higher
|
||||
|
||||
item_name_to_id = {data["name"]: item_id for item_id, data in Items.item_table.items()}
|
||||
item_name_groups = Items.item_name_groups
|
||||
@@ -206,6 +206,17 @@ class HereticWorld(World):
|
||||
count = item["count"] if item["name"] not in self.starting_level_for_episode else item["count"] - 1
|
||||
itempool += [self.create_item(item["name"]) for _ in range(count)]
|
||||
|
||||
# Bag(s) of Holding based on options
|
||||
if self.options.split_bag_of_holding.value:
|
||||
itempool += [self.create_item("Crystal Capacity") for _ in range(self.options.bag_of_holding_count.value)]
|
||||
itempool += [self.create_item("Ethereal Arrow Capacity") for _ in range(self.options.bag_of_holding_count.value)]
|
||||
itempool += [self.create_item("Claw Orb Capacity") for _ in range(self.options.bag_of_holding_count.value)]
|
||||
itempool += [self.create_item("Rune Capacity") for _ in range(self.options.bag_of_holding_count.value)]
|
||||
itempool += [self.create_item("Flame Orb Capacity") for _ in range(self.options.bag_of_holding_count.value)]
|
||||
itempool += [self.create_item("Mace Sphere Capacity") for _ in range(self.options.bag_of_holding_count.value)]
|
||||
else:
|
||||
itempool += [self.create_item("Bag of Holding") for _ in range(self.options.bag_of_holding_count.value)]
|
||||
|
||||
# Place end level items in locked locations
|
||||
for map_name in Maps.map_names:
|
||||
loc_name = map_name + " - Exit"
|
||||
@@ -274,7 +285,7 @@ class HereticWorld(World):
|
||||
episode_count = self.get_episode_count()
|
||||
count = min(remaining_loc, max(1, self.items_ratio[item_name] * episode_count))
|
||||
if count == 0:
|
||||
logger.warning("Warning, no " + item_name + " will be placed.")
|
||||
logger.warning(f"Warning, no {item_name} will be placed.")
|
||||
return
|
||||
|
||||
for i in range(count):
|
||||
@@ -290,4 +301,18 @@ class HereticWorld(World):
|
||||
slot_data["episode4"] = self.included_episodes[3]
|
||||
slot_data["episode5"] = self.included_episodes[4]
|
||||
|
||||
# Send slot data for ammo capacity values; this must be generic because Doom uses it too
|
||||
slot_data["ammo1start"] = self.options.max_ammo_crystals.value
|
||||
slot_data["ammo2start"] = self.options.max_ammo_arrows.value
|
||||
slot_data["ammo3start"] = self.options.max_ammo_claw_orbs.value
|
||||
slot_data["ammo4start"] = self.options.max_ammo_runes.value
|
||||
slot_data["ammo5start"] = self.options.max_ammo_flame_orbs.value
|
||||
slot_data["ammo6start"] = self.options.max_ammo_spheres.value
|
||||
slot_data["ammo1add"] = self.options.added_ammo_crystals.value
|
||||
slot_data["ammo2add"] = self.options.added_ammo_arrows.value
|
||||
slot_data["ammo3add"] = self.options.added_ammo_claw_orbs.value
|
||||
slot_data["ammo4add"] = self.options.added_ammo_runes.value
|
||||
slot_data["ammo5add"] = self.options.added_ammo_flame_orbs.value
|
||||
slot_data["ammo6add"] = self.options.added_ammo_spheres.value
|
||||
|
||||
return slot_data
|
||||
|
Reference in New Issue
Block a user