def command_title(entity, argument=""): """ Permette al giocatore d'inserire un proprio title al personaggio. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- if not argument: syntax = get_command_syntax(entity, "command_title") entity.send_output(syntax, break_line=False) return False if not entity.IS_PLAYER: entity.send_output("Non ti è possibile impostare un titolo.") return if is_same(argument, "cancella") or is_same(argument, "delete"): entity.title = "" entity.send_output("Il tuo titolo è stato cancellato.") return True color_qty = count_colors(argument) # (TD) In futuro non farlo dipendente dal livello ma da qualche achievement o quest if color_qty > entity.level / 2: entity.send_output("Devi crescere di livello se vuoi colorare maggiormente il tuo titolo.") return False entity.title = close_color(argument) entity.send_output("Il tuo titolo è stato modificato in: '%s'" % entity.title) return True
def get_element_from_name(enum, name): """ Ricava l'elemento di un'enumerazione con index uguale a quello passato. """ if not enum: log.bug("enum non è un parametro valido: %r" % enum) return None if not name: log.bug("name non è un parametro valido: %r" % name) return None # ------------------------------------------------------------------------- from color import remove_colors for enum_element in enum.elements: enum_element_name = remove_colors(enum_element.name) if "$o" in enum_element_name: if is_same(enum_element_name.replace("$o", "o"), name): return enum_element if is_same(enum_element_name.replace("$o", "a"), name): return enum_element else: if is_same(enum_element_name, name): return enum_element return None
def find_room(self, argument): if not argument: log.bug("argument non è un parametro valido: %r" % argument) return None # --------------------------------------------------------------------- number, argument = number_argument(argument) counter = 1 if self.trust >= TRUST.MASTER: for room_code in database["rooms"]: if is_same(argument, room_code): if counter == number: return database["rooms"][room_code] counter += 1 counter = 1 for room in database["rooms"].itervalues(): if is_same(argument, room.get_name(looker=self)): if counter == number: return room counter += 1 # --------------------------------------------------------------------- counter = 1 if self.trust >= TRUST.MASTER: for room_code in database["rooms"]: if is_prefix(argument, room_code): if counter == number: return database["rooms"][room_code] counter += 1 counter = 1 for room in database["rooms"].itervalues(): if is_prefix(argument, room.get_name(looker=self)): if counter == number: return room counter += 1 # --------------------------------------------------------------------- counter = 1 if self.trust >= TRUST.MASTER: for room_code in database["rooms"]: if is_infix(argument, room_code): if counter == number: return database["rooms"][room_code] counter += 1 counter = 1 for room in database["rooms"].itervalues(): if is_infix(argument, room.get_name(looker=self)): if counter == number: return room counter += 1 return None
def search_for_player(entity, argument): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False if not argument: log.bug("argument non è un parametro valido: %r" % argument) return False # ------------------------------------------------------------------------- number, argument = number_argument(argument) counter = 1 for player in database["players"].itervalues(): if not player.game_request: continue if player.incognito and player.trust > entity.trust: continue if is_same(argument, player.name): if counter == number: return player counter += 1 counter = 1 for player in database["players"].itervalues(): if not player.game_request: continue if player.incognito and player.trust > entity.trust: continue if is_prefix(argument, player.name): if counter == number: return player counter += 1 # Cerca ora tra i giocatori offline, giusto per ritornare un qualcosa counter = 1 for player in database["players"].itervalues(): if player.game_request: continue if player.incognito and player.trust > entity.trust: continue if is_same(argument, player.name): if counter == number: return player counter += 1 counter = 1 for player in database["players"].itervalues(): if player.game_request: continue if player.incognito and player.trust > entity.trust: continue if is_prefix(argument, player.name): if counter == number: return player counter += 1 return None
def after_listen_rpg_channel(astronoma, player, target, phrase, ask, exclaim, behavioured): if target and target != astronoma: return if is_same(phrase, "si"): after_nod(player,astronoma, phrase) elif is_same(phrase, "no"): after_shake(player, astronoma, phrase)
def after_listen_rpg_channel(astronoma, player, target, phrase, ask, exclaim, behavioured): if target and target != astronoma: return if is_same(phrase, "si"): after_nod(player, astronoma, phrase) elif is_same(phrase, "no"): after_shake(player, astronoma, phrase)
def is_masculine(argument): """ Ritorna vero se l'argomento passato è una parola maschile. """ if not argument: log.bug("argument non è un parametro valido: %r" % argument) return False # ------------------------------------------------------------------------- # Bisogna avere per forza un dizionario che indichi le eccezioni non # ricavabili dalla funzione for entry_word in vocabulary: if is_same( argument, (entry_word.masculine_singular, entry_word.masculine_plural)): return True elif is_same( argument, (entry_word.feminine_singular, entry_word.feminine_plural)): return False word = grammar_cleaner(argument) # Di solito le parole con la 'a' finale non sono maschili if word[-1] == "a": # Le parole che finiscono in "essa" non sono maschili if is_suffix("essa", word): return False # Le tipologie di derivazione greca che finiscono in "ma" sono maschili if is_same(word, ("diploma", "dramma", "poema", "teorema", "problema")): return True # Altre parole maschili if is_same(word, ("duca", "nulla", "papa", "pigiama", "poeta", "profeta", "vaglia")): return True return False elif word[-1] == "e": # Se la parole finisce in "tore" è maschile if is_suffix("tore", word): return True # Se finisce in "sore" la maggior parte delle volte è maschile if is_suffix("sore", word): return True # Quelle che finiscono in trice sono femminili if is_suffix("trice", word): return False return True elif word[-1] == "i": return True elif word[-1] == "o": return True elif word[-1] == "u": return True return False
def command_help(entity, argument=""): """ Comando che serve a trovare e visualizzare un argomento di help. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- if not argument: help = get_help(entity, "help") if not help: entity.send_output("Nessun aiuto base trovato.") return False else: help = get_help(entity, argument) if not help: not_found_output = "Nessun aiuto trovato con argomento [white]%s[close]\n" % argument similar_helps = get_similar_helps(entity, argument) if similar_helps: not_found_output += "%s\n" % similar_helps entity.send_output(not_found_output, break_line=False) log.huh_helps(entity, argument) return False output = "" # Se si è Admin fa visualizzare anche le parole chiave if entity.trust > TRUST.PLAYER: if is_same(help.italian_keywords, help.english_keywords): output += format_for_admin( "Italian/EnlighKeywords: %s" % help.italian_keywords) + "\n" else: output += format_for_admin( "ItalianKeywords: %s" % help.italian_keywords) + "\n" output += format_for_admin( "EnglishKeywords: %s" % help.english_keywords) + "\n" if help.text: if is_same(help.code, "help") and help.syntax_function: output += help.syntax_function(entity) output += "%s\n" % help.text if help.admin_text and entity.trust > TRUST.PLAYER: output += "%s\n" % help.admin_text if help.see_also: output += "%s\n" % get_see_also_links(entity, help.see_also) entity.send_output(output, break_line=False) return True
def is_masculine(argument): """ Ritorna vero se l'argomento passato è una parola maschile. """ if not argument: log.bug("argument non è un parametro valido: %r" % argument) return False # ------------------------------------------------------------------------- # Bisogna avere per forza un dizionario che indichi le eccezioni non # ricavabili dalla funzione for entry_word in vocabulary: if is_same(argument, (entry_word.masculine_singular, entry_word.masculine_plural)): return True elif is_same(argument, (entry_word.feminine_singular, entry_word.feminine_plural)): return False word = grammar_cleaner(argument) # Di solito le parole con la 'a' finale non sono maschili if word[-1] == "a": # Le parole che finiscono in "essa" non sono maschili if is_suffix("essa", word): return False # Le tipologie di derivazione greca che finiscono in "ma" sono maschili if is_same(word, ("diploma", "dramma", "poema", "teorema", "problema")): return True # Altre parole maschili if is_same(word, ("duca", "nulla", "papa", "pigiama", "poeta", "profeta", "vaglia")): return True return False elif word[-1] == "e": # Se la parole finisce in "tore" è maschile if is_suffix("tore", word): return True # Se finisce in "sore" la maggior parte delle volte è maschile if is_suffix("sore", word): return True # Quelle che finiscono in trice sono femminili if is_suffix("trice", word): return False return True elif word[-1] == "i": return True elif word[-1] == "o": return True elif word[-1] == "u": return True return False
def after_listen_say(tessi, player, target, phrase, behavioured): if not player.IS_PLAYER: return # Nel qual caso il giocatore stia parlando con qualcun'altro esce if target and target != tessi: return # Se la tessitrice non è in modalità questosa esce if tessi.race == RACE.BIRD: return # Se la tessitrice non è in attesa di risposta allora esce if "player_for_reply" not in tessi.specials or not tessi.specials["player_for_reply"]: return # Si assicura che il giocatore che ha parlato sia quello che ha attivato la quest if player.code != tessi.specials["player_for_reply"]: return phrase = ALFA_ONLY_PATTERN.sub("", phrase) if is_same(phrase, "no"): defer_random_time(1, 2, stop_waiting_for_reply, tessi, player) return if not is_same(phrase, ("si", "certo")): return print "villaggio-zingaro_mob_test-tessi - tessi ", tessi.code tessi.specials["player_for_reply"] = "" print "villaggio-zingaro_mob_test-tessi - >>> ora cerco una room <<<" room = find_room(ROOM_PROTO_CODE) if not room: print "villaggio-zingaro_mob_test-tessi - >>> nessuna room trovata per testtessi. Exit <<<" to_say = "a %s *imbarazzata* Uh, oh... ora ricordo dove ho messo il fermaglio; perdonami, tutto risolto." % player.code defer_if_possible(1, 2, tessi, player, command_say, tessi, to_say) tessi.specials["player_on_quest"] = "" return ragno = inject_if_inexist_on_area(RAGNO_PROTO_CODE, room) bozzolo = inject_if_inexist_on_area(BOZZOLO_PROTO_CODE, room) fermaglio = inject_if_inexist_on_area(FERMAGLIO_PROTO_CODE, bozzolo) to_say_1 = "a %s *compiaciuta* Ti ringrazio! Ricordo d'aver smarrito il fermaglio tornando qui dopo aver bevuto al pozzo." % player.code to_say_2 = "a %s Non impiegare più di tre giorni nella ricerca, se tornerai in tempo verrai ricompensat$o." % player.code defer_if_possible(1, 2, tessi, player, command_say, tessi, to_say_1) defer_if_possible(3, 4, tessi, player, command_say, tessi, to_say_2) tessi.specials["player_on_quest"] = player.code start_quest_timer(player, tessi)
def before_giving(player, pesce, gatto, direction, behavioured): if not player.IS_PLAYER: player.act("$N ti soffia e fa come per graffiarti, non sei una compagnia desiderabile.", TO.ENTITY, gatto) player.act("$N, con il pelo ritto sulla schiena, scaccia $n in malomodo.", TO.OTHERS, gatto) player.act("$n ti si avvicina un po' troppo per i tuoi gusti e lo scacci senza troppi complimenti.", TO.TARGET, gatto) return True pesce_keywords = multiple_arguments(pesce.get_keywords_attr(looker=gatto)) if is_same(pesce_keywords, ("agrumi", "agrume", "arance", "arancia", "limone", "limoni", "bergamotto", "mandarino", "mandarini", "pompelmo", "pompelmi", "cedro", "cedri", "mandarancio", "mandaranci", "lime")): num_rand = random.randint(1, 100) if num_rand < 75: player.act("$N ti attacca in un raptus di furia assassina!", TO.ENTITY, gatto) player.act("Apparentemente senza ragione $N attacca $n.", TO.OTHERS, gatto) player.act("Quel pazzo di $n ha tentato di darti un agrume, la dovrà pagare!", TO.TARGET, gatto) player.life -= give_damage(player) return True else: player.act("$N sguaina le unghie e tenta di attaccarti ma fortunatamente manca il colpo.", TO.ENTITY, gatto) player.act("$N fa uno scatto verso $n come per attaccarlo ma la zampata non va a buon fine.", TO.OTHERS, gatto) player.act("Tenti di attacare $n ma non ci riesci", TO.TARGET, gatto) return True if not pesce.entitype == ENTITYPE.FOOD or not is_same(pesce_keywords, ("pesce", "pesci")): player.act("$N storce i baffi schizzinoso.", TO.ENTITY, gatto) player.act("$n tenta inutilmente di dare qualcosa a $N che lo snobba schizzinoso.", TO.OTHERS, gatto) player.act("$n tenta di propinarti qualcosa che anche un cane rifiuterebbe.", TO.TARGET, gatto) return True if pesce.weight > PESO_MASSIMO: player.act("$N ti guarda perplesso dopo aver valutato il peso di ciò che gli vorresti dare.", TO.ENTITY, gatto) player.act("Noti uno strano gioco di sguardi tra $N e $n.", TO.OTHERS, gatto) player.act("$n cerca di darti qualcosa di veramente troppo pesante per te.", TO.TARGET, gatto) return True for content in gatto.iter_contains(use_reversed=True): if FLAG.INGESTED in content.flags: if content.entitype == ENTITYPE.FOOD: player.act("$N rifiuta il cibo che gli offri, d'evessere sazio!", TO.ENTITY, gatto) player.act("$n vorrebbe dare qualcosa a $N che però non sembra interessato..", TO.OTHERS, gatto) player.act("$n vorrebbe ingozzarti, la tua dignità di impedisce di far la figura del maiale all'ingrasso..", TO.TARGET, gatto) return True else: content.extract(1) return True palla = Item(PROTO_FUR_CODE) defer_random_time(1, 3, puke_hairs, gatto, player, palla) defer_random_time(4, 5, fish_eat, player, gatto, pesce)
def command_help(entity, argument=""): """ Comando che serve a trovare e visualizzare un argomento di help. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- if not argument: help = get_help(entity, "help") if not help: entity.send_output("Nessun aiuto base trovato.") return False else: help = get_help(entity, argument) if not help: not_found_output = "Nessun aiuto trovato con argomento [white]%s[close]\n" % argument similar_helps = get_similar_helps(entity, argument) if similar_helps: not_found_output += "%s\n" % similar_helps entity.send_output(not_found_output, break_line=False) log.huh_helps(entity, argument) return False output = "" # Se si è Admin fa visualizzare anche le parole chiave if entity.trust > TRUST.PLAYER: if is_same(help.italian_keywords, help.english_keywords): output += format_for_admin("Italian/EnlighKeywords: %s" % help.italian_keywords) + "\n" else: output += format_for_admin("ItalianKeywords: %s" % help.italian_keywords) + "\n" output += format_for_admin("EnglishKeywords: %s" % help.english_keywords) + "\n" if help.text: if is_same(help.code, "help") and help.syntax_function: output += help.syntax_function(entity) output += "%s\n" % help.text if help.admin_text and entity.trust > TRUST.PLAYER: output += "%s\n" % help.admin_text if help.see_also: output += "%s\n" % get_see_also_links(entity, help.see_also) entity.send_output(output, break_line=False) return True
def get_error_message_email(email, already_in_database=False): """ Controlla la validità dell'indirzzo mail inserito. Ritorna un messaggio vuoto se tutto è a posto, altrimenti il primo messaggio d'errore incontrato. Bisogna passare l'argomento already_in_database uguale a False quando si controlla l'integrità di un indirizzo mail di un Account appena creato non ancora aggiunto al database degli account, nel caso contrario bisogna passarlo uguale a True. """ # L'inserimento di un indirizzo mail è opzionale if not email: return "" # Controlla la sintassi dell'indirizzo if not PATTERN_EMAIL.match(email): return "Email inserita non valida." # Controlla che non vi sia già un account con lo stesso email for account in database["accounts"].itervalues(): if account.email and is_same(account.email, email): # Se si sta modificando l'email questo è già in un account e quindi # quando la trova per la prima volta lo salta if already_in_database: already_in_database = False continue return "Email inserita già utilizzata in un altro account" # Se arriva fino a qui è tutto a posto return ""
def after_listen_say(mob, player, target, phrase, behavioured): if not player.IS_PLAYER: return # Verifico che gli si parli con "a" if target != mob: return # Se non sta attendendo una risposta chiede l'indovinello if not mob.specials or not mob.specials["wait_for_reply"]: riddle_number = random.choice(RIDDLES.keys()) to_say = "a %s *zugiolone* " % player.code to_say += RIDDLES[riddle_number][0] defer_if_possible(1, mob, player, command_say, mob, to_say) mob.specials["wait_for_reply"] = True mob.specials["player"] = player.code mob.specials["riddle"] = riddle_number message = "*asciutto* tempo scaduto e nessuno ha indovinato..." defer(WAITING_TIME, reset_timer, mob, message) return # Ripulisce la risposta del giocatore da paccottaglie e da articoli e simili phrase = ALFA_ONLY_PATTERN.sub("", phrase) phrase = remove_little_words(phrase) riddle_number = mob.specials["riddle"] print riddle_number solutions = RIDDLES[riddle_number][1:] for solution in solutions: print "soluzioni: ", solution, " frasi: ", phrase # (TD) qui al posto della is_same ci starebbe bene una futura implementazione di soundex if is_same(phrase, solution): congratulation(mob, player) reset_timer(mob) break
def get_extra(self, argument, exact=False): """ Cerca un'extra particolare tramite l'argomento passato, esegue la ricerca in maniera esatta oppure anche in maniera prefissa. Questa funzione è da chiamare dai metodi get_extra delle stanze e delle entità. """ if not argument: log.bug("argument non è un parametro valido: %s" % argument) return None # ------------------------------------------------------------------------- for extra in self: if is_same(multiple_arguments(extra.keywords), argument): return extra # Se viene passato un argomento lungo un solo carattere allora non viene # eseguita la ricerca prefissa, questo per evitare che i player eseguano # un brute force per trovare eventuali extra nascoste (look a, look b, # look c, look d...) if not exact and len(argument) >= config.min_secret_arg_len: for extra in self: if is_prefix(argument, multiple_arguments(extra.keywords)): return extra return None
def after_listen_say(mob, player, target, phrase, behavioured): if not player.IS_PLAYER: return # Verifico che gli si parli con "a" if target != mob: return # Se non sta attendendo una risposta chiede l'indovinello if not mob.specials or not mob.specials["wait_for_reply"]: riddle_number = random.choice(RIDDLES.keys()) to_say = "a %s *zugiolone* " % player.code to_say += RIDDLES[riddle_number][0] defer_if_possible(1, mob, player, command_say, mob, to_say) mob.specials["wait_for_reply"] = True mob.specials["player"] = player.code mob.specials["riddle"] = riddle_number message = "*asciutto* tempo scaduto e nessuno ha indovinato..." defer(WAITING_TIME, reset_timer, mob, message) return # Ripulisce la risposta del giocatore da paccottaglie e da articoli e simili phrase = ALFA_ONLY_PATTERN.sub("", phrase) phrase = remove_little_words(phrase) riddle_number = mob.specials["riddle"] print riddle_number solutions = RIDDLES[riddle_number][1 : ] for solution in solutions: print "soluzioni: ", solution, " frasi: ", phrase # (TD) qui al posto della is_same ci starebbe bene una futura implementazione di soundex if is_same(phrase, solution): congratulation(mob, player) reset_timer(mob) break
def before_listen_say(listener, speaker, apprendista, phrase, ask, exclaim, behavioured): if not speaker.IS_PLAYER: return if not apprendista.specials or not "apprendista:player_code" in apprendista.specials or not "apprendista_situation" in apprendista.specials: return player_code = apprendista.specials["apprendista:player_code"] situation = apprendista.specials["apprendista_situation"] if situation == "look": if speaker.code != player_code: to_say = "a %s *allegro* Benvenuto nella bottega del tagliapietre! Eseguiamo lavorazioni per tutti i gusti e tutte le voglie!" % speaker.code command_say(apprendista, to_say) return if is_same(phrase, "no"): defer(1, reveal_secret, apprendista, speaker) defer(60, del_specials, apprendista) return defer(1, ask_again, apprendista, speaker) defer(60, del_specials_status, apprendista, "domanda") return if situation == "domanda": if speaker.code != player_code: to_say = "a %s *allegro* Benvenuto nella bottega del tagliapietre! Eseguiamo lavorazioni per tutti i gusti e tutte le voglie!" % speaker.code command_say(apprendista, to_say) return phrase = ALFA_ONLY_PATTERN.sub("", phrase) if is_same(phrase, "si"): defer(1, reveal_secret, apprendista, speaker) defer(60, del_specials, apprendista) return defer(1, no_secret, apprendista, speaker) del_specials(apprendista) return if situation == "segreto_svelato": defer(1, no_more_secrets, apprendista, speaker) del_specials(apprendista)
def get_area_from_argument(argument, only_exact=False): if not argument: log.bug("argument non è un parametro valido: %r" % argument) return None # ------------------------------------------------------------------------- for area in database["areas"].itervalues(): if is_same(argument, area.code) or is_same(argument, area.name): return area if only_exact: return None for area in database["areas"].itervalues(): if is_prefix(argument, area.code) or is_prefix(argument, area.name): return area return None
def is_singular(argument): """ Ritorna vero se l'argomento passato è una parola in singolare. """ if not argument: log.bug("argument non è un parametro valido: %r" % argument) return False # ------------------------------------------------------------------------- for entry_word in vocabulary: if is_same(argument, (entry_word.masculine_singular, entry_word.feminine_singular)): return True elif is_same(argument, (entry_word.masculine_plural, entry_word.feminine_plural)): return False # (TD) da finire, anche questa funzione come is_masculine non è pienamente # programmabile return True
def _find_entities_handler_for_admin(entity, argument, list_to_search, compare_function, avoid_inventory=False, avoid_equipment=True, avoid_doors=False): """ Per velocizzare la find_entity, che con parametro location passato a Null può arrivare a rallentamenti notevoli, è stata creata questa copia dalla _find_entity_handler con un check aggiuntivo che riguarda solo gli admin. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return [] if not argument: log.bug("argument non è un parametro valido: %r" % argument) # (TT) questo test potrebbe non servire return [] if not list_to_search and list_to_search != []: log.bug("list_to_search non è valido: %r" % list_to_search) return [] if not compare_function: log.bug("compare_function non è un parametro valido: %r" % compare_function) return [] # ------------------------------------------------------------------------- entities = [] for target in list_to_search: if avoid_inventory and len(target.wear_mode) == 0: continue if avoid_equipment and len(target.wear_mode) != 0: continue if avoid_doors and target.door_type and target.is_hinged(): continue if not entity.can_see(target): continue keywords = target.get_keywords_attr(entity) if not keywords: log.bug("target %s senza keywords valide: %s" % (target.code, keywords)) continue if compare_function(argument, multiple_arguments(keywords)) or is_same( argument, target.code): entities.append(target) return entities
def find_entity_from_args(self, arg, argument, quantity=1, location=None, entity_tables=None): """ Serve a trovare un'entità nell'inventario di self a seconda degli argomenti passati. Se vi è un solo argomento allora prende quello (look target). Se ve ne sono due allora prende il secondo (look extra target). Se si passa il parametro location allora viene utilizzata la find_entity e non la find_entity_extensively. """ if not arg: log.bug("arg non è un parametro valido: %r" % arg) return None, "", "" if not argument and argument != "": log.bug("argument non è un parametro valido: %r" % argument) return None, "", "" if quantity < 0: log.bug("quantity non è un parametro valido: %d" % quantity) return # ------------------------------------------------------------------------- if not entity_tables: entity_tables = self.ENTITY_TABLES if not argument: target_argument = arg extra_argument = "" else: target_argument = argument extra_argument = arg if is_same(target_argument, ("me", "self")): target = self else: if location: target = self.find_entity(target_argument, quantity=quantity, location=location, entity_tables=entity_tables) else: target = self.find_entity_extensively(target_argument, quantity=quantity, entity_tables=entity_tables) #global get_direction #if not get_direction: # from src.room import get_direction # Se il target è una porta aperta ricavata tramite una direzione allora # dà la precedenza all'uscita e non alla porta if (target and target.door_type and DOOR.CLOSED not in target.door_type.flags and get_direction(target_argument, exact=False) != DIR.NONE): return None, target_argument, extra_argument if quantity == 0: return target, target_argument, extra_argument else: return target.split_entity(quantity) if target else None, target_argument, extra_argument
def after_rpg_channel(listener, speaker, target, phrase, ask, exclaim, behavioured): destination_room = Destination(2, 0, -1, "conflitti").get_room() if not destination_room: # Forse non è stata ancora resettato nulla alla destinazione return False phrase = ALFA_ONLY_PATTERN.sub("", phrase) if is_same(phrase, "tutto qui sta per nutrirsi di me"): speaker = speaker.from_location(1) speaker.to_location(destination_room, use_look=True) return False
def after_listen_say(charlie, speaker, target, phrase, ask, exclaimi, behavioured): if not speaker.IS_PLAYER: return # Controlla se la quest non sia già stata resettata oppure avanzata if ("charlie_banana_quest:status" not in charlie.specials or charlie.specials["charlie_banana_quest:status"] != "domanda"): return # Ricava la frase ripulita dalla punteggiatura e non continua la quest fino # a che il giocatore non dice: sì phrase = ALFA_ONLY_PATTERN.sub("", phrase) if not is_same(phrase, "si"): return # Guarda il giocatore che ha risposto, brrrr, fa sempre senso vedere i mob # così "intelligenti" command_look(charlie, speaker.code) # Ignora coloro che hanno risposto ma che non sono stati scelti per la quest quest_player_code = charlie.specials["charlie_banana_quest:player"] if speaker.code != quest_player_code: quest_player = database["players"][quest_player_code] # Ricava il nome o la short per come lo vede charlie to_say = "a %s *concentrato* Grazie, ma no, grazie! Sto aspettando la risposta da %s." % ( speaker.code, quest_player.get_name(charlie)) command_say(charlie, to_say) return # Visto che il secondo stadio della missione si sta attivando cancella il # precedente reset che è meglio che sia reimpostato a fine funzione delete_charlie_reset_call(charlie) # Ecco un nuovo pollo da spennare! Finalmente il giocatore si è deciso a # rispondere! # Facciamo avanzare lo stato della quest e descriviamo quello che vogliamo charlie.specials["charlie_banana_quest:status"] = "cerca" to_say = "a %s *esasperato* Non ce la faccio più! Questi due unicorni mi stanno facendo impazzire!" % quest_player_code reactor.callLater(random.randint(1, 2), command_say, charlie, to_say) to_say = "a %s Portami due banane, cosicché io possa sopportarli almeno per un po'.." % quest_player_code reactor.callLater(random.randint(4, 6), command_say, charlie, to_say) # (TT) questo è da snoopare.. forse non funziona il self say con parole chiave del nome to_murmur = "a self *pensieroso* Già! Con due banane potrei..." reactor.callLater(random.randint(20, 40), command_murmur, charlie, to_murmur) # Ecco qui, qui viene impostata la durata media della quest, ovvero quanto # charlie attenderà che il giocatore gli porti due banane reset_call = reactor.callLater(random.randint(200, 300), reset_banana_quest, charlie) charlie.specials["charlie_banana_quest:reset_call"] = reset_call
def _find_entity_handler_for_admin(entity, argument, list_to_search, number, compare_function, avoid_inventory=False, avoid_equipment=True, avoid_doors=False): """ Per velocizzare la find_entity, che con parametro location passato a Null può arrivare a rallentamenti notevoli, è stata creata questa copia dalla _find_entity_handler con un check aggiuntivo che riguarda solo gli admin. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return None if not argument: log.bug("argument non è un parametro valido: %r" % argument) # (TT) questo test potrebbe non servire return None if not list_to_search and list_to_search != []: log.bug("list_to_search non è valido: %r" % list_to_search) return None if number <= 0: log.bug("number non è un parametro valido: %r" % number) return None if not compare_function: log.bug("compare_function non è un parametro valido: %r" % compare_function) return None # ------------------------------------------------------------------------- counter = 0 for target in list_to_search: if avoid_inventory and len(target.wear_mode) == 0: continue if avoid_equipment and len(target.wear_mode) != 0: continue if avoid_doors and target.door_type and target.is_hinged(): continue if not entity.can_see(target): continue keywords = target.get_keywords_attr(entity) if not keywords: log.bug("target %s senza keywords valide: %s" % (target.code, keywords)) continue if compare_function(argument, multiple_arguments(keywords)) or is_same(argument, target.code) or is_prefix(argument + "#", target.code): if counter + target.quantity >= number: return target counter += target.quantity return None
def is_singular(argument): """ Ritorna vero se l'argomento passato è una parola in singolare. """ if not argument: log.bug("argument non è un parametro valido: %r" % argument) return False # ------------------------------------------------------------------------- for entry_word in vocabulary: if is_same( argument, (entry_word.masculine_singular, entry_word.feminine_singular)): return True elif is_same( argument, (entry_word.masculine_plural, entry_word.feminine_plural)): return False # (TD) da finire, anche questa funzione come is_masculine non è pienamente # programmabile return True
def after_listen_say(idrusa, speaker, target, phrase, behavioured): if not speaker.IS_PLAYER: return # Controlla se la quest non sia già stata resettata oppure avanzata if "quest_status" not in idrusa.specials or idrusa.specials[ "quest_status"] != "domanda": return # Ricava la frase ripulita dalla punteggiatura e non continua la quest fino # a che il giocatore non dice: sì phrase = ALFA_ONLY_PATTERN.sub("", phrase) if not is_same(phrase, "si"): return # Guarda il giocatore che ha risposto command_look(idrusa, speaker.code) # Ignora coloro che hanno risposto ma che non hanno avviato la quest quest_player_code = idrusa.specials["player_code"] if speaker.code != quest_player_code: quest_player = database["players"][quest_player_code] # Ricava il nome o la short per come lo vede idrusa to_say = "a %s No, non la tua risposta attendo ma di %s." % ( speaker.code, quest_player.get_name(looker=idrusa)) command_say(idrusa, to_say) return # Visto che il secondo stadio della missione si sta attivando cancella il # precedente reset che è meglio che sia reimpostato a fine funzione delete_deferred_reset(idrusa) # Facciamo avanzare lo stato della quest idrusa.specials["quest_status"] = "cerca" # Descriviamo quello che vogliamo to_say = "a %s *in tono grave* L'accesso ti verrà indicato solo se porterai una farfalla!" % speaker.code defer_if_possible(1, 2, idrusa, speaker, command_say, idrusa, to_say) # Ecco qui, qui viene impostata la durata media della quest, ovvero quanto # idrusa attenderà che il giocatore gli porti la farfalla deferred_reset = defer_random_time(200, 300, reset_farfalla_quest, idrusa) idrusa.specials["deferred_reset"] = deferred_reset
def after_listen_say(idrusa, speaker, target, phrase, behavioured): if not speaker.IS_PLAYER: return # Controlla se la quest non sia già stata resettata oppure avanzata if "quest_status" not in idrusa.specials or idrusa.specials["quest_status"] != "domanda": return # Ricava la frase ripulita dalla punteggiatura e non continua la quest fino # a che il giocatore non dice: sì phrase = ALFA_ONLY_PATTERN.sub("", phrase) if not is_same(phrase, "si"): return # Guarda il giocatore che ha risposto command_look(idrusa, speaker.code) # Ignora coloro che hanno risposto ma che non hanno avviato la quest quest_player_code = idrusa.specials["player_code"] if speaker.code != quest_player_code: quest_player = database["players"][quest_player_code] # Ricava il nome o la short per come lo vede idrusa to_say = "a %s No, non la tua risposta attendo ma di %s." % (speaker.code, quest_player.get_name(looker=idrusa)) command_say(idrusa, to_say) return # Visto che il secondo stadio della missione si sta attivando cancella il # precedente reset che è meglio che sia reimpostato a fine funzione delete_deferred_reset(idrusa) # Facciamo avanzare lo stato della quest idrusa.specials["quest_status"] = "cerca" # Descriviamo quello che vogliamo to_say = "a %s *in tono grave* L'accesso ti verrà indicato solo se porterai una farfalla!" % speaker.code defer_if_possible(1, 2, idrusa, speaker, command_say, idrusa, to_say) # Ecco qui, qui viene impostata la durata media della quest, ovvero quanto # idrusa attenderà che il giocatore gli porti la farfalla deferred_reset = defer_random_time(200, 300, reset_farfalla_quest, idrusa) idrusa.specials["deferred_reset"] = deferred_reset
def search_online_player(argument, only_exact=False): """ A volte è meglio dare precedenza alla ricerca dei giocatori online al posto di quelli offline per comodità, poiché spesso gli admin inseriscono l'abbreviazione di un player correntemente online. """ for player in database["players"].itervalues(): if not player.game_request: continue if is_same(argument, player.name): return player if only_exact: return None for player in database["players"].itervalues(): if not player.game_request: continue if is_prefix(argument, player.name): return player return None
def commands_skills_socials_handler(entity, argument, inputs_type): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # argument può essere una stringa vuota if not inputs_type: log.bug("inputs_type non è un parametro valido: %r" % inputs_type) return False # ------------------------------------------------------------------------- arg, argument = one_argument(argument) # Ricava in che lingua visualizzare i comandi language = "en" if entity.IS_PLAYER and OPTION.ITALIAN in entity.account.options: language = "it" if arg: if is_same(arg, ("italiano", "italian")): language = "it" if is_same(arg, ("inglese", "english")): language = "en" # Esegue il controllo degli argomenti if not arg or is_same(arg, ("italiano", "italian", "inglese", "english")): return show_list_normal(entity, language, inputs_type) elif is_same(arg, ("traduzione", "translation", "traduzioni", "translations")): return show_list_translation(entity, language, inputs_type) elif inputs_type == "command" and is_same( arg, ("tipo", "type", "tipi", "types")): return show_list_type(entity, language, inputs_type) elif entity.trust >= TRUST.MASTER and is_same( arg, ("fiducia", "trust", "fiduce", "trusts")): return show_list_trust(entity, language, inputs_type) else: return show_list_found(entity, language, inputs_type, arg)
def commands_skills_socials_handler(entity, argument, inputs_type): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # argument può essere una stringa vuota if not inputs_type: log.bug("inputs_type non è un parametro valido: %r" % inputs_type) return False # ------------------------------------------------------------------------- arg, argument = one_argument(argument) # Ricava in che lingua visualizzare i comandi language = "en" if entity.IS_PLAYER and OPTION.ITALIAN in entity.account.options: language = "it" if arg: if is_same(arg, ("italiano", "italian")): language = "it" if is_same(arg, ("inglese", "english")): language = "en" # Esegue il controllo degli argomenti if not arg or is_same(arg, ("italiano", "italian", "inglese", "english")): return show_list_normal(entity, language, inputs_type) elif is_same(arg, ("traduzione", "translation", "traduzioni", "translations")): return show_list_translation(entity, language, inputs_type) elif inputs_type == "command" and is_same(arg, ("tipo", "type", "tipi", "types")): return show_list_type(entity, language, inputs_type) elif entity.trust >= TRUST.MASTER and is_same(arg, ("fiducia", "trust", "fiduce", "trusts")): return show_list_trust(entity, language, inputs_type) else: return show_list_found(entity, language, inputs_type, arg)
def command_snoop(entity, argument=""): """ Permette di visualizzare tutto l'output di uno o più entità. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- if not argument: syntax = get_command_syntax(entity, "command_snoop") entity.send_output(syntax, break_line=False) being_watched = [] for other in database["players"].values() + database["mobs"].values() + database["items"].values(): if entity in other.snoopers: being_watched.append(other) if being_watched: entity.send_output("Entità che stai snoopando:") for other in being_watched: if other.IS_ITEM: goto_input = "igoto" elif other.IS_ROOM: goto_input = "rgoto" elif other.IS_MOB: goto_input = "mgoto" else: goto_input = "goto" javascript_code = '''javascript:parent.sendInput("%s %s");''' % (goto_input, other.code) entity.send_output('''- <a href='%s'>%s</a>''' % (javascript_code, other.get_name(entity))) else: entity.send_output("Non stai snoopando nessuno.") return False # ------------------------------------------------------------------------- if is_same(argument, "stop"): counter = remove_and_count_snooped_by(entity) if counter > 0: entity.send_output("Smetti di snoopare %d entità." % counter) log.admin("%s smette di snoopare %d entità" % (entity.name, counter)) else: entity.send_output("Non hai nessuna entità snoopata.") return True target = entity.find_entity_extensively(argument, inventory_pos="first") if not target: target = entity.find_entity(argument) if not target: entity.send_output("Nessuna entità trovata con argomento [green]%s[close]" % argument) return False if entity == target: entity.send_output("Non puoi snoopare te stesso.") return False if entity in target.snoopers: target.snoopers.remove(entity) entity.send_output("Smetti di snoopare %s." % target.get_name(entity)) log.admin("%s smette di snoopare %s" % (entity.name, target.name)) else: snoopers = [] for snooper in target.snoopers: if snooper.trust > entity.trust: continue snoopers.append(snooper.name) if snoopers: entity.send_output("%s viene comunque già snoopat%s da: %s" % ( target, grammar_gender(target), ",".join(snoopers))) target.snoopers.append(entity) entity.send_output("Incominci a snoopare %s." % target.get_name(entity)) log.admin("%s incomincia a snoopare %s" % (entity.name, target.name)) return True
def get_error_message_name(name, already_in_database, table_name="accounts"): """ Controlla che il nome passato sia valido. Questa funzione viene utilizzata sia per i nomi degli account sia per quelli dei personaggi. Ritorna un messaggio vuoto se tutto è a posto, altrimenti il primo messaggio d'errore incontrato. Bisogna passare l'argomento already_in_database uguale a False quando si controlla l'integrità di un nome di Account o di Player appena creati e non ancora aggiunti al relativo database, viceversa bisogna passarlo a True. """ if table_name not in ("players", "accounts"): return "L'argomento table_name non è valido: %s" % table_name # ------------------------------------------------------------------------- name = name or "" # Se è un nome di un personaggio rimuove gli eventuali codici css if table_name == "players": name = remove_colors(name) # Controlla la lunghezza del nome length = len(name) if length < config.min_len_name: return "Nome troppo corto, deve essere almeno di %d caratteri." % config.min_len_name if length > config.max_len_name: return "Nome troppo lungo, può essere al massimo lungo %d caratteri." % config.max_len_name # Controlla che i caratteri del nome siano solo alfabetici o accentati # (BB) c'è ancora il problema degli accenti che non vengono letti da scritte # inviate tramite web, commentate alcune righe in favore di un rimpiazzo # in attesa del python 3.0 per risolvere la faccenda if table_name == "accounts" and not isalnum_accent(name): #return "Il nome può essere formato solo da lettere (accentate o meno) e da numeri." return "Il nome può essere formato solo da lettere e da numeri." if table_name == "players" and not isalpha_accent(name): #return "Il nome può essere formato solo da lettere (accentate o meno)." return "Il nome può essere formato solo da lettere." # Il nome può avere in più un accento per ogni tre caratteri if count_accents(name) > len(name) / 3: return "Il nome, per essere maggiormente leggibile, può avere solo un accento ogni tre caratteri." # Controlla che il nome abbia una determinata varietà di caratteri inseriti # per evitare nomi come Aaa if len(set(name.lower())) < math.floor(math.log(len(name)) * 2): return "Nome troppo poco vario, utilizzare un maggior numero di vocali o consonanti differenti" # Controlla se esiste già il nome nel database passato, bisogna utilizzare # is_same() altrimenti nomi simili, ma uno con vocale semplice e l'altro # con vocale accentanta, vengono visti come differenti for data in database[table_name].itervalues(): if is_same(data.name, name) or (hasattr(data, "code") and is_same(data.code, name)): # Se si sta controllando un nome già esistente nel database # quando lo trova per una volta lo salta if already_in_database: already_in_database = False continue return "Il nome è già utilizzato in un altro account." # Controlla che il nome non sia una parolaccia, una parola off-rpg, un # nome non utilizzabile o una little word, che degenererebbe la creazione # dinamica delle kewywords per i personaggi for swear_word in swearwords: if is_same(swear_word, name): return "Il nome non è valido perché è una parolaccia." if table_name == "players": for offrpg_word in offrpg_words: if is_same(offrpg_word, name): return "Il nome non è valido perché è una parola non GDR." for forbidden_name in forbidden_names: if is_same(forbidden_name, name): return "Il nome non è valido." for little_word in little_words: if is_same(little_word, name): return "Il nome non è valido." # Controlla che la prima lettera sia maiuscola e il resto minuscolo if name != name.capitalize(): return "Il nome non inizia con la maiuscola e il resto minuscolo" # Se tutto è ok ritorna un messaggio vuoto return ""
def command_timemachine(entity, argument): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- if not argument: syntax = get_command_syntax(entity, "command_timemachine") entity.send_output(syntax, break_line=False) return False minute = calendar.minute hour = calendar.hour day = calendar.day month = calendar.month year = calendar.year args = multiple_arguments(argument) # Permette di digitare il comando anche così: 'time machine' if is_same(args[0], "machine"): args = args[1:] if not args: syntax = get_command_syntax(entity, "command_timemachine") entity.send_output(syntax, break_line=False) return False if is_number(args[0]): minute = int(args[0]) else: entity.send_output( "Il primo argomento, relativo ai [white]minuti[close], dev'essere numerico e non: [green]%s[close]" % args[0]) return False if minute < 0 or minute > config.minutes_in_hour - 1: entity.send_output("I minuti devono essere tra 0 e %d." % (config.minutes_in_hour - 1)) return False if len(args) > 1: if is_number(args[1]): hour = int(args[1]) else: entity.send_output( "Il secondo argomento, relativo all'[white]ora[close], dev'essere numerico e non: [green]%s[close]" % args[1]) return False if hour < 0 or hour > config.hours_in_day - 1: entity.send_output("L'ora dev'essere tra 0 e %d." % (config.hours_in_day - 1)) return False if len(args) > 2: if is_number(args[2]): day = int(args[2]) else: entity.send_output( "Il terzo argomento, relativo al [white]giorno[close], dev'essere numerico e non: [green]%s[close]" % args[2]) return False if day < 1 or day > config.days_in_month: entity.send_output("Il numero del giorno dev'essere tra 1 e %d." % config.days_in_month) return False if len(args) > 3: if is_number(args[3]): month = int(args[3]) else: entity.send_output( "Il quarto argomento, relativo al [white]mese[close], dev'essere numerico e non: [green]%s[close]" % args[3]) return False if month < 1 or month > config.months_in_year: entity.send_output("Il numero del mese dev'essere tra 1 e %d." % config.months_in_year) return False month = MONTH.elements[month - 1] if len(args) > 4: if is_number(args[4]): year = int(args[4]) else: entity.send_output( "Il quinto argomento, relativo all'[white]anno[close], dev'essere numerico e non: [green]%s[close]" % args[4]) return False if (minute == calendar.minute and hour == calendar.hour and day == calendar.day and month == calendar.month and year == calendar.year): entity.send_output( "La data da impostare è la stessa di quella corrente!") return False stop_all_reset_events() calendar.minute = minute calendar.hour = hour calendar.day = day calendar.month = month calendar.year = year article = "le" if hour == 1: article = "la" entity.send_output( "La nuova data impostata è: %s [white]%d[close] e [white]%d[close] del giorno [white]%d[close] del mese %s nell'anno [white]%d[close]" % (article, hour, minute, day, month, year)) # Ora che è cambiata la data reinizializza tutti i reset defer_all_reset_events() return True
def before_giving(player, banana, charlie, direction, behavioured): if not player.IS_PLAYER: to_say = "a %s *concentrato* Grazie, ma no, grazie! Non accetto nulla da chicchessia." % player.get_keywords_attr().split()[0] reactor.callLater(random.randint(1, 2), command_say, charlie, to_say) return True command_look(charlie, player.code) # Charlie non ha iniziato a dare nessuna quest if "charlie_banana_quest:status" not in charlie.specials: to_say = "a %s *impensierito* Grazie, ma no, grazie! Non accetto mai caramelle da sconosciuti." % (player.code) reactor.callLater(random.randint(1, 2), command_say, charlie, to_say) to_say = "a %s Sai, da quanto ho perso un rene..." % (player.code) reactor.callLater(random.randint(3, 4), command_whisper, charlie, to_say) return True quest_player_code = charlie.specials["charlie_banana_quest:player"] quest_player = database["players"][quest_player_code] quest_player_name = quest_player.get_name(charlie) quest_status = charlie.specials["charlie_banana_quest:status"] if quest_status == "domanda": to_say = "a %s *concentrato* Grazie, ma no, grazie! Sto attendendo che %s si decida a rispondermi." % ( player.code, quest_player_name) reactor.callLater(random.randint(1, 2), command_say, charlie, to_say) return True # Controlla che l'entità che dà sia il giocatore della quest if player.code != quest_player_code: to_say = "a %s Grazie, ma no, grazie! Sto aspettando delle banane da parte di %s." % ( player.code, quest_player_name) reactor.callLater(random.randint(1, 2), command_say, charlie, to_say) return True # Controlla se l'oggetto dato sia una banana, lo fa in maniera grezza, prima # di tutto controlla se sia un cibo, e poi ne controlla la short if not banana.entitype == ENTITYPE.FOOD: to_say = "a %s *critico* Questa cosa non mi sembra del cibo, figuriamoci una banana!" % quest_player_code reactor.callLater(random.randint(1, 2), command_say, charlie, to_say) return True if not is_same(("banana", "banane"), banana.short.split()) and not is_same(("banana", "banane"), banana.short_night.split()): to_say = "a %s *disinteressato* Sono convinto che sia buono, ma ora non ho fame, ho bisogno di banane!" % quest_player_code reactor.callLater(random.randint(1, 2), command_say, charlie, to_say) return True # Charlie decide che l'oggetto dato è abbastanza bananoso e lo accetta if charlie.specials["charlie_banana_quest:status"] != "banana" and is_same("banana", banana.short.split()): to_yell = "a %s *sorpreso* Eccone una! Ora mi serve anche l'altra!" % quest_player_code reactor.callLater(random.randint(1, 2), command_yell, charlie, to_yell) charlie.specials["charlie_banana_quest:status"] = "banana" else: charlie.specials["charlie_banana_quest:status"] = "completa" # Ora che la quest è completa ne blocca un eventuale reset, fino a # quando le banane non si sciolgono delete_charlie_reset_call(charlie) to_yell = "a %s *al settimo cielo* Sei il mio salvatore! Finalmente con queste banane potrò sopportare questi due!" % quest_player_code reactor.callLater(random.randint(1, 2), command_yell, charlie, to_yell) to_emote = "con la $hand destra si mette una banana nell'orecchio destra" reactor.callLater(random.randint(4, 6), command_emote, charlie, to_emote) to_emote = "con la $hand sinistra si mette una banana nell'orecchio sinistra" reactor.callLater(random.randint(7, 9), command_emote, charlie, to_emote) to_say = "a self *sollevato* finalmente non li sento più..." reactor.callLater(random.randint(10, 13), command_say, charlie, to_say) # Tra un po' di tempo le banane si squaglieranno e quindi charlie # dovrà di nuovo affidarsi a qualche alla bontà di qualche player reactor.callLater(random.randint(3600, 4800), you_are_not_the_banana_king, charlie)
def before_giving(player, pesce, gatto, direction, behavioured): if not player.IS_PLAYER: player.act( "$N ti soffia e fa come per graffiarti, non sei una compagnia desiderabile.", TO.ENTITY, gatto) player.act( "$N, con il pelo ritto sulla schiena, scaccia $n in malomodo.", TO.OTHERS, gatto) player.act( "$n ti si avvicina un po' troppo per i tuoi gusti e lo scacci senza troppi complimenti.", TO.TARGET, gatto) return True pesce_keywords = multiple_arguments(pesce.get_keywords_attr(looker=gatto)) if is_same(pesce_keywords, ("agrumi", "agrume", "arance", "arancia", "limone", "limoni", "bergamotto", "mandarino", "mandarini", "pompelmo", "pompelmi", "cedro", "cedri", "mandarancio", "mandaranci", "lime")): num_rand = random.randint(1, 100) if num_rand < 75: player.act("$N ti attacca in un raptus di furia assassina!", TO.ENTITY, gatto) player.act("Apparentemente senza ragione $N attacca $n.", TO.OTHERS, gatto) player.act( "Quel pazzo di $n ha tentato di darti un agrume, la dovrà pagare!", TO.TARGET, gatto) player.life -= give_damage(player) return True else: player.act( "$N sguaina le unghie e tenta di attaccarti ma fortunatamente manca il colpo.", TO.ENTITY, gatto) player.act( "$N fa uno scatto verso $n come per attaccarlo ma la zampata non va a buon fine.", TO.OTHERS, gatto) player.act("Tenti di attacare $n ma non ci riesci", TO.TARGET, gatto) return True if not pesce.entitype == ENTITYPE.FOOD or not is_same( pesce_keywords, ("pesce", "pesci")): player.act("$N storce i baffi schizzinoso.", TO.ENTITY, gatto) player.act( "$n tenta inutilmente di dare qualcosa a $N che lo snobba schizzinoso.", TO.OTHERS, gatto) player.act( "$n tenta di propinarti qualcosa che anche un cane rifiuterebbe.", TO.TARGET, gatto) return True if pesce.weight > PESO_MASSIMO: player.act( "$N ti guarda perplesso dopo aver valutato il peso di ciò che gli vorresti dare.", TO.ENTITY, gatto) player.act("Noti uno strano gioco di sguardi tra $N e $n.", TO.OTHERS, gatto) player.act( "$n cerca di darti qualcosa di veramente troppo pesante per te.", TO.TARGET, gatto) return True for content in gatto.iter_contains(use_reversed=True): if FLAG.INGESTED in content.flags: if content.entitype == ENTITYPE.FOOD: player.act( "$N rifiuta il cibo che gli offri, d'evessere sazio!", TO.ENTITY, gatto) player.act( "$n vorrebbe dare qualcosa a $N che però non sembra interessato..", TO.OTHERS, gatto) player.act( "$n vorrebbe ingozzarti, la tua dignità di impedisce di far la figura del maiale all'ingrasso..", TO.TARGET, gatto) return True else: content.extract(1) return True palla = Item(PROTO_FUR_CODE) defer_random_time(1, 3, puke_hairs, gatto, player, palla) defer_random_time(4, 5, fish_eat, player, gatto, pesce)
def interpret(entity, argument, use_check_alias=True, force_position=True, show_input=True, show_prompt=True, behavioured=False): """ Funzione che interpreta gli inputi inviati dalle entità. L'argomento use_check_alias a False viene passato dalla find_alias per evitare chiamate di alias da altri alias e quindi ricorsioni. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return if not argument: log.bug("argument non è un parametro valido: %r" % argument) return # ------------------------------------------------------------------------- # Si assicura che colui che esegue l'azione sia un'entità unica e # non un mucchio fisico entity = entity.split_entity(1) if FLAG.CONVERSING in entity.flags and len(argument) == 1 and is_number( argument): # (TD) return arg, argument = one_argument(argument, search_separator=False) arg = arg.lower() input, huh_input, lang = multiple_search_on_inputs( entity, arg, use_check_alias=use_check_alias, argument=argument) # Utilizzo bislacco di lang per indicare che è stato trovato un alias # e che questo verrà processato tramite un'altra chiamata all'interpret if use_check_alias and lang == "alias": return # Resetta l'inattività di un player se ha inviato un comando if entity.IS_PLAYER: entity.inactivity = 0 # Se non ha trovato nulla invia un messaggio apposito if not input: if show_input: entity.send_output(''' <span class="system">%s %s</span>''' % (remove_colors(arg), argument)) entity.send_output("Huh?") # Se l'input non è stato trovato neanche nell'altra lingua allora # esegue il log dell'input, potrebbero esservene alcuni di sensati # da utilizzare in futuro come sinonimi # Scrive anche gli huh input dei mob così da ricavare gamescript o # random_do_inputs errati if not huh_input: log.huh_inputs(entity, arg) # Se serve visualizza il prompt if show_input: entity.send_prompt() return False # Poiché alcune words nello stesso input a volte hanno prefisso differente # tra loro allora cerca quello più simile possibile per farlo visualizzare # all'utente founded_input = input.findable_words[0] for word in input.findable_words: if is_prefix(arg, word): founded_input = word break # Se il giocatore è in stato di wait e l'input è un comando interattivo # allora evita di inviarlo subito ma lo mette in coda if entity.deferred_wait and CMDFLAG.INTERACT in input.command.flags: entity.waiting_inputs.append("%s %s" % (founded_input, argument)) return False else: # Altrimenti scrive anche l'input a fianco del prompt if show_input: entity.send_output(''' <span class="system">%s %s</span>''' % (founded_input, argument)) # Se il pg si è scollegato dalla pagina di gioco non esegue il comando if not entity.location: return False # Vengono salvate le informazioni sull'ultimo input inviato if argument: last_input = "%s %s" % (arg, argument) else: last_input = arg engine.last_input_sender = entity engine.last_input_sended = last_input # Si salva l'ultimo input inviato con successo if show_input and entity.IS_PLAYER and CMDFLAG.NO_LAST_INPUT not in input.command.flags: entity.last_input = last_input if CMDFLAG.GDR in input.command.flags: entity.sended_inputs.append("%s %s" % (founded_input, argument)) if argument: argument = html_escape(argument) # Gestisce i comandi che devono essere digitati per intero command = input.command if CMDFLAG.TYPE_ALL in command.flags and not is_same( arg, input.findable_words): first_words, other_words = one_argument(input.words, search_separator=False) entity.send_output( "Se vuoi veramente farlo devi scrivere per intero [limegreen]%s[close]." % first_words) execution_result = False elif not check_position(entity, command.position, force_position): # Se la posizione non è corretta invia il relativo messaggio d'errore vowel_of_genre = grammar_gender(entity) if entity.position == POSITION.DEAD: entity.send_output("Un po' difficile fino a che rimani MORT%s.." % vowel_of_genre.upper()) elif (entity.position == POSITION.MORTAL or entity.position == POSITION.INCAP): entity.send_output("Sei troppo ferit%s per farlo." % vowel_of_genre) elif entity.position == POSITION.STUN: entity.send_output("Sei troppo intontit%s per farlo." % vowel_of_genre) elif entity.position == POSITION.SLEEP: entity.send_output("Nei tuoi sogni, o cosa?") elif entity.position == POSITION.REST: entity.send_output("Nah.. Sei troppo rilassat%s ora.." % vowel_of_genre) elif entity.position == POSITION.KNEE: entity.send_output("Non puoi farlo da inginocchiat%s" % vowel_of_genre) elif entity.position == POSITION.SIT: entity.send_output("Non puoi farlo da sedut%s." % vowel_of_genre) else: log.bug("Manca la posizione %r" % entity.position) execution_result = False else: if command.type == CMDTYPE.SOCIAL: check_social(entity, command, argument=argument, behavioured=behavioured) if CMDFLAG.PRIVATE not in command.flags and ( entity.IS_PLAYER or config.print_entity_inputs) and show_input and show_prompt: if entity.IS_PLAYER: write_on_file = True else: write_on_file = False log.input("'%s%s%s' digitato da %s in %s" % (founded_input, " " if argument else "", argument, entity.code, entity.location.get_name()), write_on_file=write_on_file) # Per comodità di sviluppo ricarica il modulo relativo al comando ogni # volta che lo si digita, così da poter testare le modifiche al codice # dei comandi senza aver bisogno di riavviare il gioco tutte le volte if config.reload_commands: reload(command.module) command.import_module_and_function() # Se si sta eseguendo un'azione che richiede tempo la interrompe if entity.action_in_progress and CMDFLAG.INTERACT in command.flags: if entity.action_in_progress.defer_later: entity.action_in_progress.stop() entity.action_in_progress = None # Esegue la funzione del comando cronometrandola input.counter_use += 1 starting_time = time.time() execution_result = (command.function)(entity, argument) if command.fun_name[: 8] == "command_" and execution_result != True and execution_result != False: log.bug("execution_result non è valido per il comando %s: %r" % (command.fun_name, execution_result)) if command.fun_name[: 6] == "skill_" and execution_result != "clumsy" and execution_result != "failure" and execution_result != "success" and execution_result != "magistral": log.bug("execution_result non è valido per la skill %s: %r" % (command.fun_name, execution_result)) execution_time = time.time() - starting_time # Comandi che superano il tempo definito nella max_execution_time # possono portare a bachi creati dalla deferred impostata nel metodo # split_entity (nello stesso metodo c'è un commento con più informazioni) # Quindi devono essere il più possibile da evitare, allo stesso tempo # sarebbe meglio che il max_execution_time sia relativamente basso. if execution_time > config.max_execution_time: log.time( "Il comando %s è stato eseguito in troppo tempo: %f secondi" % (command.fun_name, execution_time)) command.timer += execution_time # Gestisce i comandi da loggare if CMDFLAG.LOG in command.flags: log.command("%s %s" % (command.fun_name, argument)) if FLAG.AFK in entity.flags and command.fun_name != "command_afk": command_afk(entity) # Infine visualizza il prompt if show_prompt: entity.send_prompt() # Se la lista di input ancora da inviare non è vuota allora crea un # "falso wait" per forzarne l'invio. In teoria potrei inviarlo da qui, ma # il codice di ritorno execution_result andrebbe perduto, ecco perché # si fa uso della wait(). if not entity.deferred_wait and entity.waiting_inputs: entity.wait(0.001) # Questa parte è da attivare con l'opzione check_references solo nei # server di test perché consuma molta cpu essendo eseguita su migliaia # di dati ad ogni invio di input, è una modalità di diagnostica # che non bada a spese in termini prestazionali if config.check_references and not database.reference_error_found: database.check_all_references() return execution_result
def command_countraces(entity, argument=""): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- only_items = False if not argument: syntax = get_command_syntax(entity, "command_countraces") entity.send_output(syntax, break_line=False) else: arg, argument = one_argument(argument) if is_same(arg, "items") or (argument and is_same(argument, "items")): only_items = True if only_items: attr_suffix = "items" else: attr_suffix = "mobs" counter = {} counter["totale"] = EnumElementDict() for area in database["areas"].itervalues(): counter[area] = EnumElementDict() targets = getattr(area, attr_suffix) for target in targets: if target.race == RACE.NONE: continue if target.race not in counter[area]: counter[area][target.race] = 0 counter[area][target.race] += 1 if target.race not in counter["totale"]: counter["totale"][target.race] = 0 counter["totale"][target.race] += 1 if only_items: entity.send_output("\nLista del numero di razze degli oggetti suddivisi per area.", break_line=False) else: entity.send_output("\nLista del numero di razze dei mob suddivisi per area.", break_line=False) output = [] for area in counter: if not counter[area] or area == "totale": continue output.append('''<br>[%s]%s[close] (%s):''' % (area.color.web_name, area.name, area.code)) output.append('''<table class="mud" style="width:75%">''') for race_element in RACE.elements: if race_element not in counter[area]: continue output.append('''<tr><td style="width:33%%">%s</td><td style="width:33%%">%s</td><td>%d</td></tr>''' % ( race_element.code, race_element, counter[area][race_element])) output.append('''</table>''') if output: output.append('''<br>[white]Gran Totale[close]:''') output.append('''<table class="mud" style="width:75%">''') for race_element in RACE.elements: if race_element not in counter["totale"]: continue output.append('''<tr><td style="width:33%%">%s</td><td style="width:33%%">%s</td><td>%d</td></tr>''' % ( race_element.code, race_element, counter["totale"][race_element])) output.append('''</table>''') entity.send_output("".join(output)) else: entity.send_output('''<br>Nessuna!''') return True
def get_help(entity, argument): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False if not argument: log.bug("argument non è un parametro valido: %r" % argument) return "" # ------------------------------------------------------------------------- # Se argument è formato da più parole erroneamente separate da più spazi # allora li converte in un'unico spazio if " " in argument: argument = " ".join(argument.split()) # Cerca prima tra gli help della propria lingua in maniera esatta if entity.IS_PLAYER or OPTION.ITALIAN in entity.account.options: for help in database["helps"].itervalues(): if not help.text and help.admin_text and entity.trust == TRUST.PLAYER: continue if is_same(argument, multiple_arguments(help.italian_keywords)): return help else: for help in database["helps"].itervalues(): if not help.text and help.admin_text and entity.trust == TRUST.PLAYER: continue if is_same(argument, multiple_arguments(help.english_keywords)): return help # Cerca poi tra gli help della propria lingua in maniera prefissa if entity.IS_PLAYER or OPTION.ITALIAN in entity.account.options: for help in database["helps"].itervalues(): if not help.text and help.admin_text and entity.trust == TRUST.PLAYER: continue if is_prefix(argument, multiple_arguments(help.italian_keywords)): return help else: for help in database["helps"].itervalues(): if not help.text and help.admin_text and entity.trust == TRUST.PLAYER: continue if is_prefix(argument, multiple_arguments(help.english_keywords)): return help # Cerca poi tra gli help della lingua secondaria in maniera esatta if entity.IS_PLAYER or OPTION.ITALIAN in entity.account.options: for help in database["helps"].itervalues(): if not help.text and help.admin_text and entity.trust == TRUST.PLAYER: continue if is_same(argument, multiple_arguments(help.english_keywords)): return help else: for help in database["helps"].itervalues(): if not help.text and help.admin_text and entity.trust == TRUST.PLAYER: continue if is_same(argument, multiple_arguments(help.italian_keywords)): return help # Cerca poi tra gli help della lingua secondaria in maniera prefissa if entity.IS_PLAYER or OPTION.ITALIAN in entity.account.options: for help in database["helps"].itervalues(): if not help.text and help.admin_text and entity.trust == TRUST.PLAYER: continue if is_prefix(argument, multiple_arguments(help.english_keywords)): return help else: for help in database["helps"].itervalues(): if not help.text and help.admin_text and entity.trust == TRUST.PLAYER: continue if is_prefix(argument, multiple_arguments(help.italian_keywords)): return help return None
def find_entity_from_args(self, arg, argument, quantity=1, location=None, entity_tables=None): """ Serve a trovare un'entità nell'inventario di self a seconda degli argomenti passati. Se vi è un solo argomento allora prende quello (look target). Se ve ne sono due allora prende il secondo (look extra target). Se si passa il parametro location allora viene utilizzata la find_entity e non la find_entity_extensively. """ if not arg: log.bug("arg non è un parametro valido: %r" % arg) return None, "", "" if not argument and argument != "": log.bug("argument non è un parametro valido: %r" % argument) return None, "", "" if quantity < 0: log.bug("quantity non è un parametro valido: %d" % quantity) return # ------------------------------------------------------------------------- if not entity_tables: entity_tables = self.ENTITY_TABLES if not argument: target_argument = arg extra_argument = "" else: target_argument = argument extra_argument = arg if is_same(target_argument, ("me", "self")): target = self else: if location: target = self.find_entity(target_argument, quantity=quantity, location=location, entity_tables=entity_tables) else: target = self.find_entity_extensively( target_argument, quantity=quantity, entity_tables=entity_tables) #global get_direction #if not get_direction: # from src.room import get_direction # Se il target è una porta aperta ricavata tramite una direzione allora # dà la precedenza all'uscita e non alla porta if (target and target.door_type and DOOR.CLOSED not in target.door_type.flags and get_direction(target_argument, exact=False) != DIR.NONE): return None, target_argument, extra_argument if quantity == 0: return target, target_argument, extra_argument else: return target.split_entity( quantity) if target else None, target_argument, extra_argument
def interpret(entity, argument, use_check_alias=True, force_position=True, show_input=True, show_prompt=True, behavioured=False): """ Funzione che interpreta gli inputi inviati dalle entità. L'argomento use_check_alias a False viene passato dalla find_alias per evitare chiamate di alias da altri alias e quindi ricorsioni. """ if not entity: log.bug("entity non è un parametro valido: %r" % entity) return if not argument: log.bug("argument non è un parametro valido: %r" % argument) return # ------------------------------------------------------------------------- # Si assicura che colui che esegue l'azione sia un'entità unica e # non un mucchio fisico entity = entity.split_entity(1) if FLAG.CONVERSING in entity.flags and len(argument) == 1 and is_number(argument): # (TD) return arg, argument = one_argument(argument, search_separator=False) arg = arg.lower() input, huh_input, lang = multiple_search_on_inputs(entity, arg, use_check_alias=use_check_alias, argument=argument) # Utilizzo bislacco di lang per indicare che è stato trovato un alias # e che questo verrà processato tramite un'altra chiamata all'interpret if use_check_alias and lang == "alias": return # Resetta l'inattività di un player se ha inviato un comando if entity.IS_PLAYER: entity.inactivity = 0 # Se non ha trovato nulla invia un messaggio apposito if not input: if show_input: entity.send_output(''' <span class="system">%s %s</span>''' % (remove_colors(arg), argument)) entity.send_output("Huh?") # Se l'input non è stato trovato neanche nell'altra lingua allora # esegue il log dell'input, potrebbero esservene alcuni di sensati # da utilizzare in futuro come sinonimi # Scrive anche gli huh input dei mob così da ricavare gamescript o # random_do_inputs errati if not huh_input: log.huh_inputs(entity, arg) # Se serve visualizza il prompt if show_input: entity.send_prompt() return False # Poiché alcune words nello stesso input a volte hanno prefisso differente # tra loro allora cerca quello più simile possibile per farlo visualizzare # all'utente founded_input = input.findable_words[0] for word in input.findable_words: if is_prefix(arg, word): founded_input = word break # Se il giocatore è in stato di wait e l'input è un comando interattivo # allora evita di inviarlo subito ma lo mette in coda if entity.deferred_wait and CMDFLAG.INTERACT in input.command.flags: entity.waiting_inputs.append("%s %s" % (founded_input, argument)) return False else: # Altrimenti scrive anche l'input a fianco del prompt if show_input: entity.send_output(''' <span class="system">%s %s</span>''' % (founded_input, argument)) # Se il pg si è scollegato dalla pagina di gioco non esegue il comando if not entity.location: return False # Vengono salvate le informazioni sull'ultimo input inviato if argument: last_input = "%s %s" % (arg, argument) else: last_input = arg engine.last_input_sender = entity engine.last_input_sended = last_input # Si salva l'ultimo input inviato con successo if show_input and entity.IS_PLAYER and CMDFLAG.NO_LAST_INPUT not in input.command.flags: entity.last_input = last_input if CMDFLAG.GDR in input.command.flags: entity.sended_inputs.append("%s %s" % (founded_input, argument)) if argument: argument = html_escape(argument) # Gestisce i comandi che devono essere digitati per intero command = input.command if CMDFLAG.TYPE_ALL in command.flags and not is_same(arg, input.findable_words): first_words, other_words = one_argument(input.words, search_separator=False) entity.send_output("Se vuoi veramente farlo devi scrivere per intero [limegreen]%s[close]." % first_words) execution_result = False elif not check_position(entity, command.position, force_position): # Se la posizione non è corretta invia il relativo messaggio d'errore vowel_of_genre = grammar_gender(entity) if entity.position == POSITION.DEAD: entity.send_output("Un po' difficile fino a che rimani MORT%s.." % vowel_of_genre.upper()) elif (entity.position == POSITION.MORTAL or entity.position == POSITION.INCAP): entity.send_output("Sei troppo ferit%s per farlo." % vowel_of_genre) elif entity.position == POSITION.STUN: entity.send_output("Sei troppo intontit%s per farlo." % vowel_of_genre) elif entity.position == POSITION.SLEEP: entity.send_output("Nei tuoi sogni, o cosa?") elif entity.position == POSITION.REST: entity.send_output("Nah.. Sei troppo rilassat%s ora.." % vowel_of_genre) elif entity.position == POSITION.KNEE: entity.send_output("Non puoi farlo da inginocchiat%s" % vowel_of_genre) elif entity.position == POSITION.SIT: entity.send_output("Non puoi farlo da sedut%s." % vowel_of_genre) else: log.bug("Manca la posizione %r" % entity.position) execution_result = False else: if command.type == CMDTYPE.SOCIAL: check_social(entity, command, argument=argument, behavioured=behavioured) if CMDFLAG.PRIVATE not in command.flags and (entity.IS_PLAYER or config.print_entity_inputs) and show_input and show_prompt: if entity.IS_PLAYER: write_on_file = True else: write_on_file = False log.input("'%s%s%s' digitato da %s in %s" % ( founded_input, " " if argument else "", argument, entity.code, entity.location.get_name()), write_on_file=write_on_file) # Per comodità di sviluppo ricarica il modulo relativo al comando ogni # volta che lo si digita, così da poter testare le modifiche al codice # dei comandi senza aver bisogno di riavviare il gioco tutte le volte if config.reload_commands: reload(command.module) command.import_module_and_function() # Se si sta eseguendo un'azione che richiede tempo la interrompe if entity.action_in_progress and CMDFLAG.INTERACT in command.flags: if entity.action_in_progress.defer_later: entity.action_in_progress.stop() entity.action_in_progress = None # Esegue la funzione del comando cronometrandola input.counter_use += 1 starting_time = time.time() execution_result = (command.function)(entity, argument) if command.fun_name[ : 8] == "command_" and execution_result != True and execution_result != False: log.bug("execution_result non è valido per il comando %s: %r" % (command.fun_name, execution_result)) if command.fun_name[ : 6] == "skill_" and execution_result != "clumsy" and execution_result != "failure" and execution_result != "success" and execution_result != "magistral": log.bug("execution_result non è valido per la skill %s: %r" % (command.fun_name, execution_result)) execution_time = time.time() - starting_time # Comandi che superano il tempo definito nella max_execution_time # possono portare a bachi creati dalla deferred impostata nel metodo # split_entity (nello stesso metodo c'è un commento con più informazioni) # Quindi devono essere il più possibile da evitare, allo stesso tempo # sarebbe meglio che il max_execution_time sia relativamente basso. if execution_time > config.max_execution_time: log.time("Il comando %s è stato eseguito in troppo tempo: %f secondi" % (command.fun_name, execution_time)) command.timer += execution_time # Gestisce i comandi da loggare if CMDFLAG.LOG in command.flags: log.command("%s %s" % (command.fun_name, argument)) if FLAG.AFK in entity.flags and command.fun_name != "command_afk": command_afk(entity) # Infine visualizza il prompt if show_prompt: entity.send_prompt() # Se la lista di input ancora da inviare non è vuota allora crea un # "falso wait" per forzarne l'invio. In teoria potrei inviarlo da qui, ma # il codice di ritorno execution_result andrebbe perduto, ecco perché # si fa uso della wait(). if not entity.deferred_wait and entity.waiting_inputs: entity.wait(0.001) # Questa parte è da attivare con l'opzione check_references solo nei # server di test perché consuma molta cpu essendo eseguita su migliaia # di dati ad ogni invio di input, è una modalità di diagnostica # che non bada a spese in termini prestazionali if config.check_references and not database.reference_error_found: database.check_all_references() return execution_result
def command_countraces(entity, argument=""): if not entity: log.bug("entity non è un parametro valido: %r" % entity) return False # ------------------------------------------------------------------------- only_items = False if not argument: syntax = get_command_syntax(entity, "command_countraces") entity.send_output(syntax, break_line=False) else: arg, argument = one_argument(argument) if is_same(arg, "items") or (argument and is_same(argument, "items")): only_items = True if only_items: attr_suffix = "items" else: attr_suffix = "mobs" counter = {} counter["totale"] = EnumElementDict() for area in database["areas"].itervalues(): counter[area] = EnumElementDict() targets = getattr(area, attr_suffix) for target in targets: if target.race == RACE.NONE: continue if target.race not in counter[area]: counter[area][target.race] = 0 counter[area][target.race] += 1 if target.race not in counter["totale"]: counter["totale"][target.race] = 0 counter["totale"][target.race] += 1 if only_items: entity.send_output( "\nLista del numero di razze degli oggetti suddivisi per area.", break_line=False) else: entity.send_output( "\nLista del numero di razze dei mob suddivisi per area.", break_line=False) output = [] for area in counter: if not counter[area] or area == "totale": continue output.append('''<br>[%s]%s[close] (%s):''' % (area.color.web_name, area.name, area.code)) output.append('''<table class="mud" style="width:75%">''') for race_element in RACE.elements: if race_element not in counter[area]: continue output.append( '''<tr><td style="width:33%%">%s</td><td style="width:33%%">%s</td><td>%d</td></tr>''' % (race_element.code, race_element, counter[area][race_element])) output.append('''</table>''') if output: output.append('''<br>[white]Gran Totale[close]:''') output.append('''<table class="mud" style="width:75%">''') for race_element in RACE.elements: if race_element not in counter["totale"]: continue output.append( '''<tr><td style="width:33%%">%s</td><td style="width:33%%">%s</td><td>%d</td></tr>''' % (race_element.code, race_element, counter["totale"][race_element])) output.append('''</table>''') entity.send_output("".join(output)) else: entity.send_output('''<br>Nessuna!''') return True