Ejemplo n.º 1
0
class Money(object):
    PRIMARY_KEY = ""
    VOLATILES   = []
    MULTILINES  = ["comment"]
    SCHEMA      = {}
    REFERENCES  = {}
    WEAKREFS    = {}

    def __init__(self, title=""):
        self.comment      = ""
        self.copper_value = 0
        self.races        = Flags(RACE.NONE)
    #- Fine Inizializzazione -

    def __str__(self):
        r = "<"
        if self.comment:
            r += "C "
        r += "%d" % self.copper_value
        if self.races:
            return " %s" % self.races
        r += ">"

        return r
    #- Fine Metodo -

    def get_error_message(self, entity):
        if self.copper_value <= 0:
            return "copper_value non è un valore valido: %d" % self.copper_value
        elif self.races.get_error_message(RACE, "races") != "":
            return self.races.get_error_message(RACE, "races")

        return ""
    #- Fine Metodo -

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

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

        if self.comment != money2.comment:
            return False
        if self.copper_value != money2.copper_value:
            return False
        if self.races != money2.races:
            return False

        return True
Ejemplo n.º 2
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
Ejemplo n.º 3
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
Ejemplo n.º 4
0
class Plant(object):
    PRIMARY_KEY = ""
    VOLATILES   = ["deferred_stage"]
    MULTILINES  = ["comment"]
    SCHEMA      = {"temperature"    : ("",            "temperature"),
                   "humidity"       : ("",            "percent"),
                   "contents"       : ("",            "int"),
                   "worse_affects"  : ("src.affect",  "Affect"),
                   "better_affects" : ("src.affect",  "Affect")}
    REFERENCES  = {"worse_entity"   : ["proto_items", "proto_mobs"],
                   "normal_entity"  : ["proto_items", "proto_mobs"],
                   "better_entity"  : ["proto_items", "proto_mobs"],
                   "dead_entity"    : ["proto_items", "proto_mobs"]}
    WEAKREFS    = {}

    def __init__(self):
        self.comment        = ""
        self.sectors        = Flags(SECTOR.NONE)  # Settori in cui può essere seminato
        self.rpg_hours      = 1    # Durata in ore rpg prima che questo stadio si attivi
        self.temperature    = 20   # Temperatura media ideale
        self.humidity       = 50   # Percentuale dell'umidità ideale
        self.contents       = {}   # Dizionario con valori di codice_entità/quantità per popolare il contenuto dell'entità di questo stadio
        self.worse_entity   = None # Entità peggiore del prossimo stadio di crescita, se in questo stadio non viene curata o curata male
        self.normal_entity  = None # Entità normale del prossimo stadio di crescita, se in questo stadio viene curata normalmente
        self.better_entity  = None # Entità migliore del prossimo stadio di crescita, se in questo stadio viene curata molto bene
        self.dead_entity    = None # Entità morta relativa al prossimo stadio
        self.worse_affects  = []   # Affect che danneggiano la pianta
        self.better_affects = []   # Affect che migliorano la pianta
        self.decomposition_rpg_hours = config.purification_rpg_hours  # Ore Rpg prima che il contenuto venga decomposto dopo essere caduta dalla pianta
        self.remaining_life = -1   # Cicli di vita rimanenti alla pianta prima di morire
        self.worse_counter  = 0    # Contatore degli stadi di crescita andati male
        self.normal_counter = 0    # Contatore degli stadi di crescita andati normalmente
        self.better_counter = 0    # Contatore degli stadi di crescita andati ottimamente

        # Volatili
        self.deferred_stage = None
    #- Fine Inizializzazione -

    def get_error_message(self, entity):
        if self.remaining_life <= 0 and self.remaining_life != -1:
            return "remaining_life non è un'aspettativa di vita valida, deve essere maggiore di 0 oppure diverso da -1: %d" % self.remaining_life
        elif self.sectors.get_error_message(SECTOR, "sectors") != "":
            return self.sectors.get_error_message(SECTOR, "sectors")
        if self.rpg_hours <= 0:
            return "rpg_hours non è una durata in ore rpg valida: %d" % self.rpg_hours
        elif self.get_contents_error_message() != "":
            return self.get_contents_error_message()
        elif self.get_affects_error_message("worse_affects") != "":
            return self.get_affects_error_message("worse_affects")
        elif self.get_affects_error_message("better_affects") != "":
            return self.get_affects_error_message("better_affects")

        return ""
    #- Fine Metodo -

    def get_contents_error_message(self):
        for key, value in self.contents.iteritems():
            if not key:
                return "contents con chiave non valida (%r) per il valore %s" % (key, value)
            if int(value) <= 0:
                return "contents con valore non valido (%d) per la chiave %s" % (int(value), key)

        return ""
    #- Fine Metodo -

    def get_affects_error_message(self, attr_name):
        if attr_name not in ("worse_affects", "better_affects"):
            log.bug("attr_name non è un parametro valido: %s" % attr_name)
            return ""

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

        for affect in getattr(self, attr_name):
            error_message = affect.get_error_message()
            if error_message != "":
                return error_message
        return ""
    #- Fine Metodo -

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

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

        if self.deferred_stage or plant2.deferred_stage:
            return False

        if self.comment != plant2.comment:
            return False
        if self.sectors != plant2.sectors:
            return False
        if self.rpg_hours != plant2.rpg_hours:
            return False
        if self.temperature != plant2.temperature:
            return False
        if self.humidity != plant2.humidity:
            return False
        if self.worse_entity != plant2.worse_entity:
            return False
        if self.normal_entity != plant2.normal_entity:
            return False
        if self.better_entity != plant2.better_entity:
            return False
        if self.dead_entity != plant2.dead_entity:
            return False
        if self.decomposition_rpg_hours != plant2.decomposition_rpg_hours:
            return False
        if self.remaining_life != plant2.remaining_life:
            return False
        if self.worse_counter != plant2.worse_counter:
            return False
        if self.normal_counter != plant2.normal_counter:
            return False
        if self.better_counter != plant2.better_counter:
            return False

        if len(self.contents) != len(plant2.contents):
            return False
        for key, value in self.contents.iteritems():
            if key not in plant2.contents:
                return False
            if value != plant2.contents[key]:
                return False

        if len(self.worse_affects) != len(plant2.worse_affects):
            return False
        for affect in self.worse_affects:
            for affect2 in plant2.worse_affects:
                if affect == affect2:
                    break
            else:
                return False

        if len(self.better_affects) != len(plant2.better_affects):
            return False
        for affect in self.better_affects:
            for affect2 in plant2.better_affects:
                if affect == affect2:
                    break
            else:
                return False

        return True
    #- Fine Metodo -

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

    def start_growth(self, entity, type_attr_name):
        if not entity:
            log.bug("entity non è parametro valido: %r" % entity)
            return

        if type_attr_name not in ("plant_type", "seed_type"):
            log.bug("type_attr_name non è parametro valido: %r" % type_attr_name)
            return

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

        seconds = self.rpg_hours * (config.seconds_in_minute * config.minutes_in_hour)
        self.deferred_stage = defer(seconds, self.next_stage, entity, type_attr_name)
    #- Fine Metodo -

    def stop_growth(self):
        if self.deferred_stage:
            self.deferred_stage.pause()
            self.deferred_stage = None
    #- Fine Metodo -

    def next_stage(self, old_entity, type_attr_name):
        if not old_entity:
            log.bug("old_entity non è parametro valido: %r" % old_entity)
            return

        if type_attr_name not in ("plant_type", "seed_type"):
            log.bug("type_attr_name non è parametro valido: %r" % type_attr_name)
            return

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

        # Pulisce la deferred relativa a questo metodo in qualsiasi caso
        self.deferred_stage = None

        entitype = getattr(old_entity, type_attr_name)
        if not entitype:
            log.bug("%s dell'entità precedente non valido: %r" % (type_attr_name, entitype))
            return

        # (TD) deve scegliere quale delle tre entità worse, normal o better
        # in maniera non casuale ma basandosi su effettivi fattori ambientali
        entitypes = []
        for entitype_name in ("worse_entity", "normal_entity", "better_entity"):
            if getattr(entitype, entitype_name):
                entitypes.append(entitype_name)
        if not entitypes:
            log.bug("Nessuna tipologia d'entità da utilizzare come prossimo stadio: %r" % entitypes)
            return
        choised_attr = random.choice(entitypes)

        # Se la vita della pianta è terminata e finalmente si trova un'entità
        # di pianta morta, allora la utilizza
        if entitype.remaining_life == 0 and entitype.dead_entity:
            choised_attr = "dead_entity"

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

        # Crea la nuova pianta a seconda delle scelte di cui sopra
        choised_entity = getattr(entitype, choised_attr)
        if not choised_entity:
            log.bug("Impossibile continuare con la crescita della pianta da %s per la scelta %s" % (
                old_entity.code, choised_attr))
            return

        if choised_entity.max_global_quantity > 0 and choised_entity.current_global_quantity >= choised_entity.max_global_quantity:
            return

        new_entity = choised_entity.CONSTRUCTOR(choised_entity.code)

        # Passa alcune caratteristiche della vecchia entità nella nuova
        # prima di distruggerla
        if new_entity.plant_type:
            new_entity.flags += FLAG.GROWING
            new_entity.plant_type.remaining_life = entitype.remaining_life
            new_entity.plant_type.worse_counter  = entitype.worse_counter
            new_entity.plant_type.normal_counter = entitype.normal_counter
            new_entity.plant_type.better_counter = entitype.better_counter
            quality_attr = choised_attr.split("_")[0] + "_counter"
            setattr(new_entity.plant_type, quality_attr, getattr(new_entity.plant_type, quality_attr) + 1)

        # Inserisce la nuova entità in gioco
        new_entity.inject(old_entity.location)

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

        # Lista delle entità che cambieranno locazione nel ciclo sottostante
        # e che vengono passate nel trigger on_next_stage per comodità, vengono
        # salvati solo le entità frutta, seme e cibo
        entities = []

        # Controlla come deve comportarsi con il contenuto della vecchia entità:
        # se passarlo alla nuova, oppure distruggerlo, oppure ancora farlo
        # cadere a terra
        flower_counter = 0
        for content in old_entity.iter_contains(use_reversed=True):
            if content.entitype == ENTITYPE.FLOWER:
                flower_counter += 1
                continue
            elif content.entitype in (ENTITYPE.FRUIT, ENTITYPE.SEED, ENTITYPE.FOOD):
                content = content.from_location(content.quantity, use_repop=False)
                in_room = content.get_in_room()
                container_carrier = content.get_container_carrier()
                # Più la pianta è grande e maggiore è la probabilità che il suo
                # contenuto cada nella stanza invece che nel vaso
                if in_room and container_carrier and random.randint(0, max(1, math.log(new_entity.get_weight()) - math.log(container_carrier.get_weight()))) == 0:
                    content.to_location(in_room)
                    entities.append(content)
                elif in_room and random.randint(0, max(1, math.log(new_entity.get_weight()))) == 0:
                    content.to_location(in_room)
                    entities.append(content)
                elif container_carrier:
                    content.to_location(container_carrier)
                    entities.append(content)
                else:
                    content.to_location(old_entity.location)
                    entities.append(content)
                # Tutte le entità inserite a terra attivano un timer per
                # rimuoverle e non creare inutili mucchi di semi
                content.start_purification(entitype.decomposition_rpg_hours, decomposition=True)
            else:
                # (BB) qui se passavano delle entità di tipo food invece di
                # ENTITYPE.FRUIT bacava i riferimenti, probabilmente il
                # problema c'è ancora, per questo l'elif sopra accetta
                # anche food
                content = content.from_location(content.quantity, use_repop=False)
                content.to_location(new_entity)

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

        # Si salva tutti i semi per sapere se entità da inserire nella pianta
        # sia solo di tipo seme oppure se eventuali semi sono mischiati ad
        # altre tipo di entità, ciò serve perché in tal caso i semi vengono
        # inseriti nelle altre tipologie di entità (frutti o fiori chessia)
        seeds = []
        for proto_code, quantity in entitype.contents.iteritems():
            prototype = database.get_proto_entity(proto_code)
            if not prototype:
                continue
            if prototype.entitype == ENTITYPE.SEED:
                seeds.append([prototype, quantity])
        if len(seeds) == len(entitype.contents):
            seeds = []

        # Ogni volta che la pianta produce dei semi diminuisce le proprie
        # risorse vitali
        if seeds and new_entity.plant_type.remaining_life > 0:
            new_entity.plant_type.remaining_life -= 1

        # Crea l'eventuale contenuto voluto per la nuova entità
        for proto_code, quantity in entitype.contents.iteritems():
            prototype = database.get_proto_entity(proto_code)
            if not prototype:
                continue
            # Se il prototipo è un seme da inserire in un frutto o simile allora lo salta
            for seed in seeds:
                if prototype == seed[0]:
                    break
            else:
                add_content(prototype, quantity, choised_attr, flower_counter, new_entity, seeds)

        # Crea, se è il caso, una tipologia di contenitore alla nuova entità
        # per permettere ai giocatori ad interagire con la pianta
        if not new_entity.container_type and new_entity.entitype == ENTITYPE.PLANT:
            container = Container()
            container.max_weight = new_entity.get_carried_weight() * 2
            new_entity.container_type = container

        # Avvisa dell'avvenuta crescita della pianta
        if new_entity.plant_type:
            message = "%s cresce: %s"
        else:
            message = "%s finisce di crescere: %s"
        log.plant(message % (old_entity.prototype.code, new_entity.prototype.code))

        # Supporto gamescript, se viene forzato il ritorno non esegue
        # l'eventuale stadio successivo
        force_return = check_trigger(old_entity, "on_next_stage", old_entity, new_entity, choised_attr, entities)
        if force_return:
            return True

        # Ora si può rimuovere la vecchia pianta
        # (la si può estrarre completamente perché se possiede del contenuto non
        # viene raggruppata fisicamente, altrimenti si può rimuovere il gruppetto
        # senza problemi perché senza contenuto)
        old_entity.extract(old_entity.quantity, use_repop=False)

        # Prepara il lancio per il prossimo stage
        if choised_attr != "dead_entity" and new_entity.plant_type:
            new_entity.plant_type.start_growth(new_entity, "plant_type")
