diff --git a/main.py b/main.py index 09090bf..8bfe466 100644 --- a/main.py +++ b/main.py @@ -11,6 +11,7 @@ import filemanager import random import strings as s import logging +from roles import * logging.basicConfig(level=logging.WARNING, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') @@ -21,411 +22,6 @@ updater = Updater(token) freenames = s.names_list.copy() -# Ruoli possibili per i giocatori -# Base di un ruolo -class Role: - """Classe base di un ruolo. Da qui si sviluppano tutti gli altri ruoli.""" - icon = "-" # Icona del ruolo, da visualizzare di fianco al nome - team = 'None' # Squadra: 'None', 'Good', 'Evil', 'Chaos'; conta per le condizioni di vittoria - name = "UNDEFINED" # Nome del ruolo, viene visualizzato dall'investigatore e durante l'assegnazione - powerdesc = None # Ha un potere? Se sì, queste sono le info su come usarlo in seconda persona. - - def __init__(self, player): - self.player = player - - def __repr__(self) -> str: - return "" - - def __str__(self) -> str: - return "{} {}".format(self.icon, self.name) - - def power(self, bot, game, arg): - """Il potere del ruolo. Si attiva quando il bot riceve un /power in chat privata.""" - pass - - def onendday(self, bot, game): - """Metodo chiamato alla fine di ogni giorno.""" - pass - - def ondeath(self, bot, game): - """Metodo chiamato alla morte del giocatore.""" - pass - - def onstartgame(self, bot, game): - """Metodo chiamato all'inizio della partita.""" - pass - - -class Royal(Role): - """Un membro della Royal Games. Il ruolo principale, non ha alcun potere se non quello di votare.""" - icon = s.royal_icon - team = 'Good' - name = s.royal_name - - def __init__(self, player): - super().__init__(player) - - def __repr__(self) -> str: - return "" - - -class Mifioso(Role): - """Il nemico globale. Può impostare come bersaglio una persona al giorno, per poi ucciderla alla fine.""" - icon = s.mifia_icon - team = 'Evil' - name = s.mifia_name - powerdesc = s.mifia_power_description - - def __init__(self, player): - super().__init__(player) - self.target = None - - def __repr__(self) -> str: - if self.target is None: - return "" - else: - return "".format(target=self.target.tusername) - - def power(self, bot, game, arg): - # Imposta una persona come bersaglio da uccidere. - selected = game.findplayerbyusername(arg) - if selected is None: - self.player.message(bot, s.error_username) - return - self.target = selected - self.player.message(bot, s.mifia_target_selected.format(target=self.target.tusername)) - - - def onendday(self, bot, game): - if game.votingmifia: - # Se la partita è in modalità votingmifia l'uccisione della mifia viene gestita dalla classe Game - self.target = None - else: - # Uccidi il bersaglio se non è protetto da un Angelo. - if self.target is not None: - if self.target.protectedby is None: - if game.missingmifia and random.randrange(0, 100) < game.misschance: - # Colpo mancato - game.message(bot, s.mifia_target_missed.format(target=self.target.tusername)) - else: - # Uccisione riuscita - self.target.kill(bot, self) - game.message(bot, s.mifia_target_killed.format(target=self.target.tusername, - icon=self.target.role.icon, - role=self.target.role.name)) - else: - # Bersaglio protetto da un angelo - game.message(bot, s.mifia_target_protected.format(target=self.target.tusername, - icon=self.target.protectedby.role.icon, - protectedby=self.target.protectedby.tusername)) - self.target = None - - -class Investigatore(Role): - """L'investigatore può indagare sul vero ruolo di una persona una volta al giorno.""" - icon = s.detective_icon - team = 'Good' - name = s.detective_name - powerdesc = s.detective_power_description - refillpoweruses = 1 - - def __init__(self, player): - super().__init__(player) - self.poweruses = self.refillpoweruses - - def __repr__(self) -> str: - return "".format(uses=self.poweruses) - - def power(self, bot, game, arg): - # Indaga sul vero ruolo di una persona, se sono ancora disponibili usi del potere. - if self.poweruses <= 0: - # Non hai abbastanza cariche! - self.player.message(bot, s.error_no_uses) - return - target = game.findplayerbyusername(arg) - if target is None: - # Username non valido - self.player.message(bot, s.error_username) - return - # Utilizza il potere su quella persona - self.poweruses -= 1 - self.player.message(bot, s.detective_discovery.format(target=target.tusername, - icon=target.role.icon, - role=target.role.name, - left=self.poweruses)) - - - - def onendday(self, bot, game): - # Ripristina il potere - self.poweruses = self.refillpoweruses - - -class Corrotto(Investigatore): - """Il corrotto è un investigatore che lavora per la Mifia.""" - icon = s.corrupt_icon - team = 'Evil' - name = s.corrupt_name - powerdesc = s.detective_power_description - refillpoweruses = 1 - - def __repr__(self) -> str: - return "".format(uses=self.poweruses) - - -class Angelo(Role): - """L'angelo può proteggere una persona al giorno dalla Mifia. - Se ha successo nella protezione, il suo ruolo sarà rivelato a tutti.""" - icon = s.angel_icon - team = 'Good' - name = s.angel_name - powerdesc = s.angel_power_description - - def __init__(self, player): - super().__init__(player) - self.protecting = None # La persona che questo angelo sta proteggendo - - def __repr__(self) -> str: - if self.protecting is None: - return "" - else: - return "".format(target=self.protecting.tusername) - - def power(self, bot, game, arg): - # Imposta qualcuno come protetto - selected = game.findplayerbyusername(arg) - if selected is None: - self.player.message(bot, s.error_username) - return - - # Controlla che l'angelo stia provando a proteggere sè stesso - if selected is not self.player: - # Togli la protezione a quello che stavi proteggendo prima - if self.protecting is not None: - self.protecting.protectedby = None - # Aggiungi la protezione al nuovo giocatore selezionato - selected.protectedby = self.player - self.protecting = selected - self.player.message(bot, s.angel_target_selected.format(target=self.protecting.tusername)) - else: - self.player.message(bot, s.error_angel_no_selfprotect) - - def onendday(self, bot, game): - # Resetta la protezione - if self.protecting is not None: - self.protecting.protectedby = None - self.protecting = None - - -class Terrorista(Role): - """Il terrorista è un mifioso che può uccidere in un solo modo: facendosi uccidere dai Royal. - Se riesce, vince la partita e uccide tutti quelli che lo hanno votato.""" - icon = s.terrorist_icon - team = "Evil" - name = s.terrorist_name - powerdesc = s.terrorist_power_description - - def __repr__(self) -> str: - return "" - - def ondeath(self, bot, game): - # Se è stato ucciso da una votazione, attiva il suo potere - if self.player == game.lastlynch: - game.message(bot, s.terrorist_kaboom) - for selectedplayer in game.players: - # Elimina ogni giocatore che sta votando per sè stesso - if selectedplayer.votingfor == self.player: - game.message(bot, s.terrorist_target_killed.format(target=selectedplayer.tusername, - icon=selectedplayer.role.icon, - role=selectedplayer.role.name)) - selectedplayer.kill(bot, game) - - -class Derek(Role): - """Derek muore. Quando gli pare.""" - icon = s.derek_icon - team = "Good" - name = s.derek_name - powerdesc = s.derek_power_description - - def __init__(self, player): - super().__init__(player) - # Per qualche motivo assurdo ho deciso di tenere l'oggetto Player qui - self.deathwish = False - self.chaos = False - - def __repr__(self) -> str: - return "" - - def power(self, bot, game, arg): - # Attiva / disattiva la morte alla fine del round - self.deathwish = not self.deathwish - if self.deathwish: - self.player.message(bot, s.derek_deathwish_unset) - else: - - self.player.message(bot, s.derek_deathwish_set) - - def onendday(self, bot, game): - if self.deathwish: - game.message(bot, s.derek_deathwish_successful.format(name=self.player.tusername)) - self.player.kill(bot, game) - self.chaos = True - - -class Disastro(Role): - """L'investigatore sbadato investiga, ma giunge a conclusioni sbagliate...""" - icon = s.detective_icon - team = 'Good' - name = s.detective_name - powerdesc = s.detective_power_description - refillpoweruses = 1 - - def __init__(self, player): - super().__init__(player) - self.poweruses = self.refillpoweruses - - def __repr__(self) -> str: - return "".format(uses=self.poweruses) - - def power(self, bot, game, arg): - # Indaga sul vero ruolo di una persona, se sono ancora disponibili usi del potere. - if self.poweruses > 0: - target = game.findplayerbyusername(arg) - if target is not None: - self.poweruses -= 1 - randomrole = random.sample(rolepriority, 1)[0] - self.player.message(bot, s.detective_discovery.format(target=target.tusername, - icon=randomrole.icon, - role=randomrole.name, - left=self.poweruses)) - else: - self.player.message(bot, s.error_username) - else: - self.player.message(bot, s.error_no_uses) - - def onendday(self, bot, game): - # Ripristina il potere - self.poweruses = self.refillpoweruses - - def ondeath(self, bot, game): - self.icon = s.disaster_icon - self.name = s.disaster_name - - -class Mamma(Role): - """La mamma sente i pettegolezzi in giro per la città e inizia conoscendo un ruolo a caso...""" - icon = s.mom_icon - team = 'Good' - name = s.mom_name - powerdesc = s.mom_power_description - - def __repr__(self) -> str: - return "" - - def onstartgame(self, bot, game): - # Scegli un bersaglio casuale che non sia il giocatore stesso - possibletargets = game.players.copy() - possibletargets.pop(self.player) - target = random.sample(possibletargets, 1)[0] - self.player.message(bot, s.mom_discovery.format(target=target.tusername, - icon=target.role.icon, - role=target.role.name)) - - -class Stagista(Role): - """Lo stagista sceglie una persona da cui andare in stage e prende il suo ruolo.""" - icon = s.intern_icon - team = 'Good' - name = s.intern_name - powerdesc = s.intern_power_description - - def __init__(self, player): - super().__init__(player) - self.master = None - - def __repr__(self) -> str: - return "" - - def power(self, bot, game, arg): - target = game.findplayerbyusername(arg) - if target is not None and target is not self.player and target.alive: - self.master = target - self.player.message(bot, s.intern_started_internship.format(master=self.master.tusername)) - else: - self.player.message(bot, s.error_no_username) - - def onendday(self, bot, game): - if self.master is not None: - if isinstance(self.master.role, Derek) and self.master.role.chaos: - game.message(bot, s.intern_chaos_summoned) - self.master.alive = True - game.changerole(bot, self.master, SignoreDelCaos) - game.changerole(bot, self.player, Servitore) - else: - game.message(bot, s.intern_changed_role.format(icon=self.master.role.__class__.icon, role=self.master.role.__class__.name)) - game.changerole(bot, self.player, self.master.role.__class__) - - -class SignoreDelCaos(Role): - """Il Signore del Caos è un Derek negli ultimi secondi prima della morte. - Può cambiare la vita delle altre persone... Anche se non può decidere in cosa.""" - icon = s.chaos_lord_icon - team = 'Chaos' - name = s.chaos_lord_name - powerdesc = s.chaos_lord_power_description - - def __init__(self, player): - super().__init__(player) - self.target = None - - def __repr__(self) -> str: - return "" - - def power(self, bot, game, arg): - selected = game.findplayerbyusername(arg) - if selected is not None and selected is not self.player and selected.alive: - self.target = selected - self.player.message(bot, s.chaos_lord_target_selected.format(target=self.target.tusername)) - else: - self.player.message(bot, s.error_no_username) - - def onendday(self, bot, game): - if self.target is not None: - if self.target.alive and self.player.alive: - if not isinstance(self.target.role, SignoreDelCaos) or not isinstance(self.target.role, Servitore): - randomrole = random.sample(rolepriority, 1)[0] - game.changerole(bot, self.target, randomrole) - game.message(bot, s.chaos_lord_randomized) - else: - game.message(bot, s.chaos_lord_failed) - - - -class Servitore(Role): - """Il servitore del Caos è il sottoposto al Signore del Caos. - Se non ci sono Signori del Caos in partita diventa Signore del Caos.""" - icon = s.derek_icon - team = 'Chaos' - name = s.chaos_servant_name - powerdesc = s.chaos_servant_power_description - - def __repr__(self) -> str: - return "" - - def onendday(self, bot, game): - for chaoslord in game.playersinrole["SignoreDelCaos"]: - if chaoslord.alive: - break - else: - game.changerole(bot, self.player, SignoreDelCaos) - game.message(bot, s.chaos_servant_inherited) - - -# Ordine in cui vengono eseguiti i onendday dei vari ruoli. -rolepriority = [Mifioso, Investigatore, Corrotto, Disastro, Angelo, Derek, Stagista, Terrorista, Mamma, SignoreDelCaos, Servitore] - - class Player: """Classe di un giocatore. Contiene tutti i dati riguardanti un giocatore all'interno di una partita, come il ruolo, e i dati riguardanti telegram, come ID e username.""" diff --git a/roles/Angelo.py b/roles/Angelo.py new file mode 100644 index 0000000..765dec4 --- /dev/null +++ b/roles/Angelo.py @@ -0,0 +1,45 @@ +from .Role import Role +import strings as s + +class Angelo(Role): + """L'angelo può proteggere una persona al giorno dalla Mifia. + Se ha successo nella protezione, il suo ruolo sarà rivelato a tutti.""" + icon = s.angel_icon + team = 'Good' + name = s.angel_name + powerdesc = s.angel_power_description + + def __init__(self, player): + super().__init__(player) + self.protecting = None # La persona che questo angelo sta proteggendo + + def __repr__(self) -> str: + if self.protecting is None: + return "" + else: + return "".format(target=self.protecting.tusername) + + def power(self, bot, game, arg): + # Imposta qualcuno come protetto + selected = game.findplayerbyusername(arg) + if selected is None: + self.player.message(bot, s.error_username) + return + + # Controlla che l'angelo stia provando a proteggere sè stesso + if selected is not self.player: + # Togli la protezione a quello che stavi proteggendo prima + if self.protecting is not None: + self.protecting.protectedby = None + # Aggiungi la protezione al nuovo giocatore selezionato + selected.protectedby = self.player + self.protecting = selected + self.player.message(bot, s.angel_target_selected.format(target=self.protecting.tusername)) + else: + self.player.message(bot, s.error_angel_no_selfprotect) + + def onendday(self, bot, game): + # Resetta la protezione + if self.protecting is not None: + self.protecting.protectedby = None + self.protecting = None \ No newline at end of file diff --git a/roles/Corrotto.py b/roles/Corrotto.py new file mode 100644 index 0000000..00f38f4 --- /dev/null +++ b/roles/Corrotto.py @@ -0,0 +1,39 @@ +from .Role import Role +import strings as s + +class Corrotto(Role): + """Il corrotto è un investigatore che lavora per la Mifia.""" + icon = s.detective_icon + team = 'Evil' + name = s.detective_name + powerdesc = s.detective_power_description + refillpoweruses = 1 + + def __init__(self, player): + super().__init__(player) + self.poweruses = self.refillpoweruses + + def __repr__(self) -> str: + return "".format(uses=self.poweruses) + + def power(self, bot, game, arg): + # Indaga sul vero ruolo di una persona, se sono ancora disponibili usi del potere. + if self.poweruses <= 0: + # Non hai abbastanza cariche! + self.player.message(bot, s.error_no_uses) + return + target = game.findplayerbyusername(arg) + if target is None: + # Username non valido + self.player.message(bot, s.error_username) + return + # Utilizza il potere su quella persona + self.poweruses -= 1 + self.player.message(bot, s.detective_discovery.format(target=target.tusername, + icon=target.role.icon, + role=target.role.name, + left=self.poweruses)) + + def onendday(self, bot, game): + # Ripristina il potere + self.poweruses = self.refillpoweruses \ No newline at end of file diff --git a/roles/Derek.py b/roles/Derek.py new file mode 100644 index 0000000..5a0ecf8 --- /dev/null +++ b/roles/Derek.py @@ -0,0 +1,33 @@ +from .Role import Role +import strings as s + +class Derek(Role): + """Derek muore. Quando gli pare.""" + icon = s.derek_icon + team = "Good" + name = s.derek_name + powerdesc = s.derek_power_description + + def __init__(self, player): + super().__init__(player) + # Per qualche motivo assurdo ho deciso di tenere l'oggetto Player qui + self.deathwish = False + self.chaos = False + + def __repr__(self) -> str: + return "" + + def power(self, bot, game, arg): + # Attiva / disattiva la morte alla fine del round + self.deathwish = not self.deathwish + if self.deathwish: + self.player.message(bot, s.derek_deathwish_unset) + else: + + self.player.message(bot, s.derek_deathwish_set) + + def onendday(self, bot, game): + if self.deathwish: + game.message(bot, s.derek_deathwish_successful.format(name=self.player.tusername)) + self.player.kill(bot, game) + self.chaos = True \ No newline at end of file diff --git a/roles/Disastro.py b/roles/Disastro.py new file mode 100644 index 0000000..4d2fb3e --- /dev/null +++ b/roles/Disastro.py @@ -0,0 +1,41 @@ +from .Role import Role +import strings as s + +class Disastro(Role): + """L'investigatore sbadato investiga, ma giunge a conclusioni sbagliate...""" + icon = s.detective_icon + team = 'Good' + name = s.detective_name + powerdesc = s.detective_power_description + refillpoweruses = 1 + + def __init__(self, player): + super().__init__(player) + self.poweruses = self.refillpoweruses + + def __repr__(self) -> str: + return "".format(uses=self.poweruses) + + def power(self, bot, game, arg): + # Indaga sul vero ruolo di una persona, se sono ancora disponibili usi del potere. + if self.poweruses > 0: + target = game.findplayerbyusername(arg) + if target is not None: + self.poweruses -= 1 + randomrole = random.sample(rolepriority, 1)[0] + self.player.message(bot, s.detective_discovery.format(target=target.tusername, + icon=randomrole.icon, + role=randomrole.name, + left=self.poweruses)) + else: + self.player.message(bot, s.error_username) + else: + self.player.message(bot, s.error_no_uses) + + def onendday(self, bot, game): + # Ripristina il potere + self.poweruses = self.refillpoweruses + + def ondeath(self, bot, game): + self.icon = s.disaster_icon + self.name = s.disaster_name diff --git a/roles/Investigatore.py b/roles/Investigatore.py new file mode 100644 index 0000000..7f92bc6 --- /dev/null +++ b/roles/Investigatore.py @@ -0,0 +1,39 @@ +from .Role import Role +import strings as s + +class Investigatore(Role): + """L'investigatore può indagare sul vero ruolo di una persona una volta al giorno.""" + icon = s.detective_icon + team = 'Good' + name = s.detective_name + powerdesc = s.detective_power_description + refillpoweruses = 1 + + def __init__(self, player): + super().__init__(player) + self.poweruses = self.refillpoweruses + + def __repr__(self) -> str: + return "".format(uses=self.poweruses) + + def power(self, bot, game, arg): + # Indaga sul vero ruolo di una persona, se sono ancora disponibili usi del potere. + if self.poweruses <= 0: + # Non hai abbastanza cariche! + self.player.message(bot, s.error_no_uses) + return + target = game.findplayerbyusername(arg) + if target is None: + # Username non valido + self.player.message(bot, s.error_username) + return + # Utilizza il potere su quella persona + self.poweruses -= 1 + self.player.message(bot, s.detective_discovery.format(target=target.tusername, + icon=target.role.icon, + role=target.role.name, + left=self.poweruses)) + + def onendday(self, bot, game): + # Ripristina il potere + self.poweruses = self.refillpoweruses \ No newline at end of file diff --git a/roles/Mamma.py b/roles/Mamma.py new file mode 100644 index 0000000..5a94e09 --- /dev/null +++ b/roles/Mamma.py @@ -0,0 +1,22 @@ +from .Role import Role +import strings as s +import random + +class Mamma(Role): + """La mamma sente i pettegolezzi in giro per la città e inizia conoscendo un ruolo a caso...""" + icon = s.mom_icon + team = 'Good' + name = s.mom_name + powerdesc = s.mom_power_description + + def __repr__(self) -> str: + return "" + + def onstartgame(self, bot, game): + # Scegli un bersaglio casuale che non sia il giocatore stesso + possibletargets = game.players.copy() + possibletargets.pop(self.player) + target = random.sample(possibletargets, 1)[0] + self.player.message(bot, s.mom_discovery.format(target=target.tusername, + icon=target.role.icon, + role=target.role.name)) diff --git a/roles/Mifioso.py b/roles/Mifioso.py new file mode 100644 index 0000000..ece1b7a --- /dev/null +++ b/roles/Mifioso.py @@ -0,0 +1,53 @@ +from .Role import Role +import strings as s + +class Mifioso(Role): + """Il nemico globale. Può impostare come bersaglio una persona al giorno, per poi ucciderla alla fine.""" + icon = s.mifia_icon + team = 'Evil' + name = s.mifia_name + powerdesc = s.mifia_power_description + + def __init__(self, player): + super().__init__(player) + self.target = None + + def __repr__(self) -> str: + if self.target is None: + return "" + else: + return "".format(target=self.target.tusername) + + def power(self, bot, game, arg): + # Imposta una persona come bersaglio da uccidere. + selected = game.findplayerbyusername(arg) + if selected is None: + self.player.message(bot, s.error_username) + return + self.target = selected + self.player.message(bot, s.mifia_target_selected.format(target=self.target.tusername)) + + + def onendday(self, bot, game): + if game.votingmifia: + # Se la partita è in modalità votingmifia l'uccisione della mifia viene gestita dalla classe Game + self.target = None + else: + # Uccidi il bersaglio se non è protetto da un Angelo. + if self.target is not None: + if self.target.protectedby is None: + if game.missingmifia and random.randrange(0, 100) < game.misschance: + # Colpo mancato + game.message(bot, s.mifia_target_missed.format(target=self.target.tusername)) + else: + # Uccisione riuscita + self.target.kill(bot, self) + game.message(bot, s.mifia_target_killed.format(target=self.target.tusername, + icon=self.target.role.icon, + role=self.target.role.name)) + else: + # Bersaglio protetto da un angelo + game.message(bot, s.mifia_target_protected.format(target=self.target.tusername, + icon=self.target.protectedby.role.icon, + protectedby=self.target.protectedby.tusername)) + self.target = None diff --git a/roles/Role.py b/roles/Role.py new file mode 100644 index 0000000..a462f73 --- /dev/null +++ b/roles/Role.py @@ -0,0 +1,32 @@ +# Base di un ruolo +class Role: + """Classe base di un ruolo. Da qui si sviluppano tutti gli altri ruoli.""" + icon = "-" # Icona del ruolo, da visualizzare di fianco al nome + team = 'None' # Squadra: 'None', 'Good', 'Evil', 'Chaos'; conta per le condizioni di vittoria + name = "UNDEFINED" # Nome del ruolo, viene visualizzato dall'investigatore e durante l'assegnazione + powerdesc = None # Ha un potere? Se sì, queste sono le info su come usarlo in seconda persona. + + def __init__(self, player): + self.player = player + + def __repr__(self) -> str: + return "" + + def __str__(self) -> str: + return "{} {}".format(self.icon, self.name) + + def power(self, bot, game, arg): + """Il potere del ruolo. Si attiva quando il bot riceve un /power in chat privata.""" + pass + + def onendday(self, bot, game): + """Metodo chiamato alla fine di ogni giorno.""" + pass + + def ondeath(self, bot, game): + """Metodo chiamato alla morte del giocatore.""" + pass + + def onstartgame(self, bot, game): + """Metodo chiamato all'inizio della partita.""" + pass \ No newline at end of file diff --git a/roles/Royal.py b/roles/Royal.py new file mode 100644 index 0000000..e55fe6c --- /dev/null +++ b/roles/Royal.py @@ -0,0 +1,14 @@ +from .Role import Role +import strings as s + +class Royal(Role): + """Un membro della Royal Games. Il ruolo principale, non ha alcun potere se non quello di votare.""" + icon = s.royal_icon + team = 'Good' + name = s.royal_name + + def __init__(self, player): + super().__init__(player) + + def __repr__(self) -> str: + return "" \ No newline at end of file diff --git a/roles/Servitore.py b/roles/Servitore.py new file mode 100644 index 0000000..b36bc13 --- /dev/null +++ b/roles/Servitore.py @@ -0,0 +1,22 @@ +from .Role import Role +from .SignoreDelCaos import SignoreDelCaos +import strings as s + +class Servitore(Role): + """Il servitore del Caos è il sottoposto al Signore del Caos. + Se non ci sono Signori del Caos in partita diventa Signore del Caos.""" + icon = s.derek_icon + team = 'Chaos' + name = s.chaos_servant_name + powerdesc = s.chaos_servant_power_description + + def __repr__(self) -> str: + return "" + + def onendday(self, bot, game): + for chaoslord in game.playersinrole["SignoreDelCaos"]: + if chaoslord.alive: + break + else: + game.changerole(bot, self.player, SignoreDelCaos) + game.message(bot, s.chaos_servant_inherited) diff --git a/roles/SignoreDelCaos.py b/roles/SignoreDelCaos.py new file mode 100644 index 0000000..44a68c3 --- /dev/null +++ b/roles/SignoreDelCaos.py @@ -0,0 +1,38 @@ +from .Role import Role +from .Servitore import Servitore +from . import rolepriority +import strings as s +import random + +class SignoreDelCaos(Role): + """Il Signore del Caos è un Derek negli ultimi secondi prima della morte. + Può cambiare la vita delle altre persone... Anche se non può decidere in cosa.""" + icon = s.chaos_lord_icon + team = 'Chaos' + name = s.chaos_lord_name + powerdesc = s.chaos_lord_power_description + + def __init__(self, player): + super().__init__(player) + self.target = None + + def __repr__(self) -> str: + return "" + + def power(self, bot, game, arg): + selected = game.findplayerbyusername(arg) + if selected is not None and selected is not self.player and selected.alive: + self.target = selected + self.player.message(bot, s.chaos_lord_target_selected.format(target=self.target.tusername)) + else: + self.player.message(bot, s.error_no_username) + + def onendday(self, bot, game): + if self.target is not None: + if self.target.alive and self.player.alive: + if not isinstance(self.target.role, SignoreDelCaos) or not isinstance(self.target.role, Servitore): + randomrole = random.sample(rolepriority, 1)[0] + game.changerole(bot, self.target, randomrole) + game.message(bot, s.chaos_lord_randomized) + else: + game.message(bot, s.chaos_lord_failed) diff --git a/roles/Stagista.py b/roles/Stagista.py new file mode 100644 index 0000000..b2094cc --- /dev/null +++ b/roles/Stagista.py @@ -0,0 +1,38 @@ +from .Role import Role +from .Derek import Derek +from .SignoreDelCaos import SignoreDelCaos +from .Servitore import Servitore +import strings as s + +class Stagista(Role): + """Lo stagista sceglie una persona da cui andare in stage e prende il suo ruolo.""" + icon = s.intern_icon + team = 'Good' + name = s.intern_name + powerdesc = s.intern_power_description + + def __init__(self, player): + super().__init__(player) + self.master = None + + def __repr__(self) -> str: + return "" + + def power(self, bot, game, arg): + target = game.findplayerbyusername(arg) + if target is not None and target is not self.player and target.alive: + self.master = target + self.player.message(bot, s.intern_started_internship.format(master=self.master.tusername)) + else: + self.player.message(bot, s.error_no_username) + + def onendday(self, bot, game): + if self.master is not None: + if isinstance(self.master.role, Derek) and self.master.role.chaos: + game.message(bot, s.intern_chaos_summoned) + self.master.alive = True + game.changerole(bot, self.master, SignoreDelCaos) + game.changerole(bot, self.player, Servitore) + else: + game.message(bot, s.intern_changed_role.format(icon=self.master.role.__class__.icon, role=self.master.role.__class__.name)) + game.changerole(bot, self.player, self.master.role.__class__) diff --git a/roles/Terrorista.py b/roles/Terrorista.py new file mode 100644 index 0000000..298f63c --- /dev/null +++ b/roles/Terrorista.py @@ -0,0 +1,25 @@ +from .Role import Role +import strings as s + +class Terrorista(Role): + """Il terrorista è un mifioso che può uccidere in un solo modo: facendosi uccidere dai Royal. + Se riesce, vince la partita e uccide tutti quelli che lo hanno votato.""" + icon = s.terrorist_icon + team = "Evil" + name = s.terrorist_name + powerdesc = s.terrorist_power_description + + def __repr__(self) -> str: + return "" + + def ondeath(self, bot, game): + # Se è stato ucciso da una votazione, attiva il suo potere + if self.player == game.lastlynch: + game.message(bot, s.terrorist_kaboom) + for selectedplayer in game.players: + # Elimina ogni giocatore che sta votando per sè stesso + if selectedplayer.votingfor == self.player: + game.message(bot, s.terrorist_target_killed.format(target=selectedplayer.tusername, + icon=selectedplayer.role.icon, + role=selectedplayer.role.name)) + selectedplayer.kill(bot, game) \ No newline at end of file diff --git a/roles/__init__.py b/roles/__init__.py new file mode 100644 index 0000000..08a8e6b --- /dev/null +++ b/roles/__init__.py @@ -0,0 +1,16 @@ +from .Role import Role +from .Angelo import Angelo +from .Corrotto import Corrotto +from .Derek import Derek +from .Disastro import Disastro +from .Investigatore import Investigatore +from .Mamma import Mamma +from .Mifioso import Mifioso +from .Royal import Royal +from .Servitore import Servitore +from .SignoreDelCaos import SignoreDelCaos +from .Stagista import Stagista +from .Terrorista import Terrorista + +# Ordine in cui vengono eseguiti i onendday dei vari ruoli. +rolepriority = [Mifioso, Investigatore, Corrotto, Disastro, Angelo, Derek, Stagista, Terrorista, Mamma, SignoreDelCaos, Servitore]