Пример #1
0
    def __init__(self, size):
        """Construct a square TetrisGrid with the given size."""

        # Initialise grid squares
        grid_squares = []
        for column_index in range(0, size):
            column = []
            for row_index in range(0, size):
                column.append(GridSquare())
            grid_squares.append(column)

        super(TetrisGrid, self).__init__(
            attrs_dict={
                "_size": size,
                "x_bounds": (0, size - 1),
                "y_bounds": (0, size - 1),
                "grid_squares": grid_squares
            })

        # Populate grid with fixed elements
        for row_num in range(*self.y_bounds):
            # Left Wall
            self._get_grid_square(Position(self.x_bounds[0],
                                           row_num)).fill_with(
                                               Element(ElementType.WALL))
            # Right wall
            self._get_grid_square(Position(self.y_bounds[-1],
                                           row_num)).fill_with(
                                               Element(ElementType.WALL))

        # Floor
        for col_num in range(*self.y_bounds):
            self._get_grid_square(Position(col_num,
                                           self.y_bounds[0])).fill_with(
                                               Element(ElementType.WALL))
Пример #2
0
    def __init__(self, name=""):
        self.comment                = ""
        self.created_time           = datetime.datetime.now()  # Data di creazione del'account
        self.name                   = name  # Nome di login
        self.password               = ""    # Password
        self.email                  = ""    # Indirizzo e-mail (opzionale)
        self.options                = Flags(OPTION.NONE)
        self.show_logs              = Flags(LOG.NONE)
        self.aliases                = {}  # Dizionario relativo agli alias
        self.macros                 = {}  # Dizionario relativo alle macro
        # (TD) provare a convertire questi datetime in None e caricarli tramite schema
        self.last_bug_sended_at     = None
        self.last_comment_sended_at = None
        self.last_typo_sended_at    = None
        self.last_idea_sended_at    = None
        self.sended_bugs            = 0  # Bug totali inviati
        self.sended_comments        = 0  # Typo totali inviati
        self.sended_ideas           = 0  # Idee totali inviati
        self.sended_typos           = 0  # Typo totali inviati
        self.user_agents            = [] # Informazioni relative ai client browser utilizzati dal giocatore per entrare nel Mud
        self.resolution_width       = 0  # Risoluzione in pixel del monitor del client in larghezza
        self.resolution_height      = 0  # Risoluzione in pixel del monitor del client in altezza

        # Al primo account creato in assoluto dà poteri di Implementor, dando
        # per scontato che il primo giocatore che utilizza questo Mud sia il
        # futuro amministratore, ai successivi account dona la trust di player
        if not database["accounts"]:
            self.trust = Element(TRUST.IMPLEMENTOR)
        else:
            self.trust = Element(TRUST.PLAYER)

        # Attributi volatili
        self.players = {}  # Dizionario dei giocatori creati dall'account
        self.player  = None  # Personaggio che si sta creando o utilizzando
Пример #3
0
    def __init__(self, code=""):
        super(Mob, self).__init__()
        BehaviourUpdaterSuperclass.__init__(self)

        self.code = ""
        self.prototype = None
        if code:
            self.reinit_code(code)
            copy_existing_attributes(self.prototype,
                                     self,
                                     except_these_attrs=["code"])
            self.after_copy_existing_attributes()

        # Eventuale inizializzazione dei punti
        if self.max_life == 0:
            self.max_life = config.starting_points
        if self.max_mana == 0:
            self.max_mana = config.starting_points
        if self.max_vigour == 0:
            self.max_vigour = config.starting_points
        if self.life == 0:
            self.life = self.max_life
        if self.mana == 0:
            self.mana = self.max_mana
        if self.vigour == 0:
            self.vigour = self.max_vigour

        if self.hand == HAND.NONE:
            self.hand = self.hand.randomize()

        # Variabili proprie di una istanza di mob:
        self.area = None
        self.attack = 1
        self.defense = 1
        self.speaking = Element(
            LANGUAGE.COMMON
        )  # Indica con quale linguaggio sta attualmente parlando il mob
        self.style = Element(
            STYLE.NONE)  # Style di combattimento che sta utilizzando
        self.experience = 0  # Esperienza accumulata prima di poter livellare
        self.mount = None  # Indica quale mob o pg sta cavalcando
        self.mounted_by = None  # Indica da quali mob o pg è cavalcato
        self.specials = {
        }  # E' una lista di variabili speciali, possono essere utilizzate come delle flags, vengono aggiunte di solito nei gamescript
        self.reply = None  # Entità a cui si può replicare
        #       self.tracking        = Track()  # Serve quando il mob inizia a tracciare e cacciare una preda fuggita
        self.last_fight_time = None
        self.last_death_time = None

        # Contatori di statistica
        self.defeat_from_mob_counter = 0  # Conteggio delle sconfitte
        self.defeat_from_item_counter = 0  # Conteggio delle sconfitte
        self.defeat_from_player_counter = 0  # Conteggio delle sconfitte
        self.death_from_player_counter = 0  # Conteggio delle sconfitte
        self.mob_defeated_counter = 0  # Conteggio delle vittorie sui mob
        self.item_defeated_counter = 0  # Conteggio degli oggetti distrutti
        self.player_defeated_counter = 0  # Conteggio delle vittorie sui giocatori
        self.player_killed_counter = 0  # Conteggio delle volte che viene ucciso un giocatore

        check_trigger(self, "on_init", self)
Пример #4
0
    def fread_the_line(self, file, line, attr):
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not line:
            log.bug("line non è un parametro valido: %r" % line)
            return

        if not attr:
            log.bug("attr non è un parametro valido: %r" % attr)
            return

        # ---------------------------------------------------------------------

        try:
            entitype, percent, buyback_percent = line.split(None, 2)
        except ValueError:
            log.bug(
                "Errore nella lettura di un Sellable nel file <%s> per la linea <%s> e l'attributo <%s>"
                % (file.name, line, attr))
            return

        self.entitype = Element(entitype)
        self.percent = fread_percent(file, percent, attr)
        self.buyback_percent = fread_percent(file, buyback_percent, attr)
Пример #5
0
    def fread_the_line(self, file, line, attr):
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not line:
            log.bug("line non è un parametro valido: %r" % line)
            return

        if not attr:
            log.bug("attr non è un parametro valido: %r" % attr)
            return

        # ---------------------------------------------------------------------

        if "," in line:
            material, percent = line.split(",", 1)
        else:
            material, percent = line.split(None, 1)

        material = material.strip()
        percent = percent.strip()

        self.material = Element(material)
        self.percent = fread_percent(file, percent, attr)
Пример #6
0
 def __init__(self):
     self.comment         = ""
     self.fun_name        = ""  # Nome della funzione del comando legato al social
     self.intention       = Element(INTENTION.NONE)  # Tipologia di intenzione
     self.smiles          = ""  # Elenco degli smile supportati dal social
     self.expression      = ""  # Espressione relativa al'utilizzo degli smile
     self.racial_messages = EnumElementDict()
Пример #7
0
    def render_POST(self, request, conn):
        #if conn.new_player and conn.new_player.code in database["players"]:
        #    return "\nImpossibile creare il personaggio %s perché già esistente.\n" % conn.new_player.name

        page = self.check_number_of_players(request, conn)
        if page:
            return page

        # Ricava gli argomenti del form dalla richiesta
        race = ""
        if "race" in request.args:
            race = Element(request.args["race"][0])

        sex = ""
        if "sex" in request.args:
            sex = Element(request.args["sex"][0])

        constellation = ""
        if "constellation" in request.args:
            constellation = Element(request.args["constellation"][0])

        # Controlla la validità degli argomenti inseriti nel form
        err_msg_race = ""
        if not race:
            err_msg_race = "Scegli la razza che vuoi interpretare"
            race = RACE.NONE
        else:
            # (TD) per ora gestisce la sessualità unica delle Frijen in maniera forzata
            if race == RACE.FRIJEN:
                sex = SEX.FEMALE

        err_msg_sex = ""
        if not sex:
            err_msg_sex = "Scegli la sessualità che vuoi interpretare"
            sex = SEX.NONE

        err_msg_constellation = ""
        if not constellation:
            err_msg_constellation = "Scegli la costellazione sotto cui il tuo personaggio è nato"
            constellation = CONSTELLATION.NONE

        # Se tutti gli argomenti del form sono validi crea il personaggio e
        # passa alla pagina di creazione successiva
        if not err_msg_race and not err_msg_sex and not err_msg_constellation:
            new_player = Player()
            new_player.race = race
            new_player.sex = sex
            new_player.constellation = constellation
            conn.new_player = new_player
            request.redirect("create_player2.html")
            request.finish()
            return server.NOT_DONE_YET

        return self.create_page(request, conn, race, sex, constellation,
                                err_msg_race, err_msg_sex,
                                err_msg_constellation)
Пример #8
0
    def load(self):
        filepath = "persistence/calendar.rpg"
        try:
            file = open(filepath, "r")
        except IOError:
            log.bug("Impossibile aprire il file %s in lettura" % filepath)
            return

        for line in file:
            if not line.strip():
                continue
            if line[0] == "#":
                continue
            break
        else:
            log.bug("Non è stato trovato nessuna riga valida al file %s" %
                    filepath)
            file.close()
            return
        file.close()

        values = line.split()
        if len(values) != 5:
            log.bug(
                "E' stato trovato un numero inatteso di valori al file %s: %d"
                % (filepath, len(values)))
            return

        if is_number(values[0]):
            self.minute = int(values[0])
        else:
            log.bug("minute del file %s non sono un numero valido: %s" %
                    values[0])

        if is_number(values[1]):
            self.hour = int(values[1])
        else:
            log.bug("hour del file %s non sono un numero valido: %s" %
                    values[1])

        if is_number(values[2]):
            self.day = int(values[2])
        else:
            log.bug("day del file %s non sono un numero valido: %s" %
                    values[2])

        self.month = Element(values[3])

        if is_number(values[4]):
            self.year = int(values[4])
        else:
            log.bug("year del file %s non sono un numero valido: %s" %
                    values[4])

        self.get_error_message()
Пример #9
0
class Weapon(object):
    PRIMARY_KEY = ""
    VOLATILES = []
    MULTILINES = ["comment"]
    SCHEMA = {}
    REFERENCES = {}
    WEAKREFS = {}

    def __init__(self):
        self.comment = ""
        self.category = Element(WEAPON.NONE)  # Tipo di arma
        self.flags = Flags(WEAPONFLAG.NONE)  # Flag di arma
        self.damage = ""  # Danno dell'arma, se vuoto viene ricavato automaticamente tramite una tabella

    #- Fine Inizializzazione -

    def __str__(self):
        return "%r: %s" % (self, sorted(self.__dict__))

    #- Fine Metodo -

    def get_error_message(self, entity):
        if self.category.get_error_message(WEAPON, "category") != "":
            return self.category.get_error_message(WEAPON, "category")
        elif self.flags.get_error_message(WEAPONFLAG, "flags") != "":
            return self.category.get_error_message(WEAPONFLAG, "flags")

        return ""

    #- Fine Metodo -

    def copy(self, to_obj=None, avoid_volatiles=False):
        if not to_obj:
            to_obj = Weapon()
        copy_existing_attributes(self, to_obj, avoid_volatiles=avoid_volatiles)
        return to_obj

    #- Fine Metodo -

    def equals(self, weapon2):
        if not weapon2:
            return False

        if self.comment != weapon2.comment:
            return False
        if self.category != weapon2.category:
            return False
        if self.flags != weapon2.flags:
            return False
        if self.damage != weapon2.damage:
            return False

        return True
Пример #10
0
    def __init__(self, code=""):
        self.comment        = ""
        self.code           = code # Codice identificativo dell'area
        self.name           = ""   # Nome esteso
        self.short          = ""   # Descrizioni breve dell'area
        self.short_night    = ""   # Descrizioni breve notturna dell'area
        self.descr          = ""   # Descrizione dell'area per la pagina web della lista delle aree
        self.creators       = ""   # Lista dei creatori, vale il codice dell'account  (TD) in futuro sarà una lista per poter ricavare il riferimento
        self.level          = 1    # Livello base per tutte le entità dell'area, se viene modificato questo anche tutte le entità aumentano o diminuiscono di livello in proporzione
        self.flags          = Flags(AREA.NONE)
#       self.races          = Flags(RACE.NONE)  # Razze che si possono incontrare principalmente nell'area  (TD)
        self.color          = Element(COLOR.NONE)  # Colore dell'area
        self.music          = ""   # File mid avviato quando uno entra nell'area
        self.music_wild     = ""   # File mid avviato quando uno esce dall'area ed entra nella wild
        self.climates       = {}   # Informazioni climatiche dell'area relativamente alle stagioni
        self.maze           = None # Informazioni relative al labirinto
        self.wumpus         = None # Informazioni relative alle aree wumpus
        self.wild           = None # Struttura relativa alla wilderness
        self.landfill_code  = ""   # Codice della stanza prototipo in cui verranno inseriti gli oggetti "da buttare"
        self.repop_time     = 0    # Minuti reali tra un repop di un'entità ed un'altro
        self.room_resets    = []   # Lista dei reset dell'area

        # Attributi relativi alle liste dei messaggi di echo
        self.echoes_dawn               = []
        self.echoes_dawn_no_sun        = []
        self.echoes_sunrise            = []
        self.echoes_sunrise_no_sun     = []
        self.echoes_noon               = []
        self.echoes_noon_no_sun        = []
        self.echoes_sunset             = []
        self.echoes_sunset_no_sun      = []
        self.echoes_dusk               = []
        self.echoes_dusk_no_moon       = []
        self.echoes_dusk_full_moon     = []
        self.echoes_midnight           = []
        self.echoes_midnight_no_moon   = []
        self.echoes_midnight_full_moon = []

        # Attributi volatili:
        self.max_players    = 0  # Numero massimo di giocatori che sono stati presenti contemporaneamente nell'area nella sessione di gioco
        self.upper_limit    = 0  # Limite di coordinata Z verso l'alto oltre la quale si esce dall'area
        self.lower_limit    = 0  # Limite di coordinata Z verso il basso oltre la quale si esce dall'area
        self.rooms          = {} # Stanze in-game nelle rispettive coordinate
        self.players        = [] # Giocatori in-game che si trovano nelll'area
        self.mobs           = [] # Mob in-game che si trovano nell'area
        self.items          = [] # Oggetti in-game che si trovano nell'area
        self.meteo          = Meteo()  # Informazioni meteo in-game dell'area
        self.gamescripts    = {}   # Gamescript a livello di area

        # Liste relative ai dati modello dell'area, i prototipi
        self.proto_rooms    = {}
        self.proto_mobs     = {}
        self.proto_items    = {}
Пример #11
0
class Weapon(object):
    PRIMARY_KEY = ""
    VOLATILES   = []
    MULTILINES  = ["comment"]
    SCHEMA      = {}
    REFERENCES  = {}
    WEAKREFS    = {}

    def __init__(self):
        self.comment  = ""
        self.category = Element(WEAPON.NONE)   # Tipo di arma
        self.flags    = Flags(WEAPONFLAG.NONE) # Flag di arma
        self.damage   = ""  # Danno dell'arma, se vuoto viene ricavato automaticamente tramite una tabella
    #- Fine Inizializzazione -

    def __str__(self):
        return "%r: %s" % (self, sorted(self.__dict__))
    #- Fine Metodo -

    def get_error_message(self, entity):
        if self.category.get_error_message(WEAPON, "category") != "":
            return self.category.get_error_message(WEAPON, "category")
        elif self.flags.get_error_message(WEAPONFLAG, "flags") != "":
            return self.category.get_error_message(WEAPONFLAG, "flags")

        return ""
    #- Fine Metodo -

    def copy(self, to_obj=None, avoid_volatiles=False):
        if not to_obj:
            to_obj = Weapon()
        copy_existing_attributes(self, to_obj, avoid_volatiles=avoid_volatiles)
        return to_obj
    #- Fine Metodo -

    def equals(self, weapon2):
        if not weapon2:
            return False

        if self.comment != weapon2.comment:
            return False
        if self.category != weapon2.category:
            return False
        if self.flags != weapon2.flags:
            return False
        if self.damage != weapon2.damage:
            return False

        return True
Пример #12
0
    def __init__(self, columns=0, rows=0, code_prefix=""):
        self.columns = columns  # Numero di colonne totali del labirinto
        self.rows = rows  # Numero di righe totali del labirinto
        self.code_prefix = code_prefix  # Prefisso del codice delle room utilizzate per il reset
        self.remake_hour = -1  # In quale ora il maze viene ricreato
        self.remake_weekday = Element(WEEKDAY.NONE)
        self.remake_message = ""  # Messaggio di act a tutte le entità nel labirinto durante il relativo remake
        self.passages = [
        ]  # Elenco dei passaggi: entrate, uscite o altre nicchie, collegate al labirinto attorno al suo bordo
        self.dead_ends = [
        ]  # Elenco dei vicoli ciechi casualmente da inserire al posto di quelli standard

        # Variabili volatili
        self.cells = []
        self.track_counter = 0  # Numero di room tracciate dall'algoritmo di creazione del maze
Пример #13
0
    def fread_the_line(self, file, line, attr):
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not line:
            log.bug("line non è un parametro valido: %r" % line)
            return

        if not attr:
            log.bug("attr non è un parametro valido: %r" % attr)
            return

        # ---------------------------------------------------------------------

        try:
            entitype, percent, buyback_percent = line.split(None, 2)
        except ValueError:
            log.bug("Errore nella lettura di un Sellable nel file <%s> per la linea <%s> e l'attributo <%s>" % (
                file.name, line, attr))
            return

        self.entitype        = Element(entitype)
        self.percent         = fread_percent(file, percent, attr)
        self.buyback_percent = fread_percent(file, buyback_percent, attr)
Пример #14
0
    def fread_the_line(self, file, line, attr):
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not line:
            log.bug("line non è un parametro valido: %r" % line)
            return

        if not attr:
            log.bug("attr non è un parametro valido: %r" % attr)
            return

        # ---------------------------------------------------------------------

        if "," in line:
            material, percent = line.split(",", 1)
        else:
            material, percent = line.split(None, 1)

        material = material.strip()
        percent = percent.strip()

        self.material = Element(material)
        self.percent = fread_percent(file, percent, attr)
Пример #15
0
    def __init__(self, direction=DIR.NONE):
        if not direction:
            log.bug("direction non è un parametro valido: %r" % direction)
            return

        # ---------------------------------------------------------------------

        self.comment             = ""  # Eventuale commento al muro
        self.direction           = Element(direction)  # Tipologia della direzione
        self.maked_by            = None  # Oggetto di base utilizzato nella costruzione del muro (di solito un mattone o una pietra)
        self.depth               = 0   # Profondità della parete, assieme al tipo di materiale in quella direzione ne fanno la forza, che serve nel caso si voglia romperlo, picconarlo, sfondarlo o farlo saltare in aria!
        self.height              = 0   # Altezza del muro, se differente dall'altezza della stanza
        self.descr               = ""  # Descrizione dell'uscita che viene a formarsi quando il muro viene sfondato
        self.descr_night         = ""  # Descrizione notturna dell'uscita che viene a formarsi quando il muro viene sfondato
        self.descr_hearing       = ""  # Descrizione uditiva
        self.descr_hearing_night = ""  # Descrizione uditiva notturna
        self.descr_smell         = ""  # Descrizione odorosa
        self.descr_smell_night   = ""  # Descrizione odorosa notturna
        self.descr_touch         = ""  # Descrizione tattile
        self.descr_touch_night   = ""  # Descrizione tattile notturna
        self.descr_taste         = ""  # Descrizione del sapore
        self.descr_taste_night   = ""  # Descrizione del sapore notturna
        self.descr_sixth         = ""  # Descrizione del sesto senso
        self.descr_sixth_night   = ""  # Descrizione del sesto senso notturna
        self.extras              = Extras()  # Elenco delle extra che si possono guardare o leggere sul muro
Пример #16
0
    def __init__(self, fun_name=""):
        self.comment   = ""
        self.fun_name  = fun_name or ""  # Nome della funzione
        self.type      = Element(CMDTYPE.INFORMATION) # Tipologia del comando
        self.trust     = Element(TRUST.PLAYER)  # Fiducia minima per digitarlo
        self.position  = Element(POSITION.REST)  # Posizione minima per utilizzarlo
        self.flags     = Flags(CMDFLAG.NONE)  # Flag dei comandi
        self.no_races  = Flags(RACE.NONE)  # Razze che NON possono usarlo (RACE.NONE significa che tutti lo possono utilizzare)
        self.mini_help = ""   # Piccola descrizione dell'utilizzo del comando
        self.timer     = 0.0  # Tempo totale di esecuzione del comando (anche se nelle pagine d'amministrazione visualizza il tempo medio)

        # Variabili volatili
        self.module    = None  # Riferimento al modulo che contiene la funzione
        self.function  = None  # Riferimento alla funzione
        if self.fun_name:
            self.import_module_and_function()
