Ejemplo n.º 1
0
 def pick(self, obj, player, container):
     self.add(obj, player)
     container.remove(obj)
     if container.count(obj) > 1:
         player.events.append('vedi che ce ne sono ancora')
     elif container.count(obj) == 1:
         self.parent.events.append(
             Format("vedi che rimane solo {obj}",
                    obj=obj.description.nclose))
Ejemplo n.º 2
0
 def send_event(self,
                event: EventMessages,
                target=None,
                sound=None,
                before=None,
                after=None):
     event = deepcopy(event)
     if (msg := event.subject) and self.state.can_see:
         self.events.append(
             Format(msg, subject=target and target.description.close))
Ejemplo n.º 3
0
 def look_around(self):
     self.send_event(self.world.day_time.during_event)
     self.send_event(self.world.weather.during_event)
     self.events.append(f'Sei {self.place.description}')
     chars = self.place.objects_around(self.visibility)
     del chars[self]
     for char, direction in chars.items():
         self.events.append(
             Format((f'verso {direction[-1].description} '
                     if direction else '') + 'vedi {object}',
                    object=char.description.nfar
                    if direction else char.description.nclose))
Ejemplo n.º 4
0
 def add(self, obj, player):
     if isinstance(obj, Dress):
         setattr(self, obj.type, obj)
     elif isinstance(obj, Backpack):
         self.backpack = obj
         for bkobj in obj.objects:
             player.events.append(
                 Format("dando un'occhiata vedi che contiene {bkobj}",
                        bkobj=bkobj.description.nclose))
     elif isinstance(obj, Object):
         if not self.left_hand: self.left_hand = obj
         elif not self.right_hand: self.right_hand = obj
         else: self.backpack.objects.add(obj)
         if self.left_hand and self.right_hand and not self.backpack:
             player.send_event(EventMessages('hai le mani piene'))
Ejemplo n.º 5
0
 def send_visibility_event(self, event: EventMessages, before):
     if not self.state.can_see: return
     after = {
         c: c.place.objects_around(c.visibility)
         for c in Character.instances
     }
     event = deepcopy(event)
     for obj in set(before[self]) | set(after[self]):
         delta = self.place.deltaObject(before[self], after[self], obj)
         self.events.append(
             Format(
                 getattr(event, delta[0]),
                 object=getattr(obj.description,
                                EventMessages.what_description[delta[0]]),
                 direction=delta[1] and delta[1].description))
Ejemplo n.º 6
0
 def check_backpack(self, player):
     actions = []
     for obj in self.objects.all:
         player.events.append(
             Format('nello zaino hai {obj}', obj=obj.description.close))
     for obj in self.objects:
         actions.append(obj.drop_action)
         actions.extend(self.equip(obj))
         actions.extend(obj.picked_actions)
     actions.extend(self.objects.actions)
     if not self.objects:
         player.events.append('...è vuoto')
     actions.append(
         Action('Indietro', EventMessages(), lambda p: None, 0, 0))
     actions = [a for a in actions if a.condition(player)]
     return actions
Ejemplo n.º 7
0
 def raid(self, character) -> List[Action]:
     for obj in self.objects.all:
         character.events.append(
             Format('vedi {obj}', obj=obj.description.close))
     return [
         Action(
             (f'{obj.pick_verb} {obj.description.oneof}').capitalize(),
             EventMessages(
                 subject=
                 f'{obj.pick_verb} {obj.description.oneof} dal cadavere',
                 close=
                 f'{{subject}} prende {obj.description.oneof} dal cadavere',
                 far=f'{{subject}} prende in mano qualcosa dal cadavere',
             ),
             (lambda obj: lambda char: char.inventory.pick(
                 obj, char, self.contained))(obj),
             condition=(lambda obj: lambda char: char.inventory.
                        pick_message(obj))(obj)) for obj in self.objects
     ]
Ejemplo n.º 8
0
 def check_inventory(self, player) -> List[Action]:
     actions = []
     for obj in self.objects.all:
         player.events.append(Format('hai {obj}',
                                     obj=obj.description.close))
     for obj in self.objects:
         actions.append(obj.drop_action)
         actions.extend(obj.picked_actions)
     actions.extend(self.objects.actions)
     if self.left_hand and self.backpack and self.backpack.occupied + self.left_hand.volume <= self.backpack.volume:
         actions.append(
             Action(
                 f'Metti {self.left_hand.description.close} nello zaino',
                 EventMessages(
                     subject=
                     f'Metti {self.left_hand.description.close} nello zaino',
                     close=
                     f'{{subject}} mette {self.left_hand.description.close} nello zaino'
                 ), lambda player: self.backpack.objects.add(self.left_hand)
                 or setattr(self, 'left_hand', None)))
     if self.right_hand and self.backpack and \
      self.backpack.occupied + self.right_hand.volume <= self.backpack.volume and \
      not self.right_hand.description.grouped:
         actions.append(
             Action(
                 f'Metti {self.right_hand.description.close} nello zaino',
                 EventMessages(
                     subject=
                     f'Metti {self.right_hand.description.close} nello zaino',
                     close=
                     f'{{subject}} mette {self.right_hand.description.close} nello zaino'
                 ), lambda player: self.backpack.objects.add(
                     self.right_hand) or setattr(self, 'right_hand', None)))
     actions.append(
         Action('Indietro', EventMessages(), lambda player: '', 0, 0))
     actions = [a for a in actions if a.condition(player)]
     return actions
