Adding weights for filler and traps
This commit is contained in:
@@ -1,6 +1,14 @@
|
|||||||
|
import math
|
||||||
from BaseClasses import Region, Item, ItemClassification
|
from BaseClasses import Region, Item, ItemClassification
|
||||||
from .Locations import grinch_locations_to_id, grinch_locations, GrinchLocation, get_location_names_per_category
|
from .Locations import grinch_locations_to_id, grinch_locations, GrinchLocation, get_location_names_per_category
|
||||||
from .Items import grinch_items_to_id, GrinchItem, ALL_ITEMS_TABLE, MISC_ITEMS_TABLE, get_item_names_per_category, TRAPS_TABLE
|
from .Items import (
|
||||||
|
grinch_items_to_id,
|
||||||
|
GrinchItem,
|
||||||
|
ALL_ITEMS_TABLE,
|
||||||
|
MISC_ITEMS_TABLE,
|
||||||
|
get_item_names_per_category,
|
||||||
|
TRAPS_TABLE,
|
||||||
|
)
|
||||||
from .Regions import connect_regions
|
from .Regions import connect_regions
|
||||||
from .Rules import set_location_rules
|
from .Rules import set_location_rules
|
||||||
|
|
||||||
@@ -18,24 +26,25 @@ class GrinchWorld(World):
|
|||||||
game: ClassVar[str] = "The Grinch"
|
game: ClassVar[str] = "The Grinch"
|
||||||
options_dataclass = Options.GrinchOptions
|
options_dataclass = Options.GrinchOptions
|
||||||
options: Options.GrinchOptions
|
options: Options.GrinchOptions
|
||||||
topology_present = True #not an open world game, very linear
|
topology_present = True # not an open world game, very linear
|
||||||
item_name_to_id: ClassVar[dict[str,int]] = grinch_items_to_id()
|
item_name_to_id: ClassVar[dict[str, int]] = grinch_items_to_id()
|
||||||
location_name_to_id: ClassVar[dict[str,int]] = grinch_locations_to_id()
|
location_name_to_id: ClassVar[dict[str, int]] = grinch_locations_to_id()
|
||||||
required_client_version = (0, 6, 3)
|
required_client_version = (0, 6, 3)
|
||||||
item_name_groups = get_item_names_per_category()
|
item_name_groups = get_item_names_per_category()
|
||||||
location_name_groups = get_location_names_per_category()
|
location_name_groups = get_location_names_per_category()
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs): #Pulls __init__ function and takes control from there in BaseClasses.py
|
def __init__(self, *args, **kwargs): # Pulls __init__ function and takes control from there in BaseClasses.py
|
||||||
self.origin_region_name: str = "Mount Crumpit"
|
self.origin_region_name: str = "Mount Crumpit"
|
||||||
super(GrinchWorld, self).__init__(*args, **kwargs)
|
super(GrinchWorld, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def generate_early(self) -> None: #Special conditions changed before generation occurs
|
def generate_early(self) -> None: # Special conditions changed before generation occurs
|
||||||
if self.options.ring_link == 1 and self.options.unlimited_eggs == 1:
|
if self.options.ring_link == 1 and self.options.unlimited_eggs == 1:
|
||||||
raise OptionError("Cannot enable both unlimited rotten eggs and ring links. You can only enable one of these at a time." +
|
raise OptionError(
|
||||||
f"The following player's YAML needs to be fixed: {self.player_name}")
|
"Cannot enable both unlimited rotten eggs and ring links. You can only enable one of these at a time."
|
||||||
|
+ f"The following player's YAML needs to be fixed: {self.player_name}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def create_regions(self): # Generates all regions for the multiworld
|
||||||
def create_regions(self): #Generates all regions for the multiworld
|
|
||||||
for region_name in access_rules_dict.keys():
|
for region_name in access_rules_dict.keys():
|
||||||
self.multiworld.regions.append(Region(region_name, self.player, self.multiworld))
|
self.multiworld.regions.append(Region(region_name, self.player, self.multiworld))
|
||||||
self.multiworld.regions.append(Region("Mount Crumpit", self.player, self.multiworld))
|
self.multiworld.regions.append(Region("Mount Crumpit", self.player, self.multiworld))
|
||||||
@@ -47,12 +56,12 @@ class GrinchWorld(World):
|
|||||||
region.locations.append(entry)
|
region.locations.append(entry)
|
||||||
connect_regions(self)
|
connect_regions(self)
|
||||||
|
|
||||||
def create_item(self, item: str) -> GrinchItem: #Creates specific items on demand
|
def create_item(self, item: str) -> GrinchItem: # Creates specific items on demand
|
||||||
if item in ALL_ITEMS_TABLE.keys():
|
if item in ALL_ITEMS_TABLE.keys():
|
||||||
return GrinchItem(item, self.player, ALL_ITEMS_TABLE[item])
|
return GrinchItem(item, self.player, ALL_ITEMS_TABLE[item])
|
||||||
raise Exception(f"Invalid item name: {item}")
|
raise Exception(f"Invalid item name: {item}")
|
||||||
|
|
||||||
def create_items(self): #Generates all items for the multiworld
|
def create_items(self): # Generates all items for the multiworld
|
||||||
self_itempool: list[GrinchItem] = []
|
self_itempool: list[GrinchItem] = []
|
||||||
for item, data in ALL_ITEMS_TABLE.items():
|
for item, data in ALL_ITEMS_TABLE.items():
|
||||||
self_itempool.append(self.create_item(item))
|
self_itempool.append(self.create_item(item))
|
||||||
@@ -60,49 +69,55 @@ class GrinchWorld(World):
|
|||||||
for _ in range(3):
|
for _ in range(3):
|
||||||
self_itempool.append(self.create_item(item))
|
self_itempool.append(self.create_item(item))
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
#Get number of current unfilled locations
|
#Get number of current unfilled locations
|
||||||
unfilled_locations: int = (
|
unfilled_locations: int = (
|
||||||
len(self.multiworld.get_unfilled_locations(self.player)) - len(self_itempool)
|
len(self.multiworld.get_unfilled_locations(self.player)) - len(self_itempool)
|
||||||
)
|
)
|
||||||
|
=======
|
||||||
|
# Get number of current unfilled locations
|
||||||
|
unfilled_locations: int = (
|
||||||
|
len(self.multiworld.get_unfilled_locations(self.player)) - len(ALL_ITEMS_TABLE.keys()) - 3
|
||||||
|
)
|
||||||
|
|
||||||
|
filler_locations: int = math.floor(unfilled_locations * (1 - (self.options.trap_percentage / 100)))
|
||||||
|
trap_locations: int = math.floor(unfilled_locations * (self.options.trap_percentage / 100))
|
||||||
|
|
||||||
|
# This catches the extra 1 or 2 unfilled_locations that come up from the math.floor()
|
||||||
|
extra_locations = unfilled_locations - (filler_locations + trap_locations)
|
||||||
|
filler_locations != extra_locations
|
||||||
|
>>>>>>> 31333183 (Adding weights for filler and traps)
|
||||||
|
|
||||||
# Total available weight sum
|
# Total available weight sum
|
||||||
total_fillerweights = sum(self.options.filler_weight[filler] for filler in MISC_ITEMS_TABLE)
|
total_fillerweights = sum(self.options.filler_weight[filler] for filler in MISC_ITEMS_TABLE)
|
||||||
|
|
||||||
# Fill remaining locations according to weight ratio
|
# Fill remaining locations according to weight ratio
|
||||||
for filler in MISC_ITEMS_TABLE:
|
for filler in MISC_ITEMS_TABLE:
|
||||||
|
# This ratio is a decimal between 0 and 1, and when multiplied by 100 is the % of that filler
|
||||||
|
# item in the available unfilled locations
|
||||||
filler_weight_ratio = self.options.filler_weight[filler] / total_fillerweights
|
filler_weight_ratio = self.options.filler_weight[filler] / total_fillerweights
|
||||||
filler_count = round(unfilled_locations * filler_weight_ratio)
|
filler_count = round(filler_locations * filler_weight_ratio)
|
||||||
|
|
||||||
for _ in range(filler_count):
|
for _ in range(filler_count):
|
||||||
self_itempool.append(self.create_item(filler))
|
self_itempool.append(self.create_item(filler))
|
||||||
|
|
||||||
# Make sure we don't underfill (in case of rounding losses)
|
# # Make sure we don't underfill (in case of rounding losses)
|
||||||
while len(self_itempool) < unfilled_locations:
|
# while len(self_itempool) < unfilled_locations:
|
||||||
self_itempool.append(self.create_item(self.get_other_filler_item(list(MISC_ITEMS_TABLE.keys()))))
|
# self_itempool.append(self.create_item(self.get_other_filler_item(list(MISC_ITEMS_TABLE.keys()))))
|
||||||
|
|
||||||
# for _ in range(unfilled_locations):
|
|
||||||
# self_itempool.append(self.create_item((self.get_other_filler_item(list(MISC_ITEMS_TABLE.keys())))))
|
|
||||||
# self.multiworld.itempool += self_itempool
|
|
||||||
|
|
||||||
# Total available weight sum
|
# Total available weight sum
|
||||||
if self.options.trap_percentage > 0:
|
if self.options.trap_percentage > 0:
|
||||||
total_trapweights = sum(self.options.trap_weight[trap] for trap in TRAPS_TABLE)
|
total_trapweights = sum(self.options.trap_weight[trap] for trap in TRAPS_TABLE)
|
||||||
|
|
||||||
if total_trapweights <= 0:
|
if self.options.trap_percentage > 0 && total_trapweights <= 0:
|
||||||
raise Exception("ERROR: Traps are enabled, but all trap weights are zero or undefined")
|
raise Exception("ERROR: Traps are enabled, but all trap weights are zero or undefined")
|
||||||
|
|
||||||
# Total traps to generate (percentage of unfilled locations)
|
|
||||||
total_traps = round(unfilled_locations * (self.options.trap_percentage / 100))
|
|
||||||
|
|
||||||
for trap in TRAPS_TABLE:
|
for trap in TRAPS_TABLE:
|
||||||
trap_weight_ratio = self.options.trap_weight[trap] / total_trapweights
|
trap_weight_ratio = self.options.trap_weight[trap] / total_trapweights
|
||||||
trap_count = round(total_traps * trap_weight_ratio)
|
trap_count = round(trap_locations * trap_weight_ratio)
|
||||||
for _ in range(trap_count):
|
for _ in range(trap_count):
|
||||||
self_itempool.append(self.create_item(trap))
|
self_itempool.append(self.create_item(trap))
|
||||||
|
|
||||||
# Handle rounding differences
|
|
||||||
while len(self_itempool) < total_traps:
|
|
||||||
self_itempool.append(self.create_item(self.get_other_filler_item(list(TRAPS_TABLE.keys()))))
|
|
||||||
|
|
||||||
self.multiworld.itempool += self_itempool
|
self.multiworld.itempool += self_itempool
|
||||||
|
|
||||||
def set_rules(self):
|
def set_rules(self):
|
||||||
@@ -120,4 +135,4 @@ class GrinchWorld(World):
|
|||||||
|
|
||||||
def generate_output(self, output_directory: str) -> None:
|
def generate_output(self, output_directory: str) -> None:
|
||||||
# print("")
|
# print("")
|
||||||
pass
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user