Пример #17
0
    def __init__(self, direction=DIR.NONE):
        if not direction:
            log.bug("direction non è un parametro valido: %r" % direction)
            return

        # ---------------------------------------------------------------------

        self.comment             = ""  # Eventuale commento all'uscita
        self.direction           = Element(direction)  # Tipologia della direzione
        self.descr               = ""  # Descrizione di quello che si vede guardando la direzione
        self.descr_night         = ""  # Descrizione notturna di quello che si vede guardando la direzione
        self.descr_hearing       = ""  # Descrizione uditiva
        self.descr_hearing_night = ""  # Descrizione uditiva notturna
        self.descr_smell         = ""  # Descrizione odorosa
        self.descr_smell_night   = ""  # Descrizione odorosa notturna
        self.descr_touch         = ""  # Descrizione tattile
        self.descr_touch_night   = ""  # Descrizione tattile notturna
        self.descr_taste         = ""  # Descrizione del sapore
        self.descr_taste_night   = ""  # Descrizione del sapore notturna
        self.descr_sixth         = ""  # Descrizione del sesto senso
        self.descr_sixth_night   = ""  # Descrizione del sesto senso notturna
        self.icon                = ""  # Icona rappresentante l'uscita di giorno
        self.icon_night          = ""  # Icona rappresentante l'uscita di notte
        self.extras              = Extras()  # Descrizioni extra dell'uscita
        self.flags               = Flags(EXIT.NONE)  # Flags dell'uscita
        self.destination         = None # Stanza a cui l'uscita porta se questa differente rispetto alla direzione presa
        self.door                = None # Oggetto porta se serve aprirla (se non viene indicata questa viene caricata dal limbo una porta di default)  (TD) qui vorrei aggiungere anche una variabile finestra.. ma poi come gestire finestre e porte multiple? e il key_code nel qual caso una finestra sia chiudibile (cmq per ora continuo così.. in effetti potrei considerare il fatto di voler inserire più porte o finestre in una uscita come una eccezione e gestirla tramite gamescripts)
        self.entity_message      = ""   # Messaggio di movimento per colui che si sta spostando
        self.others_in_message   = ""   # Messaggio di movimento per gli altri della stanza di partenza
        self.others_out_message  = ""   # Messaggio di movimento per gli altri della stanza di arrivo
Пример #18
0
    def test_should_fill_with_element(self):  # noqa: D102
        grid_square = GridSquare()
        element = Element(ElementType.WALL)

        grid_square.fill_with(element)

        self.assertFalse(grid_square.is_empty())
Пример #19
0
    def test_should_clear(self):  # noqa: D102
        grid_square = GridSquare()
        element = Element(ElementType.WALL)
        grid_square.fill_with(element)

        grid_square.clear()

        self.assertTrue(grid_square.is_empty())
Пример #20
0
 def _wait_for_element(self):
     self._element = Element(self._driver, self._locator, self._position)
     WebDriverWait(self._driver, self._timeout).until(
         EC.visibility_of_element_located(
             (By.XPATH, self._element.locator)),
         "{} is not visible after {} seconds".format(
             self._element.name, self._timeout))
     self._position = 0
Пример #21
0
 def __init__(self):
     self.comment = ""  # Commento per gli area builder relativo all'entità leggibile
     self.title = ""  # Titolo del libro
     self.author = ""  # Autore o gli autori di questo libro
     self.summary = ""  # Riassunto del libro che il giocatore carpisce esaminandolo
     self.language = Element(LANGUAGE.COMMON)  # (TD) Lingua di questo libro
     self.flags = Flags(
         READABLE.NONE)  # Flag relative alle entità leggibili
     self.visual_width = ""  # Larghezza in pixel del libro sullo schermo
     self.visual_height = ""  # Larghezza in pixel del libro sullo schermo
     self.padding = ""  # Larghezza in pixel del padding della cornice del libro
     self.border_top = ""  # Bordo css decorante il libro in alto
     self.border_right = ""  # Bordo css decorante il libro a destra
     self.border_bottom = ""  # Bordo css decorante il libro in basso
     self.border_left = ""  # Bordo css decorante il libro a sinistra
     self.border_inside = ""  # Bordo css decorante il libro tra le due pagine
     self.number_decoration_left = ""  # Decorazione della pagina sinistra per i numeri di pagina
     self.number_decoration_right = ""  # Decorazione della pagina sinistra per i numeri di pagina
     self.pages = []  # Lista delle pagine e relativo contenuto
Пример #22
0
 def __init__(self):
     self.comment          = ""
     self.code             = ""   # Codice identificativo dell'help
     self.italian_keywords = ""   # Parole di ricerca italiane
     self.english_keywords = ""   # Parole di ricerca inglesi
     self.type             = Element(HELP.NONE)  # Tipologia dell'help
     self.text             = ""   # Testo visualizzato da tutti
     self.admin_text       = ""   # Testo visualizzato solo dagli Admin
     self.see_also         = ""   # Voci degli help simili a questo
     self.counter_use      = 0    # Contatore dell'utilizzo dell'help
     self.syntax_function  = None # Eventuale funzione che fa visualizzare la sintassi del comando
Пример #23
0
    def __init__(self, code=""):
        super(ProtoMob, self).__init__()

        self.code = code or ""
        self.height = 0
        self.constellation = Element(
            CONSTELLATION.NONE)  # Costellazione sotto cui è nato il mob
        self.virtue = Element(
            VIRTUE.NONE)  # Virtù che il mob segue principalmente
        self.hand = Element(
            HAND.NONE)  # Indica quale mano utilizza preferibilmente
        self.hometown = ""  # Area che il mob o il pg considera come propria casa
        self.group_name = ""  # Nome del gruppo in cui fa parte, fanno parte tutti i mob che lo hanno uguale
        self.voice_emote = ""  # Stringa che ne descrive la voce nel canale rpg_channel()
        self.voice_potence = 50  # Potenza della voce, 0 o meno significa aver perso la voce, per razze umanoidi i valori sono da 40 a 80, per razze 'minori' o 'maggiori' i valori possono variare e superare anche il 100
        self.parts = {
        }  # Forma, materiale, vita, flags delle parti sono già di default a seconda delle razza, però si possono cambiare anche a livello di file di area
        self.morph = None  # Tipo di morph sotto cui il personaggio è affetto
        self.skill_messages = {
        }  # Dizionario dei messaggi personalizzati riguardanti le skill

        # Attributi
        self.strength = 0
        self.endurance = 0
        self.agility = 0
        self.speed = 0
        self.intelligence = 0
        self.willpower = 0
        self.personality = 0
        self.luck = 0

        # Condizioni
        self.thirst = 0
        self.hunger = 0
        self.sleep = 0
        self.drunkness = 0
        self.adrenaline = 0
        self.mind = 0  # Tale quale a quello dello smaug
        self.emotion = 0  # Tale quale a quello dello smaug
        self.bloodthirst = 0

        self.eye_color = Element(COLOR.NONE)
        self.hair_color = Element(COLOR.NONE)
        self.hair_length = 0
        self.hair_type = Element(HAIRTYPE.NONE)
        self.skin_color = Element(COLOR.NONE)
Пример #24
0
    def __init__(self, columns=0, rows=0, code_prefix=""):
        self.columns         = columns     # Numero di colonne totali del labirinto
        self.rows            = rows        # Numero di righe totali del labirinto
        self.code_prefix     = code_prefix # Prefisso del codice delle room utilizzate per il reset
        self.remake_hour     = -1          # In quale ora il maze viene ricreato
        self.remake_weekday  = Element(WEEKDAY.NONE)
        self.remake_message  = ""          # Messaggio di act a tutte le entità nel labirinto durante il relativo remake
        self.passages        = []          # Elenco dei passaggi: entrate, uscite o altre nicchie, collegate al labirinto attorno al suo bordo
        self.dead_ends       = []          # Elenco dei vicoli ciechi casualmente da inserire al posto di quelli standard

        # Variabili volatili
        self.cells         = []
        self.track_counter = 0  # Numero di room tracciate dall'algoritmo di creazione del maze
Пример #25
0
 def __init__(self, layout, position):
     """Construct a TetrisPiece using the given Layout located at the given Position."""
     super(TetrisPiece, self).__init__(
         attrs_dict={
             'layout':
             layout,
             'position':
             position,
             'elements': [
                 Element(ElementType.PIECE, position.add(elem_position))
                 for elem_position in layout.positions
             ]
         })
Пример #26
0
    def __init__(self, name=""):
        self.comment = ""
        self.created_time = datetime.datetime.now(
        )  # Data di creazione del'account
        self.name = name  # Nome di login
        self.password = ""  # Password
        self.email = ""  # Indirizzo e-mail (opzionale)
        self.options = Flags(OPTION.NONE)
        self.show_logs = Flags(LOG.NONE)
        self.aliases = {}  # Dizionario relativo agli alias
        self.macros = {}  # Dizionario relativo alle macro
        # (TD) provare a convertire questi datetime in None e caricarli tramite schema
        self.last_bug_sended_at = None
        self.last_comment_sended_at = None
        self.last_typo_sended_at = None
        self.last_idea_sended_at = None
        self.sended_bugs = 0  # Bug totali inviati
        self.sended_comments = 0  # Typo totali inviati
        self.sended_ideas = 0  # Idee totali inviati
        self.sended_typos = 0  # Typo totali inviati
        self.user_agents = [
        ]  # Informazioni relative ai client browser utilizzati dal giocatore per entrare nel Mud
        self.resolution_width = 0  # Risoluzione in pixel del monitor del client in larghezza
        self.resolution_height = 0  # Risoluzione in pixel del monitor del client in altezza

        # Al primo account creato in assoluto dà poteri di Implementor, dando
        # per scontato che il primo giocatore che utilizza questo Mud sia il
        # futuro amministratore, ai successivi account dona la trust di player
        if not database["accounts"]:
            self.trust = Element(TRUST.IMPLEMENTOR)
        else:
            self.trust = Element(TRUST.PLAYER)

        # Attributi volatili
        self.players = {}  # Dizionario dei giocatori creati dall'account
        self.player = None  # Personaggio che si sta creando o utilizzando
Пример #27
0
    def load(self):
        filepath = "persistence/calendar.rpg"
        try:
            file = open(filepath, "r")
        except IOError:
            log.bug("Impossibile aprire il file %s in lettura" % filepath)
            return

        for line in file:
            if not line.strip():
                continue
            if line[0] == "#":
                continue
            break
        else:
            log.bug("Non è stato trovato nessuna riga valida al file %s" % filepath)
            file.close()
            return
        file.close()

        values = line.split()
        if len(values) != 5:
            log.bug("E' stato trovato un numero inatteso di valori al file %s: %d" % (filepath, len(values)))
            return

        if is_number(values[0]):
            self.minute = int(values[0])
        else:
            log.bug("minute del file %s non sono un numero valido: %s" % values[0])

        if is_number(values[1]):
            self.hour = int(values[1])
        else:
            log.bug("hour del file %s non sono un numero valido: %s" % values[1])

        if is_number(values[2]):
            self.day = int(values[2])
        else:
            log.bug("day del file %s non sono un numero valido: %s" % values[2])

        self.month = Element(values[3])

        if is_number(values[4]):
            self.year = int(values[4])
        else:
            log.bug("year del file %s non sono un numero valido: %s" % values[4])

        self.get_error_message()
Пример #28
0
 def __init__(self, season=SEASON.NONE):
     self.season = Element(season)
     self.temperature = 17  # In gradi centigradi
     self.wind_direction = Element(DIR.NONE)  # Direzione del vento
     self.cloud_color = Element(COLOR.NONE)  # Colore delle nuvole
     self.cloud = 25  # Densità delle nuvole del cielo: 0 è limpido, 100 è completamente coperto
     self.humidity = 20  # Umidità nell'aria: 0 deserto secco, 100 foresta pluviale
     self.fog = 10  # Probabilità che vi sia la nebbia, da 0 a 100
     self.rain = 15  # Probabilità che piova, da 0 a 100 (se la temperatura è bassa si tramuta in neve)
     self.hail = 2  # Probabilità che grandini, da 0 a 100
     self.snow = 3  # Probabilità che nevichi
     self.lightning = 5  # Probabilità che tuoni e fulmini, da 0 a 100
Пример #29
0
 def __init__(self):
     self.comment       = ""  # Commento per gli area builder relativo all'entità leggibile
     self.title         = ""  # Titolo del libro
     self.author        = ""  # Autore o gli autori di questo libro
     self.summary       = ""  # Riassunto del libro che il giocatore carpisce esaminandolo
     self.language      = Element(LANGUAGE.COMMON) # (TD) Lingua di questo libro
     self.flags         = Flags(READABLE.NONE)  # Flag relative alle entità leggibili
     self.visual_width  = ""  # Larghezza in pixel del libro sullo schermo
     self.visual_height = ""  # Larghezza in pixel del libro sullo schermo
     self.padding       = ""  # Larghezza in pixel del padding della cornice del libro
     self.border_top    = ""  # Bordo css decorante il libro in alto
     self.border_right  = ""  # Bordo css decorante il libro a destra
     self.border_bottom = ""  # Bordo css decorante il libro in basso
     self.border_left   = ""  # Bordo css decorante il libro a sinistra
     self.border_inside = ""  # Bordo css decorante il libro tra le due pagine
     self.number_decoration_left  = ""  # Decorazione della pagina sinistra per i numeri di pagina
     self.number_decoration_right = ""  # Decorazione della pagina sinistra per i numeri di pagina
     self.pages         = []  # Lista delle pagine e relativo contenuto
Пример #30
0
    def __init__(self, fun_name=""):
        self.comment = ""
        self.fun_name = fun_name or ""  # Nome della funzione
        self.type = Element(CMDTYPE.INFORMATION)  # Tipologia del comando
        self.trust = Element(TRUST.PLAYER)  # Fiducia minima per digitarlo
        self.position = Element(
            POSITION.REST)  # Posizione minima per utilizzarlo
        self.flags = Flags(CMDFLAG.NONE)  # Flag dei comandi
        self.no_races = Flags(
            RACE.NONE
        )  # Razze che NON possono usarlo (RACE.NONE significa che tutti lo possono utilizzare)
        self.mini_help = ""  # Piccola descrizione dell'utilizzo del comando
        self.timer = 0.0  # Tempo totale di esecuzione del comando (anche se nelle pagine d'amministrazione visualizza il tempo medio)

        # Variabili volatili
        self.module = None  # Riferimento al modulo che contiene la funzione
        self.function = None  # Riferimento alla funzione
        if self.fun_name:
            self.import_module_and_function()