Ejemplo n.º 5
0
class Container(OpenableGenericType):
    PRIMARY_KEY = ""
    VOLATILES   = []
    MULTILINES  = ["comment"]
    SCHEMA      = {"max_weight" : ("", "weight")}
    REFERENCES  = {}
    WEAKREFS    = {}

    CLOSED_FLAG = CONTAINER.CLOSED
    SECRET_FLAG = CONTAINER.SECRET

    def __init__(self):
        super(Container, self).__init__()

        self.flags      = Flags(CONTAINER.NONE)  # Flag speciali di contenitore, sono praticamente uguali a quelle della porta
        self.max_weight = 0  # Massimo peso in grammi riempibile
    #- Fine Inizializzazione -

    def get_error_message(self, entity):
        msg = super(Container, self).get_error_message(entity)
        if msg:
            return msg
        elif self.flags.get_error_message(CONTAINER, "flags") != "":
            return self.flags.get_error_message(CONTAINER, "flags")
        # Viene accettato il valore zero per fare degli oggetti che sembrano
        # contenitori ma che non possono contenere nulla
        elif self.max_weight < 0:
            return "max_weight è minore di 0: %d" % self.max_weight

        return ""
    #- Fine Metodo -

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

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

        if not super(Container, self).equals(container2):
            return False

        if self.flags != container2.flags:
            return False
        if self.max_weight != container2.max_weight:
            return False

        return True
    #- Fine Metodo -

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

    def get_status(self, sex, looker=None):
        status = ""

        if CONTAINER.CLOSED in self.flags:
            # Se il contenitore è segreto non visualizza lo stato di aperto o chiuso
            if CONTAINER.SECRET not in self.flags:
                if sex == SEX.FEMALE:
                    status += " chiusa"
                else:
                    status += " chiuso"
        else:
            if sex == SEX.FEMALE:
                status += " aperta"
            else:
                status += " aperto"

        if looker and looker.trust >= TRUST.MASTER and CONTAINER.SECRET in self.flags:
            status += " (secret)"

        return status
