/*
* (c) 2000-2009 Carlos G�mez Rodr�guez, todos los derechos reservados / all rights reserved.
* Licencia en license/bsd.txt / License in license/bsd.txt
*/
package eu.irreality.age;
//package AetheriaAWT;
import java.util.*;
import java.io.*;
import eu.irreality.age.debug.Debug;
import eu.irreality.age.debug.ExceptionPrinter;
import eu.irreality.age.scripting.ScriptException;
import eu.irreality.age.util.Conversions;
public class Item extends Entity implements Descriptible , SupportingCode , Nameable, UniqueNamed
{
//////////////////////
//INSTANCE VARIABLES//
//////////////////////
/**Tipo.*/
/*00*/ private String itemType;
/**ID del objeto.*/
/*01*/ private int idnumber;
/**Hereda de.*/
/*02*/ private int inheritsFrom;
/*03*/ // inherited protected int state;
// inherited protected long timeunitsleft;
/**Nombre sint�tico del objeto.*/
/*04*/ protected String title;
/**Es instancia de.*/
/*05*/ private String isInstanceOf;
/**Lista din�mica de descripciones.*/
/*10*/ protected Description[] descriptionList;
/**Lista din�mica de nombres en singular. (espada, espada oxidada... son la misma espada con varios estados)*/
/*11*/ protected Description[] singNames;
/**Lista din�mica de nombres en plural.*/
/*12*/ protected Description[] plurNames;
/**G�nero.*/
/*13*/ protected boolean gender; //true=masculino
/**Responder a... (comandos)*/
/*14*/ protected List respondToSing = new ArrayList();
/*15*/ protected List respondToPlur = new ArrayList();
/**Volumen.*/
/*17*/ protected int volume;
/**Peso.*/
/*16*/ protected int weight;
/**Inventario de contenedor.*/
/*20*/ protected String inventoryString;
protected Inventory inventory;
/**Inventario de item compuesto.*/
protected String partsInventoryString;
protected Inventory partsInventory;
/**Lista din�mica de personajes. �necesario?*/
/*22*/ protected Vector characterRefs;
/*21*/ protected Vector mobRefs;
/**Descripciones de subcosas del objeto.*/
/*30*/ protected String extraDescriptions; //OLD
protected List extraDescriptionArrays = new ArrayList(); /*List of Description Arrays*/
protected List extraDescriptionNameArrays = new ArrayList(); /*List of String Arrays*/
/**Restricciones de acceso y otras.*/
/*31*/ protected Vector onlyRestrictions;
/**Lista din�mica de descripciones de apertura.*/
/*32*/ protected Description[] openDescriptionList = null;
/**Lista din�mica de descripciones de cierre.*/
/*33*/ protected Description[] closeDescriptionList = null;
/**Lista din�mica de descripciones de apertura con llave.*/
/*34*/ protected Description[] unlockDescriptionList = null;
/**Lista din�mica de descripciones de cierre con llave.*/
/*35*/ protected Description[] lockDescriptionList = null;
/**Lista din�mica de llaves que lo abren, si el item es abrible/cerrable.*/
/**Ojo: la llave que abre un item tiene que ser anterior en n�mero...*/
/*36*/ protected Inventory keys;
//Bitvectors
/*40*/ protected boolean enabled;
/*41*/ protected boolean isVirtual;
/*42*/ protected boolean canGet;
/**C�digo en Ensamblador Virtual Aetheria (EVA)*/
/*80*/ protected ObjectCode itsCode;
/**Note: having these attributes set to true is a sufficient condition (not necessary)
* for the item to be openable/closeable/lockable/unlockable.*/
private boolean openable=false;
private boolean closeable=false;
private boolean lockable=false;
private boolean unlockable=false;
//emulador de numeros aleatorios
private Random aleat;
//mundo
private World mundo;
protected boolean properName = false; //marks names by proper as default
//esto se ir� rellenando al hacer addItem().
protected transient List rooms = new ArrayList(); //habitaciones donde est� el item.
protected transient List mobiles = new ArrayList(); //mobiles donde est� el item.
protected transient List containers = new ArrayList(); //contenedores donde est� el item.
public void addRoomReference ( Room r )
{
rooms.add(r);
}
public void removeRoomReference ( Room r )
{
rooms.remove(r);
}
public List getRoomReferences ( )
{
return rooms;
}
public void addMobileReference ( Mobile m )
{
mobiles.add(m);
}
public void removeMobileReference ( Mobile m )
{
mobiles.remove(m);
}
public List getMobileReferences ( )
{
return mobiles;
}
public void addContainerReference ( Item c )
{
containers.add(c);
}
public void removeContainerReference ( Item c )
{
containers.remove(c);
}
public List getContainerReferences ( )
{
return containers;
}
public boolean isGettable()
{
return canGet;
}
public void setGettable ( boolean gettable )
{
canGet = gettable;
}
public Item createNewInstance ( World mundo , boolean cloneContents , boolean cloneParts )
{
return createNewInstance ( mundo , cloneContents , cloneParts, null );
}
//crea un nuevo Item que hereda de �ste y lo a�ade al mundo
public Item createNewInstance( World mundo , boolean cloneContents , boolean cloneParts , String uniqueName )
{
Item it = (Item) this.clone();
this.mundo=mundo;
it.inheritsFrom = 0;
if ( this.isInstanceOf == null || StringMethods.isStringOfZeroes ( this.isInstanceOf ) )
{
it.isInstanceOf = title;
Debug.println("1) instanceOf set to " + title);
}
else
{
it.isInstanceOf = this.isInstanceOf;
Debug.println("2) instanceOf set to " + this.isInstanceOf);
}
if ( cloneContents && it.inventory != null )
{
//poner inventario de copias
it.inventory = it.inventory.cloneCopyingItems(mundo,cloneContents,cloneParts);
}
if ( cloneParts && it.inventory != null )
{
it.partsInventory = it.partsInventory.cloneCopyingItems(mundo,cloneContents,cloneParts);
}
if ( uniqueName == null ) it.title = mundo.generateUnusedUniqueName(this.getUniqueName());
else it.title = uniqueName;
mundo.addItemAssigningID ( it );
return it;
}
public Object clone( )
{
//do it!
Item it = new Item();
copyItemFieldsTo(it);
return it;
}
/**
* Returns true if this item is a container and contains the specified item.
* @param it
* @return
*/
public boolean contains ( Item it )
{
if ( !isContainer() ) return false;
else return getContents().contains(it);
}
//notaci�n un poco inconsistente con la de Entity::copyEntityFields; pero bueno
public void copyItemFieldsTo ( Item it )
{
it.copyEntityFields(this); //estados, propiedades, etc.
//Debug.println("Random from SOURCE item: " + getRandom());
it.aleat = getRandom();
it.canGet=canGet;
it.enabled = enabled;
it.extraDescriptions = extraDescriptions;
it.gender = gender;
it.idnumber = idnumber; //will have to change the ID later!
//it.inheritsFrom = 0; //creates an identical (strong inherit) item -> No weak inherit
//nay, identical copy
it.inheritsFrom = inheritsFrom;
if ( inventory != null )
it.inventory = (Inventory) inventory.clone();
else it.inventory = null;
it.inventoryString = inventoryString;
//it.isInstanceOf = idnumber; //creates an identical (strong inherit) item
//nay, identical copy
it.isInstanceOf = isInstanceOf;
it.isVirtual = isVirtual;
it.itemType = itemType;
if ( itsCode != null )
it.itsCode = //itsCode; //code is unmodifiable (shallow copy)
itsCode.cloneIfNecessary();
else
it.itsCode = null;
if ( keys != null )
it.keys = (Inventory) keys.clone();
else it.keys = null;
if ( partsInventory != null )
it.partsInventory = (Inventory) partsInventory.clone();
else
it.partsInventory = null;
it.partsInventoryString = partsInventoryString;
it.respondToPlur = respondToPlur;
it.respondToSing = respondToSing;
it.title = title;
it.volume = volume;
it.weight = weight;
it.properName = properName;
if ( closeDescriptionList != null )
{
it.closeDescriptionList = new Description[closeDescriptionList.length];
for ( int i = 0 ; i < it.closeDescriptionList.length ; i++ )
{
it.closeDescriptionList[i] = (Description) closeDescriptionList[i].clone();
}
}
it.descriptionList = new Description[descriptionList.length];
for ( int i = 0 ; i < it.descriptionList.length ; i++ )
{
it.descriptionList[i] = (Description) descriptionList[i].clone();
}
if ( lockDescriptionList != null )
{
it.lockDescriptionList = new Description[lockDescriptionList.length];
for ( int i = 0 ; i < it.lockDescriptionList.length ; i++ )
{
it.openDescriptionList[i] = (Description) openDescriptionList[i].clone();
}
}
if ( openDescriptionList != null )
{
it.openDescriptionList = new Description[openDescriptionList.length];
for ( int i = 0 ; i < it.lockDescriptionList.length ; i++ )
{
it.unlockDescriptionList[i] = (Description) unlockDescriptionList[i].clone();
}
}
if ( unlockDescriptionList != null )
{
it.unlockDescriptionList = new Description[unlockDescriptionList.length];
for ( int i = 0 ; i < it.lockDescriptionList.length ; i++ )
{
it.lockDescriptionList[i] = (Description) lockDescriptionList[i].clone();
}
}
it.singNames = new Description[singNames.length];
for ( int i = 0 ; i < it.singNames.length ; i++ )
{
it.singNames[i] = (Description) singNames[i].clone();
}
it.plurNames = new Description[plurNames.length];
for ( int i = 0 ; i < it.plurNames.length ; i++ )
{
it.plurNames[i] = (Description) plurNames[i].clone();
}
//mob refs and only restrictions are obsolete, do not copy
//shallow!
it.extraDescriptionArrays = extraDescriptionArrays;
it.extraDescriptionNameArrays = extraDescriptionNameArrays;
}
///////////
//METHODS//
///////////
public Item ( )
{
}
/**
* Este constructor solo llama a constructItem, que es el constructor de verdad. Esta dualidad se debe a las llamadas recursivas que debe hacer constructRoom para soportar herencia dinamica (items que copian datos de otros)
*
*/
public Item ( World mundo , String itemfile ) throws IOException , FileNotFoundException
{
constructItem ( mundo , itemfile , true , "none" );
}
public Item ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException
{
constructItem ( mundo , n , true , "none" );
}
/**
* Constructor para ser llamado desde fuera, construye todas las subclases de Item seg�n el fichero
*
*/
public static Item getInstance ( World mundo , String itemfile ) throws FileNotFoundException, IOException
{
String linea;
String id_linea;
FileInputStream fp = new FileInputStream ( itemfile );
BufferedReader filein = new BufferedReader ( Utility.getBestInputStreamReader ( fp ) );
//leer el tipo de item
String itemtype = "none";
for ( int line = 1 ; line < 100 ; line++ )
{
linea = filein.readLine();
id_linea = StringMethods.getTok( linea , 1 , ' ' );
linea = StringMethods.getToks( linea , 2 , StringMethods.numToks( linea , ' ' ) , ' ' );
try
{
if ( id_linea != null && Integer.valueOf(id_linea).intValue() == 0 )
itemtype = linea;
}
catch ( NumberFormatException ex )
{
//no pasa nada, estaremos en una parte con codigo, etc.
}
}
//crear el objeto
Item ourNewItem;
if ( itemtype.equalsIgnoreCase("weapon") )
{
ourNewItem = new Weapon ( mundo , itemfile );
//llama a ourNewItem.constructItem ( mundo , itemfile , true , "weapon" );
}
else if ( itemtype.equalsIgnoreCase("wearable") )
{
ourNewItem = new Wearable ( mundo , itemfile );
}
else
{
ourNewItem = new Item ( mundo , itemfile );
//llama a ourNewItem.constructItem ( mundo , itemfile , true , "none" );
}
return ourNewItem;
}
public static Item getInstance ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException
{
if ( ! ( n instanceof org.w3c.dom.Element ) )
{
throw ( new XMLtoWorldException("Item node not Element") );
}
//{n is an Element}
org.w3c.dom.Element e = (org.w3c.dom.Element)n;
Item ourNewItem;
if ( !e.hasAttribute("type") )
{
ourNewItem = new Item ( mundo , n );
}
else if ( e.getAttribute("type").equalsIgnoreCase("weapon") )
{
ourNewItem = new Weapon ( mundo , n );
}
else if ( e.getAttribute("type").equalsIgnoreCase("wearable") )
{
ourNewItem = new Wearable ( mundo , n );
}
else
{
ourNewItem = new Item ( mundo , n );
}
return ourNewItem;
}
/**
* El pedazo de constructor que lee un item de un fichero.
*
*/
public void constructItem ( World mundo , String itemfile , boolean allowInheritance , String itemtype ) throws IOException, FileNotFoundException
{
this.mundo=mundo;
String linea;
String id_linea;
FileInputStream fp = new FileInputStream ( itemfile );
BufferedReader filein = new BufferedReader ( Utility.getBestInputStreamReader ( fp ) );
itemType = itemtype;
for ( int line = 1 ; line < 100 ; line++ )
{
linea = filein.readLine();
id_linea = StringMethods.getTok( linea , 1 , ' ' );
linea = StringMethods.getToks( linea , 2 , StringMethods.numToks( linea , ' ' ) , ' ' );
if ( id_linea != null ) switch ( Integer.valueOf(id_linea).intValue() )
{
// case 0:
// if ( linea.equalsIgnoreCase("weapon") )
// isweapon = true;
// break;
case 1:
idnumber = Integer.valueOf(linea).intValue(); break;
case 2:
inheritsFrom = Integer.valueOf(linea).intValue();
if ( inheritsFrom < idnumber && allowInheritance ) /*el item del que heredamos debe tener ID menor*/
{
/*construimos segun constructor de la habitacion de que heredamos*/
constructItem ( mundo, Utility.itemFile(mundo,inheritsFrom) , true , itemtype );
/*overrideamos lo que tengamos que overridear*/
constructItem ( mundo, itemfile , false , itemtype );
return;
}
break;
case 3:
//state = Integer.valueOf(linea).intValue(); break;
setNewState(Integer.valueOf(linea).intValue()); break;
case 4:
title = linea; break;
case 5:
/*la herencia fuerte se hace exactamente igual que la d�bil, no pueden aparecer las dos (se ignorar�a la 2a)*/
isInstanceOf = String.valueOf(Integer.valueOf(linea).intValue());
if ( Integer.valueOf(isInstanceOf).intValue() < Integer.valueOf(idnumber).intValue() && allowInheritance ) /*el item del que heredamos debe tener ID menor*/
{
/*construimos segun constructor de la habitacion de que heredamos*/
constructItem ( mundo, Utility.itemFile(mundo,Integer.valueOf(isInstanceOf).intValue()) , true , itemtype );
/*overrideamos lo que tengamos que overridear*/
constructItem ( mundo, itemfile , false , itemtype );
return;
}
break;
case 10:
//item description list line
{
descriptionList=Utility.loadDescriptionListFromString( linea );
break;
}
case 11:
//singular names line
{
singNames = Utility.loadDescriptionListFromString( linea ); break;
}
case 12:
//plural names line
{
plurNames = Utility.loadDescriptionListFromString( linea ); break;
}
case 13:
//gender line
{
int temp = Integer.valueOf(linea).intValue();
if ( temp == 0 ) gender = false;
else gender = true;
break;
}
case 14:
//respondToSing
{
respondToSing = Conversions.getReferenceNameList(linea); break;
}
case 15:
//respondToPlur
{
respondToPlur = Conversions.getReferenceNameList(linea); break;
}
case 16:
//weight line
{
weight = Integer.valueOf(linea).intValue(); break;
}
case 17:
//gender line
{
volume = Integer.valueOf(linea).intValue(); break;
}
case 20:
//container's inventory line
{
inventoryString = linea; break;
//la carga del inventario est� diferida, pues puede contener objetos
//de n�mero m�s alto que el actual, y que por lo tanto a�n no est�n
//cargados en memoria cuando se carga �ste.
}
case 32:
{
//description of action of opening item
openDescriptionList = Utility.loadDescriptionListFromString( linea );
break;
}
case 33:
{
//description of action of closing item
closeDescriptionList = Utility.loadDescriptionListFromString( linea );
break;
}
case 34:
{
//description of action of unlocking item
unlockDescriptionList = Utility.loadDescriptionListFromString( linea );
break;
}
case 35:
{
//description of action of locking item
lockDescriptionList = Utility.loadDescriptionListFromString( linea );
break;
}
case 36:
{
//list of keys which may unlock lockable/unlockable items
int nkeys = StringMethods.numToks(linea,'&');
keys = new Inventory ( 10000000 , 1000000 );
for ( int i = 1 ; i <= nkeys ; i++ )
{
//primero, comprobar que la ID es menor que la del item actual
int key_id = Integer.valueOf( StringMethods.getTok(linea,i,'&') ).intValue();
if ( key_id > idnumber )
{
mundo.write("Warning! La ID de una llave no puede ser mayor que la del objeto que abre (" + key_id + " > " + idnumber + ")\n");
}
else
{
try
{
keys.addItem ( mundo.getItem( key_id ) );
}
catch (Exception exc)
{
mundo.write("Excepci�n absurda (llave pesada)" + exc);
}
}
}
break;
}
case 80:
//begin EVA code line
{
String EVACodeString = linea;
boolean terminamos = false;
while ( !terminamos )
{
linea = filein.readLine();
id_linea = StringMethods.getTok(linea,1,' ');
int intval;
try
{
intval = Integer.valueOf(id_linea).intValue();
}
catch ( NumberFormatException e )
{
intval=0;
}
if ( intval == 81 ) terminamos=true; //EVA code termination line
else
{
EVACodeString += "\n";
EVACodeString += linea;
}
}
itsCode = new ObjectCode ( EVACodeString , "EVA" , mundo );
break;
} //end case 80
case 84:
//begin BeanShell code line
{
String bshCodeString = linea;
boolean terminamos = false;
while ( !terminamos )
{
linea = filein.readLine();
id_linea = StringMethods.getTok(linea,1,' ');
int intval;
try
{
intval = Integer.valueOf(id_linea).intValue();
}
catch ( NumberFormatException e )
{
intval=0;
}
if ( intval == 85 ) terminamos=true; //EVA code termination line
else
{
bshCodeString += "\n";
bshCodeString += linea;
}
}
itsCode = new ObjectCode ( bshCodeString , "BeanShell" , mundo );
break;
} //end case 84
} //end case switch
} //end for
if ( itemtype.equalsIgnoreCase("weapon") )
{
((Weapon)this).readWeaponSpecifics ( mundo , itemfile );
}
/*
else if ( itemtype.equalsIgnoreCase("wearable") )
{
((Wearable)this).readWearableSpecifics ( mundo , itemfile );
}
*/
//poner bien la id
if ( getID() < 10000000 )
idnumber += 30000000; //prefijo de objeto
}
public void constructItem ( World mundo , org.w3c.dom.Node n , boolean allowInheritance , String itemtype ) throws XMLtoWorldException
{
if ( ! ( n instanceof org.w3c.dom.Element ) )
{
throw ( new XMLtoWorldException ( "Item node not Element" ) );
}
//{n is an Element}
org.w3c.dom.Element e = (org.w3c.dom.Element) n;
//type
itemType = itemtype;
//world
this.mundo=mundo;
//default values
canGet=true; isVirtual=false; enabled=true;
//attribs
//weak inheritance?
if ( e.hasAttribute("extends") && !e.getAttribute("extends").equals("0") && !e.getAttribute("extends").equals("null") && allowInheritance )
{
//item must extend from existing item.
//clonamos ese item y overrideamos lo overrideable
//(n�tese que la ID del item extendido ha de ser menor).
//por eso los associated nodes de los items quedan guardados [por ref] en el World hasta que
//haya concluido la construccion del mundo
//1. overrideamos el super-item usando su associated node para construirlo
constructItem ( mundo , mundo.getItemNode( e.getAttribute("extends") ) , true , itemtype );
//2. overrideamos lo que debamos overridear
constructItem ( mundo , n , false , itemtype );
return;
}
//strong inheritance?
if ( e.hasAttribute("clones") && !e.getAttribute("clones").equals("0") && !e.getAttribute("clones").equals("null") && allowInheritance )
{
//funciona igual que la weak inheritance a este nivel.
//no deberian aparecer los dos; pero si asi fuera esta herencia (la fuerte) tendria precedencia.
//1. overrideamos el super-item usando su associated node para construirlo
//System.err.println("Building item from node " + e.getAttribute("name"));
//new Throwable().printStackTrace();
constructItem ( mundo , mundo.getItemNode( e.getAttribute("clones") ) , true , itemtype );
Debug.println("Overridden item gender is " + gender);
//2. overrideamos lo que debamos overridear
//no overriding in strong inheritance!
//removed the following line 2011-05-01.
//constructItem ( mundo , n , false , itemtype );
//we now only override the isInstanceOf field and the unique name (the latter added as fix, 2013-02-07)
isInstanceOf = e.getAttribute("clones");
//the unique name still has to be unique
if ( !e.hasAttribute("name") )
throw ( new XMLtoWorldException ( "Item node lacks attribute name" ) );
title = e.getAttribute("name");
return;
}
//Debug.println("IID = " + e.getAttribute("id") + ", " + allowInheritance);
//mandatory XML-attribs exceptions
//if ( !e.hasAttribute("id") )
// throw ( new XMLtoWorldException ( "Item node lacks attribute id" ) );
if ( !e.hasAttribute("name") )
throw ( new XMLtoWorldException ( "Item node lacks attribute name" ) );
if ( !e.hasAttribute("volume") && allowInheritance )
throw ( new XMLtoWorldException ( "Item node lacks attribute volume, id=" + e.getAttribute("id") ) );
if ( !e.hasAttribute("weight") && allowInheritance )
throw ( new XMLtoWorldException ( "Item node lacks attribute weight, id=" + e.getAttribute("id") ) );
if ( !e.hasAttribute("gender") && allowInheritance )
throw ( new XMLtoWorldException ( "Item node lacks attribute gender, id=" + e.getAttribute("id") ) );
//mandatory XML-attribs parsing
try
{
//id no longer mandatory
if ( e.hasAttribute("id") )
idnumber = Integer.valueOf ( e.getAttribute("id") ).intValue();
}
catch ( NumberFormatException nfe )
{
throw ( new XMLtoWorldException ( "Bad number format at attribute id in item node" ) );
}
title = e.getAttribute("name");
if ( ! gender ) //si es true es porque lo hemos heredado true (!=default)
gender = Boolean.valueOf ( e.getAttribute("gender") ).booleanValue();
Debug.println("Gender has been set to " + gender + " for " + title);
try
{
weight = Integer.valueOf ( e.getAttribute("weight") ).intValue();
}
catch ( NumberFormatException nfe )
{
if ( allowInheritance )
throw ( new XMLtoWorldException ( "Bad number format at attribute weight in item node" ) );
}
try
{
volume = Integer.valueOf ( e.getAttribute("volume") ).intValue();
}
catch ( NumberFormatException nfe )
{
if ( allowInheritance )
throw ( new XMLtoWorldException ( "Bad number format at attribute volume in item node" ) );
}
//non-mandatory attribs
if ( e.hasAttribute("enabled") )
{
enabled = Boolean.valueOf ( e.getAttribute("enabled") ).booleanValue();
}
if ( e.hasAttribute("isVirtual") )
{
isVirtual = Boolean.valueOf ( e.getAttribute("isVirtual") ).booleanValue();
}
if ( e.hasAttribute("canGet") )
{
canGet = Boolean.valueOf ( e.getAttribute("canGet") ).booleanValue();
}
if ( e.hasAttribute("properName") )
{
properName = Boolean.valueOf ( e.getAttribute("properName") ).booleanValue();
}
//Entity parsing
readPropListFromXML ( mundo , n );
//[old] de momento no leeremos openable,closeable,lockable,unlockable:
//depender�n de si las description lists son o no nulas
//[new 2011-11-26] leemos estos cuatro atributos si est�n.
//el objeto ser� abrible/cerrable/etc. si (1) est� el atributo, OR (2)
//la lista correspondiente no es nula.
if ( e.hasAttribute("openable") )
{
openable = Boolean.valueOf ( e.getAttribute("openable") ).booleanValue();
}
if ( e.hasAttribute("closeable") )
{
closeable = Boolean.valueOf ( e.getAttribute("closeable") ).booleanValue();
}
if ( e.hasAttribute("lockable") )
{
lockable = Boolean.valueOf ( e.getAttribute("lockable") ).booleanValue();
}
if ( e.hasAttribute("unlockable") )
{
unlockable = Boolean.valueOf ( e.getAttribute("unlockable") ).booleanValue();
}
//description list (same as in Path)
//WE CAN REWRITE ALL THESE USING "Utility.loadDescriptionListFromXML()" AND MAKE
//THEM SHORTER. DO IT IF NEEDIN' TO MODIFY.
org.w3c.dom.NodeList descrListNodes = e.getElementsByTagName( "DescriptionList" );
if ( descrListNodes.getLength() > 0 )
{
org.w3c.dom.Element descrListNode = (org.w3c.dom.Element) descrListNodes.item(0);
org.w3c.dom.NodeList descrNodes = descrListNode.getElementsByTagName ( "Description" );
descriptionList = new Description[descrNodes.getLength()];
for ( int i = 0 ; i < descrNodes.getLength() ; i++ )
{
org.w3c.dom.Element descrNode = (org.w3c.dom.Element) descrNodes.item(i);
try
{
descriptionList[i] = new Description(mundo,descrNode);
}
catch ( XMLtoWorldException xe )
{
throw ( new XMLtoWorldException ( "Error at item description: " + xe.getMessage() ) );
}
}
}
//singNames (same)
descrListNodes = e.getElementsByTagName( "SingularNames" );
if ( descrListNodes.getLength() > 0 )
{
org.w3c.dom.Element descrListNode = (org.w3c.dom.Element) descrListNodes.item(0);
org.w3c.dom.NodeList descrNodes = descrListNode.getElementsByTagName ( "Description" );
singNames = new Description[descrNodes.getLength()];
for ( int i = 0 ; i < descrNodes.getLength() ; i++ )
{
org.w3c.dom.Element descrNode = (org.w3c.dom.Element) descrNodes.item(i);
try
{
singNames[i] = new Description(mundo,descrNode);
}
catch ( XMLtoWorldException xe )
{
throw ( new XMLtoWorldException ( "Error at item description: " + xe.getMessage() ) );
}
}
}
//plurNames (same)
descrListNodes = e.getElementsByTagName( "PluralNames" );
if ( descrListNodes.getLength() > 0 )
{
org.w3c.dom.Element descrListNode = (org.w3c.dom.Element) descrListNodes.item(0);
org.w3c.dom.NodeList descrNodes = descrListNode.getElementsByTagName ( "Description" );
plurNames = new Description[descrNodes.getLength()];
for ( int i = 0 ; i < descrNodes.getLength() ; i++ )
{
org.w3c.dom.Element descrNode = (org.w3c.dom.Element) descrNodes.item(i);
try
{
plurNames[i] = new Description(mundo,descrNode);
}
catch ( XMLtoWorldException xe )
{
throw ( new XMLtoWorldException ( "Error at item description: " + xe.getMessage() ) );
}
}
}
//singular reference names (respondToSing), XML format is:
//<SingularReferenceNames><Name>nombre1</Name><Name>nombre2</Name>...</SingularReferenceNames>
//while internal format is
//nombre1$nombre2
//WE CAN REWRITE ALL THESE USING "Utility.loadNameListFromXML()" AND MAKE
//THEM SHORTER. DO IT IF NEEDIN' TO MODIFY.
/*
* legacy removed 2014-01-07
*
org.w3c.dom.NodeList singRefNamesNodes = e.getElementsByTagName("SingularReferenceNames" );
if ( singRefNamesNodes.getLength() > 0 )
{
org.w3c.dom.Element singRefNamesNode = (org.w3c.dom.Element)singRefNamesNodes.item(0);
org.w3c.dom.NodeList nameNodes = singRefNamesNode.getElementsByTagName("Name");
//init respondToSing
respondToSing = "";
for ( int i = 0 ; i < nameNodes.getLength() ; i++ )
{
//get this name node
org.w3c.dom.Element nameNode = (org.w3c.dom.Element) nameNodes.item(i);
//get first text node in this name node -- WE ASSUME THERE IS ONE!!
org.w3c.dom.Node hijo = nameNode.getFirstChild();
while ( !( hijo instanceof org.w3c.dom.Text ) )
hijo = hijo.getNextSibling();
//{hijo is an org.w3c.dom.Text}
respondToSing += ( hijo.getNodeValue() );
if ( i < nameNodes.getLength()-1 ) //i.e. not last
respondToSing += "$";
}
}
*/
//singular reference names (respondToSing)
respondToSing = Utility.loadNameListFromXML ( mundo , e , "SingularReferenceNames" , true );
//plural reference names (respondToPlur) just same as singular reference names.
//System.err.println("respondToSing of item " + this + " initted to " + respondToSing);
//new Throwable().printStackTrace();
respondToPlur = Utility.loadNameListFromXML ( mundo , e , "PluralReferenceNames" , true );
//System.err.println("respondToPlur of item " + this + " initted to " + respondToPlur);
//new Throwable().printStackTrace();
//inventory:
//NO lo hacemos ahora: es una carga DIFERIDA. Repito: DIFERIDA.
//(para construir un inventory a partir de un Node estamos pidiendo que todos los items ya existan)
//como guardamos el Node en el World, ya haremos esta carga.
//keys inventory:
//tambi�n es una carga DIFERIDA.
//extra descriptions:
//XML format is:
//<ExtraDescriptionList> <ExtraDescription> <Name>cosa</Name> <Name>objeto</Name> la descripci�n de la cosa, tambi�n llamada objeto </ExtraDescription> <ExtraDescription> ... </ExtraDescription> </ExtraDescriptionList>
//internal representation is:
//cosa$objeto$la descripci�n de la cosa, tambi�n llamada objeto@[otra descripci�n]@...
//extraDescriptions = Utility.loadExtraDescriptionsFromXML ( e , "ExtraDescriptionList" , true );
List temp = Utility.loadExtraDescriptionsFromXML ( mundo , e , "ExtraDescriptionList" , true );
if ( temp == null || temp.size() < 2 )
{
extraDescriptionArrays = new ArrayList();
extraDescriptionNameArrays = new ArrayList();
}
else
{
extraDescriptionArrays = (List) temp.get(1);
extraDescriptionNameArrays = (List) temp.get(0);
}
//open, close, lock, unlock description lists.
//code written in the new format, i.e. using the Utility function
Description[] dl = Utility.loadDescriptionListFromXML ( mundo , e , "OpenDescriptionList" , true );
if ( dl != null )
openDescriptionList = dl; //if null, preserve inherited
dl = Utility.loadDescriptionListFromXML ( mundo , e , "CloseDescriptionList" , true );
if ( dl != null )
closeDescriptionList = dl;
dl = Utility.loadDescriptionListFromXML ( mundo , e , "LockDescriptionList" , true );
if ( dl != null )
lockDescriptionList = dl;
dl = Utility.loadDescriptionListFromXML ( mundo , e , "UnlockDescriptionList" , true );
if ( dl != null )
unlockDescriptionList = dl;
//then do:
// - World diferidas support (compile errors on this file)
org.w3c.dom.NodeList codeNodes = e.getElementsByTagName ( "Code" );
if ( codeNodes.getLength() > 0 )
{
try
{
itsCode = new ObjectCode ( mundo , codeNodes.item(0) );
}
catch ( XMLtoWorldException ex )
{
throw ( new XMLtoWorldException ( "Exception at Code node: " + ex.getMessage() ) );
}
}
//FINALLY... type-specifics!!
if ( itemtype.equalsIgnoreCase("weapon") )
{
((Weapon)this).readWeaponSpecifics ( mundo , e );
}
else if ( itemtype.equalsIgnoreCase("wearable") )
{
((Wearable)this).readWearableSpecifics ( mundo , e );
}
//poner bien la id
if ( getID() < 10000000 )
idnumber += 30000000; //prefijo de objeto
//from 2014-10-22, onInit() is not executed when loading states, see issue #310
if ( !mundo.comesFromLoadedState() )
{
//eventos onInit()
try
{
boolean ejecutado = execCode ( "onInit" ,
new Object[]
{
}
);
}
catch ( ScriptException te )
{
te.printStackTrace();
mundo.writeError("BeanShell error on initting item " + this + ": error was " + te);
mundo.writeError(ExceptionPrinter.getExceptionReport(te));
}
}
}
public int getID ( )
{
return idnumber;
}
/**
* @deprecated Use {@link #getUniqueName()} instead
*/
public String getTitle ( )
{
return getUniqueName();
}
public String getUniqueName ( )
{
return title;
}
public int getWeight()
{
return weight;
}
public int getTotalWeight ( )
{
int totalWeight = weight;
if ( inventory != null )
totalWeight += inventory.getWeight();
return totalWeight;
}
public int getVolume ( )
{
return volume;
}
public void setVolume ( int volume )
{
this.volume = volume;
}
public String getDescription ( long comparand )
{
String desString="";
for ( int i = 0 ; i < descriptionList.length ; i++ )
{
if ( descriptionList[i].matches(comparand) )
desString += descriptionList[i].getText();
}
if ( !isContainer() )
{
return desString;
}
else if ( inventory.isEmpty() ) //puede contener items; pero no. Est� vac�o.
{
//si la descripci�n est� construida con la conocida f�rmula "hay x" o "lleva x", cambiamos por "no hay nada" o "no lleva nada".
//si no, simplemente por "nada".
return StringMethods.textualSubstitution ( StringMethods.textualSubstitution ( StringMethods.textualSubstitution ( desString , "lleva %INVENTORY" , "no lleva nada." ) , "hay %INVENTORY" , "no hay nada." ) , "%INVENTORY" , mundo.getMessages().getMessage("nothing")+"." );
}
else
{
return StringMethods.textualSubstitution ( desString , "%INVENTORY" , inventory.toString(mundo) );
}
}
//in order for bsh getDescription() to be able to use native getDescription()
//without falling in infinite recursivity
transient boolean getDescription_bsh_call = false;
public String getDescription ( Entity viewer )
{
//bsh getDescription override support
if ( !getDescription_bsh_call ) //avoid infinite recursivity if bsh calls this method
{
boolean ejecutado = false;
ReturnValue retval = new ReturnValue ( null );
try
{
getDescription_bsh_call = true;
ejecutado = execCode ( "getDescription" ,
new Object[]
{
viewer
}
, retval
);
}
catch ( ScriptException te )
{
te.printStackTrace();
}
finally
{
getDescription_bsh_call = false;
}
if ( retval.getRetVal() != null )
return (String)retval.getRetVal();
else if ( ejecutado ) //sobreescribe comportamiento por defecto
return null;
}
//normal (non-bsh) description generation
String desString="";
for ( int i = 0 ; i < descriptionList.length ; i++ )
{
if ( descriptionList[i].matchesConditions(this,viewer) )
desString += descriptionList[i].getText();
}
if ( !isContainer() )
{
return desString;
}
else if ( inventory.isEmpty() ) //puede contener items; pero no. Est� vac�o.
{
//si la descripci�n est� construida con la conocida f�rmula "hay x" o "lleva x", cambiamos por "no hay nada" o "no lleva nada".
//si no, simplemente por "nada".
return StringMethods.textualSubstitution ( StringMethods.textualSubstitution ( StringMethods.textualSubstitution ( desString , "lleva %INVENTORY" , "no lleva nada." ) , "hay %INVENTORY" , "no hay nada." ) , "%INVENTORY" , mundo.getMessages().getMessage("nothing")+"." );
}
else
{
return StringMethods.textualSubstitution ( desString , "%INVENTORY" , inventory.toString(mundo) );
}
}
public String getName ( boolean s_p , int comparand )
{
Description[] theList;
if ( s_p ) theList = singNames;
else theList = plurNames;
String desString="";
for ( int i = 0 ; i < theList.length ; i++ )
{
if ( theList[i].matches(comparand) )
desString += theList[i].getText();
}
return desString;
}
//new version supporting predicates
public String getName ( boolean s_p , Entity viewer )
{
Description[] theList;
if ( s_p ) theList = singNames;
else theList = plurNames;
String desString="";
if ( theList == null ) return desString;
for ( int i = 0 ; i < theList.length ; i++ )
{
if ( theList[i].matchesConditions(this,viewer) )
desString += theList[i].getText();
}
return desString;
}
public String getSingName ( int comparand )
{
return getName ( true , comparand );
}
public String getSingNameTrue ( int comparand )
{
String s = getName ( true , comparand );
if ( s != null & s.length() > 0 )
return s;
else
return Character.toLowerCase(title.charAt(0)) + title.substring(1);
}
//predicate-supporting
public String getSingName ( Entity viewer )
{
return getName ( true , viewer );
}
//predicate-supporting
public String getSingNameTrue ( Entity viewer )
{
String s = getName ( true , viewer );
if ( s != null & s.length() > 0 )
return s;
else
return Character.toLowerCase(title.charAt(0)) + title.substring(1);
}
public String getPlurName ( int comparand )
{
return getName ( false , comparand );
}
//predicate-supporting
public String getPlurName ( Entity viewer )
{
return getName ( false , viewer );
}
public String getPlurNameTrue ( int comparand )
{
String s = getName ( false , comparand );
if ( s != null & s.length() > 0 )
return s;
else
return Character.toLowerCase(title.charAt(0)) + title.substring(1);
}
//predicate-supporting
public String getPlurNameTrue ( Entity viewer )
{
String s = getName ( false , viewer );
if ( s != null & s.length() > 0 )
return s;
else
return Character.toLowerCase(title.charAt(0)) + title.substring(1);
}
//devuelve "una espada", "dos hachas", etc.
public String constructName ( int nItems , int comparand )
{
if ( nItems == 1 )
{
if ( gender )
return ( "un " + getSingName( comparand ) );
else
return ( "una " + getSingName( comparand ) );
}
else if ( nItems < 10 )
{
String str;
switch ( nItems )
{
case 2: str="dos"; break;
case 3: str="tres"; break;
case 4: str="cuatro"; break;
case 5: str="cinco"; break;
case 6: str="seis"; break;
case 7: str="siete"; break;
case 8: str="ocho"; break;
default: str="nueve"; break;
}
return ( str + " " + getPlurName ( comparand ) );
}
else
{
return ( nItems + " " + getPlurName( comparand ) );
}
}
//predicate-supporting
public String constructName ( int nItems , Entity viewer )
{
if ( nItems == 1 )
{
return presentName ( getSingName(viewer) , mundo.getMessages().getMessage("art.ind.m") , mundo.getMessages().getMessage("art.ind.f") );
/*
if ( gender )
return ( "un " + getSingName( viewer ) );
else
return ( "una " + getSingName( viewer ) );
*/
}
else if ( nItems < 10 )
{
String str;
switch ( nItems )
{
case 2: str="dos"; break;
case 3: str="tres"; break;
case 4: str="cuatro"; break;
case 5: str="cinco"; break;
case 6: str="seis"; break;
case 7: str="siete"; break;
case 8: str="ocho"; break;
default: str="nueve"; break;
}
Debug.println("CONSNAME RETT'N' " + str + " " + getPlurName ( viewer ));
return ( str + " " + getPlurName ( viewer ) );
}
else
{
return ( nItems + " " + getPlurName( viewer ) );
}
}
//devuelve "la espada", "dos hachas", etc.
public String constructName2 ( int nItems , int comparand )
{
if ( nItems == 1 )
{
if ( gender )
return ( "el " + getSingName( comparand ) );
else
return ( "la " + getSingName( comparand ) );
}
else
{
return ( nItems + " " + getPlurName( comparand ) );
}
}
//predicate-supporting
public String constructName2 ( int nItems , Entity viewer )
{
if ( nItems == 1 )
{
return presentName ( getSingNameTrue(viewer) , mundo.getMessages().getMessage("art.def.m") , mundo.getMessages().getMessage("art.def.f") );
/*
if ( gender )
return ( "el " + getSingName( viewer ) );
else
return ( "la " + getSingName( viewer ) );
*/
}
else
{
return ( nItems + " " + getPlurName( viewer ) );
}
}
//lo mismo que constructName2; pero si no hay ning�n nombre v�lido en este estado,
//se las arregla para conseguir uno: devuelve el t�tulo.
public String constructName2True ( int nItems , int comparand )
{
if ( nItems == 1 )
{
if ( gender )
return ( "el " + getSingNameTrue( comparand ) );
else
return ( "la " + getSingNameTrue( comparand ) );
}
else
{
return ( nItems + " " + getPlurNameTrue( comparand ) );
}
}
//predicate-supporting
public String constructName2True ( int nItems , Entity viewer )
{
if ( nItems == 1 )
{
/*
if ( gender )
return ( "el " + getSingNameTrue( viewer ) );
else
return ( "la " + getSingNameTrue( viewer ) );
*/
return presentName ( getSingNameTrue(viewer) , mundo.getMessages().getMessage("art.def.m") , mundo.getMessages().getMessage("art.def.f") );
}
else
{
return ( nItems + " " + getPlurNameTrue( viewer ) );
}
}
public String constructName2OneItem ( )
{
return constructName2True ( 1 , getState() );
}
//predicate-supporting
public String constructName2OneItem ( Entity viewer )
{
return constructName2True ( 1 , viewer ) ;
}
public String presentName ( String baseName , String mascArticle , String femArticle )
{
boolean properName = this.properName;
if ( baseName.startsWith("P$")) //names starting with P$ are always treated as proper
{
properName = true;
baseName = baseName.substring(2);
}
else if ( baseName.startsWith("N$")) //names starting with N$ are always treated as not proper
{
properName = false;
baseName = baseName.substring(2);
}
//note that names not starting with P$ or N$ are treated as proper or not proper depending on
//the properName variable of the mobile.
if ( properName )
return baseName;
if ( gender )
return ( mascArticle + " " + baseName );
else
return ( femArticle + " " + baseName );
}
//convert numbers to their word representation
public String numberToWord ( int number )
{
switch ( number )
{
case 1: return "uno";
case 2: return "dos";
case 3: return "tres";
case 4: return "cuatro";
case 5: return "cinco";
case 6: return "seis";
case 7: return "siete";
case 8: return "ocho";
case 9: return "nueve";
default: return String.valueOf(number);
}
}
//master method for getting output names
/**
* Gets the output name of this entity, given
* @param nItems The number of copies of this entity that are being shown.
* @viewer The entity who is viewing this entity, if any.
* @mascArt Article to be used for showing a single instance if the item is masculine.
* @femArt Article to be used for showing a single instance if the item is feminine.
* @evenIfInvisible If true, return a nonempty string even if the entity is invisible for the viewer (fallback to getTitle()).
* @numberToWord If nItems > 1, show the number of items in word form (eight) rather than numerical form (8).
*/
public String getOutputName ( int nItems , Entity viewer , String mascArt , String femArt , boolean evenIfInvisible , boolean numberToWord )
{
if ( nItems == 1 )
{
String baseName;
if ( evenIfInvisible ) baseName = getSingNameTrue(viewer);
else baseName = getSingName(viewer);
return presentName ( baseName , mascArt , femArt );
}
else
{
String baseName;
if ( evenIfInvisible ) baseName = getPlurNameTrue(viewer);
else baseName = getPlurName(viewer);
if ( numberToWord ) return presentName ( baseName , numberToWord(nItems) , numberToWord(nItems) );
else return presentName ( baseName , String.valueOf(nItems) , String.valueOf(nItems) );
}
}
/**
* Gets the output name to show nItems copies of this entity to viewer, without any article.
* @param nItems The number of copies of this entity that are being showed.
* @param viewer The entity who is viewing this entity.
* @return String with the output name to show to viewer.
*/
public String getOutputNameOnly ( int nItems , Entity viewer )
{
return getOutputName ( nItems , viewer , "" , "" , false , true );
}
/**
* Gets the output name to show nItems copies of this entity, without parameterising it for any viewer in particular, without any article.
* @param nItems The number of copies of this entity that are being showed.
* @return String with the output name to show to viewer, without using any article for a single item.
*/
public String getOutputNameOnly ( int nItems )
{
return getOutputName ( nItems , null , "" , "" , true , true );
}
/**
* Gets the output name to show one instance of this entity to viewer, without any article.
* @return String with the output name to show to viewer, without using any article.
*/
public String getOutputNameOnly ( Entity viewer )
{
return getOutputName ( 1 , viewer , "" , "" , true , true );
}
/**
* Gets the output name to show one instance of this entity, without parameterising the name for any viewer in particular, without any article.
* @return String with the output name to show to viewer, without using any article.
*/
public String getOutputNameOnly ( )
{
return getOutputName ( 1 , null , "" , "" , true , true );
}
/**
* Gets the output name to show nItems copies of this entity to viewer, with a definite article if applicable.
* @param nItems The number of copies of this entity that are being showed.
* @param viewer The entity who is viewing this entity.
* @return String with the output name to show to viewer, with a definite article or the number of items.
*/
public String getOutputNameThe ( int nItems , Entity viewer )
{
return getOutputName ( nItems , viewer , mundo.getMessages().getMessage("art.def.m") , mundo.getMessages().getMessage("art.def.f") , false , true );
}
/**
* Gets the output name to show nItems copies of this entity, without parameterising them for any viewer in particular, with a definite article if applicable.
* @param nItems The number of copies of this entity that are being showed.
* @return String with the output name to show to viewer, with a definite article or the number of items.
*/
public String getOutputNameThe ( int nItems )
{
return getOutputName ( nItems , null , mundo.getMessages().getMessage("art.def.m") , mundo.getMessages().getMessage("art.def.f") , true , true );
}
/**
* Gets the output name to show one instance of this entity to viewer, using a definite article.
* @return String with the output name to show to viewer, using a definite article
*/
public String getOutputNameThe ( Entity viewer )
{
return getOutputName ( 1 , viewer , mundo.getMessages().getMessage("art.def.m") , mundo.getMessages().getMessage("art.def.f") , true , true );
}
/**
* Gets the output name to show one instance of this entity, without parameterising the name for any viewer in particular, using a definite article.
* @return String with the output name to show to viewer, using a definite article
*/
public String getOutputNameThe ( )
{
return getOutputName ( 1 , null , mundo.getMessages().getMessage("art.def.m") , mundo.getMessages().getMessage("art.def.f") , true , true );
}
/**
* Gets the output name to show nItems copies of this entity to viewer, with an indefinite article if applicable.
* @param nItems The number of copies of this entity that are being showed.
* @param viewer The entity who is viewing this entity.
* @return String with the output name to show to viewer, with an indefinite article or the number of items.
*/
public String getOutputNameA ( int nItems , Entity viewer )
{
return getOutputName ( nItems , viewer , mundo.getMessages().getMessage("art.ind.m") , mundo.getMessages().getMessage("art.ind.f") , false , true );
}
/**
* Gets the output name to show nItems copies of this entity, without parameterising them for any viewer in particular, with an indefinite article if applicable.
* @param nItems The number of copies of this entity that are being showed.
* @return String with the output name to show to viewer, with an indefinite article or the number of items.
*/
public String getOutputNameA ( int nItems )
{
return getOutputName ( nItems , null , mundo.getMessages().getMessage("art.ind.m") , mundo.getMessages().getMessage("art.ind.f") , true , true );
}
/**
* Gets the output name to show one instance of this entity to a given viewer, using an indefinite article.
* @return String with the output name to show to viewer, using an indefinite article.
*/
public String getOutputNameA ( Entity viewer )
{
return getOutputName ( 1 , viewer , mundo.getMessages().getMessage("art.ind.m") , mundo.getMessages().getMessage("art.ind.f") , true , true );
}
/**
* Gets the output name to show one instance of this entity, without parameterising the name for any viewer in particular, using an indefinite article.
* @return String with the output name to show to viewer, using an indefinite article.
*/
public String getOutputNameA ( )
{
return getOutputName ( 1 , null , mundo.getMessages().getMessage("art.ind.m") , mundo.getMessages().getMessage("art.ind.f") , true , true );
}
/**
* Obtains an extra description, representing a description of a particular component, feature or aspect of this Item.
* This method's implementation has been changed as of 2012-12-01 to match in a more useful way, similar to the Entity moderateMatchesCommand() method.
* @param requestedName The name to match against descriptions (e.g. typed by the player)
* @param viewer The Entity for which the description will be customized.
* @return A description for the component/feature/aspect named requestedName, or null if no such component exists.
*/
public String getExtraDescription ( String requestedName , Entity viewer )
{
if ( requestedName == null || requestedName.length() == 0 ) return null;
for ( int i = 0 ; i < extraDescriptionNameArrays.size() ; i++ )
{
String[] curNameArray = (String[]) extraDescriptionNameArrays.get(i);
Description[] curDesArray = (Description[]) extraDescriptionArrays.get(i);
for ( int j = 0 ; j < curNameArray.length ; j++ )
{
String currentReferenceName = curNameArray[j];
int position = requestedName.toLowerCase().indexOf(currentReferenceName.toLowerCase());
if ( position < 0 ) //does not match
continue;
if ( position != 0 && !Character.isWhitespace(requestedName.charAt(position-1)) ) //matches but starts at a place other than beginning/whitespace
continue;
if ( position+currentReferenceName.length() != requestedName.length() && !Character.isWhitespace(requestedName.charAt(position+currentReferenceName.length())) ) //matches but ends at a place other than end/whitespace
continue;
//if we have reached this point, the match is acceptable
String desString="";
for ( int k = 0 ; k < curDesArray.length ; k++ )
{
if ( curDesArray[k].matchesConditions(this,viewer) ) //or general comparand?
{
desString += "\n";
desString += curDesArray[k].getText();
}
}
if ( desString.length() > 0 )
return desString.substring(1); //quitamos primer \n
else
return null;
}
}
//nothing found
return null;
}
/*
//as of 03.09.03, extra descriptions are regular descriptions.
//Parallel lists of Description[] and String[].
public String getExtraDescription ( String thingieName , Entity viewer )
{
if ( thingieName == null || thingieName.length() == 0 ) return null;
for ( int i = 0 ; i < extraDescriptionNameArrays.size() ; i++ )
{
String[] curNameArray = (String[]) extraDescriptionNameArrays.get(i);
Description[] curDesArray = (Description[]) extraDescriptionArrays.get(i);
//Modern Extra Description Support! As of 05-07-14! Let's Rock It!
for ( int j = 0 ; j < curNameArray.length ; j++ )
{
if ( thingieName.toLowerCase().endsWith(curNameArray[j].toLowerCase()) )
{
String desString="";
for ( int k = 0 ; k < curDesArray.length ; k++ )
{
if ( curDesArray[k].matchesConditions(this,viewer) ) //or general comparand?
{
desString += "\n";
desString += curDesArray[k].getText();
}
}
if ( desString.length() > 0 )
return desString.substring(1); //quitamos primer \n
else
return null;
}
}
//Ancient Extra Description Support. Buuuh! Buuuh!
for ( int j = 0 ; j < curNameArray.length ; j++ )
{
//si la ultima palabra de lo que pone despues de "mirar" coincide con el nombre actual
if ( StringMethods.getTok(thingieName,StringMethods.numToks(thingieName,' '),' ').equalsIgnoreCase(curNameArray[j]) )
{
String desString="";
for ( int k = 0 ; k < curDesArray.length ; k++ )
{
if ( curDesArray[k].matchesConditions(this,viewer) ) //or general comparand?
{
desString += "\n";
desString += curDesArray[k].getText();
}
}
if ( desString.length() > 0 )
return desString.substring(1); //quitamos primer \n
else
return null;
}
}
}
return null;
}
*/
//as of 02.09.28, extra descriptions MAY be stated,
//using dynlists as in std. descriptions, with room state.
//in this case, no &'s in an extra description means 0&0&...
/*
public String getExtraDescription ( String thingieName , long comparand )
{
int nTokens = StringMethods.numToks(extraDescriptions,'@');
for ( int i = 1 ; i <= nTokens ; i++ )
{
String curToken = StringMethods.getTok(extraDescriptions,i,'@');
int nTokens2 = StringMethods.numToks(curToken,'$');
for ( int j = 1 ; j < nTokens2 ; j++ )
{
//si la ultima palabra de lo que pone despues de "mirar" coincide con uno de los nTokens2-1 primeros tokens (es decir, comandos que activan extrades)
if ( StringMethods.getTok(thingieName,StringMethods.numToks(thingieName,' '),' ').equalsIgnoreCase(StringMethods.getTok(curToken,j,'$')) )
{
String theDescription = StringMethods.getTok(curToken,nTokens2,'$');
//puede ser stateful o stateless. Vamos a verlo.
if ( theDescription.indexOf('&') < 0 )
return theDescription; //sin depender de estados
else
{
//depende de estados (es una description list con comparandos y m�scaras)
//procesar comparandos y m�scaras como en getDescription
Description[] dList = Utility.loadDescriptionListFromString ( theDescription );
String desString="";
for ( int k = 0 ; k < dList.length ; k++ )
{
if ( dList[k].matches(comparand) ) //or general comparand?
{
desString += "\n";
desString += dList[k].getText();
}
}
if ( desString.length() > 0 )
return desString;
else return null;
}
}
}
}
return null;
}
*/
/*
obsolete public String getExtraDescription ( String thingieName )
{
int nTokens = StringMethods.numToks(extraDescriptions,'@');
for ( int i = 1 ; i <= nTokens ; i++ )
{
String curToken = StringMethods.getTok(extraDescriptions,i,'@');
int nTokens2 = StringMethods.numToks(curToken,'$');
for ( int j = 1 ; j < nTokens2 ; j++ )
{
//si la ultima palabra de lo que pone despues de "mirar" coincide con uno de los nTokens2-1 primeros tokens (es decir, comandos que activan extrades)
if ( StringMethods.getTok(thingieName,StringMethods.numToks(thingieName,' '),' ').equalsIgnoreCase(StringMethods.getTok(curToken,j,'$')) )
return StringMethods.getTok(curToken,nTokens2,'$');
}
}
return null;
}
*/
/**
* Nos dice si se da por aludido el objeto ante un comando (ej. "mirar piedra") -> se pasa "piedra")
*
* @param commandArgs Los argumentos del comando.
* @param pluralOrSingular 1 si plural.
* @return 0 si no se da por aludido, 1 si s�, y con qu� prioridad. (+ n� = - prioridad). La prioridad es el orden que ocupa el nombre que se corresponde con el comando dado en la lista de nombres.
*/
public int matchesCommand ( String commandArgs , boolean pluralOrSingular )
{
List listaDeInteres;
if ( pluralOrSingular ) // plural
listaDeInteres = respondToPlur;
else
listaDeInteres = respondToSing;
/*
int nToksArg = StringMethods.numToks( commandArgs , ' ');
int nToksList = StringMethods.numToks( listaDeInteres , '$');
for ( int i = 1 ; i <= nToksArg ; i++ )
{
String currentToAnalyze = StringMethods.getToks( commandArgs , i , nToksArg , ' ' );
//"mirar la piedra peque�a" -> commandArgs="la piedra peque�a" -> vamos analizando "la piedra peque�a", "piedra peque�a", ...
for ( int j = 1 ; j <= nToksList ; j++ )
{
if ( StringMethods.getTok( listaDeInteres , j , '$' ) .equalsIgnoreCase(currentToAnalyze) )
{
return j;
}
}
//TODO: here, add reverse analysis. gettoks from 1 to moving i.
}
return 0;
*/
return matchesCommand ( commandArgs , listaDeInteres , mundo.getCommandMatchingMode() );
}
public String getInstanceOf ( )
{
return isInstanceOf;
}
public void setWorld ( World mundo )
{
this.mundo = mundo;
}
public void setInstanceOf ( String newid )
{
isInstanceOf = newid;
}
/**
* Returns true if viewer cannot distinguish this item from other.
* This is used to collapse descriptions, e.g. to show "two stones" rather than "a stone and a stone".
* @param other The item that we want to know whether it is indistinguishable or not from this one.
* @param viewer The viewer for which we want to know if items are indistinguishable.
* @return
*/
public boolean isIndistinguishableFrom ( Item other , Entity viewer )
{
String plurName1 = this.getPlurName(viewer);
String plurName2 = other.getPlurName(viewer);
if ( plurName1 != null && plurName1.trim().length() > 0
&& plurName2 != null && plurName2.trim().length() > 0 )
return plurName1.equals(plurName2);
else
return isSame ( other );
}
/**
* Returns true if this item is the same as the one passed by parameter, or if they are copies of the same item.
* @param other
* @return
*/
public boolean isSame ( Item other )
{
//Debug.print ( "isSame " + this + "("+this.getUniqueName()+","+this.idnumber+", cloning "+this.getInstanceOf()+")" + " " + other + "("+other.getUniqueName()+","+other.idnumber+", cloning "+other.getInstanceOf()+")? ");
/*
Debug.println ( "" + ( ( idnumber % 10000000 == other.getInstanceOf () % 10000000 )
|| ( isInstanceOf % 10000000 == other.getID () % 10000000 )
|| ( isInstanceOf % 10000000 == other.getInstanceOf() % 10000000 && isInstanceOf % 10000000 != 0 ) ) );
*/
//fix for problem with first item, which always seems same as everything because
//items which aren't instance of anything have instanceof 0, and that item
//has id 0
//removed 2011-05-01
//if ( isInstanceOf == 0 || other.getInstanceOf() == 0 ) return false;
/*
return ( ( idnumber % 10000000 == other.getInstanceOf () % 10000000 )
|| ( isInstanceOf % 10000000 == other.getID () % 10000000 )
|| ( isInstanceOf % 10000000 == other.getInstanceOf() % 10000000 && isInstanceOf % 10000000 != 0 ) );
*/
return (
this.getUniqueName().equals(other.getInstanceOf())
|| other.getUniqueName().equals(this.getInstanceOf())
|| (
this.getInstanceOf() != null &&
this.getInstanceOf().equals(other.getInstanceOf()) &&
!StringMethods.isStringOfZeroes(this.getInstanceOf())
)
);
/*observemos que la herencia fuerte no producira los resultados
deseados si se encadena (A hereda de B, B de C...). No se implementan
las cadenas porque son inutiles y solo recargarian el juego. Las
cadenas solo son utiles en herencia debil, en herencia fuerte se
supone que las instancias son iguales y da igual que hereden todas
de una que unas de otras, por lo tanto.*/
}
/*ejecuta el codigo EVA del objeto correspondiente a la rutina dada si existe.
Si no existe, simplemente no ejecuta nada y devuelve false.*/
public boolean execCode ( String routine , String dataSegment ) throws EVASemanticException
{
if ( itsCode != null )
return itsCode.run ( routine , dataSegment );
else return false;
}
/*
public boolean isInvisible ( Entity viewer )
{
//if ( !properName )
return ( StringMethods.numToks ( constructName(1,viewer) , ' ' ) < 2 );
//else
// return ( StringMethods.numToks ( constructName(1,viewer) , ' ' ) < 1 );
}
*/
public boolean isInvisible ( Entity viewer )
{
return !( getSingName(viewer).length() > 0 );
}
/*ejecuta el codigo EVA del objeto correspondiente a la rutina dada si existe.
Si no existe, simplemente no ejecuta nada y devuelve false.*/
public boolean execCode ( String routine , Object[] args ) throws ScriptException
{
if ( itsCode != null )
return itsCode.run ( routine , this , args );
else return false;
}
/*ejecuta el codigo bsh del objeto correspondiente a la rutina dada si existe.
Si no existe, simplemente no ejecuta nada y devuelve false.*/
public boolean execCode ( String routine , Object[] args , ReturnValue retval ) throws ScriptException
{
//S/ystem.out.println("Mobile code runnin'.");
//Debug.println("Its Code: " + itsCode);
if ( itsCode != null )
return itsCode.run ( routine , this , args , retval );
else return false;
}
//[old] Hay que definir el changeState.
public void changeState ( World mundo )
{
try
{
execCode("event_endstate","this: "+ getID() + "state: " + getState() );
}
catch ( EVASemanticException exc )
{
mundo.write("EVASemanticException found at event_endstate , item number " + getID() );
}
}
public boolean getGender()
{
return gender;
}
/**Devuelve si el item puede abrirse (no si el personaje puede hacerlo, sino si tiene sentido abrirlo)*/
public boolean isOpenable()
{
return ( openable || (openDescriptionList != null && openDescriptionList.length > 0) );
}
/**Devuelve si el item puede cerrarse (no es lo mismo, un huevo es openable y no closeable)*/
public boolean isCloseable()
{
return ( closeable || ( closeDescriptionList != null && closeDescriptionList.length > 0 ) );
}
//id. anteriores
public boolean isUnlockable()
{
return ( unlockable || ( unlockDescriptionList != null && unlockDescriptionList.length > 0 ) );
}
//id. anteriores
public boolean isLockable()
{
return ( lockable || ( lockDescriptionList != null && lockDescriptionList.length > 0 ) );
}
public boolean isOpen()
{
return //( (256 & getState()) == 0 ) && //legacy state removed 2011-05-14
( !getPropertyValueAsBoolean("closed") );
}
public boolean isClosed()
{
return !isOpen();
}
public boolean isUnlocked()
{
return //( (512 & getState()) == 0 ) && //legacy state removed 2011-05-14
( !getPropertyValueAsBoolean("locked") );
}
public boolean isLocked()
{
return !isUnlocked();
}
public boolean unlocksWithKey( Item key )
{
if ( keys != null )
{
for ( int i = 0 ; i < keys.size() ; i++ )
{
if ( keys.elementAt(i).equals(key) ) return true;
}
}
return false;
}
/**
* Returns an initialization array for matchesConditions with the viewer, actor and key variables.
* @param viewer
* @param actor
* @return
*/
private static Object[][] viewerActorKey ( Mobile viewer , Mobile actor , Item key )
{
return new Object[][] { {"viewer",viewer},{"actor" ,actor},{"key", key} };
}
//intentar abrir sin llave.
public String abrir ( Mobile abridor )
{
boolean exito = false; //si realmente abrimos el objeto
String descriptionText = "";
if ( !isOpenable() )
{
return //"Es absurdo abrir eso.";
mundo.getMessages().getMessage("item.not.openable",new Object[]{this});
}
//else if ( !isUnlocked() )
//{
//correcci�n: quitamos esto. En realidad, se tratar� como el resto.
//return "\n�No se abre!";
//}
else
{
//descripciones open
for ( int i = 0 ; i < openDescriptionList.length ; i++ )
{
//Debug.print("A");
Description des_actual = openDescriptionList[i];
if ( des_actual.matchesConditions ( this , viewerActorKey(abridor,abridor,null) ) )
{
//Debug.print("B");
//Debug.print(des_actual.getText());
String elTexto = des_actual.getText();
StringTokenizer st = new StringTokenizer(elTexto,":");
//mirar si antes de ":" sale �xito o fracaso (al abrir)
String firstToken = st.nextToken();
if ( firstToken.equalsIgnoreCase("SUCCESS") || firstToken.equalsIgnoreCase("EXITO") )
{
exito = true;
}
//coger el resto de la descripci�n y a�adirla
elTexto = "";
while ( st.hasMoreTokens() ) elTexto+=st.nextToken();
if ( !elTexto.equals("") )
{
descriptionText += elTexto;
//descriptionText += "\n";
}
}
}
if ( descriptionText.equals("") )
{
//if no description was matched, then we make a default decision based on the open/closed/locked/unlocked
//state of the item
if ( isOpen() )
{
exito = false;
descriptionText = mundo.getMessages().getMessage("cant.open.already.open","$item",this.getOutputNameThe(),"$oa",(getGender()?"o":"a"),new Object[]{this});
}
else if ( isLocked() )
{
exito = false;
descriptionText = mundo.getMessages().getMessage("cant.open.locked","$item",this.getOutputNameThe(),"$oa",(getGender()?"o":"a"),new Object[]{this});
}
else //isClosed() && !isLocked()
{
exito = true;
descriptionText = mundo.getMessages().getMessage("you.open.item","$item",this.getOutputNameThe(),"$oa",(getGender()?"o":"a"),new Object[]{this});
}
}
//si ha tenido �xito (se cumpl�a alguno de los estados de �xito) abrimos
if ( exito )
{
//old open
setNewState( getState() & (~256) );
//new open
setProperty("closed",false);
//opened item inform
List habitaciones = getRoomReferences();
for ( int i = 0 ; i < habitaciones.size() ; i++ )
{
Room thisHabitacion = (Room) habitaciones.get(i);
//@@UNCOMMENT
//NO DE MOMENTO. PENSAR C�MO HACER QUE ESTO NO DIGA "ALGO"
//TAL VEZ NOMBRES CON PAR�METRO SHOWONROOM, O ALGO AS�
//thisHabitacion.informAction(this,null,null,"$1 se abre.\n","Te abres.\n","Abres.\n",false);
}
}
}
try
{
execCode("onOpen" , new Object[] {abridor , new Boolean(exito)} );
execCode("onOpen" , new Object[] {new Boolean(exito)} );
}
catch ( ScriptException bshte )
{
return( "bsh.TargetError found onOpen , item number " + getID() + ": " + bshte + "[description was: " + descriptionText + "]" );
}
return descriptionText;
} //end function
//intentar cerrar sin llave
public String cerrar ( Mobile cerrador )
{
if ( !isCloseable() )
{
return //"Es absurdo cerrar eso.";
mundo.getMessages().getMessage("item.not.closeable",new Object[]{this});
}
else
{
//descripciones close
String descriptionText = "";
boolean exito = false; //si realmente cerramos el objeto
for ( int i = 0 ; i < closeDescriptionList.length ; i++ )
{
Description des_actual = closeDescriptionList[i];
if ( des_actual.matchesConditions ( this , viewerActorKey(cerrador,cerrador,null) ) )
{
String elTexto = des_actual.getText();
StringTokenizer st = new StringTokenizer(elTexto,":");
//mirar si antes de ":" sale �xito o fracaso (al cerrar)
String firstToken = st.nextToken();
if ( firstToken.equalsIgnoreCase("SUCCESS") || firstToken.equalsIgnoreCase("EXITO") )
{
exito = true;
}
//coger el resto de la descripci�n y a�adirla
elTexto = "";
while ( st.hasMoreTokens() ) elTexto+=st.nextToken();
if ( !elTexto.equals("") )
{
descriptionText += elTexto;
//descriptionText += "\n";
}
}
}
if ( descriptionText.equals("") )
{
//if no description was matched, then we make a default decision based on the open/closed/locked/unlocked
//state of the item
if ( isClosed() )
{
exito = false;
descriptionText = mundo.getMessages().getMessage("cant.close.already.closed","$item",this.getOutputNameThe(),"$oa",(getGender()?"o":"a"),new Object[]{this});
}
else
{
exito = true;
descriptionText = mundo.getMessages().getMessage("you.close.item","$item",this.getOutputNameThe(),"$oa",(getGender()?"o":"a"),new Object[]{this});
}
}
//si ha tenido �xito (se cumpl�a alguno de los estados de �xito) cerramos
if ( exito )
{
//old close
setNewState( getState() | 256 );
//new close
setProperty("closed",true);
//closed item inform
List habitaciones = getRoomReferences();
for ( int i = 0 ; i < habitaciones.size() ; i++ )
{
Room thisHabitacion = (Room) habitaciones.get(i);
//@@UNCOMMENT
//NO DE MOMENTO. PENSAR C�MO HACER QUE ESTO NO DIGA "ALGO"
//TAL VEZ NOMBRES CON PAR�METRO SHOWONROOM, O ALGO AS�
//thisHabitacion.informAction(this,null,null,"$1 se cierra.\n","Te cierras.\n","Cierras.\n",false);
}
}
try
{
execCode("onClose" , new Object[] {cerrador , new Boolean(exito)} );
execCode("onClose" , new Object[] {new Boolean(exito)} );
}
catch ( ScriptException bshte )
{
return( "bsh.TargetError found onOpen , item number " + getID() + ": " + bshte + "[description was: " + descriptionText + "]" );
}
return descriptionText;
}
}
public String unlock ( Item key , Mobile unlocker )
{
if ( !isUnlockable() )
{
return //"No parece que se pueda abrir eso de ese modo.";
mundo.getMessages().getMessage("item.not.unlockable",new Object[]{this});
}
else
{
//descripciones unlock: a diferencia de las open, pueden tener dos diferentes
//son de la forma SUCCESS:des1:FAIL:des2 <- s�lo un succ/fail por descripci�n as of 2011-05-13
//(las open s�lo tienen una de las dos partes que indica si abres o no
//en ese estado; pero en las unlock el que abras o no viene dado por
//la llave que uses aparte del estado)
//2011-05-13: si no tiene la llave, miramos solo fail (eso ya estaba antes).
//si tiene la llave, miramos primero success. si alguna matchea, perfecto
//si no, miramos fail (puede fallar por otras condiciones ajenas a la llave).
//2011-11-26: si no tiene ni success ni fail, se usa un mensaje por defecto
//y la acci�n tiene �xito dependiendo de si tiene o no la llave.
boolean unlocked = false;
String descriptionText = "";
if ( !unlocksWithKey ( key ) )
{
//consideramos s�lo descripciones "fail"
for ( int i = 0 ; i < unlockDescriptionList.length ; i++ )
{
Description des_actual = unlockDescriptionList[i];
String elTexto2 = ""; //to append to description
if ( des_actual.matchesConditions ( this , viewerActorKey(unlocker,unlocker,key) ) )
{
//buscar descripci�n fail (obligatoria) <- no oblig. (2008-04)
String elTexto1 = des_actual.getText();
StringTokenizer st = new StringTokenizer(elTexto1,":");
String temp;
while ( st.hasMoreTokens() && !((temp=st.nextToken()).equalsIgnoreCase("FAIL")) && !temp.equalsIgnoreCase("FRACASO") )
{
;
}
if ( st.hasMoreTokens() )
elTexto2 = st.nextToken();
else
elTexto2 = "";
} //end if matches getstate
descriptionText += elTexto2;
}
/*
if ( descriptionText.equals("") )
{
descriptionText = "No consigues abrir " + this.getUniqueName(); //TODO temp, modify
}
*/
}
else
{
//consideramos la descripci�n "success" y abrimos, o, si no hay
//descripci�n "success", entonces miramos descripciones fail
//(puede fallar por motivos como que la puerta no este cerrada
//con llave, etc.)
unlocked = false;
//check success descriptions first
for ( int i = 0 ; i < unlockDescriptionList.length ; i++ )
{
Description des_actual = unlockDescriptionList[i];
//String elTexto2 = ""; //to append to description
if ( des_actual.isSuccessDescription() && des_actual.matchesConditions ( this , viewerActorKey(unlocker,unlocker,key) ) )
{
//if ( des_actual.isSuccessDescription() )
//{
descriptionText += des_actual.getTextWithoutSuccessMark();
unlocked = true;
//}
}
} //end for all possible descriptions in different states
//now if not successful, check fail descriptions
if ( !unlocked )
{
for ( int i = 0 ; i < unlockDescriptionList.length ; i++ )
{
Description des_actual = unlockDescriptionList[i];
//String elTexto2 = ""; //to append to description
if ( des_actual.isFailDescription() && des_actual.matchesConditions ( this , viewerActorKey(unlocker,unlocker,key) ) )
{
//if ( des_actual.isFailDescription() )
//{
descriptionText += des_actual.getTextWithoutSuccessMark();
//}
}
} //end for all possible descriptions in different states
}
if ( descriptionText.equals("") )
{
//in this case, there wasn't any success or failure description.
//so the default behaviour (since we used the correct key) is success.
unlocked = true;
}
if ( unlocked )
{
//hemos conseguido abrirlo
//cambiar el estado para que se refleje esto
//old unlock
setNewState( getState() & (~512) );
//new unlock
setProperty("locked",false);
//unlocked item inform
List habitaciones = getRoomReferences();
for ( int i = 0 ; i < habitaciones.size() ; i++ )
{
Room thisHabitacion = (Room) habitaciones.get(i);
//removed, does not make sense:
//thisHabitacion.reportAction(this,null,null,"$1 se abre con llave.\n","Te abres con llave.\n","Abres con llave.\n",false);
}
}
} //end else (if unlocks with key)
if ( descriptionText.equals("") )
{
//if no descriptions matched, then we use default messages as the description.
if ( unlocked )
descriptionText = mundo.getMessages().getMessage("you.unlock.item","$item",this.getOutputNameThe(),"$key",key.getOutputNameThe(),new Object[]{this});
else
descriptionText = mundo.getMessages().getMessage("cant.unlock.key","$item",this.getOutputNameThe(),"$key",key.getOutputNameThe(),new Object[]{this});
}
try
{
execCode("onUnlock" , new Object[] {unlocker , key , new Boolean(unlocked)} );
//execCode("onUnlock" , new Object[] {new Boolean(exito)} );
}
catch ( ScriptException bshte )
{
return( "bsh.TargetError found onUnlock , item " + this + ": " + bshte + "[description was: " + descriptionText + "]" );
}
return descriptionText;
} //end else (if it's unlockable)
} //end function
public String lock ( Item key , Mobile locker )
//sim�trico de unlock
{
if ( !isLockable() )
{
return //"No parece que se pueda cerrar eso de ese modo.";
mundo.getMessages().getMessage("item.not.lockable",new Object[]{this});
}
else
{
//descripciones lock: igual que las de unlock, pueden tener dos diferentes
//son de la forma SUCCESS:des1:FAIL:des2 <- s�lo un succ/fail por descripci�n as of 2011-05-13
//(las open s�lo tienen una de las dos partes que indica si abres o no
//en ese estado; pero en las unlock/lock el que abras o no viene dado por
//la llave que uses aparte del estado)
//2011-05-13: si no tiene la llave, miramos solo fail (eso ya estaba antes).
//si tiene la llave, miramos primero success. si alguna matchea, perfecto
//si no, miramos fail (puede fallar por otras condiciones ajenas a la llave).
//2011-11-26: si no tiene ni success ni fail, se usa un mensaje por defecto
//y la acci�n tiene �xito dependiendo de si tiene o no la llave.
boolean locked = false;
String descriptionText = "";
if ( !unlocksWithKey ( key ) )
{
//consideramos s�lo descripciones "fail"
for ( int i = 0 ; i < lockDescriptionList.length ; i++ )
{
Description des_actual = lockDescriptionList[i];
String elTexto2 = ""; //to append to description
if ( des_actual.matchesConditions ( this , viewerActorKey(locker,locker,key) ) )
{
//buscar descripci�n fail (obligatoria)
String elTexto1 = des_actual.getText();
StringTokenizer st = new StringTokenizer(elTexto1,":");
String temp;
while ( st.hasMoreTokens() && !((temp=st.nextToken()).equalsIgnoreCase("FAIL")) && !temp.equalsIgnoreCase("FRACASO") )
{
;
}
if ( st.hasMoreTokens() )
elTexto2 = st.nextToken();
} //end if matches getstate
if ( !elTexto2.equals("") )
{
descriptionText += "\n";
descriptionText += elTexto2;
}
}
}
else
{
//consideramos la descripci�n "success" y lockeamos, o, si no hay
//descripci�n "success", miramos las fail
locked = false;
//check success descriptions first
for ( int i = 0 ; i < lockDescriptionList.length ; i++ )
{
Description des_actual = lockDescriptionList[i];
//String elTexto2 = ""; //to append to description
if ( des_actual.isSuccessDescription() && des_actual.matchesConditions ( this , viewerActorKey(locker,locker,key) ) )
{
//if ( des_actual.isSuccessDescription() )
//{
descriptionText += des_actual.getTextWithoutSuccessMark();
locked = true;
//}
}
} //end for all possible descriptions in different states
//now if not successful, check fail descriptions
if ( !locked )
{
for ( int i = 0 ; i < lockDescriptionList.length ; i++ )
{
Description des_actual = lockDescriptionList[i];
//String elTexto2 = ""; //to append to description
if ( des_actual.isFailDescription() && des_actual.matchesConditions ( this , viewerActorKey(locker,locker,key) ) )
{
//if ( des_actual.isFailDescription() )
//{
descriptionText += des_actual.getTextWithoutSuccessMark();
//}
}
} //end for all possible descriptions in different states
}
if ( descriptionText.equals("") )
{
//in this case, there wasn't any success or failure description.
//so the default behaviour (since we used the correct key) is success.
locked = true;
}
if ( locked )
{
//hemos conseguido cerrarlo
//cambiar el estado para que se refleje esto
//old lock
setNewState( getState() | 512 );
//new lock
setProperty("locked",true);
//locked item inform
List habitaciones = getRoomReferences();
for ( int i = 0 ; i < habitaciones.size() ; i++ )
{
Room thisHabitacion = (Room) habitaciones.get(i);
//removed 2011-05-13:
//thisHabitacion.reportAction(this,null,null,"$1 se cierra con llave.\n","Te cierras con llave.\n","Cierras con llave.\n",false);
}
}
} //end else (if unlocks with key)
if ( descriptionText.equals("") )
{
//if no descriptions matched, then we use default messages as the description.
if ( locked )
descriptionText = mundo.getMessages().getMessage("you.lock.item","$item",this.getOutputNameThe(),"$key",key.getOutputNameThe(),new Object[]{this});
else
descriptionText = mundo.getMessages().getMessage("cant.lock.key","$item",this.getOutputNameThe(),"$key",key.getOutputNameThe(),new Object[]{this});
}
try
{
execCode("onLock" , new Object[] {locker , key , new Boolean(locked)} );
//execCode("onUnlock" , new Object[] {new Boolean(exito)} );
}
catch ( ScriptException bshte )
{
return( "bsh.TargetError found onLock , item " + this + ": " + bshte + "[description was: " + descriptionText + "]" );
}
return descriptionText;
} //end else (if it's unlockable)
} //end function
//nos devuelve el nombre m�s espec�fico con el que nos podemos referir al objeto en
//un comando. �til para zonas de referencia.
public String getBestReferenceName ( boolean pluralOrSingular )
{
List theList;
if ( pluralOrSingular ) //true? plural
theList = respondToPlur;
else
theList = respondToSing;
String tmp = // StringMethods.getTok(theList,1,'$');
(String) theList.get(0);
return ( Character.toLowerCase( tmp.charAt(0) ) ) + tmp.substring(1);
}
/**
* Used when contained items are put inside of a container on world load, to set the references from those items to
* their container.
*/
private void createReferencesInContainedItems()
{
if ( isContainer() )
for ( int i = 0 ; i < inventory.size() ; i++ )
{
((Item)inventory.get(i)).addContainerReference(this);
}
}
/* Carga diferida del inventario (y tambi�n del parts-inventory o inventario de composite)*/
/* (y del key list) <- 2008-04-27*/
public void loadInventoryFromXML ( World mundo ) throws XMLtoWorldException
{
org.w3c.dom.Node n = mundo.getItemNode( String.valueOf(getID()) );
org.w3c.dom.Element e = null;
try
{
e = (org.w3c.dom.Element) n;
}
catch ( ClassCastException cce )
{
throw ( new XMLtoWorldException ( "Item node not Element" ) );
}
org.w3c.dom.NodeList inventoryNodes = e.getElementsByTagName ( "Inventory" );
//solo nos interesan los hijos DIRECTOS
List realInventoryNodes = new ArrayList();
List partsInventoryNodes = new ArrayList();
List keysInventoryNodes = new ArrayList();
for ( int i = 0 ; i < inventoryNodes.getLength() ; i++ )
{
if ( inventoryNodes.item(i).getParentNode() == e ) realInventoryNodes.add ( inventoryNodes.item(i) );
else if ( inventoryNodes.item(i).getParentNode() instanceof org.w3c.dom.Element && ((org.w3c.dom.Element)inventoryNodes.item(i).getParentNode()).getTagName().equalsIgnoreCase("parts") ) partsInventoryNodes.add ( inventoryNodes.item(i) );
else if ( inventoryNodes.item(i).getParentNode() instanceof org.w3c.dom.Element && ((org.w3c.dom.Element)inventoryNodes.item(i).getParentNode()).getTagName().equalsIgnoreCase("keylist") ) keysInventoryNodes.add ( inventoryNodes.item(i) );
}
if ( realInventoryNodes.size() < 1 )
{
//Debug.println("No inventory nodes, inventory will be left null.");
inventory = null;
}
else
{
inventory = new Inventory ( mundo , (org.w3c.dom.Node)realInventoryNodes.get(0) );
createReferencesInContainedItems();
}
if ( partsInventoryNodes.size ( ) < 1 )
{
partsInventory = null;
}
else
{
partsInventory = new Inventory ( mundo , (org.w3c.dom.Node)partsInventoryNodes.get(0) );
}
if ( keysInventoryNodes.size ( ) < 1 )
{
keys = null;
}
else
{
keys = new Inventory ( mundo , (org.w3c.dom.Node)keysInventoryNodes.get(0) );
}
}
/*
Carga del inventario para contenedores a partir de la l�nea correspondiente del fichero
(inventoryString), que se difiere para poder soportar items de n�mero mayor que �ste.
*/
//I think this is unused and I don't have to repeat it for partsInventory. But not sure.
public void loadInventory ( World mundo )
{
//item references line
if ( inventoryString == null || inventoryString.equals("") )
{
inventory = null; return;
}
//Debug.println("Container item found. Performing delayed load.\n");
int nObjects = StringMethods.numToks(inventoryString,'$') - 2;
//Debug.println("nObjects is " + nObjects);
//if ( nObjects < 1 )
//{
// inventory = null; return;
//}
int maxweight,maxvol;
try
{
maxweight = Integer.valueOf(StringMethods.getTok(inventoryString,1,'$')).intValue();
maxvol = Integer.valueOf(StringMethods.getTok(inventoryString,2,'$')).intValue();
}
catch ( NumberFormatException nfe )
{
inventory = null; return;
}
//Debug.println("Proceeding to item load.");
inventory = new Inventory ( maxweight , maxvol, nObjects );
for ( int i = 0 ; i < nObjects ; i++ )
{
//Debug.println("Adding item to container.");
try
{
this.addItem ( mundo.getItem(StringMethods.getTok(inventoryString,i+3,'$')) );
}
catch (WeightLimitExceededException exc)
{
mundo.write("Item too heavy for container, ID " + idnumber );
}
catch (VolumeLimitExceededException exc2)
{
mundo.write("Item too big for container , ID " + idnumber );
}
}
} //end function load inventory
public Inventory getContents ( )
{
return inventory;
}
public boolean isContainer ( )
{
return (inventory!=null);
}
public Inventory getParts ( )
{
return partsInventory;
}
public boolean isComposite ( )
{
return (partsInventory!=null);
}
public org.w3c.dom.Node getXMLRepresentation ( org.w3c.dom.Document doc )
{
org.w3c.dom.Element suElemento = doc.createElement( "Item" );
suElemento.setAttribute ( "id" , String.valueOf( idnumber ) );
suElemento.setAttribute ( "name" , String.valueOf ( title ) );
suElemento.setAttribute ( "extends" , String.valueOf ( inheritsFrom ) );
suElemento.setAttribute ( "clones" , String.valueOf ( isInstanceOf ) );
suElemento.setAttribute ( "type" , String.valueOf ( itemType ) );
suElemento.setAttribute ( "volume" , String.valueOf( volume ) );
suElemento.setAttribute ( "weight" , String.valueOf( weight ) );
suElemento.setAttribute ( "enabled" , String.valueOf( enabled ) );
suElemento.setAttribute ( "isVirtual" , String.valueOf( isVirtual ) );
suElemento.setAttribute ( "canGet" , String.valueOf( canGet ) );
if ( properName ) suElemento.setAttribute ( "properName" , String.valueOf( properName ) );
suElemento.setAttribute ( "openable" , String.valueOf(isOpenable()) /*String.valueOf( openDescriptionList != null )*/ );
suElemento.setAttribute ( "closeable" , String.valueOf(isCloseable()) /* String.valueOf( closeDescriptionList != null )*/ );
suElemento.setAttribute ( "lockable" , String.valueOf(isLockable()) /*String.valueOf( lockDescriptionList != null )*/ );
suElemento.setAttribute ( "unlockable" , String.valueOf(isUnlockable()) /*String.valueOf( unlockDescriptionList != null )*/ );
//temp gender representation
suElemento.setAttribute ( "gender" , String.valueOf( gender ) );
suElemento.appendChild ( getPropListXMLRepresentation(doc) );
suElemento.appendChild ( getRelationshipListXMLRepresentation(doc) );
org.w3c.dom.Element listaDesc;
if ( descriptionList != null )
{
listaDesc = doc.createElement("DescriptionList");
for ( int i = 0 ; i < descriptionList.length ; i++ )
{
Description nuestraDescripcion = descriptionList[i];
listaDesc.appendChild ( nuestraDescripcion.getXMLRepresentation(doc) );
}
suElemento.appendChild(listaDesc);
}
if ( singNames != null )
{
org.w3c.dom.Element listaSing = doc.createElement("SingularNames");
for ( int i = 0 ; i < singNames.length ; i++ )
{
Description nuestraDescripcion = singNames[i];
listaSing.appendChild ( nuestraDescripcion.getXMLRepresentation(doc) );
}
suElemento.appendChild(listaSing);
}
if ( plurNames != null )
{
org.w3c.dom.Element listaPlur = doc.createElement("PluralNames");
for ( int i = 0 ; i < plurNames.length ; i++ )
{
Description nuestraDescripcion = plurNames[i];
listaPlur.appendChild ( nuestraDescripcion.getXMLRepresentation(doc) );
}
suElemento.appendChild(listaPlur);
}
//"respond to" names (temp XML representation)
if ( respondToSing != null )
{
org.w3c.dom.Element respTo = getNameListXMLRepresentation(doc,respondToSing,"SingularReferenceNames");
suElemento.appendChild(respTo);
}
if ( respondToPlur != null )
{
org.w3c.dom.Element respTo = getNameListXMLRepresentation(doc,respondToPlur,"PluralReferenceNames");
suElemento.appendChild(respTo);
}
//inventario
if ( inventory != null )
suElemento.appendChild(inventory.getXMLRepresentation(doc));
if ( partsInventory != null )
{
org.w3c.dom.Element partsElt = doc.createElement("Parts");
suElemento.appendChild(partsElt);
partsElt.appendChild(partsInventory.getXMLRepresentation(doc));
}
//extra descriptions (temp XML representation)
if ( extraDescriptions != null )
{
org.w3c.dom.Element extraDes = doc.createElement("ExtraDescriptionList");
StringTokenizer st1 = new StringTokenizer ( extraDescriptions, "@" );
while ( st1.hasMoreTokens() )
{
String desActual = st1.nextToken();
org.w3c.dom.Element unaDescripcion = doc.createElement("ExtraDescription");
StringTokenizer st2 = new StringTokenizer ( desActual , "$" );
while ( st2.hasMoreTokens() )
{
String wordActual = st2.nextToken();
if ( st2.hasMoreTokens() )
{
org.w3c.dom.Element comando = doc.createElement("Name");
org.w3c.dom.Text contenido = doc.createTextNode(wordActual);
comando.appendChild(contenido);
unaDescripcion.appendChild(comando);
}
else
{
org.w3c.dom.Text texto = doc.createTextNode(wordActual);
unaDescripcion.appendChild(texto);
}
}
extraDes.appendChild ( unaDescripcion );
}
//org.w3c.dom.Text extraDesContent = doc.createTextNode(extraDescriptions);
//extraDes.appendChild(extraDesContent);
suElemento.appendChild(extraDes);
}
//new extra description support
if ( extraDescriptionNameArrays != null && extraDescriptionArrays != null )
{
suElemento.appendChild(Utility.getExtraDescriptionXMLRepresentation(extraDescriptionNameArrays, extraDescriptionArrays, doc));
}
//keys inventory
if ( keys != null )
{
org.w3c.dom.Element keysel = doc.createElement("KeyList");
keysel.appendChild(keys.getXMLRepresentation(doc));
suElemento.appendChild(keysel);
}
//only restrictions: not at the moment
//open, close, lock, unlock lists
if ( openDescriptionList != null )
{
listaDesc = doc.createElement("OpenDescriptionList");
for ( int i = 0 ; i < openDescriptionList.length ; i++ )
{
Description nuestraDescripcion = openDescriptionList[i];
listaDesc.appendChild ( nuestraDescripcion.getXMLRepresentation(doc) );
}
suElemento.appendChild(listaDesc);
}
if ( closeDescriptionList != null )
{
listaDesc = doc.createElement("CloseDescriptionList");
for ( int i = 0 ; i < closeDescriptionList.length ; i++ )
{
Description nuestraDescripcion = closeDescriptionList[i];
listaDesc.appendChild ( nuestraDescripcion.getXMLRepresentation(doc) );
}
suElemento.appendChild(listaDesc);
}
if ( lockDescriptionList != null )
{
listaDesc = doc.createElement("LockDescriptionList");
for ( int i = 0 ; i < lockDescriptionList.length ; i++ )
{
Description nuestraDescripcion = lockDescriptionList[i];
listaDesc.appendChild ( nuestraDescripcion.getXMLRepresentation(doc) );
}
suElemento.appendChild(listaDesc);
}
if ( unlockDescriptionList != null )
{
listaDesc = doc.createElement("UnlockDescriptionList");
for ( int i = 0 ; i < unlockDescriptionList.length ; i++ )
{
Description nuestraDescripcion = unlockDescriptionList[i];
listaDesc.appendChild ( nuestraDescripcion.getXMLRepresentation(doc) );
}
suElemento.appendChild(listaDesc);
}
//object code
if ( itsCode != null )
suElemento.appendChild(itsCode.getXMLRepresentation(doc));
return suElemento;
}
public void loadNumberGenerator ( World mundo )
{
aleat = mundo.getRandom();
//Debug.println("I am " + this + "[IID:"+getID()+"][INAME"+title+"], and my Random has been set to " + aleat);
}
public java.util.Random getRandom()
{
return aleat;
}
public void setID ( int newid )
{
if ( newid < 30000000 )
idnumber = newid + 30000000;
else
idnumber = newid;
}
//Crea el cad�ver del bicho dado.
public static Item initCorpse ( Mobile m )
{
Item it = new Item();
//no fijamos una ID porque la fijar� World::addItemDinamically()
it.itemType = "corpse";
it.inheritsFrom = 0;
it.isInstanceOf = "0";
it.title = "cad�ver de " + //m.constructName(1);
m.getOutputNameA();
it.descriptionList = new Description[1];
it.descriptionList[0] = ( new Description ( "Es un cad�ver de " + m.getOutputNameA() + ", que lleva %INVENTORY" , 0 , 0 ) );
it.singNames = new Description[1];
it.singNames[0] = new Description ( it.title , 0 , 0 );
it.plurNames = new Description[1];
it.plurNames[0] = new Description ( "cad�veres de "
//+ m.constructName(2)
//+ m.getOutputNameOnly(2)
+ m.getPlurNameTrue(null)
, 0 , 0 );
it.gender = true; //masculino
it.respondToSing = new ArrayList();
it.respondToSing.add(it.title);
it.respondToSing.add("cad�ver"); //TODO localize this
it.respondToSing.add("cadaver");
it.respondToSing.add("cuerpo");
it.respondToSing.add("muerto");
it.respondToSing.addAll(m.respondToSing);
it.respondToPlur = new ArrayList();
it.respondToPlur.add(it.title);
it.respondToSing.add("cad�veres"); //TODO localize this
it.respondToSing.add("cadaveres");
it.respondToSing.add("cuerpos");
it.respondToSing.add("muertos");
it.respondToSing.addAll(m.respondToPlur);
//temp!
it.volume = 1000;
it.weight = 1000;
//inventory
it.inventory = m.getInventoryForCorpse();
if ( it.inventory == null )
it.inventory = new Inventory(10000,10000);
it.mobRefs = null; //unnecessary, probably
it.extraDescriptions = null;
it.onlyRestrictions = null;
it.openDescriptionList = null;
it.closeDescriptionList = null;
it.lockDescriptionList = null;
it.unlockDescriptionList = null;
it.keys = null;
it.enabled = true;
it.isVirtual = false;
it.canGet = true;
it.properName = false;
it.itsCode = null;
return it;
}
//devuelve un Inventory formado por las partes, las partes de partes, etc. etc.
public Inventory getFlattenedPartsInventory()
{
if ( partsInventory == null ) return new Inventory(1,1);
Inventory result = new Inventory(partsInventory.getWeightLimit(),partsInventory.getVolumeLimit());
for ( int i = 0 ; i < partsInventory.size() ; i++ )
{
Item thisPart = partsInventory.elementAt(i);
Inventory subInv = thisPart.getFlattenedPartsInventory();
//add part's flattened parts inventory
try
{
result.setVolumeLimit ( result.getVolumeLimit() + subInv.getVolumeLimit() );
result.setWeightLimit ( result.getWeightLimit() + subInv.getWeightLimit() );
}
catch ( Exception e )
{
Debug.println("Impossible exception thrown: " + e);
e.printStackTrace();
}
for ( int j = 0 ; j < subInv.size() ; j++ )
{
try
{
result.addItem ( subInv.elementAt(j) );
}
catch ( Exception e )
{
Debug.println("Impossible exception thrown: " + e);
e.printStackTrace();
}
}
//add this part
try
{
result.addItem ( thisPart );
}
catch ( Exception e )
{
Debug.println("Impossible exception thrown: " + e);
e.printStackTrace();
}
}
return result;
}
//call Room::informActionAuto on all item's rooms
/**
* @deprecated Use {@link #reportActionAuto(Entity,Entity,Entity[],String,boolean)} instead
*/
public void informActionAuto ( Entity source /*$1*/ , Entity target /*$2*/ , Entity[] objects /*$3..$n*/ , String thirdPersonDes , boolean self_included )
{
reportActionAuto(source, target, objects, thirdPersonDes, self_included);
}
/**
* @deprecated Use {@link #reportAction(Entity,Entity,Entity[],String,String,String,boolean)} instead
*/
public void informAction ( Entity source /*$1*/ , Entity target /*$2*/ , Entity[] objects /*$3..$n*/ , String thirdPersonDes , String sufferDes , String execDes , boolean self_included )
{
reportAction(source, target, objects, thirdPersonDes, sufferDes,
execDes, self_included);
}
public void reportActionAuto ( Entity source /*$1*/ , Entity target /*$2*/ , Entity[] objects /*$3..$n*/ , String thirdPersonDes , boolean self_included )
{
reportActionAuto ( source , target , objects , thirdPersonDes , null , self_included );
}
public void reportAction ( Entity source /*$1*/ , Entity target /*$2*/ , Entity[] objects /*$3..$n*/ , String thirdPersonDes , String sufferDes , String execDes , boolean self_included )
{
reportAction ( source , target , objects , thirdPersonDes , sufferDes , execDes , null , self_included );
}
//call Room::informActionAuto on all item's rooms
public void reportActionAuto ( Entity source /*$1*/ , Entity target /*$2*/ , Entity[] objects /*$3..$n*/ , String thirdPersonDes , String style , boolean self_included )
{
List habitaciones = getRoomReferences();
for ( int i = 0 ; i < habitaciones.size() ; i++ )
{
Room hab = (Room)habitaciones.get(i);
hab.reportActionAuto ( source , target , objects , thirdPersonDes , style , self_included );
}
}
public void reportAction ( Entity source /*$1*/ , Entity target /*$2*/ , Entity[] objects /*$3..$n*/ , String thirdPersonDes , String sufferDes , String execDes , String style , boolean self_included )
{
List habitaciones = getRoomReferences();
for ( int i = 0 ; i < habitaciones.size() ; i++ )
{
Room hab = (Room)habitaciones.get(i);
hab.reportAction ( source , target , objects , thirdPersonDes , sufferDes , execDes , style , self_included );
}
}
public void removeFromInventories ( )
{
for ( int i = 0 ; i < rooms.size() ; i++ )
{
Room r = (Room) rooms.get(i);
r.removeItem(this);
}
for ( int i = 0 ; i < mobiles.size() ; i++ )
{
Mobile m = (Mobile) mobiles.get(i);
m.removeItem(this);
}
removeFromContainers();
}
public void removeFromContainers ( )
{
for ( int i = 0 ; i < containers.size() ; i++ )
{
Item cont = (Item) containers.get(i);
cont.removeItem(this);
}
}
public void moveTo ( Room target ) throws WeightLimitExceededException,VolumeLimitExceededException
{
removeFromInventories();
target.addItem(this);
}
public void moveTo ( Mobile target ) throws WeightLimitExceededException,VolumeLimitExceededException
{
removeFromInventories();
target.addItem(this);
}
public void moveTo ( Item target ) throws WeightLimitExceededException,VolumeLimitExceededException
{
removeFromInventories();
target.addItem(this);
}
/**
* Returns a list of all the locations (rooms, mobiles, containers) this item is in.
* @return
*/
public EntityList getLocations()
{
EntityList result = new EntityList();
for ( int i = 0 ; i < rooms.size() ; i++ ) result.addEntity((Entity)rooms.get(i));
for ( int i = 0 ; i < mobiles.size() ; i++ ) result.addEntity((Entity)mobiles.get(i));
for ( int i = 0 ; i < containers.size() ; i++ ) result.addEntity((Entity)containers.get(i));
return result;
}
/**
* Returns the first location (room, mobile, container) this item is in. Note that an item can
* be at several locations at the same time, but this method returns only one.
* @return
*/
public Entity getLocation()
{
return getLocations().get(0);
}
//devuelve un Inventory formado por el contenido, el contenido del contenido, etc. etc.
public Inventory getFlattenedInventory()
{
if ( inventory == null ) return new Inventory(1,1);
Inventory result = new Inventory(inventory.getWeightLimit(),inventory.getVolumeLimit());
for ( int i = 0 ; i < inventory.size() ; i++ )
{
Item thisPart = inventory.elementAt(i);
Inventory subInv = thisPart.getFlattenedInventory();
//add part's flattened parts inventory
try
{
result.setVolumeLimit ( result.getVolumeLimit() + subInv.getVolumeLimit() );
result.setWeightLimit ( result.getWeightLimit() + subInv.getWeightLimit() );
}
catch ( Exception e )
{
Debug.println("Impossible exception thrown: " + e);
e.printStackTrace();
}
for ( int j = 0 ; j < subInv.size() ; j++ )
{
try
{
result.addItem ( subInv.elementAt(j) );
}
catch ( Exception e )
{
Debug.println("Impossible exception thrown: " + e);
e.printStackTrace();
}
}
//add this part
try
{
result.addItem ( thisPart );
}
catch ( Exception e )
{
Debug.println("Impossible exception thrown: " + e);
e.printStackTrace();
}
}
return result;
}
public boolean isWearable() { return ( this instanceof Wearable ); }
public boolean isWeapon() { return ( this instanceof Weapon ); }
/**
* Obtain a list with the singular reference names of the item, in order.
*/
public List getSingularReferenceNames()
{
return //Conversions.getReferenceNameList(respondToSing);
(List) ((ArrayList)respondToSing).clone();
}
/**
* Obtain a list with the plural reference names of the item, in order.
*/
public List getPluralReferenceNames()
{
//System.err.println("The item: " + this + " with pl. names: " + respondToPlur);
return //Conversions.getReferenceNameList(respondToPlur);
(List) ((ArrayList)respondToPlur).clone();
}
/**
* Adds a new singular reference name, with lower priority than the existing reference names.
*/
public void addSingularReferenceName(String newName)
{
respondToSing.add(newName);
mundo.getSpellChecker().addNewName(newName);
}
/**
* Adds a new singular reference name, located at the given index that defines its priority.
*/
public void addSingularReferenceName(int index,String newName)
{
respondToSing.add(index,newName);
mundo.getSpellChecker().addNewName(newName);
}
/**
* Removes a singular reference name from the list of such names, if present. Returns whether it has actually been removed or not.
* Note that this does not remove any word from the world's vocabulary used by the spell checker.
* Call the rebuild() method in the world's spell checker if this effect is desired (but beware, that takes a nontrivial amount of time)
*/
public boolean removeSingularReferenceName(String oldName)
{
return respondToSing.remove(oldName);
}
/**
* Adds a new plural reference name, with lower priority than the existing reference names.
*/
public void addPluralReferenceName(String newName)
{
respondToPlur.add(newName);
mundo.getSpellChecker().addNewName(newName);
}
/**
* Adds a new plural reference name, located at the given index that defines its priority.
*/
public void addPluralReferenceName(int index,String newName)
{
respondToPlur.add(index,newName);
mundo.getSpellChecker().addNewName(newName);
}
/**
* Removes a plural reference name from the list of such names, if present. Returns whether it has actually been removed or not.
* Note that this does not remove any word from the world's vocabulary used by the spell checker.
* Call the rebuild() method in the world's spell checker if this effect is desired (but beware, that takes a nontrivial amount of time)
*/
public boolean removePluralReferenceName(String oldName)
{
return respondToPlur.remove(oldName);
}
public ObjectCode getAssociatedCode()
{
return itsCode;
}
public boolean removeItem ( Item viejo )
{
if ( !isContainer() ) return false;
else
{
viejo.removeContainerReference(this);
return inventory.removeItem(viejo);
}
}
public boolean addItem ( Item nuevo ) throws WeightLimitExceededException , VolumeLimitExceededException
{
if ( !isContainer() ) return false;
else if ( !inventory.contains(nuevo) )
{
inventory.addItem(nuevo);
nuevo.addContainerReference(this);
return true;
}
else return false;
}
/**
* Builds a list with all the extra description names and returns it.
* Careful, each call to this method builds the list!
* @return
*/
public List getExtraDescriptionNames()
{
List result = new ArrayList();
for ( int i = 0 ; i < extraDescriptionNameArrays.size() ; i++ )
{
String[] ar = (String[]) extraDescriptionNameArrays.get(i);
for ( int j = 0 ; j < ar.length ; j++ )
{
result.add(ar[j]);
}
}
return result;
}
} //end class item