Пример #31
0
class Maze(object):
    """
    Classe relativa ad un labirinto.
    """
    PRIMARY_KEY = ""
    VOLATILES   = ["cells", "track_counter"]
    MULTILINES  = []
    SCHEMA      = {"passages"  : ("src.games.maze", "MazePassage"),
                   "dead_ends" : ("src.games.maze", "MazeDeadEnd")}
    REFERENCES  = {}
    WEAKREFS    = {}

    def __init__(self, columns=0, rows=0, code_prefix=""):
        self.columns         = columns     # Numero di colonne totali del labirinto
        self.rows            = rows        # Numero di righe totali del labirinto
        self.code_prefix     = code_prefix # Prefisso del codice delle room utilizzate per il reset
        self.remake_hour     = -1          # In quale ora il maze viene ricreato
        self.remake_weekday  = Element(WEEKDAY.NONE)
        self.remake_message  = ""          # Messaggio di act a tutte le entità nel labirinto durante il relativo remake
        self.passages        = []          # Elenco dei passaggi: entrate, uscite o altre nicchie, collegate al labirinto attorno al suo bordo
        self.dead_ends       = []          # Elenco dei vicoli ciechi casualmente da inserire al posto di quelli standard

        # Variabili volatili
        self.cells         = []
        self.track_counter = 0  # Numero di room tracciate dall'algoritmo di creazione del maze
    #- Fine Inizializzazione -

    def get_error_message(self):
        if self.columns <= 1:
            return "colums non è valido: %d" % self.columns
        elif self.rows <= 1:
            return "rows non è valido: %d" % self.rows
        elif self.remake_hour < -1 and self.remake_hour > config.hours_in_day - 1:
            return "remake_hour non è un'ora rpg valida: %d (inserire da -1 a %d)" % (self.remake_hour, config.hours_in_day - 1)
        elif self.remake_weekday.get_error_message(WEEKDAY, "remake_weekday") != "":
            return self.remake_weekday.get_error_message(WEEKDAY, "remake_weekday")
        elif self.get_error_message_passages() != "":
            return self.get_error_message_passages()
        elif self.get_error_message_dead_ends() != "":
            return self.get_error_message_dead_ends()
        else:
            return ""
    #- Fine Metodo -

    def get_error_message_passages(self):
        for passage in self.passages:
            message = passage.get_error_message(self)
            if message:
                return message

        return ""
    #- Fine Metodo -

    def get_error_message_dead_ends(self):
        for dead_end in self.dead_ends:
            message = dead_end.get_error_message(self)
            if message:
                return message

        return ""
    #- Fine Metodo -

    def create(self, area):
        if not area:
            log.bug("area non è un parametro valido: %r" % area)
            return

        # ---------------------------------------------------------------------

        # Mette il token(none), wall(4 * True) e visited(false) a tutte le room
        self.cells = [[MazeCell() for r in xrange(self.rows)] for c in xrange(self.columns)]
        self.track_counter = 0

        # A stack containing coordinates of the current cell and a scrambled
        # list of the direction to its neighbors
        shuffled = list(DIRS)
        random.shuffle(shuffled)

        # inizialmente contiene solo dati per una room: coordinate e la sequenza delle vicine scramblate
        stack = [StackElement(math.floor(random.random() * self.columns),
                              math.floor(random.random() * self.rows),
                              shuffled)]

        # Il loop deve iterare fino a che ha visitato tutte le celle, ma poiché
        # il depth first può anche tornare sui propri passi non basta farlo
        # iterare (self.rows * self.columns) volte
        while self.track_counter < (self.rows * self.columns):
            self.depth_first_search(stack)

        # Toglie i muri relativi ai vari passaggi fuori dai limiti della griglia
        # aprendo dei passi in questa maniera vengono correttamente caricate
        # le stanze a seconda delle uscite attorno
        for passage in self.passages:
            if passage.z != 0:
                continue
            coords = "%d %d %d" % (passage.x, passage.y, passage.z)
            if coords not in area.rooms:
                log.bug("Non esistono le coordinate %s nell'area %s (nel ciclo dei passages attorno)" % (coords, area.code))
                continue
            passage_room = area.rooms[coords]
            if passage.y == -1:
                self.cells[passage.x][0].wall[SOUTH] = False;
                if DIR.NORTH not in passage_room.exits:
                    passage_room.exits[DIR.NORTH] = Exit(DIR.NORTH)
            if passage.y == self.rows:
                self.cells[passage.x][self.rows - 1].wall[NORTH] = False;
                if DIR.SOUTH not in passage_room.exits:
                    passage_room.exits[DIR.SOUTH] = Exit(DIR.SOUTH)
            if passage.x == -1:
                self.cells[0][passage.y].wall[WEST] = False;
                if DIR.EAST not in passage_room.exits:
                    passage_room.exits[DIR.EAST] = Exit(DIR.EAST)
            if passage.x == self.columns:
                self.cells[self.columns - 1][passage.y].wall[EAST] = False;
                if DIR.WEST not in passage_room.exits:
                    passage_room.exits[DIR.WEST] = Exit(DIR.WEST)

        # Crea ed avvia i reset per l'area del labirinto
        self.create_resets(area)

        # Crea le aperture in alto e in basso per eventuali altri passaggi
        # Non esistendo delle descrizioni di stanze con uscite verso il basso
        # e verso l'alto è dato al giocatore fare attenzione a queste uscite
        # verso l'inizio o la fine del labirinto o altre nicchie.
        # Stesso discorso per l'aggiunta delle uscite diagonali per i 4 angoli
        # esterni.
        # Se la room relativa al passaggio non possiede l'uscita per arrivare
        # alla stanza del labirinto viene creata automaticamente.
        for passage in self.passages:
            if passage.z == 0:
                maze_coords = ""
                if passage.x == -1 and passage.y == -1:
                    maze_coords = "0 0 0"
                    maze_dir    = DIR.SOUTHWEST
                elif passage.x == -1 and passage.y == self.rows:
                    maze_coords = "0 %d 0" % self.rows - 1
                    maze_dir    = DIR.NORTHEAST
                elif passage.x == self.columns and passage.y == -1:
                    maze_coords = "%d 0 0" % self.columns - 1
                    maze_dir    = DIR.SOUTHEAST
                elif passage.x == self.columns and passage.y == self.rows:
                    maze_coords = "%d %d 0" % (self.columns - 1, self.rows - 1)
                    maze_dir    = DIR.NORTHEAST
                if maze_coords:
                    maze_room = area.rooms[maze_coords]
                    maze_room.exits[maze_dir] = Exit(maze_dir)
                    passage_coords = "%d %d %d" % (passage.x, passage.y, passage.z)
                    if passage_coords not in area.rooms:
                        log.bug("Non esistono le coordinate %s nell'area %s (nel ciclo dei passages negli angoli)" % (passage_coords, area.code))
                        continue
                    passage_room = area.rooms[passage_coords]
                    if maze_dir.reverse_dir not in passage_room.exits:
                        passage_room.exits[maze_dir.reverse_dir] = Exit(maze_dir.reverse_dir)
            else:
                passage_coords = "%d %d %d" % (passage.x, passage.y, passage.z)
                if passage_coords not in area.rooms:
                    log.bug("Non esistono le coordinate %s nell'area %s (nel ciclo dei passages nell'up & down)" % (passage_coords, area.code))
                    continue
                passage_room = area.rooms[passage_coords]
                maze_room = area.rooms["%d %d 0" % (passage.x, passage.y)]
                if passage.z == 1:
                    maze_room.exits[DIR.UP] = Exit(DIR.UP)
                    if DIR.DOWN not in passage_room.exits:
                        passage_room.exits[DIR.DOWN] = Exit(DIR.DOWN)
                else:
                    maze_room.exits[DIR.DOWN] = Exit(DIR.DOWN)
                    if DIR.UP not in passage_room.exits:
                        passage_room.exits[DIR.UP] = Exit(DIR.UP)

        # (TD) Ora provvede ad inserire casualmente i DeadEnds evitando
        # che questi tangino eventuali Passagges
        pass

        # Rimuove le informazioni delle MazeCell per pulizia
        self.cells = []
    #- Fine Metodo -

    def depth_first_search(self, stack):
        tail_element = stack[-1]
        x = tail_element.x
        y = tail_element.y
        neighbors = tail_element.neighbors

        # When all cells have been visited at least once, it's done
        if not self.cells[x][y].visited:
            self.cells[x][y].visited = True
            self.track_counter = self.track_counter +1

        # Stampa le coordinate della via seguita per la generazione del maze per
        # verificare che non restino celle non tracciate
        # When all cells have been visited at least once, it's done
        #print "(", x, ",", y, ")", "- room tracciate", self.track_counter

        # Look for a neighbor that is in the maze and hasn't been visited yet
        while len(neighbors) > 0:
            direction = neighbors.pop()
            if len(neighbors) == 0:
                stack.pop()  # All neighbors checked, done with this one

            dx = x + DELTA["x"][direction]
            dy = y + DELTA["y"][direction]
            if dx >= 0 and dy >= 0 and dx < self.columns and dy < self.rows:
                if self.cells[dx][dy].visited == False:
                    # Break down the wall between them. The new neighbor is
                    # added onto the stack and becomes the new current cell
                    self.cells[x][y].wall[direction] = False
                    self.cells[dx][dy].wall[UNDIRS[direction]] = False
                    shuffled = list(DIRS)
                    random.shuffle(shuffled)
                    new_element = StackElement(dx, dy, shuffled)
                    stack.append(new_element);
                    break;
    #- Fine Metodo -

    def create_resets(self, area):
        """
        Esegue il reset del labirinto con le stanze appositamente create per
        l'area.
        """
        for x in xrange(self.columns):
            for y in xrange(self.rows):
                wall = self.cells[x][y].wall
                           # [NORTH, SOUTH, WEST,  EAST  ]
                #print "x:%d y:%d NORTH:%s SOUTH:%s WEST:%s EAST:%s" % (x, y, wall[NORTH], wall[SOUTH], wall[WEST], wall[EAST])
                if   wall == [True,  False, True,  True ]:  code = "_sud"        # switch 1
                elif wall == [False, True,  True,  True ]:  code = "_nord"       # switch 1
                elif wall == [True,  True,  False, True ]:  code = "_ovest"
                elif wall == [True,  True,  True,  False]:  code = "_est"
                elif wall == [False, False, True,  True ]:  code = "_nord-sud"
                elif wall == [True,  True,  False, False]:  code = "_est-ovest"
                elif wall == [False, False, False, False]:  code = "_incrocio"
                elif wall == [True,  False, True,  False]:  code = "_sud-est"    # switch 2
                elif wall == [True,  False, False, True ]:  code = "_sud-ovest"  # switch 3
                elif wall == [False, True,  True,  False]:  code = "_nord-est"   # switch 2
                elif wall == [False, True,  False, True ]:  code = "_nord-ovest" # switch 3
                elif wall == [False, False, False, True ]:  code = "_3no-est"
                elif wall == [False, True,  False, False]:  code = "_3no-sud"    # switch 4
                elif wall == [False, False, True,  False]:  code = "_3no-ovest"
                elif wall == [True,  False, False, False]:  code = "_3no-nord"   # switch 4
                elif wall == [True,  True,  True,  True ]:  code = "_no" #; print wall
                else:
                    log.bug("Qui non dovrebbe mai passare: %s", wall)
                    continue
                room_reset = RoomReset()
                room_reset.proto_room = database["proto_rooms"][self.code_prefix + code]
                room_reset.destination = Destination(x, y, 0, area)
                area.room_resets.append(room_reset)

        # Una volta creati i reset li avvia
        area.defer_reset_events()
    #- Fine Metodo -

    def destroy(self, area):
        if not area:
            log.bug("area non è un parametro valido: %r" % area)
            return

        # ---------------------------------------------------------------------

        room_codes = []
        for passage in self.passages:
            room_codes.append(passage.proto_room.code)

        area.stop_reset_events(except_these=room_codes)
        area.room_resets = []
        area.extract_rooms(except_these=room_codes)
    #- Fine Metodo -

    def remake(self, area):
        # Ricava le entità da salvarsi e trasportare nel nuovo labirinto
        players = []
        for player in area.players:
            self.send_remake_message(player)
            player = player.from_location(1, use_repop=False)
            players.append(player)
        entities = []
        for entity in area.iter_contains(use_reversed=True):
            if not entity.location:
                log.bug("location dell'entità %s non è valido: %r" % (entity.code, entity.location))
                continue
            if not entity.IS_PLAYER and entity.location.IS_ROOM:
                self.send_remake_message(entity)
                entity = entity.from_location(entity.quantity, use_repop=False)
                entities.append(entity)

        # Distrugge il vecchio labirinto e ne crea uno nuovo
        self.destroy(area)
        self.create(area)

        # Sposta le entità salvate precedentemente nel nuovo labirinto
        for entity in players + entities:
            if entity.previous_location() and entity.previous_location().IS_ROOM:
                coords = "%d %d %d" % (entity.previous_location().x, entity.previous_location().y, entity.previous_location().z)
                if coords in area.rooms:
                    room = area.rooms[coords]
                else:
                    room = random.choice(area.rooms.values())
            else:
                room = random.choice(area.rooms.values())
            entity.to_location(room)
    #- Fine Metodo -

    def send_remake_message(self, entity):
        if self.remake_message == "no_send":
            return

        if self.remake_message:
            message = "\n" + self.remake_message
        else:
            message = "\nD'improvviso le aperture e i corridoi attorno a te si muovono come mischiandosi e ti ritrovi smarrit$o."

        entity.send_output(message)
        entity.send_prompt()
Пример #32
0
 def __init__(self):
     self.material = Element(MATERIAL.NONE)
     self.percent = 0
Пример #33
0
class MaterialPercentage(object):
    PRIMARY_KEY = ""
    VOLATILES = []
    MULTILINES = []
    SCHEMA = {}
    REFERENCES = {}
    WEAKREFS = {}

    def __init__(self):
        self.material = Element(MATERIAL.NONE)
        self.percent = 0

    #- Fine Inizializzazione -

    def __repr__(self):
        return "%s %s %s%%" % (super(
            MaterialPercentage, self).__repr__(), self.material, self.percent)

    #- Fine Metodo -

    def copy(self, to_obj=None, avoid_volatiles=False):
        if not to_obj:
            to_obj = MaterialPercentage()
        copy_existing_attributes(self, to_obj, avoid_volatiles=avoid_volatiles)
        return to_obj

    #- Fine Funzione -

    def equals(self, material2):
        if not material2:
            return False

        if self.material != material2.material:
            return False

        if self.percent != material2.percent:
            return False

        return True

    #- Fine Metodo -

    def get_error_message(self):
        if self.material.get_error_message(
                MATERIAL, "material", allow_none=False) != "":
            return self.material.get_error_message(MATERIAL,
                                                   "material",
                                                   allow_none=False)
        elif self.percent < 1 or self.percent > 100:
            return "percent dev'essere tra 1 e 100 e non %d" % self.percent

        return ""

    #- Fine Metodo -

    def fread_the_line(self, file, line, attr):
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not line:
            log.bug("line non è un parametro valido: %r" % line)
            return

        if not attr:
            log.bug("attr non è un parametro valido: %r" % attr)
            return

        # ---------------------------------------------------------------------

        if "," in line:
            material, percent = line.split(",", 1)
        else:
            material, percent = line.split(None, 1)

        material = material.strip()
        percent = percent.strip()

        self.material = Element(material)
        self.percent = fread_percent(file, percent, attr)

    #- Fine Metodo -

    def fwrite_the_line(self, file, label, indentation=""):
        """
        Scrive su file un elemento sinonimo.
        """
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not label:
            log.bug("label non è un parametro valido: %r" % label)
            return

        # -------------------------------------------------------------------------

        file.write("%s%s%s %s%%\n" %
                   (indentation, label, self.material.code, self.percent))
Пример #34
0
 def __init__(self):
     self.minute = 0  # Minuto rpg
     self.hour   = 0  # Ora rpg
     self.day    = 1  # Giorno rpg
     self.month  = Element(MONTH.NONE)  # Mese rpg
     self.year   = 0  # Anno rpg
Пример #35
0
class Calendar(object):
    def __init__(self):
        self.minute = 0  # Minuto rpg
        self.hour   = 0  # Ora rpg
        self.day    = 1  # Giorno rpg
        self.month  = Element(MONTH.NONE)  # Mese rpg
        self.year   = 0  # Anno rpg
    #- Fine Inizializzazione -

    def get_error_message(self):
        # L'anno non ha bisogno di check perché può avere qualsiasi valore
        if self.minute < 0 or self.minute > config.minutes_in_hour - 1:
            msg = "minute non è un valore valido: %d (dev'essere tra -1 e %d)" % (self.minute, config.minutes_in_hour - 1)
        elif self.hour < 0 or self.hour > config.hours_in_day - 1:
            msg = "hour non è un valore valido: %d (dev'essere tra 0 e %d)" % (self.hour, config.hours_in_day)
        elif self.day <= 0 or self.day > config.days_in_month:
            msg = "day non è un valore valido: %s (dev'essere tra -1 e %s)" % (self.day, config.days_in_month)
        elif self.month.get_error_message(MONTH, "month") != "":
            msg = self.month.get_error_message(MONTH, "month")
        else:
            return ""

        # Se arriva fino a qui ha un messaggio di errore da inviare
        log.bug("(Calendar) %s" % msg)
        return msg
    #- Fine Metodo -

    def __str__(self):
        return "%d-%02d-%02d %02d:%02d" % (
            self.year, self.month.index, self.day, self.hour, self.minute)
    #- Fine Metodo -

    def load(self):
        filepath = "persistence/calendar.rpg"
        try:
            file = open(filepath, "r")
        except IOError:
            log.bug("Impossibile aprire il file %s in lettura" % filepath)
            return

        for line in file:
            if not line.strip():
                continue
            if line[0] == "#":
                continue
            break
        else:
            log.bug("Non è stato trovato nessuna riga valida al file %s" % filepath)
            file.close()
            return
        file.close()

        values = line.split()
        if len(values) != 5:
            log.bug("E' stato trovato un numero inatteso di valori al file %s: %d" % (filepath, len(values)))
            return

        if is_number(values[0]):
            self.minute = int(values[0])
        else:
            log.bug("minute del file %s non sono un numero valido: %s" % values[0])

        if is_number(values[1]):
            self.hour = int(values[1])
        else:
            log.bug("hour del file %s non sono un numero valido: %s" % values[1])

        if is_number(values[2]):
            self.day = int(values[2])
        else:
            log.bug("day del file %s non sono un numero valido: %s" % values[2])

        self.month = Element(values[3])

        if is_number(values[4]):
            self.year = int(values[4])
        else:
            log.bug("year del file %s non sono un numero valido: %s" % values[4])

        self.get_error_message()
    #- Fine Metodo -

    def save(self):
        filepath = "persistence/calendar.rpg"
        try:
            file = open(filepath, "w")
        except IOError:
            log.bug("Impossibile aprire il file %s in scrittura" % filepath)
            return

        file.write("# minute hour day month year\n")
        file.write("%d %d %d %s %d\n" % (self.minute, self.hour, self.day, self.month.code, self.year))
        file.close()
    #- Fine Metodo -

    # -------------------------------------------------------------------------

    def is_day(self):
        if self.hour >= config.sunrise_hour and self.hour <= config.sunset_hour:
            return True
        return False
    #- Fine Metodo -

    def is_night(self):
        if self.hour < config.sunrise_hour or self.hour > config.sunset_hour:
            return True
        return False
    #- Fine Metodo -

    def get_weekday(self):
        """
        Ritorna il giorno corrente della settimana.
        """
        # (bb) (TD) Per ora ogni anno il calendario si resetta al primo giorno
        # della settimana anche se l'ultimo giorno dell'anno rpg precedente
        # non era l'ultimo giorno della settimana
        day_number  = (self.month.index + 1) * config.days_in_month
        day_number += self.day
        day_number %= len(WEEKDAY.elements) - 1

        return WEEKDAY.elements[day_number]
    #- Fine Metodo -

    def get_season(self):
        """
        Ritorna la stagione corrente.
        Le stagioni di "passaggio" durano 3 mesi, le altre 2 mesi.
        """
        if self.month == MONTH.TEN or self.month == MONTH.ONE:
            return SEASON.WINTER
        elif self.month == MONTH.TWO or self.month == MONTH.THREE or self.month == MONTH.FOUR:
            return SEASON.SPRING
        elif self.month == MONTH.FIVE or self.month == MONTH.SIX:
            return SEASON.SUMMER
        elif self.month == MONTH.SEVEN or self.month == MONTH.EIGHT or self.month == MONTH.NINE:
            return SEASON.AUTUMN

        log.bug("self.month non è valido: %r" % self.month)
        return SEASON.NONE
    #- Fine Metodo -

    def get_first_month_of_season(self, season=None):
        if not season:
            season = self.get_season()

        if   season == SEASON.WINTER:  return MONTH.TEN
        elif season == SEASON.SPRING:  return MONTH.TWO
        elif season == SEASON.SUMMER:  return MONTH.FIVE
        elif season == SEASON.AUTUMN:  return MONTH.SEVEN

        log.bug("Stagione mancante o errata: %r" % season)
        return MONTH.NONE
    #- Fine Metodo -

    def get_real_seconds_to(self, minute=-1, hour=-1, day=-1, month=MONTH.NONE, year=-1, force_advance=False):
        if minute < -1 or minute > config.minutes_in_hour:
            log.bug("minute non è un parametro valido: %d" % minute)
            return -1

        if hour < -1 or hour > config.hours_in_day:
            log.bug("hour non è un parametro valido: %d" % hour)
            return -1

        if day < -1 or day > config.days_in_month:
            log.bug("day non è un parametro valido: %d" % day)
            return -1

        if not month:
            log.bug("month non è un parametro valido: %r" % month)
            return -1

        if year < -1:
            log.bug("year non è un parametro valido: %d" % year)
            return -1

        # force_advance ha valore di verità

        # ---------------------------------------------------------------------

        if minute == -1:
            #minute_is_defined = False
            minute = self.minute
        else:
            #minute_is_defined = True
            pass

        if hour == -1:
            hour_is_defined = False
            hour = self.hour
        else:
            hour_is_defined = True

        if day == -1:
            day_is_defined = False
            day = self.day
        else:
            day_is_defined = True

        if month == MONTH.NONE:
            month_is_defined = False
            month = self.month
        else:
            month_is_defined = True

        if year == -1:
            #year_is_defined = False
            year = self.year
        else:
            #year_is_defined = True
            pass

        # ---------------------------------------------------------------------

        advance_a_day = False
        if not hour_is_defined and minute > self.minute:
            hour += 1
            # Le ore vanno da 0 al suo massimo escluso
            if hour >= config.hours_in_day:
                hour = 0
                advance_a_day = True

        advance_a_month = False
        if advance_a_day:
            day += 1
            # I giorni vanno da 1 al suo massimo incluso
            if day > config.days_in_month:
                day = 1
                advance_a_month = True

        if advance_a_month:
            month += 1
            # Se in una enumerazione sfora il massimo dei mesi rinizi dal
            # primo automaticamente (vedi cycle_on_last nel file element.py)
            if month == MONTH.ONE:
                year += 1

        # year non ha limite superiore per cui non c'è bisogno di controllarlo

        # ---------------------------------------------------------------------

        #print minute, hour, day, month.index, year, "-->",
        # (TD) Brrrr... lo so che fa schifo, ma per ora si tiene così fino a
        # che non si trova un po' di tempo per trovare una struttura smart
        if force_advance:
            if month < self.month:
                #print "A1",
                year += 1
            elif day < self.day and month <= self.month:
                if month_is_defined and month == self.month:
                    #print "B1",
                    year += 1
                else:
                    #print "B2",
                    month += 1
                    if month == MONTH.ONE:
                        #print "B3",
                        year += 1
            elif hour < self.hour and day <= self.day and month <= self.month:
                if day_is_defined and day == self.day:
                    if month_is_defined and month == self.month:
                        #print "C1",
                        year += 1
                    else:
                        #print "C2",
                        month += 1
                        if month == MONTH.ONE:
                            #print "C3",
                            year += 1
                else:
                    #print "C4",
                    day += 1
                    if day > config.days_in_month:
                        #print "C5",
                        day = 1
                        if month_is_defined and month == self.month:
                            #print "C6",
                            year += 1
                        else:
                            #print "C7",
                            month += 1
                            if month == MONTH.ONE:
                                #print "C8",
                                year += 1
            elif minute < self.minute and hour <= self.hour and day <= self.day and month <= self.month:
                if hour_is_defined and hour == self.hour:
                    if day_is_defined and day == self.day:
                        if month_is_defined and month == self.month:
                            #print "D1",
                            year += 1
                        else:
                            #print "D2",
                            month += 1
                            if month == MONTH.ONE:
                                #print "D3",
                                year += 1
                    else:
                        #print "D4",
                        day += 1
                        if day > config.days_in_month:
                            #print "D5",
                            day = 1
                            if month_is_defined and month == self.month:
                                #print "D6",
                                year += 1
                            else:
                                #print "D7",
                                month += 1
                                if month == MONTH.ONE:
                                    #print "D8",
                                    year += 1
                else:
                    #print "D9",
                    hour += 1
                    if hour >= config.hours_in_day:
                        #print "D10",
                        hour = 0
                        if day_is_defined and day == self.day:
                            if month_is_defined and month == self.month:
                                #print "D11",
                                year += 1
                            else:
                                #print "D12",
                                month += 1
                                if month == MONTH.ONE:
                                    #print "D13",
                                    year += 1
                        else:
                            #print "D14",
                            day += 1
                            if day > config.days_in_month:
                                #print "D15",
                                day = 1
                                if month_is_defined and month == self.month:
                                    #print "D16",
                                    year += 1
                                else:
                                    #print "D17",
                                    month += 1
                                    if month == MONTH.ONE:
                                        #print "D18",
                                        year += 1

        # ---------------------------------------------------------------------

        minutes  = (minute - self.minute)
        minutes += (hour - self.hour) * config.minutes_in_hour
        minutes += (day - self.day) * (config.minutes_in_hour * config.hours_in_day)
        minutes += (month.index - self.month.index) * (config.minutes_in_hour * config.hours_in_day * config.days_in_month)
        minutes += (year - self.year) * (config.minutes_in_hour * config.hours_in_day * config.days_in_month * config.months_in_year)

        #print "PROSSIMO RESET:%ss attuale:%d %d %d %d %d reset:%d %d %d %d %d %s %s %s" % (
        #    minutes * config.seconds_in_minute,
        #    self.minute, self.hour, self.day, self.month.index, self.year,
        #    minute, hour, day, month.index, year,
        #    hour_is_defined, day_is_defined, month_is_defined)
        return minutes * config.seconds_in_minute
    #- Fine Metodo -

    def update(self):
        first_day_of_month = False
        first_day_of_year  = False
        moment_type        = ""

        if self.minute < config.minutes_in_hour - 1:
            self.minute += 1
        else:
            self.minute = 0
            # Controlla il cambio dell'ora
            if self.hour < config.hours_in_day - 1:
                self.hour += 1
            else:
                self.hour = 0
                # Controlla il cambio del giorno
                if self.day < config.days_in_month:
                    self.day += 1
                else:
                    first_day_of_month = True
                    self.day = 1
                    # Controlla il cambio del mese
                    if self.month.index < len(MONTH.elements):
                        self.month += 1
                    else:
                        first_day_of_year = True
                        self.month = MONTH.ONE
                        self.year += 1
            if self.hour == config.dawn_hour:
                moment_type = "dawn"
            elif self.hour == config.sunrise_hour:
                moment_type = "sunrise"
            elif self.hour == config.noon_hour:
                moment_type = "noon"
            elif self.hour == config.sunset_hour:
                moment_type = "sunset"
            elif self.hour == config.dusk_hour:
                moment_type = "dusk"
            elif self.hour == config.midnight_hour:
                moment_type = "midnight"

        from src.database import database
        if moment_type:
            for area in database["areas"].itervalues():
                echoes = globals()["ECHOES_%s" % moment_type.upper()]

                # (TD) a seconda che nell'area vi sia bello o brutto tempo fa
                # vedere o meno il sole o la luna con messaggi appositi
                # E anche il sistema della luna piena
                area_echoes = getattr(area, "echoes_%s" % moment_type)
                if area_echoes:
                    echoes = area_echoes

                # Poiché esistono anche gli echoes personalizzabili per stanza
                # allora esegue una ricerca stanza per stanza
                for room in reversed(area.rooms.values()):
                    room_echoes = getattr(room, "echoes_%s" % moment_type)
                    if room_echoes:
                        echoes = room_echoes

                    # Se la stanza è interna allora non fa visualizzare i
                    # messaggi di echo di default, a meno che appunto non
                    # siano stati inseriti ad uopo per la stanza
                    if ROOM.INSIDE in room.flags and not room_echoes:
                        pass
                    elif echoes:
                        # Non esegue il random pg per pg per poter avere un
                        # messaggio unico almeno stanza per stanza
                        room.echo(random.choice(echoes))

                    # I check sui trigger
                    force_return = check_trigger(room, "on_" + moment_type, room)
                    if force_return:
                        continue
                    for content in room.iter_all_entities(use_reversed=True):
                        force_return = check_trigger(content, "on_" + moment_type, content)
                        if force_return:
                            break

        # A tutti fa visualizzare se il giorno è il primo dell'anno o del mese
        # (TD) in futuro anche il nome della settimana
        for player in database["players"].itervalues():
            if not player.game_request:
                continue
            if first_day_of_year:
                player.send_output("\nOggi è il [white]primo giorno[close] dell'anno %d!" % self.year)
                player.send_prompt()
            elif first_day_of_month:
                player.send_output("\nOggi è il [white]primo giorno[close] del mese %s." % self.month.description)
                player.send_prompt()
