Exemple #1
0
    def go_get_drop(self, area: Area):
        self.end_ambush()
        out = self.go_to(area)
        if out is not None:
            Narrator().add([self.name, f'goes {out.to} to get loot'])
        else:
            Narrator().cut()
        if self.check_for_ambush_and_traps():
            return
        seen_neighbors = [
            p for p in Map().potential_players(self)
            if self.can_see(p) and p != self
        ]
        free_neighbors = [
            p for p in seen_neighbors
            if p.current_area == self.current_area and not p.busy
        ]
        potential_danger = sum([p.dangerosity for p in seen_neighbors])
        actual_danger = sum([p.dangerosity for p in free_neighbors])

        if potential_danger > self.dangerosity and potential_danger > self.courage:
            Narrator().add([
                self.name, 'sees',
                format_list([p.name for p in seen_neighbors])
            ])
            self.flee(filtered_areas=[area])
        elif actual_danger > self.dangerosity and actual_danger > self.courage:
            Narrator().add([
                self.name, 'sees',
                format_list([p.name for p in free_neighbors])
            ])
            self.flee(filtered_areas=[area])
        elif actual_danger > 0:  # enemy present -> fight them
            Narrator().cut()
            self.attack_at_random()
        elif potential_danger > 0 and actual_danger == 0:  # enemy busy but incoming
            if self.dangerosity > potential_danger:  # attack before the other(s) arrive
                Narrator().cut()
                self.attack_at_random()
            else:  # loot and go/get your load and hit the road
                Narrator().add([
                    self.name, 'avoids',
                    format_list([p.name for p in seen_neighbors])
                ])
                self.loot(take_a_break=False)
                self.flee(filtered_areas=[area])
        else:  # servez-vous
            self.loot()
        if len(Narrator().current_sentence) == 0:
            Narrator().add([
                self.name,
                f'potential_danger={potential_danger}',
                f'actual_danger={actual_danger}',
                f'dangerosity={self.dangerosity}',
                f'courage={self.courage}',
            ])
Exemple #2
0
 def pillage(self, stuff):
     if len([p for p in Context().alive_players if p.is_alive]) == 1:
         return
     if Map().players_count(self) > 1:
         return
     looted = []
     for item in stuff:
         if item not in Map().loot(self.current_area):
             continue
         if isinstance(item, Weapon):
             if item.damage_mult > self.weapon.damage_mult:
                 looted.append(item)
                 Map().remove_loot(item, self.current_area)
         else:
             looted.append(item)
             Map().remove_loot(item, self.current_area)
     if not len(looted):
         return
     Narrator().add(
         [self.name, 'loots',
          format_list([e.long_name for e in looted])])
     for item in looted:
         if isinstance(item, Weapon):
             self.get_weapon(item)
         else:
             self.get_item(item)
Exemple #3
0
 def check_bag(self):
     if 'unchecked bag' in self.status:
         self.status.remove('unchecked bag')
         bags = [e for e in self._equipment if isinstance(e, Bag)]
         if not len(bags):
             return
         stuff = [e.name for bag in bags for e in bag.content]
         if len(stuff):
             Narrator().new([
                 self.name, 'checks', self.his,
                 'bags,' if len(bags) > 1 else 'bag,', 'finds',
                 format_list(stuff)
             ])
             Narrator().cut()
         else:
             Narrator().new([
                 self.name, 'checks', self.his,
                 'bags,' if len(bags) > 1 else 'bag,', 'finds',
                 'they are' if len(bags) > 1 else 'it is', 'empty'
             ])
             Narrator().cut()
         for i in range(1, len(bags)):
             extra_bag = bags[i]
             self._equipment.remove(extra_bag)
             bags[0].content.extend(extra_bag.content)
         bag_weapons = [
             i for i in bags[0].content if isinstance(i, Weapon)
             and i.damage_mult > self.weapon.damage_mult
         ]
         bag_weapons.sort(key=lambda x: -x.damage_mult)
         if len(bag_weapons):
             bags[0].content.remove(bag_weapons[0])
             self.get_weapon(bag_weapons[0])
