diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000000..3f991ef96aa1 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,14 @@ +name: Test apworld +on: + push: + pull_request: + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - uses: Eijebong/ap-actions/ap-tests@main + with: + apworld-path: worlds/sims4 + ap-version: latest + python-version: '3.12' \ No newline at end of file diff --git a/worlds/sims4/Items.py b/worlds/sims4/Items.py index e9670b592fc1..3b6761e986e7 100644 --- a/worlds/sims4/Items.py +++ b/worlds/sims4/Items.py @@ -5,6 +5,7 @@ from .Names import SkillNames, JunkNames, UsefulNames from .Names.DLC import ExpansionNames, GamePackNames, StuffNames + class ItemDict(TypedDict): classification: ItemClassification count: int @@ -24,14 +25,21 @@ class Sims4Item(Item): skills_table: dict[int, ItemDict] = {} + +class SkillConfigError(ValueError): + """Raised when skill configuration is invalid.""" + + def add_skill(skill_name: str, expansion: str, max_level: int) -> int: + if max_level < 2: + raise SkillConfigError(f"max_level must be at least 2, got {max_level}") if skills_table: skill_id = max(skills_table.keys()) + 1 else: skill_id = 0x7334001 skills_table[skill_id] = { - "name": f"{skill_name}", + "name": skill_name, "classification": ItemClassification.progression, "count": max_level - 2, "tech_type": "Skill", @@ -39,6 +47,7 @@ def add_skill(skill_name: str, expansion: str, max_level: int) -> int: } return skill_id + add_skill(SkillNames.base_skill_comedy, ExpansionNames.base, 10) add_skill(SkillNames.base_skill_guitar, ExpansionNames.base, 10) add_skill(SkillNames.base_skill_logic, ExpansionNames.base, 10) @@ -80,7 +89,7 @@ def add_skill(skill_name: str, expansion: str, max_level: int) -> int: add_skill(SkillNames.du_robotics_skill, ExpansionNames.discover_university, 10) add_skill(SkillNames.el_fabrication_skill, ExpansionNames.eco_lifestyle, 10) add_skill(SkillNames.el_juicefizzing_skill, ExpansionNames.eco_lifestyle, 5) -add_skill(SkillNames.nk_knitting_skill, StuffNames.nifty_knitting, 10) +add_skill(SkillNames.nk_knitting_skill, StuffNames.nifty_knitting, 10) add_skill(SkillNames.sy_rock_climbing_skill, ExpansionNames.snowy_escape, 10) add_skill(SkillNames.sy_skiing_skill, ExpansionNames.snowy_escape, 10) add_skill(SkillNames.sy_snowboarding_skill, ExpansionNames.snowy_escape, 10) @@ -97,7 +106,7 @@ def add_skill(skill_name: str, expansion: str, max_level: int) -> int: add_skill(SkillNames.ebn_apothecary_skill, ExpansionNames.enchanted_by_nature, 10) add_skill(SkillNames.ebn_natural_living_skill, ExpansionNames.enchanted_by_nature, 10) -useful_table = { +useful_table: dict[int, ItemDict] = { 0x733400FF: {'classification': ItemClassification.useful, 'count': 4, 'name': UsefulNames.skill_gain_boost, @@ -106,7 +115,7 @@ def add_skill(skill_name: str, expansion: str, max_level: int) -> int: } -junk_table = { +junk_table: dict[int, ItemDict] = { 0x73340FFF: {'classification': ItemClassification.filler, 'count': 0, 'name': JunkNames.twothousand_simoleons, diff --git a/worlds/sims4/Locations.py b/worlds/sims4/Locations.py index 66097397a37e..41711504c613 100644 --- a/worlds/sims4/Locations.py +++ b/worlds/sims4/Locations.py @@ -9,10 +9,6 @@ class Sims4Location(Location): game: str = "The Sims 4" - def __init__(self, player: int, name: str, address: Optional[int], parent): - super().__init__(player, name, address, parent) - self.event = not address - class Sims4LocationDict(TypedDict, total=False): name: str @@ -27,6 +23,7 @@ class Sims4LocationData(NamedTuple): skill_locations_table: dict[int, Sims4LocationDict] = {} + def add_skill_location(skill_name: str, expansion: str, max_level: int) -> int: if skill_locations_table: start_id = max(skill_locations_table.keys()) @@ -42,6 +39,7 @@ def add_skill_location(skill_name: str, expansion: str, max_level: int) -> int: } return skill_id + add_skill_location(SkillNames.base_skill_comedy, ExpansionNames.base, 10) add_skill_location(SkillNames.base_skill_guitar, ExpansionNames.base, 10) add_skill_location(SkillNames.base_skill_logic, ExpansionNames.base, 10) @@ -83,7 +81,7 @@ def add_skill_location(skill_name: str, expansion: str, max_level: int) -> int: add_skill_location(SkillNames.du_robotics_skill, ExpansionNames.discover_university, 10) add_skill_location(SkillNames.el_fabrication_skill, ExpansionNames.eco_lifestyle, 10) add_skill_location(SkillNames.el_juicefizzing_skill, ExpansionNames.eco_lifestyle, 5) -add_skill_location(SkillNames.nk_knitting_skill, StuffNames.nifty_knitting, 10) +add_skill_location(SkillNames.nk_knitting_skill, StuffNames.nifty_knitting, 10) add_skill_location(SkillNames.sy_rock_climbing_skill, ExpansionNames.snowy_escape, 10) add_skill_location(SkillNames.sy_skiing_skill, ExpansionNames.snowy_escape, 10) add_skill_location(SkillNames.sy_snowboarding_skill, ExpansionNames.snowy_escape, 10) @@ -97,13 +95,13 @@ def add_skill_location(skill_name: str, expansion: str, max_level: int) -> int: add_skill_location(SkillNames.lnd_thanatology_skill, ExpansionNames.life_and_death, 5) add_skill_location(SkillNames.bnh_pottery_skill, ExpansionNames.business_and_hobbies, 10) add_skill_location(SkillNames.bnh_tattooing_skill, ExpansionNames.business_and_hobbies, 10) -add_skill_location(SkillNames.ebn_apothecary_skill, ExpansionNames.enchanted_by_nature , 10) -add_skill_location(SkillNames.ebn_natural_living_skill, ExpansionNames.enchanted_by_nature , 10) +add_skill_location(SkillNames.ebn_apothecary_skill, ExpansionNames.enchanted_by_nature, 10) +add_skill_location(SkillNames.ebn_natural_living_skill, ExpansionNames.enchanted_by_nature, 10) del add_skill_location -careers_locations_table = { +careers_locations_table: dict[int, Sims4LocationDict] = { 0x73342001: {"name": f"{CareerNames.base_career_athlete_2}", "category": "Athlete", @@ -568,7 +566,7 @@ def add_skill_location(skill_name: str, expansion: str, max_level: int) -> int: } -ptj_locations_table = { +ptj_locations_table: dict[int, Sims4LocationDict] = { 0x733420A2: {"name": f"{CareerNames.base_ptj_babysitter_2}", "category": "Babysitter", @@ -606,7 +604,7 @@ def add_skill_location(skill_name: str, expansion: str, max_level: int) -> int: "expansion": "base"}, } -aspiration_locations_table = { +aspiration_locations_table: dict[int, Sims4LocationDict] = { 0x73343000: {"name": f"{AspirationNames.base_aspiration_basic_trainer}", "category": "Aspirations", "expansion": "base"}, @@ -882,7 +880,7 @@ def add_skill_location(skill_name: str, expansion: str, max_level: int) -> int: "expansion": "base"}, } -location_table = { +location_table: dict[int, Sims4LocationDict] = { **skill_locations_table, **careers_locations_table, **aspiration_locations_table, diff --git a/worlds/sims4/Names/EventNames.py b/worlds/sims4/Names/EventNames.py new file mode 100644 index 000000000000..6b319ffd53b0 --- /dev/null +++ b/worlds/sims4/Names/EventNames.py @@ -0,0 +1,36 @@ +bodybuilder = "Completed Bodybuilder Aspiration" +bodybuilder_item = "Completed Bodybuilder" +painter_extraordinaire = "Completed Painter Extraordinaire Aspiration" +painter_extraordinaire_item = "Completed Painter Extraordinaire" +bestselling_author = "Completed Bestselling Author Aspiration" +bestselling_author_item = "Completed Bestselling Author" +musical_genius = "Completed Musical Genius Aspiration" +musical_genius_item = "Completed Musical Genius" +chief_of_mischief = "Completed Chief of Mischief Aspiration" +chief_of_mischief_item = "Completed Chief of Mischief" +public_enemy = "Completed Public Enemy Aspiration" +public_enemy_item = "Completed Public Enemy" +master_chef = "Completed Master Chef Aspiration" +master_chef_item = "Completed Master Chef" +master_mixologist = "Completed Master Mixologist Aspiration" +master_mixologist_item = "Completed Master Mixologist" +renaissance_sim = "Completed Renaissance Sim Aspiration" +renaissance_sim_item = "Completed Renaissance Sim" +nerd_brain = "Completed Nerd Brain Aspiration" +nerd_brain_item = "Completed Nerd Brain" +computer_whiz = "Completed Computer Whiz Aspiration" +computer_whiz_item = "Completed Computer Whiz" +serial_romantic = "Completed Serial Romantic Aspiration" +serial_romantic_item = "Completed Serial Romantic" +freelance_botanist = "Completed Freelance Botanist Aspiration" +freelance_botanist_item = "Completed Freelance Botanist" +the_curator = "Completed The Curator Aspiration" +the_curator_item = "Completed The Curator" +angling_ace = "Completed Angling Ace Aspiration" +angling_ace_item = "Completed Angling Ace" +joke_star = "Completed Joke Star Aspiration" +joke_star_item = "Completed Joke Star" +friend_of_the_world = "Completed Friend of the World Aspiration" +friend_of_the_world_item = "Completed Friend of the World" +neighborly_advisor = "Completed Neighborly Advisor Aspiration" +neighborly_advisor_item = "Completed Neighborly Advisor" diff --git a/worlds/sims4/Rules.py b/worlds/sims4/Rules.py index c17fe64357e5..c4ecc654f8f3 100644 --- a/worlds/sims4/Rules.py +++ b/worlds/sims4/Rules.py @@ -2,13 +2,13 @@ from typing import TYPE_CHECKING -from BaseClasses import CollectionState +from BaseClasses import CollectionState, MultiWorld from worlds.AutoWorld import LogicMixin from .Names.DLC import ExpansionNames, GamePackNames, StuffNames from ..generic.Rules import set_rule -from .Names import SkillNames, CareerNames, AspirationNames -from .Options import Sims4Options +from .Names import EventNames, SkillNames, CareerNames, AspirationNames +from .Options import AspirationGoal, Sims4Options if TYPE_CHECKING: from . import Sims4World @@ -18,553 +18,56 @@ class Sims4Logic(LogicMixin): def _sims4_rule(self, player: int): return True +def set_rules(world: MultiWorld, player: int, options: Sims4Options): + # TODO: Part Time Jobs? + set_career_rules(world, player, options) + set_aspiration_rules(world, player, options) + set_skill_rules(world, player, options) + set_completion_condition(world, player, options) -def set_rules(sims4_world: Sims4World): - world = sims4_world.multiworld - player = sims4_world.player - options: Sims4Options = sims4_world.options +# TODO: use events for the completion condition in order to facilitate easier goal stuff, and presence in spoiler (also permits future goals to be more dynamic) +def set_completion_condition(world: MultiWorld, player: int, options: Sims4Options): + goal = options.goal + goal_value = goal.value - # Career Rules - # TODO relearn how the career locations send, and then refactor this to use has_skill - - # Athlete - if CareerNames.base_career_athlete in options.career: - set_rule(world.get_location(CareerNames.base_career_athlete_4, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=1) - and state.has(SkillNames.base_skill_fitness, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_athlete_5A, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) - and state.has(SkillNames.base_skill_fitness, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_athlete_5B, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) - and state.has(SkillNames.base_skill_fitness, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_athlete_6A, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) - and state.has(SkillNames.base_skill_fitness, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_athlete_7A, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) - and state.has(SkillNames.base_skill_fitness, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_athlete_8A, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=3) - and state.has(SkillNames.base_skill_fitness, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_athlete_9A, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=4) - and state.has(SkillNames.base_skill_fitness, player, count=7)) - set_rule(world.get_location(CareerNames.base_career_athlete_10A, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=6) - and state.has(SkillNames.base_skill_fitness, player, count=8)) - set_rule(world.get_location(CareerNames.base_career_athlete_6B, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=3) - and state.has(SkillNames.base_skill_fitness, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_athlete_7B, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=3) - and state.has(SkillNames.base_skill_fitness, player, count=7)) - set_rule(world.get_location(CareerNames.base_career_athlete_8B, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=4) - and state.has(SkillNames.base_skill_fitness, player, count=8)) - set_rule(world.get_location(CareerNames.base_career_athlete_9B, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=5) - and state.has(SkillNames.base_skill_fitness, player, count=8)) - set_rule(world.get_location(CareerNames.base_career_athlete_10B, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=6) - and state.has(SkillNames.base_skill_fitness, player, count=8)) - # Astronaut - if CareerNames.base_career_astronaut in options.career: - set_rule(world.get_location(CareerNames.base_career_astronaut_4, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_astronaut_5, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=2) - and state.has(SkillNames.base_skill_fitness, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_astronaut_6, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=3) - and state.has(SkillNames.base_skill_fitness, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_astronaut_7, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=3) - and state.has(SkillNames.base_skill_fitness, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_astronaut_8A, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=4) - and state.has(SkillNames.base_skill_fitness, player, count=5)) - set_rule(world.get_location(CareerNames.base_career_astronaut_8B, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=4) - and state.has(SkillNames.base_skill_fitness, player, count=5)) - set_rule(world.get_location(CareerNames.base_career_astronaut_9A, player), - lambda state: state.has(SkillNames.base_skill_fitness, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_astronaut_10A, player), - lambda state: state.has(SkillNames.base_skill_rocket_science, player, count=2) - and state.has(SkillNames.base_skill_fitness, player, count=8)) - set_rule(world.get_location(CareerNames.base_career_astronaut_9B, player), - lambda state: state.has(SkillNames.base_skill_fitness, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_astronaut_10B, player), - lambda state: state.has(SkillNames.base_skill_rocket_science, player, count=2) - and state.has(SkillNames.base_skill_fitness, player, count=8)) - # Business - if CareerNames.base_career_business in options.career: - set_rule(world.get_location(CareerNames.base_career_business_5, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_business_6, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_business_7A, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) - and state.has(SkillNames.base_skill_logic, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_business_7B, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) - and state.has(SkillNames.base_skill_logic, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_business_8A, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=4) - and state.has(SkillNames.base_skill_logic, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_business_9A, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=6) - and state.has(SkillNames.base_skill_logic, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_business_10A, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=8) - and state.has(SkillNames.base_skill_logic, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_business_8B, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=3) - and state.has(SkillNames.base_skill_logic, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_business_9B, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=4) - and state.has(SkillNames.base_skill_logic, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_business_10B, player), - lambda state: state.has(SkillNames.base_skill_charisma, player, count=6) - and state.has(SkillNames.base_skill_logic, player, count=8)) - # Criminal - if CareerNames.base_career_criminal in options.career: - set_rule(world.get_location(CareerNames.base_career_criminal_4, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_criminal_5, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_criminal_6A, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_criminal_6B, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_criminal_7A, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=5)) - set_rule(world.get_location(CareerNames.base_career_criminal_8A, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_criminal_9A, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=7) - and state.has(SkillNames.base_skill_handiness, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_criminal_10A, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=8) - and state.has(SkillNames.base_skill_handiness, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_criminal_7B, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=5) - and state.has(SkillNames.base_skill_programming, player, count=0)) - set_rule(world.get_location(CareerNames.base_career_criminal_8B, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=6) - and state.has(SkillNames.base_skill_programming, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_criminal_9B, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=7) - and state.has(SkillNames.base_skill_programming, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_criminal_10B, player), - lambda state: state.has(SkillNames.base_skill_mischief, player, count=8) - and state.has(SkillNames.base_skill_programming, player, count=6)) - # Culinary - if CareerNames.base_career_culinary in options.career: - set_rule(world.get_location(CareerNames.base_career_culinary_5, player), - lambda state: state.has(SkillNames.base_skill_cooking, player, count=1) - and state.has(SkillNames.base_skill_mixology, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_culinary_6A, player), - lambda state: state.has(SkillNames.base_skill_cooking, player, count=2) - and state.has(SkillNames.base_skill_mixology, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_culinary_6B, player), - lambda state: state.has(SkillNames.base_skill_cooking, player, count=2) - and state.has(SkillNames.base_skill_mixology, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_culinary_7A, player), - lambda state: state.has(SkillNames.base_skill_cooking, player, count=4) - and state.has(SkillNames.base_skill_gourmet, player, count=0) - and state.has(SkillNames.base_skill_mixology, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_culinary_8A, player), - lambda state: state.has(SkillNames.base_skill_cooking, player, count=6) - and state.has(SkillNames.base_skill_gourmet, player, count=4) - and state.has(SkillNames.base_skill_mixology, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_culinary_9A, player), - lambda state: state.has(SkillNames.base_skill_cooking, player, count=6) - and state.has(SkillNames.base_skill_gourmet, player, count=4) - and state.has(SkillNames.base_skill_mixology, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_culinary_10A, player), - lambda state: state.has(SkillNames.base_skill_cooking, player, count=8) - and state.has(SkillNames.base_skill_gourmet, player, count=6) - and state.has(SkillNames.base_skill_mixology, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_culinary_7B, player), - lambda state: state.has(SkillNames.base_skill_mixology, player, count=3) - and state.has(SkillNames.base_skill_charisma, player, count=0) - and state.has(SkillNames.base_skill_cooking, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_culinary_8B, player), - lambda state: state.has(SkillNames.base_skill_mixology, player, count=5) - and state.has(SkillNames.base_skill_charisma, player, count=2) - and state.has(SkillNames.base_skill_cooking, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_culinary_9B, player), - lambda state: state.has(SkillNames.base_skill_mixology, player, count=6) - and state.has(SkillNames.base_skill_charisma, player, count=4) - and state.has(SkillNames.base_skill_cooking, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_culinary_10B, player), - lambda state: state.has(SkillNames.base_skill_mixology, player, count=8) - and state.has(SkillNames.base_skill_charisma, player, count=6) - and state.has(SkillNames.base_skill_cooking, player, count=2)) - # Entertainer - if CareerNames.base_career_entertainer in options.career: - set_rule(world.get_location(CareerNames.base_career_entertainer_5A, player), - lambda state: (state.has(SkillNames.base_skill_guitar, player, count=1) - or state.has(SkillNames.base_skill_violin, player, count=1)) - and state.has(SkillNames.base_skill_comedy, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_entertainer_5B, player), - lambda state: (state.has(SkillNames.base_skill_guitar, player, count=1) - or state.has(SkillNames.base_skill_violin, player, count=1)) - and state.has(SkillNames.base_skill_comedy, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_entertainer_6A, player), - lambda state: state.has(SkillNames.base_skill_violin, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_entertainer_7A, player), - lambda state: (state.has(SkillNames.base_skill_guitar, player, count=3) - or state.has(SkillNames.base_skill_violin, player, count=3)) - and state.has(SkillNames.base_skill_piano, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_entertainer_8A, player), - lambda state: (state.has(SkillNames.base_skill_guitar, player, count=4) - or state.has(SkillNames.base_skill_violin, player, count=4)) - and state.has(SkillNames.base_skill_piano, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_entertainer_9A, player), - lambda state: (state.has(SkillNames.base_skill_guitar, player, count=5) - or state.has(SkillNames.base_skill_violin, player, count=5)) - and state.has(SkillNames.base_skill_piano, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_entertainer_10A, player), - lambda state: (state.has(SkillNames.base_skill_guitar, player, count=6) - or state.has(SkillNames.base_skill_violin, player, count=6)) - and state.has(SkillNames.base_skill_piano, player, count=8)) - set_rule(world.get_location(CareerNames.base_career_entertainer_6B, player), - lambda state: state.has(SkillNames.base_skill_comedy, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_entertainer_7B, player), - lambda state: state.has(SkillNames.base_skill_comedy, player, count=5)) - set_rule(world.get_location(CareerNames.base_career_entertainer_8B, player), - lambda state: state.has(SkillNames.base_skill_comedy, player, count=6) - and state.has(SkillNames.base_skill_charisma, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_entertainer_9B, player), - lambda state: state.has(SkillNames.base_skill_comedy, player, count=7) - and state.has(SkillNames.base_skill_charisma, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_entertainer_10B, player), - lambda state: state.has(SkillNames.base_skill_comedy, player, count=8) - and state.has(SkillNames.base_skill_charisma, player, count=6)) - # Painter - if CareerNames.base_career_painter in options.career: - set_rule(world.get_location(CareerNames.base_career_painter_4, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_painter_5, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_painter_6, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_painter_7A, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=5)) - set_rule(world.get_location(CareerNames.base_career_painter_7B, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=5)) - set_rule(world.get_location(CareerNames.base_career_painter_8A, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_painter_9A, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=7) - and state.has(SkillNames.base_skill_logic, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_painter_10A, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=8) - and state.has(SkillNames.base_skill_logic, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_painter_8B, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_painter_9B, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=7) - and state.has(SkillNames.base_skill_charisma, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_painter_10B, player), - lambda state: state.has(SkillNames.base_skill_painting, player, count=8) - and state.has(SkillNames.base_skill_charisma, player, count=4)) - # Secret Agent - if CareerNames.base_career_secret_agent in options.career: - set_rule(world.get_location(CareerNames.base_career_secret_agent_4, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=1) - and state.has(SkillNames.base_skill_charisma, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_secret_agent_5, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=1) - and state.has(SkillNames.base_skill_charisma, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_secret_agent_6, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=3) - and state.has(SkillNames.base_skill_charisma, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_secret_agent_7, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=3) - and state.has(SkillNames.base_skill_charisma, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_secret_agent_8A, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=4) - and state.has(SkillNames.base_skill_charisma, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_secret_agent_8B, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=4) - and state.has(SkillNames.base_skill_charisma, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_secret_agent_9A, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=6) - and state.has(SkillNames.base_skill_charisma, player, count=5)) - set_rule(world.get_location(CareerNames.base_career_secret_agent_10A, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=8) - and state.has(SkillNames.base_skill_charisma, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_secret_agent_9B, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_secret_agent_10B, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=8) - and state.has(SkillNames.base_skill_mischief, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_secret_agent_11B, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=8) - and state.has(SkillNames.base_skill_mischief, player, count=4)) - # Style Influencer - if CareerNames.base_career_style_influencer in options.career: - set_rule(world.get_location(CareerNames.base_career_style_influencer_4, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_5, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_6A, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=3) - and state.has(SkillNames.base_skill_charisma, player, count=1) - and state.has(SkillNames.base_skill_painting, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_7A, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=4) - and state.has(SkillNames.base_skill_charisma, player, count=3) - and state.has(SkillNames.base_skill_painting, player, count=2) - and state.has(SkillNames.base_skill_photography, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_8A, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=5) - and state.has(SkillNames.base_skill_charisma, player, count=4) - and state.has(SkillNames.base_skill_painting, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_9A, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=6) - and state.has(SkillNames.base_skill_charisma, player, count=5) - and state.has(SkillNames.base_skill_painting, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_10A, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=7) - and state.has(SkillNames.base_skill_charisma, player, count=6) - and state.has(SkillNames.base_skill_painting, player, count=5)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_6B, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=3) - and state.has(SkillNames.base_skill_charisma, player, count=1) - and state.has(SkillNames.base_skill_painting, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_7B, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=4) - and state.has(SkillNames.base_skill_charisma, player, count=3) - and state.has(SkillNames.base_skill_painting, player, count=2) - and state.has(SkillNames.base_skill_photography, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_8B, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=5) - and state.has(SkillNames.base_skill_charisma, player, count=4) - and state.has(SkillNames.base_skill_painting, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_9B, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=6) - and state.has(SkillNames.base_skill_charisma, player, count=5) - and state.has(SkillNames.base_skill_painting, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_style_influencer_10B, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=7) - and state.has(SkillNames.base_skill_charisma, player, count=6) - and state.has(SkillNames.base_skill_painting, player, count=5)) - # Tech Guru - # TODO check project manager career logic https://discord.com/channels/731205301247803413/1079002955262480424/1403764728177758252 - if CareerNames.base_career_tech_guru in options.career: - set_rule(world.get_location(CareerNames.base_career_tech_guru_4, player), - lambda state: has_skill(state, SkillNames.base_skill_programming, player, 3)) - set_rule(world.get_location(CareerNames.base_career_tech_guru_5, player), - lambda state: has_skill(state, SkillNames.base_skill_programming, player, 4) - and has_skill(state, SkillNames.base_skill_video_gaming, player, 3)) - set_rule(world.get_location(CareerNames.base_career_tech_guru_6, player), - lambda state: state.has(SkillNames.base_skill_programming, player, count=3) - and state.has(SkillNames.base_skill_video_gaming, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_tech_guru_7A, player), - lambda state: state.has(SkillNames.base_skill_programming, player, count=4) - and state.has(SkillNames.base_skill_video_gaming, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_tech_guru_7B, player), - lambda state: state.has(SkillNames.base_skill_programming, player, count=4) - and state.has(SkillNames.base_skill_video_gaming, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_tech_guru_8A, player), - lambda state: state.has(SkillNames.base_skill_programming, player, count=4) - and state.has(SkillNames.base_skill_video_gaming, player, count=4)) - set_rule(world.get_location(CareerNames.base_career_tech_guru_9A, player), - lambda state: state.has(SkillNames.base_skill_programming, player, count=5) - and state.has(SkillNames.base_skill_video_gaming, player, count=6)) - set_rule(world.get_location(CareerNames.base_career_tech_guru_10A, player), - lambda state: state.has(SkillNames.base_skill_programming, player, count=6) - and state.has(SkillNames.base_skill_video_gaming, player, count=8)) - set_rule(world.get_location(CareerNames.base_career_tech_guru_8B, player), - lambda state: state.has(SkillNames.base_skill_programming, player, count=6) - and state.has(SkillNames.base_skill_charisma, player, count=0)) - set_rule(world.get_location(CareerNames.base_career_tech_guru_9B, player), - lambda state: state.has(SkillNames.base_skill_programming, player, count=7) - and state.has(SkillNames.base_skill_charisma, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_tech_guru_10B, player), - lambda state: state.has(SkillNames.base_skill_programming, player, count=8) - and state.has(SkillNames.base_skill_charisma, player, count=4)) - # Writer - if CareerNames.base_career_writer in options.career: - set_rule(world.get_location(CareerNames.base_career_writer_4, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_writer_5, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_writer_6A, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_writer_6B, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_writer_7A, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=5)) - set_rule(world.get_location(CareerNames.base_career_writer_8A, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=6) - and state.has(SkillNames.base_skill_logic, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_writer_9A, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=7) - and state.has(SkillNames.base_skill_logic, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_writer_10A, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=8) - and state.has(SkillNames.base_skill_logic, player, count=3)) - set_rule(world.get_location(CareerNames.base_career_writer_7B, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=5)) - set_rule(world.get_location(CareerNames.base_career_writer_8B, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=6) - and state.has(SkillNames.base_skill_charisma, player, count=1)) - set_rule(world.get_location(CareerNames.base_career_writer_9B, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=7) - and state.has(SkillNames.base_skill_charisma, player, count=2)) - set_rule(world.get_location(CareerNames.base_career_writer_10B, player), - lambda state: state.has(SkillNames.base_skill_writing, player, count=8) - and state.has(SkillNames.base_skill_charisma, player, count=3)) - # Part Time Jobs - - # Aspirations - if options.goal.value == options.goal.option_bodybuilder: - set_rule(world.get_location(AspirationNames.base_aspiration_exercise_demon, player), - lambda state: has_skill(state, SkillNames.base_skill_fitness, player, 4)) - set_rule(world.get_location(AspirationNames.base_aspiration_fit_to_a_t, player), - lambda state: has_skill(state, SkillNames.base_skill_fitness, player, 6)) - set_rule(world.get_location(AspirationNames.base_aspiration_bodybuilder, player), - lambda state: has_skill(state, SkillNames.base_skill_fitness, player, 10)) - elif options.goal.value == options.goal.option_painter_extraordinaire: - set_rule(world.get_location(AspirationNames.base_aspiration_fine_artist, player), - lambda state: has_skill(state, SkillNames.base_skill_painting, player, 4)) - set_rule(world.get_location(AspirationNames.base_aspiration_brushing_with_greatness, player), - lambda state: has_skill(state, SkillNames.base_skill_painting, player, 6)) - set_rule(world.get_location(AspirationNames.base_aspiration_painter_extraordinaire, player), - lambda state: has_skill(state, SkillNames.base_skill_painting, player, 10)) - elif options.goal.value == options.goal.option_bestselling_author: - set_rule(world.get_location(AspirationNames.base_aspiration_competent_wordsmith, player), - lambda state: has_skill(state, SkillNames.base_skill_writing, player, 4)) - set_rule(world.get_location(AspirationNames.base_aspiration_novelest_novelist, player), - lambda state: has_skill(state, SkillNames.base_skill_writing, player, 6)) - set_rule(world.get_location(AspirationNames.base_aspiration_bestselling_author, player), - lambda state: has_skill(state, SkillNames.base_skill_writing, player, 10)) - elif options.goal.value == options.goal.option_musical_genius: - set_rule(world.get_location(AspirationNames.base_aspiration_fine_tuned, player), - lambda state: has_skill(state, SkillNames.base_skill_guitar, player, 4) - or has_skill(state, SkillNames.base_skill_violin, player, 4) - or has_skill(state, SkillNames.base_skill_piano, player, 4)) - set_rule(world.get_location(AspirationNames.base_aspiration_harmonious, player), - lambda state: has_skill(state, SkillNames.base_skill_guitar, player, 8) - or has_skill(state, SkillNames.base_skill_violin, player, 8) - or has_skill(state, SkillNames.base_skill_piano, player, 8)) - set_rule(world.get_location(AspirationNames.base_aspiration_musical_genius, player), - lambda state: has_skill(state, SkillNames.base_skill_guitar, player, 10) - or has_skill(state, SkillNames.base_skill_violin, player, 10) - or has_skill(state, SkillNames.base_skill_piano, player, 10)) - elif options.goal.value == options.goal.option_public_enemy: - set_rule(world.get_location(AspirationNames.base_aspiration_criminal_mind, player), - lambda state: has_skill(state, SkillNames.base_skill_mischief, player, 3)) - set_rule(world.get_location(AspirationNames.base_aspiration_public_enemy, player), - lambda state: has_skill(state, SkillNames.base_skill_mischief, player, 8) - and has_skill(state, SkillNames.base_skill_programming, player, 4)) - - elif options.goal.value == options.goal.option_chief_of_mischief: - set_rule(world.get_location(AspirationNames.base_aspiration_artful_trickster, player), - lambda state: has_skill(state, SkillNames.base_skill_mischief, player, 3)) - set_rule(world.get_location(AspirationNames.base_aspiration_professional_prankster, player), - lambda state: has_skill(state, SkillNames.base_skill_mischief, player, 6)) - set_rule(world.get_location(AspirationNames.base_aspiration_chief_of_mischief, player), - lambda state: has_skill(state, SkillNames.base_skill_mischief, player, 10)) - elif options.goal.value == options.goal.option_master_chef: - set_rule(world.get_location(AspirationNames.base_aspiration_captain_cook, player), - lambda state: has_skill(state, SkillNames.base_skill_cooking, player, 5)) - set_rule(world.get_location(AspirationNames.base_aspiration_culinary_artist, player), - lambda state: has_skill(state, SkillNames.base_skill_cooking, player, 5)) - set_rule(world.get_location(AspirationNames.base_aspiration_master_chef, player), - lambda state: (has_skill(state, SkillNames.base_skill_gourmet, player, 6) - and has_skill(state, SkillNames.base_skill_cooking, player, 8)) - or (has_skill(state, SkillNames.base_skill_gourmet, player, 5) - and has_skill(state, SkillNames.base_skill_mixology, player, 7) - and has_skill(state, SkillNames.base_skill_charisma, player, 4))) - elif options.goal.value == options.goal.option_master_mixologist: - set_rule(world.get_location(AspirationNames.base_aspiration_electric_mixer, player), - lambda state: has_skill(state, SkillNames.base_skill_mixology, player, 4)) - set_rule(world.get_location(AspirationNames.base_aspiration_beverage_boss, player), - lambda state: has_skill(state, SkillNames.base_skill_mixology, player, 7) - and has_skill(state, SkillNames.base_skill_cooking, player, 4)) - set_rule(world.get_location(AspirationNames.base_aspiration_master_mixologist, player), - lambda state: has_skill(state, SkillNames.base_skill_mixology, player, 10) - and has_skill(state, SkillNames.base_skill_cooking, player, 4)) - elif options.goal.value == options.goal.option_renaissance_sim: - set_rule(world.get_location(AspirationNames.base_aspiration_prudent_student, player), - lambda state: state.has(SkillNames.base_skill_logic, player, count=1)) - set_rule(world.get_location(AspirationNames.base_aspiration_jack_of_some_trades, player), - lambda state: count_skills_over(2, state, player) >= 4) - set_rule(world.get_location(AspirationNames.base_aspiration_pantologist, player), - lambda state: count_skills_over(3, state, player) >= 5) - set_rule(world.get_location(AspirationNames.base_aspiration_renaissance_sim, player), - lambda state: count_skills_over(6, state, player) >= 6) - elif options.goal.value == options.goal.option_nerd_brain: - set_rule(world.get_location(AspirationNames.base_aspiration_prudent_student, player), - lambda state: has_skill(state, SkillNames.base_skill_logic, player, 3)) - set_rule(world.get_location(AspirationNames.base_aspiration_erudite, player), - lambda state: has_skill(state, SkillNames.base_skill_logic, player, 6)) - set_rule(world.get_location(AspirationNames.base_aspiration_rocket_scientist, player), - lambda state: has_skill(state, SkillNames.base_skill_handiness, player, 5)) - set_rule(world.get_location(AspirationNames.base_aspiration_nerd_brain, player), - lambda state: has_skill(state, SkillNames.base_skill_logic, player, 10) - and has_skill(state, SkillNames.base_skill_handiness, player, 5)) - elif options.goal.value == options.goal.option_computer_whiz: - set_rule(world.get_location(AspirationNames.base_aspiration_technically_adept, player), - lambda state: has_skill(state, SkillNames.base_skill_programming, player, 3)) - set_rule(world.get_location(AspirationNames.base_aspiration_computer_geek, player), - lambda state: has_skill(state, SkillNames.base_skill_programming, player, 7)) - set_rule(world.get_location(AspirationNames.base_aspiration_computer_whiz, player), - lambda state: has_skill(state, SkillNames.base_skill_programming, player, 7) - and has_skill(state, SkillNames.base_skill_video_gaming, player, 4)) - elif options.goal.value == options.goal.option_serial_romantic: - set_rule(world.get_location(AspirationNames.base_aspiration_up_to_date, player), - lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 4)) - set_rule(world.get_location(AspirationNames.base_aspiration_romance_juggler, player), - lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 6)) - set_rule(world.get_location(AspirationNames.base_aspiration_serial_romantic, player), - lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 6)) - elif options.goal.value == options.goal.option_freelance_botanist: - set_rule(world.get_location(AspirationNames.base_aspiration_garden_variety, player), - lambda state: has_skill(state, SkillNames.base_skill_gardening, player, 4)) - set_rule(world.get_location(AspirationNames.base_aspiration_nature_nurturer, player), - lambda state: has_skill(state, SkillNames.base_skill_gardening, player, 6)) - set_rule(world.get_location(AspirationNames.base_aspiration_freelance_botanist, player), - lambda state: has_skill(state, SkillNames.base_skill_gardening, player, 10)) - elif options.goal.value == options.goal.option_angling_ace: - set_rule(world.get_location(AspirationNames.base_aspiration_hooked, player), - lambda state: has_skill(state, SkillNames.base_skill_fishing, player, 4)) - set_rule(world.get_location(AspirationNames.base_aspiration_reel_smart, player), - lambda state: has_skill(state, SkillNames.base_skill_fishing, player, 6)) - set_rule(world.get_location(AspirationNames.base_aspiration_angling_ace, player), - lambda state: has_skill(state, SkillNames.base_skill_fishing, player, 10)) - elif options.goal.value == options.goal.option_joke_star: - set_rule(world.get_location(AspirationNames.base_aspiration_practical_joker, player), - lambda state: has_skill(state, SkillNames.base_skill_comedy, player, 3)) - set_rule(world.get_location(AspirationNames.base_aspiration_standup_startup, player), - lambda state: has_skill(state, SkillNames.base_skill_comedy, player, 3)) - set_rule(world.get_location(AspirationNames.base_aspiration_funny, player), - lambda state: has_skill(state, SkillNames.base_skill_comedy, player, 6) - and (has_skill(state, SkillNames.base_skill_guitar, player, 3) - or has_skill(state, SkillNames.base_skill_violin, player, 3))) - set_rule(world.get_location(AspirationNames.base_aspiration_joke_star, player), - lambda state: has_skill(state, SkillNames.base_skill_comedy, player, 10) - and (has_skill(state, SkillNames.base_skill_guitar, player, 3) - or has_skill(state, SkillNames.base_skill_violin, player, 3))) - elif options.goal.value == options.goal.option_friend_of_the_world: - set_rule(world.get_location(AspirationNames.base_aspiration_well_liked, player), - lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 4)) - set_rule(world.get_location(AspirationNames.base_aspiration_super_friend, player), - lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 6)) - set_rule(world.get_location(AspirationNames.base_aspiration_friend_of_the_world, player), - lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 10)) - elif options.goal.value == options.goal.option_neighborly_advisor: - set_rule(world.get_location(AspirationNames.base_aspiration_neighborly_advisor, player), - lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 7)) - - # Skillchecks + if goal_value == goal.option_bodybuilder: + world.completion_condition[player] = lambda state: state.has(EventNames.bodybuilder_item, player) + elif goal_value == goal.option_painter_extraordinaire: + world.completion_condition[player] = lambda state: state.has(EventNames.painter_extraordinaire_item, player) + elif goal_value == goal.option_bestselling_author: + world.completion_condition[player] = lambda state: state.has(EventNames.bestselling_author_item, player) + elif goal_value == goal.option_musical_genius: + world.completion_condition[player] = lambda state: state.has(EventNames.musical_genius_item, player) + elif goal_value == goal.option_public_enemy: + world.completion_condition[player] = lambda state: state.has(EventNames.public_enemy_item, player) + elif goal_value == goal.option_chief_of_mischief: + world.completion_condition[player] = lambda state: state.has(EventNames.chief_of_mischief_item, player) + elif goal_value == goal.option_master_chef: + world.completion_condition[player] = lambda state: state.has(EventNames.master_chef_item, player) + elif goal_value == goal.option_master_mixologist: + world.completion_condition[player] = lambda state: state.has(EventNames.master_mixologist_item, player) + elif goal_value == goal.option_renaissance_sim: + world.completion_condition[player] = lambda state: state.has(EventNames.renaissance_sim_item, player) + elif goal_value == goal.option_nerd_brain: + world.completion_condition[player] = lambda state: state.has(EventNames.nerd_brain_item, player) + elif goal_value == goal.option_computer_whiz: + world.completion_condition[player] = lambda state: state.has(EventNames.computer_whiz_item, player) + elif goal_value == goal.option_serial_romantic: + world.completion_condition[player] = lambda state: state.has(EventNames.serial_romantic_item, player) + elif goal_value == goal.option_freelance_botanist: + world.completion_condition[player] = lambda state: state.has(EventNames.freelance_botanist_item, player) + elif goal_value == goal.option_the_curator: + world.completion_condition[player] = lambda state: state.has(EventNames.the_curator_item, player) + elif goal_value == goal.option_angling_ace: + world.completion_condition[player] = lambda state: state.has(EventNames.angling_ace_item, player) + elif goal_value == goal.option_joke_star: + world.completion_condition[player] = lambda state: state.has(EventNames.joke_star_item, player) + elif goal_value == goal.option_friend_of_the_world: + world.completion_condition[player] = lambda state: state.has(EventNames.friend_of_the_world_item, player) + elif goal_value == goal.option_neighborly_advisor: + world.completion_condition[player] = lambda state: state.has(EventNames.neighborly_advisor_item, player) +def set_skill_rules(world: MultiWorld, player: int, options: Sims4Options): skills = { SkillNames.base_skill_comedy: (3, 11), SkillNames.base_skill_charisma: (3, 11), @@ -588,67 +91,71 @@ def set_rules(sims4_world: Sims4World): SkillNames.base_skill_rocket_science: (3, 11), } - if ExpansionNames.get_to_work in options.expansion_packs.value: + eps = options.expansion_packs.value + gps = options.game_packs.value + sps = options.stuff_packs.value + + if ExpansionNames.get_to_work in eps: skills[SkillNames.gtw_baking_skill] = (3, 11) - if ExpansionNames.get_together in options.expansion_packs.value: + if ExpansionNames.get_together in eps: skills[SkillNames.gt_dancing_skill] = (3, 6) skills[SkillNames.gt_djmixing_skill] = (3, 11) - if ExpansionNames.city_living in options.expansion_packs.value: + if ExpansionNames.city_living in eps: skills[SkillNames.cl_singing_skill] = (3, 11) - if ExpansionNames.cats_and_dogs in options.expansion_packs.value: + if ExpansionNames.cats_and_dogs in eps: skills[SkillNames.cnd_pettraining_skill] = (3, 6) - skills[SkillNames.cnd_veterinarian_skill] = (3,11) - if ExpansionNames.seasons in options.expansion_packs.value: + skills[SkillNames.cnd_veterinarian_skill] = (3, 11) + if ExpansionNames.seasons in eps: skills[SkillNames.se_flowerarranging_skill] = (3, 11) - if ExpansionNames.get_famous in options.expansion_packs.value: + if ExpansionNames.get_famous in eps: skills[SkillNames.gf_acting_skill] = (3, 11) skills[SkillNames.gf_mediaproduction_skill] = (3, 6) - if ExpansionNames.discover_university in options.expansion_packs.value: + if ExpansionNames.discover_university in eps: skills[SkillNames.du_robotics_skill] = (3, 11) skills[SkillNames.du_researchanddebate_skill] = (3, 11) - if ExpansionNames.eco_lifestyle in options.expansion_packs.value: + if ExpansionNames.eco_lifestyle in eps: skills[SkillNames.el_fabrication_skill] = (3, 11) skills[SkillNames.el_juicefizzing_skill] = (3, 6) - if ExpansionNames.snowy_escape in options.expansion_packs.value: + if ExpansionNames.snowy_escape in eps: skills[SkillNames.sy_rock_climbing_skill] = (3, 11) skills[SkillNames.sy_skiing_skill] = (3, 11) skills[SkillNames.sy_snowboarding_skill] = (3, 11) - if ExpansionNames.cottage_living in options.expansion_packs.value: + if ExpansionNames.cottage_living in eps: skills[SkillNames.cgl_cross_stitch_skill] = (3, 6) - if ExpansionNames.high_school_years in options.expansion_packs.value: + if ExpansionNames.high_school_years in eps: skills[SkillNames.hsy_entrepreneur_skill] = (3, 6) - if ExpansionNames.horse_ranch in options.expansion_packs.value: + if ExpansionNames.horse_ranch in eps: skills[SkillNames.hr_horse_riding_skill] = (3, 11) skills[SkillNames.hr_nectar_making_skill] = (3, 6) - if ExpansionNames.lovestruck in options.expansion_packs.value: + if ExpansionNames.lovestruck in eps: skills[SkillNames.lv_romance_skill] = (3, 11) - if ExpansionNames.life_and_death in options.expansion_packs.value: + if ExpansionNames.life_and_death in eps: skills[SkillNames.lnd_thanatology_skill] = (3, 6) - if ExpansionNames.business_and_hobbies in options.expansion_packs.value: + if ExpansionNames.business_and_hobbies in eps: skills[SkillNames.bnh_pottery_skill] = (3, 11) skills[SkillNames.bnh_tattooing_skill] = (3, 11) - if ExpansionNames.enchanted_by_nature in options.expansion_packs.value: + if ExpansionNames.enchanted_by_nature in eps: skills[SkillNames.ebn_apothecary_skill] = (3, 11) skills[SkillNames.ebn_natural_living_skill] = (3, 11) - if GamePackNames.outdoor_retreat in options.game_packs.value: + if GamePackNames.outdoor_retreat in gps: skills[SkillNames.or_herbalism_skill] = (3, 11) - if GamePackNames.spa_day in options.game_packs.value: + if GamePackNames.spa_day in gps: skills[SkillNames.sd_wellness_skill] = (3, 11) - if GamePackNames.vampires in options.game_packs.value: + if GamePackNames.vampires in gps: skills[SkillNames.vamp_pipeorgan_skill] = (3, 11) skills[SkillNames.vamp_vampirelore_skill] = (3, 16) - if GamePackNames.parenthood in options.game_packs.value: + if GamePackNames.parenthood in gps: skills[SkillNames.ph_parenting_skill] = (3, 11) - if GamePackNames.jungle_adventure in options.game_packs.value: + if GamePackNames.jungle_adventure in gps: skills[SkillNames.ja_archaeology_skill] = (3, 11) skills[SkillNames.ja_sevadoradianculture_skill] = (3, 6) - if StuffNames.bowling_night in options.stuff_packs.value: + if StuffNames.bowling_night in sps: skills[SkillNames.bns_bowling_skill] = (3, 6) - if StuffNames.nifty_knitting in options.stuff_packs.value: + if StuffNames.nifty_knitting in sps: skills[SkillNames.nk_knitting_skill] = (3, 11) - if StuffNames.paranormal in options.stuff_packs.value: + if StuffNames.paranormal in sps: skills[SkillNames.pa_medium_skill] = (3, 6) - if StuffNames.crystal_creations in options.stuff_packs.value: + if StuffNames.crystal_creations in sps: skills[SkillNames.cc_gemology_skill] = (3, 11) for skill, (low, high) in skills.items(): @@ -657,61 +164,644 @@ def set_rules(sims4_world: Sims4World): set_rule(world.get_location(f"{skill} {level}", player), lambda state, s=skill, l=level: has_skill(state, s, player, l)) - if options.goal.value == options.goal.option_bodybuilder: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_bodybuilder, player), player=player) - elif options.goal.value == options.goal.option_painter_extraordinaire: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_painter_extraordinaire, player), player=player) - elif options.goal.value == options.goal.option_bestselling_author: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_bestselling_author, player), player=player) - elif options.goal.value == options.goal.option_musical_genius: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_musical_genius, player), player=player) - elif options.goal.value == options.goal.option_public_enemy: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_public_enemy, player), player=player) - elif options.goal.value == options.goal.option_chief_of_mischief: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_chief_of_mischief, player), player=player) - elif options.goal.value == options.goal.option_master_chef: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_master_chef, player), player=player) - elif options.goal.value == options.goal.option_master_mixologist: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_master_mixologist, player), player=player) - elif options.goal.value == options.goal.option_renaissance_sim: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_renaissance_sim, player), player=player) - elif options.goal.value == options.goal.option_nerd_brain: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_nerd_brain, player), player=player) - elif options.goal.value == options.goal.option_computer_whiz: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_computer_whiz, player), player=player) - elif options.goal.value == options.goal.option_serial_romantic: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_serial_romantic, player), player=player) - elif options.goal.value == options.goal.option_freelance_botanist: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_freelance_botanist, player), player=player) - elif options.goal.value == options.goal.option_the_curator: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_the_curator, player), player=player) - elif options.goal.value == options.goal.option_angling_ace: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_angling_ace, player), player=player) - elif options.goal.value == options.goal.option_joke_star: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_joke_star, player), player=player) - elif options.goal.value == options.goal.option_friend_of_the_world: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_friend_of_the_world, player), player=player) - elif options.goal.value == options.goal.option_neighborly_advisor: - world.completion_condition[player] = lambda state: state.can_reach( - world.get_location(AspirationNames.base_aspiration_neighborly_advisor, player), player=player) +def _bodybuilder(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_exercise_demon, player), + lambda state: has_skill(state, SkillNames.base_skill_fitness, player, 4)) + set_rule(world.get_location(AspirationNames.base_aspiration_fit_to_a_t, player), + lambda state: has_skill(state, SkillNames.base_skill_fitness, player, 6)) + set_rule(world.get_location(AspirationNames.base_aspiration_bodybuilder, player), + lambda state: has_skill(state, SkillNames.base_skill_fitness, player, 10)) + set_rule(world.get_location(EventNames.bodybuilder, player), + lambda state: state.can_reach(world.get_location(AspirationNames.base_aspiration_bodybuilder, player), player=player)) + +def _painter_extraordinaire(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_fine_artist, player), + lambda state: has_skill(state, SkillNames.base_skill_painting, player, 4)) + set_rule(world.get_location(AspirationNames.base_aspiration_brushing_with_greatness, player), + lambda state: has_skill(state, SkillNames.base_skill_painting, player, 6)) + set_rule(world.get_location(AspirationNames.base_aspiration_painter_extraordinaire, player), + lambda state: has_skill(state, SkillNames.base_skill_painting, player, 10)) + set_rule(world.get_location(EventNames.painter_extraordinaire, player), + lambda state: state.can_reach(world.get_location(AspirationNames.base_aspiration_painter_extraordinaire, player), + player=player)) + +def _bestselling_author(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_competent_wordsmith, player), + lambda state: has_skill(state, SkillNames.base_skill_writing, player, 4)) + set_rule(world.get_location(AspirationNames.base_aspiration_novelest_novelist, player), + lambda state: has_skill(state, SkillNames.base_skill_writing, player, 6)) + set_rule(world.get_location(AspirationNames.base_aspiration_bestselling_author, player), + lambda state: has_skill(state, SkillNames.base_skill_writing, player, 10)) + set_rule(world.get_location(EventNames.bestselling_author, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_bestselling_author, player), player=player)) + +def _musical_genius(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_fine_tuned, player), + lambda state: has_skill(state, SkillNames.base_skill_guitar, player, 4) + or has_skill(state, SkillNames.base_skill_violin, player, 4) + or has_skill(state, SkillNames.base_skill_piano, player, 4)) + set_rule(world.get_location(AspirationNames.base_aspiration_harmonious, player), + lambda state: has_skill(state, SkillNames.base_skill_guitar, player, 8) + or has_skill(state, SkillNames.base_skill_violin, player, 8) + or has_skill(state, SkillNames.base_skill_piano, player, 8)) + set_rule(world.get_location(AspirationNames.base_aspiration_musical_genius, player), + lambda state: has_skill(state, SkillNames.base_skill_guitar, player, 10) + or has_skill(state, SkillNames.base_skill_violin, player, 10) + or has_skill(state, SkillNames.base_skill_piano, player, 10)) + set_rule(world.get_location(EventNames.musical_genius, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_musical_genius, player), player=player)) + +def _public_enemy(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_criminal_mind, player), + lambda state: has_skill(state, SkillNames.base_skill_mischief, player, 3)) + set_rule(world.get_location(AspirationNames.base_aspiration_public_enemy, player), + lambda state: has_skill(state, SkillNames.base_skill_mischief, player, 8) + and has_skill(state, SkillNames.base_skill_programming, player, 4)) + set_rule(world.get_location(EventNames.public_enemy, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_public_enemy, player), player=player)) + +def _chief_of_mischief(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_artful_trickster, player), + lambda state: has_skill(state, SkillNames.base_skill_mischief, player, 3)) + set_rule(world.get_location(AspirationNames.base_aspiration_professional_prankster, player), + lambda state: has_skill(state, SkillNames.base_skill_mischief, player, 6)) + set_rule(world.get_location(AspirationNames.base_aspiration_chief_of_mischief, player), + lambda state: has_skill(state, SkillNames.base_skill_mischief, player, 10)) + set_rule(world.get_location(EventNames.chief_of_mischief, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_chief_of_mischief, player), player=player)) + +def _master_chef(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_captain_cook, player), + lambda state: has_skill(state, SkillNames.base_skill_cooking, player, 5)) + set_rule(world.get_location(AspirationNames.base_aspiration_culinary_artist, player), + lambda state: has_skill(state, SkillNames.base_skill_cooking, player, 5)) + set_rule(world.get_location(AspirationNames.base_aspiration_master_chef, player), + lambda state: (has_skill(state, SkillNames.base_skill_gourmet, player, 6) + and has_skill(state, SkillNames.base_skill_cooking, player, 8)) + or (has_skill(state, SkillNames.base_skill_gourmet, player, 5) + and has_skill(state, SkillNames.base_skill_mixology, player, 7) + and has_skill(state, SkillNames.base_skill_charisma, player, 4))) + set_rule(world.get_location(EventNames.master_chef, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_master_chef, player), player=player)) + +def _master_mixologist(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_electric_mixer, player), + lambda state: has_skill(state, SkillNames.base_skill_mixology, player, 4)) + set_rule(world.get_location(AspirationNames.base_aspiration_beverage_boss, player), + lambda state: has_skill(state, SkillNames.base_skill_mixology, player, 7) + and has_skill(state, SkillNames.base_skill_cooking, player, 4)) + set_rule(world.get_location(AspirationNames.base_aspiration_master_mixologist, player), + lambda state: has_skill(state, SkillNames.base_skill_mixology, player, 10) + and has_skill(state, SkillNames.base_skill_cooking, player, 4)) + set_rule(world.get_location(EventNames.master_mixologist, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_master_mixologist, player), player=player)) +def _renaissance_sim(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_prudent_student, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=1)) + set_rule(world.get_location(AspirationNames.base_aspiration_jack_of_some_trades, player), + lambda state: count_skills_over(2, state, player) >= 4) + set_rule(world.get_location(AspirationNames.base_aspiration_pantologist, player), + lambda state: count_skills_over(3, state, player) >= 5) + set_rule(world.get_location(AspirationNames.base_aspiration_renaissance_sim, player), + lambda state: count_skills_over(6, state, player) >= 6) + set_rule(world.get_location(EventNames.renaissance_sim, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_renaissance_sim, player), player=player)) + +def _nerd_brain(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_prudent_student, player), + lambda state: has_skill(state, SkillNames.base_skill_logic, player, 3)) + set_rule(world.get_location(AspirationNames.base_aspiration_erudite, player), + lambda state: has_skill(state, SkillNames.base_skill_logic, player, 6)) + set_rule(world.get_location(AspirationNames.base_aspiration_rocket_scientist, player), + lambda state: has_skill(state, SkillNames.base_skill_handiness, player, 5)) + set_rule(world.get_location(AspirationNames.base_aspiration_nerd_brain, player), + lambda state: has_skill(state, SkillNames.base_skill_logic, player, 10) + and has_skill(state, SkillNames.base_skill_handiness, player, 5)) + set_rule(world.get_location(EventNames.nerd_brain, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_nerd_brain, player), player=player)) + +def _computer_whiz(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_technically_adept, player), + lambda state: has_skill(state, SkillNames.base_skill_programming, player, 3)) + set_rule(world.get_location(AspirationNames.base_aspiration_computer_geek, player), + lambda state: has_skill(state, SkillNames.base_skill_programming, player, 7)) + set_rule(world.get_location(AspirationNames.base_aspiration_computer_whiz, player), + lambda state: has_skill(state, SkillNames.base_skill_programming, player, 7) + and has_skill(state, SkillNames.base_skill_video_gaming, player, 4)) + set_rule(world.get_location(EventNames.computer_whiz, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_computer_whiz, player), player=player)) + +def _serial_romantic(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_up_to_date, player), + lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 4)) + set_rule(world.get_location(AspirationNames.base_aspiration_romance_juggler, player), + lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 6)) + set_rule(world.get_location(AspirationNames.base_aspiration_serial_romantic, player), + lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 6)) + set_rule(world.get_location(EventNames.serial_romantic, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_serial_romantic, player), player=player)) + +def _freelance_botanist (world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_garden_variety, player), + lambda state: has_skill(state, SkillNames.base_skill_gardening, player, 4)) + set_rule(world.get_location(AspirationNames.base_aspiration_nature_nurturer, player), + lambda state: has_skill(state, SkillNames.base_skill_gardening, player, 6)) + set_rule(world.get_location(AspirationNames.base_aspiration_freelance_botanist, player), + lambda state: has_skill(state, SkillNames.base_skill_gardening, player, 10)) + set_rule(world.get_location(EventNames.freelance_botanist, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_freelance_botanist, player), player=player)) + +def _angling_ace(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_hooked, player), + lambda state: has_skill(state, SkillNames.base_skill_fishing, player, 4)) + set_rule(world.get_location(AspirationNames.base_aspiration_reel_smart, player), + lambda state: has_skill(state, SkillNames.base_skill_fishing, player, 6)) + set_rule(world.get_location(AspirationNames.base_aspiration_angling_ace, player), + lambda state: has_skill(state, SkillNames.base_skill_fishing, player, 10)) + set_rule(world.get_location(EventNames.angling_ace, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_angling_ace, player), player=player)) + +def _joke_star(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_practical_joker, player), + lambda state: has_skill(state, SkillNames.base_skill_comedy, player, 3)) + set_rule(world.get_location(AspirationNames.base_aspiration_standup_startup, player), + lambda state: has_skill(state, SkillNames.base_skill_comedy, player, 3)) + set_rule(world.get_location(AspirationNames.base_aspiration_funny, player), + lambda state: has_skill(state, SkillNames.base_skill_comedy, player, 6) + and (has_skill(state, SkillNames.base_skill_guitar, player, 3) + or has_skill(state, SkillNames.base_skill_violin, player, 3))) + set_rule(world.get_location(AspirationNames.base_aspiration_joke_star, player), + lambda state: has_skill(state, SkillNames.base_skill_comedy, player, 10) + and (has_skill(state, SkillNames.base_skill_guitar, player, 3) + or has_skill(state, SkillNames.base_skill_violin, player, 3))) + set_rule(world.get_location(EventNames.joke_star, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_joke_star, player), player=player)) +def _friend_of_the_world(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_well_liked, player), + lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 4)) + set_rule(world.get_location(AspirationNames.base_aspiration_super_friend, player), + lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 6)) + set_rule(world.get_location(AspirationNames.base_aspiration_friend_of_the_world, player), + lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 10)) + set_rule(world.get_location(EventNames.friend_of_the_world, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_friend_of_the_world, player), player=player)) + +def _neighborly_advisor(world: MultiWorld, player: int): + set_rule(world.get_location(AspirationNames.base_aspiration_neighborly_advisor, player), + lambda state: has_skill(state, SkillNames.base_skill_charisma, player, 7)) + set_rule(world.get_location(EventNames.neighborly_advisor, player), + lambda state: state.can_reach( + world.get_location(AspirationNames.base_aspiration_neighborly_advisor, player), player=player)) + +ASPIRATION_RULES = { + AspirationGoal.option_bodybuilder: _bodybuilder, + AspirationGoal.option_painter_extraordinaire: _painter_extraordinaire, + AspirationGoal.option_bestselling_author: _bestselling_author, + AspirationGoal.option_musical_genius: _musical_genius, + AspirationGoal.option_public_enemy: _public_enemy, + AspirationGoal.option_chief_of_mischief: _chief_of_mischief, + AspirationGoal.option_master_chef: _master_chef, + AspirationGoal.option_master_mixologist: _master_mixologist, + AspirationGoal.option_renaissance_sim: _renaissance_sim, + AspirationGoal.option_nerd_brain: _nerd_brain, + AspirationGoal.option_computer_whiz: _computer_whiz, + AspirationGoal.option_serial_romantic: _serial_romantic, + AspirationGoal.option_freelance_botanist: _freelance_botanist, + AspirationGoal.option_angling_ace: _angling_ace, + AspirationGoal.option_joke_star: _joke_star, + AspirationGoal.option_friend_of_the_world: _friend_of_the_world, + AspirationGoal.option_neighborly_advisor: _neighborly_advisor, + } + +def set_aspiration_rules(world: MultiWorld, player: int, options: Sims4Options): + handler = ASPIRATION_RULES.get(options.goal) + if handler: + handler(world, player) + +def _career_athlete(world: MultiWorld, player: int): + set_rule(world.get_location(CareerNames.base_career_athlete_4, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=1) + and state.has(SkillNames.base_skill_fitness, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_athlete_5A, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) + and state.has(SkillNames.base_skill_fitness, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_athlete_5B, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) + and state.has(SkillNames.base_skill_fitness, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_athlete_6A, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) + and state.has(SkillNames.base_skill_fitness, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_athlete_7A, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) + and state.has(SkillNames.base_skill_fitness, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_athlete_8A, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=3) + and state.has(SkillNames.base_skill_fitness, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_athlete_9A, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=4) + and state.has(SkillNames.base_skill_fitness, player, count=7)) + set_rule(world.get_location(CareerNames.base_career_athlete_10A, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=6) + and state.has(SkillNames.base_skill_fitness, player, count=8)) + set_rule(world.get_location(CareerNames.base_career_athlete_6B, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=3) + and state.has(SkillNames.base_skill_fitness, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_athlete_7B, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=3) + and state.has(SkillNames.base_skill_fitness, player, count=7)) + set_rule(world.get_location(CareerNames.base_career_athlete_8B, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=4) + and state.has(SkillNames.base_skill_fitness, player, count=8)) + set_rule(world.get_location(CareerNames.base_career_athlete_9B, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=5) + and state.has(SkillNames.base_skill_fitness, player, count=8)) + set_rule(world.get_location(CareerNames.base_career_athlete_10B, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=6) + and state.has(SkillNames.base_skill_fitness, player, count=8)) + +def _career_astronaut(world: MultiWorld, player: int): + set_rule(world.get_location(CareerNames.base_career_astronaut_4, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_astronaut_5, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=2) + and state.has(SkillNames.base_skill_fitness, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_astronaut_6, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=3) + and state.has(SkillNames.base_skill_fitness, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_astronaut_7, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=3) + and state.has(SkillNames.base_skill_fitness, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_astronaut_8A, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=4) + and state.has(SkillNames.base_skill_fitness, player, count=5)) + set_rule(world.get_location(CareerNames.base_career_astronaut_8B, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=4) + and state.has(SkillNames.base_skill_fitness, player, count=5)) + set_rule(world.get_location(CareerNames.base_career_astronaut_9A, player), + lambda state: state.has(SkillNames.base_skill_fitness, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_astronaut_10A, player), + lambda state: state.has(SkillNames.base_skill_rocket_science, player, count=2) + and state.has(SkillNames.base_skill_fitness, player, count=8)) + set_rule(world.get_location(CareerNames.base_career_astronaut_9B, player), + lambda state: state.has(SkillNames.base_skill_fitness, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_astronaut_10B, player), + lambda state: state.has(SkillNames.base_skill_rocket_science, player, count=2) + and state.has(SkillNames.base_skill_fitness, player, count=8)) + +def _career_business(world: MultiWorld, player: int): + set_rule(world.get_location(CareerNames.base_career_business_5, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_business_6, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_business_7A, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) + and state.has(SkillNames.base_skill_logic, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_business_7B, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=2) + and state.has(SkillNames.base_skill_logic, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_business_8A, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=4) + and state.has(SkillNames.base_skill_logic, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_business_9A, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=6) + and state.has(SkillNames.base_skill_logic, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_business_10A, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=8) + and state.has(SkillNames.base_skill_logic, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_business_8B, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=3) + and state.has(SkillNames.base_skill_logic, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_business_9B, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=4) + and state.has(SkillNames.base_skill_logic, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_business_10B, player), + lambda state: state.has(SkillNames.base_skill_charisma, player, count=6) + and state.has(SkillNames.base_skill_logic, player, count=8)) + +def _career_criminal(world: MultiWorld, player: int): + set_rule(world.get_location(CareerNames.base_career_criminal_4, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_criminal_5, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_criminal_6A, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_criminal_6B, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_criminal_7A, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=5)) + set_rule(world.get_location(CareerNames.base_career_criminal_8A, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_criminal_9A, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=7) + and state.has(SkillNames.base_skill_handiness, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_criminal_10A, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=8) + and state.has(SkillNames.base_skill_handiness, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_criminal_7B, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=5) + and state.has(SkillNames.base_skill_programming, player, count=0)) + set_rule(world.get_location(CareerNames.base_career_criminal_8B, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=6) + and state.has(SkillNames.base_skill_programming, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_criminal_9B, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=7) + and state.has(SkillNames.base_skill_programming, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_criminal_10B, player), + lambda state: state.has(SkillNames.base_skill_mischief, player, count=8) + and state.has(SkillNames.base_skill_programming, player, count=6)) +def _career_culinary(world: MultiWorld, player: int): + set_rule(world.get_location(CareerNames.base_career_culinary_5, player), + lambda state: state.has(SkillNames.base_skill_cooking, player, count=1) + and state.has(SkillNames.base_skill_mixology, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_culinary_6A, player), + lambda state: state.has(SkillNames.base_skill_cooking, player, count=2) + and state.has(SkillNames.base_skill_mixology, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_culinary_6B, player), + lambda state: state.has(SkillNames.base_skill_cooking, player, count=2) + and state.has(SkillNames.base_skill_mixology, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_culinary_7A, player), + lambda state: state.has(SkillNames.base_skill_cooking, player, count=4) + and state.has(SkillNames.base_skill_gourmet, player, count=0) + and state.has(SkillNames.base_skill_mixology, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_culinary_8A, player), + lambda state: state.has(SkillNames.base_skill_cooking, player, count=6) + and state.has(SkillNames.base_skill_gourmet, player, count=4) + and state.has(SkillNames.base_skill_mixology, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_culinary_9A, player), + lambda state: state.has(SkillNames.base_skill_cooking, player, count=6) + and state.has(SkillNames.base_skill_gourmet, player, count=4) + and state.has(SkillNames.base_skill_mixology, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_culinary_10A, player), + lambda state: state.has(SkillNames.base_skill_cooking, player, count=8) + and state.has(SkillNames.base_skill_gourmet, player, count=6) + and state.has(SkillNames.base_skill_mixology, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_culinary_7B, player), + lambda state: state.has(SkillNames.base_skill_mixology, player, count=3) + and state.has(SkillNames.base_skill_charisma, player, count=0) + and state.has(SkillNames.base_skill_cooking, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_culinary_8B, player), + lambda state: state.has(SkillNames.base_skill_mixology, player, count=5) + and state.has(SkillNames.base_skill_charisma, player, count=2) + and state.has(SkillNames.base_skill_cooking, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_culinary_9B, player), + lambda state: state.has(SkillNames.base_skill_mixology, player, count=6) + and state.has(SkillNames.base_skill_charisma, player, count=4) + and state.has(SkillNames.base_skill_cooking, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_culinary_10B, player), + lambda state: state.has(SkillNames.base_skill_mixology, player, count=8) + and state.has(SkillNames.base_skill_charisma, player, count=6) + and state.has(SkillNames.base_skill_cooking, player, count=2)) + +def _career_entertainer(world: MultiWorld, player: int): + set_rule(world.get_location(CareerNames.base_career_entertainer_5A, player), + lambda state: (state.has(SkillNames.base_skill_guitar, player, count=1) + or state.has(SkillNames.base_skill_violin, player, count=1)) + and state.has(SkillNames.base_skill_comedy, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_entertainer_5B, player), + lambda state: (state.has(SkillNames.base_skill_guitar, player, count=1) + or state.has(SkillNames.base_skill_violin, player, count=1)) + and state.has(SkillNames.base_skill_comedy, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_entertainer_6A, player), + lambda state: state.has(SkillNames.base_skill_violin, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_entertainer_7A, player), + lambda state: (state.has(SkillNames.base_skill_guitar, player, count=3) + or state.has(SkillNames.base_skill_violin, player, count=3)) + and state.has(SkillNames.base_skill_piano, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_entertainer_8A, player), + lambda state: (state.has(SkillNames.base_skill_guitar, player, count=4) + or state.has(SkillNames.base_skill_violin, player, count=4)) + and state.has(SkillNames.base_skill_piano, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_entertainer_9A, player), + lambda state: (state.has(SkillNames.base_skill_guitar, player, count=5) + or state.has(SkillNames.base_skill_violin, player, count=5)) + and state.has(SkillNames.base_skill_piano, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_entertainer_10A, player), + lambda state: (state.has(SkillNames.base_skill_guitar, player, count=6) + or state.has(SkillNames.base_skill_violin, player, count=6)) + and state.has(SkillNames.base_skill_piano, player, count=8)) + set_rule(world.get_location(CareerNames.base_career_entertainer_6B, player), + lambda state: state.has(SkillNames.base_skill_comedy, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_entertainer_7B, player), + lambda state: state.has(SkillNames.base_skill_comedy, player, count=5)) + set_rule(world.get_location(CareerNames.base_career_entertainer_8B, player), + lambda state: state.has(SkillNames.base_skill_comedy, player, count=6) + and state.has(SkillNames.base_skill_charisma, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_entertainer_9B, player), + lambda state: state.has(SkillNames.base_skill_comedy, player, count=7) + and state.has(SkillNames.base_skill_charisma, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_entertainer_10B, player), + lambda state: state.has(SkillNames.base_skill_comedy, player, count=8) + and state.has(SkillNames.base_skill_charisma, player, count=6)) + +def _career_painter(world: MultiWorld, player: int): + set_rule(world.get_location(CareerNames.base_career_painter_4, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_painter_5, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_painter_6, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_painter_7A, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=5)) + set_rule(world.get_location(CareerNames.base_career_painter_7B, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=5)) + set_rule(world.get_location(CareerNames.base_career_painter_8A, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_painter_9A, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=7) + and state.has(SkillNames.base_skill_logic, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_painter_10A, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=8) + and state.has(SkillNames.base_skill_logic, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_painter_8B, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_painter_9B, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=7) + and state.has(SkillNames.base_skill_charisma, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_painter_10B, player), + lambda state: state.has(SkillNames.base_skill_painting, player, count=8) + and state.has(SkillNames.base_skill_charisma, player, count=4)) +def _career_secret_agent(world: MultiWorld, player: int): + set_rule(world.get_location(CareerNames.base_career_secret_agent_4, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=1) + and state.has(SkillNames.base_skill_charisma, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_secret_agent_5, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=1) + and state.has(SkillNames.base_skill_charisma, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_secret_agent_6, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=3) + and state.has(SkillNames.base_skill_charisma, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_secret_agent_7, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=3) + and state.has(SkillNames.base_skill_charisma, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_secret_agent_8A, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=4) + and state.has(SkillNames.base_skill_charisma, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_secret_agent_8B, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=4) + and state.has(SkillNames.base_skill_charisma, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_secret_agent_9A, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=6) + and state.has(SkillNames.base_skill_charisma, player, count=5)) + set_rule(world.get_location(CareerNames.base_career_secret_agent_10A, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=8) + and state.has(SkillNames.base_skill_charisma, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_secret_agent_9B, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_secret_agent_10B, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=8) + and state.has(SkillNames.base_skill_mischief, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_secret_agent_11B, player), + lambda state: state.has(SkillNames.base_skill_logic, player, count=8) + and state.has(SkillNames.base_skill_mischief, player, count=4)) +def _career_style_influencer(world: MultiWorld, player: int): + set_rule(world.get_location(CareerNames.base_career_style_influencer_4, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_5, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_6A, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=3) + and state.has(SkillNames.base_skill_charisma, player, count=1) + and state.has(SkillNames.base_skill_painting, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_7A, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=4) + and state.has(SkillNames.base_skill_charisma, player, count=3) + and state.has(SkillNames.base_skill_painting, player, count=2) + and state.has(SkillNames.base_skill_photography, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_8A, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=5) + and state.has(SkillNames.base_skill_charisma, player, count=4) + and state.has(SkillNames.base_skill_painting, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_9A, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=6) + and state.has(SkillNames.base_skill_charisma, player, count=5) + and state.has(SkillNames.base_skill_painting, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_10A, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=7) + and state.has(SkillNames.base_skill_charisma, player, count=6) + and state.has(SkillNames.base_skill_painting, player, count=5)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_6B, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=3) + and state.has(SkillNames.base_skill_charisma, player, count=1) + and state.has(SkillNames.base_skill_painting, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_7B, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=4) + and state.has(SkillNames.base_skill_charisma, player, count=3) + and state.has(SkillNames.base_skill_painting, player, count=2) + and state.has(SkillNames.base_skill_photography, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_8B, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=5) + and state.has(SkillNames.base_skill_charisma, player, count=4) + and state.has(SkillNames.base_skill_painting, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_9B, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=6) + and state.has(SkillNames.base_skill_charisma, player, count=5) + and state.has(SkillNames.base_skill_painting, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_style_influencer_10B, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=7) + and state.has(SkillNames.base_skill_charisma, player, count=6) + and state.has(SkillNames.base_skill_painting, player, count=5)) +def _career_tech_guru(world: MultiWorld, player: int): + # TODO check project manager career logic https://discord.com/channels/731205301247803413/1079002955262480424/1403764728177758252 + set_rule(world.get_location(CareerNames.base_career_tech_guru_4, player), + lambda state: has_skill(state, SkillNames.base_skill_programming, player, 3)) + set_rule(world.get_location(CareerNames.base_career_tech_guru_5, player), + lambda state: has_skill(state, SkillNames.base_skill_programming, player, 4) + and has_skill(state, SkillNames.base_skill_video_gaming, player, 3)) + set_rule(world.get_location(CareerNames.base_career_tech_guru_6, player), + lambda state: state.has(SkillNames.base_skill_programming, player, count=3) + and state.has(SkillNames.base_skill_video_gaming, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_tech_guru_7A, player), + lambda state: state.has(SkillNames.base_skill_programming, player, count=4) + and state.has(SkillNames.base_skill_video_gaming, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_tech_guru_7B, player), + lambda state: state.has(SkillNames.base_skill_programming, player, count=4) + and state.has(SkillNames.base_skill_video_gaming, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_tech_guru_8A, player), + lambda state: state.has(SkillNames.base_skill_programming, player, count=4) + and state.has(SkillNames.base_skill_video_gaming, player, count=4)) + set_rule(world.get_location(CareerNames.base_career_tech_guru_9A, player), + lambda state: state.has(SkillNames.base_skill_programming, player, count=5) + and state.has(SkillNames.base_skill_video_gaming, player, count=6)) + set_rule(world.get_location(CareerNames.base_career_tech_guru_10A, player), + lambda state: state.has(SkillNames.base_skill_programming, player, count=6) + and state.has(SkillNames.base_skill_video_gaming, player, count=8)) + set_rule(world.get_location(CareerNames.base_career_tech_guru_8B, player), + lambda state: state.has(SkillNames.base_skill_programming, player, count=6) + and state.has(SkillNames.base_skill_charisma, player, count=0)) + set_rule(world.get_location(CareerNames.base_career_tech_guru_9B, player), + lambda state: state.has(SkillNames.base_skill_programming, player, count=7) + and state.has(SkillNames.base_skill_charisma, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_tech_guru_10B, player), + lambda state: state.has(SkillNames.base_skill_programming, player, count=8) + and state.has(SkillNames.base_skill_charisma, player, count=4)) +def _career_writer(world: MultiWorld, player: int): + set_rule(world.get_location(CareerNames.base_career_writer_4, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_writer_5, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_writer_6A, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_writer_6B, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_writer_7A, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=5)) + set_rule(world.get_location(CareerNames.base_career_writer_8A, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=6) + and state.has(SkillNames.base_skill_logic, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_writer_9A, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=7) + and state.has(SkillNames.base_skill_logic, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_writer_10A, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=8) + and state.has(SkillNames.base_skill_logic, player, count=3)) + set_rule(world.get_location(CareerNames.base_career_writer_7B, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=5)) + set_rule(world.get_location(CareerNames.base_career_writer_8B, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=6) + and state.has(SkillNames.base_skill_charisma, player, count=1)) + set_rule(world.get_location(CareerNames.base_career_writer_9B, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=7) + and state.has(SkillNames.base_skill_charisma, player, count=2)) + set_rule(world.get_location(CareerNames.base_career_writer_10B, player), + lambda state: state.has(SkillNames.base_skill_writing, player, count=8) + and state.has(SkillNames.base_skill_charisma, player, count=3)) + +CAREER_RULES = { + CareerNames.base_career_athlete: _career_athlete, + CareerNames.base_career_astronaut: _career_astronaut, + CareerNames.base_career_business: _career_business, + CareerNames.base_career_criminal: _career_criminal, + CareerNames.base_career_culinary: _career_culinary, + CareerNames.base_career_entertainer: _career_entertainer, + CareerNames.base_career_painter: _career_painter, + CareerNames.base_career_secret_agent: _career_secret_agent, + CareerNames.base_career_style_influencer: _career_style_influencer, + CareerNames.base_career_tech_guru: _career_tech_guru, + CareerNames.base_career_writer: _career_writer, +} + +def set_career_rules(world: MultiWorld, player: int, options: Sims4Options): + # TODO relearn how the career locations send, and then refactor this to use has_skill + career = options.career + + for career_name, handler in CAREER_RULES.items(): + if career_name in career: + handler(world, player) def count_skills_over(threshold: int, state, player) -> int: total_count = 0 @@ -763,6 +853,7 @@ def has_skill(state: CollectionState, skill: str, player: int, skill_level: int) # determines how many skill items are required based on the skill level passed into the function skills_required: int = skill_level - 2 return state.has(skill, player, skills_required) + def has_multiple_skills(state: CollectionState, skills_and_levels: dict[str, int], player: int): skills = list(skills_and_levels.keys()) - return has_skill(state, skills[0], player, skills_and_levels[skills[0]]) and has_skill(state, skills[1], player, skills_and_levels[skills[1]]) + return has_skill(state, skills[0], player, skills_and_levels[skills[0]]) and has_skill(state, skills[1], player, skills_and_levels[skills[1]]) \ No newline at end of file diff --git a/worlds/sims4/Version.py b/worlds/sims4/Version.py index 688056448192..1a738e528a07 100644 --- a/worlds/sims4/Version.py +++ b/worlds/sims4/Version.py @@ -1,4 +1,4 @@ -VERSION: tuple[int, int, int] | tuple[int, int, int, str] = (2, 0, 0, "rc2") +VERSION: tuple[int, int, int] | tuple[int, int, int, str] = (2, 0, 0, "rc3") class Sims4Version: @@ -26,5 +26,8 @@ def is_rc(version: tuple[int, int, int] | tuple[int, int, int, str]) -> bool: return len(version) == 4 @staticmethod - def does_major_version_mismatch(client_version: tuple[int, int, int] | tuple[int, int, int, str], server_version: tuple[int, int, int] | tuple[int, int, int, str]) -> bool: + def does_major_version_mismatch( + client_version: tuple[int, int, int] | tuple[int, int, int, str], + server_version: tuple[int, int, int] | tuple[int, int, int, str] + ) -> bool: return client_version[0] != server_version[0] diff --git a/worlds/sims4/__init__.py b/worlds/sims4/__init__.py index 6371d0123647..e578135e1a0a 100644 --- a/worlds/sims4/__init__.py +++ b/worlds/sims4/__init__.py @@ -1,24 +1,26 @@ # standard lib imports -from typing import Mapping, Any, ClassVar +from typing import Any, ClassVar +from collections.abc import Mapping # ap imports -from BaseClasses import Item, ItemClassification, Region, Entrance +from BaseClasses import ItemClassification, Region, Entrance from worlds.AutoWorld import World from ..LauncherComponents import Component, components, Type, icon_paths, launch # TS4 specific imports from .Locations import location_table, Sims4Location, skill_locations_table -from .Items import item_table, skills_table, Sims4Item, junk_table, filler_set -from .Options import Sims4Options -from .Regions import sims4_careers, sims4_aspiration_milestones, sims4_skill_dependencies, \ - sims4_regions -from .Rules import set_rules as ts4_set_rules +from .Items import item_table, Sims4Item, junk_table, filler_set +from .Names import EventNames +from .Options import AspirationGoal, Sims4Options +from .Regions import sims4_careers, sims4_aspiration_milestones +from .Rules import set_rules from .Groups import location_name_groups, item_name_groups from .UT import UTMixin from .Settings import Sims4Settings from .Web import Sims4Web from .Version import VERSION, Sims4Version + def run_client(*args: str) -> None: from .Client import main launch(main, name="The Sims 4 Client", args=args) @@ -28,6 +30,7 @@ def run_client(*args: str) -> None: icon_paths["plumbob"] = f"ap:{__name__}/icons/plumbob.png" + class Sims4World(World, UTMixin): """ The Sims 4 is the fourth installment in The Sims franchise. Like the previous games in the series, @@ -55,26 +58,61 @@ class Sims4World(World, UTMixin): settings: ClassVar[Sims4Settings] - # ut_can_gen_without_yaml = True - # passthrough: dict[str, Any] + GOAL_TO_EVENT_MAPPING: ClassVar[dict[int, tuple[str, str]]] = { + AspirationGoal.option_bodybuilder: (EventNames.bodybuilder, EventNames.bodybuilder_item), + AspirationGoal.option_painter_extraordinaire: ( + EventNames.painter_extraordinaire, EventNames.painter_extraordinaire_item + ), + AspirationGoal.option_bestselling_author: (EventNames.bestselling_author, EventNames.bestselling_author_item), + AspirationGoal.option_musical_genius: (EventNames.musical_genius, EventNames.musical_genius_item), + AspirationGoal.option_public_enemy: (EventNames.public_enemy, EventNames.public_enemy_item), + AspirationGoal.option_chief_of_mischief: (EventNames.chief_of_mischief, EventNames.chief_of_mischief_item), + AspirationGoal.option_master_chef: (EventNames.master_chef, EventNames.master_chef_item), + AspirationGoal.option_master_mixologist: (EventNames.master_mixologist, EventNames.master_mixologist_item), + AspirationGoal.option_renaissance_sim: (EventNames.renaissance_sim, EventNames.renaissance_sim_item), + AspirationGoal.option_nerd_brain: (EventNames.nerd_brain, EventNames.nerd_brain_item), + AspirationGoal.option_computer_whiz: (EventNames.computer_whiz, EventNames.computer_whiz_item), + AspirationGoal.option_serial_romantic: (EventNames.serial_romantic, EventNames.serial_romantic_item), + AspirationGoal.option_freelance_botanist: (EventNames.freelance_botanist, EventNames.freelance_botanist_item), + AspirationGoal.option_the_curator: (EventNames.the_curator, EventNames.the_curator_item), + AspirationGoal.option_angling_ace: (EventNames.angling_ace, EventNames.angling_ace_item), + AspirationGoal.option_joke_star: (EventNames.joke_star, EventNames.joke_star_item), + AspirationGoal.option_friend_of_the_world: ( + EventNames.friend_of_the_world, EventNames.friend_of_the_world_item + ), + AspirationGoal.option_neighborly_advisor: ( + EventNames.neighborly_advisor, EventNames.neighborly_advisor_item + ) + } def generate_early(self) -> None: # this is specific to UT, it doesn't apply unless UT is being used self.get_options_from_slot_data(self) - - def create_item(self, name: str) -> Item: + def create_item(self, name: str) -> Sims4Item: item_id: int = self.item_name_to_id[name] return Sims4Item(name, item_table[item_id]["classification"], - item_id, player=self.player) + item_id, self.player) + + def create_location(self, name: str, parent: Region) -> Sims4Location: + location_id: int = self.location_name_to_id[name] - def create_event(self, event: str): + return Sims4Location(self.player, name, location_id, parent) + + def create_event(self, event: str) -> Sims4Item: return Sims4Item(event, ItemClassification.progression, None, self.player) + def create_event_location(self, event: str, region: Region) -> Sims4Location: + return Sims4Location(self.player, event, None, region) + def create_items(self) -> None: - used_dlc = set(self.options.expansion_packs.value | self.options.game_packs.value | self.options.stuff_packs.value) + used_dlc = set( + self.options.expansion_packs.value | + self.options.game_packs.value | + self.options.stuff_packs.value + ) pool = [] unfilled_locations = len(self.multiworld.get_unfilled_locations(self.player)) @@ -92,44 +130,50 @@ def create_items(self) -> None: self.multiworld.itempool += pool - def create_region(self, name: str, locations=None, exits=None): + def create_region(self, name: str, locations: list[str] | None = None, exits: list[str] | None = None) -> Region: ret = Region(name, self.player, self.multiworld) if locations: - for location in locations: - loc_id = self.location_name_to_id.get(location, None) - location = Sims4Location(self.player, location, loc_id, ret) + for location_name in locations: + location = self.create_location(location_name, ret) ret.locations.append(location) if exits: for region_exit in exits: ret.exits.append(Entrance(self.player, region_exit, ret)) return ret - def create_regions(self): + def create_regions(self) -> None: menu = self.create_region("Menu", locations=None, exits=None) chosen_careers = sorted(self.options.career.value) - aspiration_key = self.options.goal.current_key + goal = self.options.goal + goal_value = goal.value + aspiration_key = goal.current_key for career_key in chosen_careers: for career in sims4_careers[career_key.lower().replace(" ", "_")]: - menu.locations.append( - Sims4Location(self.player, career, self.location_name_to_id.get(career), menu)) + menu.locations.append(self.create_location(career, menu)) for aspiration in sims4_aspiration_milestones[aspiration_key]: - menu.locations.append( - Sims4Location(self.player, aspiration, self.location_name_to_id.get(aspiration), menu) - ) - used_dlc = set(self.options.expansion_packs.value | self.options.game_packs.value | self.options.stuff_packs.value) + menu.locations.append(self.create_location(aspiration, menu)) + used_dlc = set( + self.options.expansion_packs.value | + self.options.game_packs.value | + self.options.stuff_packs.value + ) for skill in skill_locations_table.values(): skill_name = skill["name"] if skill['expansion'] == 'base' or skill['expansion'] in used_dlc: - menu.locations.append( - Sims4Location(self.player, skill_name, self.location_name_to_id.get(skill_name), menu) - ) + menu.locations.append(self.create_location(skill_name, menu)) + mapping = self.GOAL_TO_EVENT_MAPPING.get(goal_value) + if mapping: + event_name, item_name = mapping + event = self.create_event_location(event_name, menu) + menu.locations.append(event) + event.place_locked_item(self.create_event(item_name)) + self.multiworld.regions.append(menu) def set_rules(self) -> None: - ts4_set_rules(self) + set_rules(self.multiworld, self.player, self.options) def fill_slot_data(self) -> Mapping[str, Any]: - # slot_data = self.options.as_dict("goal", "career", "expansion_packs", "game_packs", "stuff_packs", "cas_kits", "build_kits") slot_data = { "goal": self.options.goal.current_key, "career": self.options.career.value, diff --git a/worlds/sims4/archipelago.json b/worlds/sims4/archipelago.json index b89d0e7a8db4..464cdbf7753e 100644 --- a/worlds/sims4/archipelago.json +++ b/worlds/sims4/archipelago.json @@ -1,6 +1,6 @@ { "game": "The Sims 4", "world_version": "2.0.0", - "world_version_full": "2.0.0-beta2", + "world_version_full": "2.0.0-beta3", "contributors": ["mrsummer360", "itsmisscactus", "silasary"] }