def create_js_menu_inventory(target, entity): """ Crea un menù javascript apribile con il tasto destro sul link dell'entità in inventario. Permette di guardare o droppare un'entità. """ if not target: log.bug("target non è un parametro valido: %r" % target) return "" if not entity: log.bug("entity non è un parametro valido: %r" % entity) return "" # ------------------------------------------------------------------------- look_translation = translate_input(entity, "look", "en") if not look_translation: log.bug("look_translation non è valida: %r" % look_translation) look_translation = "guarda" drop_translation = translate_input(entity, "drop", "en") if not drop_translation: log.bug("drop_translation non è valida: %r" % drop_translation) drop_translation = "posa" keywords = target.get_keywords_attr(entity) if not keywords: log.bug("keywords non è valida: %r" % keywords) return "" # (TD) return ""
def defeat(self, active_entity, passive_entity, active, passive): # Può accadere visto che il metodo è deferrato if not passive_entity: return if not passive_entity.IS_ITEM: if active_entity.IS_MOB: passive_entity.defeat_from_mob_counter += 1 elif active_entity.IS_ITEM: passive_entity.defeat_from_item_counter += 1 elif active_entity.IS_PLAYER: passive_entity.defeat_from_player_counter += 1 if passive_entity.IS_ITEM: active_entity.item_defeated_counter += 1 elif passive_entity.IS_PLAYER: active_entity.player_defeated_counter += 1 else: active_entity.mob_defeated_counter += 1 if passive_entity.IS_ITEM: if self.code.startswith("rip_item_broken-"): active_entity.act("\nDopo il colpo che gli hai inferto $N si polverizza.", TO.ENTITY, passive_entity) active_entity.act("Dopo il colpo che $n gli ha inferto $N si polverizza.", TO.OTHERS, passive_entity) active_entity.act("Dopo il colpo che $n ti ha inferto ti polverizzi.", TO.TARGET, passive_entity) else: active_entity.act("\nDopo il colpo che gli hai inferto $N si rompe.", TO.ENTITY, passive_entity) active_entity.act("Dopo il colpo che $n gli ha inferto $N si rompe.", TO.OTHERS, passive_entity) active_entity.act("Dopo il colpo che $n ti ha inferto ti rompi.", TO.TARGET, passive_entity) active_entity.send_prompt(show_opponent=False) else: active_entity.act("\nDopo il colpo che gli hai inferto $N stramazza al suolo.", TO.ENTITY, passive_entity) active_entity.act("Dopo il colpo che $n gli ha inferto $N stramazza al suolo.", TO.OTHERS, passive_entity) active_entity.act("Dopo il colpo che $n ti ha inferto stramazzi al suolo.", TO.TARGET, passive_entity) #passive_entity.send_output('''<script>$("#output").vibrate()</script>''') # (bb) self.gain_xp(active_entity, passive_entity, active, passive) # A seconda del numero di morti il gap dei px persi è maggiore, # alle prime morti è zero died_counter = passive_entity.defeat_from_mob_counter + passive_entity.defeat_from_item_counter + passive_entity.death_from_player_counter malus = 1 if died_counter > 0: malus = math.log(died_counter) self.loose_xp(active_entity, passive_entity, active, passive) # Se è un giocatore bisogna digitare il comando kill per finirlo if active_entity.IS_PLAYER and passive_entity.IS_PLAYER: from src.interpret import translate_input passive_entity.flags += FLAG.BEATEN kill_translation = translate_input(active_entity, "kill", "en") javascript_code = '''javascript:parent.sendInput('%s %s');''' % ( kill_translation, passive_entity.get_numbered_keyword(looker=active_entity)) active_entity.send_output('''\nHai vinto! Se vuoi finire %s <a href="%s">uccidil%s</a>.\n''' % ( passive_entity.get_name(active_entity), javascript_code, grammar_gender(passive_entity))) else: # Altrimenti se è un'entità muore o di rompe in automatico if active_entity.IS_PLAYER and active_entity.account and OPTION.AUTO_LOOT in active_entity.account.options: passive_entity.dies(opponent=active_entity, auto_loot=True) else: passive_entity.dies(opponent=active_entity)
def get_command_syntax(entity, fun_name): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return "" if not fun_name: log.bug("fun_name non è un parametro valido: %r" % fun_name) return "" # ------------------------------------------------------------------------- module = database["commands"][fun_name].module if not module: log.bug("module non è valido: %r" % module) return "" syntax_string = getattr(module, "get_syntax_template")(entity) if not syntax_string: log.bug("syntax_string non è valida: %r" % syntax_string) return "" # Ricava il nome dell'input dalla funzione del comando input_word = fun_name[fun_name.find("_") + 1:] # Ricava la traduzione dell'input a seconda della lingua dei # comandi utilizzata dall'entità translation = translate_input(entity, input_word, "en") # Preparare ed invia la tabella con la sintassi colorata del comando output = '''<table class="mud">''' for x, line in enumerate(syntax_string.split("\n")): if not line.strip(): continue # Esegue un replace di tutti i simboli di minore e maggiore che devono # essere passati nella pagina come entità html line = html_escape(line) # Se trova uno spazio significa che ci sono argomenti aggiuntivi # al comando normale che colora di verde più scuro if " " in line: line = line.replace(input_word, "[limegreen]%s[close][green]" % translation, 1) else: line = line.replace(input_word, "[limegreen]%s" % translation, 1) line = '''<td>%s[close]</td></tr>''' % line # Alla prima linea inserisce la dicitura di Sintassi, alle altre dello # spazio per incolonnare correttamente if x == 0: line = '''<tr><td>[yellow]Sintassi[close]:</td>%s''' % line else: line = '''<tr><td></td>%s''' % line output += line output += '''</table>''' return output
def get_command_syntax(entity, fun_name): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return "" if not fun_name: log.bug("fun_name non è un parametro valido: %r" % fun_name) return "" # ------------------------------------------------------------------------- module = database["commands"][fun_name].module if not module: log.bug("module non è valido: %r" % module) return "" syntax_string = getattr(module, "get_syntax_template")(entity) if not syntax_string: log.bug("syntax_string non è valida: %r" % syntax_string) return "" # Ricava il nome dell'input dalla funzione del comando input_word = fun_name[fun_name.find("_")+1 : ] # Ricava la traduzione dell'input a seconda della lingua dei # comandi utilizzata dall'entità translation = translate_input(entity, input_word, "en") # Preparare ed invia la tabella con la sintassi colorata del comando output = '''<table class="mud">''' for x, line in enumerate(syntax_string.split("\n")): if not line.strip(): continue # Esegue un replace di tutti i simboli di minore e maggiore che devono # essere passati nella pagina come entità html line = html_escape(line) # Se trova uno spazio significa che ci sono argomenti aggiuntivi # al comando normale che colora di verde più scuro if " " in line: line = line.replace(input_word, "[limegreen]%s[close][green]" % translation, 1) else: line = line.replace(input_word, "[limegreen]%s" % translation, 1) line = '''<td>%s[close]</td></tr>''' % line # Alla prima linea inserisce la dicitura di Sintassi, alle altre dello # spazio per incolonnare correttamente if x == 0: line = '''<tr><td>[yellow]Sintassi[close]:</td>%s''' % line else: line = '''<tr><td></td>%s''' % line output += line output += '''</table>''' return output
def get_inventory_list(looker, target): if not looker: log.bug("looker non è un parametro valido: %r" % looker) return [] if not target: log.bug("target non è un parametro valido: %r" % target) return [] # ------------------------------------------------------------------------- from src.find_entity import INSTANCE, COUNTER, NO_LOOK_LIST, BURIED, INGESTED, INCOGNITO look_translation = translate_input(looker, "look", "en") if not look_translation: log.bug("look_translation non è valida: %r" % look_translation) look_translation = "guarda" output = [] for possession in target.get_list_of_entities(looker, admin_descrs=True): if not looker.can_see(possession[INSTANCE]): continue # Si suppone che se il giocatore ha con sé un oggetto no look list # sappia della sua esistenza if looker != target and FLAG.NO_LOOK_LIST in possession[INSTANCE].flags: continue if FLAG.INTERACTABLE_FROM_OUTSIDE in possession[INSTANCE].flags and possession[INSTANCE].location != target: continue interactable_entities = list(possession[INSTANCE].iter_only_interactable_entities(use_can_see=True)) if "$i" in possession[INSTANCE].long or "$I" in possession[INSTANCE].long or interactable_entities: # (TT) Far vedere la long al posto della short nell'inventario # per tutte e quante le entità: da pensare! name = possession[INSTANCE].get_long(looker, look_translation) else: name = possession[INSTANCE].get_formatted_name(looker, location=target, look_translation=look_translation) output.append('''%s pesante %s, %s.''' % ( name, get_weight_descr(possession[INSTANCE].get_total_weight()), possession[INSTANCE].get_condition())) if possession[COUNTER] > 1: output.append(" (%s)" % possession[COUNTER]) if looker.trust > TRUST.PLAYER: if looker == target: message = "%s%s%s" % (possession[BURIED], possession[INGESTED], possession[INCOGNITO]) else: message = "%s%s%s%s" % (possession[NO_LOOK_LIST], possession[BURIED], possession[INGESTED], possession[INCOGNITO]) if message: output.append(" " + format_for_admin(message.lstrip())) output.append("\n") # È corretto che possa ritornare output vuoto, viene gestito esternamente return output
def render_GET(self, request, conn): mapping = {"players" : self.create_player_options(request, conn), "look" : translate_input(conn, "look", "en", colorize=True), "listen" : translate_input(conn, "listen", "en", colorize=True), "smell" : translate_input(conn, "smell", "en", colorize=True), "touch" : translate_input(conn, "touch", "en", colorize=True), "taste" : translate_input(conn, "taste", "en", colorize=True), "intuition" : translate_input(conn, "intuition", "en", colorize=True)} return self.PAGE_TEMPLATE.safe_substitute(mapping)
def render_GET(self, request, conn): mapping = { "players": self.create_player_options(request, conn), "look": translate_input(conn, "look", "en", colorize=True), "listen": translate_input(conn, "listen", "en", colorize=True), "smell": translate_input(conn, "smell", "en", colorize=True), "touch": translate_input(conn, "touch", "en", colorize=True), "taste": translate_input(conn, "taste", "en", colorize=True), "intuition": translate_input(conn, "intuition", "en", colorize=True) } return self.PAGE_TEMPLATE.safe_substitute(mapping)
def get_see_also_links(entity, see_also): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return "" if not see_also: log.bug("see_also non è un parametro valido: %r" % see_also) return "" # ------------------------------------------------------------------------- help_translation = translate_input(entity, "help", "en") if not help_translation: log.bug("help_translation non valido: %r" % help_translation) help_translation = "aiuto" output = "[white]Vedi anche[close]: " # Supporto ai SeeAlso composti da solo link if see_also.lower().startswith("<a "): return output + see_also for help_code in see_also.split(): help_code = help_code.strip(",") if help_code not in database["helps"]: log.bug("help_code %s non si trova tra gli helps" % help_code) continue help = database["helps"][help_code] if entity.IS_PLAYER and OPTION.ITALIAN in entity.account.options: help_keyword, dummy = one_argument(help.italian_keywords) else: help_keyword, dummy = one_argument(help.english_keywords) javascript_code = '''javascript:parent.sendInput('%s %s');''' % ( help_translation, help_keyword) output += '''<a href="%s">%s</a>, ''' % (javascript_code, help_keyword) return output.rstrip(", ")
def get_equipment_list(entity, target): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False if not target: log.bug("target non è un parametro valido: %r" % target) return False # ------------------------------------------------------------------------- look_translation = translate_input(entity, "look", "en") if not look_translation: log.bug("look_translation non è valida: %r" % look_translation) look_translation = "guarda" location = None if entity != target: location = target output = [] # Questo serve ad evitare di visualizzare tot volte la stessa entità se # questa copre più parti del corpo already_founds = [] # (TD) NO non va bene, bisogna farlo ordinato a seconda delle dichiarazioni # fatte nei vari bodies files, devo aggiungere un numero alla classe Part # e fare un ordinamento come ho fatto con gli EnumElement body_parts = target.get_body_parts() for part in PART.elements: # Evita di visualizzare parti estranee (check che in realtà non dovrebbe # servire essendo controllato nel wear) o organi interni if part not in body_parts: continue # Gli admin vedono anche gli organi interni, se eventualmente vestiti if PARTFLAG.INTERNAL in body_parts[part].flags and entity.trust == TRUST.PLAYER: continue if PARTFLAG.NO_EQUIP_LIST in body_parts[part].flags: continue under_weareds = [] for weared_entity in target.iter_contains(): if weared_entity.under_weared and weared_entity.under_weared(): under_weareds.append(weared_entity.under_weared()) for weared_entity in target.iter_contains(): if weared_entity in already_founds: continue if weared_entity in under_weareds: continue if len(weared_entity.wear_mode) > 0: part_descriptions = get_part_descriptions(weared_entity, "equip", target, entity) if entity == target: part_descr = part_descriptions[TO.ENTITY] else: part_descr = part_descriptions[TO.OTHERS] if part in weared_entity.wear_mode: output.append('''%s %s\n''' % ( weared_entity.get_formatted_name(looker=entity, location=location, look_translation=look_translation), part_descr)) already_founds.append(weared_entity) holded = target.get_holded_entity() wielded = target.get_wielded_entity() if holded or wielded: look_translation = translate_input(entity, "look", "en") if not look_translation: log.bug("look_translation non è valida: %r" % look_translation) look_translation = "guarda" if holded: if holded.weapon_type: holded_verb = "impugnat%s" % grammar_gender(holded) else: holded_verb = "tenut%s" % grammar_gender(holded) holded_name = holded.get_formatted_name(looker=entity, location=location, look_translation=look_translation) if wielded: if wielded.weapon_type: wielded_verb = "impugnat%s" % grammar_gender(wielded) else: wielded_verb = "tenut%s" % grammar_gender(wielded) wielded_name = wielded.get_formatted_name(looker=entity, location=location, look_translation=look_translation) equipment_line_hold = "" equipment_line_wield = "" if target == entity: if holded and holded == wielded: equipment_line_hold = "%s %s con tutte e due le $hands\n" % (holded_name, holded_verb) else: if holded: equipment_line_hold = "%s %s nella $hand2\n" % (holded_name, holded_verb) if wielded: equipment_line_wield = "%s %s nella $hand1\n" % (wielded_name, wielded_verb) else: if holded and holded == wielded: equipment_line_hold = "%s %s con tutte e due le $HANDS\n" % (holded_name, holded_verb) else: if holded: equipment_line_hold = "%s %s nella $HAND2\n" % (holded_name, holded_verb) if wielded: equipment_line_wield = "%s %s nella $HAND1\n" % (wielded_name, wielded_verb) if equipment_line_hold: output.append(entity.replace_act_tags(equipment_line_hold, target=target)) if equipment_line_wield: output.append(entity.replace_act_tags(equipment_line_wield, target=target)) return output
def defeat(self, active_entity, passive_entity, active, passive): # Può accadere visto che il metodo è deferrato if not passive_entity: return if not passive_entity.IS_ITEM: if active_entity.IS_MOB: passive_entity.defeat_from_mob_counter += 1 elif active_entity.IS_ITEM: passive_entity.defeat_from_item_counter += 1 elif active_entity.IS_PLAYER: passive_entity.defeat_from_player_counter += 1 if passive_entity.IS_ITEM: active_entity.item_defeated_counter += 1 elif passive_entity.IS_PLAYER: active_entity.player_defeated_counter += 1 else: active_entity.mob_defeated_counter += 1 if passive_entity.IS_ITEM: if self.code.startswith("rip_item_broken-"): active_entity.act( "\nDopo il colpo che gli hai inferto $N si polverizza.", TO.ENTITY, passive_entity) active_entity.act( "Dopo il colpo che $n gli ha inferto $N si polverizza.", TO.OTHERS, passive_entity) active_entity.act( "Dopo il colpo che $n ti ha inferto ti polverizzi.", TO.TARGET, passive_entity) else: active_entity.act( "\nDopo il colpo che gli hai inferto $N si rompe.", TO.ENTITY, passive_entity) active_entity.act( "Dopo il colpo che $n gli ha inferto $N si rompe.", TO.OTHERS, passive_entity) active_entity.act( "Dopo il colpo che $n ti ha inferto ti rompi.", TO.TARGET, passive_entity) active_entity.send_prompt(show_opponent=False) else: active_entity.act( "\nDopo il colpo che gli hai inferto $N stramazza al suolo.", TO.ENTITY, passive_entity) active_entity.act( "Dopo il colpo che $n gli ha inferto $N stramazza al suolo.", TO.OTHERS, passive_entity) active_entity.act( "Dopo il colpo che $n ti ha inferto stramazzi al suolo.", TO.TARGET, passive_entity) #passive_entity.send_output('''<script>$("#output").vibrate()</script>''') # (bb) self.gain_xp(active_entity, passive_entity, active, passive) # A seconda del numero di morti il gap dei px persi è maggiore, # alle prime morti è zero died_counter = passive_entity.defeat_from_mob_counter + passive_entity.defeat_from_item_counter + passive_entity.death_from_player_counter malus = 1 if died_counter > 0: malus = math.log(died_counter) self.loose_xp(active_entity, passive_entity, active, passive) # Se è un giocatore bisogna digitare il comando kill per finirlo if active_entity.IS_PLAYER and passive_entity.IS_PLAYER: from src.interpret import translate_input passive_entity.flags += FLAG.BEATEN kill_translation = translate_input(active_entity, "kill", "en") javascript_code = '''javascript:parent.sendInput('%s %s');''' % ( kill_translation, passive_entity.get_numbered_keyword(looker=active_entity)) active_entity.send_output( '''\nHai vinto! Se vuoi finire %s <a href="%s">uccidil%s</a>.\n''' % (passive_entity.get_name(active_entity), javascript_code, grammar_gender(passive_entity))) else: # Altrimenti se è un'entità muore o di rompe in automatico if active_entity.IS_PLAYER and active_entity.account and OPTION.AUTO_LOOT in active_entity.account.options: passive_entity.dies(opponent=active_entity, auto_loot=True) else: passive_entity.dies(opponent=active_entity)
def command_kill(entity, argument="", verbs=VERBS, behavioured=False): if not verbs: log.bug("verbs non è un parametro valido: %r" % verbs) return False # ------------------------------------------------------------------------- # È possibile se il comando è stato deferrato if not entity: return False entity = entity.split_entity(1) if not argument: entity.send_output("Chi o che cosa vorresti %s?" % verbs["infinitive"]) if entity.IS_PLAYER and OPTION.NEWBIE in entity.account.options: syntax = get_command_syntax(entity, "command_kill") entity.send_output(syntax, break_line=False) return False # (TD) Controllo sul mental state # Cerca la vittima da attaccare entity_tables = ["mobs", "players"] target = entity.find_entity(argument, location=entity.location, entity_tables=entity_tables, avoid_equipment=True) if not target: target = entity.find_entity(argument, location=entity.location, entity_tables=["items"], avoid_equipment=True, compare_functions=[is_same]) if target: destroy_translation = translate_input(entity, "destroy", "en") javascript_code = '''javascript:parent.sendInput('%s %s');''' % ( destroy_translation, target.get_numbered_keyword(looker=entity)) destroy_verb = DESTROY_VERBS["noun"] % grammar_gender(target) html_code = '''<a href="%s">%s</a>''' % (javascript_code, destroy_verb) entity.act( "Non puoi %s $N ma puoi sempre %s!" % (verbs["infinitive"], html_code), TO.ENTITY, target) entity.act( "$n si guarda attorno con [red]brama di sangue[close]...", TO.OTHERS, target) entity.act("$N ti guarda con [red]brama di sangue[close]...", TO.TARGET, target) else: entity.act( "Non trovi nessun [white]%s[close] da %s" % (argument, verbs["infinitive"]), TO.ENTITY) entity.act( "$n si guarda attorno con [red]brama di sangue[close]...", TO.OTHERS) return False if FLAG.BEATEN in target.flags: force_return = check_trigger(entity, "before_kill", entity, target, behavioured) if force_return: return True force_return = check_trigger(target, "before_killed", entity, target, behavioured) if force_return: return True entity.act("Dai il [red]colpo di grazia[close] a $N!", TO.ENTITY, target) entity.act("$n dà il [red]colpo di grazia[close] a $N!", TO.OTHERS, target) entity.act("$n ti dà il [red]colpo di grazia[close]!", TO.TARGET, target) target.dies(opponent=entity) entity.player_killed_counter += 1 target.death_from_player_counter += 1 force_return = check_trigger(entity, "after_kill", entity, target, behavioured) if force_return: return True force_return = check_trigger(target, "after_killed", entity, target, behavioured) if force_return: return True return True # Se non sta combattendo procede all'attacco o alla distruzione della vittima if entity.is_fighting(with_him=target): entity.act( "Non è ancora giusto il momento di dare il colpo di grazia a $N.", TO.ENTITY, target) entity.act( "$n vorrebbe dare il colpo di grazia a $N, ma non è ancora giunto il suo momento...", TO.OTHERS, target) entity.act( "$n vorrebbe darti il colpo di grazia, ma non è ancora giunto il tuo momento...", TO.TARGET, target) return False if target.IS_ITEM: execution_result = kill_handler(entity, argument, "command_kill", entity_tables, verbs=DESTROY_VERBS, behavioured=behavioured) else: execution_result = kill_handler(entity, argument, "command_kill", entity_tables, verbs=ATTACK_VERBS, behavioured=behavioured) return execution_result
def command_tell(entity, argument=""): """ Permette di parlare con tutti nel Mud, in maniera off-gdr. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- if not argument: entity.send_output("Vuoi %s a qualcuno che cosa?" % CHANNEL.TELL) if entity.IS_PLAYER and OPTION.NEWBIE in entity.account.options: syntax = get_command_syntax(entity, "command_tell") entity.send_output(syntax, break_line=False) return False # Qui per la ricerca di target non viene utilizzata la find_entity perché # deve cercare solo i giocatori online # (TD) oltre alla ricerca di admin che possiedono mob o oggetti arg, argument = one_argument(argument) target = search_for_player(entity, arg) if not target: # (TD) se non è stato tovato allora cerca tra gli identificativi # personali relativi ai personaggi invisibili (implementazione # alternativa del reply) entity.send_output( "Non è stato trovato nessun giocatore con argomento [white]%s[close]" % arg) return False # (TD) possibile implementazione di NOTELL, anche se è preferibile punizione # classica di NO_ENTER_IN_GAME per tot giorni if entity == target: entity.send_output("Non puoi comunicare con [white]te stess$o[close]!") return False if not target.game_request: entity.send_output( "Il giocatore [white]%s[close] è attualmente [darkslategray]offline[close]." % target.name) return False if not argument: entity.send_output( "Che messaggio privato vorresti inviare a [white]%s[close]?" % target.name) return False channel_color = get_first_color(str(CHANNEL.TELL)) afk_status = "" if FLAG.AFK in target.flags: if entity.account and OPTION.ITALIAN in entity.account.options: afk_status = " (LDT)" else: afk_status = " (AFK)" if is_vowel(remove_colors(target.name)[0]): preposition = "ad" else: preposition = "a" entity.send_output("%s %s%s[close] %s: %s'%s'" % (CHANNEL.TELL.verb_you, channel_color, preposition, target.name, afk_status, argument), avoid_snoop=True) # (TD) inviare anche il soft beep per avvertire che ha ricevuto un messaggio # ed aggiungere l'opzione apposita if target.get_conn().get_browser(): numbered_keyword = entity.get_numbered_keyword(looker=target) javascript = '''javascript:putInput('%s %s ');''' % (translate_input( target, "tell", "en"), numbered_keyword) target.send_output("""\n<a href="%s">%s%s ti[close]%s</a>: '%s'""" % (javascript, entity.name, channel_color, CHANNEL.TELL.verb_it, argument), avoid_snoop=True) else: target.send_output( """\n%s %sti[close]%s: '%s'""" % (entity.name, channel_color, CHANNEL.TELL.verb_it, argument), avoid_snoop=True) target.send_prompt() return True
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"><</a> </div>''' % js_minimum_arguments browse_to_right = '''<div style="float:left"> <a href="javascript:sendInput('%s')" style="font-size:larger">></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
def move(self, direction, behavioured=False, following=False, fleeing=False, fall_number=0): """ Se possibile muove l'entità verso la direzione voluta. """ if not direction: log.bug("direction non è un parametro valido: %r" % direction) return False if fall_number < 0 or fall_number > 10000: log.bug("fall_number non è un parametro valido: %d" % fall_number) return False # --------------------------------------------------------------------- self = self.split_entity(1) if self.location.IS_ITEM: self.send_output("Devi uscire da %s prima di poter andare a %s." % ( self.location, direction)) return False if self.location.IS_ACTOR: self.send_output("Devi uscire dall'inventario di %s prima di poter andare a %s." % ( self.location, direction)) return False if self.position < POSITION.STAND: self.send_output("Devi almeno essere in piedi per poter andare a %s." % direction) return False drunk, mount_drunk = self.has_drunk_walking() drunk_direction = None mount_drunk_direction = None if fall_number == 0: if drunk: drunk_direction.randomize() if mount_drunk: mount_drunk_direction.randomize() # Se non è possibile andare da quella parte e non vi è nemmeno una porta # stampa dei messaggi appositi. # (TD) visto che per ora non ci si può ubriacare evito i messaggi per il drunk walking if drunk and not mount_drunk: if drunk_direction not in self.location.exits or EXIT.DIGGABLE in self.location.exits[drunk_direction].flags: return False elif drunk and mount_drunk: # Quando sia cavalcatura e padrone sono ubriachi sceglie a caso # la direzione 'ubriaca' tra le due if random.randint(0, 1) == 0: choised_direction = mount_drunk_direction else: choised_direction = drunk_direction if choised_direction not in self.location.exits or EXIT.DIGGABLE in self.location.exits[choised_direction].flags: return False elif not drunk and mount_drunk: if mount_drunk_direction not in self.location.exits or EXIT.DIGGABLE in self.location.exits[mount_drunk_direction].flags: return False else: if direction not in self.location.exits or EXIT.DIGGABLE in self.location.exits[direction].flags: self.send_output("Non ti è possibile andare verso %s." % direction) return False # Se l'uscita ha una porta e questa è chiusa blocca il percorso o # controlla se sia per caso una finestra door = self.location.get_door(direction) if door: # Se l'uscita è una finestra non c'è modo di oltrepassarla a meno # che non sia una porta-finestra # (TD) è un controllo da effettuare quando avrò creato gli oggetti, per ora fatto alla buona if door.door_type and DOOR.WINDOW in door.door_type.flags: self.send_output("Non c'è nessuna porta verso %s ma una finestra." % direction) return False # (TD) Se l'uscita è una porta e questa è chiusa ci si va' contro # a meno che non abbia attivato l'opzione AUTO_OPEN, in quel caso # apre la porta automaticamente if self != door and door.door_type and DOOR.CLOSED in door.door_type.flags: if door.door_type and DOOR.SECRET in door.door_type.flags: self.send_output("Non ti è possibile andare verso %s." % direction) return False else: # Se l'uscita è una porta liscia liscia ed apribile andandoci # contro la porta verrà aperta automatica tramite l'opzione # AUTO_OPEN; lo stesso controllo viene effettuato più sotto if (self.IS_PLAYER and OPTION.AUTO_OPEN in self.account.options and DOOR.LOCKED not in door.door_type.flags and DOOR.NO_USE_DIR not in door.door_type.flags): if OPTION.ITALIAN in self.account.options: return command_open(self, door.get_numbered_keyword(looker=self)) else: return command_open(self, door.get_numbered_keyword(looker=self)) else: self.send_output("Non puoi andare %s, c'è %s%s." % (direction.to_dir2, door.get_name(self), door.door_type.get_status(door.sex))) return False reverse_door = self.location.get_door(direction, direct_search=False) if reverse_door: if reverse_door.door_type and DOOR.WINDOW in reverse_door.door_type.flags: self.send_output("Non c'è nessuna porta verso %s ma una finestra." % direction) return False if reverse_door.door_type and DOOR.CLOSED in reverse_door.door_type.flags: if self != reverse_door and reverse_door.door_type and DOOR.SECRET in reverse_door.door_type.flags: if (self.IS_PLAYER and OPTION.AUTO_OPEN in self.account.options and DOOR.LOCKED not in door.door_type.flags and DOOR.NO_USE_DIR not in door.door_type.flags): if OPTION.ITALIAN in self.account.options: return command_open(self, direction.name) else: return command_open(self, direction.english) else: self.send_output("Non ti è possibile andare verso %s." % direction) return False else: self.send_output("Non puoi andare %s, c'è %s%s." % (direction.to_dir2, reverse_door.get_name(self), reverse_door.door_type.get_status(reverse_door.sex))) return False # Se l'entità è sotto charm e il suo padrone è nei paraggi questa # non può andarsene if (fall_number == 0 and is_affected(self, "charm") and self.owner() and self.location == self.owner().location): if self.master.sex == SEX.FEMALE: self.send_output("No! Non vuoi stare lontano dalla tua Padrona.") else: self.send_output("No! Non vuoi stare lontano dal tuo Padrone.") return False # (TD) Se l'area della nuova stanza è differente da quella precedente # cerca di inviare un *.mid tramite send_audio se questo esiste # (Vedere il bard per questo) pass # (TD) ci sono così tante cose da fare ancora che lascio perdere.. # facciamo finta di nulla e facciamo passare sta povera entità.. if fall_number == 0: pass # Finalmente trova la stanza di destinazione e muove l'entità laggiù # (TD) devo ricordarmi di aggiungere le due "direzioni ubriache" destination_room = self.location.get_destination_room(direction) if not destination_room: if self.IS_PLAYER: log.bug("destination inesistente partendo dalla stanza %s %d %d %d e andando verso %s" % ( self.area.code, self.location.x, self.location.y, self.location.z, direction)) self.send_output("Non ti è possibile andare verso %s." % str(direction).lower()) return False if (not following and self.IS_MOB and EXIT.NO_MOB in self.location.exits[direction].flags or not following and self.IS_ITEM and EXIT.NO_ITEM in self.location.exits[direction].flags or not following and self.IS_ROOM and EXIT.NO_ROOM in self.location.exits[direction].flags or self.IS_PLAYER and EXIT.NO_PLAYER in self.location.exits[direction].flags): self.act("Ti è proibito andare verso %s." % direction, TO.ENTITY) self.act("$n cerca di andare verso %s ma gli è proibito." % direction, TO.OTHERS) return False if (not following and self.IS_MOB and ROOM.NO_MOB in destination_room.flags or not following and self.IS_ITEM and ROOM.NO_ITEM in destination_room.flags or not following and self.IS_ROOM and ROOM.NO_ROOM in destination_room.flags or self.IS_PLAYER and ROOM.NO_PLAYER in destination_room.flags): self.act("Ti è proibito entrare in $N.", TO.ENTITY, destination_room) # (GR) self.act("$n cerca di entrare in $N ma gli è proibito.", TO.OTHERS, destination_room) # (GR) return False # Se si sta combattendo allora non si può muoversi normalmente # ma tramite il flee, automatico o meno if not fleeing and self.is_fighting() and self.get_opponent().location == self.location: if self.IS_PLAYER and OPTION.AUTO_FLEE in self.account.options: return command_flee(self, direction.english_nocolor) else: flee_translation = translate_input(self, "flee", "en") if not flee_translation: log.bug("flee_translation non è valido: %r" % flee_translation) flee_translation = "fuggi" javascript_code = '''javascript:parent.sendInput('%s');''' % flee_translation self.send_output('''Se vuoi andartene mentre stai combattendo, <a href="%s">fuggi</a>!''' % javascript_code) return False # Controlla se l'entità stia correndo, cioè se stia inviando comandi # di movimento con una certa frequenza running = False if self.last_movement: execution_time = time.time() - self.last_movement if execution_time <= config.running_step_time: running = True force_return = check_trigger(self, "before_move", self, self.location, direction, destination_room, running, behavioured) if force_return: return True force_return = check_trigger(self, "before_" + direction.trigger_suffix, self, self.location, direction, destination_room, running, behavioured) if force_return: return True for en in self.location.iter_contains(use_reversed=True): if en == self: continue force_return = check_trigger(en, "before_outcoming", self, self.location, direction, destination_room, en, running, behavioured) if force_return: return True for en in destination_room.iter_contains(use_reversed=True): force_return = check_trigger(en, "before_incoming", self, self.location, direction, destination_room, en, running, behavioured) if force_return: return True followers = self.get_followers_here() avoid_prompt = bool(followers) break_line = not avoid_prompt # Se arriva fin qui significa che alla direzione voluta c'è un'uscita exit = self.location.exits[direction] follower_names = [] for follower in followers: follower_names.append(follower.get_name(self)) if following: send_follow_entity_go_message(self.walker, self, direction, fleeing, running) elif exit.entity_message: self.act(exit.entity_message + "\n", TO.ENTITY, destination_room, self.location, direction.to_dir) else: self.act("%s %s.\n" % (self.go_verb_you(fleeing, running), direction.to_dir), TO.ENTITY) if following: send_follow_others_go_message(self.walker, self, direction, fleeing, running) elif exit.others_in_message: self.act(exit.others_in_message, TO.OTHERS, destination_room, self.location, direction.to_dir, avoid_prompt=avoid_prompt, break_line=break_line) else: self.act("$n %s %s." % (self.go_verb_it(fleeing, running), direction.to_dir), TO.OTHERS, avoid_prompt=avoid_prompt, break_line=break_line) # Per risparmiare in cpu esegue la modifica iterativa di tutti i # riferimenti area solo se ci si sta muovendo effettivamente da un'area # ad un'altra # (TT) Per ora l'use_look nel movimento è per i soli player, è una # scelta per diminuire i costi della cpu, ma potrebbe non essere # buona per il futuro quando ci saranno tutti i gamescript attivabili if self.location.area == destination_room.area: self = self.from_location(1, use_iterative_remove=False, use_repop=True) self.to_location(destination_room, use_look=True if self.IS_PLAYER else False, use_iterative_put=False) else: self = self.from_location(1, use_repop=True) self.to_location(destination_room, use_look=True if self.IS_PLAYER else False) # Messaggio aggiunto per rendere più chiaro a colui che viene seguito di esserlo if follower_names: send_follow_entity_come_message(self.walker, self, direction, fleeing, running, follower_names) if following: send_follow_others_come_message(self.walker, self, direction, fleeing, running) elif exit.others_out_message: self.act(exit.others_out_message, TO.OTHERS, destination_room, self.previous_location(), direction.reverse_dir.from_dir, avoid_prompt=avoid_prompt, break_line=break_line) else: self.act("$n %s %s." % (self.go_verb_it(fleeing, running), direction.reverse_dir.from_dir), TO.OTHERS, avoid_prompt=avoid_prompt, break_line=break_line) self.persistent_act.set_message("others", "$n %s %s." % (self.come_verb_it(fleeing, running), direction.reverse_dir.from_dir)) # Esegue il movimento automatico anche per coloro che seguono entity for follower in followers: follower.move(direction, following=True) follower.send_prompt() if self.location.IS_ROOM and ROOM.DEATH_TRAP in self.location.flags: if self.IS_PLAYER: self.dies(teleport_corpse=True) else: # use_repop a True perché magari un builder inserisce una # entity reset in una DT self.extract(1, use_repop=True) # Imposta il tempo attuale per poter cronometrare il prossimo comando # di movimento e vedere se l'entità sta correndo o meno self.last_movement = time.time() force_return = check_trigger(self, "after_move", self, self.location, direction, destination_room, running, behavioured) if force_return: return True force_return = check_trigger(self, "after_" + direction.trigger_suffix, self, self.location, direction, destination_room, running, behavioured) if force_return: return True for en in self.previous_location().iter_contains(use_reversed=True): force_return = check_trigger(en, "after_outcoming", self, self.location, direction, destination_room, en, running, behavioured) if force_return: return True for en in destination_room.iter_contains(use_reversed=True): if en == self: continue force_return = check_trigger(en, "after_incoming", self, self.location, direction, destination_room, en, running, behavioured) if force_return: return True return True
def command_force(entity, argument=""): """ Forza l'esecuzione di un comando da parte di un'altra entità. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- if not argument: syntax = get_command_syntax(entity, "command_force") entity.send_output(syntax, break_line=False) return False arg1, argument = one_argument(argument) target = entity.find_entity_extensively(arg1, inventory_pos="first") if not target: target = entity.find_entity_extensively(arg1) if not target: entity.send_output( "Nessuna entità trovata con argomento [white]%s[close]" % arg1) return False arg2, argument = one_argument(argument) if not arg2: entity.send_output("Che comando vorresti [red]forzare[close] a %s?" % target.get_name(entity)) return False input, huh_input, input_lang = multiple_search_on_inputs(entity, arg2) if not input: entity.send_output( "L'argomento %s non è relativo ad un comando valido." % arg2) return False if input.command and input.command.fun_name == "command_force": entity.send_output("Non puoi forzare un force.") return False translated_input = translate_input(target, arg2, input_lang) if not translated_input: entity.send_output( "Non è stato possibile tradurre l'input %s per %s (lingua originale: %s)" % (arg2, target.get_name(entity), input_lang)) return False target.send_output("\n") execution_result = interpret(target, "%s %s" % (translated_input, argument), force_position=True, show_input=False) if not execution_result: if target == entity: entity.send_output( "\nL'esecuzione dell'input [limegreen]%s[close] forzato su di [white]te stess%c[close] non è andata a buon fine." % (arg2, grammar_gender(entity))) else: entity.send_output( "\nL'esecuzione dell'input %s forzato su di %s non è andata a buon fine." % (arg2, target.get_name(entity))) if not entity.incognito: target.send_output("\n%s ti ha forzato a fare qualcosa." % entity.get_name(target)) log.admin("%s ha cercato di forzare %s a fare: %s %s" % (entity.name, target.name, arg2, argument)) return False if target == entity: message = "\n" + format_for_admin( "Il force dell'input [green]%s[close] su [white]te stess%c[close] sembra essere andato a buon fine." % (arg2, grammar_gender(entity))) entity.send_output(message) else: message = "\n" + format_for_admin( "Il force dell'input [green]%s[close] su di %s sembra andato a buon fine." % (arg2, target.get_name(entity))) entity.send_output(message) if not entity.incognito: target.send_output("\n%s ti ha forzato a fare qualcosa." % entity.get_name(target)) log.admin("%s ha forzato %s a fare: %s %s" % (entity.name, target.name, arg2, argument)) return True
def command_kill(entity, argument="", verbs=VERBS, behavioured=False): if not verbs: log.bug("verbs non è un parametro valido: %r" % verbs) return False # ------------------------------------------------------------------------- # È possibile se il comando è stato deferrato if not entity: return False entity = entity.split_entity(1) if not argument: entity.send_output("Chi o che cosa vorresti %s?" % verbs["infinitive"]) if entity.IS_PLAYER and OPTION.NEWBIE in entity.account.options: syntax = get_command_syntax(entity, "command_kill") entity.send_output(syntax, break_line=False) return False # (TD) Controllo sul mental state # Cerca la vittima da attaccare entity_tables = ["mobs", "players"] target = entity.find_entity(argument, location=entity.location, entity_tables=entity_tables, avoid_equipment=True) if not target: target = entity.find_entity(argument, location=entity.location, entity_tables=["items"], avoid_equipment=True, compare_functions=[is_same]) if target: destroy_translation = translate_input(entity, "destroy", "en") javascript_code = '''javascript:parent.sendInput('%s %s');''' % (destroy_translation, target.get_numbered_keyword(looker=entity)) destroy_verb = DESTROY_VERBS["noun"] % grammar_gender(target) html_code = '''<a href="%s">%s</a>''' % (javascript_code, destroy_verb) entity.act("Non puoi %s $N ma puoi sempre %s!" % (verbs["infinitive"], html_code), TO.ENTITY, target) entity.act("$n si guarda attorno con [red]brama di sangue[close]...", TO.OTHERS, target) entity.act("$N ti guarda con [red]brama di sangue[close]...", TO.TARGET, target) else: entity.act("Non trovi nessun [white]%s[close] da %s" % (argument, verbs["infinitive"]), TO.ENTITY) entity.act("$n si guarda attorno con [red]brama di sangue[close]...", TO.OTHERS) return False if FLAG.BEATEN in target.flags: force_return = check_trigger(entity, "before_kill", entity, target, behavioured) if force_return: return True force_return = check_trigger(target, "before_killed", entity, target, behavioured) if force_return: return True entity.act("Dai il [red]colpo di grazia[close] a $N!", TO.ENTITY, target) entity.act("$n dà il [red]colpo di grazia[close] a $N!", TO.OTHERS, target) entity.act("$n ti dà il [red]colpo di grazia[close]!", TO.TARGET, target) target.dies(opponent=entity) entity.player_killed_counter += 1 target.death_from_player_counter += 1 force_return = check_trigger(entity, "after_kill", entity, target, behavioured) if force_return: return True force_return = check_trigger(target, "after_killed", entity, target, behavioured) if force_return: return True return True # Se non sta combattendo procede all'attacco o alla distruzione della vittima if entity.is_fighting(with_him=target): entity.act("Non è ancora giusto il momento di dare il colpo di grazia a $N.", TO.ENTITY, target) entity.act("$n vorrebbe dare il colpo di grazia a $N, ma non è ancora giunto il suo momento...", TO.OTHERS, target) entity.act("$n vorrebbe darti il colpo di grazia, ma non è ancora giunto il tuo momento...", TO.TARGET, target) return False if target.IS_ITEM: execution_result = kill_handler(entity, argument, "command_kill", entity_tables, verbs=DESTROY_VERBS, behavioured=behavioured) else: execution_result = kill_handler(entity, argument, "command_kill", entity_tables, verbs=ATTACK_VERBS, behavioured=behavioured) return execution_result
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"><</a> </div>''' % js_minimum_arguments browse_to_right = '''<div style="float:left"> <a href="javascript:sendInput('%s')" style="font-size:larger">></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
def get_equipment_list(entity, target): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False if not target: log.bug("target non è un parametro valido: %r" % target) return False # ------------------------------------------------------------------------- look_translation = translate_input(entity, "look", "en") if not look_translation: log.bug("look_translation non è valida: %r" % look_translation) look_translation = "guarda" location = None if entity != target: location = target output = [] # Questo serve ad evitare di visualizzare tot volte la stessa entità se # questa copre più parti del corpo already_founds = [] # (TD) NO non va bene, bisogna farlo ordinato a seconda delle dichiarazioni # fatte nei vari bodies files, devo aggiungere un numero alla classe Part # e fare un ordinamento come ho fatto con gli EnumElement body_parts = target.get_body_parts() for part in PART.elements: # Evita di visualizzare parti estranee (check che in realtà non dovrebbe # servire essendo controllato nel wear) o organi interni if part not in body_parts: continue # Gli admin vedono anche gli organi interni, se eventualmente vestiti if PARTFLAG.INTERNAL in body_parts[ part].flags and entity.trust == TRUST.PLAYER: continue if PARTFLAG.NO_EQUIP_LIST in body_parts[part].flags: continue under_weareds = [] for weared_entity in target.iter_contains(): if weared_entity.under_weared and weared_entity.under_weared(): under_weareds.append(weared_entity.under_weared()) for weared_entity in target.iter_contains(): if weared_entity in already_founds: continue if weared_entity in under_weareds: continue if len(weared_entity.wear_mode) > 0: part_descriptions = get_part_descriptions( weared_entity, "equip", target, entity) if entity == target: part_descr = part_descriptions[TO.ENTITY] else: part_descr = part_descriptions[TO.OTHERS] if part in weared_entity.wear_mode: output.append( '''%s %s\n''' % (weared_entity.get_formatted_name( looker=entity, location=location, look_translation=look_translation), part_descr)) already_founds.append(weared_entity) holded = target.get_holded_entity() wielded = target.get_wielded_entity() if holded or wielded: look_translation = translate_input(entity, "look", "en") if not look_translation: log.bug("look_translation non è valida: %r" % look_translation) look_translation = "guarda" if holded: if holded.weapon_type: holded_verb = "impugnat%s" % grammar_gender(holded) else: holded_verb = "tenut%s" % grammar_gender(holded) holded_name = holded.get_formatted_name( looker=entity, location=location, look_translation=look_translation) if wielded: if wielded.weapon_type: wielded_verb = "impugnat%s" % grammar_gender(wielded) else: wielded_verb = "tenut%s" % grammar_gender(wielded) wielded_name = wielded.get_formatted_name( looker=entity, location=location, look_translation=look_translation) equipment_line_hold = "" equipment_line_wield = "" if target == entity: if holded and holded == wielded: equipment_line_hold = "%s %s con tutte e due le $hands\n" % ( holded_name, holded_verb) else: if holded: equipment_line_hold = "%s %s nella $hand2\n" % (holded_name, holded_verb) if wielded: equipment_line_wield = "%s %s nella $hand1\n" % (wielded_name, wielded_verb) else: if holded and holded == wielded: equipment_line_hold = "%s %s con tutte e due le $HANDS\n" % ( holded_name, holded_verb) else: if holded: equipment_line_hold = "%s %s nella $HAND2\n" % (holded_name, holded_verb) if wielded: equipment_line_wield = "%s %s nella $HAND1\n" % (wielded_name, wielded_verb) if equipment_line_hold: output.append( entity.replace_act_tags(equipment_line_hold, target=target)) if equipment_line_wield: output.append( entity.replace_act_tags(equipment_line_wield, target=target)) return output
def get_inventory_list(looker, target): if not looker: log.bug("looker non è un parametro valido: %r" % looker) return [] if not target: log.bug("target non è un parametro valido: %r" % target) return [] # ------------------------------------------------------------------------- from src.find_entity import INSTANCE, COUNTER, NO_LOOK_LIST, BURIED, INGESTED, INCOGNITO look_translation = translate_input(looker, "look", "en") if not look_translation: log.bug("look_translation non è valida: %r" % look_translation) look_translation = "guarda" output = [] for possession in target.get_list_of_entities(looker, admin_descrs=True): if not looker.can_see(possession[INSTANCE]): continue # Si suppone che se il giocatore ha con sé un oggetto no look list # sappia della sua esistenza if looker != target and FLAG.NO_LOOK_LIST in possession[INSTANCE].flags: continue if FLAG.INTERACTABLE_FROM_OUTSIDE in possession[ INSTANCE].flags and possession[INSTANCE].location != target: continue interactable_entities = list( possession[INSTANCE].iter_only_interactable_entities( use_can_see=True)) if "$i" in possession[INSTANCE].long or "$I" in possession[ INSTANCE].long or interactable_entities: # (TT) Far vedere la long al posto della short nell'inventario # per tutte e quante le entità: da pensare! name = possession[INSTANCE].get_long(looker, look_translation) else: name = possession[INSTANCE].get_formatted_name( looker, location=target, look_translation=look_translation) output.append( '''%s pesante %s, %s.''' % (name, get_weight_descr(possession[INSTANCE].get_total_weight()), possession[INSTANCE].get_condition())) if possession[COUNTER] > 1: output.append(" (%s)" % possession[COUNTER]) if looker.trust > TRUST.PLAYER: if looker == target: message = "%s%s%s" % (possession[BURIED], possession[INGESTED], possession[INCOGNITO]) else: message = "%s%s%s%s" % ( possession[NO_LOOK_LIST], possession[BURIED], possession[INGESTED], possession[INCOGNITO]) if message: output.append(" " + format_for_admin(message.lstrip())) output.append("\n") # È corretto che possa ritornare output vuoto, viene gestito esternamente return output
def command_force(entity, argument=""): """ Forza l'esecuzione di un comando da parte di un'altra entità. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- if not argument: syntax = get_command_syntax(entity, "command_force") entity.send_output(syntax, break_line=False) return False arg1, argument = one_argument(argument) target = entity.find_entity_extensively(arg1, inventory_pos="first") if not target: target = entity.find_entity_extensively(arg1) if not target: entity.send_output("Nessuna entità trovata con argomento [white]%s[close]" % arg1) return False arg2, argument = one_argument(argument) if not arg2: entity.send_output("Che comando vorresti [red]forzare[close] a %s?" % target.get_name(entity)) return False input, huh_input, input_lang = multiple_search_on_inputs(entity, arg2) if not input: entity.send_output("L'argomento %s non è relativo ad un comando valido." % arg2) return False if input.command and input.command.fun_name == "command_force": entity.send_output("Non puoi forzare un force.") return False translated_input = translate_input(target, arg2, input_lang) if not translated_input: entity.send_output("Non è stato possibile tradurre l'input %s per %s (lingua originale: %s)" % ( arg2, target.get_name(entity), input_lang)) return False target.send_output("\n") execution_result = interpret(target, "%s %s" % (translated_input, argument), force_position=True, show_input=False) if not execution_result: if target == entity: entity.send_output("\nL'esecuzione dell'input [limegreen]%s[close] forzato su di [white]te stess%c[close] non è andata a buon fine." % ( arg2, grammar_gender(entity))) else: entity.send_output("\nL'esecuzione dell'input %s forzato su di %s non è andata a buon fine." % ( arg2, target.get_name(entity))) if not entity.incognito: target.send_output("\n%s ti ha forzato a fare qualcosa." % entity.get_name(target)) log.admin("%s ha cercato di forzare %s a fare: %s %s" % (entity.name, target.name, arg2, argument)) return False if target == entity: message = "\n" + format_for_admin("Il force dell'input [green]%s[close] su [white]te stess%c[close] sembra essere andato a buon fine." % ( arg2, grammar_gender(entity))) entity.send_output(message) else: message = "\n" + format_for_admin("Il force dell'input [green]%s[close] su di %s sembra andato a buon fine." % ( arg2, target.get_name(entity))) entity.send_output(message) if not entity.incognito: target.send_output("\n%s ti ha forzato a fare qualcosa." % entity.get_name(target)) log.admin("%s ha forzato %s a fare: %s %s" % (entity.name, target.name, arg2, argument)) return True
def command_destroy(entity, argument="", verbs=VERBS, behavioured=False): # È possibile se il comando è stato deferrato if not entity: return False entity = entity.split_entity(1) if entity.sended_inputs and is_prefix("romp", entity.sended_inputs[-1]): verbs = VERBS2 if not argument: entity.send_output("Che cosa vorresti %s?" % verbs["infinitive"]) if entity.IS_PLAYER and OPTION.NEWBIE in entity.account.options: syntax = get_command_syntax(entity, "command_destroy") entity.send_output(syntax, destroy_line=False) return False # Solo gli oggetti animati possono utilizzare tale comando if entity.IS_ITEM and FLAG.CAN_DAMAGING not in entity.flags: entity.act("Non ti è possibile %s nulla di nulla.", TO.ENTITY) entity.act("$n sembra vibrare per un attimo... ma forse è stato un abbaglio.", TO.OTHERS) return False # Ricava l'eventuale quantità d'oggetti da raccogliere quantity, argument = quantity_argument(argument) arg, argument = one_argument(argument) target = entity.find_entity_extensively(arg, entity_tables=["items"], inventory_pos="first") if not target: target = entity.find_entity_extensively(arg, inventory_pos="first") if target: attack_translation = translate_input(entity, "attack", "en") javascript_code = '''javascript:parent.sendInput('%s %s');''' % (attack_translation, target.get_numbered_keyword(looker=entity)) destroy_noun = verbs["noun"] % grammar_gender(target) attack_noun = ATTACK_VERBS["noun"] % grammar_gender(target) html_code = '''<a href="%s">%s</a>''' % (javascript_code, attack_noun) entity.act("$N non è un oggetto quindi non puoi %s, ma puoi sempre %s." % (destroy_noun, html_code), TO.ENTITY, target) entity.act("$n posa uno sguardo indagatore su $N.", TO.OTHERS, target) entity.act("$n posa uno sguardo indagatore su di te.", TO.TARGET, target) else: entity.act("Non riesci a trovare nessun [white]%s[close] da %s" % (arg, verbs["infinitive"]), TO.ENTITY) entity.act("$n cerca qualcosa che però non trova.", TO.OTHERS) return False # (TD) resistenza al comando se charmati # (TD) skill di forza bruta if quantity == 0: quantity = target.quantity elif target.quantity < quantity: entity.act("Non puoi %s $N perché ve ne sono solo %d e non %d." % (verbs["infinitive"], target.quantity, quantity), TO.ENTITY, target) entity.act("$n sta cercando di ammucchiare un quantitativo voluto di $N per poterlo %s" % verbs["infinitive"], TO.OTHERS, target) entity.act("$n sta cercando di ammucchiarti per un quantitativo voluto per %s" % ["you2"], TO.TARGET, target) return False # In questa maniera crea l'entità finale che verrà manipolata dai trigger # in maniera omogenea senza dover attendere la chiamata della from_location target = target.split_entity(quantity) force_return = check_trigger(entity, "before_destroy", entity, target, behavioured) if force_return: return True force_return = check_trigger(target, "before_broken", entity, target, behavioured) if force_return: return True damage = damage_target(entity, target) index, dam_verb_you, dam_verb_it = get_destroy_verbs(damage) if target.life <= 0: end_destroy(entity, target, verbs, behavioured) else: messages = { "entity" : "%s $N." % dam_verb_you, "others" : "$n %s $N." % dam_verb_it, "target" : "$n ti %s." % dam_verb_it} send_destroy_messages(messages, "start_destroy", entity, target, verbs) if index != 0: entity.action_in_progress = ActionInProgress(DESTROY_SECONDS, continue_destroy, stop_destroy, entity, target, verbs, behavioured) return True
def command_tell(entity, argument=""): """ Permette di parlare con tutti nel Mud, in maniera off-gdr. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- if not argument: entity.send_output("Vuoi %s a qualcuno che cosa?" % CHANNEL.TELL) if entity.IS_PLAYER and OPTION.NEWBIE in entity.account.options: syntax = get_command_syntax(entity, "command_tell") entity.send_output(syntax, break_line=False) return False # Qui per la ricerca di target non viene utilizzata la find_entity perché # deve cercare solo i giocatori online # (TD) oltre alla ricerca di admin che possiedono mob o oggetti arg, argument = one_argument(argument) target = search_for_player(entity, arg) if not target: # (TD) se non è stato tovato allora cerca tra gli identificativi # personali relativi ai personaggi invisibili (implementazione # alternativa del reply) entity.send_output("Non è stato trovato nessun giocatore con argomento [white]%s[close]" % arg) return False # (TD) possibile implementazione di NOTELL, anche se è preferibile punizione # classica di NO_ENTER_IN_GAME per tot giorni if entity == target: entity.send_output("Non puoi comunicare con [white]te stess$o[close]!") return False if not target.game_request: entity.send_output("Il giocatore [white]%s[close] è attualmente [darkslategray]offline[close]." % target.name) return False if not argument: entity.send_output("Che messaggio privato vorresti inviare a [white]%s[close]?" % target.name) return False channel_color = get_first_color(str(CHANNEL.TELL)) afk_status = "" if FLAG.AFK in target.flags: if entity.account and OPTION.ITALIAN in entity.account.options: afk_status = " (LDT)" else: afk_status = " (AFK)" if is_vowel(remove_colors(target.name)[0]): preposition = "ad" else: preposition = "a" entity.send_output("%s %s%s[close] %s: %s'%s'" % ( CHANNEL.TELL.verb_you, channel_color, preposition, target.name, afk_status, argument), avoid_snoop=True) # (TD) inviare anche il soft beep per avvertire che ha ricevuto un messaggio # ed aggiungere l'opzione apposita if target.get_conn().get_browser(): numbered_keyword = entity.get_numbered_keyword(looker=target) javascript = '''javascript:putInput('%s %s ');''' % (translate_input(target, "tell", "en"), numbered_keyword) target.send_output("""\n<a href="%s">%s%s ti[close]%s</a>: '%s'""" % (javascript, entity.name, channel_color, CHANNEL.TELL.verb_it, argument), avoid_snoop=True) else: target.send_output("""\n%s %sti[close]%s: '%s'""" % (entity.name, channel_color, CHANNEL.TELL.verb_it, argument), avoid_snoop=True) target.send_prompt() return True
def get_list_of_entities(self, looker, entity_tables=None, include_looker=False, avoid_inventory=False, avoid_equipment=True, avoid_doors=False, admin_descrs=False, use_number_argument=True): """ Ritorna una stringa con tutte le entità relative ad una stanza. Il parametro no_number_argument serve ad evitare ricorsioni della get_long. """ if not looker: log.bug("looker non è un parametro valido: %r" % looker) return # --------------------------------------------------------------------- from src.web_resource import create_icon look_translation = translate_input(looker, "look", "en") if not look_translation: log.bug("look_translation non è valida: %r" % look_translation) look_translation = "guarda" is_admin = looker.trust >= TRUST.MASTER # Ricava la lista di entità da visualizzare entities = [] for entity in list( self.iter_contains(entity_tables=entity_tables)) + list( self.iter_only_interactable_entities( entity_tables=entity_tables, use_can_see=True)): if not include_looker and entity == looker: continue if avoid_inventory and len(entity.wear_mode) == 0: continue if avoid_equipment and len(entity.wear_mode) != 0: continue if avoid_doors and entity.door_type and entity.is_hinged(): continue if entity in [en[INSTANCE] for en in entities]: continue if not is_admin: if FLAG.BURIED in entity.flags: continue if FLAG.INGESTED in entity.flags: continue if entity.incognito: continue long_descr = put_final_dot( entity.get_long(looker, look_translation, use_number_argument)) # (TD) magari in futuro creare addirittura una classe apposita # per tutta questa lista appendata entities.append([ entity, create_icon(entity.get_icon()), long_descr, entity.quantity, "", "", "", "", [] ]) # Raggruppa eventuali entità che si visualizzerebbero in maniera identica if config.use_visual_grouping: for entity1 in entities: for entity2 in entities: if entity1[COUNTER] <= 0 or entity2[COUNTER] <= 0: continue if entity1[INSTANCE] == entity2[INSTANCE]: continue if entity1[ICON] != entity2[ICON]: continue if entity1[LONG] == entity2[LONG]: if entity1[COUNTER] > 1: entity1[COUNTER] += entity2[INSTANCE].quantity entity2[COUNTER] -= entity2[INSTANCE].quantity entity1[ENTITIES].append(entity2[INSTANCE]) else: entity1[COUNTER] -= entity1[INSTANCE].quantity entity2[COUNTER] += entity1[INSTANCE].quantity entity2[ENTITIES].append(entity1[INSTANCE]) # Ripulisce le entità che hanno ora counter minore o uguale a zero for entity in reversed(entities): if entity[COUNTER] <= 0: entities.remove(entity) # Inserisce per ultimi nella lista relativa a ENTITIES le entità che # possiedono la flag NO_LOOK_LIST, in maniera da mantenere l'ordinamento # della visualizzazione con quello della ricerca nel qual caso alcune # entità visualizzabili abbiano lo stesso nome di quelle con tale flag # In pratica tutto questo per evitare che qualcuno tramite, ad esempio, # get 2.pomodoro non raccolga per sbaglio l'entità NO_LOOK_LIST invece # di quella visualizzata, come invece sarebbe voluto for entity in entities: no_look_list_entities = [] for en in reversed(entity[ENTITIES]): if FLAG.NO_LOOK_LIST in en.flags: entity[ENTITIES].remove(en) no_look_list_entities.append(en) entity[ENTITIES].extend(reversed(no_look_list_entities)) # Ai soli admin crea le informazioni relative alle flags if is_admin and admin_descrs: for entity in entities: no_look_list_counter = 0 buried_counter = 0 ingested_counter = 0 incognito_counter = 0 for en in [entity[INSTANCE]] + entity[ENTITIES]: if FLAG.NO_LOOK_LIST in en.flags: no_look_list_counter += en.quantity if FLAG.BURIED in en.flags: buried_counter += en.quantity if FLAG.INGESTED in en.flags: ingested_counter += en.quantity if en.incognito: incognito_counter += en.quantity no_look_list_descr = "" if no_look_list_counter == 1 and entity[COUNTER] == 1: no_look_list_descr = " no_look_list" elif no_look_list_counter > 0: no_look_list_descr = " no_look_list(%d)" % no_look_list_counter entity[NO_LOOK_LIST] = no_look_list_descr buried_descr = "" if buried_counter == 1 and entity[COUNTER] == 1: buried_descr = " buried" elif buried_counter > 0: buried_descr = " buried(%d)" % buried_counter entity[BURIED] = buried_descr ingested_descr = "" if ingested_counter == 1 and entity[COUNTER] == 1: ingested_descr = " ingested" elif ingested_counter > 0: ingested_descr = " ingested(%d)" % ingested_counter entity[INGESTED] = ingested_descr incognito_descr = "" if incognito_counter == 1 and entity[COUNTER] == 1: incognito_descr = " incognito" elif incognito_counter > 0: incognito_descr = " incognito(%d)" % incognito_counter entity[INCOGNITO] = incognito_descr return entities
def command_list(entity, argument="", behavioured=False): """ Permette di comprare entità da un commerciante. """ # Può essere normale se il comando è stato deferrato if not entity: return False entity = entity.split_entity(1) if argument: dealer = entity.find_entity_extensively(argument) if not dealer: entity.act("Non trovi nessun negoziante chiamato [white]%s[close]." % argument, TO.ENTITY) entity.act("$n sembra cercare qualcuno un negoziante.", TO.OTHERS) return False if not dealer.shop: entity.act("$N non sembra essere un negoziante.", TO.ENTITY, dealer) entity.act("$n crede erroneamente che $N sia un negoziante.", TO.OTHERS, dealer) entity.act("$n crede erroneamente che tu sia un negoziante.", TO.TARGET, dealer) return False # Altrimenti cerca il primo negoziante che si trova nella locazione del giocatore else: for dealer in entity.location.iter_contains(): if dealer.shop: break else: entity.act("Qui non trovi nessun [white]negoziante[close].", TO.ENTITY) entity.act("$n non sembra trovare nessun negoziante qui intorno.", TO.OTHERS) return False in_location = dealer.shop.in_location(dealer) if not in_location and SHOP.DISPENSER not in dealer.shop.types: entity.act("$N non ti mostra la merce perché non si trova nel suo negozio.", TO.ENTITY, dealer) entity.act("$N non mostra la merce a $n perché non si trova nel suo negozio.", TO.OTHERS, dealer) entity.act("Non mostri la tua merce a $n perché non ti trovi nel tuo negozio.", TO.TARGET, dealer) return False # Indica che un'entità vuole interagire con il dealer if entity not in dealer.interactions: dealer.interactions.append(entity) storage = dealer.shop.get_storage(dealer) if not storage: if dealer.shop.proto_storages and dealer.shop.proto_storages[0].IS_MOB: from_where = "da chi" else: from_where = "da dove" entity.act("Non puoi avere la lista da $N perché non ha %s prendere la mercanzia!" % from_where, TO.ENTITY, dealer) entity.act("$n non può avere la lista da $N perché non ha %s prendere la mercanzia!" % from_where, TO.OTHERS, dealer) entity.act("$n non può avere la lista perché non hai %s prendere la mercanzia!" % from_where, TO.TARGET, dealer) return False if not dealer.shop.buyables: entity.send_output("%s non possiede nessuna mercanzia" % dealer.get_name(looker=entity)) log.bug("Non è stato trovato nessun buyable impostato per %s" % dealer.code) return False # Controlla se il magazzino contiene almeno un oggetto comprabile dall'utente if dealer.shop.storage_is_empty(storage): entity.act("Ti accorgi che il negozio non possiede mercanzia, meglio tornare più tardi, dopo il rifornimento.", TO.ENTITY, dealer) entity.act("$n si accorge che il negozio non possiede mercanzia.", TO.OTHERS, dealer) entity.act("$n si accorge che il tuo negozio non possiede mercanzia.", TO.TARGET, dealer) return False force_return = check_trigger(entity, "before_list", entity, dealer, behavioured) if force_return: return True force_return = check_trigger(dealer, "before_listed", entity, dealer, behavioured) if force_return: return True if SHOP.DISPENSER in dealer.shop.types: if not in_location: entity.act("Leggi su di una targetta la lista delle mercanzie di $N anche se non si trova nel suo negozio.", TO.OTHERS, dealer) entity.act("$n legge su di una targetta la lista delle mercanzie di $N anche se non si trova nel suo negozio.", TO.OTHERS, dealer) entity.act("$n legge la tua targetta con la lista delle mercanzie anche se non si trova nel suo negozio.", TO.TARGET, dealer) else: entity.act("Leggi su di una targetta la lista delle mercanzie di $N.", TO.OTHERS, dealer) entity.act("$n legge su di una targetta la lista delle mercanzie di $N.", TO.OTHERS, dealer) entity.act("$n legge la tua targetta con la lista delle mercanzie.", TO.TARGET, dealer) else: entity.act("Chiedi la lista delle mercanzie di $N.", TO.OTHERS, dealer) entity.act("$n chiede la lista delle mercanzie di $N.", TO.OTHERS, dealer) entity.act("$n ti chiede la lista delle mercanzie.", TO.TARGET, dealer) discount_exist = False for buyable in dealer.shop.buyables: if buyable.has_discount(): discount_exist = True buy_translation = translate_input(entity, "buy", "en") rows = [] rows.append('''<table class="mud">''') discount_cell = "" if SHOP.DISPENSER in dealer.shop.types: name_cell = "Prodotti" else: name_cell = "Mercanzia" if discount_exist: discount_cell = '''<th>Sconto</th>''' rows.append('''<tr><th></th><th>%s</th><th colspan="4">Prezzo</th><th>Livello</th><th></th><th></th>%s</tr>''' % ( name_cell, discount_cell)) for en in storage.get_list_of_entities(entity): en = en[INSTANCE] for buyable in dealer.shop.buyables: if en.prototype != buyable.proto_entity: continue # Purtroppo però il sistema di mucchio visivo non permetterà di # visualizzare quantità superiori ad 1 per oggetti di long uguali # tra loro, la quantità si deve per forza basare sul mucchio fisico quantity = 10 if buyable.has_discount(): quantity = buyable.discount_quantity if en.quantity < quantity: quantity = en.quantity name = en.get_name(looker=entity) single_price, dummy_discount = buyable.get_price(en, quantity=1) block_price, dummy_discount = buyable.get_price(en, quantity=quantity) mithril, gold, silver, copper = pretty_money_icons(single_price) rows.append('''<tr><td>%s</td>''' % create_icon(en.get_icon(), add_span=False)) rows.append('''<td>%s </td>''' % create_tooltip(entity.get_conn(), en.get_descr(looker=entity), name)) rows.append('''<td align="right">%s</td>''' % mithril) rows.append('''<td align="right">%s</td>''' % gold) rows.append('''<td align="right">%s</td>''' % silver) rows.append('''<td align="right">%s</td>''' % copper) rows.append('''<td align="center">%d</td>''' % en.level) rows.append('''<td><input type="submit" value="%s" onclick="sendInput('%s 1 %s')" title="Comprerai %s per un prezzo di %s"/></td>''' % ( buy_translation.capitalize(), buy_translation, en.get_numbered_keyword(looker=entity), remove_colors(name), remove_colors(pretty_money_value(single_price)))) rows.append('''<td><input type="submit" value="%s x %d" onclick="sendInput('%s %d %s')" title="Comprerai %d unità di %s per un prezzo di %s"/></td>''' % ( buy_translation.capitalize(), quantity, buy_translation, quantity, en.get_numbered_keyword(looker=entity), quantity, remove_colors(name), remove_colors(pretty_money_value(block_price)))) if discount_exist: if buyable.has_discount(): rows.append('''<td align="center">%d%% per quantità maggiori di %d</td>''' % (buyable.discount_percent, buyable.discount_quantity)) else: rows.append('''<td align="center">Nessuno</td>''') rows.append('''</tr>''') rows.append('''</table>''') entity.send_output("".join(rows), break_line=False) force_return = check_trigger(entity, "after_list", entity, dealer, behavioured) if force_return: return True force_return = check_trigger(dealer, "after_listed", entity, dealer, behavioured) if force_return: return True return True
def get_list_of_entities(self, looker, entity_tables=None, include_looker=False, avoid_inventory=False, avoid_equipment=True, avoid_doors=False, admin_descrs=False, use_number_argument=True): """ Ritorna una stringa con tutte le entità relative ad una stanza. Il parametro no_number_argument serve ad evitare ricorsioni della get_long. """ if not looker: log.bug("looker non è un parametro valido: %r" % looker) return # --------------------------------------------------------------------- from src.web_resource import create_icon look_translation = translate_input(looker, "look", "en") if not look_translation: log.bug("look_translation non è valida: %r" % look_translation) look_translation = "guarda" is_admin = looker.trust >= TRUST.MASTER # Ricava la lista di entità da visualizzare entities = [] for entity in list(self.iter_contains(entity_tables=entity_tables)) + list(self.iter_only_interactable_entities(entity_tables=entity_tables, use_can_see=True)): if not include_looker and entity == looker: continue if avoid_inventory and len(entity.wear_mode) == 0: continue if avoid_equipment and len(entity.wear_mode) != 0: continue if avoid_doors and entity.door_type and entity.is_hinged(): continue if entity in [en[INSTANCE] for en in entities]: continue if not is_admin: if FLAG.BURIED in entity.flags: continue if FLAG.INGESTED in entity.flags: continue if entity.incognito: continue long_descr = put_final_dot(entity.get_long(looker, look_translation, use_number_argument)) # (TD) magari in futuro creare addirittura una classe apposita # per tutta questa lista appendata entities.append([entity, create_icon(entity.get_icon()), long_descr, entity.quantity, "", "", "", "", []]) # Raggruppa eventuali entità che si visualizzerebbero in maniera identica if config.use_visual_grouping: for entity1 in entities: for entity2 in entities: if entity1[COUNTER] <= 0 or entity2[COUNTER] <= 0: continue if entity1[INSTANCE] == entity2[INSTANCE]: continue if entity1[ICON] != entity2[ICON]: continue if entity1[LONG] == entity2[LONG]: if entity1[COUNTER] > 1: entity1[COUNTER] += entity2[INSTANCE].quantity entity2[COUNTER] -= entity2[INSTANCE].quantity entity1[ENTITIES].append(entity2[INSTANCE]) else: entity1[COUNTER] -= entity1[INSTANCE].quantity entity2[COUNTER] += entity1[INSTANCE].quantity entity2[ENTITIES].append(entity1[INSTANCE]) # Ripulisce le entità che hanno ora counter minore o uguale a zero for entity in reversed(entities): if entity[COUNTER] <= 0: entities.remove(entity) # Inserisce per ultimi nella lista relativa a ENTITIES le entità che # possiedono la flag NO_LOOK_LIST, in maniera da mantenere l'ordinamento # della visualizzazione con quello della ricerca nel qual caso alcune # entità visualizzabili abbiano lo stesso nome di quelle con tale flag # In pratica tutto questo per evitare che qualcuno tramite, ad esempio, # get 2.pomodoro non raccolga per sbaglio l'entità NO_LOOK_LIST invece # di quella visualizzata, come invece sarebbe voluto for entity in entities: no_look_list_entities = [] for en in reversed(entity[ENTITIES]): if FLAG.NO_LOOK_LIST in en.flags: entity[ENTITIES].remove(en) no_look_list_entities.append(en) entity[ENTITIES].extend(reversed(no_look_list_entities)) # Ai soli admin crea le informazioni relative alle flags if is_admin and admin_descrs: for entity in entities: no_look_list_counter = 0 buried_counter = 0 ingested_counter = 0 incognito_counter = 0 for en in [entity[INSTANCE]] + entity[ENTITIES]: if FLAG.NO_LOOK_LIST in en.flags: no_look_list_counter += en.quantity if FLAG.BURIED in en.flags: buried_counter += en.quantity if FLAG.INGESTED in en.flags: ingested_counter += en.quantity if en.incognito: incognito_counter += en.quantity no_look_list_descr = "" if no_look_list_counter == 1 and entity[COUNTER] == 1: no_look_list_descr = " no_look_list" elif no_look_list_counter > 0: no_look_list_descr = " no_look_list(%d)" % no_look_list_counter entity[NO_LOOK_LIST] = no_look_list_descr buried_descr = "" if buried_counter == 1 and entity[COUNTER] == 1: buried_descr = " buried" elif buried_counter > 0: buried_descr = " buried(%d)" % buried_counter entity[BURIED] = buried_descr ingested_descr = "" if ingested_counter == 1 and entity[COUNTER] == 1: ingested_descr = " ingested" elif ingested_counter > 0: ingested_descr = " ingested(%d)" % ingested_counter entity[INGESTED] = ingested_descr incognito_descr = "" if incognito_counter == 1 and entity[COUNTER] == 1: incognito_descr = " incognito" elif incognito_counter > 0: incognito_descr = " incognito(%d)" % incognito_counter entity[INCOGNITO] = incognito_descr return entities