Пример #36
0
 def __init__(self):
     self.comment  = ""
     self.category = Element(WEAPON.NONE)   # Tipo di arma
     self.flags    = Flags(WEAPONFLAG.NONE) # Flag di arma
     self.damage   = ""  # Danno dell'arma, se vuoto viene ricavato automaticamente tramite una tabella
Пример #37
0
class Climate(object):
    """
    Gestisce le informazioni climatiche di un'area.
    """
    PRIMARY_KEY = ""
    VOLATILES = []
    MULTILINES = []
    SCHEMA = {
        "temperature": ("", "temperature"),
        "cloud": ("", "percent"),
        "humidity": ("", "percent"),
        "fog": ("", "percent"),
        "rain": ("", "percent"),
        "hail": ("", "percent"),
        "snow": ("", "percent"),
        "lightning": ("", "percent")
    }
    REFERENCES = {}
    WEAKREFS = {}

    def __init__(self, season=SEASON.NONE):
        self.season = Element(season)
        self.temperature = 17  # In gradi centigradi
        self.wind_direction = Element(DIR.NONE)  # Direzione del vento
        self.cloud_color = Element(COLOR.NONE)  # Colore delle nuvole
        self.cloud = 25  # Densità delle nuvole del cielo: 0 è limpido, 100 è completamente coperto
        self.humidity = 20  # Umidità nell'aria: 0 deserto secco, 100 foresta pluviale
        self.fog = 10  # Probabilità che vi sia la nebbia, da 0 a 100
        self.rain = 15  # Probabilità che piova, da 0 a 100 (se la temperatura è bassa si tramuta in neve)
        self.hail = 2  # Probabilità che grandini, da 0 a 100
        self.snow = 3  # Probabilità che nevichi
        self.lightning = 5  # Probabilità che tuoni e fulmini, da 0 a 100

    #- Fine Inizializzazione -

    def __repr__(self):
        return "%s: %s" % (super(Climate, self).__repr__, self.climate)

    #- Fine Metodo -

    def get_error_message(self):
        """
        Controlla l'integrità degli attributi della istanza.
        """
        if self.season.get_error_message(SEASON, "season") != "":
            msg = self.season.get_error_message(SEASON, "season")
        elif self.temperature < -273 or self.temperature > 10000:
            msg = "temperatura del clima errata: %d" % self.temperature
        elif self.wind_direction.get_error_message(DIR,
                                                   "wind_direction") != "":
            msg = self.wind_direction.get_error_message(DIR, "wind_direction")
        elif self.cloud_color.get_error_message(COLOR, "cloud_color") != "":
            msg = self.cloud_color.get_error_message(COLOR, "cloud_color")
        elif self.cloud < 0 or self.cloud > 100:
            msg = "probabilità di nuvolosità errata: %d" % self.cloud
        elif self.humidity < 0 or self.humidity > 100:
            msg = "probabilità di umidità errata: %d" % self.humidity
        elif self.fog < 0 or self.fog > 100:
            msg = "probabilità di nebbia errata: %d" % self.fog
        elif self.rain < 0 or self.rain > 100:
            msg = "probabilità di pioggia errata: %d" % self.rain
        elif self.hail < 0 or self.hail > 100:
            msg = "probabilità di grandine errata: %d" % self.hail
        elif self.snow < 0 or self.snow > 100:
            msg = "probabilità di nevicate errata: %d" % self.snow
        elif self.lightning < 0 or self.lightning > 100:
            msg = "probabilità dei tempeste con fulmini errata: %d" % self.lightning
        else:
            return ""

        log.error("(Meteo: repr %s) %s" % (repr(self), msg))
        return msg
Пример #38
0
class Maze(object):
    """
    Classe relativa ad un labirinto.
    """
    PRIMARY_KEY = ""
    VOLATILES = ["cells", "track_counter"]
    MULTILINES = []
    SCHEMA = {
        "passages": ("src.games.maze", "MazePassage"),
        "dead_ends": ("src.games.maze", "MazeDeadEnd")
    }
    REFERENCES = {}
    WEAKREFS = {}

    def __init__(self, columns=0, rows=0, code_prefix=""):
        self.columns = columns  # Numero di colonne totali del labirinto
        self.rows = rows  # Numero di righe totali del labirinto
        self.code_prefix = code_prefix  # Prefisso del codice delle room utilizzate per il reset
        self.remake_hour = -1  # In quale ora il maze viene ricreato
        self.remake_weekday = Element(WEEKDAY.NONE)
        self.remake_message = ""  # Messaggio di act a tutte le entità nel labirinto durante il relativo remake
        self.passages = [
        ]  # Elenco dei passaggi: entrate, uscite o altre nicchie, collegate al labirinto attorno al suo bordo
        self.dead_ends = [
        ]  # Elenco dei vicoli ciechi casualmente da inserire al posto di quelli standard

        # Variabili volatili
        self.cells = []
        self.track_counter = 0  # Numero di room tracciate dall'algoritmo di creazione del maze

    #- Fine Inizializzazione -

    def get_error_message(self):
        if self.columns <= 1:
            return "colums non è valido: %d" % self.columns
        elif self.rows <= 1:
            return "rows non è valido: %d" % self.rows
        elif self.remake_hour < -1 and self.remake_hour > config.hours_in_day - 1:
            return "remake_hour non è un'ora rpg valida: %d (inserire da -1 a %d)" % (
                self.remake_hour, config.hours_in_day - 1)
        elif self.remake_weekday.get_error_message(WEEKDAY,
                                                   "remake_weekday") != "":
            return self.remake_weekday.get_error_message(
                WEEKDAY, "remake_weekday")
        elif self.get_error_message_passages() != "":
            return self.get_error_message_passages()
        elif self.get_error_message_dead_ends() != "":
            return self.get_error_message_dead_ends()
        else:
            return ""

    #- Fine Metodo -

    def get_error_message_passages(self):
        for passage in self.passages:
            message = passage.get_error_message(self)
            if message:
                return message

        return ""

    #- Fine Metodo -

    def get_error_message_dead_ends(self):
        for dead_end in self.dead_ends:
            message = dead_end.get_error_message(self)
            if message:
                return message

        return ""

    #- Fine Metodo -

    def create(self, area):
        if not area:
            log.bug("area non è un parametro valido: %r" % area)
            return

        # ---------------------------------------------------------------------

        # Mette il token(none), wall(4 * True) e visited(false) a tutte le room
        self.cells = [[MazeCell() for r in xrange(self.rows)]
                      for c in xrange(self.columns)]
        self.track_counter = 0

        # A stack containing coordinates of the current cell and a scrambled
        # list of the direction to its neighbors
        shuffled = list(DIRS)
        random.shuffle(shuffled)

        # inizialmente contiene solo dati per una room: coordinate e la sequenza delle vicine scramblate
        stack = [
            StackElement(math.floor(random.random() * self.columns),
                         math.floor(random.random() * self.rows), shuffled)
        ]

        # Il loop deve iterare fino a che ha visitato tutte le celle, ma poiché
        # il depth first può anche tornare sui propri passi non basta farlo
        # iterare (self.rows * self.columns) volte
        while self.track_counter < (self.rows * self.columns):
            self.depth_first_search(stack)

        # Toglie i muri relativi ai vari passaggi fuori dai limiti della griglia
        # aprendo dei passi in questa maniera vengono correttamente caricate
        # le stanze a seconda delle uscite attorno
        for passage in self.passages:
            if passage.z != 0:
                continue
            coords = "%d %d %d" % (passage.x, passage.y, passage.z)
            if coords not in area.rooms:
                log.bug(
                    "Non esistono le coordinate %s nell'area %s (nel ciclo dei passages attorno)"
                    % (coords, area.code))
                continue
            passage_room = area.rooms[coords]
            if passage.y == -1:
                self.cells[passage.x][0].wall[SOUTH] = False
                if DIR.NORTH not in passage_room.exits:
                    passage_room.exits[DIR.NORTH] = Exit(DIR.NORTH)
            if passage.y == self.rows:
                self.cells[passage.x][self.rows - 1].wall[NORTH] = False
                if DIR.SOUTH not in passage_room.exits:
                    passage_room.exits[DIR.SOUTH] = Exit(DIR.SOUTH)
            if passage.x == -1:
                self.cells[0][passage.y].wall[WEST] = False
                if DIR.EAST not in passage_room.exits:
                    passage_room.exits[DIR.EAST] = Exit(DIR.EAST)
            if passage.x == self.columns:
                self.cells[self.columns - 1][passage.y].wall[EAST] = False
                if DIR.WEST not in passage_room.exits:
                    passage_room.exits[DIR.WEST] = Exit(DIR.WEST)

        # Crea ed avvia i reset per l'area del labirinto
        self.create_resets(area)

        # Crea le aperture in alto e in basso per eventuali altri passaggi
        # Non esistendo delle descrizioni di stanze con uscite verso il basso
        # e verso l'alto è dato al giocatore fare attenzione a queste uscite
        # verso l'inizio o la fine del labirinto o altre nicchie.
        # Stesso discorso per l'aggiunta delle uscite diagonali per i 4 angoli
        # esterni.
        # Se la room relativa al passaggio non possiede l'uscita per arrivare
        # alla stanza del labirinto viene creata automaticamente.
        for passage in self.passages:
            if passage.z == 0:
                maze_coords = ""
                if passage.x == -1 and passage.y == -1:
                    maze_coords = "0 0 0"
                    maze_dir = DIR.SOUTHWEST
                elif passage.x == -1 and passage.y == self.rows:
                    maze_coords = "0 %d 0" % self.rows - 1
                    maze_dir = DIR.NORTHEAST
                elif passage.x == self.columns and passage.y == -1:
                    maze_coords = "%d 0 0" % self.columns - 1
                    maze_dir = DIR.SOUTHEAST
                elif passage.x == self.columns and passage.y == self.rows:
                    maze_coords = "%d %d 0" % (self.columns - 1, self.rows - 1)
                    maze_dir = DIR.NORTHEAST
                if maze_coords:
                    maze_room = area.rooms[maze_coords]
                    maze_room.exits[maze_dir] = Exit(maze_dir)
                    passage_coords = "%d %d %d" % (passage.x, passage.y,
                                                   passage.z)
                    if passage_coords not in area.rooms:
                        log.bug(
                            "Non esistono le coordinate %s nell'area %s (nel ciclo dei passages negli angoli)"
                            % (passage_coords, area.code))
                        continue
                    passage_room = area.rooms[passage_coords]
                    if maze_dir.reverse_dir not in passage_room.exits:
                        passage_room.exits[maze_dir.reverse_dir] = Exit(
                            maze_dir.reverse_dir)
            else:
                passage_coords = "%d %d %d" % (passage.x, passage.y, passage.z)
                if passage_coords not in area.rooms:
                    log.bug(
                        "Non esistono le coordinate %s nell'area %s (nel ciclo dei passages nell'up & down)"
                        % (passage_coords, area.code))
                    continue
                passage_room = area.rooms[passage_coords]
                maze_room = area.rooms["%d %d 0" % (passage.x, passage.y)]
                if passage.z == 1:
                    maze_room.exits[DIR.UP] = Exit(DIR.UP)
                    if DIR.DOWN not in passage_room.exits:
                        passage_room.exits[DIR.DOWN] = Exit(DIR.DOWN)
                else:
                    maze_room.exits[DIR.DOWN] = Exit(DIR.DOWN)
                    if DIR.UP not in passage_room.exits:
                        passage_room.exits[DIR.UP] = Exit(DIR.UP)

        # (TD) Ora provvede ad inserire casualmente i DeadEnds evitando
        # che questi tangino eventuali Passagges
        pass

        # Rimuove le informazioni delle MazeCell per pulizia
        self.cells = []

    #- Fine Metodo -

    def depth_first_search(self, stack):
        tail_element = stack[-1]
        x = tail_element.x
        y = tail_element.y
        neighbors = tail_element.neighbors

        # When all cells have been visited at least once, it's done
        if not self.cells[x][y].visited:
            self.cells[x][y].visited = True
            self.track_counter = self.track_counter + 1

        # Stampa le coordinate della via seguita per la generazione del maze per
        # verificare che non restino celle non tracciate
        # When all cells have been visited at least once, it's done
        #print "(", x, ",", y, ")", "- room tracciate", self.track_counter

        # Look for a neighbor that is in the maze and hasn't been visited yet
        while len(neighbors) > 0:
            direction = neighbors.pop()
            if len(neighbors) == 0:
                stack.pop()  # All neighbors checked, done with this one

            dx = x + DELTA["x"][direction]
            dy = y + DELTA["y"][direction]
            if dx >= 0 and dy >= 0 and dx < self.columns and dy < self.rows:
                if self.cells[dx][dy].visited == False:
                    # Break down the wall between them. The new neighbor is
                    # added onto the stack and becomes the new current cell
                    self.cells[x][y].wall[direction] = False
                    self.cells[dx][dy].wall[UNDIRS[direction]] = False
                    shuffled = list(DIRS)
                    random.shuffle(shuffled)
                    new_element = StackElement(dx, dy, shuffled)
                    stack.append(new_element)
                    break

    #- Fine Metodo -

    def create_resets(self, area):
        """
        Esegue il reset del labirinto con le stanze appositamente create per
        l'area.
        """
        for x in xrange(self.columns):
            for y in xrange(self.rows):
                wall = self.cells[x][y].wall
                # [NORTH, SOUTH, WEST,  EAST  ]
                #print "x:%d y:%d NORTH:%s SOUTH:%s WEST:%s EAST:%s" % (x, y, wall[NORTH], wall[SOUTH], wall[WEST], wall[EAST])
                if wall == [True, False, True, True]: code = "_sud"  # switch 1
                elif wall == [False, True, True, True]:
                    code = "_nord"  # switch 1
                elif wall == [True, True, False, True]:
                    code = "_ovest"
                elif wall == [True, True, True, False]:
                    code = "_est"
                elif wall == [False, False, True, True]:
                    code = "_nord-sud"
                elif wall == [True, True, False, False]:
                    code = "_est-ovest"
                elif wall == [False, False, False, False]:
                    code = "_incrocio"
                elif wall == [True, False, True, False]:
                    code = "_sud-est"  # switch 2
                elif wall == [True, False, False, True]:
                    code = "_sud-ovest"  # switch 3
                elif wall == [False, True, True, False]:
                    code = "_nord-est"  # switch 2
                elif wall == [False, True, False, True]:
                    code = "_nord-ovest"  # switch 3
                elif wall == [False, False, False, True]:
                    code = "_3no-est"
                elif wall == [False, True, False, False]:
                    code = "_3no-sud"  # switch 4
                elif wall == [False, False, True, False]:
                    code = "_3no-ovest"
                elif wall == [True, False, False, False]:
                    code = "_3no-nord"  # switch 4
                elif wall == [True, True, True, True]:
                    code = "_no"  #; print wall
                else:
                    log.bug("Qui non dovrebbe mai passare: %s", wall)
                    continue
                room_reset = RoomReset()
                room_reset.proto_room = database["proto_rooms"][
                    self.code_prefix + code]
                room_reset.destination = Destination(x, y, 0, area)
                area.room_resets.append(room_reset)

        # Una volta creati i reset li avvia
        area.defer_reset_events()

    #- Fine Metodo -

    def destroy(self, area):
        if not area:
            log.bug("area non è un parametro valido: %r" % area)
            return

        # ---------------------------------------------------------------------

        room_codes = []
        for passage in self.passages:
            room_codes.append(passage.proto_room.code)

        area.stop_reset_events(except_these=room_codes)
        area.room_resets = []
        area.extract_rooms(except_these=room_codes)

    #- Fine Metodo -

    def remake(self, area):
        # Ricava le entità da salvarsi e trasportare nel nuovo labirinto
        players = []
        for player in area.players:
            self.send_remake_message(player)
            player = player.from_location(1, use_repop=False)
            players.append(player)
        entities = []
        for entity in area.iter_contains(use_reversed=True):
            if not entity.location:
                log.bug("location dell'entità %s non è valido: %r" %
                        (entity.code, entity.location))
                continue
            if not entity.IS_PLAYER and entity.location.IS_ROOM:
                self.send_remake_message(entity)
                entity = entity.from_location(entity.quantity, use_repop=False)
                entities.append(entity)

        # Distrugge il vecchio labirinto e ne crea uno nuovo
        self.destroy(area)
        self.create(area)

        # Sposta le entità salvate precedentemente nel nuovo labirinto
        for entity in players + entities:
            if entity.previous_location() and entity.previous_location(
            ).IS_ROOM:
                coords = "%d %d %d" % (entity.previous_location().x,
                                       entity.previous_location().y,
                                       entity.previous_location().z)
                if coords in area.rooms:
                    room = area.rooms[coords]
                else:
                    room = random.choice(area.rooms.values())
            else:
                room = random.choice(area.rooms.values())
            entity.to_location(room)

    #- Fine Metodo -

    def send_remake_message(self, entity):
        if self.remake_message == "no_send":
            return

        if self.remake_message:
            message = "\n" + self.remake_message
        else:
            message = "\nD'improvviso le aperture e i corridoi attorno a te si muovono come mischiandosi e ti ritrovi smarrit$o."

        entity.send_output(message)
        entity.send_prompt()
Пример #39
0
 def __init__(self):
     self.material = Element(MATERIAL.NONE)
     self.percent  = 0
