Exemple #1
0
def unnamed_monster(level: int, iterations: int) -> Monster:
    result = T.cast(Monster, random.choice(MONSTERS))
    for _ in range(iterations):
        alternative = T.cast(Monster, random.choice(MONSTERS))
        if abs(level - alternative.level) < abs(level - result.level):
            result = alternative
    return result
Exemple #2
0
def pick_equipment(
    source: T.List[EquipmentPreset], goal: int
) -> EquipmentPreset:
    result = T.cast(EquipmentPreset, random.choice(source))
    for _ in range(5):
        alternative = T.cast(EquipmentPreset, random.choice(source))
        if abs(goal - alternative.quality) < abs(goal - result.quality):
            result = alternative
    return result
Exemple #3
0
def generate_name() -> str:
    parts = [
        "br|cr|dr|fr|gr|j|kr|l|m|n|pr||||r|sh|tr|v|wh|x|y|z".split("|"),
        "a|a|e|e|i|i|o|o|u|u|ae|ie|oo|ou".split("|"),
        "b|ck|d|g|k|m|n|p|t|v|x|z".split("|"),
    ]
    result = ""
    for i in range(6):
        result += random.choice(parts[i % 3])
    return result.title()
Exemple #4
0
    def win_equipment(self) -> None:
        choice = random.choice(list(EquipmentType))

        stuff: T.List[EquipmentPreset]
        better: T.List[Modifier]
        worse: T.List[Modifier]

        if choice == EquipmentType.weapon:
            stuff = WEAPONS
            better = OFFENSE_ATTRIB
            worse = OFFENSE_BAD
        else:
            stuff = SHIELDS if choice == EquipmentType.shield else ARMORS
            better = DEFENSE_ATTRIB
            worse = DEFENSE_BAD

        equipment = pick_equipment(stuff, self.level)
        name = equipment.name
        plus = self.level - equipment.quality
        if plus < 0:
            modifier_pool = worse
        else:
            modifier_pool = better
        count = 0
        while count < 2 and plus:
            modifier = random.choice(modifier_pool)
            if modifier.name in name:
                break  # no repeats
            if abs(plus) < abs(modifier.quality):
                break  # too much
            name = modifier.name + " " + name
            plus -= modifier.quality
            count += 1

        if plus < 0:
            name = f"{plus} {name}"
        if plus > 0:
            name = f"+{plus} {name}"

        logger.info("Gained %s %s", name, choice.value)
        self.equipment.put(choice, name)
Exemple #5
0
    def complete_quest(self) -> None:
        self.player.quest_book.quest_bar.reset(50 + random.below_low(1000))
        if self.player.quest_book.current_quest:
            logger.info(
                "Quest completed: %s", self.player.quest_book.current_quest
            )
            random.choice(
                [
                    self.player.win_spell,
                    self.player.win_equipment,
                    self.player.win_stat,
                    self.player.win_item,
                ]
            )()

        self.player.quest_book.monster = None
        caption = ""
        choice = random.below(5)
        if choice == 0:
            self.player.quest_book.monster = unnamed_monster(
                self.player.level, iterations=3
            )
            caption = "Exterminate " + definite(
                self.player.quest_book.monster.name, 2
            )
        elif choice == 1:
            caption = "Seek " + definite(interesting_item(), 1)
        elif choice == 2:
            caption = "Deliver this " + boring_item()
        elif choice == 3:
            caption = "Fetch me " + indefinite(boring_item(), 1)
        elif choice == 4:
            monster = unnamed_monster(self.player.level, iterations=1)
            caption = "Placate " + definite(monster.name, 2)
        else:
            raise AssertionError

        self.player.quest_book.add_quest(caption)
        self.player.quest_book.emit("start_quest", caption)
Exemple #6
0
    def win_stat(self) -> bool:
        chosen_stat: T.Optional[StatType] = None

        if random.odds(1, 2):
            chosen_stat = random.choice(list(StatType))
        else:
            # favor the best stat so it will tend to clump
            t = sum(value ** 2 for _stat, value in self.stats)
            t = random.below(t)
            chosen_stat = None
            for stat, value in self.stats:
                chosen_stat = stat
                t -= value ** 2
                if t < 0:
                    break

        assert chosen_stat is not None
        self.stats.increment(chosen_stat)
        if chosen_stat == StatType.strength:
            self.inventory.set_capacity(10 + self.stats[StatType.strength])
        return True
Exemple #7
0
def monster_task(
    player_level: int, quest_monster: T.Optional[Monster]
) -> KillTask:
    level = player_level
    for _ in range(level):
        if random.odds(2, 5):
            level += random.below(2) * 2 - 1
    if level < 1:
        level = 1

    is_definite = False
    monster: T.Optional[Monster] = None
    if random.odds(1, 25):
        # use an NPC every once in a while
        race = random.choice(RACES)
        if random.odds(1, 2):
            result = "passing " + race.name + " " + random.choice(CLASSES).name
        else:
            result = (
                random.choice_low(TITLES)
                + " "
                + generate_name()
                + " the "
                + race.name
            )
            is_definite = True
        lev = level
    elif quest_monster and random.odds(1, 4):
        # use the quest monster
        monster = quest_monster
        result = monster.name
        lev = monster.level
    else:
        # pick the monster out of so many random ones closest to the level we want
        monster = unnamed_monster(level, iterations=5)
        result = monster.name
        lev = monster.level

    qty = 1
    if level - lev > 10:
        # lev is too low. multiply
        qty = (level + random.below(max(lev, 1))) // max(lev, 1)
        if qty < 1:
            qty = 1
        level //= qty

    if level - lev <= -10:
        result = "imaginary " + result
    elif level - lev < -5:
        i = 10 + level - lev
        i = 5 - random.below(i + 1)
        result = sick(i, young(lev - level - i, result))
    elif level - lev < 0 and random.below(2) == 1:
        result = sick(level - lev, result)
    elif level - lev < 0:
        result = young(level - lev, result)
    elif level - lev >= 10:
        result = "messianic " + result
    elif level - lev > 5:
        i = 10 - (level - lev)
        i = 5 - random.below(i + 1)
        result = big(i, special(level - lev - i, result))
    elif level - lev > 0 and random.below(2) == 1:
        result = big(level - lev, result)
    elif level - lev > 0:
        result = special(level - lev, result)

    lev = level
    level = lev * qty
    if not is_definite:
        result = indefinite(result, qty)

    duration = (2 * 3 * level * 1000) // player_level
    return KillTask(f"Executing {result}", duration, monster=monster)
Exemple #8
0
def impressive_guy() -> str:
    return T.cast(str, random.choice(IMPRESSIVE_TITLES)) + (
        " of the " + T.cast(Race, random.choice(RACES)).name
        if random.below(2)
        else " of " + generate_name()
    )
Exemple #9
0
def boring_item() -> str:
    return T.cast(str, random.choice(BORING_ITEMS))
Exemple #10
0
def interesting_item() -> str:
    return (
        T.cast(str, random.choice(ITEM_ATTRIB))
        + " "
        + T.cast(str, random.choice(SPECIALS))
    )
Exemple #11
0
def special_item() -> str:
    return interesting_item() + " of " + T.cast(str, random.choice(ITEM_OFS))
Exemple #12
0
def terminate_message(player_name: str) -> str:
    adjective = random.choice(["faithful", "noble", "loyal", "brave"])
    return f"Terminate {adjective} {player_name}?"