Exemple #4
0
    def run(self):
        self.day = 1
        self._event_gauge = 0
        self._players_at_last_event = len(self.alive_players)
        self._time_since_last_event = 0
        Narrator().new(f'== DAY {self.day} START ==')
        Narrator().new(['All players start', self.map.get_area(START_AREA).at])
        self.time = STARTER
        Context().forbidden_areas.append(self.map.get_area(START_AREA))
        rounds = 0
        while len(self.playing_entities_at(self.map.get_area(START_AREA))) > 1:
            Narrator().tell()
            self.launch()
            Narrator().tell(filters=[self.map.get_area(START_AREA).at])
            Narrator().new(f'...')
            if self.map.players_count(START_AREA) > 1:
                Narrator().new([
                    format_list([p.name for p in self.alive_players if p.current_area.is_start]),
                    'remain',
                    self.map.get_area(START_AREA).at
                ])
            elif self.map.players_count(START_AREA) == 1:
                Narrator().new([
                    'Only',
                    [p for p in self.alive_players if p.current_area.is_start][0].name,
                    'remains',
                    self.map.get_area(START_AREA).at
                ])
                Narrator().tell()
                self.launch()
                Narrator().tell(filters=[self.map.get_area(START_AREA).at])
            rounds += 1
            if rounds > 10:
                raise Exception
        self._players_at_last_event = len(self.alive_players)

        while len(self.alive_players) > 1 and self.day < 10:
            if self.day != 1:
                self.time = MORNING
                self.launch()
            if len(self.alive_players) < 2:
                break
            Narrator().new(f'-- DAY {self.day} afternoon --')
            self.time = AFTERNOON
            self.launch()
            if len(self.alive_players) < 2:
                break
            Narrator().new(f'-- NIGHT {self.day} --')
            self.time = NIGHT
            self.launch()
            if len(self.alive_players) < 2:
                break
            Narrator().tell()
            self.status()
            self.day += 1
            Narrator().new(f'\n== DAY {self.day} morning ==')
        if len(self.alive_players) == 1:
            Narrator().tell()
            print(f'{self.alive_players[0].name} wins the Hunger Games!')
Exemple #5
0
    def patch(self, wound: str, stock=False):
        verbs = []
        tools = []
        if self.has_item('iodine'):
            self.remove_item('iodine')
            verbs = ['disinfects']
            tools = ['iodine']
        elif Map().has_water(self):
            self._max_health *= 0.99
            verbs = ['cleans']
            tools = [f'{self.current_area}\'s water']
        elif sum([b.fill for b in self.bottles]) > 0.2:
            self.use_water(0.2)
            self._max_health *= 0.99
            verbs = ['cleans']
            tools = ['water']
        else:
            self._max_health *= 0.95

        verbs.append('stops' if wound == BLEEDING else 'patches')
        verb_part_2 = 'from bleeding' if wound == BLEEDING else ''
        if self.has_item('bandages'):
            self.remove_item('bandages')
            tools.append('bandages')
        else:
            self._max_health *= 0.95
            tools.append(choice(['moss', 'cloth']))

        wound_name = 'wounds' if wound == BLEEDING else wound
        Narrator().add([
            self.name,
            format_list(verbs), self.his, wound_name, verb_part_2, 'using',
            format_list(tools)
        ],
                       stock=stock)

        self.status.remove(wound)
Exemple #6
0
 def trigger_event(self):
     possible_events = [cls for cls in self.event_classes if cls.can_happen()]
     if not len(possible_events):
         return
     self._event_gauge = 0
     event = choice(possible_events)()
     areas = format_list(list(set([f'the {area.name}' for area in event.areas])))
     Narrator().new(['EVENT:', event.name.upper(), f'at {areas}'])
     Narrator().new(['EVENT:', event.name.upper(), f'at {event.areas}'])
     Narrator().cut()
     event.trigger()
     Narrator().new(' ')
     Narrator().cut()
     self._players_at_last_event = len(self.alive_players)
     self._time_since_last_event = 0
Exemple #7
0
    def trigger(self):
        Context().forbidden_areas.extend(self.areas)
        saw_it_coming = []
        warned = []
        # Narrator().add(['should trigger for', [p.name for a in self.areas for p in a.players]])
        for area in self.areas:
            for p_e in Context().playing_entities_at(area):
                for p in p_e.players:
                    if p.wisdom * random() > self.stealth:
                        saw_it_coming.append(p.name)
                        warned.extend(p_e.players)
                        break
        if len(saw_it_coming):
            Narrator().new([
                format_list(saw_it_coming), 'see' if len(saw_it_coming) > 1 else 'sees', self.it, 'coming'
            ])
        for area in self.areas:
            area_players = copy(area.players)
            for p in area_players:
                Narrator().cut()

                if p.can_flee():
                    if p in warned:
                        p.flee()
                        if p.current_area in self.areas:
                            Narrator().new([
                                'error:', 'forbidden:', Context().forbidden_areas, p.name, p.current_area.at])
                            Map().test = 'SHIT'
                    elif p.be_damaged(self.base_damage, weapon=self.weapon_name):
                        Narrator().new([p.name, 'fails', 'to escape', self.it, 'and', self.dies, area.at])
                    else:
                        Narrator().apply_stock()
                        p.flee(panic=True, drop_verb='loses')
                    continue  # successful escape
                Narrator().new([p.name, 'is', 'trapped', area.at])
                if self.trapped_means_dead:
                    p.be_damaged(1)
                    Narrator().add([p.name, 'is', 'swiped', 'by', self.it, area.at, 'and', self.dies])
                elif p.be_damaged(random() * self.extra_damage + self.base_damage, weapon=self.weapon_name):
                    Narrator().add(['and', self.dies])
                else:
                    Narrator().apply_stock()
                if not len(Narrator().current_sentence):  # error
                    Narrator().add([p.name, 'escaped', self.it, 'and is', p.current_area.at])
            Narrator().clear_stock()
            if self.remove_loot:
                area.loot.clear()
