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)) ]
class States: Normal = State(modifier=Modifier(thirst=95 / 1440, hunger=50 / 1440, sleepiness=105 / 1440, fatigue=250 / 1440, bloodlost=-70 / 1440, each_tick=True)) Sleeping = State(ending=Ending('che dorme', 'che dormono', 'che dormono'), can_see=False, can_act=False, modifier=Modifier(thirst=100 / 1440, hunger=50 / 1440, fatigue=-250 / 1440, sleepiness=-400 / 1440, bloodlost=-70 / 1440, each_tick=True)) Unconscious = State(ending=Ending('che ha perso i sensi', 'che ha perso i sensi', 'che ha perso i sensi'), can_act=False, can_see=False, modifier=Modifier(thirst=100 / 1440, hunger=50 / 1440, fatigue=-300 / 1440, sleepiness=-400 / 1440, bloodlost=-70 / 1440, each_tick=True)) Lying = State( ending=Ending('a terra', 'a terra', 'a terra'), actions=[ Action('Alzati', EventMessages(subject='ti alzi', close='{subject} si alza da terra', far='{subject} si alza da terra'), do=lambda char: setattr(char, 'state', States.Normal), time=2, fatigue=0.5) ], defenses=[ Defense( name='Rotola a terra', tags={'arretra'}, chances=15, success_event=EventMessages( subject='riesci a rotolare via', object='{subject} riesce a rotolare di lato', close='{subject} rotola via da {object}', far='vedi {subject} rotolare a terra in lontananza'), fail_event=EventMessages( subject='non riesci a rotolare via', object='{subject} prova a rotolare via ma non ci riesce', close= '{subject} cerca di rotolare via da {object} ma fallisce')) ], modifier=Modifier(thirst=95 / 1440, hunger=50 / 1440, sleepiness=105 / 1440, bloodlost=-70 / 1440, each_tick=True) + Modifier(agility=-30))
def defenses(self) -> List[Defense]: return [d for w in self.weapons for d in w.defenses] + [ Defense('Arretra', {'arretra'}, 25, success_event=EventMessages( subject='riesci ad arretrare', object='{subject} riesce ad arretrare', close='{subject} riesce ad arretrare'), fail_event=EventMessages( subject='non riesci ad arretrare', object='{subject} non riesce ad arretrare', close='{subject} non riesce ad arretrare')) ]
def drop_action(self): return Action( f'{self.drop_verb} {self.description.close}'.capitalize(), EventMessages( subject=f'posi a terra {self.description.close}', close=f'{{subject}} posa a terra {self.description.nclose}', far=f'{{subject}} posa a terra qualcosa'), lambda player: player.inventory.drop(self, player))
def actions(self): return [ Action( f'Conta {value[0].description.close.plural}', EventMessages( subject= f'Conti {value[0].description.close.plural} e sono {len(value)}' ), lambda player: 0, 0, 0) for key, value in self.d.items() if len(value) > 2 ]
def actions(self) -> List[Action]: a = Action( time=self.distance, fatigue=self.distance, sound=Sound(event=EventMessages( far='{direction} senti qualcuno che cammina', )), name=f'Vai {self.description}{self.direction.objects_description}', event=EventMessages(), visibility_event=EventMessages( close_to_far='dietro di te vedi ancora {object}', close_to_none='dietro di te non vedi più {object}', far_to_close='arrivi da {object}', far_to_closer= 'ti avvicini verso {object}, che vedi {direction}', far_to_farer='dietro di te vedi ancora {object}', far_to_none='dietro di te non vedi più {object}', none_to_close='come arrivi vedi {object}', none_to_far='ora {direction} vedi {object}'), post_event=EventMessages( subject=f'arrivi {self.direction.description}', close= f'{{subject}} si allontana {self.description} ma la strada curva e riporta da te', close_to_far=f'{{subject}} si allontana {self.description}', close_to_none= f'{{subject}} si allontana {self.description} e scompare dalla tua vista', far='distante, {direction}, vedi {subject} spostarsi', far_to_close= f'{self.inverse.description} da te arriva {{subject}}', far_to_closer= 'ancora distante, {direction} vedi avvicinarsi {subject}', far_to_farer= 'già distante, {direction} vedi allontanarsi {subject}', far_to_none= '{direction} vedi {subject} allontanarsi e scomparire dalla tua vista', none_to_close= f'improvvisamente {{subject}} arriva da te {self.description.inverse}', none_to_far='improvvisamente vedi {subject} {direction}'), do=lambda c: c.move_to(self), condition=lambda c: c.last_exit is not self) b = copy(a) # Same, but with 'Torna verso' instead of 'Vai verso' b.name = f'Torna {self.description}{self.direction.objects_description}' b.condition = lambda c: c.last_exit is self return [a, b]
def picked_actions(self): return [Action( f'Mangia {self.description}', EventMessages( subject=f'mangi {self.description}', close=f'{{subject}} mangia {self.description}', far=f'{{subject}} mangia qualcosa' ), lambda char: setattr(char, 'hunger', char.hunger - self.nutrition) or \ char.inventory.remove(self) )]
def attacks(self) -> List[Attack]: return [a for w in self.weapons for a in w.attacks] + [ Attack( 'cerca di spingere {target} a terra', lambda subject, target: setattr(target, 'state', States.Lying), EventMessages( subject='cerchi di spingere {subject} a terra', object='{subject} cerca di spingerti a terra', close='{subject} cerca di spingere {object} a terra', far='{subject} cerca di spingere {object} a terra'), EventMessages(subject='{subject} cade a terra', object='cadi a terra', close='{object} cade a terra', far='{object} cade a terra'), EventMessages(subject='rimane in piedi', object='rimani in piedi', close='{object} rimane in piedi', far='{object} rimane in piedi'), {'arretra'}, difficulty=25, condition=lambda p, t: t.state is States.Normal) ]
def picked_actions(self): return [Action( f'Bevi {self.description}', EventMessages( subject=f'bevi {self.description}', close=f'{{subject}} beve {self.description}', far=f'{{subject}} beve qualcosa' ), lambda char: setattr(char, 'thirst', char.thirst - self.water) or \ setattr(self, 'water', 0) or \ char.inventory.contained.remove(self) )]
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 picked_actions(self): return [ Action( f'Cura {self.wound.name} con {self.description.oneof}', EventMessages( subject=f'Curi {self.wound.name}', close= f'{{subject}} cura {self.wound.name} con {self.description.oneof}' ), lambda char: self.wound.unaffect( char) or char.inventory.remove(self), condition=lambda char: self.wound in char.wounds) ]
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
def equip(self, obj): can_left = lambda player: self.occupied - obj.volume + player.inventory.left_hand.volume > self.volume can_right = lambda player: self.occupied - obj.volume + player.inventory.right_hand.volume > self.volume left_action = Action( f'Prendi nella mano sinistra {obj.description.close}', EventMessages( subject=f'prendi nella mano sinistra {obj.description.close}', close=f'{{subject}} afferra in mano {obj.description.close}'), lambda player: actual_equip(player, 'left_hand'), 0, 0, condition=can_left) right_action = Action( f'Prendi nella mano destra {obj.description.close}', EventMessages( subject=f'prendi nella mano destra {obj.description.close}', close=f'{{subject}} afferra in mano {obj.description.close}'), lambda player: actual_equip(player, 'right_hand'), 0, 0, condition=can_right) choose_action = Action( f'Prendi in mano {obj.description.close}', EventMessages(subject='si, ma in che mano?'), lambda p: [left_action, right_action], 0, 0, condition=lambda p: can_left(p) and can_right(p)) def actual_equip(player, hand): if getattr(player.inventory, hand): self.objects.add(getattr(player.inventory, hand)) self.objects.remove(obj) setattr(player.inventory, hand, obj) return [left_action, right_action, choose_action]
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'))
def actions(self) -> List[Action]: return self._user_actions + \ [a for exit in self.exits for a in exit.actions] + \ self.contained.actions + \ [Action( (f'{obj.pick_verb} {obj.description.oneof}').capitalize(), EventMessages( subject=f'{obj.pick_verb} {obj.description.oneof}', close=f'{{subject}} prende {obj.description.oneof}', far=f'{{subject}} prende in mano qualcosa', ), (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.contained if isinstance(obj, Object) and not obj.visible] + \ [a for obj in self.contained for a in getattr(obj, 'ground_actions', []) if isinstance(obj, Object)]
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
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 ]
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 ]
def __add__(self, other): if self.value + other > 120 and self.value <= 120: self.parent.state = States.Normal #TODO add a "f*****g dead" state self.parent.send_event(self.die_event) self.parent.die() elif self.value + other > 105 and self.value <= 105: self.parent.send_event( EventMessages( subject= 'senti le tue forze venirti a meno e ti accasci sul suolo', close='{subject} sviene', far='{subject} si accascia a terra')) self.parent.state = States.Unconscious elif self.value + other < 90 and self.value >= 90: self.parent.state = States.Lying self.parent.send_event( EventMessages(subject='ti senti meglio, e torni in te', close='{subject} riprende i sensi')) elif self.value + other < 0: other = 0 - self.value elif self.value + other >= 30 and self.value < 30: self.parent.send_event(EventMessages(self.low_up_message)) elif self.value + other >= 60 and self.value < 60: self.parent.wakeup() self.parent.send_event(EventMessages(self.medium_up_message)) elif self.value + other >= 80 and self.value < 80: self.parent.wakeup() self.parent.send_event(EventMessages(self.high_up_message)) if self.wound and not self.wound in self.parent.wounds: self.wound.affect(self.parent) elif self.value + other < 30 and self.value > 30: self.parent.send_event(EventMessages(self.low_down_message)) elif self.value + other < 60 and self.value > 60: self.parent.send_event(EventMessages(self.medium_down_message)) elif self.value + other < 80 and self.value > 80: self.parent.send_event(EventMessages(self.high_down_message)) new = copy(self) new.value = self.value + other return new
def die(self): self.place.contained.remove(self) self.place.contained.append( Object( self.description, default_state=Ending(*['a terra, cadavere'] * 3), volume=100, visible=True, ground_actions=[ Action( f'Esamina il cadavere di {self.description.nclose}', EventMessages( subject='esamini il cadavere', close= f'{{subject}} esamina il cadavere di {self.description.nclose}', far= f'{{subject}} esamina il cadavere di {self.description.nclose}', ), do=lambda character: self.inventory.raid(character), time=2, ) ])) self.instances.remove(self) return v
class Wounds: TaglioBraccia = Wound( 'il taglio al braccio', start_event=EventMessages( subject= 'senti una fitta di dolore e vedi un taglio lungo e profondo sul braccio da cui inizia subito a colare sangue', close='{subject} inizia a perdere sangue dal braccio'), during_event=EventMessages( subject='continui a perdere sangue dal braccio', close='{subject} sta visibilmente sanguinando dal braccio'), worsen_event=EventMessages(subject='il sangue schizza ovunque', close='{subject} schizza sangue ovunque'), stop_event=EventMessages( subject= 'il taglio al braccio sembra essersi rimarginato, non stai più perdendo sangue', close='{subject} sembra di non star più sanguinando dal braccio'), modifier=Modifier(bloodlost=65 / 240, each_tick=True) + Modifier(agility=-10), duration=240) TaglioBusto = Wound( 'la ferita al petto', start_event=EventMessages( subject= 'senti una fitta di dolore e vedi un taglio profondo sul petto da cui cola sangue', close='{subject} inizia a perdere sangue dal petto'), during_event=EventMessages( subject='continui a perdere sangue dal taglio al petto', close='{subject} sta visibilmente sanguinando da un taglio al petto' ), worsen_event=EventMessages(subject='il sangue schizza ovunque', close='{subject} schizza sangue ovunque'), stop_event=EventMessages( subject= 'il taglio al petto sembra essersi rimarginato, non stai più perdendo sangue', close='{subject} sembra di non star più sanguinando dal petto'), modifier=Modifier(bloodlost=110 / 240, each_tick=True) + Modifier(agility=-20), duration=240) TaglioGambe = Wound( 'il taglio alle gambe', start_event=EventMessages( subject= 'senti una fitta di dolore e vedi un taglio lungo e profondo su una gamba da cui inizia subito a colare sangue e che ti fa zoppicare', close='{subject} inizia a perdere sangue da un taglio alle gambe'), during_event=EventMessages( subject= 'continui a perdere sangue dal taglio alle gambe, e non riesci ancora a camminare correttamente', close= '{subject} sta visibilmente sanguinando da un taglio alle gambe'), worsen_event=EventMessages(subject='il sangue schizza ovunque', close='{subject} schizza sangue ovunque'), stop_event=EventMessages( subject= 'il taglio al braccio sembra essersi rimarginato, non stai più perdendo sangue', close='{subject} sembra di non star più sanguinando dal braccio'), modifier=Modifier(bloodlost=75 / 24, each_tick=True) + Modifier(agility=-30), duration=240) Nausea = Wound( 'la nausea', start_event=EventMessages( subject='inizi a sentire un forte senso di nausea'), during_event=EventMessages( subject='improvvisamente hai un rigurgito e vomiti per terra', close='improvvisamente {subject} si mette a vomitare'), worsen_event=EventMessages(), stop_event=EventMessages( subject='la sgradevole sensazione di nausea termina'), modifier=Modifier(hunger=50 / 1440, each_tick=True), duration=550) Febbre = Wound( 'la febbre', start_event=EventMessages(subject='inizi a sentirti una forte febbre'), during_event=EventMessages(subject='la febbre ti da i brividi'), worsen_event=EventMessages(), stop_event=EventMessages( subject= 'la sensazione di febbre lentamente termina, e ti senti meglio'), modifier=Modifier(fatigue=150 / 1440, hunger=30 / 1440, thirst=50 / 1440, each_tick=True) + Modifier(agility=-10, strenght=-15), duration=1500) Frattura = Wound( 'la frattura', start_event=EventMessages( subject= 'con grande dolore ti rendi conto di esserti fratturato un osso della gamba' ), during_event=EventMessages( subject='la frattura ti fa un male terribile, zoppichi'), stop_event=EventMessages( subject='riesci di nuovo, bene o male, a camminare'), worsen_event=EventMessages(), modifier=Modifier(agility=-50), duration=14400) Ipotermia = Wound( 'l\'ipotermia', start_event=EventMessages( subject='ti rendi conto di star andando in ipotermia dal freddo'), during_event=EventMessages( subject='inizia a non riuscire a muoverti dal freddo'), stop_event=EventMessages( subject= 'il sangue inizia a tornare a circolare negli arti, e senti il calore tornare' ), worsen_event=EventMessages(), modifier=Modifier(agility=-40), until=lambda char: char.cold < 50) HeatStroke = Wound( 'il colpo di sole', start_event=EventMessages( subject= 'il caldo inizia a farsi insopportabile, la tua testa inizia a girare' ), during_event=EventMessages( subject='la testa continua a girarti dal caldo'), stop_event=EventMessages( subject='inizi a sentirti meglio, il sole non è più così intenso'), worsen_event=EventMessages(), modifier=Modifier(agility=-40), until=lambda char: char.hot < 50)
class VitalParameters: thirst = lambda: VitalParameter( 'inizi ad avere sete', 'hai molta sete, ti senti più debole', 'stai morendo di sete, ti senti debolissimo', 'non hai più sete', 'hai meno sete di prima', '', EventMessages(subject='muori di sete', close='{subject} muore di sete', far='{subject} crolla a terra'), modifier=lambda p: Modifier(strenght=-.4 * p), wound=Wounds.Nausea) hunger = lambda: VitalParameter( 'inizi ad avere fame', 'hai molta fame, ti senti più debole', 'stai morendo di fame, ti senti debolissimo', 'non hai più fame', 'hai meno fame di prima', '', EventMessages(subject='muori di fame', close='{subject} muore di fame', far='{subject} crolla a terra'), modifier=lambda p: Modifier(strenght=-.4 * p), wound=Wounds.Febbre) sleepiness = lambda: VitalParameter( 'inizi ad avere sonno', 'hai molto sonno', 'stai morendo di sonno', 'non hai più sonno', 'hai meno sonno di prima', '', EventMessages(subject='muori di sonno', close='{subject} muore di sonno', far='{subject} crolla a terra'), modifier=lambda p: Modifier(strenght=-.35 * p, agility=-.35 * p), wound=Wounds.Febbre, action=Action('Mettiti a dormire per terra', event=EventMessages( subject='ti addormenti velocemente', close='{subject} si mette a dormire a terra', far='{subject} si sdraia a terra'), do=lambda char: char.sleep(), condition=lambda char: char.world.hour > 22 or char.world .hour < 4)) fatigue = lambda: VitalParameter( 'inizi a essere stanco', 'sei molto stanco', 'stai morendo di stanchezza', 'non sei più stanco', 'sei meno stanco di prima', '', EventMessages(subject='muori di stanchezza', close='{subject} muore di stanchezza', far='{subject} crolla a terra'), modifier=lambda p: Modifier(strenght=-.35 * p, agility=-.35 * p), action=Action('Riposati qui qualche minuto', time=7, fatigue=-30, event=EventMessages(subject='riposi qualche minuto', close= '{subject} si ferma per riposarsi', far='{subject} si siede brevemente'), do=lambda char: None, condition=lambda char: char.world.hour > 22 or char.world .hour < 4)) bloodlost = lambda: VitalParameter( 'stai perdendo sangue', 'inizi a impallidire da quanto sangue perdi', 'sei praticamente dissanguato', 'senti di essere di nuovo in forze', 'inizi a sentirti meglio', 'non stai più perdendo sangue', EventMessages(subject='muori dissanguato', close='{subject} muore dissanguato', far='{subject} crolla a terra in una pozza di sangue'), modifier=lambda p: Modifier(strenght=-.5 * p)) cold = lambda: VitalParameter( 'inizi ad avere freddo', 'hai molto freddo ora', 'stai gelando', 'non hai più freddo', 'inizi a scaldarti', 'la temperatura sembra aumentare', EventMessages(subject='muori di freddo', close='{subject} muore di freddo', far='{subject} crolla a terra congelato'), wound=Wounds.Ipotermia) hot = lambda: VitalParameter('inizi ad avere caldo', 'hai molto caldo ora', 'stai evaporando', 'non hai più caldo', 'inizi a stare meglio', 'la temperatura sembra diminuire', EventMessages(subject='muori di caldo', close= '{subject} muore di caldo', far='{subject} crolla a terra'), modifier=lambda p: Modifier(thrist=-.4 * p, ), wound=Wounds.HeatStroke)
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,
def picked_actions(self) -> List[Action]: return [ Action(f'Guarda cosa hai dentro {self.description.close}', EventMessages(), self.check_backpack, 0, 0) ]
def actions(self) -> List[Action]: return [ Action('Controlla cosa hai', EventMessages(), self.check_inventory, 0, 0) ] * bool(self.objects)