Exemple #1
0
    def consume(self, consumer):
        if not consumer.inventory.find("lighter"):
            if consumer is _G.player:
                say.insayne(f"You have no way to light the {self.name}.")
                return
        consumer.inventory.remove(self)
        cigarette_butt = CigaretteButt.create()
        consumer.inventory.add(cigarette_butt)
        consumer.current_room.items.add(Smoke.create(consumer.current_room))

        if consumer is _G.player:
            say.insayne(
                f"You take a furtive puff on the {self.name}. It tastes foul "
                "and acrid. You do not feel like you are wearing a leather "
                "jacket at all.")
            consumer.psyche.heal_or_harm(dice.roll("1d2"))
            # TODO: Make insanity a variable statistic?
            consumer.insanity.heal_or_harm(-dice.roll("1d2"))
            # TODO: Interesting problem with how this is implemented:
            # because text is not queued but printed directly, if this line
            # precedes anything else in this function and player dies,
            # weird stuff will ensue.
            consumer.health.heal_or_harm(-dice.roll("2d2"),
                                         cause="smoking half a cig")
        else:
            name = say.capitalized(consumer.name)
            say.insayne(f"{name} puffs furtively on a {self.name}.")
Exemple #2
0
    def consume(self, consumer):
        if not consumer.inventory.find("lighter"):
            if consumer is _G.player:
                say.insayne(f"You have no way to light the {self.name}.")
                return

        # TODO: Buff strength for a little bit.
        # TODO: Heal insanity, restore psyche.
        # TODO: I don't like this solution as it presumes the item is in the
        # consumer's inventory. Maybe that is a fine assumption. If not,
        # consider storing the inventory relationship as two-way.
        consumer.inventory.remove(self)
        cigarette_stub = CigaretteStub.create()
        consumer.inventory.add(cigarette_stub)
        consumer.current_room.items.add(Smoke.create(consumer.current_room))

        # TODO: Customize text based on whether consumer is player.
        # TODO: Add location to actors so that the state of onlookers can
        # be properly assessed.
        aliases = random.sample(self.aliases, 2)
        if consumer is _G.player:
            say.insayne(
                f"You take a long, smooth drag on the {aliases[0]}. Time seems "
                "to mellow; all activity nearby slows. Onlookers watch as you "
                "draw measured, pensive little puffs from the delicious "
                f"{aliases[1]}. You look very cool.")
            consumer.health.heal_or_harm(-dice.roll("1d2"), cause="being cool")
            consumer.psyche.heal_or_harm(dice.roll("2d2"))
            # TODO: Make insanity a variable statistic?
            consumer.insanity.heal_or_harm(-dice.roll("2d2"))
        else:
            name = say.capitalized(consumer.name)
            say.insayne(
                f"{name} puffs mellowly on a {self.name}, looking extremely fly."
            )
Exemple #3
0
def _resolve_attack(attacker, attack):
    # TODO: Add equipment, different damage dice, etc.
    # TODO: Respect attack.method.
    defender = attack.target
    is_player = attacker is G.player
    if is_player:
        subj, obj = ["you", defender.name]
    else:
        subj, obj = [attacker.name, "you"]
    subj = say.capitalized(subj)
    miss = "miss" if is_player else "misses"
    hit = "hit" if is_player else "hits"

    strength_mod = int((attacker.strength.value - 10) / 2)
    to_hit = strength_mod + dice.roll("1d20")
    if to_hit < (10 + (defender.stamina.value - 10) / 2):
        say.insayne(f"{subj} {miss}.")

    else:
        damage = dice.roll("1d8") + strength_mod
        # TODO: How to organize messages better? Death also creates text, so
        # there should be a way to make sure the messages are ordered.
        say.insayne(f"{subj} {hit} {obj} for {damage} damage!")
        # TODO: Attack should have associated text which is consulted here.
        defender.health.heal_or_harm(
            -1 * damage, cause=f"the fins of {say.a(attacker.name)}")

    if not (is_player or defender.alive):
        G.just_died = True
 def execute(self):
     self._timer += 1
     if self._timer % 3 != 0:
         return
     roll = dice.roll("1d10")
     if roll <= 4:
         return
     cig = items.Cigarette.create()
     self.owner.inventory.add(cig)
     cig.consume(self.owner)
Exemple #5
0
 def test_roll_range(self):
     possible_values = set(range(1, 11))
     for _ in range(100):
         self.assertIn(dice.roll("d10"), possible_values)
Exemple #6
0
 def test_roll_parses_expression(self):
     with patch("random.randint", new_callable=_MockRandom):
         self.assertEqual(4, dice.roll("d3"))
         self.assertEqual(3, dice.roll("1d2"))
         self.assertEqual(4, dice.roll("2d1"))
 def execute(self):
     if self._counter % 3 == 0:
         say.insayne("The heat is too much for you.")
         G.player.health.heal_or_harm(-1 * dice.roll("1d2"),
                                      cause="sweating in the boiler room")
     self._counter += 1
 def execute(self):
     if dice.roll("1d100") > 90:
         say.insayne("A drop of acid falls on your head.")
         G.player.health.heal_or_harm(-1 * dice.roll("1d2"),
                                      cause="being scalded with acid")
    def generate(cls, theme, number_rooms=None):
        if theme == "office":
            return _generate_office()

        room_dict = {}
        room_list = rooms.get_rooms(number=number_rooms, theme=theme)
        start_coordinate = _Coordinate(10, 10)
        coordinate_queue = collections.deque()
        coordinate_queue.append(start_coordinate)

        for room in room_list:
            if not coordinate_queue:
                break
            if len(room_dict) >= number_rooms:
                break

            # Finds an unoccupied coordinate.
            while True:
                coordinate = coordinate_queue.popleft()
                if room_dict.get(coordinate) is None:
                    break

            # Creates a new room in that location.
            room_dict[coordinate] = room

            for direction in ["north", "south", "east", "west"]:
                new_coordinate = getattr(coordinate, direction)
                next_room = room_dict.get(new_coordinate)
                if next_room is None:
                    coordinate_queue.append(new_coordinate)

                else:
                    # Adds some exits.
                    if dice.roll("1d100") > 50:
                        _add_exit(room, next_room, direction)

        # Traverse room graph. If any rooms are not connected, use a
        # non-Euclidean entrance to address that.
        # TODO: pop() isn't really random!! Does that matter?
        all_rooms = set(room_dict.values())
        traversed_rooms = set()
        last_cohort = set()

        while all_rooms:
            next_room = all_rooms.pop()
            if last_cohort:
                logging.debug("adding a weird transition")
                next_room.add_exit(directions.purple, traversed_rooms.pop())
                last_cohort.clear()
            traversed_rooms.add(next_room)
            last_cohort.add(next_room)
            traversal_queue = collections.deque()
            traversal_queue.append(next_room)
            while traversal_queue:
                next_room = traversal_queue.popleft()
                actual_room = next_room

                for exit in actual_room.exits:
                    destination, _ = actual_room.exit(exit)
                    destination_number = destination
                    if destination_number in all_rooms:
                        all_rooms.remove(destination_number)
                        traversed_rooms.add(destination_number)
                        last_cohort.add(destination_number)
                        traversal_queue.append(destination_number)

        return Floor(room_dict)