#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
# MUnDoCAAD MUD Engine
# Copyright (C) 2002-2008, 2021 Josť Manuel Ferrer Ortiz
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License version
# 3, as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Affero General Public License version 3 for more details.
#
# You should have received a copy of the GNU Affero General Public
# License version 3 along with this program. If not, see
# <http://www.gnu.org/licenses/>.
import random
import archivero
import escriba
import mensajero
# Busca un nombre en una lista de entidades
def buscaNombre (palabra, lista):
for entidad in lista:
if palabra in archivero.evaluaPropiedad (entidad, 'nombres'):
return entidad
return None
def coger (personaje, localidad, objeto):
objs = archivero.evaluaPropiedad (localidad, 'lista_objs')
pers = archivero.evaluaPropiedad (localidad, 'lista_pers')
inven = archivero.evaluaPropiedad (personaje, 'contenido')
objeto = buscaNombre (objeto, list (objs) + list (pers) + list (inven))
if not objeto:
return 'Parece que eso no estŠ por aquŪ.'
if objeto in pers: # Es un personaje
return 'Pesa demasiado para ti.'
if objeto in inven:
return 'Ya l' + escriba.o (objeto) + ' tienes.'
testigos = pers.difference ([personaje]) # No advertimos dos veces al jugador
if archivero.evaluaPropiedad (objeto, 'fijo'):
# Advertimos a los testigos de esta acciůn
if testigos: # Sůlo en caso de tenerlos
parte1 = archivero.evaluaPropiedad (personaje, 'titulo') + ' intenta '
parte2 = 'r ' + escriba.el_ (objeto) + ', pero no lo consigue.'
for testigo in pers: # De uno en uno por si alguno es hispanoamericano
mensajero.enviaMensaje (tuple ([testigo]), parte1 + escriba.coge \
(testigo) + parte2)
mensaje = 'Intentas ' + escriba.coge (personaje) + 'r ' + \
escriba.el_ (objeto) + ', pero estŠ' + escriba.n (objeto) + \
' firmemente sujet' + escriba.o (objeto) + '.'
else: # Superadas todas las restricciones
# El personaje coge el objeto en cuestiůn
archivero.escribePropiedad (localidad, 'lista_objs', 1,
objs.difference ([objeto]))
archivero.escribePropiedad (personaje, 'contenido', 1,
inven.union ([objeto]))
# Vemos si el objeto tiene un tratamiento personalizado para la acciůn
mensaje = archivero.evaluaPropiedad (objeto, 'coger')
if mensaje: # El objeto tenŪa tratamiento personalizado
parte2 = mensaje[1] + mensaje[2]
parte3 = mensaje[0] + mensaje[2]
else:
parte2 = ' ' + escriba.el_ (objeto) + '.'
parte3 = parte2
# Advertimos a los testigos de esta acciůn
if testigos: # Sůlo en caso de tenerlos
parte1 = archivero.evaluaPropiedad (personaje, 'titulo') + ' '
for testigo in pers: # De uno en uno por si alguno es hispanoamericano
mensajero.enviaMensaje (tuple ([testigo]),
parte1 + escriba.coge (testigo) + parte2)
mensaje = escriba.coge (personaje).capitalize() + 's' + parte3
return mensaje
def decir (personaje, localidad, mensaje):
# TODO: Las preguntas y exclamaciones pueden empezar en mitad de la frase, ej:
# di ah, Tulisid, Ņves las tildes y eŮes bien?
# TODO: Las URLs no deben ponerse con H inicial mayķscula ni punto final
# Buscamos el primer carŠcter alfabťtico
for i in range (len (mensaje)):
if mensaje[i].isalpha():
# Lo pasamos a mayķscula
mensaje = mensaje[:i] + mensaje[i].upper() + mensaje[i + 1:]
break
else: # Mensaje sin letras
return 'DeberŪas decir al menos alguna palabra.'
# Analizamos los primeros y ķltimos caracteres no alfabťticos
abre_exclam = abre_interr = 0
for i in range (0, i):
if mensaje[i] in ('°', '!'):
abre_exclam += 1
elif mensaje[i] in ('Ņ', '?'):
abre_interr += 1
cier_exclam = cier_interr = 0
for i in range (len (mensaje) - 1, i, -1):
if mensaje[i] in ('!', '°'):
cier_exclam += 1
elif mensaje[i] in ('?', 'Ņ'):
cier_interr += 1
elif mensaje[i].isalpha():
break
exclam = max (abre_exclam, cier_exclam)
interr = max (abre_interr, cier_interr)
if exclam or interr:
mensaje = mensaje.strip ('°Ņ?!')
mensaje = '°' * exclam + 'Ņ' * interr + mensaje + '?' * interr + \
'!' * exclam
else:
if mensaje[-1].isalnum():
mensaje = mensaje + '.' # AŮadimos un punto final
# Enviamos el mensaje a los de la localidad (menos al personaje emisor)
testigos = archivero.evaluaPropiedad (localidad,
'lista_pers').difference ([personaje])
if testigos:
texto = archivero.evaluaPropiedad (personaje, 'titulo') + ' '
if exclam:
if interr:
texto += random.choice (('pregunta a gritos',
'pregunta exclamando'))
else:
texto += random.choice (('exclama', 'grita'))
elif interr:
texto += 'pregunta'
else:
texto += 'dice'
texto += ': ' + mensaje
mensajero.enviaMensaje (testigos, texto)
if exclam:
return 'Gritas: ' + mensaje
if interr:
return 'Preguntas: ' + mensaje
return 'Dices: ' + mensaje
def dejar (personaje, localidad, objeto):
contenido = archivero.evaluaPropiedad (personaje, 'contenido')
objeto = buscaNombre (objeto, contenido)
if not objeto:
return 'No tienes eso.'
# El personaje deja el objeto en cuestiůn
archivero.escribePropiedad (personaje, 'contenido', 1,
contenido.difference ([objeto]))
archivero.escribePropiedad (localidad, 'lista_objs', 1,
archivero.evaluaPropiedad (localidad, 'lista_objs').union ([objeto]))
# Advertimos a los testigos de esta acciůn
testigos = archivero.evaluaPropiedad (localidad, 'lista_pers').difference (
[personaje])
if testigos:
mensajero.enviaMensaje (testigos, archivero.evaluaPropiedad (personaje, \
'titulo') + ' deja ' + escriba.un_ (objeto) + '.')
return 'Dejas ' + escriba.el_ (objeto) + '.'
def empujar (personaje, localidad, objeto):
pers = archivero.evaluaPropiedad (localidad, 'lista_pers')
inven = archivero.evaluaPropiedad (personaje, 'contenido')
objeto = buscaNombre (objeto, list (archivero.evaluaPropiedad (localidad,
'lista_objs')) + list (pers) + list (inven))
if not objeto:
return 'Parece que eso no estŠ por aquŪ.'
if objeto == personaje: # Se intenta empujar a sŪ mismo
return 'Nadie puede empujarse a sŪ mismo.'
if objeto in inven: # EstŠ en el inventario del personaje
return 'No tiene sentido empujar algo que estŠ en tu posesiůn.'
# Obtenemos la lista de testigos de la acciůn
testigos = pers.difference ([personaje, objeto])
# Vemos si el objeto tiene un tratamiento personalizado para la acciůn
mensaje = archivero.evaluaPropiedad (objeto, 'empujar')
if mensaje: # Lo tiene
# Advertimos a los testigos de esta acciůn
if testigos:
mensajero.enviaMensaje (testigos, archivero.evaluaPropiedad \
(personaje, 'titulo') + ' ' + mensaje[1] + mensaje[2])
# Advertimos (si corresponde) a los presentes en otra localidad
if len (mensaje) > 3:
mensajero.enviaMensaje (archivero.evaluaPropiedad (mensaje[3][0], \
'lista_pers'), mensaje[3][1])
return mensaje[0] + mensaje[2] # Advertimos al jugador
# Advertimos a los testigos de esta acciůn
if testigos:
mensaje = archivero.evaluaPropiedad (personaje, 'titulo') + ' empuja '
if objeto[0] != 'o': # Empuja a un personaje
mensaje += 'a ' + archivero.evaluaPropiedad (objeto, 'titulo')
else:
mensaje += escriba.el_ (objeto)
mensaje += '.'
mensajero.enviaMensaje (testigos, mensaje)
if objeto[0] != 'o': # Empuja a un personaje
mensajero.enviaMensaje ([objeto], archivero.evaluaPropiedad \
(personaje, 'titulo') + ' te empuja.')
mensaje = 'a ' + archivero.evaluaPropiedad (objeto, 'titulo')
else:
mensaje = escriba.el_ (objeto)
return 'Empujas ' + mensaje + '.'
def examinar (personaje, localidad, objeto):
pers = archivero.evaluaPropiedad (localidad, 'lista_pers')
objeto = buscaNombre (objeto, list (archivero.evaluaPropiedad (localidad, \
'lista_objs')) + list (archivero.evaluaPropiedad (personaje, 'contenido')) \
+ list (pers))
if not objeto:
return 'Parece que eso no estŠ por aquŪ.'
if objeto == personaje: # Se examina a sŪ mismo
return 'Eres tal y como recordabas.'
if objeto in pers: # Examina otro personaje
contenido = archivero.evaluaPropiedad (objeto, 'contenido')
if contenido: # Dicho personaje lleva algķn objeto
return 'Lleva ' + escriba.listaEntidades (set (contenido))
return archivero.evaluaPropiedad (objeto, 'descripcion')
def gesticular (personaje, localidad, tipo):
# Advertimos a los presentes de la sonrisa
testigos = archivero.evaluaPropiedad (localidad,
'lista_pers').difference ([personaje])
if testigos:
if tipo == 0:
mensaje = ' sonrŪe.'
elif tipo == 1:
mensaje = random.choice ([' se parte de risa.', \
' se rŪe a carcajada limpia.', ' se rŪe a carcajadas.'])
elif tipo == 2:
mensaje = ' se rŪe.'
else:
mensaje = ' llora.'
mensajero.enviaMensaje (testigos, archivero.evaluaPropiedad (personaje, \
'titulo') + mensaje)
if tipo == 0:
mensaje = 'SonrŪes.'
elif tipo == 1:
mensaje = 'Te rŪes a carcajadas.'
elif tipo == 2:
mensaje = 'Te rŪes.'
else:
mensaje = 'Lloras.'
return mensaje
def llegar (personaje, origen, destino):
# Advertimos a los presentes de la llegada de este personaje
testigos = archivero.evaluaPropiedad (destino, 'lista_pers')
if testigos:
salidas = []
for s in ('loc_norte', 'loc_sur', 'loc_este', 'loc_oeste', 'loc_arriba', \
'loc_abajo'):
salida = archivero.evaluaPropiedad (destino, s)
if salida == origen: # Salida a la localidad de origen
salida = s
break
elif type (salida) == str and salida[:4] == 'loc_':
salidas.append (s)
else:
if salidas: # La localidad de destino no tiene salida hacia la de origen
salida = random.choice (salidas) # Nos inventamos una al azar
else: # La localidad de destino no tiene salidas
salida = ''
mensaje = archivero.evaluaPropiedad (personaje, 'titulo') + ' llega'
if salida:
mensaje += ' desde ' + escriba.listaSalida (salida)
mensaje += '.'
mensajero.enviaMensaje (testigos, mensaje)
# Colocamos al personaje en la nueva localidad (la de destino)
archivero.escribePropiedad (destino, 'lista_pers', 1,
testigos.union ([personaje]))
archivero.escribePropiedad (personaje, 'localidad', 1, destino)
def mirar (personaje, localidad, avisar):
mensaje = archivero.evaluaPropiedad (localidad, 'descripcion')
if type (mensaje) != str:
mensaje = ''
print 'La propiedad "descripcion" de "' + localidad + \
'" no es una cadena'
# Describimos las demŠs entidades de aquŪ (si las hay y se puede)
lista = archivero.evaluaPropiedad (localidad, 'lista_objs').difference \
(archivero.evaluaPropiedad (localidad, 'no_listar'))
if lista: # Hay objetos que listar
mensaje += '\r\nAquŪ hay ' + escriba.listaEntidades (set (lista))
lista = archivero.evaluaPropiedad (localidad, 'lista_pers').difference \
([personaje])
if lista: # Hay personajes que listar
mensaje += '\r\nAquŪ estŠ ' + escriba.listaEntidades (set (lista), True)
# Avisamos si corresponde a los testigos de esta acciůn
if avisar:
mensajero.enviaMensaje (lista, archivero.evaluaPropiedad (personaje, \
'titulo') + ' mira a su alrededor.')
return mensaje
def partir (personaje, localidad, salida):
# Advertimos a los presentes de la partida de este personaje
testigos = archivero.evaluaPropiedad (localidad,
'lista_pers').difference ([personaje])
if testigos:
if salida[0] != 'l': # El personaje se va del MUD
salidas = []
for s in ('loc_norte', 'loc_sur', 'loc_este', 'loc_oeste', 'loc_arriba', \
'loc_abajo'):
salida = archivero.evaluaPropiedad (localidad, s)
if type (salida) == str and salida[:4] == 'loc_':
salidas.append (s)
if salidas: # La localidad tiene alguna salida
salida = random.choice (salidas) # Nos inventamos una al azar
else: # La localidad no tiene salidas
salida = ''
mensaje = archivero.evaluaPropiedad (personaje, 'titulo') + ' se va'
if salida:
mensaje += ' hacia ' + escriba.listaSalida (salida)
mensaje += '.'
mensajero.enviaMensaje (testigos, mensaje)
# Quitamos al personaje de la antigua localidad
archivero.escribePropiedad (localidad, 'lista_pers', 1, testigos)
# Da la bienvenida a un personaje que acaba de entrar al juego
def recibir (personaje):
mensajero.enviaMensaje ([personaje], '\r\nHola ' + archivero.evaluaPropiedad \
(personaje, 'titulo') + ', bienvenid' + escriba.o (personaje) + \
' a MUnDo CAAD: Aventura sin fin\r\n', False, False)
def tirar (personaje, localidad, objeto):
pers = archivero.evaluaPropiedad (localidad, 'lista_pers')
inven = archivero.evaluaPropiedad (personaje, 'contenido')
lista = list (archivero.evaluaPropiedad (localidad, 'lista_objs')) + \
list (pers) + list (inven)
objeto = buscaNombre (objeto, lista)
if not objeto:
return 'Parece que eso no estŠ por aquŪ.'
if objeto == personaje: # Intenta tirar de sŪ mismo
return 'Nadie puede tirar de sŪ mismo.'
if objeto in inven: # EstŠ en el inventario del personaje
return 'No tiene sentido tirar de algo que estŠ en tu posesiůn.'
# Obtenemos la lista de testigos de la acciůn
testigos = pers.difference ([personaje, objeto])
# Vemos si el objeto tiene un tratamiento personalizado para la acciůn
mensaje = archivero.evaluaPropiedad (objeto, 'tirar')
if mensaje: # Lo tiene
# Advertimos a los testigos de esta acciůn
if testigos:
mensajero.enviaMensaje (testigos, archivero.evaluaPropiedad \
(personaje, 'titulo') + ' ' + mensaje[1] + mensaje[2])
# Advertimos (si corresponde) a los presentes en otra localidad
if len (mensaje) > 3:
mensajero.enviaMensaje (archivero.evaluaPropiedad (mensaje[3][0], \
'lista_pers'), mensaje[3][1])
return mensaje[0] + mensaje[2] # Advertimos al jugador
# Advertimos a los testigos de esta acciůn
if testigos:
mensaje = archivero.evaluaPropiedad (personaje, 'titulo') + ' tira ' + \
escriba.del_ (objeto) + '.'
mensajero.enviaMensaje (testigos, mensaje)
if objeto[0] != 'o': # Tira de un personaje
mensajero.enviaMensaje ([objeto], archivero.evaluaPropiedad \
(personaje, 'titulo') + ' tira de ti.')
return 'Tiras ' + escriba.del_ (objeto) + '.'