Exemple #8
0
    def dine(self):
        self.take_a_break()
        food_owner: Dict[Food, Player] = {}
        for player in self.acting_players:
            for e in player.equipment:
                if isinstance(e, Food):
                    food_owner[e] = player
        if not len(food_owner):
            Narrator().add([self.name, 'does not have', 'anything to eat'])
        else:
            food = list(food_owner.keys())
            food.sort(key=lambda x: x.value)
            diner = {p: [] for p in self.acting_players}
            poison = {p: None for p in self.acting_players}
            eaters = copy(self.acting_players)
            eaters.sort(key=lambda x: -x.hunger)
            while len(eaters) and len(food):
                eaters_this_round = copy(eaters)
                for eater in eaters_this_round:
                    try:
                        meal = food.pop()
                    except IndexError:
                        break
                    food_owner[meal].remove_item(meal)
                    diner[eater].append(meal.name)
                    if eater.eat(meal, verbose=False) == 'poison':
                        poison[eater] = meal
                        eaters.remove(eater)
                    elif not eater.hunger:
                        eaters.remove(eater)

            for player in self.acting_players:
                if len(diner[player]):
                    Narrator().add([
                        player.name, 'eats', player.his,
                        format_list(diner[player]), self.current_area.at
                    ])
                    if poison[player] is not None:
                        Narrator().new(
                            [f'the {poison[player].name}', 'is', 'poisonous!'])
                        Narrator().cut()
                    player.consume_antidote()
Exemple #9
0
 def pursue(self):
     available_areas = [
         a for a in Map().areas if a not in Context().forbidden_areas
     ]
     available_areas.sort(
         key=lambda x: sum(p._pursue_value(x) for p in self.acting_players))
     out = None
     if not available_areas:
         out = self.go_to(available_areas[-1])
     if out is None:
         self.hide()
         Narrator().replace('hides and rests', 'rests')
     else:
         targets = [
             p.name for p in Context().alive_players
             if p not in self.players
         ]
         players = 'players' if len(targets) > 2 else format_list(targets)
         Narrator().add([self.name, 'searches for', players, out.at])
         self.check_for_ambush_and_traps()
Exemple #10
0
 def trigger(self):
     possible_loots = [
         Food(choice(['ration', 'food can', 'energy bar']), 0.75),
         Food(choice(['ration', 'food can', 'energy bar']), 0.50),
         Food(choice(['ration', 'food can', 'energy bar']), 0.25),
         Item('bandages'), Item('iodine'), Item('antidote'), Bottle(1),
         Weapon(choice([SWORD, AXE, MACE]), 2 + random())
     ]
     possible_loots = [i for i in possible_loots if sum(p.estimate(i) for p in Context().alive_players)]
     possible_loots.sort(key=lambda x: -sum(p.estimate(x) for p in Context().alive_players))
     area = self.areas[0]
     nb_bags = randint(1, len(Context().alive_players) - 1)
     while nb_bags > len(possible_loots):
         possible_loots.extend(possible_loots)
     bags = []
     for i in range(nb_bags):
         bags.append(Bag([possible_loots[i], possible_loots[-(i + 1)]]))
     for bag in bags:
         Map().add_loot(bag, area)
     verb = 'have' if nb_bags > 1 else 'has'
     Narrator().new([nb_bags, 'bag' + ('s' if nb_bags > 1 else ''), verb, 'been dropped', area.at])
     Narrator().new([
         'The bag' + ('s' if nb_bags > 1 else ''), 'contain' + ('s' if nb_bags == 1 else ''),
         format_list([i.name for b in bags for i in b.content])])
Exemple #11
0
 def dine(self):
     self.take_a_break()
     if not self.has_food:
         Narrator().add([self.name, 'does not have', 'anything to eat'])
     else:
         foods = [e for e in self.equipment if isinstance(e, Food)]
         foods.sort(key=lambda x: x.value)
         diner = []
         poison = None
         while self.hunger > 0 and len(foods):
             meal = foods.pop()
             self.remove_item(meal)
             diner.append(meal.name)
             if self.eat(meal, verbose=False) == 'poison':
                 poison = meal
                 break
         Narrator().add([
             self.name, 'eats', self.his,
             format_list(diner), self.current_area.at
         ])
         if poison is not None:
             Narrator().new([f'the {poison.name}', 'is', 'poisonous!'])
             Narrator().cut()
             self.consume_antidote()
Exemple #12
0
def player_names(players: List[Player]) -> str:
    return format_list([p.name for p in players])
Exemple #13
0
 def describe_allies(self):
     return format_list([p.name for p in self.allies()])
Exemple #14
0
 def full_status_desc(self):
     return format_list([*self.status, *[str(p) for p in self._poisons]])