Пример #40
0
class Account(Data):
    """
    Contiene tutte le informazioni e le opzioni di un Account di gioco, in
    esso c'è anche la lista dei personaggi creati e giocabili dal giocatore
    dell'account.
    """
    PRIMARY_KEY = "name"
    VOLATILES   = ["player", "players"]
    MULTILINES  = []
    SCHEMA      = {"players"                : ("src.player",  "Player"),
                   "player"                 : ("src.player",  "Player"),
                   "aliases"                : ("src.account", "Alias"),
                   "macros"                 : ("src.account", "Macro"),
                   "user_agents"            : ("",            "str"),
                   "created_time"           : ("",            "datetime"),
                   "last_bug_sended_at"     : ("",            "datetime"),
                   "last_comment_sended_at" : ("",            "datetime"),
                   "last_typo_sended_at"    : ("",            "datetime"),
                   "last_idea_sended_at"    : ("",            "datetime")}
    REFERENCES  = {}
    WEAKREFS    = {}

    def __init__(self, name=""):
        self.comment                = ""
        self.created_time           = datetime.datetime.now()  # Data di creazione del'account
        self.name                   = name  # Nome di login
        self.password               = ""    # Password
        self.email                  = ""    # Indirizzo e-mail (opzionale)
        self.options                = Flags(OPTION.NONE)
        self.show_logs              = Flags(LOG.NONE)
        self.aliases                = {}  # Dizionario relativo agli alias
        self.macros                 = {}  # Dizionario relativo alle macro
        # (TD) provare a convertire questi datetime in None e caricarli tramite schema
        self.last_bug_sended_at     = None
        self.last_comment_sended_at = None
        self.last_typo_sended_at    = None
        self.last_idea_sended_at    = None
        self.sended_bugs            = 0  # Bug totali inviati
        self.sended_comments        = 0  # Typo totali inviati
        self.sended_ideas           = 0  # Idee totali inviati
        self.sended_typos           = 0  # Typo totali inviati
        self.user_agents            = [] # Informazioni relative ai client browser utilizzati dal giocatore per entrare nel Mud
        self.resolution_width       = 0  # Risoluzione in pixel del monitor del client in larghezza
        self.resolution_height      = 0  # Risoluzione in pixel del monitor del client in altezza

        # Al primo account creato in assoluto dà poteri di Implementor, dando
        # per scontato che il primo giocatore che utilizza questo Mud sia il
        # futuro amministratore, ai successivi account dona la trust di player
        if not database["accounts"]:
            self.trust = Element(TRUST.IMPLEMENTOR)
        else:
            self.trust = Element(TRUST.PLAYER)

        # Attributi volatili
        self.players = {}  # Dizionario dei giocatori creati dall'account
        self.player  = None  # Personaggio che si sta creando o utilizzando
    #- Fine Inizializzazione -

    def __repr__(self):
        return "%s %s" % (super(Account, self).__repr__, self.name)
    #- Fine Metodo -

    def get_error_message(self, already_in_database=True):
        """
        Ritorna una stringa vuota se l'account non ha errori, altrimenti il
        messaggio d'errore.
        Bisogna passare l'argomento already_in_database uguale a False quando
        si controlla l'integrità di un account appena creato e che non si è
        ancora aggiunto al database degli account.
        """
        msg = ""
        if already_in_database != True and already_in_database != False:
            msg = "L'argomento already_in_database non è un booleano valido: %s" % already_in_database

        # ---------------------------------------------------------------------

        # self.player è lecito che sia anche None se l'account non sta giocando

        if msg:
            pass
        elif get_error_message_name(self.name, already_in_database) != "":
            msg = "%s: %s" % (get_error_message_name(self.name, already_in_database), self.name)
        elif get_error_message_password(self.password) != "":
            msg = "%s: %s" % (get_error_message_password(self.password), self.password)
        elif get_error_message_email(self.email, already_in_database) != "":
            msg = "%s: %s" % (get_error_message_email(self.email, already_in_database), self.email)
        elif self.trust.get_error_message(TRUST, "trust") != "":
            msg = self.trust.get_error_message(TRUST, "trust")
        elif self.options.get_error_message(OPTION, "options") != "":
            msg = self.options.get_error_message(OPTION, "options")
        elif self.show_logs.get_error_message(LOG, "logs") != "":
            msg = self.show_logs.get_error_message(LOG, "logs")
        elif len(self.players) > config.max_account_players:
            msg = "Numero di personaggi superiore a %s" % config.max_account_players
        elif self._get_error_message_only_one_player() != "":
            msg = self._get_error_message_only_one_player()
        elif len(self.aliases) > config.max_aliases:
            msg = "Numero degli alias superiore al massimo (%d): %d" % (config.max_aliases, len(self.aliases))
        elif len(self.macros) > config.max_macros:
            msg = "Numero delle macro superiore al massimo (%d): %d" % (config.max_macros, len(self.macros))
        elif self.resolution_width < 0:
            msg = "Risoluzione del client in larghezza errato: %d" % self.resolution_width
        elif self.resolution_height < 0:
            msg = "Risoluzione del client in altezza errato: %d" % self.resolution_height
        else:
            return ""

        # Se ha trovato un errore invia il relativo messaggio
        log.bug("(Account: name %s) %s" % (self.name, msg))
        return msg
    #- Fine Metodo -

    def _get_error_message_only_one_player(self):
        """
        Controlla che due o più account non utilizzino lo stesso player.
        """
        for player in self.players.itervalues():
            for account in database["accounts"].itervalues():
                if account.name == self.name:
                    continue
                if player.code in account.players:
                    return "Personaggio %s già esistente nell'account %s" % (player.code, account.name)
        return ""
    #- Fine Metodo -

    # -------------------------------------------------------------------------

    def get_id(self):
        """
        Ritorna una o tutte tra le seguenti informazioni: il nome dell'account
        e il nome del personaggio.
        Molto utile da utilizzare nei messaggi di log.
        Questo metodo fa a coppia con quello nella classe Connection.
        """
        player_name = "None"
        if self.player:
            player_name = self.player.code

        return "%s.%s" % (self.name, player_name)
    #- Fine Metodo -

    def check_alias(self, arg, argument):
        """
        Controlla se argument sia un alias di un pg, se sì lo ritorna.
        """
        if not arg:
            log.bug("arg non è un parametro valido: %r" % arg)
            return

        # ---------------------------------------------------------------------

        if arg not in self.aliases:
            return False

        alias = self.aliases[arg]
        argument = argument or ""
        interpret(self.player, "%s %s" % (alias.action, argument), use_check_alias=False)
        return True
Пример #41
0
class Area(Data, AreaResetsSuperclass):
    """
    Contiene tutte le informazioni di un'area e i metodi per gestirla.
    """
    PRIMARY_KEY = "code"
    VOLATILES   = ["max_players", "upper_limit", "lower_limit",
                   "rooms", "players", "mobs", "items",
                   "room_scripts", "mob_scripts", "item_scripts", "player_scripts",
                   "meteo", "proto_rooms", "proto_mobs", "proto_items"]
    MULTILINES  = ["descr"]
    SCHEMA      = {"climates"                  : ("src.climate",      "Climate"),
                   "maze"                      : ("src.games.maze",   "Maze"),
                   "wumpus"                    : ("src.games.wumpus", "Wumpus"),
                   "wild"                      : ("src.wild",         "Wild"),
                   "room_resets"               : ("src.reset",        "RoomReset"),
                   "echoes_dawn"               : ("", "str"),
                   "echoes_dawn_no_sun"        : ("", "str"),
                   "echoes_sunrise"            : ("", "str"),
                   "echoes_sunrise_no_sun"     : ("", "str"),
                   "echoes_noon"               : ("", "str"),
                   "echoes_noon_no_sun"        : ("", "str"),
                   "echoes_sunset"             : ("", "str"),
                   "echoes_sunset_no_sun"      : ("", "str"),
                   "echoes_dusk"               : ("", "str"),
                   "echoes_dusk_no_moon"       : ("", "str"),
                   "echoes_dusk_full_moon"     : ("", "str"),
                   "echoes_midnight"           : ("", "str"),
                   "echoes_midnight_no_moon"   : ("", "str"),
                   "echoes_midnight_full_moon" : ("", "str")}

    REFERENCES  = {}
    WEAKREFS    = {}

    IS_AREA   = True
    IS_DESCR  = False
    IS_ROOM   = False
    IS_EXIT   = False
    IS_WALL   = False
    IS_ACTOR  = False
    IS_MOB    = False
    IS_ITEM   = False
    IS_PLAYER = False
    IS_EXTRA  = False
    IS_PROTO  = False

    def __init__(self, code=""):
        self.comment        = ""
        self.code           = code # Codice identificativo dell'area
        self.name           = ""   # Nome esteso
        self.short          = ""   # Descrizioni breve dell'area
        self.short_night    = ""   # Descrizioni breve notturna dell'area
        self.descr          = ""   # Descrizione dell'area per la pagina web della lista delle aree
        self.creators       = ""   # Lista dei creatori, vale il codice dell'account  (TD) in futuro sarà una lista per poter ricavare il riferimento
        self.level          = 1    # Livello base per tutte le entità dell'area, se viene modificato questo anche tutte le entità aumentano o diminuiscono di livello in proporzione
        self.flags          = Flags(AREA.NONE)
#       self.races          = Flags(RACE.NONE)  # Razze che si possono incontrare principalmente nell'area  (TD)
        self.color          = Element(COLOR.NONE)  # Colore dell'area
        self.music          = ""   # File mid avviato quando uno entra nell'area
        self.music_wild     = ""   # File mid avviato quando uno esce dall'area ed entra nella wild
        self.climates       = {}   # Informazioni climatiche dell'area relativamente alle stagioni
        self.maze           = None # Informazioni relative al labirinto
        self.wumpus         = None # Informazioni relative alle aree wumpus
        self.wild           = None # Struttura relativa alla wilderness
        self.landfill_code  = ""   # Codice della stanza prototipo in cui verranno inseriti gli oggetti "da buttare"
        self.repop_time     = 0    # Minuti reali tra un repop di un'entità ed un'altro
        self.room_resets    = []   # Lista dei reset dell'area

        # Attributi relativi alle liste dei messaggi di echo
        self.echoes_dawn               = []
        self.echoes_dawn_no_sun        = []
        self.echoes_sunrise            = []
        self.echoes_sunrise_no_sun     = []
        self.echoes_noon               = []
        self.echoes_noon_no_sun        = []
        self.echoes_sunset             = []
        self.echoes_sunset_no_sun      = []
        self.echoes_dusk               = []
        self.echoes_dusk_no_moon       = []
        self.echoes_dusk_full_moon     = []
        self.echoes_midnight           = []
        self.echoes_midnight_no_moon   = []
        self.echoes_midnight_full_moon = []

        # Attributi volatili:
        self.max_players    = 0  # Numero massimo di giocatori che sono stati presenti contemporaneamente nell'area nella sessione di gioco
        self.upper_limit    = 0  # Limite di coordinata Z verso l'alto oltre la quale si esce dall'area
        self.lower_limit    = 0  # Limite di coordinata Z verso il basso oltre la quale si esce dall'area
        self.rooms          = {} # Stanze in-game nelle rispettive coordinate
        self.players        = [] # Giocatori in-game che si trovano nelll'area
        self.mobs           = [] # Mob in-game che si trovano nell'area
        self.items          = [] # Oggetti in-game che si trovano nell'area
        self.meteo          = Meteo()  # Informazioni meteo in-game dell'area
        self.gamescripts    = {}   # Gamescript a livello di area

        # Liste relative ai dati modello dell'area, i prototipi
        self.proto_rooms    = {}
        self.proto_mobs     = {}
        self.proto_items    = {}
    #- Fine Inizializzazione -

    def __repr__(self):
        return "%s %s" % (super(Area, self).__repr__, self.code)
    #- Fine Metodo -

    def get_error_message(self):
        """
        Ritorna un messaggio di errore se la struttura dell'area contiene delle
        anomalie, altrimenti se tutto è corretto ritorna una stringa vuota.
        """
        if not self.code:
            msg = "code dell'area non valido"
        elif not self.code.islower():
            msg = "code dell'area per convenzione deve essere scritto in minuscolo: %s" % self.code
        elif not self.short:
            msg = "short dell'area non valido: %r" % self.short
        elif not self.name:
            msg = "name dell'area non valido: %r" % self.name
        elif not self.descr:
            msg = "descr dell'area non valida: %r" % self.descr
        elif self.get_error_message_creators() != "":
           msg = self.get_error_message_creators()
        elif self.level <= 0:
            msg = "Il livello di un'area non può essere uguale a 0 o negativo: %d" % self.level
#       elif self.races.get_error_message(RACE, "races") != "":
#           msg = self.races.get_error_message(RACE, "races")
        elif self.flags.get_error_message(AREA, "flags") != "":
            msg = self.flags.get_error_message(AREA, "flags")
        elif self.color.get_error_message(COLOR, "color") != "":
            msg = self.color.get_error_message(COLOR, "color")
        elif self.get_error_message_climates() != "":
            msg = self.get_error_message_climates()
        elif self.maze and self.maze.get_error_message() != "":
            msg = self.maze.get_error_message()
        elif self.wumpus and self.wumpus.get_error_message() != "":
            msg = self.wumpus.get_error_message()
        elif self.repop_time < config.min_repop_time or self.repop_time > config.max_repop_time:
            msg = "il repop time deve essere compreso tra %d e %d minuti invece è: %d" % (
                config.min_repop_time, config.max_repop_time, self.repop_time)
        elif not self.landfill_code and not self.wild:
            msg = "landfill_code dell'area non valido: %r" % self.landfill_code
        elif self.get_error_message_resets() != "":
            msg = self.get_error_message_resets()
        else:
            return ""

        # Se arriva qui c'è un messaggio d'errore da inviare
        log.error("(Area: %s) %s" % (self.code, msg))
        return msg
    #- Fine Metodo -

    def get_error_message_creators(self):
        if self.creators:
            from src.database import database
            hint = "controllare di aver inserito il nome con la maiuscola"
            for name in self.creators.split():
                if name not in database["accounts"]:
                    #return "area %s non ha trovato nell'etichetta Creators un nome tra quelli degli account: %s (%s)" % (
                    #    self.code, name, hint)
                    continue

        return ""
    #- Fine Metodo -

    def get_error_message_climates(self):
        for climate in self.climates:
            if climate.get_error_message() != "":
                return climate.get_error_message()

        return ""
    #- Fine Metodo -

    # (TD)
    def get_pedantic_messages(self):
        messages = []

        if not self.short_night and "@empty_short_night" not in self.comment:
            messages.append("short_night non è stata scritta, da ignorare nel qual caso nell'area non sussistano grossi cambiamenti di luce o altro, tra giorno e notte. (@empty_short_night)")

        length = len(remove_colors(getattr(self, "descr")))
        if length > config.max_google_translate * 2 and "@descr_too_long" not in self.comment:
            messages.append("descr è più lunga di %d caratteri: %d (@descr_too_long)" % (config.max_google_translate * 2, length))

        for i, message in enumerate(messages):
            messages[i] = "(Area: code %s) %s" % (self.code, message)

        return messages
    #- Fine Metodo -

    def get_name(self, looker=None):
        # (TD) fare il sistema di self.name
        if calendar.is_night() and self.short_night:
            return self.short_night
        else:
            return self.short
    #- Fine Metodo -

    def extract_rooms(self, except_these=None):
        if except_these is None:
            except_these = []

        for room in reversed(self.rooms.values()):
            if room.prototype.code not in except_these:
                room.extract(1)

        # (TD) L'estrazione del resto delle altre entità non dovrebbe servire,
        # tuttavia in futuro sarebbe il caso di aggiungere un check per
        # controllare i riferimenti
    #- Fine Metodo -

    # (TT) Questo metodo è uguale a quello in entity.py, possibilità di accorpare?
    def iter_contains(self, entity_tables=None, use_reversed=False):
        """
        È curioso come a volte questo metodo possa essere utilizzato per
        iterare i codici dell entità prototipo passando un entity_tables uguale a questo:
        ("proto_items", "proto_mobs", "proto_rooms"); per avere i valori di
        prototipo invece basta utilizzare il metodo iter_protos.
        """
        if not entity_tables:
            entity_tables = ["items", "mobs", "players"]

        if use_reversed:
            for type in entity_tables:
                for content in reversed(getattr(self, type)):
                    yield content
        else:
            for type in entity_tables:
                for content in getattr(self, type):
                    yield content
    #- Fine Metodo -

    def iter_protos(self, entity_tables=None, use_reversed=False):
        if not entity_tables:
            entity_tables = ["proto_items", "proto_mobs", "proto_rooms"]

        if use_reversed:
            for type in entity_tables:
                for content in reversed(getattr(self, type).values()):
                    yield content
        else:
            for type in entity_tables:
                for content in getattr(self, type).values():
                    yield content
    #- Fine Metodo -

    def get_list_of_entities(looker, include_looker="dummy-parameter", avoid_inventory="dummy-parameter", avoid_equipment="dummy-parameter", admin_descrs="dummy-parameter"):
        return getattr(self, entity_type)
    #- Fine Metodo -

    def get_min_coord(self, axis):
        if axis not in ("x", "y", "z"):
            log.bug("axis non è una asse cartesiano valido: %s" % axis)
            return 0

        #----------------------------------------------------------------------

        coords = []
        for room_reset in self.room_resets:
            coords.append(getattr(room_reset.destination, axis))

        if coords:
            return min(coords)
        else:
            return 0
    #- Fine Metodo -

    def get_max_coord(self, axis):
        if axis not in ("x", "y", "z"):
            log.bug("axis non è una asse cartesiano valido: %s" % axis)
            return 0

        #----------------------------------------------------------------------

        coords = []
        for room_reset in self.room_resets:
            coords.append(getattr(room_reset.destination, axis))

        if coords:
            return max(coords)
        else:
            return 0