Ejemplo n.º 9
0
from core import Modifier, Attack, Defense, Dodge, Action
from things import Object, Food, HealWound
from life import Wounds, States
from containers import ObjectGroup, Backpack, Weapon
from words import EventMessages, Description, Format, ExitDescription
from map import Place, Exit


logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
					level=logging.INFO)

world = World(
	weathers = {
		Weather(
			Modifier(),
			EventMessages(Format('Il sole {sole}', sole='inizia a splendere')),
			EventMessages(Format('Il sole {sole}', sole='smette di splendere')),
			EventMessages(Format('Il sole {sole}', sole='splende sempre più intensamente')),
			EventMessages()
			),
		Weather(
			Modifier(),
			EventMessages('le nuvole si addensano sopra di te'),
			EventMessages('le nuvole sopra di te si diradano'),
			EventMessages('le nuvole si fanno sempre più fitte'),
			EventMessages()
			)
		},
	day_times = {
		DayTime(
			range(24), 0, 0,
Ejemplo n.º 10
0
class Character:

    description: Description

    strenght: int
    agility: int
    visibility: int
    _strenght: int = 50  #avg 50
    _agility: int = 50  #avg 50
    _visibility: int = 3

    inventory: Inventory = field(default_factory=Inventory)

    place: Optional[Place] = None
    world: Optional[World] = None

    thirst: VitalParameter = field(default_factory=VitalParameters.thirst)
    hunger: VitalParameter = field(default_factory=VitalParameters.hunger)
    sleepiness: VitalParameter = field(
        default_factory=VitalParameters.sleepiness)
    fatigue: VitalParameter = field(default_factory=VitalParameters.fatigue)
    bloodlost: VitalParameter = field(
        default_factory=VitalParameters.bloodlost)
    cold: VitalParameter = field(default_factory=VitalParameters.cold)
    hot: VitalParameter = field(default_factory=VitalParameters.hot)

    vital_names: str = ('thirst', 'hunger', 'sleepiness', 'fatigue',
                        'bloodlost', 'cold', 'hot')

    wounds: List[Wound] = field(default_factory=list)
    state: State = field(default_factory=lambda: States.Normal)

    busy_until: int = 0
    events: Events = field(default_factory=Events)
    last_exit: Optional[Exit] = None
    instances = []
    visible: bool = True
    current_actions: List[Action] = field(default_factory=list)
    groundActions: List[Action] = field(default_factory=list)

    def __post_init__(self):
        self.vitals = [getattr(self, x) for x in self.vital_names]
        for vital in self.vitals:
            vital.parent = self
        self.inventory.parent, self.description.parent = self, self
        self.instances.append(self)

    @property
    def modifier(self) -> Modifier:
        mod = sum(x.modifier for x in [self.place, self.inventory] +
                  self.wounds + [getattr(self, x) for x in self.vital_names])
        if self.state.modifier: mod += self.state.modifier
        return mod

    @property
    def visibility(self):
        return self._visibility + self.modifier.permanent['visibility']

    @visibility.setter
    def visibility(self, value):
        self._visibility = value

    @property
    def agility(self):
        return self._agility + self.modifier.permanent['agility']

    @agility.setter
    def agility(self, value):
        self._agility = value

    @property
    def strenght(self):
        return self._strenght + self.modifier.permanent['strenght']

    @strenght.setter
    def strenght(self, value):
        self._strenght = value

    @property
    def actions(self) -> List[Action]:
        return [
            a for a in (self.state.actions or [
                action for x in (self.place, self.inventory, self.thirst,
                                 self.hunger, self.sleepiness, self.fatigue,
                                 self.bloodlost, self.cold, self.hot)
                for action in x.actions
            ] + self.social_actions) if a.condition(self)
        ]

    @property
    def social_actions(self) -> List[Action]:
        return [
            Action(
                f'Interagisci con {person.description.far if direction else person.description.oneof}',
                do=(lambda person: lambda character: [
                    Action(f'Attacca',
                           do=lambda character: character.war_actions(person),
                           event=EventMessages(),
                           time=1,
                           fatigue=0)
                ] * bool(character.war_actions(person)) + [
                    Action(f'Dai oggetti',
                           do=lambda character: character.give_actions(person),
                           event=EventMessages(),
                           time=1,
                           fatigue=0)
                ] * bool(self.give_actions(person) and not direction) + [
                    Action(f'Indietro',
                           do=lambda character: None,
                           event=EventMessages(),
                           time=0,
                           fatigue=0)
                ])(person),
                event=EventMessages(),
                time=0,
                fatigue=0) for person, direction in self.place.objects_around(
                    self.visibility, all=False).items()
            if isinstance(person, Character) and (person is not self) and (
                self.war_actions(person) or
                (self.give_actions(person) and not direction))
        ]

    def war_actions(self, target) -> List[Action]:
        return [
            Action(name=attack.name.format(
                target=target.description.oneof).capitalize(),
                   event=EventMessages(),
                   time=1,
                   fatigue=1,
                   do=(lambda attack: lambda char: attack.do(char, target)
                       )(attack))
            for attack in self.inventory.attacks + self.place.attacks
            if target in self.place.objects_around(attack.range)
            and attack.condition(self, target)
        ]

    def give_actions(self, target) -> List[Action]:
        return [
            Action(
                name=f'Dai {obj.description.oneof}',
                event=EventMessages(
                    subject=f'Dai {obj.description.oneof} a {{subject}}',
                    object=f'{{subject}} ti da {obj.description.oneof}',
                    close=
                    f'{{subject}} da {obj.description.oneof} a {{object}}',
                    far=f'{{subject}} da qualcosa a {{object}}'),
                time=1,
                fatigue=0,
                target=target,
                do=(lambda obj: lambda char: char.inventory.remove(obj) and
                    target.inventory.add(obj, target))(obj),
                condition=(
                    lambda obj: lambda char: char.inventory.pick_message(obj)))
            for obj in self.inventory.all_objects
        ]

    @property
    def defenses(self) -> List[Defense]:
        return self.state.defenses or [
            x for x in self.inventory.defenses if x.condition(self)
        ]

    def look_around(self):
        self.send_event(self.world.day_time.during_event)
        self.send_event(self.world.weather.during_event)
        self.events.append(f'Sei {self.place.description}')
        chars = self.place.objects_around(self.visibility)
        del chars[self]
        for char, direction in chars.items():
            self.events.append(
                Format((f'verso {direction[-1].description} '
                        if direction else '') + 'vedi {object}',
                       object=char.description.nfar
                       if direction else char.description.nclose))

    def sleep(self):
        self.busy_until = self.world.time + 600
        self.state = States.Sleeping

    def wakeup(self):
        if not self.state is States.Sleeping: return
        self.events.append('ti svegli')
        self.state = States.Lying
        self.busy_until = self.world.time + 1
        self.look_around()

    def check_wounds(self):
        for wound in [*self.wounds]:
            if (wound.duration and wound.end_time < self.world.time) or (
                    wound.until and wound.until(self)):
                wound.unaffect(self)
            elif random() > .9:
                self.send_event(wound.during_event)

    def tick(self):
        self.wakeup()
        self.check_wounds()
        Telegram.instance.ask(self, self.actions)

    def apply_modifier(self, time, modifier):
        for key, value in modifier.each_tick.items():
            setattr(self, key, getattr(self, key) + value * time)

    def work_for(self, time):
        self.apply_modifier(time, self.modifier)

    def move_to(self, exit):
        self.place.contained.remove(self)
        self.place = exit.direction
        self.last_exit = exit.inverse
        self.place.contained.add(self)

    def send_event(self,
                   event: EventMessages,
                   target=None,
                   sound=None,
                   before=None,
                   after=None):
        event = deepcopy(event)
        if (msg := event.subject) and self.state.can_see:
            self.events.append(
                Format(msg, subject=target and target.description.close))
        if (msg := event.object) and target and target.state.can_see:
            target.events.append(Format(msg, subject=self.description.close))
Ejemplo n.º 11
0
                Format(msg, subject=target and target.description.close))
        if (msg := event.object) and target and target.state.can_see:
            target.events.append(Format(msg, subject=self.description.close))
        for char in self.instances:
            a = (after and after[char]) or char.place.objects_around(
                char.visibility)
            b = (before and before[char]) or a
            if char is self or (target and char is target): continue
            if (delta := self.place.deltaObject(b, a,
                                                self)) and char.state.can_see:
                char.events.append(
                    Format(
                        getattr(event, delta[0]),
                        subject=getattr(
                            self.description,
                            EventMessages.what_description[delta[0]]),
                        object=target
                        and getattr(target.description,
                                    EventMessages.what_description[delta[0]]),
                        direction=delta[1].description if delta[1] else ''))
            elif sound and self in (around := char.place.objects_around(
                    sound.strenght)):
                if sound.strenght > 4 and char.state is States.Sleeping:
                    char.wakeup()
                if not char.state.can_see: continue
                char.events.append(
                    Format(sound.event.far,
                           direction=around[self][-1].description))

    def send_visibility_event(self, event: EventMessages, before):
        if not self.state.can_see: return