Ejemplo n.º 6
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)
Ejemplo n.º 7
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
Ejemplo n.º 8
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
Ejemplo n.º 9
0
class Door(OpenableGenericType):
    #PRIMARY_KEY = ""
    #VOLATILES   = []
    #MULTILINES  = []
    #SCHEMA      = {}
    #REFERENCES  = {}
    #WEAKREFS    = {}

    CLOSED_FLAG = DOOR.CLOSED
    SECRET_FLAG = DOOR.SECRET

    def __init__(self):
        super(Door, self).__init__()

        self.flags = Flags(DOOR.NONE)
        self.bash_difficulty = 0  # Livello di difficoltà per il bash
        self.pass_door_difficulty = 0  # Livello di difficoltà per il pass door
        self.destination_open_message = ""  # Messaggio d'apertura stile act a tutti gli altri al di là della porta
        self.destination_close_message = ""  # Messaggio di chiusura stile act a tutti gli altri al di là della porta
        self.destination_lock_message = ""  # Messaggio di blocco(key) stile act a tutti gli altri al di là della porta
        self.destination_unlock_message = ""  # Messaggio di sblocco(key) stile act a tutti gli altri al di là della porta
        self.destination_bolt_message = ""  # Messaggio di sprangata(bolt) stile act a tutti gli altri al di là della porta
        self.destination_unbolt_message = ""  # Messaggio di desprangata(bolt) stile act a tutti gli altri al di là della porta
        self.reset_open_message = ""  # Messaggio di apertura di una porta tramite un reset
        self.reset_close_message = ""  # Messaggio di chiusura di una porta tramite un reset
        self.open_icon = ""  # Icona rappresentante la porta aperta di giorno
        self.open_icon_night = ""  # Icona rappresentante la porta aperta di notte

    #- Fine Inizializzazione -

    def get_error_message(self, entity):
        msg = super(Door, self).get_error_message(entity)
        if msg:
            return msg
        elif self.flags.get_error_message(DOOR, "flags") != "":
            return self.flags.get_error_message(DOOR, "flags")
        elif self.bash_difficulty < 0:
            return "bash_difficulty non può essere negativo: %s" % self.bash_difficulty
        elif self.pass_door_difficulty < 0:
            return "pass_door_difficulty non può essere negativo: %s" % self.pass_door_difficulty

        # L'esistenza dei diversi messaggi è slegata tra loro, ovvero possono
        # essere inizializzati tutti come solo uno di loro o, naturalmente,
        # nessuno, quindi non vi è bisogno di controllarli

        return ""

    #- Fine Metodo -

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

    #- Fine Metodo -

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

        if not super(Door, self).equals(door2):
            return False

        if self.flags != door2.flags:
            return False
        if self.bash_difficulty != door2.bash_difficulty:
            return False
        if self.pass_door_difficulty != door2.pass_door_difficulty:
            return False
        if self.destination_open_message != door2.destination_open_message:
            return False
        if self.destination_close_message != door2.destination_close_message:
            return False
        if self.destination_lock_message != door2.destination_lock_message:
            return False
        if self.destination_unlock_message != door2.destination_unlock_message:
            return False
        if self.destination_bolt_message != door2.destination_bolt_message:
            return False
        if self.destination_unbolt_message != door2.destination_unbolt_message:
            return False
        if self.reset_open_message != door2.reset_open_message:
            return False
        if self.reset_close_message != door2.reset_close_message:
            return False
        if self.open_icon != door2.open_icon:
            return False
        if self.open_icon_night != door2.open_icon_night:
            return False

        return True

    #- Fine Metodo -

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

    def get_status(self, sex, looker=None):
        status = ""

        if DOOR.CLOSED in self.flags:
            if sex == SEX.FEMALE:
                status += " chiusa"
            else:
                status += " chiuso"
        else:
            if sex == SEX.FEMALE:
                status += " aperta"
            else:
                status += " aperto"

        if looker and looker.trust >= TRUST.MASTER and DOOR.SECRET in self.flags:
            status += " (secret)"

        return status

    #- Fine Metodo -

    def get_icon(self):
        icon = ""
        if calendar.is_night():
            icon = self.open_icon_night

        if not icon:
            icon = self.open_icon

        return icon

    #- Fine Metodo -

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

    def send_open_messages(self,
                           entity,
                           target,
                           verbs,
                           direction=None,
                           destination_room=None,
                           target_on_destination=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door,
              self).send_open_messages(entity, target, verbs, direction,
                                       destination_room, target_on_destination)

        if destination_room and direction:
            target = target_on_destination or target
            if self.destination_open_message:
                message = self.destination_open_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(
                            direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (
                    verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message,
                       TO.OTHERS,
                       target,
                       destination_room,
                       target_on_destination,
                       send_to_location=destination_room)

    #- Fine Metodo -

    def send_close_messages(self,
                            entity,
                            target,
                            verbs,
                            direction=None,
                            destination_room=None,
                            target_on_destination=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_close_messages(entity, target, verbs, direction,
                                              destination_room,
                                              target_on_destination)

        # Cose riguardanti solo le porte
        if destination_room and direction:
            target = target_on_destination or target
            if self.destination_close_message:
                message = self.destination_close_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(
                            direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (
                    verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message,
                       TO.OTHERS,
                       target,
                       destination_room,
                       target_on_destination,
                       send_to_location=destination_room)

    #- Fine Metodo -

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

    def send_lock_messages(self,
                           entity,
                           target,
                           verbs,
                           direction=None,
                           destination_room=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_lock_messages(entity, target, verbs, direction,
                                             destination_room)

        if destination_room:
            if self.destination_lock_message:
                message = self.destination_lock_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(
                            direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (
                    verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message,
                       TO.OTHERS,
                       target,
                       destination_room,
                       send_to_location=destination_room)

    #- Fine Metodo -

    def send_unlock_messages(self,
                             entity,
                             target,
                             verbs,
                             direction=None,
                             destination_room=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_unlock_messages(entity, target, verbs,
                                               direction, destination_room)

        if destination_room:
            if self.destination_unlock_message:
                message = self.destination_unlock_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(
                            direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (
                    verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message,
                       TO.OTHERS,
                       target,
                       destination_room,
                       send_to_location=destination_room)

    #- Fine Metodo -

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

    def send_unbolt_messages(self,
                             entity,
                             target,
                             verbs,
                             destination_room=None,
                             direction=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_unbolt_messages(entity, target, verbs,
                                               direction, destination_room)

        if destination_room and direction:
            if self.destination_unbolt_message:
                message = self.destination_unbolt_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(
                            direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (
                    verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message,
                       TO.OTHERS,
                       target,
                       destination_room,
                       send_to_location=destination_room)

    #- Fine Metodo -

    def send_bolt_messages(self,
                           entity,
                           target,
                           verbs,
                           direction=None,
                           destination_room=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_bolt_messages(entity, target, verbs, direction,
                                             destination_room)

        # Cose riguardanti solo le porte
        if destination_room and direction:
            if self.destination_bolt_message:
                message = self.destination_bolt_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(
                            direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (
                    verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message,
                       TO.OTHERS,
                       target,
                       destination_room,
                       send_to_location=destination_room)
Ejemplo n.º 10
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
Ejemplo n.º 11
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
Ejemplo n.º 12
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
Ejemplo n.º 13
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)
Ejemplo n.º 14
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
Ejemplo n.º 15
0
class Shop(object):
    """
    Classe che gestisce tutte le informazioni di un negoziante.
    """
    PRIMARY_KEY = ""
    VOLATILES   = []
    MULTILINES  = ["comment"]
    SCHEMA      = {"buyables"  : ("src.shop", "Buyable"),
                   "sellables" : ("src.shop", "Sellable")}
    REFERENCES  = {"proto_locations" : ["proto_rooms", "proto_mobs", "proto_items"],
                   "proto_storages"  : ["proto_rooms", "proto_mobs", "proto_items"]}
    WEAKREFS    = {}

    def __init__(self):
        self.comment                      = ""  # Commento relativo la struttura
        self.types                        = Flags(SHOP.NONE)  # Tipologia/e di shop, se non impostata viene considerato un negozio qualsiasi
        self.proto_locations              = []  # Prototipo delle locazioni in cui l'entità negozierà, se non ne viene indicata nessuna il negoziante è un venditore ambulante
        self.proto_storages               = []  # Prototipo delle locazioni da cui l'entità prenderà la mercanzia da vendere
        self.buyables                     = []  # Entità comprabili da parte di un giocatore e relative informazioni di magazzino
        self.sellables                    = []  # Tipologie di entità vendibili da parte del giocatore, se non viene impostata allora si potrà vendere qualsiasi cosa
        self.entity_buy_message           = ""  # Messaggi di act relativi al comando buy avvenuto, sono messaggi facoltativi
        self.others_buy_message           = ""
        self.target_buy_message           = ""
        self.dealer_buy_message           = ""
        self.entity_cannot_afford_message = ""  # Messaggi di act relativi al comando buy se non si hanno i soldi necessari, sono messaggi facoltativi
        self.others_cannot_afford_message = ""
        self.target_cannot_afford_message = ""
        self.dealer_cannot_afford_message = ""
        self.entity_sell_message          = ""  # Messaggi di act relativi al comando sell avvenuto, sono messaggi facoltativi
        self.others_sell_message          = ""
        self.target_sell_message          = ""
        self.dealer_sell_message          = ""
        self.entity_offer_message         = ""  # Messaggi di act relativi al comando offer avvenuto, sono messaggi facoltativi
        self.others_offer_message         = ""
        self.target_offer_message         = ""
        self.dealer_offer_message         = ""
        self.entity_uninterested_message  = ""  # Messaggi di act relativi al disinteresse del mercante per un determinata entità offerta o venduta, sono messaggi facoltativi
        self.others_uninterested_message  = ""
        self.target_uninterested_message  = ""
        self.dealer_uninterested_message  = ""
    #- Fine Inizializzazione -

    def get_error_message(self):
        if self.types.get_error_message(SHOP, "types") != "":
            return self.types.get_error_message(SHOP, "types")
        elif self.get_error_message_buyables() != "":
            return self.get_error_message_buyables()
        elif self.get_error_message_sellables() != "":
            return self.get_error_message_sellables()

        return ""
    #- Fine Metodo -

    def get_error_message_buyables(self):
        if not self.buyables:
            return "buyables non è stata impostata"

        for buyable in self.buyables:
            if buyable.get_error_message() != "":
                return buyable.get_error_message()

        return ""
    #- Fine Metodo -

    def get_error_message_sellables(self):
        for sellable in self.sellables:
            if sellable.entitype == ENTITYPE.NONE:
                if len(self.sellables) > 1:
                    return "Quando si esplicita il valore di ENTITYPE.NONE in un sellable deve essere il solo e unico."

        for sellable in self.sellables:
            if sellable.get_error_message() != "":
                return sellable.get_error_message()

        return ""
    #- Fine Metodo -

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

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

        if self.comment != shop2.comment:
            return False
        if self.types != shop2.types:
            return False

        for location in self.proto_locations:
            for location2 in shop2.proto_locations:
                if location == location2:
                    break
            else:
                return False

        for storage in self.proto_storages:
            for storage2 in shop2.proto_storages:
                if storage == storage2:
                    break
            else:
                return False

        if len(self.buyables) != len(shop2.buyables):
            return False
        for buyable in self.buyables:
            for buyable2 in shop2.buyables:
                if buyable.equals(buyable2):
                    break
            else:
                return False

        if len(self.sellables) != len(shop2.sellables):
            return False
        for sellable in self.sellables:
            for sellable2 in shop2.sellables:
                if sellable.equals(sellable2):
                    break
            else:
                return False

        if self.entity_buy_message           != shop2.entity_buy_message:           return False
        if self.others_buy_message           != shop2.others_buy_message:           return False
        if self.target_buy_message           != shop2.target_buy_message:           return False
        if self.dealer_buy_message           != shop2.dealer_buy_message:           return False
        if self.entity_cannot_afford_message != shop2.entity_cannot_afford_message: return False
        if self.others_cannot_afford_message != shop2.others_cannot_afford_message: return False
        if self.target_cannot_afford_message != shop2.target_cannot_afford_message: return False
        if self.dealer_cannot_afford_message != shop2.dealer_cannot_afford_message: return False
        if self.entity_sell_message          != shop2.entity_sell_message:          return False
        if self.others_sell_message          != shop2.others_sell_message:          return False
        if self.target_sell_message          != shop2.target_sell_message:          return False
        if self.dealer_sell_message          != shop2.dealer_sell_message:          return False
        if self.entity_offer_message         != shop2.entity_offer_message:         return False
        if self.others_offer_message         != shop2.others_offer_message:         return False
        if self.target_offer_message         != shop2.target_offer_message:         return False
        if self.dealer_offer_message         != shop2.dealer_offer_message:         return False
        if self.entity_uninterested_message  != shop2.entity_uninterested_message:  return False
        if self.others_uninterested_message  != shop2.others_uninterested_message:  return False
        if self.target_uninterested_message  != shop2.target_uninterested_message:  return False
        if self.dealer_uninterested_message  != shop2.dealer_uninterested_message:  return False

        return True
    #- Fine Metodo -

    def in_location(self, dealer):
        """
        Controlla se possa interagire nel luogo in cui si trova.
        """
        if not dealer:
            log.bug("dealer non è un parametro valido: %s" % dealer)
            return 0

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

        if not self.proto_locations:
            return True

        if dealer.location.prototype in self.proto_locations:
            return True

        return False
    #- Fine Metodo -

    def get_storage(self, dealer):
        """
        Ritorna il luogo in cui vengono inserite le cose da vendere, il magazzino.
        """
        if not dealer:
            log.bug("dealer non è un parametro valido: %s" % dealer)
            return 0

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

        if not self.proto_storages:
            return dealer

        # Da priorità al dealer e alla locazione nel qual caso vi siano
        # più storages tutti nella stessa stanza
        if dealer.prototype in self.proto_storages:
            return dealer
        if dealer.location.prototype in self.proto_storages:
            return dealer.location

        for en in dealer.iter_contains():
            if en.IS_PLAYER:
                continue
            if en.prototype in self.proto_storages:
                return en

        for en in dealer.location.iter_contains():
            if en.IS_PLAYER:
                continue
            if en.prototype in self.proto_storages:
                return en

        # Adesso invece cerca tra le stanze dell'area
        for room in dealer.location.area.rooms.values():
            if room.prototype in self.proto_storages:
                return room

        return None
    #- Fine Metodo -

    def get_buyable(self, purchase):
        """
        Ritorna la struttura di buyable relativa alla mercanzia passata.
        """
        if not purchase:
            log.bug("purchase non è un parametro valido: %s" % purchase)
            return None

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

        for buyable in self.buyables:
            if purchase.prototype == buyable.proto_entity:
                return buyable

        return None
    #- Fine Metodo -

    def get_sellable(self, target):
        """
        Ritorna il sellable del negoziante relativo all'entità passata, se
        possibile.
        """
        if not self.sellables:
            return None

        # Se viene impostato esplicitamente ENTITYPE.NONE allora accetta di
        # far vendere qualsiasi cosa al negoziante
        for sellable in self.sellables:
            if sellable.entitype == ENTITYPE.NONE:
                return sellable

        for sellable in self.sellables:
            if sellable.entitype == target.entitype:
                return sellable

        return None
    #- Fine Metodo -

    def storage_is_empty(self, storage):
        """
        Ritorna verso se il magazzino passato non ha mercanzia da vendere.
        """
        if not storage:
            log.bug("storage non è un parametro valido: %r" % storage)
            return False

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

        for en in storage.iter_contains():
            for buyable in self.buyables:
                if en.prototype == buyable.proto_entity:
                    return False

        return True
    #- Fine Metodo -

    def add_buyable(self, dealer, target, sellable, quantity):
        """
        Aggiunge una nuova entità comprabile al negoziante ma senza che questa
        abbia futura possibilità di aggiornare il proprio magazzino.
        """
        if not dealer:
            log.bug("dealer non è un parametro valido: %s" % dealer)
            return

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

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

        if quantity <= 0:
            log.bug("quantity non può essere minore o uguale a 0: %d" % quantity)
            return

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

        # Se non c'è nessun magazzino in cui inserire l'entità allora esce
        storage = self.get_storage(dealer)
        if not storage:
            target.extract()
            return

        if not storage.IS_ROOM and not storage.can_carry_target(target, quantity=quantity):
            target.extract()
            return

        # Crea un buyable e lo aggiunge alla lista delle mercanzie del negozio
        buyable              = Buyable()
        buyable.proto_entity = target.prototype
        buyable.percent      = sellable.buyback_percent

        self.buyables.append(buyable)
    #- Fine Metodo -

    def send_buy_messages(self, entity, purchase, dealer, verbs, quantity, pretty_price, discount):
        if not entity:
            log.bug("entity non è un parametro valido: %r" % entity)
            return

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

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

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

        if quantity < 0:
            log.bug("quantity non è un parametro valido: %d" % quantity)
            return

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

        if discount < 0:
            log.bug("discount non è un parametro valido: %d" % discount)
            return

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

        is_dispenser = SHOP.DISPENSER in dealer.shop.types

        discount_descr = ""
        if discount > 0:
            discount_descr = " scontato"

        quantity_descr = ""
        if quantity > 1:
            quantity_descr = "%d " % quantity

        if self.entity_buy_message:
            message = self.entity_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["you"]))
                else:
                    message = message.replace("%verb", verbs["you"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            if is_dispenser:
                message = "%s %s$N da $a inserendovi %s." % (color_first_upper(verbs["you"]), quantity_descr, pretty_price)
            else:
                message = "%s %s$N da $a pagandol$O %s%s." % (color_first_upper(verbs["you"]), quantity_descr, pretty_price, discount_descr)
        entity.act(message, TO.ENTITY, purchase, dealer)

        if self.others_buy_message:
            message = self.others_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            if is_dispenser:
                message = "$n %s %s$N da $a inserendovi %s." % (verbs["it"], quantity_descr, pretty_price)
            else:
                message = "$n %s %s$N da $a pagandol$O %s%s." % (verbs["it"], quantity_descr, pretty_price, discount_descr)
        entity.act(message, TO.OTHERS, purchase, dealer)

        if self.target_buy_message:
            message = self.target_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            if is_dispenser:
                message = "$n ti %s da $a inserendovi %s." % (verbs["it"], pretty_price)
            else:
                message = "$n ti %s da $a pagandoti %s%s." % (verbs["it"], pretty_price, discount_descr)
        entity.act(message, TO.TARGET, purchase, dealer)

        if self.dealer_buy_message:
            message = self.dealer_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            if is_dispenser:
                message = "$n ti %s %s$N inserendoti %s." % (verbs["it"], quantity_descr, pretty_price)
            else:
                message = "$n ti %s %s$N pagandol$O %s%s." % (verbs["it"], quantity_descr, pretty_price, discount_descr)
        entity.act(message, TO.TARGET, dealer, purchase)
    #- Fine Metodo -

    def send_cannot_afford_messages(self, entity, purchase, dealer, verbs, quantity, pretty_price):
        if not entity:
            log.bug("entity non è un parametro valido: %r" % entity)
            return

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

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

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

        if quantity < 0:
            log.bug("quantity non è un parametro valido: %d" % quantity)
            return

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

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

        quantity_descr = ""
        if quantity > 1:
            quantity_descr = "%d " % quantity

        if self.entity_cannot_afford_message:
            message = self.entity_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["infinitive"]))
                else:
                    message = message.replace("%verb", verbs["infinitive"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            message = "Non hai abbastanza soldi per poter %s %s$N da $a: costa %s." % (verbs["infinitive"], quantity_descr, pretty_price)
        entity.act(message, TO.ENTITY, purchase, dealer)

        if self.others_cannot_afford_message:
            message = self.others_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["infinitive"]))
                else:
                    message = message.replace("%verb", verbs["infinitive"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            message = "$n non sembra avere abbastanza soldi per poter %s %s$N." % (verbs["infinitive"], quantity_descr)
        entity.act(message, TO.OTHERS, purchase, dealer)

        if self.target_cannot_afford_message:
            message = self.target_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["infinitive"]))
                else:
                    message = message.replace("%verb", verbs["infinitive"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            message = "$n non ha abbastanza soldi per poterti %s da $a." % verbs["infinitive"]
        entity.act(message, TO.TARGET, purchase, dealer)

        if self.dealer_cannot_afford_message:
            message = self.dealer_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["infinitive"]))
                else:
                    message = message.replace("%verb", verbs["infinitive"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            message = "$n non ha abbastanza soldi per poter %s %s$a da te." % (verbs["infinitive"], quantity_descr)
        entity.act(message, TO.TARGET, dealer, purchase)
    #- Fine Metodo -

    def send_sell_messages(self, entity, target, dealer, verbs, quantity, pretty_price):
        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 not dealer:
            log.bug("dealer non è un parametro valido: %r", dealer)
            return

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

        if quantity < 0:
            log.bug("quantity non è un parametro valido: %d" % quantity)
            return

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

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

        quantity_descr = ""
        if quantity > 1:
            quantity_descr = "%d " % quantity

        if self.entity_sell_message:
            message = self.entity_sell_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["you"]))
                else:
                    message = message.replace("%verb", verbs["you"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        elif quantity <= 1:
            message = "%s $a a $N per %s." % (color_first_upper(verbs["you"]), pretty_price)
        else:
            message = "%s $N, in %d unità, a $a per %s." % (color_first_upper(verbs["you"]))
        entity.act(message, TO.ENTITY, target, dealer)

        if self.others_sell_message:
            message = self.entity_sell_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        elif quantity <= 1:
            message = "$n %s $N a $a per %s." % (verbs["it"], pretty_price)
        else:
            message = "$n %s $N, in %d unità, a $a per %s." % (verbs["it"], quantity, pretty_price)
        entity.act(message, TO.OTHERS, target, dealer)

        if target != entity:
            if self.target_sell_message:
                message = self.entity_sell_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message.replace("%verb", color_first_upper(verbs["it"]))
                    else:
                        message = message.replace("%verb", verbs["it"].lower())
                if "%quantity" in message:
                    message = message.replace("%quantity", quantity_descr)
                if "%price" in message:
                    message = message.replace("%price", pretty_price)
            elif quantity <= 1:
                message = "$n ti %s $N per %s." % (verbs["it"], pretty_price)
            else:
                message = "$n ti %s $N, in %d unità, per %s." % (verbs["it"], quantity, pretty_price)
            entity.act(message, TO.TARGET, target, dealer)

        if dealer != entity:
            if self.dealer_sell_message:
                message = self.entity_sell_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message.replace("%verb", color_first_upper(verbs["it"]))
                    else:
                        message = message.replace("%verb", verbs["it"].lower())
                if "%quantity" in message:
                    message = message.replace("%quantity", quantity_descr)
                if "%price" in message:
                    message = message.replace("%price", pretty_price)
            elif quantity <= 1:
                message = "$n ti %s a $N per %s." % (verbs["it"], pretty_price)
            else:
                message = "$n ti %s a $N, in %d unità, per %s." % (verbs["it"], quantity, pretty_price)
            entity.act(message, TO.TARGET, dealer, target)
    #- Fine Metodo -

    def send_offer_messages(self, entity, target, dealer, verbs, quantity, pretty_price):
        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 not dealer:
            log.bug("dealer non è un parametro valido: %r", dealer)
            return

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

        if quantity < 0:
            log.bug("quantity non è un parametro valido: %d" % quantity)
            return

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

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

        quantity_descr = ""
        if quantity > 1:
            quantity_descr = "%d " % quantity

        if self.entity_offer_message:
            message = self.entity_offer_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        elif quantity <= 1:
            message = "$N ti %s %s per $N." % (verbs["it"], pretty_price)
        else:
            message = "$N ti %s %s per %d unità di $N." % (verbs["it"], pretty_price, quantity)
        entity.act(message, TO.ENTITY, target, dealer)

        if self.others_offer_message:
            message = self.entity_offer_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb", color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        elif quantity <= 1:
            message = "$N %s %s a $n per $N." % (verbs["it"], pretty_price)
        else:
            message = "$N %s %s a $n per %d unità di $N." % (verbs["it"], pretty_price, quantity)
        entity.act(message, TO.OTHERS, target, dealer)

        if target != entity:
            if self.target_offer_message:
                message = self.entity_offer_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message.replace("%verb", color_first_upper(verbs["you"]))
                    else:
                        message = message.replace("%verb", verbs["you"].lower())
                if "%quantity" in message:
                    message = message.replace("%quantity", quantity_descr)
                if "%price" in message:
                    message = message.replace("%price", pretty_price)
            elif quantity <= 1:
                message = "%s a $n %s per $N." % (color_first_upper(verbs["you"]), pretty_price)
            else:
                message = "%s a $n %s per %d unità di $N." % (color_first_upper(verbs["you"], quantity), pretty_price)
            entity.act(message, TO.TARGET, target, dealer)

        if dealer != entity:
            if self.dealer_offer_message:
                message = self.entity_offer_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message.replace("%verb", color_first_upper(verbs["it"]))
                    else:
                        message = message.replace("%verb", verbs["it"].lower())
                if "%quantity" in message:
                    message = message.replace("%quantity", quantity_descr)
                if "%price" in message:
                    message = message.replace("%price", pretty_price)
            elif quantity <= 1:
                message = "$a %s a $n %s per te." % (verbs["it"], pretty_price)
            else:
                message = "$a %s a $n %s per %d unità di te." % (verbs["it"], pretty_price, quantity)
            entity.act(message, TO.TARGET, dealer, target)
    #- Fine Metodo -

    def send_uninterested_messages(self, entity, target, dealer):
        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 not dealer:
            log.bug("dealer non è un parametro valido: %r", dealer)
            return

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

        if self.entity_uninterested_message:
            entity.act(self.entity_uninterested_message, TO.ENTITY, target, dealer)
        else:
            entity.act("$N non è una tipologia che a $a possa interessare.", TO.ENTITY, target, dealer)

        if self.others_uninterested_message:
            entity.act(self.others_uninterested_message, TO.OTHERS, target, dealer)
        else:
            entity.act("$N di $n non è una tipologia che a $a possa interessare.", TO.OTHERS, target, dealer)

        if self.target_uninterested_message:
            entity.act(self.target_uninterested_message, TO.TARGET, target, dealer)
        else:
            entity.act("Non sei una tipologia che a $a possa interessare.", TO.TARGET, target, dealer)

        if self.dealer_uninterested_message:
            entity.act(self.dealer_uninterested_message, TO.TARGET, dealer, target)
        else:
            entity.act("Non sei interessato a $a di $n, non è simile alla tua mercanzia.", TO.TARGET, dealer, target)
Ejemplo n.º 16
0
class ExtraDescription(MIMLParserSuperclass):
    """
    Gestisce una descrizione extra.
    """
    PRIMARY_KEY = "keywords"
    VOLATILES = []
    MULTILINES = [
        "comment", "descr", "descr_night", "descr_hearing",
        "descr_hearing_night", "descr_smell", "descr_smell_night",
        "descr_touch", "descr_touch_night", "descr_taste", "descr_taste_night",
        "descr_sixth", "descr_sixth_night"
    ]
    SCHEMA = {}
    REFERENCES = {"author": ["players", "proto_mobs", "proto_items"]}
    WEAKREFS = {}

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

    def __init__(self, keywords=""):
        if not keywords and keywords != "":
            log.bug("keywords passato non è una stringa valida: %s" % keywords)
            return

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

        self.comment = ""  # Eventuale commento alle extra
        self.keywords = keywords  # Parole chiave con cui accedere all'extra
        self.descr = ""  # Descrizione diurna
        self.descr_night = ""  # Descrizione notturna
        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.flags = Flags(
            EXTRA.NONE
        )  # Flag per indicare la tipologia di extra e altre proprietà particolari
        self.author = None  # Entità che ha scritto, o disegnato, l'extra

    #- Fine Inizializzazione -

    def get_error_message(self):
        # E' possibile evitare di inserire sia la descrizione notturna che
        # quella diurna di ognuno dei 6 sensi, (TD) cmq almeno una descr ci
        # deve essere
        msg = ""
        if not self.keywords:
            msg = "keywords di extra non valida"
        # Non bisogna controllare neppure la descr perché potrebbe essere
        # EXTRA.NIGHT_ONLY (TD) fare un check migliore
        elif self.flags.get_error_message(EXTRA, "flags") != "":
            msg = self.flags.get_error_message(EXTRA, "flags")
        return msg

    #- Fine Funzione -

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

    #- Fine Funzione -

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

        items1 = self.__dict__.items()
        items2 = extra2.__dict__.items()
        if len(items1) != len(items2):
            return False
        for attr, value in items1:
            if getattr(extra2, attr) != value:
                return False

        return True

    #- Fine Metodo -

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

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

        if calendar.is_night():
            descr_night = getattr(self, "descr%s_night" % type)
            if descr_night:
                return put_final_dot(color_first_upper(descr_night))
            elif EXTRA.DAY_ONLY in self.flags:
                return ""

        # Non c'è bisogno di implementare la EXTRA.DAY_ONLY perché
        # concettualmente già funziona così, l'ho aggiunta perché i builder
        # si trovano meglio a inserirla esplicitamente in alcuni casi

        descr = getattr(self, "descr%s" % type)

        if MIML_SEPARATOR in descr:
            if parent:
                descr = parent.parse_miml(descr, looker)
            else:
                log.bug(
                    "Anche se il parametro è opzionale è inteso come dovuto: %r"
                    % parent)

        if descr:
            return put_final_dot(color_first_upper(descr))
        else:
            # Può accadere quando il type è una stringa indicante un senso
            # differente da quello della vista
            return ""
Ejemplo n.º 17
0
class Container(OpenableGenericType):
    PRIMARY_KEY = ""
    VOLATILES = []
    MULTILINES = ["comment"]
    SCHEMA = {"max_weight": ("", "weight")}
    REFERENCES = {}
    WEAKREFS = {}

    CLOSED_FLAG = CONTAINER.CLOSED
    SECRET_FLAG = CONTAINER.SECRET

    def __init__(self):
        super(Container, self).__init__()

        self.flags = Flags(
            CONTAINER.NONE
        )  # Flag speciali di contenitore, sono praticamente uguali a quelle della porta
        self.max_weight = 0  # Massimo peso in grammi riempibile

    #- Fine Inizializzazione -

    def get_error_message(self, entity):
        msg = super(Container, self).get_error_message(entity)
        if msg:
            return msg
        elif self.flags.get_error_message(CONTAINER, "flags") != "":
            return self.flags.get_error_message(CONTAINER, "flags")
        # Viene accettato il valore zero per fare degli oggetti che sembrano
        # contenitori ma che non possono contenere nulla
        elif self.max_weight < 0:
            return "max_weight è minore di 0: %d" % self.max_weight

        return ""

    #- Fine Metodo -

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

    #- Fine Metodo -

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

        if not super(Container, self).equals(container2):
            return False

        if self.flags != container2.flags:
            return False
        if self.max_weight != container2.max_weight:
            return False

        return True

    #- Fine Metodo -

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

    def get_status(self, sex, looker=None):
        status = ""

        if CONTAINER.CLOSED in self.flags:
            # Se il contenitore è segreto non visualizza lo stato di aperto o chiuso
            if CONTAINER.SECRET not in self.flags:
                if sex == SEX.FEMALE:
                    status += " chiusa"
                else:
                    status += " chiuso"
        else:
            if sex == SEX.FEMALE:
                status += " aperta"
            else:
                status += " aperto"

        if looker and looker.trust >= TRUST.MASTER and CONTAINER.SECRET in self.flags:
            status += " (secret)"

        return status
Ejemplo n.º 18
0
class Door(OpenableGenericType):
    #PRIMARY_KEY = ""
    #VOLATILES   = []
    #MULTILINES  = []
    #SCHEMA      = {}
    #REFERENCES  = {}
    #WEAKREFS    = {}

    CLOSED_FLAG = DOOR.CLOSED
    SECRET_FLAG = DOOR.SECRET

    def __init__(self):
        super(Door, self).__init__()

        self.flags                      = Flags(DOOR.NONE)
        self.bash_difficulty            = 0    # Livello di difficoltà per il bash
        self.pass_door_difficulty       = 0    # Livello di difficoltà per il pass door
        self.destination_open_message   = ""   # Messaggio d'apertura stile act a tutti gli altri al di là della porta
        self.destination_close_message  = ""   # Messaggio di chiusura stile act a tutti gli altri al di là della porta
        self.destination_lock_message   = ""   # Messaggio di blocco(key) stile act a tutti gli altri al di là della porta
        self.destination_unlock_message = ""   # Messaggio di sblocco(key) stile act a tutti gli altri al di là della porta
        self.destination_bolt_message   = ""   # Messaggio di sprangata(bolt) stile act a tutti gli altri al di là della porta
        self.destination_unbolt_message = ""   # Messaggio di desprangata(bolt) stile act a tutti gli altri al di là della porta
        self.reset_open_message         = ""   # Messaggio di apertura di una porta tramite un reset
        self.reset_close_message        = ""   # Messaggio di chiusura di una porta tramite un reset
        self.open_icon                  = ""   # Icona rappresentante la porta aperta di giorno
        self.open_icon_night            = ""   # Icona rappresentante la porta aperta di notte
    #- Fine Inizializzazione -

    def get_error_message(self, entity):
        msg = super(Door, self).get_error_message(entity)
        if msg:
            return msg
        elif self.flags.get_error_message(DOOR, "flags") != "":
            return self.flags.get_error_message(DOOR, "flags")
        elif self.bash_difficulty < 0:
            return "bash_difficulty non può essere negativo: %s" % self.bash_difficulty
        elif self.pass_door_difficulty < 0:
            return "pass_door_difficulty non può essere negativo: %s" % self.pass_door_difficulty

        # L'esistenza dei diversi messaggi è slegata tra loro, ovvero possono
        # essere inizializzati tutti come solo uno di loro o, naturalmente,
        # nessuno, quindi non vi è bisogno di controllarli

        return ""
    #- Fine Metodo -

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

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

        if not super(Door, self).equals(door2):
            return False

        if self.flags != door2.flags:
            return False
        if self.bash_difficulty != door2.bash_difficulty:
            return False
        if self.pass_door_difficulty != door2.pass_door_difficulty:
            return False
        if self.destination_open_message != door2.destination_open_message:
            return False
        if self.destination_close_message != door2.destination_close_message:
            return False
        if self.destination_lock_message != door2.destination_lock_message:
            return False
        if self.destination_unlock_message != door2.destination_unlock_message:
            return False
        if self.destination_bolt_message != door2.destination_bolt_message:
            return False
        if self.destination_unbolt_message != door2.destination_unbolt_message:
            return False
        if self.reset_open_message != door2.reset_open_message:
            return False
        if self.reset_close_message != door2.reset_close_message:
            return False
        if self.open_icon != door2.open_icon:
            return False
        if self.open_icon_night != door2.open_icon_night:
            return False

        return True
    #- Fine Metodo -

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

    def get_status(self, sex, looker=None):
        status = ""

        if DOOR.CLOSED in self.flags:
            if sex == SEX.FEMALE:
                status += " chiusa"
            else:
                status += " chiuso"
        else:
            if sex == SEX.FEMALE:
                status += " aperta"
            else:
                status += " aperto"

        if looker and looker.trust >= TRUST.MASTER and DOOR.SECRET in self.flags:
            status += " (secret)"

        return status
    #- Fine Metodo -

    def get_icon(self):
        icon = ""
        if calendar.is_night():
            icon = self.open_icon_night

        if not icon:
            icon = self.open_icon

        return icon
    #- Fine Metodo -

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

    def send_open_messages(self, entity, target, verbs, direction=None, destination_room=None, target_on_destination=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_open_messages(entity, target, verbs, direction, destination_room, target_on_destination)

        if destination_room and direction:
            target = target_on_destination or target
            if self.destination_open_message:
                message = self.destination_open_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message, TO.OTHERS, target, destination_room, target_on_destination, send_to_location=destination_room)
    #- Fine Metodo -

    def send_close_messages(self, entity, target, verbs, direction=None, destination_room=None, target_on_destination=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_close_messages(entity, target, verbs, direction, destination_room, target_on_destination)

        # Cose riguardanti solo le porte
        if destination_room and direction:
            target = target_on_destination or target
            if self.destination_close_message:
                message = self.destination_close_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message, TO.OTHERS, target, destination_room, target_on_destination, send_to_location=destination_room)
    #- Fine Metodo -

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

    def send_lock_messages(self, entity, target, verbs, direction=None, destination_room=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_lock_messages(entity, target, verbs, direction, destination_room)

        if destination_room:
            if self.destination_lock_message:
                message = self.destination_lock_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message, TO.OTHERS, target, destination_room, send_to_location=destination_room)
    #- Fine Metodo -

    def send_unlock_messages(self, entity, target, verbs, direction=None, destination_room=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_unlock_messages(entity, target, verbs, direction, destination_room)

        if destination_room:
            if self.destination_unlock_message:
                message = self.destination_unlock_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message, TO.OTHERS, target, destination_room, send_to_location=destination_room)
    #- Fine Metodo -

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

    def send_unbolt_messages(self, entity, target, verbs, destination_room=None, direction=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_unbolt_messages(entity, target, verbs, direction, destination_room)

        if destination_room and direction:
            if self.destination_unbolt_message:
                message = self.destination_unbolt_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message, TO.OTHERS, target, destination_room, send_to_location=destination_room)
    #- Fine Metodo -

    def send_bolt_messages(self, entity, target, verbs, direction=None, destination_room=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 not verbs:
            log.bug("verbs non è un parametro valido: %r" % verbs)
            return False

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

        super(Door, self).send_bolt_messages(entity, target, verbs, direction, destination_room)

        # Cose riguardanti solo le porte
        if destination_room and direction:
            if self.destination_bolt_message:
                message = self.destination_bolt_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message % color_first_upper(verbs["it"])
                    else:
                        message = message % verbs["it"].lower()
                if "%dir" in message:
                    if message.startswith("%dir"):
                        message = message % color_first_upper(direction.to_dir2)
                    else:
                        message = message % direction.to_dir2.lower()
            else:
                message = "Qualcuno, dall'altra parte, %s $N %s" % (verbs["it"].lower(), direction.reverse_dir.to_dir2)
            entity.act(message, TO.OTHERS, target, destination_room, send_to_location=destination_room)
Ejemplo n.º 19
0
class Shop(object):
    """
    Classe che gestisce tutte le informazioni di un negoziante.
    """
    PRIMARY_KEY = ""
    VOLATILES = []
    MULTILINES = ["comment"]
    SCHEMA = {
        "buyables": ("src.shop", "Buyable"),
        "sellables": ("src.shop", "Sellable")
    }
    REFERENCES = {
        "proto_locations": ["proto_rooms", "proto_mobs", "proto_items"],
        "proto_storages": ["proto_rooms", "proto_mobs", "proto_items"]
    }
    WEAKREFS = {}

    def __init__(self):
        self.comment = ""  # Commento relativo la struttura
        self.types = Flags(
            SHOP.NONE
        )  # Tipologia/e di shop, se non impostata viene considerato un negozio qualsiasi
        self.proto_locations = [
        ]  # Prototipo delle locazioni in cui l'entità negozierà, se non ne viene indicata nessuna il negoziante è un venditore ambulante
        self.proto_storages = [
        ]  # Prototipo delle locazioni da cui l'entità prenderà la mercanzia da vendere
        self.buyables = [
        ]  # Entità comprabili da parte di un giocatore e relative informazioni di magazzino
        self.sellables = [
        ]  # Tipologie di entità vendibili da parte del giocatore, se non viene impostata allora si potrà vendere qualsiasi cosa
        self.entity_buy_message = ""  # Messaggi di act relativi al comando buy avvenuto, sono messaggi facoltativi
        self.others_buy_message = ""
        self.target_buy_message = ""
        self.dealer_buy_message = ""
        self.entity_cannot_afford_message = ""  # Messaggi di act relativi al comando buy se non si hanno i soldi necessari, sono messaggi facoltativi
        self.others_cannot_afford_message = ""
        self.target_cannot_afford_message = ""
        self.dealer_cannot_afford_message = ""
        self.entity_sell_message = ""  # Messaggi di act relativi al comando sell avvenuto, sono messaggi facoltativi
        self.others_sell_message = ""
        self.target_sell_message = ""
        self.dealer_sell_message = ""
        self.entity_offer_message = ""  # Messaggi di act relativi al comando offer avvenuto, sono messaggi facoltativi
        self.others_offer_message = ""
        self.target_offer_message = ""
        self.dealer_offer_message = ""
        self.entity_uninterested_message = ""  # Messaggi di act relativi al disinteresse del mercante per un determinata entità offerta o venduta, sono messaggi facoltativi
        self.others_uninterested_message = ""
        self.target_uninterested_message = ""
        self.dealer_uninterested_message = ""

    #- Fine Inizializzazione -

    def get_error_message(self):
        if self.types.get_error_message(SHOP, "types") != "":
            return self.types.get_error_message(SHOP, "types")
        elif self.get_error_message_buyables() != "":
            return self.get_error_message_buyables()
        elif self.get_error_message_sellables() != "":
            return self.get_error_message_sellables()

        return ""

    #- Fine Metodo -

    def get_error_message_buyables(self):
        if not self.buyables:
            return "buyables non è stata impostata"

        for buyable in self.buyables:
            if buyable.get_error_message() != "":
                return buyable.get_error_message()

        return ""

    #- Fine Metodo -

    def get_error_message_sellables(self):
        for sellable in self.sellables:
            if sellable.entitype == ENTITYPE.NONE:
                if len(self.sellables) > 1:
                    return "Quando si esplicita il valore di ENTITYPE.NONE in un sellable deve essere il solo e unico."

        for sellable in self.sellables:
            if sellable.get_error_message() != "":
                return sellable.get_error_message()

        return ""

    #- Fine Metodo -

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

    #- Fine Metodo -

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

        if self.comment != shop2.comment:
            return False
        if self.types != shop2.types:
            return False

        for location in self.proto_locations:
            for location2 in shop2.proto_locations:
                if location == location2:
                    break
            else:
                return False

        for storage in self.proto_storages:
            for storage2 in shop2.proto_storages:
                if storage == storage2:
                    break
            else:
                return False

        if len(self.buyables) != len(shop2.buyables):
            return False
        for buyable in self.buyables:
            for buyable2 in shop2.buyables:
                if buyable.equals(buyable2):
                    break
            else:
                return False

        if len(self.sellables) != len(shop2.sellables):
            return False
        for sellable in self.sellables:
            for sellable2 in shop2.sellables:
                if sellable.equals(sellable2):
                    break
            else:
                return False

        if self.entity_buy_message != shop2.entity_buy_message: return False
        if self.others_buy_message != shop2.others_buy_message: return False
        if self.target_buy_message != shop2.target_buy_message: return False
        if self.dealer_buy_message != shop2.dealer_buy_message: return False
        if self.entity_cannot_afford_message != shop2.entity_cannot_afford_message:
            return False
        if self.others_cannot_afford_message != shop2.others_cannot_afford_message:
            return False
        if self.target_cannot_afford_message != shop2.target_cannot_afford_message:
            return False
        if self.dealer_cannot_afford_message != shop2.dealer_cannot_afford_message:
            return False
        if self.entity_sell_message != shop2.entity_sell_message: return False
        if self.others_sell_message != shop2.others_sell_message: return False
        if self.target_sell_message != shop2.target_sell_message: return False
        if self.dealer_sell_message != shop2.dealer_sell_message: return False
        if self.entity_offer_message != shop2.entity_offer_message:
            return False
        if self.others_offer_message != shop2.others_offer_message:
            return False
        if self.target_offer_message != shop2.target_offer_message:
            return False
        if self.dealer_offer_message != shop2.dealer_offer_message:
            return False
        if self.entity_uninterested_message != shop2.entity_uninterested_message:
            return False
        if self.others_uninterested_message != shop2.others_uninterested_message:
            return False
        if self.target_uninterested_message != shop2.target_uninterested_message:
            return False
        if self.dealer_uninterested_message != shop2.dealer_uninterested_message:
            return False

        return True

    #- Fine Metodo -

    def in_location(self, dealer):
        """
        Controlla se possa interagire nel luogo in cui si trova.
        """
        if not dealer:
            log.bug("dealer non è un parametro valido: %s" % dealer)
            return 0

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

        if not self.proto_locations:
            return True

        if dealer.location.prototype in self.proto_locations:
            return True

        return False

    #- Fine Metodo -

    def get_storage(self, dealer):
        """
        Ritorna il luogo in cui vengono inserite le cose da vendere, il magazzino.
        """
        if not dealer:
            log.bug("dealer non è un parametro valido: %s" % dealer)
            return 0

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

        if not self.proto_storages:
            return dealer

        # Da priorità al dealer e alla locazione nel qual caso vi siano
        # più storages tutti nella stessa stanza
        if dealer.prototype in self.proto_storages:
            return dealer
        if dealer.location.prototype in self.proto_storages:
            return dealer.location

        for en in dealer.iter_contains():
            if en.IS_PLAYER:
                continue
            if en.prototype in self.proto_storages:
                return en

        for en in dealer.location.iter_contains():
            if en.IS_PLAYER:
                continue
            if en.prototype in self.proto_storages:
                return en

        # Adesso invece cerca tra le stanze dell'area
        for room in dealer.location.area.rooms.values():
            if room.prototype in self.proto_storages:
                return room

        return None

    #- Fine Metodo -

    def get_buyable(self, purchase):
        """
        Ritorna la struttura di buyable relativa alla mercanzia passata.
        """
        if not purchase:
            log.bug("purchase non è un parametro valido: %s" % purchase)
            return None

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

        for buyable in self.buyables:
            if purchase.prototype == buyable.proto_entity:
                return buyable

        return None

    #- Fine Metodo -

    def get_sellable(self, target):
        """
        Ritorna il sellable del negoziante relativo all'entità passata, se
        possibile.
        """
        if not self.sellables:
            return None

        # Se viene impostato esplicitamente ENTITYPE.NONE allora accetta di
        # far vendere qualsiasi cosa al negoziante
        for sellable in self.sellables:
            if sellable.entitype == ENTITYPE.NONE:
                return sellable

        for sellable in self.sellables:
            if sellable.entitype == target.entitype:
                return sellable

        return None

    #- Fine Metodo -

    def storage_is_empty(self, storage):
        """
        Ritorna verso se il magazzino passato non ha mercanzia da vendere.
        """
        if not storage:
            log.bug("storage non è un parametro valido: %r" % storage)
            return False

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

        for en in storage.iter_contains():
            for buyable in self.buyables:
                if en.prototype == buyable.proto_entity:
                    return False

        return True

    #- Fine Metodo -

    def add_buyable(self, dealer, target, sellable, quantity):
        """
        Aggiunge una nuova entità comprabile al negoziante ma senza che questa
        abbia futura possibilità di aggiornare il proprio magazzino.
        """
        if not dealer:
            log.bug("dealer non è un parametro valido: %s" % dealer)
            return

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

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

        if quantity <= 0:
            log.bug("quantity non può essere minore o uguale a 0: %d" %
                    quantity)
            return

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

        # Se non c'è nessun magazzino in cui inserire l'entità allora esce
        storage = self.get_storage(dealer)
        if not storage:
            target.extract()
            return

        if not storage.IS_ROOM and not storage.can_carry_target(
                target, quantity=quantity):
            target.extract()
            return

        # Crea un buyable e lo aggiunge alla lista delle mercanzie del negozio
        buyable = Buyable()
        buyable.proto_entity = target.prototype
        buyable.percent = sellable.buyback_percent

        self.buyables.append(buyable)

    #- Fine Metodo -

    def send_buy_messages(self, entity, purchase, dealer, verbs, quantity,
                          pretty_price, discount):
        if not entity:
            log.bug("entity non è un parametro valido: %r" % entity)
            return

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

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

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

        if quantity < 0:
            log.bug("quantity non è un parametro valido: %d" % quantity)
            return

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

        if discount < 0:
            log.bug("discount non è un parametro valido: %d" % discount)
            return

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

        is_dispenser = SHOP.DISPENSER in dealer.shop.types

        discount_descr = ""
        if discount > 0:
            discount_descr = " scontato"

        quantity_descr = ""
        if quantity > 1:
            quantity_descr = "%d " % quantity

        if self.entity_buy_message:
            message = self.entity_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb",
                                              color_first_upper(verbs["you"]))
                else:
                    message = message.replace("%verb", verbs["you"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            if is_dispenser:
                message = "%s %s$N da $a inserendovi %s." % (color_first_upper(
                    verbs["you"]), quantity_descr, pretty_price)
            else:
                message = "%s %s$N da $a pagandol$O %s%s." % (
                    color_first_upper(verbs["you"]), quantity_descr,
                    pretty_price, discount_descr)
        entity.act(message, TO.ENTITY, purchase, dealer)

        if self.others_buy_message:
            message = self.others_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb",
                                              color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            if is_dispenser:
                message = "$n %s %s$N da $a inserendovi %s." % (
                    verbs["it"], quantity_descr, pretty_price)
            else:
                message = "$n %s %s$N da $a pagandol$O %s%s." % (
                    verbs["it"], quantity_descr, pretty_price, discount_descr)
        entity.act(message, TO.OTHERS, purchase, dealer)

        if self.target_buy_message:
            message = self.target_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb",
                                              color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            if is_dispenser:
                message = "$n ti %s da $a inserendovi %s." % (verbs["it"],
                                                              pretty_price)
            else:
                message = "$n ti %s da $a pagandoti %s%s." % (
                    verbs["it"], pretty_price, discount_descr)
        entity.act(message, TO.TARGET, purchase, dealer)

        if self.dealer_buy_message:
            message = self.dealer_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb",
                                              color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            if is_dispenser:
                message = "$n ti %s %s$N inserendoti %s." % (
                    verbs["it"], quantity_descr, pretty_price)
            else:
                message = "$n ti %s %s$N pagandol$O %s%s." % (
                    verbs["it"], quantity_descr, pretty_price, discount_descr)
        entity.act(message, TO.TARGET, dealer, purchase)

    #- Fine Metodo -

    def send_cannot_afford_messages(self, entity, purchase, dealer, verbs,
                                    quantity, pretty_price):
        if not entity:
            log.bug("entity non è un parametro valido: %r" % entity)
            return

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

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

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

        if quantity < 0:
            log.bug("quantity non è un parametro valido: %d" % quantity)
            return

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

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

        quantity_descr = ""
        if quantity > 1:
            quantity_descr = "%d " % quantity

        if self.entity_cannot_afford_message:
            message = self.entity_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace(
                        "%verb", color_first_upper(verbs["infinitive"]))
                else:
                    message = message.replace("%verb",
                                              verbs["infinitive"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            message = "Non hai abbastanza soldi per poter %s %s$N da $a: costa %s." % (
                verbs["infinitive"], quantity_descr, pretty_price)
        entity.act(message, TO.ENTITY, purchase, dealer)

        if self.others_cannot_afford_message:
            message = self.others_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace(
                        "%verb", color_first_upper(verbs["infinitive"]))
                else:
                    message = message.replace("%verb",
                                              verbs["infinitive"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            message = "$n non sembra avere abbastanza soldi per poter %s %s$N." % (
                verbs["infinitive"], quantity_descr)
        entity.act(message, TO.OTHERS, purchase, dealer)

        if self.target_cannot_afford_message:
            message = self.target_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace(
                        "%verb", color_first_upper(verbs["infinitive"]))
                else:
                    message = message.replace("%verb",
                                              verbs["infinitive"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            message = "$n non ha abbastanza soldi per poterti %s da $a." % verbs[
                "infinitive"]
        entity.act(message, TO.TARGET, purchase, dealer)

        if self.dealer_cannot_afford_message:
            message = self.dealer_buy_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace(
                        "%verb", color_first_upper(verbs["infinitive"]))
                else:
                    message = message.replace("%verb",
                                              verbs["infinitive"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        else:
            message = "$n non ha abbastanza soldi per poter %s %s$a da te." % (
                verbs["infinitive"], quantity_descr)
        entity.act(message, TO.TARGET, dealer, purchase)

    #- Fine Metodo -

    def send_sell_messages(self, entity, target, dealer, verbs, quantity,
                           pretty_price):
        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 not dealer:
            log.bug("dealer non è un parametro valido: %r", dealer)
            return

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

        if quantity < 0:
            log.bug("quantity non è un parametro valido: %d" % quantity)
            return

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

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

        quantity_descr = ""
        if quantity > 1:
            quantity_descr = "%d " % quantity

        if self.entity_sell_message:
            message = self.entity_sell_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb",
                                              color_first_upper(verbs["you"]))
                else:
                    message = message.replace("%verb", verbs["you"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        elif quantity <= 1:
            message = "%s $a a $N per %s." % (color_first_upper(
                verbs["you"]), pretty_price)
        else:
            message = "%s $N, in %d unità, a $a per %s." % (color_first_upper(
                verbs["you"]))
        entity.act(message, TO.ENTITY, target, dealer)

        if self.others_sell_message:
            message = self.entity_sell_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb",
                                              color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        elif quantity <= 1:
            message = "$n %s $N a $a per %s." % (verbs["it"], pretty_price)
        else:
            message = "$n %s $N, in %d unità, a $a per %s." % (
                verbs["it"], quantity, pretty_price)
        entity.act(message, TO.OTHERS, target, dealer)

        if target != entity:
            if self.target_sell_message:
                message = self.entity_sell_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message.replace(
                            "%verb", color_first_upper(verbs["it"]))
                    else:
                        message = message.replace("%verb", verbs["it"].lower())
                if "%quantity" in message:
                    message = message.replace("%quantity", quantity_descr)
                if "%price" in message:
                    message = message.replace("%price", pretty_price)
            elif quantity <= 1:
                message = "$n ti %s $N per %s." % (verbs["it"], pretty_price)
            else:
                message = "$n ti %s $N, in %d unità, per %s." % (
                    verbs["it"], quantity, pretty_price)
            entity.act(message, TO.TARGET, target, dealer)

        if dealer != entity:
            if self.dealer_sell_message:
                message = self.entity_sell_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message.replace(
                            "%verb", color_first_upper(verbs["it"]))
                    else:
                        message = message.replace("%verb", verbs["it"].lower())
                if "%quantity" in message:
                    message = message.replace("%quantity", quantity_descr)
                if "%price" in message:
                    message = message.replace("%price", pretty_price)
            elif quantity <= 1:
                message = "$n ti %s a $N per %s." % (verbs["it"], pretty_price)
            else:
                message = "$n ti %s a $N, in %d unità, per %s." % (
                    verbs["it"], quantity, pretty_price)
            entity.act(message, TO.TARGET, dealer, target)

    #- Fine Metodo -

    def send_offer_messages(self, entity, target, dealer, verbs, quantity,
                            pretty_price):
        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 not dealer:
            log.bug("dealer non è un parametro valido: %r", dealer)
            return

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

        if quantity < 0:
            log.bug("quantity non è un parametro valido: %d" % quantity)
            return

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

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

        quantity_descr = ""
        if quantity > 1:
            quantity_descr = "%d " % quantity

        if self.entity_offer_message:
            message = self.entity_offer_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb",
                                              color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        elif quantity <= 1:
            message = "$N ti %s %s per $N." % (verbs["it"], pretty_price)
        else:
            message = "$N ti %s %s per %d unità di $N." % (
                verbs["it"], pretty_price, quantity)
        entity.act(message, TO.ENTITY, target, dealer)

        if self.others_offer_message:
            message = self.entity_offer_message
            if "%verb" in message:
                if message.startswith("%verb"):
                    message = message.replace("%verb",
                                              color_first_upper(verbs["it"]))
                else:
                    message = message.replace("%verb", verbs["it"].lower())
            if "%quantity" in message:
                message = message.replace("%quantity", quantity_descr)
            if "%price" in message:
                message = message.replace("%price", pretty_price)
        elif quantity <= 1:
            message = "$N %s %s a $n per $N." % (verbs["it"], pretty_price)
        else:
            message = "$N %s %s a $n per %d unità di $N." % (
                verbs["it"], pretty_price, quantity)
        entity.act(message, TO.OTHERS, target, dealer)

        if target != entity:
            if self.target_offer_message:
                message = self.entity_offer_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message.replace(
                            "%verb", color_first_upper(verbs["you"]))
                    else:
                        message = message.replace("%verb",
                                                  verbs["you"].lower())
                if "%quantity" in message:
                    message = message.replace("%quantity", quantity_descr)
                if "%price" in message:
                    message = message.replace("%price", pretty_price)
            elif quantity <= 1:
                message = "%s a $n %s per $N." % (color_first_upper(
                    verbs["you"]), pretty_price)
            else:
                message = "%s a $n %s per %d unità di $N." % (
                    color_first_upper(verbs["you"], quantity), pretty_price)
            entity.act(message, TO.TARGET, target, dealer)

        if dealer != entity:
            if self.dealer_offer_message:
                message = self.entity_offer_message
                if "%verb" in message:
                    if message.startswith("%verb"):
                        message = message.replace(
                            "%verb", color_first_upper(verbs["it"]))
                    else:
                        message = message.replace("%verb", verbs["it"].lower())
                if "%quantity" in message:
                    message = message.replace("%quantity", quantity_descr)
                if "%price" in message:
                    message = message.replace("%price", pretty_price)
            elif quantity <= 1:
                message = "$a %s a $n %s per te." % (verbs["it"], pretty_price)
            else:
                message = "$a %s a $n %s per %d unità di te." % (
                    verbs["it"], pretty_price, quantity)
            entity.act(message, TO.TARGET, dealer, target)

    #- Fine Metodo -

    def send_uninterested_messages(self, entity, target, dealer):
        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 not dealer:
            log.bug("dealer non è un parametro valido: %r", dealer)
            return

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

        if self.entity_uninterested_message:
            entity.act(self.entity_uninterested_message, TO.ENTITY, target,
                       dealer)
        else:
            entity.act("$N non è una tipologia che a $a possa interessare.",
                       TO.ENTITY, target, dealer)

        if self.others_uninterested_message:
            entity.act(self.others_uninterested_message, TO.OTHERS, target,
                       dealer)
        else:
            entity.act(
                "$N di $n non è una tipologia che a $a possa interessare.",
                TO.OTHERS, target, dealer)

        if self.target_uninterested_message:
            entity.act(self.target_uninterested_message, TO.TARGET, target,
                       dealer)
        else:
            entity.act("Non sei una tipologia che a $a possa interessare.",
                       TO.TARGET, target, dealer)

        if self.dealer_uninterested_message:
            entity.act(self.dealer_uninterested_message, TO.TARGET, dealer,
                       target)
        else:
            entity.act(
                "Non sei interessato a $a di $n, non è simile alla tua mercanzia.",
                TO.TARGET, dealer, target)
Ejemplo n.º 20
0
class Plant(object):
    PRIMARY_KEY = ""
    VOLATILES = ["deferred_stage"]
    MULTILINES = ["comment"]
    SCHEMA = {
        "temperature": ("", "temperature"),
        "humidity": ("", "percent"),
        "contents": ("", "int"),
        "worse_affects": ("src.affect", "Affect"),
        "better_affects": ("src.affect", "Affect")
    }
    REFERENCES = {
        "worse_entity": ["proto_items", "proto_mobs"],
        "normal_entity": ["proto_items", "proto_mobs"],
        "better_entity": ["proto_items", "proto_mobs"],
        "dead_entity": ["proto_items", "proto_mobs"]
    }
    WEAKREFS = {}

    def __init__(self):
        self.comment = ""
        self.sectors = Flags(SECTOR.NONE)  # Settori in cui può essere seminato
        self.rpg_hours = 1  # Durata in ore rpg prima che questo stadio si attivi
        self.temperature = 20  # Temperatura media ideale
        self.humidity = 50  # Percentuale dell'umidità ideale
        self.contents = {
        }  # Dizionario con valori di codice_entità/quantità per popolare il contenuto dell'entità di questo stadio
        self.worse_entity = None  # Entità peggiore del prossimo stadio di crescita, se in questo stadio non viene curata o curata male
        self.normal_entity = None  # Entità normale del prossimo stadio di crescita, se in questo stadio viene curata normalmente
        self.better_entity = None  # Entità migliore del prossimo stadio di crescita, se in questo stadio viene curata molto bene
        self.dead_entity = None  # Entità morta relativa al prossimo stadio
        self.worse_affects = []  # Affect che danneggiano la pianta
        self.better_affects = []  # Affect che migliorano la pianta
        self.decomposition_rpg_hours = config.purification_rpg_hours  # Ore Rpg prima che il contenuto venga decomposto dopo essere caduta dalla pianta
        self.remaining_life = -1  # Cicli di vita rimanenti alla pianta prima di morire
        self.worse_counter = 0  # Contatore degli stadi di crescita andati male
        self.normal_counter = 0  # Contatore degli stadi di crescita andati normalmente
        self.better_counter = 0  # Contatore degli stadi di crescita andati ottimamente

        # Volatili
        self.deferred_stage = None

    #- Fine Inizializzazione -

    def get_error_message(self, entity):
        if self.remaining_life <= 0 and self.remaining_life != -1:
            return "remaining_life non è un'aspettativa di vita valida, deve essere maggiore di 0 oppure diverso da -1: %d" % self.remaining_life
        elif self.sectors.get_error_message(SECTOR, "sectors") != "":
            return self.sectors.get_error_message(SECTOR, "sectors")
        if self.rpg_hours <= 0:
            return "rpg_hours non è una durata in ore rpg valida: %d" % self.rpg_hours
        elif self.get_contents_error_message() != "":
            return self.get_contents_error_message()
        elif self.get_affects_error_message("worse_affects") != "":
            return self.get_affects_error_message("worse_affects")
        elif self.get_affects_error_message("better_affects") != "":
            return self.get_affects_error_message("better_affects")

        return ""

    #- Fine Metodo -

    def get_contents_error_message(self):
        for key, value in self.contents.iteritems():
            if not key:
                return "contents con chiave non valida (%r) per il valore %s" % (
                    key, value)
            if int(value) <= 0:
                return "contents con valore non valido (%d) per la chiave %s" % (
                    int(value), key)

        return ""

    #- Fine Metodo -

    def get_affects_error_message(self, attr_name):
        if attr_name not in ("worse_affects", "better_affects"):
            log.bug("attr_name non è un parametro valido: %s" % attr_name)
            return ""

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

        for affect in getattr(self, attr_name):
            error_message = affect.get_error_message()
            if error_message != "":
                return error_message
        return ""

    #- Fine Metodo -

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

    #- Fine Metodo -

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

        if self.deferred_stage or plant2.deferred_stage:
            return False

        if self.comment != plant2.comment:
            return False
        if self.sectors != plant2.sectors:
            return False
        if self.rpg_hours != plant2.rpg_hours:
            return False
        if self.temperature != plant2.temperature:
            return False
        if self.humidity != plant2.humidity:
            return False
        if self.worse_entity != plant2.worse_entity:
            return False
        if self.normal_entity != plant2.normal_entity:
            return False
        if self.better_entity != plant2.better_entity:
            return False
        if self.dead_entity != plant2.dead_entity:
            return False
        if self.decomposition_rpg_hours != plant2.decomposition_rpg_hours:
            return False
        if self.remaining_life != plant2.remaining_life:
            return False
        if self.worse_counter != plant2.worse_counter:
            return False
        if self.normal_counter != plant2.normal_counter:
            return False
        if self.better_counter != plant2.better_counter:
            return False

        if len(self.contents) != len(plant2.contents):
            return False
        for key, value in self.contents.iteritems():
            if key not in plant2.contents:
                return False
            if value != plant2.contents[key]:
                return False

        if len(self.worse_affects) != len(plant2.worse_affects):
            return False
        for affect in self.worse_affects:
            for affect2 in plant2.worse_affects:
                if affect == affect2:
                    break
            else:
                return False

        if len(self.better_affects) != len(plant2.better_affects):
            return False
        for affect in self.better_affects:
            for affect2 in plant2.better_affects:
                if affect == affect2:
                    break
            else:
                return False

        return True

    #- Fine Metodo -

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

    def start_growth(self, entity, type_attr_name):
        if not entity:
            log.bug("entity non è parametro valido: %r" % entity)
            return

        if type_attr_name not in ("plant_type", "seed_type"):
            log.bug("type_attr_name non è parametro valido: %r" %
                    type_attr_name)
            return

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

        seconds = self.rpg_hours * (config.seconds_in_minute *
                                    config.minutes_in_hour)
        self.deferred_stage = defer(seconds, self.next_stage, entity,
                                    type_attr_name)

    #- Fine Metodo -

    def stop_growth(self):
        if self.deferred_stage:
            self.deferred_stage.pause()
            self.deferred_stage = None

    #- Fine Metodo -

    def next_stage(self, old_entity, type_attr_name):
        if not old_entity:
            log.bug("old_entity non è parametro valido: %r" % old_entity)
            return

        if type_attr_name not in ("plant_type", "seed_type"):
            log.bug("type_attr_name non è parametro valido: %r" %
                    type_attr_name)
            return

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

        # Pulisce la deferred relativa a questo metodo in qualsiasi caso
        self.deferred_stage = None

        entitype = getattr(old_entity, type_attr_name)
        if not entitype:
            log.bug("%s dell'entità precedente non valido: %r" %
                    (type_attr_name, entitype))
            return

        # (TD) deve scegliere quale delle tre entità worse, normal o better
        # in maniera non casuale ma basandosi su effettivi fattori ambientali
        entitypes = []
        for entitype_name in ("worse_entity", "normal_entity",
                              "better_entity"):
            if getattr(entitype, entitype_name):
                entitypes.append(entitype_name)
        if not entitypes:
            log.bug(
                "Nessuna tipologia d'entità da utilizzare come prossimo stadio: %r"
                % entitypes)
            return
        choised_attr = random.choice(entitypes)

        # Se la vita della pianta è terminata e finalmente si trova un'entità
        # di pianta morta, allora la utilizza
        if entitype.remaining_life == 0 and entitype.dead_entity:
            choised_attr = "dead_entity"

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

        # Crea la nuova pianta a seconda delle scelte di cui sopra
        choised_entity = getattr(entitype, choised_attr)
        if not choised_entity:
            log.bug(
                "Impossibile continuare con la crescita della pianta da %s per la scelta %s"
                % (old_entity.code, choised_attr))
            return

        if choised_entity.max_global_quantity > 0 and choised_entity.current_global_quantity >= choised_entity.max_global_quantity:
            return

        new_entity = choised_entity.CONSTRUCTOR(choised_entity.code)

        # Passa alcune caratteristiche della vecchia entità nella nuova
        # prima di distruggerla
        if new_entity.plant_type:
            new_entity.flags += FLAG.GROWING
            new_entity.plant_type.remaining_life = entitype.remaining_life
            new_entity.plant_type.worse_counter = entitype.worse_counter
            new_entity.plant_type.normal_counter = entitype.normal_counter
            new_entity.plant_type.better_counter = entitype.better_counter
            quality_attr = choised_attr.split("_")[0] + "_counter"
            setattr(new_entity.plant_type, quality_attr,
                    getattr(new_entity.plant_type, quality_attr) + 1)

        # Inserisce la nuova entità in gioco
        new_entity.inject(old_entity.location)

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

        # Lista delle entità che cambieranno locazione nel ciclo sottostante
        # e che vengono passate nel trigger on_next_stage per comodità, vengono
        # salvati solo le entità frutta, seme e cibo
        entities = []

        # Controlla come deve comportarsi con il contenuto della vecchia entità:
        # se passarlo alla nuova, oppure distruggerlo, oppure ancora farlo
        # cadere a terra
        flower_counter = 0
        for content in old_entity.iter_contains(use_reversed=True):
            if content.entitype == ENTITYPE.FLOWER:
                flower_counter += 1
                continue
            elif content.entitype in (ENTITYPE.FRUIT, ENTITYPE.SEED,
                                      ENTITYPE.FOOD):
                content = content.from_location(content.quantity,
                                                use_repop=False)
                in_room = content.get_in_room()
                container_carrier = content.get_container_carrier()
                # Più la pianta è grande e maggiore è la probabilità che il suo
                # contenuto cada nella stanza invece che nel vaso
                if in_room and container_carrier and random.randint(
                        0,
                        max(
                            1,
                            math.log(new_entity.get_weight()) -
                            math.log(container_carrier.get_weight()))) == 0:
                    content.to_location(in_room)
                    entities.append(content)
                elif in_room and random.randint(
                        0, max(1, math.log(new_entity.get_weight()))) == 0:
                    content.to_location(in_room)
                    entities.append(content)
                elif container_carrier:
                    content.to_location(container_carrier)
                    entities.append(content)
                else:
                    content.to_location(old_entity.location)
                    entities.append(content)
                # Tutte le entità inserite a terra attivano un timer per
                # rimuoverle e non creare inutili mucchi di semi
                content.start_purification(entitype.decomposition_rpg_hours,
                                           decomposition=True)
            else:
                # (BB) qui se passavano delle entità di tipo food invece di
                # ENTITYPE.FRUIT bacava i riferimenti, probabilmente il
                # problema c'è ancora, per questo l'elif sopra accetta
                # anche food
                content = content.from_location(content.quantity,
                                                use_repop=False)
                content.to_location(new_entity)

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

        # Si salva tutti i semi per sapere se entità da inserire nella pianta
        # sia solo di tipo seme oppure se eventuali semi sono mischiati ad
        # altre tipo di entità, ciò serve perché in tal caso i semi vengono
        # inseriti nelle altre tipologie di entità (frutti o fiori chessia)
        seeds = []
        for proto_code, quantity in entitype.contents.iteritems():
            prototype = database.get_proto_entity(proto_code)
            if not prototype:
                continue
            if prototype.entitype == ENTITYPE.SEED:
                seeds.append([prototype, quantity])
        if len(seeds) == len(entitype.contents):
            seeds = []

        # Ogni volta che la pianta produce dei semi diminuisce le proprie
        # risorse vitali
        if seeds and new_entity.plant_type.remaining_life > 0:
            new_entity.plant_type.remaining_life -= 1

        # Crea l'eventuale contenuto voluto per la nuova entità
        for proto_code, quantity in entitype.contents.iteritems():
            prototype = database.get_proto_entity(proto_code)
            if not prototype:
                continue
            # Se il prototipo è un seme da inserire in un frutto o simile allora lo salta
            for seed in seeds:
                if prototype == seed[0]:
                    break
            else:
                add_content(prototype, quantity, choised_attr, flower_counter,
                            new_entity, seeds)

        # Crea, se è il caso, una tipologia di contenitore alla nuova entità
        # per permettere ai giocatori ad interagire con la pianta
        if not new_entity.container_type and new_entity.entitype == ENTITYPE.PLANT:
            container = Container()
            container.max_weight = new_entity.get_carried_weight() * 2
            new_entity.container_type = container

        # Avvisa dell'avvenuta crescita della pianta
        if new_entity.plant_type:
            message = "%s cresce: %s"
        else:
            message = "%s finisce di crescere: %s"
        log.plant(message %
                  (old_entity.prototype.code, new_entity.prototype.code))

        # Supporto gamescript, se viene forzato il ritorno non esegue
        # l'eventuale stadio successivo
        force_return = check_trigger(old_entity, "on_next_stage", old_entity,
                                     new_entity, choised_attr, entities)
        if force_return:
            return True

        # Ora si può rimuovere la vecchia pianta
        # (la si può estrarre completamente perché se possiede del contenuto non
        # viene raggruppata fisicamente, altrimenti si può rimuovere il gruppetto
        # senza problemi perché senza contenuto)
        old_entity.extract(old_entity.quantity, use_repop=False)

        # Prepara il lancio per il prossimo stage
        if choised_attr != "dead_entity" and new_entity.plant_type:
            new_entity.plant_type.start_growth(new_entity, "plant_type")