Пример #42
0
class Readable(object):
    PRIMARY_KEY = ""
    VOLATILES = []
    MULTILINES = ["comment", "pages", "summary"]
    SCHEMA = {
        "visual_width": ("", "css_measure"),
        "visual_height": ("", "css_measure"),
        "padding": ("", "css_measure"),
        "border_top": ("", "css_border"),
        "border_right": ("", "css_border"),
        "border_bottom": ("", "css_border"),
        "border_left": ("", "css_border"),
        "border_inside": ("", "css_border"),
        "pages": ("", "str")
    }
    REFERENCES = {}
    WEAKREFS = {}

    def __init__(self):
        self.comment = ""  # Commento per gli area builder relativo all'entità leggibile
        self.title = ""  # Titolo del libro
        self.author = ""  # Autore o gli autori di questo libro
        self.summary = ""  # Riassunto del libro che il giocatore carpisce esaminandolo
        self.language = Element(LANGUAGE.COMMON)  # (TD) Lingua di questo libro
        self.flags = Flags(
            READABLE.NONE)  # Flag relative alle entità leggibili
        self.visual_width = ""  # Larghezza in pixel del libro sullo schermo
        self.visual_height = ""  # Larghezza in pixel del libro sullo schermo
        self.padding = ""  # Larghezza in pixel del padding della cornice del libro
        self.border_top = ""  # Bordo css decorante il libro in alto
        self.border_right = ""  # Bordo css decorante il libro a destra
        self.border_bottom = ""  # Bordo css decorante il libro in basso
        self.border_left = ""  # Bordo css decorante il libro a sinistra
        self.border_inside = ""  # Bordo css decorante il libro tra le due pagine
        self.number_decoration_left = ""  # Decorazione della pagina sinistra per i numeri di pagina
        self.number_decoration_right = ""  # Decorazione della pagina sinistra per i numeri di pagina
        self.pages = []  # Lista delle pagine e relativo contenuto

    #- Fine Inizializzazione -

    def get_error_message(self, entity):
        if not self.title:
            return "title è una stringa non valida: %r" % self.title
        elif not self.author:
            return "author è una stringa non valida: %r" % self.author
        elif not self.summary:
            return "summary è una stringa non valida: %r" % self.summary
        elif self.language.get_error_message(LANGUAGE, "language") != "":
            return self.language.get_error_message(LANGUAGE, "language")
        elif self.flags.get_error_message(READABLE, "flags") != "":
            return self.flags.get_error_message(READABLE, "flags")
        elif READABLE.CENTER in self.flags and READABLE.RIGHT in self.flags:
            return "Non possono convivere le flag READABLE.CENTER e READABLE.RIGHT assieme."
        elif (self.number_decoration_left or self.number_decoration_right
              ) and READABLE.NUMBERS not in self.flags:
            return "Nonostante sia stata definita una decorazione per i numeri non esiste la flag READABLE.NUMBERS che la mostrerebbe."
        elif not self.visual_width:
            return "visual_width è una stringa non valida: %r" % self.visual_width
        elif not self.visual_height:
            return "visual_height è una stringa non valida: %r" % self.visual_height
        elif not self.pages:
            return "dev'esservi almeno una pagina: %r" % self.pages

        return ""

    #- Fine Metodo -

    def copy(self, to_obj=None, avoid_volatiles=False):
        if not to_obj:
            to_obj = Readable()
        copy_existing_attributes(self, to_obj, avoid_volatiles=avoid_volatiles)
        return to_obj

    #- Fine Metodo -

    def equals(self, readable2):
        if not readable2:
            return False

        if self.comment != readable2.comment:
            return False
        if self.title != readable2.title:
            return False
        if self.author != readable2.author:
            return False
        if self.summary != readable2.summary:
            return False
        if self.language != readable2.language:
            return False
        if self.flags != readable2.flags:
            return False
        if self.visual_width != readable2.visual_width:
            return False
        if self.visual_height != readable2.visual_height:
            return False
        if self.padding != readable2.padding:
            return False
        if self.border_top != readable2.border_top:
            return False
        if self.border_right != readable2.border_right:
            return False
        if self.border_bottom != readable2.border_bottom:
            return False
        if self.border_left != readable2.border_left:
            return False
        if self.border_inside != readable2.border_inside:
            return False
        if self.number_decoration_left != readable2.number_decoration_left:
            return False
        if self.number_decoration_right != readable2.number_decoration_right:
            return False

        if len(self.pages) != len(readable2.pages):
            return False
        for page in self.pages:
            for page2 in readable2.pages:
                if page == page2:
                    break
            else:
                return False

        return True

    #- Fine Metodo -

    # -------------------------------------------------------------------------

    # (TD) entity e target serviranno in futuro per scramblerare la lingua del
    # libro se sconosciuta
    def get_pages(self, entity, target, page_number, from_location=None):
        if not entity:
            log.bug("entity non è un parametro valido: %r" % entity)
            return ""

        if not target:
            log.bug("target non è un parametro valido: %r" % target)
            return ""

        if page_number < 0 or page_number >= len(self.pages):
            log.bug("page_number non è un parametro valido: %r" % page_number)
            return ""

        # ---------------------------------------------------------------------

        # Prepara i bordi
        border_top = ""
        border_right = ""
        border_bottom = ""
        border_left = ""
        border_inside = ""
        if self.border_top:
            border_top = "border-top:%s;" % self.border_top
        if self.border_right:
            border_right = "border-right:%s;" % self.border_right
        if self.border_bottom:
            border_bottom = "border-bottom:%s;" % self.border_bottom
        if self.border_left:
            border_left = "border-left:%s;" % self.border_left
        if self.border_inside:
            border_inside = "border-right:%s;" % self.border_inside

        # Prepara il padding se esistente
        padding_style = ""
        if self.padding:
            padding_style = "padding:%s;" % self.padding

        # Prepara lo style css per l'output scritto della pagina
        alignment = ""
        if READABLE.CENTER in self.flags:
            alignment = '''text-align:center;'''
        if READABLE.RIGHT in self.flags:
            alignment = '''text-align:right;'''
        visual_style = ''' style="min-width:%s; max-width:%s; min-height:%s; max-height:%s; %s %s"''' % (
            self.visual_width, self.visual_width, self.visual_height,
            self.visual_height, padding_style, alignment)

        # Ricava informazioni che servono a sfogliare il libro tramite click
        translated_input = translate_input(entity, "read", "en")
        if not translated_input:
            log.bug("Non è stato possibile tradurre l'input read per %s: %r" %
                    (target.code, translated_input))
            return False
        numbered_keyword = target.get_numbered_keyword(looker=entity)
        if page_number % 2 == 0 and page_number != len(self.pages) - 1:
            minimum_page = max([0, page_number - 2])
            maximum_page = min([len(self.pages) - 1, page_number + 1])
        else:
            minimum_page = max([0, page_number - 1])
            maximum_page = min([len(self.pages) - 1, page_number + 2])
        if from_location:
            js_minimum_arguments = "%s %s %s %d" % (
                translated_input, numbered_keyword,
                from_location.get_numbered_keyword(looker=entity),
                minimum_page)
            js_maximum_arguments = "%s %s %s %d" % (
                translated_input, numbered_keyword,
                from_location.get_numbered_keyword(looker=entity),
                maximum_page)
        else:
            js_minimum_arguments = "%s %s %d" % (
                translated_input, numbered_keyword, minimum_page)
            js_maximum_arguments = "%s %s %d" % (
                translated_input, numbered_keyword, maximum_page)
        browse_to_left = '''<div style="float:left"><a href="javascript:sendInput('%s')" style="font-size:larger">&lt;</a> </div>''' % js_minimum_arguments
        browse_to_right = '''<div style="float:left"> <a href="javascript:sendInput('%s')" style="font-size:larger">&gt;</a></div>''' % js_maximum_arguments

        # Gestisce la copertina e la retrocopertina o altre tipologie di entità
        # leggibili differenti da dei libri, ovvero con al massimo il fronte
        # e il retro
        if page_number == 0 or page_number == len(self.pages) - 1:
            style = ""
            if border_top or border_right or border_bottom or border_left:
                style = ''' style="float:left; %s%s%s%s"''' % (
                    border_top, border_right, border_bottom, border_left)
            output = ""
            if page_number == len(self.pages) - 1:
                output += browse_to_left
            output += '''<div%s><div%s>%s</div></div>''' % (
                style, visual_style, self.pages[page_number])
            if page_number == 0:
                output += browse_to_right
            output += '''<div style="clear:both;" />'''
            return output

        # A seconda che si voglia visualizzare una pagina a destra o a sinistra
        # sceglie il numero corretto di pagina da far visualizzare nell'altra
        if page_number % 2 == 0:
            left_page_number = page_number - 1
            right_page_number = page_number
        else:
            left_page_number = page_number
            right_page_number = page_number + 1

        # Prepara lo stile dei bordi preparati in precedenza, se ve n'erano
        left_style = '''style="float:left;%s%s%s%s"''' % (
            border_top, border_inside, border_bottom, border_left)
        right_style = '''style="float:left;%s%s%s"''' % (
            border_top, border_right, border_bottom)

        # Prepara il contenuto scritto delle pagine aggiungendo una pagina
        # vuota prima della retrocopertina se necessario
        left_output = self.pages[left_page_number]
        if len(self.pages) % 2 == 0 and page_number == len(self.pages) - 1:
            right_output = ""
        elif len(self.pages) % 2 == 1 and page_number == len(self.pages) - 2:
            right_output = ""
        else:
            right_output = self.pages[right_page_number]
        if MIML_SEPARATOR in left_output:
            left_output = target.parse_miml(left_output, looker=entity)
        if MIML_SEPARATOR in right_output:
            right_output = target.parse_miml(right_output, looker=entity)

        # Prepara l'output per i numeri di pagina
        left_page_number_output = ""
        right_page_number_output = ""
        if READABLE.NUMBERS in self.flags:
            if len(self.number_decoration_left) == 0:
                left_page_number_output = '''<center>%d</center>''' % left_page_number
            elif len(self.number_decoration_left) == 1:
                left_page_number_output = '''<center>%s%d</center>''' % (
                    self.number_decoration_left, left_page_number)
            else:
                middle = int(math.ceil(len(self.number_decoration_left) / 2.0))
                left_page_number_output = '''<center>%s%d%s</center>''' % (
                    self.number_decoration_left[:middle], left_page_number,
                    self.number_decoration_left[middle:])
            if len(self.number_decoration_right) == 0:
                right_page_number_output = '''<center>%d</center>''' % right_page_number
            elif len(self.number_decoration_right) == 1:
                right_page_number_output = '''<center>%d%s</center>''' % (
                    right_page_number, self.number_decoration_right)
            else:
                middle = int(math.floor(
                    len(self.number_decoration_left) / 2.0))
                right_page_number_output = '''<center>%s%d%s</center>''' % (
                    self.number_decoration_right[:middle], right_page_number,
                    self.number_decoration_right[middle:])

        # Ecco l'output del libro in tutto il suo splendore
        output = browse_to_left
        output += '''<div %s><div%s>%s</div>%s</div>''' % (
            left_style, visual_style, left_output, left_page_number_output)
        output += '''<div %s><div%s>%s</div>%s</div>''' % (
            right_style, visual_style, right_output, right_page_number_output)
        output += browse_to_right
        output += '''<div style="clear:both;" />'''

        return output
Пример #43
0
class Wall(Describable):
    """
    Classe per la gestione di un muro di stanza.
    """
    PRIMARY_KEY = "direction"
    VOLATILES   = []
    MULTILINES  = ["comment"]
    SCHEMA      = {"extras" : ("src.extra", "ExtraDescription")}
    REFERENCES  = {"maked_by"  : ["proto_items", "proto_mobs"]}
    WEAKREFS    = {}

    IS_AREA   = False
    IS_DESCR  = True
    IS_ROOM   = False
    IS_EXIT   = False
    IS_WALL   = True
    IS_ACTOR  = False
    IS_MOB    = False
    IS_ITEM   = False
    IS_PLAYER = False
    IS_EXTRA  = False
    IS_PROTO  = False

    def __init__(self, direction=DIR.NONE):
        if not direction:
            log.bug("direction non è un parametro valido: %r" % direction)
            return

        # ---------------------------------------------------------------------

        self.comment             = ""  # Eventuale commento al muro
        self.direction           = Element(direction)  # Tipologia della direzione
        self.maked_by            = None  # Oggetto di base utilizzato nella costruzione del muro (di solito un mattone o una pietra)
        self.depth               = 0   # Profondità della parete, assieme al tipo di materiale in quella direzione ne fanno la forza, che serve nel caso si voglia romperlo, picconarlo, sfondarlo o farlo saltare in aria!
        self.height              = 0   # Altezza del muro, se differente dall'altezza della stanza
        self.descr               = ""  # Descrizione dell'uscita che viene a formarsi quando il muro viene sfondato
        self.descr_night         = ""  # Descrizione notturna dell'uscita che viene a formarsi quando il muro viene sfondato
        self.descr_hearing       = ""  # Descrizione uditiva
        self.descr_hearing_night = ""  # Descrizione uditiva notturna
        self.descr_smell         = ""  # Descrizione odorosa
        self.descr_smell_night   = ""  # Descrizione odorosa notturna
        self.descr_touch         = ""  # Descrizione tattile
        self.descr_touch_night   = ""  # Descrizione tattile notturna
        self.descr_taste         = ""  # Descrizione del sapore
        self.descr_taste_night   = ""  # Descrizione del sapore notturna
        self.descr_sixth         = ""  # Descrizione del sesto senso
        self.descr_sixth_night   = ""  # Descrizione del sesto senso notturna
        self.extras              = Extras()  # Elenco delle extra che si possono guardare o leggere sul muro
    #- Fine Inizializzazione -

    def get_error_message(self):
        """
        Se nell'instanza del muro c'è un errore ritorna il relativo messaggio.
        """
        if self.direction.get_error_message(DIR, "direction", allow_none=False) != "":
            msg = self.direction.get_error_message(DIR, "direction", allow_none=False)
        elif not self.maked_by:
            msg = "non esiste nessuna entità legata a maked_by"
        elif self.maked_by and self.maked_by.code not in database["proto_items"]:
            msg = "non esiste nessun oggetto prototipo dal codice %s" % self.maked_by.code
        elif self.depth <= 0:
            msg = "depth è una lunghezza e quindi non deve essere minore e uguale a 0: %d" % self.depth
        elif self.height <= 0:
            msg = "height è una lunghezza e quindi non deve essere minore e uguale a 0: %d" % self.height
        elif self.extras.get_error_message():
            msg = self.extras.get_error_message()
        else:
            return ""
        return "(wall %s): %s" % (self.direction, msg)
    #- Fine Metodo -

    def copy(self, to_obj=None, avoid_volatiles=False):
        if not to_obj:
            to_obj = Wall()
        copy_existing_attributes(self, to_obj, avoid_volatiles=avoid_volatiles)
        return to_obj
    #- Fine Metodo -

    def equals(self, wall2):
        # Non dovrebbe servire implementarli, ma inserisco questo "avviso" al caso
        raise NotImplementedError
    #- Fine Metodo -

    # -------------------------------------------------------------------------

    def get_descr(self, type="", looker=None):
        """
        Ritorna la descrizione del muro.
        """
        if type:
            type = "_" + type

        descr = ""
        if calendar.is_night():
            descr = getattr(self, "descr%s_night" % type)
        if not descr:
            descr = getattr(self, "descr%s" % type)

        # Normale che possa accadere per qualsiasi tipologia di descrizione
        if not descr:
            return ""

        if self.ASCIIART_TAG_OPEN in descr:
            descr = self.convert_asciiart_linefeeds(descr)
        else:
            descr = put_final_dot(descr)

        if ".\n" in descr:
            descr = descr.replace(".\n", ".<br>")
        if "!\n" in descr:
            descr = descr.replace("!\n", "!<br>")
        if "?\n" in descr:
            descr = descr.replace("?\n", "?<br>")
        if "\n" in descr:
            descr = descr.replace("\n", " ")

        return descr
Пример #44
0
 def __init__(self):
     self.entitype = Element(
         ENTITYPE.NONE
     )  # Tipologia di entità che possono essere venduta al negoziante
     self.percent = 50  # Percentuale sul costo per le entità vendute al negoziante
     self.buyback_percent = 100  # Percentuale sul costo per le entità comprate dal negoziante e precedentemente vendutegli
Пример #45
0
 def __init__(self):
     self.entitype        = Element(ENTITYPE.NONE)  # Tipologia di entità che possono essere venduta al negoziante
     self.percent         =  50 # Percentuale sul costo per le entità vendute al negoziante
     self.buyback_percent = 100 # Percentuale sul costo per le entità comprate dal negoziante e precedentemente vendutegli
Пример #46
0
class Social(Data):
    """
    Gestisce un social.
    """
    PRIMARY_KEY = "fun_name"
    VOLATILES   = []
    MULTILINES  = []
    SCHEMA      = {"racial_messages" : ("src.social", "SocialRacialMessage")}
    REFERENCES  = {}
    WEAKREFS    = {}

    def __init__(self):
        self.comment         = ""
        self.fun_name        = ""  # Nome della funzione del comando legato al social
        self.intention       = Element(INTENTION.NONE)  # Tipologia di intenzione
        self.smiles          = ""  # Elenco degli smile supportati dal social
        self.expression      = ""  # Espressione relativa al'utilizzo degli smile
        self.racial_messages = EnumElementDict()
    #- Fine Inizializzazione -

    def get_error_message(self):
        if not self.fun_name:
            msg = "fun_name non valida: %r" % self.fun_name
        elif " " in self.fun_name:
            msg = "fun_name contiene degli spazi: <%s>" % self.fun_name
        elif self.intention.get_error_message(INTENTION, "intention") != "":
            msg = self.intention.get_error_message(INTENTION, "intention")
        elif ((    self.smiles and not self.expression)
        or    (not self.smiles and     self.expression)):
            msg = "smiles ed expression devono essere tutti e due vuoti oppure non vuoti"
        elif not self.racial_messages:
            msg = "Deve esistere almeno un messaggio razziale di social, di solito umano"
        elif RACE.HUMAN not in self.racial_messages:
            msg = "Deve esistere sempre il messaggio razziale di social degli umani"
        elif self._get_message_error_racial_message() != "":
            msg = self._get_message_error_racial_message()
        else:
            return ""

        log.bug("(Social: fun_name %s) %s" % (self.fun_name, msg))
        return msg
    #- Fine Metodo -

    def get_input_argument(self):
        return self.fun_name.split("_")[1]
    #- Fine Metodo -

    def _get_message_error_racial_message(self):
        """
        Controlla tutti i messaggi di social razziali
        """
        for racial_message in self.racial_messages.itervalues():
            msg = racial_message.get_error_message()
            if msg:
                return msg
        return ""
    #- Fine Metodo -

    def get_racial_message(self, entity, attr, target=None, possessive="", use_human=True):
        """
        Ricava il messaggio social razziale corretto.
        """
        if not entity:
            log.bug("entity non è un parametro valido: %r" % entity)
            return

        if not attr:
            log.bug("attr non è un parametro valido: %r" % attr)
            return

        if not target and target is not None:
            log.bug("entity non è un parametro valido: %r" % target)
            return

        if possessive not in ("", "mio", "tuo", "suo"):
            log.bug("possessive non è un parametro valido: %r" % possessive)
            return

        # use_human ha valore di verità

        # -------------------------------------------------------------------------

        if entity.race in self.racial_messages:
            message = getattr(self.racial_messages[entity.race], attr)
        elif use_human:
            # I messaggi di social razziali degli umani devono esistere per forza
            message = getattr(self.racial_messages[RACE.HUMAN], attr)
        else:
            return ""

        if target and target.location == entity:
            message = message.replace("$N,", "$N, nel %s inventario," % possessive)
            message = message.replace("$N ", "$N, nel %s inventario, " % possessive)
            message = message.replace("$N.", "$N, nel %s inventario." % possessive)

        return message
    #- Fine Metodo -

    def send_to(self, sender, receiver=None):
        """
        Se receiver non è valido allora invia il social senza argomento.
        """
        # E' possibile che non siano valide per via della defer che
        # chiama questo metodo
        if not sender:
            return
        if not receiver:
            return

        modifier = 0
        if sender.position > POSITION.SLEEP and not is_affected(sender, "charm") and sender.is_original():
            # Modificatore comportamentale per i mob, un valore tra -10 e 10
            if receiver and sender.race in receiver.reputations:
                modifier = receiver.reputations[sender.race] / 10  # (TD)
            if self.intention == INTENTION.FRIENDLY:
                modifier += 5
            elif self.intention == INTENTION.AGGRESSIVE:
                modifier -= 5

        # Caso peggiorativo
        if receiver and modifier <= -10:
            if random.randint(0, 5) == 0:
                interpret(sender, "say a %s Te la sei proprio [red]andata a cercare[close]!" % receiver.get_numbered_keyword(looker=sender))
            start_fight(receiver, sender)
        # Casi non buoni
        elif modifier <= -5 and self.intention == INTENTION.AGGRESSIVE:
            self.send_with_same_intention(sender, receiver)
        # Casi neutrali
        elif -5 < modifier < 5 and self.intention == INTENTION.NEUTRAL:
            # Qui è voluto che capitino casi buffi, come ad esempio se si
            # annuisce potrebbe darsi che di risposti ci si becchi una vomitata.
            # Se si vuole un mud full-rpg forse è bene ritornare al posto di
            # questa riga sottostante
            self.send_with_same_intention(sender, receiver)
        # Casi migliorativi
        elif modifier >= 5 and self.intention == INTENTION.FRIENDLY:
            self.send_with_same_intention(sender, receiver)
    #- Fine Funzione -

    def send_with_same_intention(self, sender, receiver=None):
        """
        Invia un social a caso con la stessa intenzione.
        Se receiver non è valido allora invia il social senza argomento.
        """
        if not sender:
            log.bug("sender non è un parametro valido: %r" % sender)
            return

        # -------------------------------------------------------------------------

        # Il più delle volte invia lo stesso social in questione, altrimenti ne
        # cerca uno con intenzione simile
        if random.randint(0, 5) != 0:
            social_input = self.get_input_argument()
            if receiver:
                receiver_numbered_keyword = receiver.get_numbered_keyword(looker=sender)
                argument = "%s %s" % (social_input, receiver_numbered_keyword)
            else:
                argument = social_input
            interpret(sender, argument)
            return

        # Se il mud è stato appena creato potrebbe non avere ancora i social
        if not database["socials"]:
            return

        # Crea una lista con tutti i social con l'intenzione voluta
        socials = []
        for social in database["socials"].itervalues():
            if social.intention == self.intention:
                socials.append(social)

        # Potrebbe benissimo essere che non esistano ancora abbastanza social
        # per averne uno con quell'intenzione
        if not socials:
            return

        # Invia un social scelto a caso tra quelli voluti
        social = random.choice(socials)
        argument = social.fun_name.split("_")[1]
        if receiver:
            argument += " %s" % receiver.get_numbered_keyword(looker=sender)

        interpret(sender, argument)
Пример #47
0
class Command(Data):
    """
    Gestisce tutte le caratteristiche di un comando.
    Se tra gli attributi cercate quelli che servono per chiamare il comando
    tramite il testo inviato dai giocatori qui non li troverete, per quel
    compito ci pensa la classe Input().
    """
    PRIMARY_KEY = "fun_name"
    VOLATILES = [
        "timer",
        "module",
        "function",
    ]
    MULTILINES = ["mini_help"]
    SCHEMA = {}
    REFERENCES = {}
    WEAKREFS = {}

    def __init__(self, fun_name=""):
        self.comment = ""
        self.fun_name = fun_name or ""  # Nome della funzione
        self.type = Element(CMDTYPE.INFORMATION)  # Tipologia del comando
        self.trust = Element(TRUST.PLAYER)  # Fiducia minima per digitarlo
        self.position = Element(
            POSITION.REST)  # Posizione minima per utilizzarlo
        self.flags = Flags(CMDFLAG.NONE)  # Flag dei comandi
        self.no_races = Flags(
            RACE.NONE
        )  # Razze che NON possono usarlo (RACE.NONE significa che tutti lo possono utilizzare)
        self.mini_help = ""  # Piccola descrizione dell'utilizzo del comando
        self.timer = 0.0  # Tempo totale di esecuzione del comando (anche se nelle pagine d'amministrazione visualizza il tempo medio)

        # Variabili volatili
        self.module = None  # Riferimento al modulo che contiene la funzione
        self.function = None  # Riferimento alla funzione
        if self.fun_name:
            self.import_module_and_function()

    #- Fine Inizializzazione -

    def get_error_message(self):
        """
        Ritorna un messaggio di errore se qualcosa nel comando è sbagliata,
        altrimenti se tutto è a posto ritorna una stringa vuota.
        """
        if not self.fun_name:
            msg = "il nome della funzione non è valido"
        elif (not self.fun_name.startswith("command_")
              and not self.fun_name.startswith("skill_")
              and not self.fun_name.startswith("social_")):
            msg = "il nome della funzione non inizia per command_, skill_ o social_"
        elif self.type.get_error_message(CMDTYPE, "type") != "":
            msg = self.type.get_error_message(CMDTYPE, "type")
        elif self.trust.get_error_message(TRUST, "trust") != "":
            msg = self.trust.get_error_message(TRUST, "trust")
        elif self.position.get_error_message(POSITION, "position") != "":
            msg = self.position.get_error_message(POSITION, "position")
        elif self.flags.get_error_message(CMDFLAG, "flags") != "":
            msg = self.flags.get_error_message(CMDFLAG, "flags")
        elif self.no_races.get_error_message(RACE, "no_races") != "":
            msg = self.no_races.get_error_message(RACE, "no_races")
        # Ignora i minihelp vuoti relativi ai comandi-social
        elif not self.mini_help and not self.fun_name.startswith("social_"):
            msg = "la stringa di mini help è vuota"
        elif self.timer < 0.0:
            msg = "il timer non può essere negativo: %f" % self.timer
        elif not self.module:
            msg = "modulo non importato"
        elif not self.function:
            msg = "funzione non importata"
        else:
            return ""
        # Se arriva qui significa che ha un messaggio da inviare
        log.bug("(Command: fun_name %s) %s" % (self.fun_name, msg))
        return msg

    #- Fine Metodo -

    def get_total_use_count(self):
        """
        Ritorna l'utilizzo totale della funzione di comando tra tutti gli input.
        """
        total_use_count = 0

        for inputs_name, inputs in yield_inputs_items():
            for input in inputs:
                if input.command == self:
                    total_use_count += input.counter_use

        return total_use_count

    #- Fine Metodo -

    def import_module_and_function(self):
        """
        Importa il modulo che contiene la funzione del comando.
        """
        if self.fun_name.startswith("command_"): package = "src.commands."
        elif self.fun_name.startswith("skill_"): package = "src.skills."
        elif self.fun_name.startswith("social_"): package = "src.socials."
        else:
            log.bug("la fun_name del comando è errata: %s" % self.fun_name)
            return None

        import_path = package + self.fun_name
        self.module = __import__(import_path, globals(), locals(), [""])
        self.function = getattr(self.module, self.fun_name)
Пример #48
0
class Exit(Describable):
    """
    Gestisce una singola uscita di una stanza.
    """
    PRIMARY_KEY = "direction"
    VOLATILES   = []
    MULTILINES  = ["comment"]
    SCHEMA      = {"extras"      : ("src.extra", "ExtraDescription"),
                   "height"      : ("",          "measure"),
                   "depth"       : ("",          "measure"),
                   "destination" : ("src.room",  "Destination")}
    REFERENCES  = {}
    WEAKREFS    = {}

    IS_AREA   = False
    IS_DESCR  = True
    IS_ROOM   = False
    IS_EXIT   = True
    IS_WALL   = False
    IS_ACTOR  = False
    IS_MOB    = False
    IS_ITEM   = False
    IS_PLAYER = False
    IS_EXTRA  = False
    IS_PROTO  = False

    def __init__(self, direction=DIR.NONE):
        if not direction:
            log.bug("direction non è un parametro valido: %r" % direction)
            return

        # ---------------------------------------------------------------------

        self.comment             = ""  # Eventuale commento all'uscita
        self.direction           = Element(direction)  # Tipologia della direzione
        self.descr               = ""  # Descrizione di quello che si vede guardando la direzione
        self.descr_night         = ""  # Descrizione notturna di quello che si vede guardando la direzione
        self.descr_hearing       = ""  # Descrizione uditiva
        self.descr_hearing_night = ""  # Descrizione uditiva notturna
        self.descr_smell         = ""  # Descrizione odorosa
        self.descr_smell_night   = ""  # Descrizione odorosa notturna
        self.descr_touch         = ""  # Descrizione tattile
        self.descr_touch_night   = ""  # Descrizione tattile notturna
        self.descr_taste         = ""  # Descrizione del sapore
        self.descr_taste_night   = ""  # Descrizione del sapore notturna
        self.descr_sixth         = ""  # Descrizione del sesto senso
        self.descr_sixth_night   = ""  # Descrizione del sesto senso notturna
        self.icon                = ""  # Icona rappresentante l'uscita di giorno
        self.icon_night          = ""  # Icona rappresentante l'uscita di notte
        self.extras              = Extras()  # Descrizioni extra dell'uscita
        self.flags               = Flags(EXIT.NONE)  # Flags dell'uscita
        self.destination         = None # Stanza a cui l'uscita porta se questa differente rispetto alla direzione presa
        self.door                = None # Oggetto porta se serve aprirla (se non viene indicata questa viene caricata dal limbo una porta di default)  (TD) qui vorrei aggiungere anche una variabile finestra.. ma poi come gestire finestre e porte multiple? e il key_code nel qual caso una finestra sia chiudibile (cmq per ora continuo così.. in effetti potrei considerare il fatto di voler inserire più porte o finestre in una uscita come una eccezione e gestirla tramite gamescripts)
        self.entity_message      = ""   # Messaggio di movimento per colui che si sta spostando
        self.others_in_message   = ""   # Messaggio di movimento per gli altri della stanza di partenza
        self.others_out_message  = ""   # Messaggio di movimento per gli altri della stanza di arrivo
    #- Fine Inizializzazione -

    def get_error_message(self):
        """
        Se c'è un errore nell'uscita ne ritorna il messaggio appropriato.
        """
        if self.direction.get_error_message(DIR, "direction", allow_none=False) != "":
            msg = self.direction.get_error_message(DIR, "direction", allow_none=False)
        elif self.flags.get_error_message(EXIT, "flags") != "":
            msg = self.flags.get_error_message(EXIT, "flags")
#        elif (self.door and self.door.code not in database["items"]
#        and   self.door and self.door.code not in database["mobs"]):
#            msg = "door dell'uscita non è un oggetto valido: %s" % self.door.code
        elif self.destination and self.destination.get_error_message() != "":
            msg = self.destination.get_error_message()
        elif self.extras.get_error_message():
            msg = self.extras.get_error_message()
        else:
            return ""

        return "(exit %r): %s" % (self.direction, msg)
    #- Fine Metodo -

    def copy(self, to_obj=None, avoid_volatiles=False):
        if not to_obj:
            to_obj = Exit()
        copy_existing_attributes(self, to_obj, avoid_volatiles=avoid_volatiles)
        return to_obj
    #- Fine Metodo -

    def equals(self, exit2):
        # Non dovrebbe servire implementarli, ma inserisco questo "avviso" al caso
        raise NotImplementedError
    #- Fine Metodo -

    # -------------------------------------------------------------------------

    def get_icon(self, room=None):
        if room:
            door = room.get_door(self.direction)
        else:
            door = None

        icon = ""
        if door and door.door_type and DOOR.CLOSED in door.door_type.flags and DOOR.SECRET not in door.door_type.flags:
            # L'icone dell'entità porta è intesa come chiusa
            icon = door.get_icon()
            if not icon:
                icon = "icons/door/default-door.png"
        elif door and door.door_type and DOOR.CLOSED not in door.door_type.flags:
            # Icona della porta aperta
            icon = door.door_type.get_icon()
            if not icon:
                icon = "icons/door/default-door-open.png"
        elif not door or (door.door_type and DOOR.SECRET not in door.door_type.flags):
            if calendar.is_night() and self.icon_night:
                # icona dell'uscita di notte
                icon = self.icon_night
            elif self.icon:
                # icona dell'uscita di giorno
                icon = self.icon

        # Inserisce di default dei simboli di una rosa dei venti
        if not icon:
            icon = "icons/compass/%s.png" % repr(self.direction).split(".")[1].lower()

        return icon
    #- Fine Metodo -

    def get_descr(self, type="", looker=None):
        """
        Ritorna la descrizione dell'uscita.
        """
        if type:
            type = "_" + type

        descr = ""
        if calendar.is_night():
            descr = getattr(self, "descr%s_night" % type)
        if not descr:
            descr = getattr(self, "descr%s" % type)

        # Normale che possa accadere per qualsiasi tipologia di descrizione
        if not descr:
            return ""

        if self.ASCIIART_TAG_OPEN in descr:
            descr = self.convert_asciiart_linefeeds(descr)
        else:
            descr = put_final_dot(descr)

        if ".\n" in descr:
            descr = descr.replace(".\n", ".<br>")
        if "!\n" in descr:
            descr = descr.replace("!\n", "!<br>")
        if "?\n" in descr:
            descr = descr.replace("?\n", "?<br>")
        if "\n" in descr:
            descr = descr.replace("\n", " ")

        return descr
Пример #49
0
class Sellable(object):
    """
    Classe che gestisce le differenti tipologie di entità vendute e comprate
    dal negoziante.
    """
    PRIMARY_KEY = ""
    VOLATILES = []
    MULTILINES = []
    SCHEMA = {"percent": ("", "percent"), "buyback_percent": ("", "percent")}
    REFERENCES = {}
    WEAKREFS = {}

    def __init__(self):
        self.entitype = Element(
            ENTITYPE.NONE
        )  # Tipologia di entità che possono essere venduta al negoziante
        self.percent = 50  # Percentuale sul costo per le entità vendute al negoziante
        self.buyback_percent = 100  # Percentuale sul costo per le entità comprate dal negoziante e precedentemente vendutegli

    #- Fine Metodo -

    def get_error_message(self):
        if self.entitype.get_error_message(ENTITYPE, "entitype") != "":
            return self.entitypes.get_error_message(ENTITYPE, "entitype")
        elif self.buyback_percent < 10 and self.buyback_percent > 1000:
            return "buyback_percent dev'essere un valore tra 10 e 1000: %d" % self.buyback_percent
        elif self.percent < 10 and self.percent > 1000:
            return "percent dev'essere un valore tra 10 e 1000: %d" % self.percent

        return ""

    #- Fine Metodo -

    def copy(self, to_obj=None, avoid_volatiles=False):
        if not to_obj:
            to_obj = Sellable()
        copy_existing_attributes(self, to_obj, avoid_volatiles=avoid_volatiles)
        return to_obj

    #- Fine Metodo -

    def equals(self, sellable2):
        if not sellable2:
            return False

        if self.entitype != sellable2.entitype:
            return False
        if self.percent != sellable2.percent:
            return False
        if self.buyback_percent != sellable2.buyback_percent:
            return False

        return True

    #- Fine Metodo -

    def fread_the_line(self, file, line, attr):
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not line:
            log.bug("line non è un parametro valido: %r" % line)
            return

        if not attr:
            log.bug("attr non è un parametro valido: %r" % attr)
            return

        # ---------------------------------------------------------------------

        try:
            entitype, percent, buyback_percent = line.split(None, 2)
        except ValueError:
            log.bug(
                "Errore nella lettura di un Sellable nel file <%s> per la linea <%s> e l'attributo <%s>"
                % (file.name, line, attr))
            return

        self.entitype = Element(entitype)
        self.percent = fread_percent(file, percent, attr)
        self.buyback_percent = fread_percent(file, buyback_percent, attr)

    #- Fine Metodo -

    def fwrite_the_line(self, file, label, indentation=""):
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not label:
            log.bug("label non è un parametro valido: %r" % label)
            return

        # -------------------------------------------------------------------------

        file.write("%s%s %r %d%% %d%%\n" %
                   (indentation, label, self.entitype, self.percent,
                    self.buyback_percent))
Пример #50
0
class Command(Data):
    """
    Gestisce tutte le caratteristiche di un comando.
    Se tra gli attributi cercate quelli che servono per chiamare il comando
    tramite il testo inviato dai giocatori qui non li troverete, per quel
    compito ci pensa la classe Input().
    """
    PRIMARY_KEY = "fun_name"
    VOLATILES   = ["timer",    "module", "function",]
    MULTILINES  = ["mini_help"]
    SCHEMA      = {}
    REFERENCES  = {}
    WEAKREFS    = {}

    def __init__(self, fun_name=""):
        self.comment   = ""
        self.fun_name  = fun_name or ""  # Nome della funzione
        self.type      = Element(CMDTYPE.INFORMATION) # Tipologia del comando
        self.trust     = Element(TRUST.PLAYER)  # Fiducia minima per digitarlo
        self.position  = Element(POSITION.REST)  # Posizione minima per utilizzarlo
        self.flags     = Flags(CMDFLAG.NONE)  # Flag dei comandi
        self.no_races  = Flags(RACE.NONE)  # Razze che NON possono usarlo (RACE.NONE significa che tutti lo possono utilizzare)
        self.mini_help = ""   # Piccola descrizione dell'utilizzo del comando
        self.timer     = 0.0  # Tempo totale di esecuzione del comando (anche se nelle pagine d'amministrazione visualizza il tempo medio)

        # Variabili volatili
        self.module    = None  # Riferimento al modulo che contiene la funzione
        self.function  = None  # Riferimento alla funzione
        if self.fun_name:
            self.import_module_and_function()
    #- Fine Inizializzazione -

    def get_error_message(self):
        """
        Ritorna un messaggio di errore se qualcosa nel comando è sbagliata,
        altrimenti se tutto è a posto ritorna una stringa vuota.
        """
        if not self.fun_name:
            msg = "il nome della funzione non è valido"
        elif (not self.fun_name.startswith("command_")
        and   not self.fun_name.startswith("skill_")
        and   not self.fun_name.startswith("social_")):
            msg = "il nome della funzione non inizia per command_, skill_ o social_"
        elif self.type.get_error_message(CMDTYPE, "type") != "":
            msg = self.type.get_error_message(CMDTYPE, "type")
        elif self.trust.get_error_message(TRUST, "trust") != "":
            msg = self.trust.get_error_message(TRUST, "trust")
        elif self.position.get_error_message(POSITION, "position") != "":
            msg = self.position.get_error_message(POSITION, "position")
        elif self.flags.get_error_message(CMDFLAG, "flags") != "":
            msg = self.flags.get_error_message(CMDFLAG, "flags")
        elif self.no_races.get_error_message(RACE, "no_races") != "":
            msg = self.no_races.get_error_message(RACE, "no_races")
        # Ignora i minihelp vuoti relativi ai comandi-social
        elif not self.mini_help and not self.fun_name.startswith("social_"):
            msg = "la stringa di mini help è vuota"
        elif self.timer < 0.0:
            msg = "il timer non può essere negativo: %f" % self.timer
        elif not self.module:
            msg = "modulo non importato"
        elif not self.function:
            msg = "funzione non importata"
        else:
            return ""
        # Se arriva qui significa che ha un messaggio da inviare
        log.bug("(Command: fun_name %s) %s" % (self.fun_name, msg))
        return msg
    #- Fine Metodo -

    def get_total_use_count(self):
        """
        Ritorna l'utilizzo totale della funzione di comando tra tutti gli input.
        """
        total_use_count = 0

        for inputs_name, inputs in yield_inputs_items():
            for input in inputs:
                if input.command == self:
                    total_use_count += input.counter_use

        return total_use_count
    #- Fine Metodo -

    def import_module_and_function(self):
        """
        Importa il modulo che contiene la funzione del comando.
        """
        if   self.fun_name.startswith("command_"):  package = "src.commands."
        elif self.fun_name.startswith("skill_"):    package = "src.skills."
        elif self.fun_name.startswith("social_"):   package = "src.socials."
        else:
            log.bug("la fun_name del comando è errata: %s" % self.fun_name)
            return None

        import_path = package + self.fun_name
        self.module = __import__(import_path, globals(), locals(), [""])
        self.function = getattr(self.module, self.fun_name)
Пример #51
0
class Sellable(object):
    """
    Classe che gestisce le differenti tipologie di entità vendute e comprate
    dal negoziante.
    """
    PRIMARY_KEY = ""
    VOLATILES   = []
    MULTILINES  = []
    SCHEMA      = {"percent"         : ("", "percent"),
                   "buyback_percent" : ("", "percent")}
    REFERENCES  = {}
    WEAKREFS    = {}

    def __init__(self):
        self.entitype        = Element(ENTITYPE.NONE)  # Tipologia di entità che possono essere venduta al negoziante
        self.percent         =  50 # Percentuale sul costo per le entità vendute al negoziante
        self.buyback_percent = 100 # Percentuale sul costo per le entità comprate dal negoziante e precedentemente vendutegli
    #- Fine Metodo -

    def get_error_message(self):
        if self.entitype.get_error_message(ENTITYPE, "entitype") != "":
            return self.entitypes.get_error_message(ENTITYPE, "entitype")
        elif self.buyback_percent < 10 and self.buyback_percent > 1000:
            return "buyback_percent dev'essere un valore tra 10 e 1000: %d" % self.buyback_percent
        elif self.percent < 10 and self.percent > 1000:
            return "percent dev'essere un valore tra 10 e 1000: %d" % self.percent

        return ""
    #- Fine Metodo -

    def copy(self, to_obj=None, avoid_volatiles=False):
        if not to_obj:
            to_obj = Sellable()
        copy_existing_attributes(self, to_obj, avoid_volatiles=avoid_volatiles)
        return to_obj
    #- Fine Metodo -

    def equals(self, sellable2):
        if not sellable2:
            return False

        if self.entitype != sellable2.entitype:
            return False
        if self.percent != sellable2.percent:
            return False
        if self.buyback_percent != sellable2.buyback_percent:
            return False

        return True
    #- Fine Metodo -

    def fread_the_line(self, file, line, attr):
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not line:
            log.bug("line non è un parametro valido: %r" % line)
            return

        if not attr:
            log.bug("attr non è un parametro valido: %r" % attr)
            return

        # ---------------------------------------------------------------------

        try:
            entitype, percent, buyback_percent = line.split(None, 2)
        except ValueError:
            log.bug("Errore nella lettura di un Sellable nel file <%s> per la linea <%s> e l'attributo <%s>" % (
                file.name, line, attr))
            return

        self.entitype        = Element(entitype)
        self.percent         = fread_percent(file, percent, attr)
        self.buyback_percent = fread_percent(file, buyback_percent, attr)
    #- Fine Metodo -

    def fwrite_the_line(self, file, label, indentation=""):
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not label:
            log.bug("label non è un parametro valido: %r" % label)
            return

        # -------------------------------------------------------------------------

        file.write("%s%s %r %d%% %d%%\n" % (indentation, label, self.entitype, self.percent, self.buyback_percent))
Пример #52
0
class MaterialPercentage(object):
    PRIMARY_KEY = ""
    VOLATILES   = []
    MULTILINES  = []
    SCHEMA      = {}
    REFERENCES  = {}
    WEAKREFS    = {}

    def __init__(self):
        self.material = Element(MATERIAL.NONE)
        self.percent  = 0
    #- Fine Inizializzazione -

    def __repr__(self):
        return "%s %s %s%%" % (super(MaterialPercentage, self).__repr__(), self.material, self.percent)
    #- Fine Metodo -

    def copy(self, to_obj=None, avoid_volatiles=False):
        if not to_obj:
            to_obj = MaterialPercentage()
        copy_existing_attributes(self, to_obj, avoid_volatiles=avoid_volatiles)
        return to_obj
    #- Fine Funzione -

    def equals(self, material2):
        if not material2:
            return False

        if self.material != material2.material:
            return False

        if self.percent != material2.percent:
            return False

        return True
    #- Fine Metodo -

    def get_error_message(self):
        if self.material.get_error_message(MATERIAL, "material", allow_none=False) != "":
            return self.material.get_error_message(MATERIAL, "material", allow_none=False)
        elif self.percent < 1 or self.percent > 100:
            return "percent dev'essere tra 1 e 100 e non %d" % self.percent

        return ""
    #- Fine Metodo -

    def fread_the_line(self, file, line, attr):
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not line:
            log.bug("line non è un parametro valido: %r" % line)
            return

        if not attr:
            log.bug("attr non è un parametro valido: %r" % attr)
            return

        # ---------------------------------------------------------------------

        if "," in line:
            material, percent = line.split(",", 1)
        else:
            material, percent = line.split(None, 1)

        material = material.strip()
        percent = percent.strip()

        self.material = Element(material)
        self.percent = fread_percent(file, percent, attr)
    #- Fine Metodo -

    def fwrite_the_line(self, file, label, indentation=""):
        """
        Scrive su file un elemento sinonimo.
        """
        if not file:
            log.bug("file non è un parametro valido: %r" % file)
            return

        if not label:
            log.bug("label non è un parametro valido: %r" % label)
            return

        # -------------------------------------------------------------------------

        file.write("%s%s%s %s%%\n" % (indentation, label, self.material.code, self.percent))
Пример #53
0
class Readable(object):
    PRIMARY_KEY = ""
    VOLATILES   = []
    MULTILINES  = ["comment", "pages", "summary"]
    SCHEMA      = {"visual_width"  : ("", "css_measure"),
                   "visual_height" : ("", "css_measure"),
                   "padding"       : ("", "css_measure"),
                   "border_top"    : ("", "css_border"),
                   "border_right"  : ("", "css_border"),
                   "border_bottom" : ("", "css_border"),
                   "border_left"   : ("", "css_border"),
                   "border_inside" : ("", "css_border"),
                   "pages"         : ("", "str")}
    REFERENCES  = {}
    WEAKREFS    = {}

    def __init__(self):
        self.comment       = ""  # Commento per gli area builder relativo all'entità leggibile
        self.title         = ""  # Titolo del libro
        self.author        = ""  # Autore o gli autori di questo libro
        self.summary       = ""  # Riassunto del libro che il giocatore carpisce esaminandolo
        self.language      = Element(LANGUAGE.COMMON) # (TD) Lingua di questo libro
        self.flags         = Flags(READABLE.NONE)  # Flag relative alle entità leggibili
        self.visual_width  = ""  # Larghezza in pixel del libro sullo schermo
        self.visual_height = ""  # Larghezza in pixel del libro sullo schermo
        self.padding       = ""  # Larghezza in pixel del padding della cornice del libro
        self.border_top    = ""  # Bordo css decorante il libro in alto
        self.border_right  = ""  # Bordo css decorante il libro a destra
        self.border_bottom = ""  # Bordo css decorante il libro in basso
        self.border_left   = ""  # Bordo css decorante il libro a sinistra
        self.border_inside = ""  # Bordo css decorante il libro tra le due pagine
        self.number_decoration_left  = ""  # Decorazione della pagina sinistra per i numeri di pagina
        self.number_decoration_right = ""  # Decorazione della pagina sinistra per i numeri di pagina
        self.pages         = []  # Lista delle pagine e relativo contenuto
    #- Fine Inizializzazione -

    def get_error_message(self, entity):
        if not self.title:
            return "title è una stringa non valida: %r" % self.title
        elif not self.author:
            return "author è una stringa non valida: %r" % self.author
        elif not self.summary:
            return "summary è una stringa non valida: %r" % self.summary
        elif self.language.get_error_message(LANGUAGE, "language") != "":
            return self.language.get_error_message(LANGUAGE, "language")
        elif self.flags.get_error_message(READABLE, "flags") != "":
            return self.flags.get_error_message(READABLE, "flags")
        elif READABLE.CENTER in self.flags and READABLE.RIGHT in self.flags:
            return "Non possono convivere le flag READABLE.CENTER e READABLE.RIGHT assieme."
        elif (self.number_decoration_left or self.number_decoration_right) and READABLE.NUMBERS not  in self.flags:
            return "Nonostante sia stata definita una decorazione per i numeri non esiste la flag READABLE.NUMBERS che la mostrerebbe."
        elif not self.visual_width:
            return "visual_width è una stringa non valida: %r" % self.visual_width
        elif not self.visual_height:
            return "visual_height è una stringa non valida: %r" % self.visual_height
        elif not self.pages:
            return "dev'esservi almeno una pagina: %r" % self.pages

        return ""
    #- Fine Metodo -

    def copy(self, to_obj=None, avoid_volatiles=False):
        if not to_obj:
            to_obj = Readable()
        copy_existing_attributes(self, to_obj, avoid_volatiles=avoid_volatiles)
        return to_obj
    #- Fine Metodo -

    def equals(self, readable2):
        if not readable2:
            return False

        if self.comment != readable2.comment:
            return False
        if self.title != readable2.title:
            return False
        if self.author != readable2.author:
            return False
        if self.summary != readable2.summary:
            return False
        if self.language != readable2.language:
            return False
        if self.flags != readable2.flags:
            return False
        if self.visual_width != readable2.visual_width:
            return False
        if self.visual_height != readable2.visual_height:
            return False
        if self.padding != readable2.padding:
            return False
        if self.border_top != readable2.border_top:
            return False
        if self.border_right != readable2.border_right:
            return False
        if self.border_bottom != readable2.border_bottom:
            return False
        if self.border_left != readable2.border_left:
            return False
        if self.border_inside != readable2.border_inside:
            return False
        if self.number_decoration_left != readable2.number_decoration_left:
            return False
        if self.number_decoration_right != readable2.number_decoration_right:
            return False

        if len(self.pages) != len(readable2.pages):
            return False
        for page in self.pages:
            for page2 in readable2.pages:
                if page == page2:
                    break
            else:
                return False

        return True
    #- Fine Metodo -

    # -------------------------------------------------------------------------

    # (TD) entity e target serviranno in futuro per scramblerare la lingua del
    # libro se sconosciuta
    def get_pages(self, entity, target, page_number, from_location=None):
        if not entity:
            log.bug("entity non è un parametro valido: %r" % entity)
            return ""

        if not target:
            log.bug("target non è un parametro valido: %r" % target)
            return ""

        if page_number < 0 or page_number >= len(self.pages):
            log.bug("page_number non è un parametro valido: %r" % page_number)
            return ""

        # ---------------------------------------------------------------------

        # Prepara i bordi
        border_top    = ""
        border_right  = ""
        border_bottom = ""
        border_left   = ""
        border_inside = ""
        if self.border_top:
            border_top    = "border-top:%s;"    % self.border_top
        if self.border_right:
            border_right  = "border-right:%s;"  % self.border_right
        if self.border_bottom:
            border_bottom = "border-bottom:%s;" % self.border_bottom
        if self.border_left:
            border_left   = "border-left:%s;"   % self.border_left
        if self.border_inside:
            border_inside  = "border-right:%s;" % self.border_inside

        # Prepara il padding se esistente
        padding_style = ""
        if self.padding:
            padding_style = "padding:%s;" % self.padding

        # Prepara lo style css per l'output scritto della pagina
        alignment = ""
        if READABLE.CENTER in self.flags:
            alignment = '''text-align:center;'''
        if READABLE.RIGHT in self.flags:
            alignment = '''text-align:right;'''
        visual_style = ''' style="min-width:%s; max-width:%s; min-height:%s; max-height:%s; %s %s"''' % (
            self.visual_width, self.visual_width, self.visual_height, self.visual_height, padding_style, alignment)

        # Ricava informazioni che servono a sfogliare il libro tramite click
        translated_input = translate_input(entity, "read", "en")
        if not translated_input:
            log.bug("Non è stato possibile tradurre l'input read per %s: %r" % (target.code, translated_input))
            return False
        numbered_keyword = target.get_numbered_keyword(looker=entity)
        if page_number % 2 == 0 and page_number != len(self.pages)-1:
            minimum_page = max([0, page_number-2])
            maximum_page = min([len(self.pages)-1, page_number+1])
        else:
            minimum_page = max([0, page_number-1])
            maximum_page = min([len(self.pages)-1, page_number+2])
        if from_location:
            js_minimum_arguments = "%s %s %s %d" % (translated_input, numbered_keyword, from_location.get_numbered_keyword(looker=entity), minimum_page)
            js_maximum_arguments = "%s %s %s %d" % (translated_input, numbered_keyword, from_location.get_numbered_keyword(looker=entity), maximum_page)
        else:
            js_minimum_arguments = "%s %s %d" % (translated_input, numbered_keyword, minimum_page)
            js_maximum_arguments = "%s %s %d" % (translated_input, numbered_keyword, maximum_page)
        browse_to_left  = '''<div style="float:left"><a href="javascript:sendInput('%s')" style="font-size:larger">&lt;</a> </div>''' % js_minimum_arguments
        browse_to_right = '''<div style="float:left"> <a href="javascript:sendInput('%s')" style="font-size:larger">&gt;</a></div>''' % js_maximum_arguments

        # Gestisce la copertina e la retrocopertina o altre tipologie di entità
        # leggibili differenti da dei libri, ovvero con al massimo il fronte
        # e il retro
        if page_number == 0 or page_number == len(self.pages) - 1:
            style = ""
            if border_top or border_right or border_bottom or border_left:
                style = ''' style="float:left; %s%s%s%s"''' % (border_top, border_right, border_bottom, border_left)
            output = ""
            if page_number == len(self.pages) - 1:
                output += browse_to_left
            output += '''<div%s><div%s>%s</div></div>''' % (style, visual_style, self.pages[page_number])
            if page_number == 0:
                output += browse_to_right
            output += '''<div style="clear:both;" />'''
            return output

        # A seconda che si voglia visualizzare una pagina a destra o a sinistra
        # sceglie il numero corretto di pagina da far visualizzare nell'altra
        if page_number % 2 == 0:
            left_page_number  = page_number - 1
            right_page_number = page_number
        else:
            left_page_number  = page_number
            right_page_number = page_number + 1

        # Prepara lo stile dei bordi preparati in precedenza, se ve n'erano
        left_style  = '''style="float:left;%s%s%s%s"''' % (border_top, border_inside, border_bottom, border_left)
        right_style = '''style="float:left;%s%s%s"'''   % (border_top, border_right,  border_bottom)

        # Prepara il contenuto scritto delle pagine aggiungendo una pagina
        # vuota prima della retrocopertina se necessario
        left_output  = self.pages[left_page_number]
        if len(self.pages) % 2 == 0 and page_number == len(self.pages) - 1:
            right_output = ""
        elif len(self.pages) % 2 == 1 and page_number == len(self.pages) - 2:
            right_output = ""
        else:
            right_output = self.pages[right_page_number]
        if MIML_SEPARATOR in left_output:
            left_output = target.parse_miml(left_output, looker=entity)
        if MIML_SEPARATOR in right_output:
            right_output = target.parse_miml(right_output, looker=entity)

        # Prepara l'output per i numeri di pagina
        left_page_number_output  = ""
        right_page_number_output = ""
        if READABLE.NUMBERS in self.flags:
            if len(self.number_decoration_left) == 0:
                left_page_number_output  = '''<center>%d</center>''' % left_page_number
            elif len(self.number_decoration_left) == 1:
                left_page_number_output  = '''<center>%s%d</center>''' % (self.number_decoration_left, left_page_number)
            else:
                middle = int(math.ceil(len(self.number_decoration_left) / 2.0))
                left_page_number_output  = '''<center>%s%d%s</center>''' % (self.number_decoration_left[ : middle],  left_page_number,  self.number_decoration_left[middle : ])
            if len(self.number_decoration_right) == 0:
                right_page_number_output  = '''<center>%d</center>''' % right_page_number
            elif len(self.number_decoration_right) == 1:
                right_page_number_output = '''<center>%d%s</center>''' % (right_page_number, self.number_decoration_right)
            else:
                middle = int(math.floor(len(self.number_decoration_left) / 2.0))
                right_page_number_output = '''<center>%s%d%s</center>''' % (self.number_decoration_right[ : middle], right_page_number, self.number_decoration_right[middle : ])

        # Ecco l'output del libro in tutto il suo splendore
        output  = browse_to_left
        output += '''<div %s><div%s>%s</div>%s</div>''' % (left_style,  visual_style, left_output,  left_page_number_output)
        output += '''<div %s><div%s>%s</div>%s</div>''' % (right_style, visual_style, right_output, right_page_number_output)
        output += browse_to_right
        output += '''<div style="clear:both;" />'''

        return output
Пример #54
0
    def parse_miml_check(self, check, looker=None):
        if not check:
            log.bug("check non è un parametro valido: %r" % check)
            return False

        # ---------------------------------------------------------------------

        check_parts = check.split()

        if check_parts[0][0:4] == "self":
            check_entity = self
        elif check_parts[0][0:8] == "location":
            if self.IS_ROOM:
                check_entity = self
            else:
                check_entity = self.location
        elif check_parts[0][0:17] == "previous_location":
            if self.IS_ROOM:
                check_entity = self
            else:
                check_entity = self.previous_location
        elif check_parts[0][0:6] == "looker":
            if not looker:
                log.bug(
                    "looker non valido (%r) anche se il check lo necessita: %s"
                    % (looker, check))
                return False
            check_entity = looker
        elif check_parts[0][0:6] == "season":
            if check_parts[1] == "is":
                if calendar.season == Element(check_parts[2]):
                    return True
                else:
                    return False
            elif check_parts[1] == "is not":
                if calendar.season != Element(check_parts[2]):
                    return True
                else:
                    return False
            else:
                log.bug(
                    "Operatore di check sconosciuto: %s per l'elemento con codice %s"
                    % (check_parts[1], check_parts[2]))
                return False
        else:
            log.bug("entità da utilizzare per i check è sconosciuta: %s" %
                    check_parts[0])
            return False

        # (TD) no, dovrò splittare con or o and ed utilizzare le builtin any o all
        #for element_code in check_parts[2].split("|"):
        #    pass

        # Miml relativo alla razza dell'entità controllata
        if check_parts[2][0:5] == "RACE.":
            if check_entity.IS_ROOM:
                return False

            if check_parts[1] == "is":
                if check_entity.race == Element(check_parts[2]):
                    return True
                else:
                    return False
            elif check_parts[1] == "is not":
                if check_entity.race != Element(check_parts[2]):
                    return True
                else:
                    return False
            else:
                log.bug(
                    "Operatore di check sconosciuto: %s per l'elemento con codice %s"
                    % (check_parts[1], check_parts[2]))
                return False
        # Miml relativo alla sessualità dell'entità controllata
        elif check_parts[2][0:4] == "SEX.":
            if check_entity.IS_ROOM:
                return False

            if check_parts[1] == "is":
                if check_entity.sex == Element(check_parts[2]):
                    return True
                else:
                    return False
            elif check_parts[1] == "is not":
                if check_entity.sex != Element(check_parts[2]):
                    return True
                else:
                    return False
            else:
                log.bug(
                    "Operatore di check sconosciuto: %s per l'elemento con codice %s"
                    % (check_parts[1], check_parts[2]))
                return False
        # Miml relativo ai contenitori
        elif check_parts[2][0:10] == "CONTAINER.":
            if check_entity.IS_ROOM or not check_entity.container_type:
                return False

            if check_parts[1] == "is":
                if Element(
                        check_parts[2]) in check_entity.container_type.flags:
                    return True
                else:
                    return False
            elif check_parts[1] == "is not":
                if Element(check_parts[2]
                           ) not in check_entity.container_type.flags:
                    return True
                else:
                    return False
            else:
                log.bug(
                    "Operatore di check sconosciuto: %s per l'elemento con codice %s"
                    % (check_parts[1], check_parts[2]))
                return False
        # Miml relativo al settore di una stanza
        elif check_parts[2][0:7] == "SECTOR.":
            if not check_entity.IS_ROOM:
                return False

            if check_parts[1] == "is":
                if check_entity.sector == Element(check_parts[2]):
                    return True
                else:
                    return False
            elif check_parts[1] == "is not":
                if check_entity.sector != Element(check_parts[2]):
                    return True
                else:
                    return False
            else:
                log.bug(
                    "Operatore di check sconosciuto: %s per l'elemento con codice %s"
                    % (check_parts[1], check_parts[2]))
                return False
        # Miml relativo alle flags di una stanza
        elif check_parts[2][0:5] == "ROOM.":
            if not check_entity.IS_ROOM:
                return False

            if check_parts[1] == "is":
                if Element(check_parts[2]) in check_entity.flags:
                    return True
                else:
                    return False
            elif check_parts[1] == "is not":
                if Element(check_parts[2]) not in check_entity.flags:
                    return True
                else:
                    return False
            else:
                log.bug(
                    "Operatore di check sconosciuto: %s per l'elemento con codice %s"
                    % (check_parts[1], check_parts[2]))
                return False
        # Miml relativo all'inventario portato
        elif check_parts[0][-14:] == ".inventory_qty":
            check_qty = 0
            if is_number(check_parts[2]):
                check_qty = int(check_parts[2])
            else:
                log.bug(
                    "la parte destra dell'opeartore del check miml %s non è un numbero valido"
                    % (check))

            qty = 0
            for content in check_entity.iter_contains():
                if len(content.wear_mode
                       ) == 0 and FLAG.INGESTED not in content.flags:
                    qty += 1

            if check_parts[1] == "==" and qty == check_qty:
                return True
            elif check_parts[1] == "!=" and qty != check_qty:
                return True
            elif check_parts[1] == ">" and qty > check_qty:
                return True
            elif check_parts[1] == ">=" and qty >= check_qty:
                return True
            elif check_parts[1] == "<" and qty < check_qty:
                return True
            elif check_parts[1] == "<=" and qty <= check_qty:
                return True
            else:
                return False
        # Miml relativo all'equipaggiamento portato
        elif check_parts[0][-14:] == ".equipment_qty":
            check_qty = 0
            if is_number(check_parts[2]):
                check_qty = int(check_parts[2])
            else:
                log.bug(
                    "la parte destra dell'opeartore del check miml %s non è un numbero valido"
                    % check)

            qty = 0
            for content in check_entity.iter_contains():
                if len(content.wear_mode
                       ) != 0 and FLAG.INGESTED not in content.flags:
                    qty += 1

            if check_parts[1] == "==" and qty == check_qty:
                return True
            elif check_parts[1] == "!=" and qty != check_qty:
                return True
            elif check_parts[1] == ">" and qty > check_qty:
                return True
            elif check_parts[1] == ">=" and qty >= check_qty:
                return True
            elif check_parts[1] == "<" and qty < check_qty:
                return True
            elif check_parts[1] == "<=" and qty <= check_qty:
                return True
            else:
                return False
        # Miml relativo alle exits, wall e direzioni
        elif get_direction_miml(check_parts[0]) != DIR.NONE:
            if not check_entity.IS_ROOM:
                return False

            direction = get_direction_miml(check_parts[0])
            if direction in check_entity.exits:
                if check_parts[1] == "is":
                    if check_parts[2] == "Exit":
                        return True
                    elif check_parts[2] == "Wall":
                        # Il check qui ci vuole comunque perché una direzione può
                        # avere sia uscita che muro, idem per il ramo 'is not'
                        if direction in check_entity.walls:
                            return True
                        else:
                            return False
                    elif check_parts[2] == "Door":
                        if check_entity.exits[
                                direction].door and check_entity.exits[
                                    direction].door.door_type:
                            return True
                        else:
                            return False
                    elif check_parts[2][:5] == "EXIT.":
                        if Element(check_parts[2]
                                   ) in check_entity.exits[direction].flags:
                            return True
                        else:
                            return False
                    elif check_parts[2][:5] == "DOOR.":
                        if check_entity.exits[
                                direction].door and check_entity.exits[
                                    direction].door.door_type and Element(
                                        check_parts[2]) in check_entity.exits[
                                            direction].door.door_type.flags:
                            return True
                        else:
                            return False
                elif check_parts[1] == "is not":
                    if check_parts[2] == "Exit":
                        return False
                    elif check_parts[2] == "Wall":
                        if direction in check_entity.walls:
                            return False
                        else:
                            return True
                    elif check_parts[2] == "Door":
                        if check_entity.exits[
                                direction].door and check_entity.exits[
                                    direction].door.door_type:
                            return False
                        else:
                            return True
                    elif check_parts[2][:5] == "EXIT.":
                        if Element(check_parts[2]
                                   ) in check_entity.exits[direction].flags:
                            return False
                        else:
                            return True
                    elif check_parts[2][:5] == "DOOR.":
                        if check_entity.exits[
                                direction].door and check_entity.exits[
                                    direction].door.door_type and Element(
                                        check_parts[2]) in check_entity.exits[
                                            direction].door.door_type.flags:
                            return False
                        else:
                            return True
                else:
                    log.bug(
                        "Operatore di check sconosciuto: %s per il check %s" %
                        (check_parts[1], check))
                    return False

            if direction in check_entity.walls:
                if check_parts[1] == "is":
                    if check_parts[2] == "Wall":
                        if direction in check_entity.walls:
                            return True
                        else:
                            return False
                elif check_parts[1] == "is not":
                    if check_parts[2] == "Wall":
                        if direction in check_entity.walls:
                            return False
                        else:
                            return True

            return False

        # Tutti gli altri casi vengono gestiti come errore di sintassi
        log.bug("check del miml dalla sintassi errata: %s" % check)
        return False