/*
* (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 bsh.*;
import java.io.*;
import java.net.URL;
import javax.sound.midi.Sequencer;
import eu.irreality.age.debug.Debug;
import eu.irreality.age.debug.ExceptionPrinter;
import eu.irreality.age.language.Mentions;
import eu.irreality.age.matching.Matches;
import eu.irreality.age.messages.Messages;
import eu.irreality.age.util.Conversions;
import eu.irreality.age.scripting.ScriptException;
public class Mobile extends Entity implements Descriptible , SupportingCode , Nameable, UniqueNamed
{
/*constantes de "state"*/
public static final int IDLE=1;
public static final int MOVING=2;
public static final int ATTACKING=3;
public static final int BLOCKING=4;
public static final int READY_TO_BLOCK=5;
public static final int DODGING=6;
public static final int READY_TO_DODGE=7;
public static final int ATTACK_RECOVER=8;
public static final int BLOCK_RECOVER=9;
public static final int DAMAGE_RECOVER=10;
public static final int DODGE_RECOVER=11;
public static final int DYING=12; //just before death
public static final int DEAD=13;
public static final int SURPRISE_RECOVER=14;
public static final int DISABLED=15; //disconnected players and suchlike. Don't do anything
public static final int CASTING=16;
//provisional
boolean numeric_damage = false;
/*end constantes de "state"
//////////////////////
//INSTANCE VARIABLES//
//////////////////////
/**Tipo de bicho.*/
/*00*/ private String mobileType;
/**ID del objeto.*/
/*01*/ private int idnumber;
/**Hereda de.*/
/*02*/ private int inheritsFrom;
/*03*/ // inherited protected int state;
// inherited protected long timeunitsleft;
/**Habitaci�n actual*/
protected Room habitacionActual;
/**Habitaci�n anterior*/
protected Room habitacionAnterior;
/**Nombre sint�tico del bicho.*/
/*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. (goblin, goblin herido... mismo goblin, 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): listas de pattern-matching.*/
/*14*/ protected List respondToSing = new ArrayList();
/*15*/ protected List respondToPlur = new ArrayList();
/*20*/ protected Inventory inventory;
/*21*/ protected Inventory virtualInventory; //actually, should be called corpseInventory
protected Inventory partsInventory;
/*23*/ protected SpellList spellRefs;
/*25*/ protected MobileList combatRefs;
//protected ArrayList combatRefsMemory;
/*26*/ protected Inventory wieldedWeapons;
protected Inventory wornItems;
/*27*/ protected Vector knownSpellRefs;
/**Descripciones de subcosas del bicho.*/
/*30*/ protected String extraDescriptions; //OLD
protected List extraDescriptionArrays; /*List of Description Arrays*/
protected List extraDescriptionNameArrays; /*List of String Arrays*/
/**bit vector (o bits, a secas, m�s bien)*/
/*40*/ protected boolean properName = false; //no se le trata de "un" ni de "el".
//por defecto, false.
/**Lista de miembros*/
/*50*/ protected Inventory wieldingLimbs;
/**Traits*/
/*60,61*/ protected Traits caracteristicas;
/*62*/ protected int hp, mp, maxhp, maxmp;
/**Bitvectors de estado de relaciones con entidades (variables de memoria)*/
// /*70*/ protected Vector relationships = new Vector(); //vector of Entity
// protected Vector relationship_properties = new Vector(); //vector of List of Property
/**C�digo en Ensamblador Virtual Aetheria (EVA)*/
/*80*/ protected ObjectCode itsCode;
/**Especificaciones de habla PSI*/
/*82*/
protected Vector PSIanswers; //vector of Description[]s
protected Vector PSIkeywords; //vector or Strings
//initted in constructor
protected InputOutputClient io /*= new InputOutputClientNula()*/; //no hace nada para los bichos que no sean Informadores
String exitname; //nombre de la salida hacia la que est� yendo, si est� en estado "go"
//for combat
//private Weapon usingWeapon; //weapon used for a given attack
Spell usingSpell; //spell bein' used
//aleatorios
private Random aleat;
protected NaturalLanguage lenguaje;
protected World mundo; //su mundo actual
///////////
//METHODS//
///////////
public Mobile ( )
{
}
/**
* Este constructor solo llama a constructMobile, que es el constructor de verdad. Esta dualidad se debe a las llamadas recursivas que debe hacer constructRoom para soportar herencia dinamica (mobs que copian datos de otros)
*
*/
public Mobile ( World mundo , String mobfile ) throws IOException , FileNotFoundException
{
this.mundo = mundo;
io = new NullInputOutputClient();
lenguaje = mundo.getLanguage();
mentions.setLastMentionedVerb(lenguaje.getDefaultVerb());
constructMob ( mundo , mobfile , true , "none" );
//el constructor de cada subclase de Mobile llamar� con esa subclase en vez de none:
//public Daedra har�
//constructMob ( mundo , mobfile , true , "daedra" );
}
public Mobile ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException
{
this.mundo = mundo;
io = new NullInputOutputClient();
lenguaje = mundo.getLanguage();
mentions.setLastMentionedVerb(lenguaje.getDefaultVerb());
constructMob ( mundo , n , true , "none" );
//el constructor de cada subclase de Mobile llamar� con esa subclase en vez de none:
//public Daedra har�
//constructMob ( mundo , mobfile , true , "daedra" );
}
/**
* Constructor para ser llamado desde fuera, construye todas las subclases de Mobile seg�n el fichero
*
*/
public static Mobile getInstance ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException
{
if ( ! ( n instanceof org.w3c.dom.Element ) )
{
throw ( new XMLtoWorldException("Mobile node not Element") );
}
//{n is an Element}
org.w3c.dom.Element e = (org.w3c.dom.Element)n;
Mobile ourNewMobile;
if ( !e.hasAttribute("type") )
{
ourNewMobile = new Mobile ( mundo , n );
}
else if ( e.getAttribute("type").equalsIgnoreCase("daedra") )
{
// ourNewMobile = new Daedra ( mundo , n );
ourNewMobile=null;
}
//else if...
else
{
ourNewMobile = new Mobile ( mundo , n );
}
return ourNewMobile;
}
public static Mobile getInstance ( World mundo , String mobfile ) throws FileNotFoundException, IOException
{
String linea;
String id_linea;
FileInputStream fp = new FileInputStream ( mobfile );
BufferedReader filein = new BufferedReader ( Utility.getBestInputStreamReader ( fp ) );
//leer el tipo de mob
String mobtype = "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 )
mobtype = linea;
}
catch ( NumberFormatException ex )
{
//no pasa nada, estaremos en una parte con codigo, etc.
}
}
//crear el bicho
Mobile ourNewMob;
if ( mobtype.equalsIgnoreCase("daedra") )
{
ourNewMob = new Mobile /*Daedra*/ ( mundo , mobfile );
//llama a ourNewItem.constructItem ( mundo , itemfile , true , "weapon" );
}
else
{
ourNewMob = new Mobile ( mundo , mobfile );
//llama a ourNewItem.constructItem ( mundo , itemfile , true , "none" );
}
return ourNewMob;
}
protected static String firstWord(String s) {
StringTokenizer st = new StringTokenizer(s);
if ( st.hasMoreTokens() ) return st.nextToken();
else return "";
}
private static String restWords(String s) {
StringTokenizer st = new StringTokenizer(s);
if ( !st.hasMoreTokens() ) return "";
else
{
st.nextToken();
if ( !st.hasMoreTokens() ) return "";
else return st.nextToken("");
}
}
/**
* El pedazo de constructor que lee un bicho de un fichero.
*
*/
public void constructMob ( World mundo , String mobfile , boolean allowInheritance , String mobtype ) throws IOException, FileNotFoundException
{
this.setProperty("describeRoomsOnArrival" , true); //defaults to true
this.setPropertyTimeLeft("describeRoomsOnArrival", -1);
String linea;
String id_linea;
FileInputStream fp = new FileInputStream ( mobfile );
BufferedReader filein = new BufferedReader ( Utility.getBestInputStreamReader ( fp ) );
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 del bicho de que heredamos*/
constructMob ( mundo, Utility.mobFile(mundo,inheritsFrom) , true , mobtype );
/*overrideamos lo que tengamos que overridear*/
constructMob ( mundo, mobfile , false , mobtype );
return;
}
break;
case 3:
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 = linea;
if ( Integer.valueOf(isInstanceOf).intValue() < idnumber && allowInheritance ) /*el item del que heredamos debe tener ID menor*/
{
/*construimos segun constructor de la habitacion de que heredamos*/
constructMob ( mundo, Utility.mobFile(mundo,Integer.valueOf(isInstanceOf).intValue()) , true , mobtype );
/*overrideamos lo que tengamos que overridear*/
constructMob ( mundo, mobfile , false , mobtype );
return;
}
break;
case 10:
//mob 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 20:
//nonvirtual inventory line
{
int nObjects = StringMethods.numToks(linea,'$');
inventory = new Inventory ( 10000,10000,nObjects );
//Item[nObjects];
for ( int i = 0 ; i < nObjects ; i++ )
{
try
{
inventory.addItem ( mundo.getItem(StringMethods.getTok(linea,i+1,'$')) );
}
catch (WeightLimitExceededException exc)
{
}
catch (VolumeLimitExceededException exc2)
{
}
}
break;
}
case 21:
//virtual inventory line
{
int nObjects = StringMethods.numToks(linea,'$');
virtualInventory = new Inventory ( 10000,10000,nObjects );
//Item[nObjects];
for ( int i = 0 ; i < nObjects ; i++ )
{
try
{
virtualInventory.addItem ( mundo.getItem(StringMethods.getTok(linea,i+1,'$')) );
}
catch (WeightLimitExceededException exc)
{
}
catch (VolumeLimitExceededException exc2)
{
}
}
break;
}
case 25:
//combat opponents line
{
int nObjects = StringMethods.numToks(linea,'$');
combatRefs = new MobileList ( nObjects );
//Item[nObjects];
for ( int i = 0 ; i < nObjects ; i++ )
{
combatRefs.addMobile ( mundo.getMob(StringMethods.getTok(linea,i+1,'$')) );
}
break;
}
case 26:
//wielded weapons line
{
int nObjects = StringMethods.numToks(linea,'$');
wieldedWeapons = new Inventory ( 10000,10000,nObjects );
//Item[nObjects];
for ( int i = 0 ; i < nObjects ; i++ )
{
try
{
wieldedWeapons.addItem ( mundo.getItem(StringMethods.getTok(linea,i+1,'$')) );
}
catch (WeightLimitExceededException exc)
{
}
catch (VolumeLimitExceededException exc2)
{
}
}
break;
}
case 40:
//bitvectors area: proper name line (bicho con nombre propio)
{
try
{
if ( linea.equalsIgnoreCase("true") ||
Integer.parseInt(linea) == 1 )
{
properName = true;
}
}
catch ( NumberFormatException nfe )
{
;
}
break;
}
case 50:
//limbs line
{
int nObjects = StringMethods.numToks(linea,'$');
wieldingLimbs = new Inventory ( 10000,10000,nObjects );
//Item[nObjects];
for ( int i = 0 ; i < nObjects ; i++ )
{
try
{
wieldingLimbs.addItem ( mundo.getItem(StringMethods.getTok(linea,i+1,'$')) );
}
catch (WeightLimitExceededException exc)
{
}
catch (VolumeLimitExceededException exc2)
{
}
}
break;
}
case 70:
//RSBL (Relationship State Bitvector List) line
{
//formato:
// 0001$35@0003$32@0021$51
// quiere decir: la relacion con 0001 esta en estado 35, la con 0003 en estado 32, y con 0021 en estado 51.
//Usa /*70*/ protected Vector relationships;
// protected Vector relationship_states;
relationships = new Vector(); //of Entity
relationship_properties = new Vector(); //of List of PropertyEntry
StringTokenizer st = new StringTokenizer ( linea , "@" );
while ( st.hasMoreTokens() )
{
relationships.add ( mundo.getObject( st.nextToken()) );
if ( st.hasMoreTokens() )
{
List l = new ArrayList();
PropertyEntry pe = new PropertyEntry ( "state" , st.nextToken() , 0 );
l.add(pe);
relationship_properties.add(l);
}
//relationship_states.add ( Integer.valueOf(st.nextToken()) );
else
{
List l = new ArrayList();
PropertyEntry pe = new PropertyEntry ( "state" , "0" , 0 );
l.add(pe);
relationship_properties.add(l);
}
//relationship_states.add ( new Integer(0) );
}
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 82:
//begin PSI specs
{
String PSISpecString = 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 == 83 ) terminamos = true; //PSI spec termination line
else
{
PSISpecString += "\n";
PSISpecString += linea;
}
}
loadPSISpecs ( PSISpecString );
break;
} //end case 82
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 for
//poner bien la ID
if ( getID() < 10000000 )
idnumber += 20000000; //prefijo de bicho
if ( wieldingLimbs != null && wieldedWeapons == null )
{
//Debug.println("El conde Laurel.\n");
//Debug.println(wieldingLimbs.size());
wieldedWeapons = new Inventory(10000,10000,wieldingLimbs.size());
wieldedWeapons.incrementSize(wieldingLimbs.size());
// try
// {
// for ( int k = 0 ; k < wieldingLimbs.size() ; k++ )
// wieldedWeapons.addItem(mundo.getItem(0));
//Debug.println(wieldedWeapons.size());
// }
// catch ( WeightLimitExceededException e1 )
// {
// Debug.println("Hmm... Exception.");
// //imposible weight/volume limit exceeded: el objeto nulo (0) no pesa.
// }
// catch ( VolumeLimitExceededException e2 )
// {
// //idem
// Debug.println("Hmm... Exception2.");
// }
}
}
if ( mobtype.equalsIgnoreCase("daedra") )
{
/*((Daedra)this).readDaedraSpecifics ( mundo , mobfile )*/;
}
}
public void constructMob ( World mundo , org.w3c.dom.Node n , boolean allowInheritance , String mobtype ) throws XMLtoWorldException
{
this.setProperty("describeRoomsOnArrival" , true); //defaults to true
this.setPropertyTimeLeft("describeRoomsOnArrival", -1);
if ( ! ( n instanceof org.w3c.dom.Element ) )
{
throw ( new XMLtoWorldException ( "Mobile node not Element" ) );
}
//{n is an Element}
org.w3c.dom.Element e = (org.w3c.dom.Element) n;
//default values
mp = 0;
maxmp = 0;
properName = false;
//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
constructMob ( mundo , mundo.getMobileNode( e.getAttribute("extends") ) , true , mobtype );
//2. overrideamos lo que debamos overridear
constructMob ( mundo , n , false , mobtype );
}
//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
constructMob ( mundo , mundo.getMobileNode( e.getAttribute("clones") ) , true , mobtype );
isInstanceOf = e.getAttribute("clones");
return;
//2. overrideamos lo que debamos overridear
//constructMob ( mundo , n , false , mobtype );
}
//mandatory XML-attribs exceptions
//if ( !e.hasAttribute("id") )
// throw ( new XMLtoWorldException ( "Mobile node lacks attribute id" ) );
if ( !e.hasAttribute("name") )
throw ( new XMLtoWorldException ( "Mobile node lacks attribute name" ) );
if ( !e.hasAttribute("hp") )
throw ( new XMLtoWorldException ( "Mobile node lacks attribute hp" ) );
if ( !e.hasAttribute("maxhp") )
throw ( new XMLtoWorldException ( "Mobile node lacks attribute maxhp" ) );
if ( !e.hasAttribute("gender") )
throw ( new XMLtoWorldException ( "Mobile node lacks attribute gender" ) );
//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 mobile node" ) );
}
title = e.getAttribute("name");
gender = Boolean.valueOf ( e.getAttribute("gender") ).booleanValue();
try
{
hp = Integer.valueOf ( e.getAttribute("hp") ).intValue();
}
catch ( NumberFormatException nfe )
{
throw ( new XMLtoWorldException ( "Bad number format at attribute hp in mobile node" ) );
}
try
{
maxhp = Integer.valueOf ( e.getAttribute("maxhp") ).intValue();
}
catch ( NumberFormatException nfe )
{
throw ( new XMLtoWorldException ( "Bad number format at attribute maxhp in mobile node" ) );
}
if ( e.hasAttribute("mp") )
{
try
{
mp = Integer.valueOf ( e.getAttribute("mp") ).intValue();
}
catch ( NumberFormatException nfe )
{
throw ( new XMLtoWorldException ( "Bad number format at attribute mp in mobile node" ) );
}
}
if ( e.hasAttribute("maxmp") )
{
try
{
maxmp = Integer.valueOf ( e.getAttribute("maxmp") ).intValue();
}
catch ( NumberFormatException nfe )
{
throw ( new XMLtoWorldException ( "Bad number format at attribute maxmp in mobile node" ) );
}
}
//non-mandatory attribs
if ( e.hasAttribute("properName") )
{
properName = Boolean.valueOf ( e.getAttribute("properName") ).booleanValue();
}
//Entity parsing
readPropListFromXML ( mundo , n );
//habitacion actual
//PARA LOS BICHOS NO DAIOS,
//NO SE NECESITA PONER UN ROOM. SE INICIALIZA AL METER AL BICHO EN LA HABITACI�N (AL CARGAR HABITACI�N)
//(ROOMS SE CARGAN MAS TARDE QUE MOBILES)
//A LOS BICHOS DAIO'S (DYNAMICALLY-ASSIGNED-ID OBJECTS) LOS PONEMOS EN LA HABITACION
//QUE INDICA SU CAMPO HABITACIONACTUAL.
boolean roomsdone=true;
try
{
mundo.getRoom(0); //si esto da NullPointerException es que las habitaciones
//no est�n inicializadas.
}
catch ( NullPointerException npe )
{
roomsdone = false;
}
if ( roomsdone )
{
org.w3c.dom.NodeList currentRoomNodes = e.getElementsByTagName("CurrentRoom");
if ( currentRoomNodes.getLength() < 1 ) habitacionActual = null;
else
{
org.w3c.dom.Element currentRoomNode = (org.w3c.dom.Element)currentRoomNodes.item(0);
if ( !(currentRoomNode.hasAttribute("id")) )
throw ( new XMLtoWorldException("CurrentRoom element lacking id at Mobile") );
else
{
Room r = mundo.getRoom ( currentRoomNode.getAttribute("id") );
if ( r == null )
throw ( new XMLtoWorldException("CurrentRoom element pointing to unknown Room object") );
habitacionActual = r;
}
}
}
//habitacion anterior
/*
NOT LOADED AT THE MOMENT
org.w3c.dom.NodeList lastRoomNodes = e.getElementsByTagName("LastRoom");
if ( lastRoomNodes.getLength() < 1 ) habitacionActual = null;
else
{
org.w3c.dom.Element lastRoomNode = (org.w3c.dom.Element)lastRoomNodes.item(0);
if ( !(lastRoomNode.hasAttribute("id")) )
throw ( new XMLtoWorldException("LastRoom element lacking id at Mobile") );
else
{
Room r = mundo.getRoom ( lastRoomNode.getAttribute("id") );
if ( r == null )
throw ( new XMLtoWorldException("LastRoom element pointing to unknown Room object") );
habitacionAnterior = r;
}
}
*/
//description list
descriptionList = Utility.loadDescriptionListFromXML ( mundo , e , "DescriptionList" , true );
//singular name description list
singNames = Utility.loadDescriptionListFromXML ( mundo , e , "SingularNames" , true );
//plural name description list
plurNames = Utility.loadDescriptionListFromXML ( mundo , e , "PluralNames" , true );
//singular reference names (respondToSing)
respondToSing = Utility.loadNameListFromXML ( mundo , e , "SingularReferenceNames" , true );
//plural reference names (respondToPlur)
respondToPlur = Utility.loadNameListFromXML ( mundo , e , "PluralReferenceNames" , true );
//inventory, virtual inventory, wielded weapons inv, wielding limbs inv:
//not DIFERIDA.
org.w3c.dom.NodeList inventoryNodes = e.getElementsByTagName ( "Inventory" );
//solo nos interesan los hijos DIRECTOS
List realInventoryNodes = new ArrayList();
for ( int i = 0 ; i < inventoryNodes.getLength() ; i++ )
if ( inventoryNodes.item(i).getParentNode() == e ) realInventoryNodes.add ( inventoryNodes.item(i) );
if ( realInventoryNodes.size() < 1 )
{
//Debug.println("No inventory nodes, inventory will be left null.");
inventory = null;
}
else
{
//Debug.println("Inventory nodes present.");
inventory = new Inventory ( mundo , (org.w3c.dom.Node)realInventoryNodes.get(0) );
//Debug.println("Inventory size: " + inventory.size() );
//Debug.println("Inventory node: " + inventoryNodes.item(0) );
//Debug.println("Inventory's parent: " + inventoryNodes.item(0).getParentNode() );
//Debug.println(inventory);
createReferencesInInventoryItems();
}
//virtual inv
org.w3c.dom.NodeList virtualInvNodes = e.getElementsByTagName ( "VirtualInventory" );
if ( virtualInvNodes.getLength() < 1 )
virtualInventory = null;
else
{
org.w3c.dom.Element e2 = ( org.w3c.dom.Element ) virtualInvNodes.item(0);
org.w3c.dom.NodeList invNodes = e2.getElementsByTagName("Inventory");
if ( invNodes.getLength() < 1 )
virtualInventory = null;
else
virtualInventory = new Inventory ( mundo , invNodes.item(0) );
}
//welded weapon inv
org.w3c.dom.NodeList wieldedInvNodes = e.getElementsByTagName ( "WieldedWeaponsInventory" );
if ( wieldedInvNodes.getLength() < 1 )
wieldedWeapons = null;
else
{
org.w3c.dom.Element e2 = ( org.w3c.dom.Element ) wieldedInvNodes.item(0);
org.w3c.dom.NodeList invNodes = e2.getElementsByTagName("Inventory");
if ( invNodes.getLength() < 1 )
wieldedWeapons = null;
else
wieldedWeapons = new Inventory ( mundo , invNodes.item(0) );
}
//worn items inv
org.w3c.dom.NodeList wornItemNodes = e.getElementsByTagName ( "WornItemsInventory" );
if ( wornItemNodes.getLength() < 1 )
wornItems = null;
else
{
org.w3c.dom.Element e2 = ( org.w3c.dom.Element ) wornItemNodes.item(0);
org.w3c.dom.NodeList invNodes = e2.getElementsByTagName("Inventory");
if ( invNodes.getLength() < 1 )
wornItems = null;
else
wornItems = new Inventory ( mundo , invNodes.item(0) );
}
//wielding limbs inv: obsolete
/*
org.w3c.dom.NodeList wieldingInvNodes = e.getElementsByTagName ( "WieldingLimbsInventory" );
if ( wieldingInvNodes.getLength() < 1 )
wieldingLimbs = null;
else
{
org.w3c.dom.Element e2 = ( org.w3c.dom.Element ) wieldingInvNodes.item(0);
org.w3c.dom.NodeList invNodes = e2.getElementsByTagName("Inventory");
if ( invNodes.getLength() < 1 )
wieldingLimbs = null;
else
{
wieldingLimbs = new Inventory ( mundo , invNodes.item(0) );
Debug.println(this + "Wielding Limbs Inventory: " + wieldingLimbs);
}
}
*/
wieldingLimbs = null;
//spell list
org.w3c.dom.NodeList spellNodes = e.getElementsByTagName("SpellList");
if ( spellNodes.getLength() < 1 )
spellRefs = null;
else
spellRefs = new SpellList ( mundo , spellNodes.item(0) );
//parts inv
org.w3c.dom.NodeList partsInvNodes = e.getElementsByTagName ( "Parts" );
if ( partsInvNodes.getLength() < 1 )
partsInventory = null;
else
{
org.w3c.dom.Element e2 = ( org.w3c.dom.Element ) partsInvNodes.item(0);
org.w3c.dom.NodeList invNodes = e2.getElementsByTagName("Inventory");
if ( invNodes.getLength() < 1 )
partsInventory = null;
else
{
partsInventory = new Inventory ( mundo , invNodes.item(0) );
Debug.println(this + "Parts Inventory: " + wieldingLimbs);
}
}
//caracteristicas (traits): not at the moment.
//or... yeWwwW!
org.w3c.dom.NodeList traitNodes = e.getElementsByTagName ( "Traits" );
if ( traitNodes.getLength() > 0 )
{
try
{
caracteristicas = new Traits ( mundo , traitNodes.item(0) );
}
catch ( XMLtoWorldException ex )
{
throw ( new XMLtoWorldException ( "Exception at Traits node: " + ex.getMessage() ) );
}
}
//if traits weren't specified, init them to default
if ( caracteristicas == null ) caracteristicas = new Traits();
//limit inventory according to strength
long strength = Math.max( caracteristicas.getSkill("FUE") , caracteristicas.getSkill("STR") );
try
{
inventory.setVolumeLimit((int)(2000+10*strength));
inventory.setWeightLimit((int)(2000+10*strength));
}
catch ( Exception exc )
{
System.err.println("[Warning] Mobile " + this.getUniqueName() + " carrying items too heavy or big for its strength of " + strength);
}
//relationship-states: not at the moment
//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);
}
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() ) );
}
}
//load PSI specifications
loadPSISpecs ( mundo , e );
//FINALLY... type-specifics!!
if ( mobtype.equalsIgnoreCase("daedra") )
{
//((Daedra)this).readDaedraSpecifics ( mundo , e );
;
}
//poner bien la id
if ( getID() < 10000000 )
idnumber += 20000000; //prefijo de bicho
//correcci�n inventarios paralelos (copiada del otro, �dobla innecesariamente?)
if ( wieldingLimbs != null && wieldedWeapons == null )
{
wieldedWeapons = new Inventory(10000,10000,wieldingLimbs.size());
wieldedWeapons.incrementSize(wieldingLimbs.size());
}
if ( wornItems == null )
{
wornItems = new Inventory(10000,10000);
}
//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.write("BeanShell error on initting mobile " + this + ": error was " + te);
mundo.writeError(ExceptionPrinter.getExceptionReport(te));
}
}
}
/**
* 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 createReferencesInInventoryItems()
{
for ( int i = 0 ; i < inventory.size() ; i++ )
{
((Item)inventory.get(i)).addMobileReference(this);
}
}
public int getID ( )
{
return idnumber;
}
/**
* @deprecated Use {@link #getUniqueName()} instead
*/
public String getTitle ( )
{
return getUniqueName();
}
public String getUniqueName ( )
{
return title;
}
public String getDescription ( long comparand )
{
String desString="";
for ( int i = 0 ; i < descriptionList.length ; i++ )
{
if ( descriptionList[i].matches(comparand) )
desString += descriptionList[i].getText();
}
return desString;
}
public String getDescription ( Entity viewer )
{
String desString="";
for ( int i = 0 ; i < descriptionList.length ; i++ )
{
if ( descriptionList[i].matchesConditions(this,viewer) )
desString += descriptionList[i].getText();
}
return desString;
}
/*
public boolean isInvisible ( int comparand )
{
if ( !properName )
return ( StringMethods.numToks ( constructName(1,comparand) , ' ' ) < 2 );
else
return ( StringMethods.numToks ( constructName(1,comparand) , ' ' ) < 1 );
}
*/
/**
* @deprecated Use {@link #getClient()} instead
*/
public InputOutputClient getIO ( )
{
return getClient();
}
public InputOutputClient getClient ( )
{
return io;
}
public boolean isInvisible ( Entity viewer )
{
return !( getSingName(viewer).length() > 0 );
/*
if ( !properName )
return ( StringMethods.numToks ( constructName(1,viewer) , ' ' ) < 2 );
else
return ( StringMethods.numToks ( constructName(1,viewer) , ' ' ) < 1 );
*/
}
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;
}
/**
* @deprecated Use getName ( boolean s_p , Entity viewer ) instead.
* @param s_p
* @return
*/
public String getName ( boolean s_p )
{
Description[] theList;
if ( s_p ) theList = singNames;
else theList = plurNames;
String desString="";
for ( int i = 0 ; i < theList.length ; i++ )
{
if ( theList[i].matchesConditions(this,(Entity)null) ) //oh wow, casting null
desString += theList[i].getText();
}
return desString;
}
public String getSingName ( int comparand )
{
return getName ( true , comparand );
}
public String getPlurName ( int comparand )
{
return getName ( false , comparand );
}
public String getSingName()
{
return getName ( true );
}
public String getPlurName()
{
return getName ( false );
}
//coge de comparando el estado del bicho
public String constructName ( int nItems )
{
return constructName ( nItems , getState() );
}
//devuelve "una espada", "dos hachas", etc.
public String constructName ( int nItems , int comparand )
{
boolean properName = this.properName;
if ( nItems == 1 )
{
String baseName = getSingName( comparand );
if ( baseName.startsWith("P$") )
{
properName = true;
baseName = baseName.substring(2);
}
if ( properName )
return baseName;
else if ( gender )
return ( "un " + baseName );
else
return ( "una " + baseName );
}
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 ) );
}
}
public String constructName2 ( int nItems )
{
return constructName2 ( nItems , getState() );
}
//devuelve "la espada", "dos hachas", etc.
public String constructName2 ( int nItems , int comparand )
{
boolean properName = this.properName;
if ( nItems == 1 )
{
String baseName = getSingName( comparand );
if ( baseName.startsWith("$") )
{
properName = true;
baseName = baseName.substring(1);
}
if ( properName )
return baseName;
if ( gender )
return ( "el " + baseName );
else
return ( "la " + baseName );
}
else
{
return ( nItems + " " + getPlurName( comparand ) );
}
}
/**
* 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;
}
/*
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;
}
*/
/*
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);
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;
}
*/
/*
* Returns the most specific name with which we can refer to an object in a command.
* Useful for pronoun substitution.
*/
public String getBestReferenceName ( boolean pluralOrSingular )
{
List theList;
if ( pluralOrSingular ) //true? plural
theList = respondToPlur;
else
theList = respondToSing;
if ( theList.size() == 0 ) return null;
String tmp = (String) theList.get(0);
return ( Character.toLowerCase( tmp.charAt(0) ) ) + tmp.substring(1);
}
/**
* 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;
return matchesCommand ( commandArgs , listaDeInteres , mundo.getCommandMatchingMode() );
}
public String getInstanceOf ( )
{
return isInstanceOf;
}
/**
* Returns true if viewer cannot distinguish this mobile from other.
* This is used to collapse descriptions, e.g. to show "two dogs" rather than "a dog and a dog".
* @param other The mobile 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 mobiles are indistinguishable.
* @return
*/
public boolean isIndistinguishableFrom ( Mobile 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 );
}
public boolean isSame ( Mobile other )
{
//old
/*
return (
( idnumber == other.getID() )
|| ( idnumber == other.getInstanceOf () )
|| ( isInstanceOf == other.getID () )
|| ( isInstanceOf == other.getInstanceOf () && isInstanceOf != 0 ) );
*/
//new
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;
}
/*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 ) 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;
}
public long getSkill ( String s )
{
if ( caracteristicas == null )
caracteristicas = new Traits();
return caracteristicas.getSkill(s);
}
public int getStat ( String s )
{
//ej. getStat("FUE") , getStat("INT")
int value = 0;
if ( caracteristicas != null )
value = (int)caracteristicas.getStat(s);
if ( value == 0 )
return 12;
else
return value;
//this is the correct one!
//return caracteristicas.getStat(s);
//this is temporal garbage, remove it!
//return 12;
}
public Weapon getCurrentWeapon()
{
return (Weapon) mundo.getItem(getPropertyValueAsInteger("usingWeapon"));
}
public void setCurrentWeapon( Weapon w )
{
setProperty("usingWeapon",w.getID());
}
public Spell getCurrentSpell()
{
return (Spell) mundo.getSpell(getPropertyValueAsInteger("usingSpell"));
}
public void setCurrentSpell( Spell s )
{
setProperty("usingSpell",s.getID());
}
public void setRoom ( Room nuevaHabitacion )
{
habitacionAnterior = habitacionActual;
if ( habitacionActual != null )
{
habitacionActual.removeMob(this);
habitacionActual = nuevaHabitacion;
if ( habitacionActual != null )
habitacionActual.addMob(this);
}
else
{
habitacionActual = nuevaHabitacion;
if ( habitacionActual != null && !habitacionActual.hasMobile(this) )
habitacionActual.addMob(this);
}
}
public void setInventory ( Inventory inv )
{
inventory = inv;
}
public Room getRoom ( )
{
return habitacionActual;
}
public Room getLastRoom ( )
{
return habitacionAnterior;
}
//begin
//relationship-related functions
/*
Las relaciones con estado entre m�viles y otros objetos (o tal vez, en el
futuro, entre entidades en general, si hiciera falta?) resultan �tiles.
Gracias a ellas, un jugador puede, por ejemplo, "recordar" lo que hab�a
en una habitaci�n: al mirarla se establece un estado 1 (por ejemplo) en su
relaci�n con esa entidad habitaci�n, de tal modo que cuando vuelve a ella
ya no tiene que "buscar" algo sino que lo ve directamente, por ejemplo.
No para cambios objetivos en la habitaci�n que ver�a cualquiera (como el
que se abra una puerta)
*/
public org.w3c.dom.Node getRelationshipListXMLRepresentation ( org.w3c.dom.Document doc )
{
org.w3c.dom.Element e = doc.createElement ( "RelationshipList" );
for ( int i = 0 ; i < relationships.size() ; i++ )
{
org.w3c.dom.Element eRel = doc.createElement ( "Relationship" );
org.w3c.dom.Element ePropList = doc.createElement ( "PropertyList" );
Entity objetivo = (Entity) relationships.elementAt(i);
eRel.setAttribute ( "id" , String.valueOf( objetivo.getID() ) );
List propertiesList = (List) relationship_properties.elementAt(i);
for ( int j = 0 ; j < propertiesList.size() ; j++ )
{
PropertyEntry pe = (PropertyEntry) propertiesList.get(j);
org.w3c.dom.Node nodoProp = pe.getXMLRepresentation(doc);
ePropList.appendChild (nodoProp);
}
eRel.appendChild ( ePropList );
e.appendChild ( eRel );
}
return e;
}
//pasar directamente como parametro el nodo del Mobile.
//esto es para carga DIFERIDA!! Son entitys, no sabemos si de las que se cargan antes o despu�s.
public void readRelationshipListFromXML ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException
{
if ( ! ( n instanceof org.w3c.dom.Element ) ) throw ( new XMLtoWorldException ( "Mobile node not Element" ) );
org.w3c.dom.Element e = ( org.w3c.dom.Element) n;
org.w3c.dom.NodeList nl = e.getElementsByTagName("RelationshipList");
if ( nl.getLength() < 1 ) ; //no hacemos nada porque relationships y cia ya son un new Vector()
else
{
org.w3c.dom.Element relationshipListNode = (org.w3c.dom.Element) nl.item(0);
org.w3c.dom.NodeList relaciones = relationshipListNode.getElementsByTagName("Relationship");
for ( int i = 0 ; i < relaciones.getLength() ; i++ )
{
org.w3c.dom.Element thisRelationshipNode = (org.w3c.dom.Element)relaciones.item(i);
//get relationship target (id)
if ( ! (thisRelationshipNode.hasAttribute("id")) )
throw ( new XMLtoWorldException ( "Relationship node lacking attribute id" ) );
relationships.add ( mundo.getObject ( thisRelationshipNode.getAttribute("id") ) );
//get relationship property list
org.w3c.dom.NodeList pListNodes = thisRelationshipNode.getElementsByTagName("PropertyList");
List propertiesList;
if ( pListNodes.getLength() < 0 )
propertiesList = new ArrayList();
else
{
propertiesList = new ArrayList();
org.w3c.dom.Element elementoPropertyList = (org.w3c.dom.Element) pListNodes.item(0);
org.w3c.dom.NodeList listaPropertyEntries = elementoPropertyList.getElementsByTagName("PropertyEntry");
for ( int k = 0 ; k < listaPropertyEntries.getLength() ; k++ )
{
org.w3c.dom.Node nod = listaPropertyEntries.item(k);
PropertyEntry pe = new PropertyEntry ( mundo , nod );
propertiesList.add(pe);
}
}
relationship_properties.add ( propertiesList );
}
} //end else if length > 0 [has relationships]
} //end method
/**Relationship functions yo-yo'd up to Entity*/
/*
public int getRelationshipState ( Entity e )
{
return getRelationshipPropertyValueAsInteger ( e , "state" );
}
public int getRelationshipPropertyValueAsInteger ( Entity e , String propertyName )
{
int lim = relationships.size();
for ( int k = 0 ; k < lim ; k++ )
{
if ( relationships.elementAt(k).equals(e) )
{
//lista de propiedades de la relaci�n
List propertiesList = (List) relationship_properties.elementAt(k);
for ( int i = 0 ; i < propertiesList.size() ; i++ )
{
PropertyEntry pe = (PropertyEntry) propertiesList.get(i);
if ( pe.getName().equalsIgnoreCase(propertyName) )
return pe.getValueAsInteger();
}
}
}
return 0; //by default
}
public boolean getRelationshipPropertyValueAsBoolean ( Entity e , String propertyName )
{
int lim = relationships.size();
for ( int k = 0 ; k < lim ; k++ )
{
if ( relationships.elementAt(k).equals(e) )
{
//lista de propiedades de la relaci�n
List propertiesList = (List) relationship_properties.elementAt(k);
for ( int i = 0 ; i < propertiesList.size() ; i++ )
{
PropertyEntry pe = (PropertyEntry) propertiesList.get(i);
if ( pe.getName().equalsIgnoreCase(propertyName) )
return pe.getValueAsBoolean();
}
}
}
return false; //by default
}
*/
/*
public void setRelationshipProperty ( Entity e , String propertyName , String propertyValue )
{
int lim = relationships.size();
for ( int k = 0 ; k < lim ; k++ )
{
if ( relationships.elementAt(k).equals(e) )
{
List propertiesList = (List) relationship_properties.elementAt(k);
for ( int i = 0 ; i < propertiesList.size() ; i++ )
{
PropertyEntry pe = (PropertyEntry) propertiesList.get(i);
if ( pe.getName().equalsIgnoreCase(propertyName) )
{
pe.setValue ( propertyValue );
return;
}
}
//property not found, add to list
propertiesList.add ( new PropertyEntry ( propertyName , propertyValue , 0 ) );
return;
}
}
//relationship not found, add to relationships
relationships.addElement ( e );
List nuevaPropEntryList = new ArrayList();
PropertyEntry pe = new PropertyEntry( propertyName , propertyValue , 0 );
nuevaPropEntryList.add(pe);
relationship_properties.addElement(nuevaPropEntryList);
return;
}
*/
/*
public void setRelationshipProperty ( Entity e , String propertyName , int propertyValue )
{
setRelationshipProperty ( e , propertyName , String.valueOf ( propertyValue ) );
}
public void setRelationshipState ( Entity e , int newState )
{
setRelationshipProperty ( e , "state" , newState );
}
*/
//end
//relationship-related functions
//
//
//public Entity getObject ( int objectid )
private void loadPSISpecs ( World mundo , org.w3c.dom.Node n ) throws XMLtoWorldException
{
org.w3c.dom.Element e;
try
{
e = (org.w3c.dom.Element) n;
}
catch ( ClassCastException cce )
{
throw ( new XMLtoWorldException ( "Mobile node not Element" ) );
}
//{e is this mobile's Element}
org.w3c.dom.NodeList convAINodes = e.getElementsByTagName( "ConversationalAI" );
if ( convAINodes.getLength() > 0 )
{
//get the first node labelled <ConversationalAI>, in fact there should be only one
org.w3c.dom.Element convAINode = (org.w3c.dom.Element) convAINodes.item(0);
//now process all mappings
org.w3c.dom.NodeList mappingNodes = convAINode.getElementsByTagName("Mapping");
for ( int i = 0 ; i < mappingNodes.getLength() ; i++ )
{
org.w3c.dom.Element curMappingNode = (org.w3c.dom.Element) mappingNodes.item(i);
if ( !curMappingNode.hasAttribute("command") )
throw ( new XMLtoWorldException ( "Mapping node lacking attribute command" ) );
else
{
//search for description node
org.w3c.dom.NodeList desNodes = curMappingNode.getElementsByTagName("Description");
if ( desNodes.getLength() < 1 )
throw ( new XMLtoWorldException ( "Mapping node lacking Description element" ) );
else
{
//org.w3c.dom.Element curDescriptionNode = (org.w3c.dom.Element) desNodes.item(0);
Description[] answer = Utility.loadDescriptionListFromXML ( mundo , curMappingNode );
if ( answer == null )
continue;
else
{
if ( PSIkeywords == null )
PSIkeywords = new Vector();
if ( PSIanswers == null )
PSIanswers = new Vector();
//init this PSI question-answer pair
PSIkeywords.add ( curMappingNode.getAttribute("command") );
PSIanswers.add ( answer );
Debug.println("Adding answers to " + curMappingNode.getAttribute("command") );
Debug.println("They are for example " + answer[0].getText() );
}
}
}
}
}
else
{
//let the PSI specs be null
return;
}
}
private void loadPSISpecs ( String PSISpecList )
{
int len = StringMethods.numToks(PSISpecList,'\n');
PSIanswers = new Vector();
PSIkeywords = new Vector();
StringTokenizer lineas = new StringTokenizer ( PSISpecList , "\n" );
int nlinea = -1;
while ( lineas.hasMoreTokens() )
{
nlinea++;
String linea = lineas.nextToken();
PSIanswers.addElement( Utility.loadDescriptionListFromString //last token with $
( StringMethods.getTok ( linea , StringMethods.numToks(linea,'$') , '$' ) ) );
PSIkeywords.addElement( StringMethods.getToks( linea , 1 , StringMethods.numToks(linea,'$')-1 , '$' ).trim() );
}
}
public String getPSIAnswer ( String question )
{
if ( PSIanswers == null || PSIanswers.size() == 0 ) return null;
for ( int i = 0 ; i < PSIanswers.size() ; i++ )
{
//Aqu� es donde hay que a�adir el soporte de Regular Expressions.
//En vez de isSubstringOf, matchesRegEx.
//keywords separadas con "$"
StringTokenizer st = new StringTokenizer ( (String)PSIkeywords.elementAt(i) , "$" );
String tok;
while ( st.hasMoreTokens() )
{
tok = st.nextToken();
if ( StringMethods.isSubstringOf ( tok.toLowerCase() , question.toLowerCase() ) )
{
Description[] nuestraRespuesta = (Description[])PSIanswers.elementAt(i);
String stringRespuesta = null;
for ( int j = 0 ; j < nuestraRespuesta.length ; j++ )
{
if ( nuestraRespuesta[j].matches(getState()) )
{
if ( stringRespuesta == null ) stringRespuesta = nuestraRespuesta[j].getText();
else stringRespuesta += nuestraRespuesta[j].getText();
}
}
return stringRespuesta;
}
}
}
return null;
}
/*
Una posible cosa a hacer con respecto a esta funci�n es usar el "escribir" como caso particular
de ella en los Informadores, (if instanceof informador then escribir, p.ej.) y de este modo
cambiar las funciones informAction para que en realidad s�lo hagan a los Mobiles ejecutar
reactToRoomText, y que cada uno lo interprete como pueda.
*/
public void reactToRoomText ( String text )
{
boolean ejecutado = false;
//room text reaction evt
try
{
ejecutado = execCode ( "onRoomText" ,
new Object[]
{
text
}
);
}
catch ( ScriptException te )
{
write(""+te);
writeError(ExceptionPrinter.getExceptionReport(te));
te.printStackTrace();
}
if ( ejecutado ) return;
if ( StringMethods.isSubstringOf ( " dice " , text.toLowerCase() ) )
{
//reaccionar a alguien que dice algo
Debug.println("Full-string: " + text);
Vector sepvector = new Vector();
sepvector.addElement(" te dice "); //n�tese que este token se mira antes.
sepvector.addElement(" dice ");
Vector analisis = StringMethods.tokenizeWithComplexSeparators ( text , sepvector , true );
String elSujeto = ((String)analisis.elementAt(0)).trim();
String resto;
boolean vaPorTi=false;
if ( analisis.size() < 2 )
{
resto = "";
}
else if ( ((String)analisis.elementAt(1)).equals( " te dice " ) )
{
vaPorTi=true;
resto = ((String)analisis.elementAt(2)).trim();
}
else
{
resto = ((String)analisis.elementAt(2)).trim();
}
Debug.println("El sujeto's string: " + elSujeto);
//Debug.println("EELLL SUJETOOO: " + elSujeto);
Mobile elSujetoEnSi=null;
Mobile elObjetoEnSi=null;
Vector patternMatchVectorSing = habitacionActual.mobsInRoom.patternMatch ( elSujeto , false ).toEntityVector(); //en singular
if ( patternMatchVectorSing != null && patternMatchVectorSing.size() > 0 )
{
elSujetoEnSi = (Mobile)patternMatchVectorSing.elementAt(0);
}
else elSujetoEnSi=null;
String loQueDice=null;
//quitar comillas
StringTokenizer st = new StringTokenizer ( resto,"\"",false );
if ( !st.hasMoreTokens() ) return;
loQueDice = st.nextToken();
if ( st.hasMoreTokens() )
{
resto = st.nextToken(); //esto puede ser el objeto.
//por ejemplo, en "juan dice "hola" a pedro"
//primera tokenizaci�n: elSujeto juan, resto "hola" a pedro
//segunda: loQueDice hola, resto a pedro
Debug.println("Resto's string: " + resto);
Vector patternMatchVectorSing2 = habitacionActual.mobsInRoom.patternMatch ( resto , false ).toEntityVector(); //en singular
if ( patternMatchVectorSing2 != null && patternMatchVectorSing2.size() > 0 )
{
elObjetoEnSi = (Mobile)patternMatchVectorSing2.elementAt(0);
}
Debug.println("El objeto: " + elObjetoEnSi);
}
if ( vaPorTi )
{
elObjetoEnSi = this;
}
//quitar comillas
/*
if ( loQueDice.length() < 1 ) return;
if ( loQueDice.charAt(0) == '\"' )
loQueDice = loQueDice.substring(1);
if ( loQueDice.length() < 1 ) return;
if ( loQueDice.charAt(loQueDice.length()-1) == '.' )
loQueDice = loQueDice.substring(0,loQueDice.length()-2);
if ( loQueDice.length() < 1 ) return;
if ( loQueDice.charAt(loQueDice.length()-1) == '\"' )
loQueDice = loQueDice.substring(0,loQueDice.length()-2);
if ( loQueDice.length() < 1 ) return;
*/
try
{
Debug.println("Calling event say with " + elSujetoEnSi + "," + loQueDice);
execCode ( "event_say",
"this: " + getID()
+ "\n" + "speaker_id: " + ((elSujetoEnSi!=null)?String.valueOf(elSujetoEnSi.getID()):null)
+ "\n" + "speaker_name: " + elSujeto
+ "\n" + "sentence: " + loQueDice );
//onSay con par�metro objeto
ejecutado=false;
ejecutado = execCode ( "onSayTo" ,
new Object[]
{
elSujetoEnSi , loQueDice , elObjetoEnSi
}
);
if ( ! ejecutado )
{
//onSay sin par�metro objeto
execCode ( "onSay" ,
new Object[]
{
elSujetoEnSi , loQueDice
}
);
}
}
catch ( EVASemanticException exc )
{
mundo.write(io.getColorCode("error") + "EVASemanticException found at event_say, mob number " + getID() + io.getColorCode("reset") );
}
catch ( ScriptException te )
{
//mundo.write(io.getColorCode("error") + "bsh.TargetError found at event_say, mob number " + getID() + io.getColorCode("reset") );
mundo.writeError(ExceptionPrinter.getExceptionReport(te,"onSay, mobile " + this));
}
String respuesta = getPSIAnswer ( loQueDice );
if ( respuesta != null )
{
say ( respuesta );
}
else
{
respuesta = getPSIAnswer ( "default" );
if ( respuesta != null )
say ( respuesta );
}
}
}
public void say ( String text )
{
if ( text.trim().equals("") ) return;
//habitacionActual.reportActionAuto ( this , null , null , "$1 dice \"" + text + "\".\n" , true );
habitacionActual.reportAction ( this , null , null , mundo.getMessages().getMessage("someone.says.something","$text",text) , mundo.getMessages().getMessage("someone.says.something","$text",text) , mundo.getMessages().getMessage("you.say.something","$text",text) , true );
}
public void say ( String text , String style )
{
if ( text.trim().equals("") ) return;
//habitacionActual.reportActionAuto ( this , null , null , "$1 dice \"" + text + "\".\n" , style , true );
habitacionActual.reportAction ( this , null , null , mundo.getMessages().getMessage("someone.says.something","$text",text) , mundo.getMessages().getMessage("someone.says.something","$text",text) , mundo.getMessages().getMessage("you.say.something","$text",text) , style , true );
}
public void sayTo ( Mobile m , String text )
{
//habitacionActual.reportAction ( this , m , null , "$1 dice \"" + text + "\" a $2.\n" , "$1 te dice \"" + text + "\".\n" , "dices \"" + text + "\" a $2.\n" , true );
habitacionActual.reportAction ( this , m , null , mundo.getMessages().getMessage("someone.tells.someone.something","$text",text) , mundo.getMessages().getMessage("someone.tells.you.something","$text",text) , mundo.getMessages().getMessage("you.tell.someone.something","$text",text) , true );
}
public void sayTo ( Mobile m , String text , String style )
{
//habitacionActual.reportAction ( this , m , null , "$1 dice \"" + text + "\" a $2.\n" , "$1 te dice \"" + text + "\".\n" , "dices \"" + text + "\" a $2.\n" , style , true );
habitacionActual.reportAction ( this , m , null , mundo.getMessages().getMessage("someone.tells.someone.something","$text",text) , mundo.getMessages().getMessage("someone.tells.you.something","$text",text) , mundo.getMessages().getMessage("you.tell.someone.something","$text",text) , style , true );
}
// procesa el comando decir
protected void comandoDecir ( String args )
{
//si hay comillas, distinguimos lo de dentro de lo de fuera
StringTokenizer st = new StringTokenizer ( " " + args , "\"" );
//el espacio a�adido a args en la l�nea enterior es para que el primer token est� siempre fuera
boolean tamosDentro = false;
String dentro="";
String fuera="";
while ( st.hasMoreTokens() )
{
if ( tamosDentro )
dentro+=st.nextToken();
else
fuera+=st.nextToken();
tamosDentro=!tamosDentro;
}
dentro = dentro.trim();
fuera = fuera.trim();
Debug.println("DENTRO:"+dentro);
Debug.println("FUERA:"+fuera);
if ( dentro.equalsIgnoreCase("") ) //no hab�a comillas
{
//interpretaci�n en este caso:
//decir hola a jorge -> hablas a todos
//decir hola -> hablas a todos
//ergo, no tenemos que buscar bichos (de momento)
say ( fuera );
}
else //hab�a comillas
{
//interpretaci�n:
//decir "hola" -> a todos
//decir "hola" a jorge, decir a jorge "hola" -> solo a jorge
//ergo, tenemos que buscar en fuera a ver si hay un bicho y decirle dentro.
MobileList ml = getRoom().getMobiles();
Vector patternMatchVectorSing = ml.patternMatch ( fuera , false ).toEntityVector(); //en singular
Vector patternMatchVectorPlur = ml.patternMatch ( fuera , true ).toEntityVector(); //en plural
if ( patternMatchVectorSing.size() > 0 )
{
//decimos algo a un bicho
sayTo ( ((Mobile)patternMatchVectorSing.elementAt(0)) , dentro );
}
else if ( patternMatchVectorPlur.size() > 0 )
{
//no era en singular, probamos en plural.
Mobile ourMob;
for ( int i = 0 ; i < patternMatchVectorPlur.size() ; i++ )
{
ourMob = (Mobile)patternMatchVectorPlur.elementAt(i);
sayTo ( ourMob , dentro );
}
}
else //no hay bicho que valga
{
say ( dentro );
}
}
}
private void defaultShowInventory( )
{
if ( inventory != null )
{
String str = inventory.toString(this,mundo);
if ( str.equalsIgnoreCase(mundo.getMessages().getMessage("nothing")+".") ) write( io.getColorCode("information") + mundo.getMessages().getMessage("you.have.nothing",new Object[]{this}) + io.getColorCode("reset") );
else
{
write( io.getColorCode("information") +
/*"Tienes "*/ mundo.getMessages().getMessage("you.have.items","$inventory",str.substring(0,str.length()-1),new Object[]{this})
//+ str
+ io.getColorCode("reset") );
Inventory limbs = getFlattenedPartsInventory();
//cosas que blandes
Inventory wieldedWeapons = getWieldedWeapons(); //this shadows the homonymous attribute
Set alreadyShown = new HashSet(); //para prevenir que armas se muestren dos veces si se llevan en varios miembros (is this really necessary?)
if ( wieldedWeapons != null )
for ( int i = 0 ; i < wieldedWeapons.size() ; i++ )
{
if ( wieldedWeapons.elementAt(i) != null )
{
Item arma = wieldedWeapons.elementAt(i);
if ( alreadyShown.contains(arma) ) continue; //this wielded item was already shown (worn in several limbs)
else alreadyShown.add(arma);
Vector miembrosOcupados = new Vector();
//buscar miembros que blanden el arma
for ( int j = 0 ; j < limbs.size() ; j++ )
{
Item miembro = limbs.elementAt(j);
if ( miembro.getRelationshipPropertyValueAsBoolean(arma,"wields") )
{
miembrosOcupados.add(miembro);
// write( io.getColorCode("information") +
//"Blandes " + arma.constructName2OneItem(this) + " en " + miembro.constructName2OneItem(this) + ".\n"
// mundo.getMessages().getMessage("you.are.wielding.item","$item",arma.constructName2OneItem(this),"$limbs",miembro.constructName2OneItem(this),new Object[]{this,arma,miembro})
// + io.getColorCode("reset") );
//break;
}
}
//output
String toOutput="";
for ( int j = 0 ; j < miembrosOcupados.size() ; j++ )
{
Item limb = (Item)miembrosOcupados.get(j);
if ( j == 0 )
toOutput += limb.getOutputNameThe(this);
else if ( j > 0 && j == miembrosOcupados.size() - 1 )
toOutput += " y " + limb.getOutputNameThe(this);
else
toOutput += ", " + limb.getOutputNameThe(this);
}
write( io.getColorCode("information") +
mundo.getMessages().getMessage("you.are.wielding.item","$item",arma.getOutputNameThe(this),"$limbs",toOutput,new Object[]{this,arma,toOutput})
+ io.getColorCode("reset") );
//old:
/*
write( io.getColorCode("information") +
//"Blandes " + arma.constructName2OneItem(this) + " en " + miembro.constructName2OneItem(this) + ".\n"
mundo.getMessages().getMessage("you.are.wielding.item","$item",arma.constructName2OneItem(this),"$limbs",miembro.constructName2OneItem(this),new Object[]{this,arma,miembro})
+ io.getColorCode("reset") );
//break;
*/
}
}
//cosas que llevas puestas
Inventory wornItems = getWornItems(); //this shadows the homonymous attribute
alreadyShown = new HashSet(); //para prevenir que prendas se muestren dos veces si se llevan en varios miembros
if ( wornItems != null )
for ( int i = 0 ; i < wornItems.size() ; i++ )
{
if ( wornItems.elementAt(i) != null )
{
Item vestido = wornItems.elementAt(i);
if ( alreadyShown.contains(vestido) ) continue; //this worn item was already shown (worn in several limbs)
else alreadyShown.add(vestido);
Vector miembrosOcupados = new Vector();
//buscar miembros que visten el wearable
for ( int j = 0 ; j < limbs.size() ; j++ )
{
Item miembro = limbs.elementAt(j);
if ( miembro.getRelationshipPropertyValueAsBoolean(vestido,"wears") )
{
miembrosOcupados.add(miembro);
}
}
//output
String toOutput="";
for ( int j = 0 ; j < miembrosOcupados.size() ; j++ )
{
Item limb = (Item)miembrosOcupados.get(j);
if ( j == 0 )
toOutput += limb.getOutputNameThe(this);
else if ( j > 0 && j == miembrosOcupados.size() - 1 )
toOutput += " y " + limb.getOutputNameThe(this);
else
toOutput += ", " + limb.getOutputNameThe(this);
}
write( io.getColorCode("information") +
//"Llevas " + vestido.constructName2OneItem(this) + " en " + toOutput + ".\n"
lenguaje.correctMorphology(
mundo.getMessages().getMessage("you.are.wearing.item","$item",vestido.getOutputNameThe(this),"$limbs",toOutput,new Object[]{this,vestido,toOutput})
)
+ "\n" + io.getColorCode("reset") );
}
}
}
}
else write( io.getColorCode("information") + mundo.getMessages().getMessage("you.have.nothing",new Object[]{this}) + io.getColorCode("reset") );
}
public void showInventory()
{
//ejecutar descripci�n (pesa poquito, etc. etc.)
boolean execced = false;
try
{
execced = this.execCode("showInventory",new Object[] {} );
}
catch ( ScriptException te )
{
write( io.getColorCode("error") + "bsh.EvalError found at showInventory() , mobile " + this + io.getColorCode("reset") + "\n" );
}
if ( !execced )
{
defaultShowInventory();
}
}
/**
* @deprecated Use {@link #write(String)} instead
*/
public void escribir ( String s )
{
write(s);
}
public void write ( String s )
{
//Escribir no hace nada para los bichos que no sean Informadores.
//Los que s� lo sean ya lo overrridear�n.
//Lo ponemos como m�todo de conveniencia, para poder llamarlo, por ejemplo,
//cuando se mueva cualquier bicho; pero que s�lo el jugador informe de ello.
;
}
/**
* @deprecated Use {@link #writeAction(String)} instead
*/
public void escribirAccion ( String s )
{
writeAction(s);
}
public void writeWithTemplate ( String colorTemplate , String s )
{
write ( io.getColorCode(colorTemplate) + s + io.getColorCode("reset") );
}
public void writeImportant ( String s )
{
writeWithTemplate("important",s);
}
public void writeError ( String s )
{
writeWithTemplate("error",s);
if ( mundo.isDebugMode() )
{
System.err.print(s);
}
}
public void writeStory ( String s )
{
writeWithTemplate("story",s);
}
public void writeAction ( String s )
{
write( io.getColorCode("action") + s + io.getColorCode("reset") );
}
/**
* @deprecated Use {@link #writeDescription(String)} instead
*/
public void escribirDescripcion ( String s )
{
writeDescription(s);
}
public void writeDescription ( String s )
{
write( io.getColorCode("description") + s + io.getColorCode("reset") );
}
/**
* @deprecated Use {@link #writeDenial(String)} instead
*/
public void escribirNegacion ( String s )
{
writeDenial(s);
}
public void writeInformation ( String s )
{
write( io.getColorCode("information") + s + io.getColorCode("reset") );
}
public void writeDenial ( String s )
{
write( io.getColorCode("denial") + s + io.getColorCode("reset") );
}
protected void escribirErrorNoEntiendo ( )
{
//write( io.getColorCode("denial") + "No entiendo...\n" + io.getColorCode("reset") );
write( io.getColorCode("denial") + mundo.getMessages().getMessage("error.parsing") /*+ "\n"*/ + io.getColorCode("reset") );
}
public boolean makeRandomValidMove ( )
{
int nsal = habitacionActual.getRandomValidExitAsNumber();
if ( nsal < 0 ) return false; //no hay salida v�lida.
if ( nsal < 10 )
{
//Debug.println ( "The movement eez true " + nsal );
return go ( habitacionActual.getExit(true , nsal) );
}
else
{
//Debug.println ( "The movement eez false " + nsal );
return go ( habitacionActual.getExit(false , 10-nsal) );
}
}
//ir a la habitaci�n dada contigua a la actual
public boolean goTo ( int roomid )
{
Debug.println("Called goTo with id: " + roomid);
Path[] std = habitacionActual.getStandardExits();
Path[] nonstd = habitacionActual.getNonStandardExits();
for ( int i = 0 ; i < std.length ; i++ )
{
if ( std[i].getDestinationID() == roomid )
{
if ( go ( habitacionActual.getExit(true , i) ) )
return true;
}
}
for ( int i = 0 ; i < nonstd.length ; i++ )
{
if ( nonstd[i].getDestinationID() == roomid )
{
if ( go ( habitacionActual.getExit( false , i ) ) )
return true;
}
}
return false;
}
public boolean goTo ( Room r )
{
Debug.println("Called goTo with room: " + r);
return goTo ( r.getID() );
}
//tempvars while go state is set
protected Path movingState_Path;
/**Comando actual*/
protected String commandstring;
/**Comando actual*/
protected String command;
/**Comando actual*/
protected String arguments;
/**Cola para los comandos*/
protected Vector commandQueue = new Vector();
/**Variables del parser de strings: zonas de referencia*/
protected Mentions mentions = new Mentions();
/**�Estamos ejecutando un comando forzado?*/
protected boolean forced;
protected String force_string;
/**�Estamos en la segunda oportunidad? (nos hemos improvisado el verbo anterior tras no reconocer el primero)*/
protected boolean secondChance;
/**Flag de control para indicar que tenemos que activar el second-chance al leer de la cola*/
protected boolean nextCommandSecondChance;
protected boolean matchedOneEntity = false;
protected boolean matchedTwoEntities = false;
protected boolean matchedOneEntityPermissive = false;
protected boolean matchedTwoEntitiesPermissive = false;
protected int oneEntityPriority = 0;
Weapon lastAttackWeapon = null;
Mobile lastAttackedEnemy = null;
Weapon lastBlockWeapon = null;
Mobile lastBlockedEnemy = null;
protected Vector finalExecutedCommandLog = new Vector();
private EntityList mobilesCache;
//ir por la salida dada. Legacy.
public boolean go ( Path p ) //throws java.io.IOException
{
Debug.println("EXECCING GO " + p );
if ( !p.isValid() )
{
//si no es un Informador, esto no hace nada.
if ( p.isStandard() ) write( io.getColorCode("denial") +
mundo.getMessages().getMessage("go.noexit",new Object[]{this,p}) //"No parece haber salida en esa direcci�n.\n"
+ io.getColorCode("reset") );
else write( io.getColorCode("denial") + mundo.getMessages().getMessage("go.invalid",new Object[]{this,p}) + io.getColorCode("reset") );
return false;
}
else
{
boolean endfound = false;
Debug.println("EXECCING GO: ENDFOUND INIT");
try
{
endfound = habitacionActual.execCode("onWalkAway" , new Object[] {this,p} );
Debug.println("EXECCING GO: ENDFOUND ASSIGN " + endfound);
}
catch ( ScriptException bshte )
{
//writeError( io.getColorCode("error") + "bsh.TargetError found onExitRoom , room number " + habitacionActual.getID() + ": " + bshte + io.getColorCode("reset") );
//writeError(ExceptionPrinter.getExceptionReport(bshte));
writeError(ExceptionPrinter.getExceptionReport(bshte,"onExitRoom , room " + habitacionActual));
}
if ( !endfound )
{
//sinonimo del anterior
try
{
endfound = habitacionActual.execCode("beforeExit" , new Object[] {this,p} );
Debug.println("EXECCING GO: ENDFOUND ASSIGN " + endfound);
}
catch ( ScriptException bshte )
{
//writeError( io.getColorCode("error") + "bsh.TargetError found onExitRoom , room number " + habitacionActual.getID() + ": " + bshte + io.getColorCode("reset") );
//writeError(ExceptionPrinter.getExceptionReport(bshte));
writeError(ExceptionPrinter.getExceptionReport(bshte,"beforeExit , room " + habitacionActual));
}
}
//<antique>
//int comparand=habitacionActual.getState();
//comparand+=exitn*(2^8); //4-bit exit ID.
//modify comparand more with character state (humor...)
//el comparando es para la descripcion de la salida, asi que la verdad no haria muchafalta meterle la id.
//</antique>
//long comparand = habitacionActual.getExit(isStandard,exitn).getState(); //de momento
//si no es un Informador, esto no hace nada.
if ( !endfound )
{
//show path description
//nay! passed to end of MOVING state, save for closed-path case.
//now set path to describe.
movingState_Path = p;
//escribir( io.getColorCode("action") + habitacionActual.getExit(isStandard,exitn).getDescription(this) + "\n" + io.getColorCode("reset") );
//habitacionActual.getExit(isStandard,exitn)
//use path if open, return false if closed.
if ( p.isOpen() ) //puerta o salida abierta
{
exitname = habitacionActual.getExitName(p);
// en chstate: habitacionActual.informAction(this,null,"$1 se va hacia " + habitacionActual.getExitName(isStandard,exitn) , null , null , false );
p.go(this); //setea estado
Debug.println("Path::go() called");
return true;
}
else //cerrado
{
//moving state will not be set, so we print movement description right now
if ( movingState_Path != null )
write( io.getColorCode("action") + movingState_Path.getDescription(this) + "\n" + io.getColorCode("reset") );
Debug.println("Closed path");
return false; //se devuelve fracaso (el jugador no sale); la descripci�n la dar� la salida en funci�n del estado cerrado.
}
}
else
{
return true; //el c�digo se encarg� de todo.
}
}
}
private static boolean isDecisionState ( int state )
{
return ( state == IDLE || state == MOVING || state == ATTACK_RECOVER ||
state == DAMAGE_RECOVER || state == BLOCK_RECOVER || state == DODGE_RECOVER || state == SURPRISE_RECOVER );
}
/**
* Returns true if this creature is in a state where it can make a decision and execute a command.
* @return
*/
public boolean isInDecisionState()
{
return isDecisionState(getState());
}
public void changeState( World mundo )
{
Debug.println(this + " state " + getState() + "TUL" + this.getPropertyTimeLeft("state"));
//if there is a command enqueued, execute it
if ( isInDecisionState() )
{
try
{
if ( obtainAndExecCommand(mundo) ) return;
}
catch ( Exception e )
{
writeError("I/O Exception on Mobile changeState(). This shouldn't happen. Only players should throw such an exception!");
}
}
//else, the AI acts
switch ( getState() )
{
case IDLE: //IDLE
//if ( ! execCommand ( mundo ) )
// setNewState ( 1 /*IDLE*/, 1 /*penalizacion*/ );
//Debug.println("Bicho's idle state.");
//si tenemos enemigos, combatir como podamos
if ( hasEnemies() )
{
Debug.println("Bicho has enemies.");
//primero vemos si nos estan atacando para poder bloquear
List atacantes = getAttackingEnemies();
Debug.println("Bicho has " + atacantes.size() + " attacking enemies.");
Debug.println("A " + this + " lo atacan " + atacantes);
if ( atacantes.size() == 0 )
{
//no nos atacan.
//primero vemos si algun enemigo huye para perseguirle.
for ( int i = 0 ; i < getEnemies().size() ; i++ )
{
Mobile m = getEnemies().elementAt(i);
if ( habitacionActual.hasMobile ( m ) && m.getState() == MOVING ) //si el enemigo esta alcanzable y se est� yendo
{
int destRoomID = m.getTarget();
//TODO: As of 2009-12-06, we don't pursue enemies by default (libraries will decide to do that).
//if ( goTo ( destRoomID ) ) return;
setNewState(IDLE,1);
return;
}
}
//Ataquemos.
boolean success = attackBestTarget();
Debug.println("It's " + success + " to say that the bicho found targets.");
if ( success ) return;
else
{
boolean weHaveEnemy = false;
for ( int i = 0 ; i < getEnemies().size() ; i++ )
{
//enemigo
Mobile m = getEnemies().elementAt(i);
if ( habitacionActual.hasMobile ( m ) )
{
weHaveEnemy = true;
break;
}
}
if ( !weHaveEnemy ) setNewState(IDLE,1); //we shrug. our enemy is not here.
//seguramente la cagamos por no tener arma blandida
Weapon w = bestNonWieldedWeapon( 5 /*inteligencia here*/ );
Debug.println("Best non-wielded weapon set to " + w );
if ( w != null )
{
boolean success2 = doWield ( w , true );
Debug.println("Weapon wield success " + success2);
if ( success2 )
setNewState(IDLE,5); //wielding time: 5 units
else
setNewState(IDLE,1); //we shrug. we don't seem to be able to attack.
return;
}
}
}
else
{
//nos atacan. Bloqueemos o esquivemos.
//de momento usamos un algoritmo random...
//refinar esto.
int aleat = getRandom().nextInt();
boolean success = blockBestTarget();
if ( !success ) //no era posible bloquear
//aqui se puede crear una funcion similar dodgeBestTarget() y si no atacar,
//y a estas funciones se le puede pasar parametro "risk" o "tolerance"
dodge ( (Mobile)atacantes.get(0) );
}
}
else //no enemies
{
setNewState(1 /*IDLE*/,2); //fixes regression bug (enemies wouldn't attack you).
}
break;
case MOVING: //GO
//escribir exit-description
if ( movingState_Path != null )
write( io.getColorCode("action") + movingState_Path.getDescription(this) + "\n" + io.getColorCode("reset") );
//has dejado la habitacion en que estabas (habitacionActual)
//-> ejecutar eventos onExitRoom
try
{
habitacionActual.execCode("event_exitroom","this: " + habitacionActual.getID() + "\n" + "player: " + getID() + "\n" + "dest: " + getTarget() );
habitacionActual.execCode("onExitRoom" , new Object[] {this} );
}
catch ( EVASemanticException exc )
{
write( io.getColorCode("error") + "EVASemanticException found at event_exitroom , room number " + habitacionActual.getID() + io.getColorCode("reset") );
}
catch ( ScriptException bshte )
{
//writeError( io.getColorCode("error") + "bsh.TargetError found onExitRoom , room number " + habitacionActual.getID() + ": " + bshte + io.getColorCode("reset") );
//writeError(ExceptionPrinter.getExceptionReport(bshte));
writeError(ExceptionPrinter.getExceptionReport(bshte,"onExitRoom , room " + habitacionActual));
}
habitacionActual.reportAction(this,null,"$1 se va hacia " + exitname + ".\n" , null , null , false );
setRoom ( mundo.getRoom(getTarget()) );
habitacionActual.reportAction(this,null,"$1 llega desde " + Path.invert(exitname) + ".\n" , null , null , false );
//Chequeo de cruces con enemigos.
//Si hay un enemigo haciendo el camino opuesto al nuestro,
//lo sorprendemos evitando su movimiento.
Room destino = mundo.getRoom(getTarget());
MobileList ml = destino.getMobiles();
for ( int i = 0 ; i < ml.size() ; i++ )
{
Mobile current = (Mobile) ml.get(i);
if ( this.hasEnemy(current) || current.hasEnemy(this) )
{
if ( current.getState() == Mobile.MOVING && mundo.getRoom(current.getTarget()) == this.getRoom() )
{
//this stuns current.
current.setNewState(Mobile.SURPRISE_RECOVER,10);
current.write("Ibas a dirigirte hacia " + current.exitname + "; pero te ves sorprendido por la aparici�n de " + this.constructName2OneItem(current) + ", que te bloquea el paso.\n");
this.write("Has sorprendido a " + current.constructName2OneItem(this) + ", que parec�a querer dirigirse hacia " + current.exitname + ".\n");
}
}
}
//has entrado en nueva habitacion (habitacionActual)
//-> ejecutar eventos onEnterRoom
try
{
habitacionActual.execCode("event_enterroom","this: " + habitacionActual.getID() + "\n" + "player: " + getID() + "\n" + "orig: " + habitacionAnterior );
habitacionActual.execCode("onEnterRoom" , new Object[] {this} );
}
catch ( EVASemanticException exc )
{
write( io.getColorCode("error") + "EVASemanticException found at event_enterroom , room number " + habitacionActual.getID() + io.getColorCode("reset") );
}
catch ( ScriptException bshte )
{
//write( io.getColorCode("error") + "bsh.TargetError found onEnterRoom , room number " + habitacionActual.getID() + ": " + bshte + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(bshte,"onEnterRoom, room " + habitacionActual));
}
//-> si hay Mobiles, pueden reaccionar tambi�n a que entres (onEnterRoom de Mobile)
MobileList mlist = habitacionActual.getMobiles(); //note that this includes itself!
if ( mlist != null )
{
for ( int i = 0 ; i < mlist.size() ; i++ )
{
Mobile bichoActual = mlist.elementAt(i);
try
{
//bichoActual.execCode("event_enterroom","this: " + habitacionActual.getID() + "\n" + "player: " + getID() + "\n" + "orig: " + habitacionAnterior );
boolean ejecutado = bichoActual.execCode("onEnterRoom" , new Object[] {this} );
if ( ejecutado ) return;
}
catch ( ScriptException bshte )
{
//write( io.getColorCode("error") + "bsh.TargetError found onEnterRoom , mobile number " + bichoActual.getID() + ": " + bshte + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(bshte,"onEnterRoom, mobile " + bichoActual));
}
}
}
//show_room ( mundo ); <- players only
setNewState ( 1 /*IDLE*/, 0 );
break;
case ATTACKING:
manageEndOfAttackState();
break;
case CASTING:
Debug.println("Calling manageEndOfCastState()");
manageEndOfCastState();
break;
case ATTACK_RECOVER:
write("Mobile's attack-recover time is over.");
setNewState ( IDLE , 0 );
break;
case DAMAGE_RECOVER:
write("Mobile's damage-recover time is over.");
setNewState ( IDLE , 0 );
break;
case BLOCK_RECOVER:
write("Mobile's block-recover time is over.");
setNewState ( IDLE , 0 );
break;
case DODGE_RECOVER:
write("Mobile's dodge-recover time is over.");
setNewState ( IDLE , 0 );
break;
case BLOCKING:
write("");
setNewState ( READY_TO_BLOCK , 0 );
break;
case READY_TO_BLOCK:
//hold on that state
setNewState ( READY_TO_BLOCK , 0 );
break;
case DODGING:
write("");
setNewState ( READY_TO_DODGE , 0 );
break;
case READY_TO_DODGE:
//hold on that state
setNewState ( READY_TO_DODGE , 0 );
break;
case DYING:
//die
die();
break;
case DEAD:
//hold on that state
setNewState ( DEAD , 5 );
break;
}
//this is 4 the players
//if ( ! execCommand ( mundo ) )
// setNewState ( 1 /*IDLE*/, 1 /*penalizacion*/ );
}
public void manageEndOfAttackState()
{
//llevar a cabo el ataque
//buscar entre los bichos enemigos al que estamos atacando
Mobile objetivo = null;
/*
for ( int i = 0 ; i < getEnemies().size() ; i++ )
{
if ( getEnemies().elementAt(i).getID() == getTarget() )
{
objetivo = getEnemies().elementAt(i);
break;
}
}
*/
//as of 2013-02-28, this method doesn't require that the target is an enemy.
//we are managing an attack that has started, so such checks should have been made when the attack was started, if relevant.
//sometimes they might not even be relevant, if the game programmers launch a single attack (which doesn't create an enmity) from code.
objetivo = mundo.getMobile( getTarget() );
if ( objetivo == null )
{
//An attack has been launched on a Mobile that does not exist in the world - this is either a world programmer error, or an internal error.
mundo.writeError( "Error: " + this + " was attacking, but has no target to attack - attack() method invoked with invalid arguments?\n" );
}
if ( !objetivo.getRoom().equals(this.getRoom()) )
{
//The attacked Mobile exists, but is not present in this room. This may be because it moved or because it's dead (and has been moved to Limbo).
if ( objetivo.getState() == Mobile.DEAD )
{
//The attacked Mobile isn't here because he's dead. This can happen e.g. because two opponents
//were attacking him, the first attack killed him and the second attack (this one) lands when
//he's already dead.
habitacionActual.reportAction(this, null, null,
mundo.getMessages().getMessage("someone.attacks.dead",new Object[]{this} ) ,
mundo.getMessages().getMessage("someone.attacks.you.dead",new Object[]{this} ) ,
mundo.getMessages().getMessage("you.attack.dead",new Object[]{this} ) ,
true);
}
else
{
//The attacked Mobile isn't here due to another reason (e.g. fleed like a chicken).
habitacionActual.reportAction(this, null, null,
//"$1 interrumpe su ataque ante la ausencia de su contrincante.\n",
//"$1 vacila ante tu ausencia.\n",
//"Te dispon�as a atacar; pero vacilas ante la ausencia de tu enemigo.\n",
mundo.getMessages().getMessage("someone.attacks.absent",new Object[]{this} ) ,
mundo.getMessages().getMessage("someone.attacks.you.absent",new Object[]{this} ) ,
mundo.getMessages().getMessage("you.attack.absent",new Object[]{this} ) ,
true);
}
setNewState ( IDLE , 1 );
return;
}
if ( objetivo.getState() != READY_TO_BLOCK /* && objetivo.getState() != BLOCKING */
&& objetivo.getState() != READY_TO_DODGE /* && objetivo.getState() != DODGING */)
{
//ataque no bloqueado
if ( getAttackSuccessFromProbability(getCurrentWeapon()) )
{
//attack successful
//solo hay un caso especial en que no se hace da�o: choque de armas en el aire
if ( objetivo.getState() == ATTACKING && objetivo.getPropertyTimeLeft("state") < 3 )
{
//choque de armas en el aire
//informar de ello
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoChoqueArmas" , new Object[] {this,objetivo} ); if ( !ejec )
ejec = execCode ( "infoChoqueArmas" , new Object[] {objetivo} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoChoqueArmas(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
habitacionActual.reportAction ( this , objetivo , null ,
//"Las armas de $1 y $2 chocan en el aire...\n" ,
//"Tu arma y la de $1 chocan en el aire...\n" ,
//"Tu arma y la de $2 chocan en el aire...\n" ,
mundo.getMessages().getMessage("someone.clashes.someone",new Object[]{this,objetivo} ) ,
mundo.getMessages().getMessage("enemy.clashes.you",new Object[]{this,objetivo} ) ,
mundo.getMessages().getMessage("you.clash.enemy",new Object[]{this,objetivo} ) ,
true );
setNewState ( ATTACK_RECOVER , generateAttackRecoverTime(getCurrentWeapon()) );
objetivo.setNewState ( ATTACK_RECOVER , objetivo.generateAttackRecoverTime(objetivo.getCurrentWeapon()) );
}
else
{
//se hace da�o
Item limbToHit = objetivo.getRandomLimbToHit(); //nullable
int danyo = getCurrentWeapon().dealDamage ( this , objetivo , false , limbToHit );
if ( objetivo.getState() == BLOCKING )
{
//informar de que no le ha dado tiempo a bloquear
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoNoTiempoBloquear" , new Object[] {this,objetivo} ); if ( !ejec )
ejec = execCode ( "infoNoTiempoBloquear" , new Object[] {objetivo} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoNoTiempoBloquear(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
habitacionActual.reportAction ( this , objetivo , null ,
null ,
//"No te da tiempo a bloquear el ataque de $1...\n" ,
//"A $2 no le da tiempo a bloquear tu ataque...\n" ,
mundo.getMessages().getMessage("you.fail.block.time.someone",new Object[]{this,objetivo} ) ,
mundo.getMessages().getMessage("someone.fails.block.time.you",new Object[]{this,objetivo} ) ,
true );
}
if ( objetivo.getState() == DODGING )
{
//informar de que no le ha dado tiempo a esquivar
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoNoTiempoEsquivar" , new Object[] {this,objetivo} ); if ( !ejec )
ejec = execCode ( "infoNoTiempoEsquivar" , new Object[] {objetivo} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoNoTiempoEsquivar(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
habitacionActual.reportAction ( this , objetivo , null ,
null ,
//"No te da tiempo a esquivar el ataque de $1...\n" ,
//"A $2 no le da tiempo a esquivar tu ataque...\n" ,
mundo.getMessages().getMessage("you.fail.dodge.time.someone",new Object[]{this,objetivo} ) ,
mundo.getMessages().getMessage("someone.fails.dodge.time.you",new Object[]{this,objetivo} ) ,
true );
}
if ( danyo > 0 )
{
//informar de que acierta
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoAcierto" , new Object[] {this,objetivo,new Integer(danyo)} ); if ( !ejec )
ejec = execCode ( "infoAcierto" , new Object[] {objetivo,new Integer(danyo)} ); if ( !ejec )
ejec = getCurrentWeapon().execCode ( "infoOnHit" , new Object[] {this,objetivo,new Integer(danyo)} ); if ( !ejec )
ejec = execCode ( "infoOnHit" , new Object[] {objetivo,new Integer(danyo)} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoAcierto(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
if ( numeric_damage )
{
habitacionActual.reportAction ( this , objetivo ,
mundo.getMessages().getMessage("someone.hits.someone.numeric","$weapon",getCurrentWeapon().getOutputNameThe(),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("enemy.hits.you.numeric","$weapon",getCurrentWeapon().getOutputNameThe(),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("you.hit.enemy.numeric","$weapon",getCurrentWeapon().getOutputNameThe(),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
//"$1 acierta a $2 con " + getCurrentWeapon().constructName2OneItem() + " infligi�ndole " + danyo + " puntos de da�o...\n" ,
//"$1 te acierta con " + getCurrentWeapon().constructName2OneItem(objetivo) + " infligi�ndote " + danyo + " puntos de da�o...\n" ,
//"Aciertas a $2 con " + getCurrentWeapon().constructName2OneItem(this) + " infligi�ndole " + danyo + " puntos de da�o...\n" ,
true );
}
else
{
habitacionActual.reportAction ( this , objetivo ,
mundo.getMessages().getMessage("someone.hits.someone","$weapon",getCurrentWeapon().getOutputNameThe(),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("enemy.hits.you","$weapon",getCurrentWeapon().getOutputNameThe(),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("you.hit.enemy","$weapon",getCurrentWeapon().getOutputNameThe(),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
//"$1 acierta a $2 con " + getCurrentWeapon().constructName2OneItem() + " infligi�ndole " + objetivo.estimateDamage(danyo) + "...\n" ,
//"$1 te acierta con " + getCurrentWeapon().constructName2OneItem(objetivo) + " infligi�ndote " + objetivo.estimateDamage(danyo) + "...\n" ,
//"Aciertas a $2 con " + getCurrentWeapon().constructName2OneItem(this) + " infligi�ndole " + objetivo.estimateDamage(danyo) + "...\n" ,
true );
habitacionActual.reportActionAuto ( objetivo , null , null , "$1 " + objetivo.estimateStatus() + ".\n" , true );
}
}
}
else
{
//informar de que acierta
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoAcierto" , new Object[] {this,objetivo,new Integer(danyo)} ); if ( !ejec )
ejec = execCode ( "infoAcierto" , new Object[] {objetivo,new Integer(danyo)} ); if (!ejec)
ejec = getCurrentWeapon().execCode ( "infoOnHit" , new Object[] {this,objetivo,new Integer(danyo)} ); if ( !ejec )
ejec = execCode ( "infoOnHit" , new Object[] {objetivo,new Integer(danyo)} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoAcierto(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
habitacionActual.reportAction ( this , objetivo ,
mundo.getMessages().getMessage("someone.hits.someone.nodamage","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("enemy.hits.you.nodamage","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("you.hit.enemy.nodamage","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
//"$1 acierta a $2 con " + getCurrentWeapon().constructName2OneItem() + " pero no le hace da�o...\n" ,
//"$1 te acierta con " + getCurrentWeapon().constructName2OneItem(objetivo) + " pero no te hace da�o...\n" ,
//"Aciertas a $2 con " + getCurrentWeapon().constructName2OneItem(this) + " pero no le haces da�o...\n" ,
true );
}
setNewState ( ATTACK_RECOVER , generateAttackRecoverTime(getCurrentWeapon()) );
if ( objetivo.getState() != DYING )
{
objetivo.interrupt ( "el golpe" );
objetivo.setNewState ( DAMAGE_RECOVER , objetivo.generateRecoverFromUnblockedHitTime() );
}
}
}
else
{
//attack unsuccessful
//informar de que falla
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoFallo" , new Object[] {this,objetivo} ); if ( !ejec )
ejec = execCode ( "infoFallo" , new Object[] {objetivo} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoAcierto(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
habitacionActual.reportAction ( this , objetivo ,
mundo.getMessages().getMessage("someone.misses.someone","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("enemy.misses.you","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("you.miss.enemy","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
//"El ataque de $1 falla a $2.\n" ,
//"El ataque de $1 te falla.\n" ,
//"Tu ataque falla a $2.\n" ,
true );
}
setNewState ( ATTACK_RECOVER , generateAttackRecoverTime(getCurrentWeapon()) );
if ( objetivo.getState() == BLOCKING )
{
//darle la iniciativa
//o bien cambiar esto por, en cambio de estado de blocking
//a ready to block de los mobiles, si ya no les est� atacando
//el objetivo, pasar a idle (m�s realista)
objetivo.setNewState ( IDLE , 1 ); //objetivo has a chance to attack right now
//informar de que tienes la iniciativa
ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoIniciativaTrasBloquear" , new Object[] {this,objetivo} ); if ( !ejec )
ejec = execCode ( "infoIniciativaTrasBloquear" , new Object[] {objetivo} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoAcierto(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
habitacionActual.reportAction ( this , objetivo , null ,
null ,
//"Tienes la iniciativa...\n" ,
//"$2 interrumpe su intento de bloquear...\n" ,
mundo.getMessages().getMessage("someone.fails.blocking.you",new Object[]{this,objetivo} ) ,
mundo.getMessages().getMessage("you.fail.blocking.someone",new Object[]{this,objetivo} ) ,
true );
}
}
if ( objetivo.getState() == DODGING )
{
//idem que el anterior
objetivo.setNewState ( IDLE , 1 ); //chance to attack for objetivo
//informar de que tienes la iniciativa
ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoIniciativaTrasEsquivar" , new Object[] {this,objetivo} ); if ( !ejec )
ejec = execCode ( "infoIniciativaTrasEsquivar" , new Object[] {objetivo} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoAcierto(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
habitacionActual.reportAction ( this , objetivo , null ,
null ,
//"Tienes la iniciativa...\n" ,
//"$2 interrumpe su intento de esquivar...\n" ,
mundo.getMessages().getMessage("someone.fails.dodging.you",new Object[]{this,objetivo} ) ,
mundo.getMessages().getMessage("you.fail.dodging.someone",new Object[]{this,objetivo} ) ,
true );
}
}
} //end attack unsucc
getCurrentWeapon().incrementAttackUsage(this); //weapon skill increases
} //end not blocking, not dodging
else if ( objetivo.getState() == READY_TO_BLOCK )
{
//ataque bloqueado
if ( getAttackSuccessFromProbability(getCurrentWeapon()) )
{
//attack successful
if ( objetivo.getBlockSuccessFromProbability( objetivo.getCurrentWeapon() ) )
{
//attack successful and block successful
Item limbHit = objetivo.getRandomLimbToHit();
int danyo = getCurrentWeapon().dealDamageDefended ( this , objetivo , false , limbHit );
//informar de que bloqueas con �xito
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoBloqueo" , new Object[] {this,objetivo,new Integer(danyo)} ); if ( !ejec )
ejec = execCode ( "infoBloqueo" , new Object[] {objetivo,new Integer(danyo)} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoBloqueo(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
if ( danyo > 0 )
{
if ( numeric_damage )
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.hits.blocked.someone.numeric","$weapon",objetivo.getCurrentWeapon().getOutputNameThe(),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,objetivo.getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("enemy.hits.blocked.you.numeric","$weapon",objetivo.getCurrentWeapon().getOutputNameThe(objetivo),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,objetivo.getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("you.hit.blocked.enemy.numeric","$weapon",objetivo.getCurrentWeapon().getOutputNameThe(this),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,objetivo.getCurrentWeapon(),new Integer(danyo)} ) ,
//"$2 se defiende de $1 con " + objetivo.getCurrentWeapon().constructName2OneItem() + " recibiendo " + danyo + " puntos de da�o...\n" ,
//"Te defiendes de $1 con " + objetivo.getCurrentWeapon().constructName2OneItem(objetivo) + " recibiendo " + danyo + " puntos de da�o...\n" ,
//"$2 se defiende con " + objetivo.getCurrentWeapon().constructName2OneItem(this) + " recibiendo " + danyo + " puntos de da�o...\n" ,
true );
}
else
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.hits.blocked.someone","$weapon",objetivo.getCurrentWeapon().getOutputNameThe(),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,objetivo.getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("enemy.hits.blocked.you","$weapon",objetivo.getCurrentWeapon().getOutputNameThe(objetivo),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,objetivo.getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("you.hit.blocked.enemy","$weapon",objetivo.getCurrentWeapon().getOutputNameThe(this),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,objetivo.getCurrentWeapon(),new Integer(danyo)} ) ,
//"$2 se defiende de $1 con " + objetivo.getCurrentWeapon().constructName2OneItem() + " recibiendo " + objetivo.estimateDamage(danyo) + "...\n" ,
//"Te defiendes de $1 con " + objetivo.getCurrentWeapon().constructName2OneItem(objetivo) + " recibiendo " + objetivo.estimateDamage(danyo) + "...\n" ,
//"$2 se defiende con " + objetivo.getCurrentWeapon().constructName2OneItem(this) + " recibiendo " + objetivo.estimateDamage(danyo) + "...\n" ,
true );
habitacionActual.reportActionAuto ( objetivo , null , null , "$1 " + objetivo.estimateStatus() + ".\n" , true );
}
}
else
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.hits.blocked.someone.nodamage","$weapon",objetivo.getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,objetivo.getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("enemy.hits.blocked.you.nodamage","$weapon",objetivo.getCurrentWeapon().getOutputNameThe(objetivo),new Object[]{this,objetivo,objetivo.getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("you.hit.blocked.enemy.nodamage","$weapon",objetivo.getCurrentWeapon().getOutputNameThe(this),new Object[]{this,objetivo,objetivo.getCurrentWeapon()} ) ,
//"$2 se defiende de $1 con " + objetivo.getCurrentWeapon().constructName2OneItem() + ", desviando el ataque...\n" ,
//"Te defiendes de $1 con " + objetivo.getCurrentWeapon().constructName2OneItem(objetivo) + ", desviando el ataque...\n" ,
//"$2 se defiende con " + objetivo.getCurrentWeapon().constructName2OneItem(this) + ", desviando el ataque...\n" ,
true );
}
}
setNewState ( ATTACK_RECOVER , generateAttackRecoverTime ( getCurrentWeapon() ) );
objetivo.setNewState ( BLOCK_RECOVER , objetivo.generateBlockRecoverTime ( objetivo.getCurrentWeapon() ) );
}
else
{
//attack successful but block unsuccessful.
//damage is deal just as at an unblocked attack
Item limbHit = objetivo.getRandomLimbToHit();
int danyo = getCurrentWeapon().dealDamage ( this , objetivo , false , limbHit );
if ( danyo > 0 )
{
//informar de que bloqueas sin �xito recibiendo da�o
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoBloqueoFallido" , new Object[] {this,objetivo,new Integer(danyo)} ); if ( !ejec )
ejec = execCode ( "infoBloqueoFallido" , new Object[] {objetivo,new Integer(danyo)} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoBloqueo(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
if ( numeric_damage )
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.hits.block.failed.someone.numeric","$weapon",getCurrentWeapon().getOutputNameThe(),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("enemy.hits.block.failed.you.numeric","$weapon",getCurrentWeapon().getOutputNameThe(objetivo),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("you.hit.block.failed.enemy.numeric","$weapon",getCurrentWeapon().getOutputNameThe(this),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
//"$2 no consigue parar el ataque de $1, que le acierta con " + getCurrentWeapon().constructName2OneItem() + " infligi�ndole " + danyo + " puntos de da�o...\n" ,
//"No consigues parar el ataque de $1, que te acierta con " + getCurrentWeapon().constructName2OneItem(objetivo) + " infligi�ndote " + danyo + " puntos de da�o...\n" ,
//"$2 no consigue parar tu ataque, le aciertas con " + getCurrentWeapon().constructName2OneItem(this) + " infligi�ndole " + danyo + " puntos de da�o...\n" ,
true );
}
else
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.hits.block.failed.someone","$weapon",getCurrentWeapon().getOutputNameThe(),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("enemy.hits.block.failed.you","$weapon",getCurrentWeapon().getOutputNameThe(objetivo),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("you.hit.block.failed.enemy","$weapon",getCurrentWeapon().getOutputNameThe(this),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
//"$2 no consigue parar el ataque de $1, que le acierta con " + getCurrentWeapon().constructName2OneItem() + " infligi�ndole " + objetivo.estimateDamage(danyo) + "...\n" ,
//"No consigues parar el ataque de $1, que te acierta con " + getCurrentWeapon().constructName2OneItem(objetivo) + " infligi�ndote " + objetivo.estimateDamage(danyo) + "...\n" ,
//"$2 no consigue parar tu ataque, le aciertas con " + getCurrentWeapon().constructName2OneItem(this) + " infligi�ndole " + objetivo.estimateDamage(danyo) + "...\n" ,
true );
habitacionActual.reportActionAuto ( objetivo , null , null , "$1 " + objetivo.estimateStatus() + ".\n" , true );
}
}
}
else
{
//informar de que bloqueas sin �xito pero no recibes da�o
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoBloqueoFallido" , new Object[] {this,objetivo,new Integer(danyo)} ); if ( !ejec )
ejec = execCode ( "infoBloqueoFallido" , new Object[] {objetivo,new Integer(danyo)} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoBloqueo(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.hits.block.failed.someone.nodamage","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("enemy.hits.block.failed.you.nodamage","$weapon",getCurrentWeapon().getOutputNameThe(objetivo),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("you.hit.block.failed.enemy.nodamage","$weapon",getCurrentWeapon().getOutputNameThe(this),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
//"$2 no consigue parar el ataque de $1, que le acierta con " + getCurrentWeapon().constructName2OneItem() + " pero no le hace da�o...\n" ,
//"No consigues parar el ataque de $1, que te acierta con " + getCurrentWeapon().constructName2OneItem(objetivo) + " pero no te hace da�o...\n" ,
//"$2 no consigue parar tu ataque, le aciertas con " + getCurrentWeapon().constructName2OneItem(this) + " pero no le haces da�o...\n" ,
true );
}
}
setNewState ( ATTACK_RECOVER , generateAttackRecoverTime(getCurrentWeapon()) );
if ( objetivo.getState() != DYING )
{
objetivo.interrupt ( "el golpe" );
objetivo.setNewState ( DAMAGE_RECOVER , objetivo.generateRecoverFromUnblockedHitTime() );
}
}
}
else
{
//estaban bloqueando y fallamos el ataque
//informar de que fallas
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoFallo" , new Object[] {this,objetivo} ); if ( !ejec )
ejec = execCode ( "infoFallo" , new Object[] {objetivo} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoFallo(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.misses.blocked.someone","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("enemy.misses.blocked.you","$weapon",getCurrentWeapon().getOutputNameThe(objetivo),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("you.miss.blocked.enemy","$weapon",getCurrentWeapon().getOutputNameThe(this),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
//"El ataque de $1 falla a $2.\n" ,
//"El ataque de $1 te falla.\n" ,
//"Tu ataque falla a $2.\n" ,
true );
}
setNewState ( ATTACK_RECOVER , generateAttackRecoverTime(getCurrentWeapon()) );
//darle la iniciativa
//o bien cambiar esto por, en cambio de estado de
//ready to block de los mobiles, si ya no les est� atacando
//el objetivo, pasar a idle (m�s realista)
objetivo.setNewState ( IDLE , 1 ); //objetivo has a chance to attack right now
}
}
else if ( objetivo.getState() == READY_TO_DODGE )
{
//ataque esquivado, posiblemente
if ( getAttackSuccessFromProbability(getCurrentWeapon()) )
{
//attack successful
if ( objetivo.getDodgeSuccessFromProbability() )
{
//attack successful and dodge successful
//int danyo = getCurrentWeapon().dealDamageDefended ( this , objetivo , false );
//informar de esquivada
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoEsquivada" , new Object[] {this,objetivo} ); if ( !ejec )
ejec = execCode ( "infoEsquivada" , new Object[] {objetivo} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoEsquivada(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.dodged.by.someone","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("enemy.dodged.by.you","$weapon",getCurrentWeapon().getOutputNameThe(objetivo),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("you.dodged.by.enemy","$weapon",getCurrentWeapon().getOutputNameThe(this),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
true );
}
setNewState ( ATTACK_RECOVER , generateAttackRecoverTime ( getCurrentWeapon() ) );
objetivo.setNewState ( DODGE_RECOVER , objetivo.generateDodgeRecoverTime ( ) );
}
else
{
//attack successful but dodge unsuccessful.
//damage is deal just as at an unblocked attack
Item limbHit = objetivo.getRandomLimbToHit();
int danyo = getCurrentWeapon().dealDamage ( this , objetivo , false , limbHit );
if ( danyo > 0 )
{
//informar de esquivada fallida
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoEsquivadaFallida" , new Object[] {this,objetivo} ); if ( !ejec )
ejec = execCode ( "infoEsquivadaFallida" , new Object[] {objetivo} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoEsquivadaFallida(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
if ( numeric_damage )
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.hits.dodge.failed.someone.numeric","$weapon",getCurrentWeapon().getOutputNameThe(),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("enemy.hits.dodge.failed.you.numeric","$weapon",getCurrentWeapon().getOutputNameThe(objetivo),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("you.hit.dodge.failed.enemy.numeric","$weapon",getCurrentWeapon().getOutputNameThe(this),"$damage",String.valueOf(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
true );
}
else
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.hits.dodge.failed.someone","$weapon",getCurrentWeapon().getOutputNameThe(),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("enemy.hits.dodge.failed.you","$weapon",getCurrentWeapon().getOutputNameThe(objetivo),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("you.hit.dodge.failed.enemy","$weapon",getCurrentWeapon().getOutputNameThe(this),"$damage",objetivo.estimateDamage(danyo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
//"$2 intenta esquivar el golpe de $1; pero no lo consigue, $1 le acierta con " + getCurrentWeapon().constructName2OneItem() + " infligi�ndole " + objetivo.estimateDamage(danyo) + ".\n" ,
//"Tu intento de esquivar falla, y $1 te acierta con " + getCurrentWeapon().constructName2OneItem(objetivo) + " infligi�ndote " + objetivo.estimateDamage(danyo) + ".\n" ,
//"A pesar de su intento de esquivar el ataque, aciertas a $2 con " + getCurrentWeapon().constructName2OneItem(this) + ", infligi�ndole " + objetivo.estimateDamage(danyo) + ".\n" ,
true );
habitacionActual.reportActionAuto ( objetivo , null , null , "$1 " + objetivo.estimateStatus() + ".\n" , true );
}
}
}
else
{
//informar de esquivada fallida
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoEsquivadaFallida" , new Object[] {this,objetivo} ); if ( !ejec )
ejec = execCode ( "infoEsquivadaFallida" , new Object[] {objetivo} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoEsquivadaFallida(), target id was " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.hits.dodge.failed.someone.nodamage","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("enemy.hits.dodge.failed.you.nodamage","$weapon",getCurrentWeapon().getOutputNameThe(objetivo),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
mundo.getMessages().getMessage("you.hit.dodge.failed.enemy.nodamage","$weapon",getCurrentWeapon().getOutputNameThe(this),new Object[]{this,objetivo,getCurrentWeapon(),new Integer(danyo)} ) ,
//"$2 intenta esquivar el golpe de $1; pero no lo consigue, $1 le acierta con " + getCurrentWeapon().constructName2OneItem() + " pero no le hace da�o.\n" ,
//"Tu intento de esquivar falla, y $1 te acierta con " + getCurrentWeapon().constructName2OneItem(objetivo) + " pero no te hace da�o.\n" ,
//"A pesar de su intento de esquivar el ataque, aciertas a $2 con " + getCurrentWeapon().constructName2OneItem(this) + "; pero no le haces da�o.\n" ,
true );
}
}
setNewState ( ATTACK_RECOVER , generateAttackRecoverTime(getCurrentWeapon()) );
if ( objetivo.getState() != DYING )
{
objetivo.interrupt ( "el golpe" );
objetivo.setNewState ( DAMAGE_RECOVER , objetivo.generateRecoverFromUnblockedHitTime() );
}
}
} //end if get attack success...
else
{
//attack unsuccessful
//defender has iniciativa
//attack unsuccessful
habitacionActual.reportAction ( this , objetivo , null ,
mundo.getMessages().getMessage("someone.misses.dodged.someone","$weapon",getCurrentWeapon().getOutputNameThe(),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("enemy.misses.dodged.you","$weapon",getCurrentWeapon().getOutputNameThe(objetivo),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
mundo.getMessages().getMessage("you.miss.dodged.enemy","$weapon",getCurrentWeapon().getOutputNameThe(this),new Object[]{this,objetivo,getCurrentWeapon()} ) ,
//"El ataque de $1 falla a $2.\n" ,
//"El ataque de $1 te falla. Tienes la iniciativa...\n" ,
//"Tu ataque falla a $2. Te desequilibras...\n" ,
true );
setNewState ( ATTACK_RECOVER , generateAttackRecoverTime(getCurrentWeapon()) );
objetivo.setNewState ( IDLE , 1 ); //objetivo has a chance to attack right now
} //end if not attack successful
} //end if state was ready to dodge
}
public void addEnemy ( Mobile nuevo )
{
if ( combatRefs == null ) combatRefs = getEnemies();
combatRefs.addMobile(nuevo);
this.setRelationshipProperty(nuevo,"enemy",true);
//ser enemigo es relaci�n sim�trica
if ( !nuevo.hasEnemy ( this ) )
nuevo.addEnemy(this);
}
public boolean removeEnemy ( Mobile viejo )
{
this.setRelationshipProperty(viejo,"enemy",false);
if ( combatRefs == null ) return false;
else return combatRefs.removeElement(viejo);
}
public void addItem ( Item nuevo ) throws WeightLimitExceededException, VolumeLimitExceededException
{
if ( inventory == null ) inventory = new Inventory(50,50); //limite de peso y volumen que ponemos por defecto
inventory.addItem(nuevo);
nuevo.addMobileReference(this);
}
public void addSpell ( Spell nuevo )
{
if ( spellRefs == null ) spellRefs = new SpellList();
spellRefs.addSpell(nuevo);
}
public boolean removeItem ( Item viejo )
{
if ( inventory == null ) return false;
else
{
viejo.removeMobileReference(this);
return inventory.removeItem(viejo);
}
}
public boolean removeSpell ( Spell viejo )
{
if ( spellRefs == null ) return false;
else return spellRefs.removeElement(viejo);
}
public boolean hasItem ( Item it )
{
return (inventory != null && inventory.contains(it) );
}
public boolean hasSpell ( Spell s )
{
return (spellRefs != null && spellRefs.contains(s) );
}
public boolean hasEnemy ( Mobile m )
{
//return (combatRefs != null && combatRefs.contains(m) );
return getEnemies().contains(m);
}
public boolean hasEnemies ( )
{
//return ( combatRefs != null && combatRefs.size() > 0 );
return getEnemies().size() > 0;
}
public Inventory getInventory ( )
{
if ( inventory == null ) inventory = new Inventory(50,50);
return inventory;
}
public SpellList getSpells ( )
{
if ( spellRefs == null ) spellRefs = new SpellList();
return spellRefs;
}
public Wearable getWornItem ( Item limb )
{
List l = limb.getRelatedEntitiesByValue ( "wears" , true );
if ( l == null || l.size() < 1 )
return null;
else
return (Wearable) l.get(0);
}
public Inventory getWornItems ()
{
Inventory limbs = getFlattenedPartsInventory();
Inventory result = new Inventory(10000,10000);
if ( limbs == null ) return result;
else
{
for ( int i = 0 ; i < limbs.size() ; i++ )
{
Item limb = limbs.elementAt(i);
Item worn = getWornItem(limb);
if ( worn != null )
{
try
{
result.addItem(worn);
}
catch ( WeightLimitExceededException wle )
{
wle.printStackTrace();
}
catch ( VolumeLimitExceededException vle )
{
vle.printStackTrace();
}
}
}
}
wornItems = result; //kinda cache
return result;
}
public boolean wieldsItem ( Item item )
{
return getWieldedWeapons().contains(item);
}
public boolean wearsItem ( Item item )
{
return getWornItems().contains(item);
}
public Weapon getWieldedItem ( Item limb )
{
List l = limb.getRelatedEntitiesByValue ( "wields" , true );
if ( l == null || l.size() < 1 )
return null;
else
return (Weapon) l.get(0);
}
public Inventory getWieldedWeapons ()
{
Inventory limbs = getFlattenedPartsInventory();
Inventory result = new Inventory(10000,10000);
if ( limbs == null ) return result;
else
{
for ( int i = 0 ; i < limbs.size() ; i++ )
{
Item limb = limbs.elementAt(i);
Item worn = getWieldedItem(limb);
if ( worn != null )
{
try
{
if ( !result.contains(worn) ) //two handed
result.addItem(worn);
}
catch ( WeightLimitExceededException wle )
{
wle.printStackTrace();
}
catch ( VolumeLimitExceededException vle )
{
vle.printStackTrace();
}
}
}
}
wieldedWeapons = result; //kinda cache
return result;
}
/*
Intenta hacer a este bicho damage da�os del tipo damtype: la cantidad de da�o que haga
en realidad se ver� reducida por las resistencias, armaduras, etc. y es la cantidad que
se devuelve. [el bloqueo, sin embargo, se resuelve antes]
*/
public int tryToDealDamage ( int damtype , int damage , boolean simulated /* , Item limb */ )
{
//resistencias, armaduras... here!
if ( !simulated )
decreaseHP ( damage );
return damage;
}
//limb is randomised
public int tryToDealDamage ( List damList , boolean simulated )
{
Item limbToHit = getRandomLimbToHit();
return tryToDealDamage ( damList , simulated , limbToHit );
}
//despu�s de bloquear; pero antes de armaduras (�stas se resuelven aqu�)
public int tryToDealDamage ( List damList , boolean simulated , Item limb )
{
Wearable armadura = null;
if ( limb != null ) armadura = getWornItem(limb); //can be null
List armorDamList = null;
if ( armadura != null ) armorDamList = armadura.getDamageList(this);
if ( armorDamList == null ) //no hay armadura
{
int damDealt = 0;
for ( int i = 0 ; i < damList.size() ; i++ )
{
int thisDam = ((Integer)damList.get(i)).intValue();
if ( !simulated )
decreaseHP ( thisDam );
damDealt+=thisDam;
}
return damDealt;
}
else
{
int damDealt = 0;
for ( int i = 0 ; i < damList.size() ; i++ )
{
int thisDam;
if ( i < armorDamList.size() )
thisDam = ((Integer)damList.get(i)).intValue() - ((Integer)armorDamList.get(i)).intValue();
else
thisDam = ((Integer)damList.get(i)).intValue();
if ( thisDam <= 0 )
{
thisDam = 0;
}
if ( !simulated && thisDam > 0 )
decreaseHP ( thisDam );
damDealt+=thisDam;
}
if ( damDealt == 0 )
{
//informar de que armadura absorbi� impacto
habitacionActual.reportAction ( this , null , null ,
mundo.getMessages().getMessage("someones.armor.absorbed","$armor",armadura.getOutputNameThe(),new Object[]{this,armadura} ) ,
null,
mundo.getMessages().getMessage("your.armor.absorbed","$armor",armadura.getOutputNameThe(this),new Object[]{this,armadura} ) ,
//armadura.constructName2OneItem() + " de $1 absorbe totalmente el impacto.\n" ,
//null,
//"Tu armadura absorbe totalmente el impacto.\n" ,
true );
}
return damDealt;
}
}
public int decreaseHP ( int amount )
{
hp -= amount;
if ( hp <= 0 ) prepareToDie();
return amount;
}
public void setHP ( int amt )
{
hp = amt;
}
public void setMP ( int amt )
{
mp = amt;
}
public void setMaxHP ( int maxHP )
{
maxhp = maxHP;
}
public void setMaxMP ( int maxMP )
{
maxmp = maxMP;
}
public void prepareToDie ( )
{
setNewState ( DYING , 1 );
}
public void die()
{
Debug.println( this + " est� m�s que muerto." );
boolean ejecutado = false;
try
{
ejecutado = execCode( "beforeDie" , new Object[] {} );
}
catch ( ScriptException bshte)
{
//write("bsh.TargetError found at die routine" );
writeError(ExceptionPrinter.getExceptionReport(bshte,"beforeDie() of mobile " + this));
}
if ( ejecutado ) return;
habitacionActual.reportAction ( this , null , mundo.getMessages().getMessage("someone.dies",new Object[]{this}) , null , mundo.getMessages().getMessage("you.die",new Object[]{this}) , true );
Item cadaver = Item.initCorpse ( this );
mundo.addItemAssigningID ( cadaver );
try
{
habitacionActual.addItem ( cadaver );
habitacionActual.removeMob ( this );
if ( mundo.getLimbo() != null )
this.setRoom(mundo.getLimbo());
//mundo.getLimbo().addMob(this);
setNewState ( DEAD , 1 );
}
catch ( WeightLimitExceededException wlee )
{
Debug.println("Can't add corpse to room: " + wlee);
}
catch ( VolumeLimitExceededException vlee )
{
Debug.println("Can't add corpse to room: " + vlee);
}
try
{
ejecutado = execCode( "afterDie" , new Object[] { cadaver } );
}
catch ( ScriptException bshte)
{
//write("bsh.TargetError found at afterDie routine" );
writeError(ExceptionPrinter.getExceptionReport(bshte,"afterDie() of mobile " + this));
}
}
public void setID ( int newid )
{
if ( newid < 20000000 )
idnumber = newid + 20000000;
else
idnumber = newid;
}
//o null si no llevamos armas encima
public Weapon bestNonWieldedWeapon ( int numberOfSimulations )
{
if ( inventory == null ) return null;
int max = -1; //maximo da�o encontrado
Weapon resultado = null;
for ( int i = 0 ; i < inventory.size() ; i++ )
{
Weapon w;
try
{
w = (Weapon) inventory.elementAt(i);
}
catch ( ClassCastException cce )
{
continue;
}
wieldedWeapons = getWieldedWeapons(); //shades attribute with the same name
if ( wieldedWeapons != null && wieldedWeapons.contains(w) ) continue;
//atacarme a mi mismo para ver el dano
int acum = 0;
for ( int k = 0 ; k < numberOfSimulations ; k++ )
{
acum += w.dealDamage ( this , this , true );
}
int media = acum / numberOfSimulations;
if ( media > max )
resultado = w;
}
return resultado;
}
//retval[0] mejor enemigo que bloquear, retval[1] la mejor arma para ello
//null: nada que bloquear
//SI EL BLOQUEO NO CONVENCE POR EL TIEMPO NECESARIO, DEVUELVE NULL
public Object[] bestBlockTargetAndWeapon ( int numberOfSimulations )
{
List atacantes = getAttackingEnemies();
Inventory usableWeapons = getUsableWeapons();
if ( getEnemies() == null || usableWeapons == null ) return null;
if ( atacantes.size() < 1 ) return null;
Object[] resultado = new Object[2];
Debug.println("Best block function result initted.");
double max = -1; //maximo valor funcion de evaluacion hasta el momento
//de momento, IA muy simple. Mas tarde, tener en cuenta para cada bicho y arma de bloqueo:
//tiempo de bloqueo, probabilidad de que no la caguemos increiblemente
//danyo que prevenimos, i.e. danyo sin bloqueo vs. danyo con el
for ( int i = 0 ; i < atacantes.size() ; i++ )
{
//enemigo
Mobile m = (Mobile ) atacantes.get(i);
if ( habitacionActual.hasMobile ( m ) ) //bicho aqui
{
Debug.println("Checking a mob.");
for ( int j = 0 ; j < usableWeapons.size() ; j++ )
{
Weapon w = (Weapon) usableWeapons.elementAt(j);
Debug.println("Checking a weapon.");
if ( w != null )
{
//tenemos una combinacion: arma w , enemigo m.
//aqui se calcularian medias, etc.
//de momento no nos lo curramos mucho
Debug.println("It's not null, this weapon.");
double deftime = w.getTypicalDefenseTime(m);
int attime = (int) m.getPropertyTimeLeft("state");
if ( deftime < attime )
{
Debug.println("ME CONVENCE.");
double evalf = 100 - deftime;
if ( evalf > max )
{
max = evalf;
resultado[0] = m;
resultado[1] = w;
} //end if combination maximizes function
}
else
{
Debug.println("NO ME CONVENCE.");
}
} //end if weapon not null
else
{
Debug.println("It was null, the weapon.");
}
} //end foreach weapon
} //end if bicho is here
} //end for each bicho atacante
if ( resultado[0] == null ) //nullified, no se le ha llegado a asignar nada
//porque todas las wielded weapons eran null
//o porque ninguna nos convencia en cuanto a tiempo de defensa
return null;
return resultado;
}
//retval[0] es el mejor objetivo de los enemigos para atacar, retval[1] la mejor arma para atacarlo.
//o bien devuelve null si no hay nada que atacar.
public Object[] bestAttackTargetAndWeapon ( int numberOfSimulations )
{
//hace las archiconocidas y famos�simas simulaciones que caracterizan la IA del AGE.
Inventory usableWeapons = getUsableWeapons();
Debug.println("Usable weapons for " + getUniqueName() + ": " + usableWeapons );
if ( getEnemies() == null || usableWeapons == null ) return null;
int max = -1; //maximo da�o encontrado hasta el momento
Object[] resultado = new Object[2];
for ( int i = 0 ; i < getEnemies().size() ; i++ )
{
//enemigo
Mobile m = getEnemies().elementAt(i);
if ( habitacionActual.hasMobile ( m ) ) //si el enemigo esta alcanzable
{
for ( int j = 0 ; j < usableWeapons.size() ; j++ )
{
Weapon w = (Weapon) usableWeapons.elementAt(j);
if ( w != null )
{
//tenemos una combinacion: arma w , enemigo m.
//calcular media del da�o producido en n simulaciones
int acum = 0;
for ( int k = 0 ; k < numberOfSimulations ; k++ )
{
acum += w.dealDamage ( this , m , true );
}
int media = acum/numberOfSimulations;
if ( media > max )
{
max = media;
resultado[0] = m;
resultado[1] = w;
}
}
}
}
}
if ( resultado[0] == null ) //nullified, no se le ha llegado a asignar nada
//porque todas las wielded weapons eran null, seguramente
return null;
return resultado;
}
//returns true if successful
public boolean attackBestTarget()
{
Object[] obj = bestAttackTargetAndWeapon ( 5 /*intelligence here*/ );
Debug.println("Best attack target and weapon: " + obj);
//Debug.println("That is: " + obj[0] + " and " + obj[1]);
if ( obj == null )
return false;
else
{
Mobile target = (Mobile)obj[0];
Weapon w = (Weapon)obj[1];
attack ( target , w );
return true;
}
}
//returns true if actually blocked
public boolean blockBestTarget()
{
Object[] obj = bestBlockTargetAndWeapon ( 5 /*intelligence here*/ );
Debug.println("Best block target and weapon: " + obj);
if ( obj == null )
return false;
else
{
Mobile target = (Mobile)obj[0];
Weapon w = (Weapon)obj[1];
block ( target , w );
return true;
}
}
public void attack ( Mobile target , Weapon w )
{
setNewTarget ( target.getID() );
setCurrentWeapon(w);
setNewState ( ATTACKING , generateAttackTime( w ) );
//informar de ataque
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoIntentoAtaque" , new Object[] {this,target} ); if ( !ejec )
ejec = execCode ( "infoIntentoAtaque" , new Object[] {target} ); if (!ejec)
ejec = getCurrentWeapon().execCode ( "infoOnAttack" , new Object[] {this,target} ); if ( !ejec )
ejec = execCode ( "infoOnAttack" , new Object[] {target} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoIntentoAtaque(), target id was " + target.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
habitacionActual.reportAction ( this , target , null ,
mundo.getMessages().getMessage("someone.attacks.someone","$weapon",w.getOutputNameThe(),new Object[]{this,target,w} ) ,
mundo.getMessages().getMessage("enemy.attacks.you","$weapon",w.getOutputNameThe(target),new Object[]{this,target,w} ) ,
mundo.getMessages().getMessage("you.attack.enemy","$weapon",w.getOutputNameThe(this),new Object[]{this,target,w} ) ,
//"$1 ataca a $2 con " + w.constructName2OneItem() + ".\n" ,
//"$1 te ataca con " + w.constructName2OneItem(target) + ".\n",
//"Atacas a $2 con " + w.constructName2OneItem(this) + ".\n",
true );
}
}
public void block ( Mobile target , Weapon w )
{
setNewTarget ( target.getID() );
setCurrentWeapon(w);
setNewState ( BLOCKING , generateBlockTime( w ) );
//informar de bloqueo
boolean ejec = false;
try
{
//tiene prioridad el arma, luego el que la maneja.
ejec = getCurrentWeapon().execCode ( "infoIntentoBloqueo" , new Object[] {this,target} ); if ( !ejec )
ejec = execCode ( "infoIntentoBloqueo" , new Object[] {target} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoIntentoBloqueo(), target id was " + target.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
habitacionActual.reportAction ( this , target , null ,
mundo.getMessages().getMessage("someone.tries.to.block.someone","$weapon",w.getOutputNameThe(),new Object[]{this,target,w} ) ,
mundo.getMessages().getMessage("enemy.tries.to.block.you","$weapon",w.getOutputNameThe(target),new Object[]{this,target,w} ) ,
mundo.getMessages().getMessage("you.try.to.block.enemy","$weapon",w.getOutputNameThe(this),new Object[]{this,target,w} ) ,
//"$1 intenta defenderse de $2 con " + w.constructName2OneItem() + ".\n",
//"$1 intenta defenderse con " + w.constructName2OneItem(target) + ".\n" ,
//"Intentas defenderte de $2 con " + w.constructName2OneItem(this) + ".\n" ,
true );
}
}
//esquivar, en general
protected boolean esquivar ( )
{
List l = getAttackingEnemies();
if ( l == null || l.size() == 0 )
return false;
else
{
Mobile objetivo = (Mobile) l.get(0);
dodge ( objetivo );
return true;
}
}
public void dodge ( Mobile target )
{
setNewTarget ( target.getID() );
setNewState ( DODGING , generateDodgeTime() );
//informar de esquivada
boolean ejec = false;
try
{
ejec = execCode ( "infoIntentoEsquivada" , new Object[] {target} );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at infoIntentoEsquivada(), target id was " + target.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejec )
{
habitacionActual.reportAction ( this , target , null ,
mundo.getMessages().getMessage("someone.tries.to.dodge.someone",new Object[]{this,target} ) ,
mundo.getMessages().getMessage("enemy.tries.to.dodge.you",new Object[]{this,target} ) ,
mundo.getMessages().getMessage("you.try.to.dodge.enemy",new Object[]{this,target} ) ,
//"$1 intenta esquivar el ataque de $2" + ".\n" ,
//"$1 intenta esquivarte" + ".\n" ,
//"Intentas esquivar el ataque de $2" + ".\n" ,
true );
}
}
public MobileList getEnemies ( )
{
if ( combatRefs == null )
{
combatRefs = new MobileList();
List el = this.getRelatedEntitiesByValue("enemy", true);
for (Iterator iterator = el.iterator(); iterator.hasNext();) {
Entity enemy = (Entity) iterator.next();
combatRefs.addEntity(enemy);
}
}
return combatRefs;
}
public void removeAllEnemies()
{
for ( int i = 0 ; i < combatRefs.size() ; i++ )
{
this.setRelationshipProperty(combatRefs.elementAt(i), "enemy", false);
combatRefs.removeElement(combatRefs.elementAt(i));
}
}
//devuelve la lista de todos los enemigos que nos est�n atacando.
//(si no hay ninguno, la lista vacia)
public List getAttackingEnemies ( )
{
if ( !hasEnemies() ) return new ArrayList();
else
{
List res = new ArrayList();
for ( int i = 0 ; i < getEnemies().size() ; i++ )
{
Mobile enemigo = getEnemies().elementAt(i);
if ( enemigo.getState() == ATTACKING && enemigo.getTarget() == getID() )
{
res.add(enemigo);
}
}
return res;
}
}
//freeLimbsNeeded == true -> s�lo blandir en miembro libre
//freeLimbsNeeded == false -> si los miembros est�n ocupados, desblandir las armas
//blandidas en ellos para poder blandir �sta
//return: true if successfully welded
//OBSOLETE
/*
public boolean wieldWeapon ( Weapon w , boolean freeLimbsNeeded )
{
//ver si ya la estamos blandiendo
if ( wieldedWeapons != null && wieldedWeapons.contains ( w ) )
{
//{ya estamos blandiendo este arma}
Debug.println("Already wielding that one.");
return false;
}
//inspeccionar miembros
Vector limbPatternMatchVector = new Vector();
if ( wieldingLimbs != null )
{
if ( w.wieldableLimbs != null )
{
StringTokenizer st = new StringTokenizer ( w.wieldableLimbs , "$" );
while ( st.hasMoreTokens() )
{
Vector temp = wieldingLimbs.patternMatch ( st.nextToken() , false );
for ( int l = 0 ; l < temp.size() ; l++ )
if ( ! ( limbPatternMatchVector.contains ( temp.elementAt(l) ) ) )
limbPatternMatchVector.addElement ( temp.elementAt(l) );
}
}
}
if ( limbPatternMatchVector.size() < 1 )
{
//{el arma no es compatible con nuestros miembros}
Debug.println("Weapon not compatible.");
return false;
}
//buscar un miembro libre entre los obtenidos
int limbn = 0;
int k;
//para cada miembro obtenido (que patternmatchea con los wieldables del arma)
for ( k = 0 ; k < limbPatternMatchVector.size() ; k++ )
{
//buscar el numero de ese miembro en nuestro bicho y, si no lleva arma, breakear
for ( limbn = 0 ; ; limbn++ )
{
if ( wieldingLimbs.elementAt(limbn) == limbPatternMatchVector.elementAt(k) ) break;
}
if ( wieldedWeapons.elementAt( limbn ) == null ) break;
}
if ( k == limbPatternMatchVector.size() )
{
//hay miembros wieldables; pero ocupados.
//solo blandiremos si freeLimbsNeeded es false.
if ( freeLimbsNeeded )
{
Debug.println("No free limbs to spare.");
return false;
}
else
{
//blandimos, por ejemplo, en limbPatternMatchVector(0)
//(es un hecho aqui {limbPatternMatchVector.size()>=1})
for ( limbn = 0 ; ; limbn++ )
{
if ( wieldingLimbs.elementAt(limbn) == limbPatternMatchVector.elementAt(0) ) break;
}
wieldedWeapons.removeItem(wieldedWeapons.elementAt(limbn));
return doWield ( w , limbn );
}
}
//si llegamos aqui, el miembro numero limbn vale para wieldear el item, y esta desocupado.
Debug.println("Calling doWield.");
return doWield ( w , limbn );
}
//pone un arma en el inventario de armas wieldeadas.
private boolean doWield ( Weapon w , int limbn )
{
if ( wieldedWeapons.elementAt ( limbn ) != null )
return false;
try
{
wieldedWeapons.setElementAt ( w , limbn );
//informar de que hemos blandido
habitacionActual.informActionAuto ( this , null , "$1 blande " + w.constructName2OneItem() + " en " + wieldingLimbs.elementAt(limbn).constructName2OneItem() + "\n" , true );
return true;
}
catch ( WeightLimitExceededException wle )
{
return false;
}
catch ( VolumeLimitExceededException vle )
{
return false;
}
}
*/
/******STUBS******/
public boolean getAttackSuccessFromProbability ( Weapon w )
{
double dado = getRandom().nextDouble();
double prob = generateAttackProbability(w);
return ( dado < prob );
}
public boolean getSuccessFromProbability ( Spell s )
{
double dado = getRandom().nextDouble();
double prob = generateCastProbability(s);
return ( dado < prob );
}
public boolean getBlockSuccessFromProbability ( Weapon w )
{
double dado = getRandom().nextDouble();
double prob = generateDefenseProbability(w);
return ( dado < prob );
}
public boolean getDodgeSuccessFromProbability ( )
{
double dado = getRandom().nextDouble();
double prob = generateDodgeProbability();
return ( dado < prob );
}
public double generateCastProbability ( Spell s )
{
double basicProb = s.getTypicalCastProbability(this);
Debug.println("Basic probability: " + basicProb);
//no introducimos factor gaussiano, la propia probabilidad ya implica influencia del azar
return basicProb;
}
public double generateAttackProbability ( Weapon w )
{
double basicProb = w.getTypicalAttackProbability(this);
//no introducimos factor gaussiano, la propia probabilidad ya implica influencia del azar
return basicProb;
}
public double generateDefenseProbability ( Weapon w )
{
double basicProb = w.getTypicalDefenseProbability(this);
//no introducimos factor gaussiano, la propia probabilidad ya implica influencia del azar
return basicProb;
}
public double generateDodgeProbability ( )
{
return 0.2; //stub
}
//Be careful with negatives. Not treated. Candidato a explicaci�n de posteriores fallos chungos?
//(la gaussiana suma negativos)
public int generateAttackTime( Weapon w )
{
double basicTime = w.getTypicalAttackTime ( this );
double variedTime = Utility.applyGaussianVariation ( basicTime , getRandom() , 1.0/3.0 );
Debug.println("Attack time with " + w + ": " + variedTime);
if ( (int) variedTime < 1 )
return 1;
else
return (int) variedTime;
}
public int generateCastTime( Spell s )
{
double basicTime = s.getTypicalCastTime ( this );
double variedTime = Utility.applyGaussianVariation ( basicTime , getRandom() , 1.0/3.0 );
Debug.println("Cast time with " + s + ": " + variedTime);
if ( (int) variedTime < 1 )
return 1;
else
return (int) variedTime;
}
public int generateBlockTime( Weapon w )
{
double basicTime = w.getTypicalDefenseTime ( this );
double variedTime = Utility.applyGaussianVariation ( basicTime , getRandom() , 1.0/3.0 );
Debug.println("Defense time with " + w + ": " + variedTime);
if ( (int) variedTime < 1 )
return 1;
else
return (int) variedTime;
}
public int generateAttackRecoverTime( Weapon w )
{
double basicTime = w.getTypicalAttackRecoverTime ( this );
double variedTime = Utility.applyGaussianVariation ( basicTime , getRandom() , 1.0/3.0 );
Debug.println("Attack recover time with " + w + ": " + (int)variedTime);
if ( (int) variedTime < 1 )
return 1;
else
return (int) variedTime;
}
public int generateBlockRecoverTime( Weapon w )
{
double basicTime = w.getTypicalDefenseRecoverTime ( this );
double variedTime = Utility.applyGaussianVariation ( basicTime , getRandom() , 1.0/3.0 );
Debug.println("Defense recover time with " + w + ": " + variedTime);
if ( (int) variedTime < 1 )
return 1;
else
return (int) variedTime;
}
public int generateRecoverFromUnblockedHitTime()
{
//var�a mucho
//later, recover usage?
double basicTime = 30.0;
double variedTime = Utility.applyGaussianVariation ( basicTime , getRandom() , 2.0/3.0 );
Debug.println("Recover from unblocked hit time generated: " + variedTime);
if ( (int) variedTime < 1 )
return 1;
else
return (int) variedTime;
}
public int generateDodgeTime()
{
return 15;
}
public int generateDodgeRecoverTime()
{
return 15;
}
public org.w3c.dom.Node getXMLRepresentation ( org.w3c.dom.Document doc )
{
org.w3c.dom.Element suElemento = doc.createElement( "Mobile" );
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 ( mobileType ) );
suElemento.setAttribute ( "properName" , String.valueOf ( properName ) );
suElemento.setAttribute ( "hp" , String.valueOf ( hp ) );
suElemento.setAttribute ( "mp" , String.valueOf ( mp ) );
suElemento.setAttribute ( "maxhp" , String.valueOf ( maxhp ) );
suElemento.setAttribute ( "maxmp" , String.valueOf ( maxmp ) );
suElemento.appendChild ( getPropListXMLRepresentation(doc) );
suElemento.appendChild ( getRelationshipListXMLRepresentation(doc) );
org.w3c.dom.Element habitacAct = doc.createElement( "CurrentRoom" );
if ( habitacionActual != null )
{
habitacAct.setAttribute ( "id" , String.valueOf(habitacionActual.getID()) );
suElemento.appendChild(habitacAct);
}
habitacAct = doc.createElement( "LastRoom" );
if ( habitacionAnterior != null )
{
habitacAct.setAttribute ( "id" , String.valueOf(habitacionAnterior.getID()) );
suElemento.appendChild(habitacAct);
}
//temp gender representation
suElemento.setAttribute ( "gender" , String.valueOf( gender ) );
org.w3c.dom.Element listaDesc = doc.createElement("DescriptionList");
for ( int i = 0 ; i < descriptionList.length ; i++ )
{
Description nuestraDescripcion = descriptionList[i];
listaDesc.appendChild ( nuestraDescripcion.getXMLRepresentation(doc) );
}
suElemento.appendChild(listaDesc);
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);
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));
//hechizos
if ( spellRefs != null )
suElemento.appendChild(spellRefs.getXMLRepresentation(doc));
//virtual inventory
if ( virtualInventory != null )
{
org.w3c.dom.Element vi = doc.createElement("VirtualInventory");
vi.appendChild(virtualInventory.getXMLRepresentation(doc));
suElemento.appendChild(vi);
}
//welded weapons inventory
if ( wieldedWeapons != null )
{
org.w3c.dom.Element ww = doc.createElement("WieldedWeaponsInventory");
ww.appendChild(wieldedWeapons.getXMLRepresentation(doc));
suElemento.appendChild(ww);
}
//worn items inventory
if ( wornItems != null )
{
org.w3c.dom.Element ww = doc.createElement("WornItemsInventory");
ww.appendChild(wornItems.getXMLRepresentation(doc));
suElemento.appendChild(ww);
}
//wielding limbs inventory
if ( wieldingLimbs != null )
{
org.w3c.dom.Element wl = doc.createElement("WieldingLimbsInventory");
wl.appendChild(wieldingLimbs.getXMLRepresentation(doc));
suElemento.appendChild(wl);
}
//parts inventory
if ( partsInventory != null )
{
org.w3c.dom.Element p = doc.createElement("Parts");
p.appendChild(partsInventory.getXMLRepresentation(doc));
suElemento.appendChild(p);
}
//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));
}
//caracter�sticas (traits): not at the moment
//yeW! let's doo-eet!
if ( caracteristicas != null )
{
suElemento.appendChild ( caracteristicas.getXMLRepresentation(doc));
}
//relationships and states: not at the moment
//object code
if ( itsCode != null )
suElemento.appendChild(itsCode.getXMLRepresentation(doc));
//PSI keywords and answers
if ( PSIkeywords != null )
{
org.w3c.dom.Element PSISpecElement = doc.createElement("ConversationalAI");
for ( int i = 0 ; i < PSIkeywords.size() ; i++ )
{
org.w3c.dom.Element mappingElement = doc.createElement("Mapping");
mappingElement.setAttribute ( "command" , (String)PSIkeywords.elementAt(i) );
Description[] respuesta = (Description[]) PSIanswers.elementAt(i);
for ( int j = 0 ; j < respuesta.length ; j++ )
{
Description nuestraDescripcion = respuesta[j];
mappingElement.appendChild ( nuestraDescripcion.getXMLRepresentation(doc) );
}
PSISpecElement.appendChild(mappingElement);
}
suElemento.appendChild(PSISpecElement);
}
return suElemento;
}
public void loadNumberGenerator ( World mundo )
{
aleat = mundo.getRandom();
}
public java.util.Random getRandom()
{
return aleat;
}
public void incSkill ( String skillName )
{
caracteristicas.incSkill ( skillName );
}
public void setSkill ( String skillN , long val )
{
caracteristicas.setSkill ( skillN , val );
}
public void setStat ( String stat , int val )
{
caracteristicas.setStat ( stat , val );
}
public Inventory getInventoryForCorpse ( )
{
if ( this instanceof Player ) return inventory;
else return virtualInventory;
}
/* Carga diferida de las relationships */
public void loadRelationshipsFromXML ( World mundo ) throws XMLtoWorldException
{
relationships = new Vector();
relationship_properties = new Vector();
org.w3c.dom.Node n = mundo.getMobileNode( String.valueOf(getID()) );
org.w3c.dom.Element e = null;
try
{
e = (org.w3c.dom.Element) n;
}
catch ( ClassCastException cce )
{
throw ( new XMLtoWorldException ( "Mobile node not Element" ) );
}
org.w3c.dom.NodeList relListNodes = e.getElementsByTagName ( "RelationshipList" );
if ( relListNodes.getLength() > 0 )
{
org.w3c.dom.NodeList relationshipNodes;
try
{
relationshipNodes = ( (org.w3c.dom.Element) relListNodes.item(0) ).getElementsByTagName ( "Relationship" );
}
catch ( ClassCastException cce )
{
throw ( new XMLtoWorldException ( "Relationship list node not Element" ) );
}
if ( relationshipNodes.getLength() > 0 )
{
for ( int i = 0 ; i < relationshipNodes.getLength() ; i++ )
{
//process a relationship
List thisRelPropList = new ArrayList();
Entity thisRelEntity = null;
org.w3c.dom.Element relationshipNode = (org.w3c.dom.Element) relationshipNodes.item(i);
org.w3c.dom.NodeList propListNodes = relationshipNode.getElementsByTagName("PropertyList");
if ( propListNodes.getLength() > 0 )
{
org.w3c.dom.Element relationshipPropertyList = (org.w3c.dom.Element) propListNodes.item(i);
org.w3c.dom.NodeList propEntryNodes = relationshipPropertyList.getElementsByTagName("PropertyEntry");
if ( propEntryNodes.getLength() > 0 )
{
for ( int j = 0 ; j < propEntryNodes.getLength() ; j++ )
{
org.w3c.dom.Node nod = propEntryNodes.item(j);
PropertyEntry pe = new PropertyEntry ( mundo , nod );
thisRelPropList.add(pe);
}
}
if ( relationshipNode.hasAttribute("id") )
{
thisRelEntity = mundo.getObject ( relationshipNode.getAttribute("id") );
if ( thisRelEntity == null )
throw ( new XMLtoWorldException ( "Entity referenced at Relationship node's ID attribute is nonexistent or null" ) );
//finally, put the relationship into the object.
relationships.add ( thisRelEntity );
relationship_properties.add ( thisRelPropList );
}
else
{
throw ( new XMLtoWorldException ( "Relationship node lacks attribute id" ) );
}
}
}
}
}
} //end method loadRel(...)
//armas blandidas y armas naturales que no est�n blandiendo nada.
public Inventory getUsableWeapons()
{
Inventory result = new Inventory(1000000,1000000); //for example
//Inventory result = getNaturalWeapons();
for ( int i = result.size()-1 ; i>=0 ; i-- )
{
Item current = result.elementAt(i);
List blandidos = current.getRelatedEntitiesByValue("wields",true);
if ( blandidos.size() > 0 )
result.removeItem(current);
}
Inventory wieldedWeapons = getWieldedWeapons();
if ( wieldedWeapons != null )
{
for ( int i = 0 ; i < wieldedWeapons.size() ; i++ )
{
Item arma = wieldedWeapons.elementAt(i);
if ( arma != null ) //old wielded weapon format permitted nulls
{
try
{
result.addItem(arma);
}
catch ( WeightLimitExceededException wle )
{
wle.printStackTrace();
}
catch ( VolumeLimitExceededException vle )
{
vle.printStackTrace();
}
}
}
}
Inventory nat = getNaturalWeapons();
for ( int i = 0 ; i < nat.size() ; i++ )
{
try
{
result.addItem(nat.elementAt(i));
}
catch ( WeightLimitExceededException wle )
{
wle.printStackTrace();
}
catch ( VolumeLimitExceededException vle )
{
vle.printStackTrace();
}
}
Debug.println("Usable weapons: " + result);
return result;
}
//devuelve las armas naturales (pu�os, etc... i.e. miembros que atacan) del bicho.
public Inventory getNaturalWeapons()
{
Inventory miembros = getFlattenedPartsInventory();
if ( miembros == null )
return new Inventory(10000,10000);
for ( int i = miembros.size()-1 ; i >= 0 ; i-- )
{
Item it = miembros.elementAt(i);
if ( !(it instanceof Weapon ) )
{
miembros.removeItem(it);
}
}
return miembros;
}
public Inventory getPartsInventory()
{
return partsInventory;
}
//devuelve un Inventory formado por las partes, las partes de partes, etc. etc.
public Inventory getFlattenedPartsInventory()
{
//if ( partsInventory == null ) return null;
if ( partsInventory == null )
partsInventory = new Inventory(10000,10000);
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;
}
/**
* @deprecated Use {@link #doWear(Item,boolean)} instead
*/
public boolean intentarVestir ( Item it , boolean freeLimbsNeeded )
{
return doWear(it, freeLimbsNeeded);
}
/**
* Tries to wear the given item.
* Does not refresh the mobile's state to reflect the time taken to wear the item - use the higher-level method wear() for that.
* @param it
* @param freeLimbsNeeded If true, the method fails (returning false) if no limbs are free. If false, we automatically remove whatever
* is worn on needed limbs in order to wear the item.
* @return
*/
public boolean doWear ( Item it , boolean freeLimbsNeeded )
{
if ( ! ( it instanceof Wearable ) )
{
if ( it instanceof Weapon )
{
//write( io.getColorCode("denial") + "�Vestir " + it.constructName2OneItem(this) + "? Parece m�s adecuado blandir" + ((it.getGender())?"lo":"la") + ".\n" );
writeDenial(mundo.getMessages().getMessage("cant.wear.weapon","$item",it.getOutputNameThe(this),"$oa",((it.getGender())?"o":"a"),new Object[]{this,it}));
}
else
{
//write( io.getColorCode("denial") + "No parece que " + it.constructName2OneItem(this) + " sea algo que se pueda vestir." + "\n" );
writeDenial(mundo.getMessages().getMessage("item.not.wearable","$item",it.getOutputNameThe(this),"$oa",((it.getGender())?"o":"a"),new Object[]{this,it}));
}
return false;
}
Inventory ourLimbs = getFlattenedPartsInventory();
if ( ourLimbs.size() < 1 )
{
//write ( io.getColorCode("error") + "No puedes ponerte ropa si no tienes ning�n miembro." );
writeError(mundo.getMessages().getMessage("cant.wear.without.limbs","$item",it.getOutputNameThe(this),"$oa",((it.getGender())?"o":"a"),new Object[]{this,it}));
}
//ver si ya estamos blandiendo el item
for ( int i = 0 ; i < ourLimbs.size() ; i++ )
{
Item limb = ourLimbs.elementAt(i);
if ( limb.getRelationshipPropertyValueAsBoolean ( it , "wears" ) )
{
//write ( io.getColorCode("denial") + "Ya llevas puesto " + it.constructName2OneItem(this) + ".\n" );
writeDenial(mundo.getMessages().getMessage("wear.already.worn","$item",it.getOutputNameThe(this),new Object[]{this,it}));
return false;
}
}
//intentar cumplir todos los limbs requeridos por el Wearable.
List requirements = ((Wearable)it).getLimbRequirementsList();
Vector usedLimbs = new Vector(); //los iremos marcando como usados
for ( int i = 0 ; i < requirements.size() ; i++ )
{
String requirementString = (String) requirements.get(i);
StringTokenizer st = new StringTokenizer ( requirementString , "$" );
Vector matchingLimbs = new Vector();
//determinar que miembros cumplen el requerimiento, poniendolos en matchingLimbs
while ( st.hasMoreTokens() )
{
Vector temp = ourLimbs.patternMatch ( st.nextToken() , false ).toEntityVector();
for ( int l = 0 ; l < temp.size() ; l++ )
if ( !matchingLimbs.contains( temp.elementAt(l) ) )
matchingLimbs.add(temp.elementAt(l) );
}
//si no hay ninguno que lo cumpla, nada, no podemos vestir.
if ( matchingLimbs.size() < 1 )
{
//write( io.getColorCode("denial") + "No parece adecuado para los de tu especie." + io.getColorCode("reset") + "\n" );
writeDenial(mundo.getMessages().getMessage("wear.no.suitable.limbs","$item",it.getOutputNameThe(this),new Object[]{this,it}));
return false;
}
int k;
//entre los miembros que cumplen el requerimiento, vemos si hay alguno libre
for ( k = 0 ; k < matchingLimbs.size() ; k++ )
{
Item thisLimb = (Item) matchingLimbs.get(k);
List vestidos = thisLimb.getRelatedEntitiesByValue("wears",true);
if ( vestidos.size() < 1 && !usedLimbs.contains(thisLimb) )
{
usedLimbs.add(thisLimb);
break;
}
}
if ( k == matchingLimbs.size() ) //no fuimos por el break, i.e. miembros ocupados
{
if ( !freeLimbsNeeded ) //Mobile auto-remove feature
{
//nos quitamos lo que llevemos en matchingLimbs(0)
Item busyLimb = (Item) matchingLimbs.get(0);
List vestidos = busyLimb.getRelatedEntitiesByValue("wears",true);
for ( int z = 0 ; z < vestidos.size() ; z++ )
{
if ( doUnwear ( (Item) vestidos.get(z) ) == false )
return false;
}
}
else //Usual for Players. Fracasa la funci�n.
{
for ( int n = 0 ; n < matchingLimbs.size() ; n++ )
{
Item current = ( Item ) matchingLimbs.get(n);
List vestidos = current.getRelatedEntitiesByValue("wears",true);
if ( vestidos.size() > 0 )
{
Item vestido = ( Item ) vestidos.get(0);
//write( io.getColorCode("information") + "Llevas puesto " + vestido.constructName2OneItem(this) + " en " + current.constructName2OneItem(this) + "." + io.getColorCode("reset") + "\n" );
writeInformation(mundo.getMessages().getMessage("you.use.limb.wearing","$item",vestido.getOutputNameThe(this),"$limb",current.getOutputNameThe(this),new Object[]{this,vestido,current.getOutputNameThe(this)}));
}
else
{
//write( io.getColorCode("information") + "Tienes libre " + current.constructName2OneItem(this) + "." + io.getColorCode("reset") + "\n" );
writeInformation(mundo.getMessages().getMessage("you.have.free.limb","$limb",current.getOutputNameThe(this),new Object[]{this,current}));
}
}
//write( io.getColorCode("denial") + "Tienes que quitarte algo para poder vestir " + it.constructName2OneItem(this) + "." + io.getColorCode("reset") + "\n" );
writeDenial(mundo.getMessages().getMessage("wear.busy.limbs","$item",it.getOutputNameThe(this),new Object[]{this,it}));
return false;
}
}
}
//{si llegamos hasta aqu�, se dan todas las condiciones para vestir el item.}
//{s�lo tenemos que marcar el item como vestido y poner la relaci�n "wears" con el item en todos los miembros de usedLimbs.}
String toOutput = "";
for ( int i = 0 ; i < usedLimbs.size() ; i++ )
{
Item limb = (Item) usedLimbs.get(i);
limb.setRelationshipProperty ( it , "wears" , true );
if ( i == 0 )
toOutput += limb.getOutputNameThe(this);
else if ( i > 0 && i == usedLimbs.size() - 1 )
toOutput += " y " + limb.getOutputNameThe(this);
else
toOutput += ", " + limb.getOutputNameThe(this);
}
//write( io.getColorCode("action") + "Te pones " + it.constructName2OneItem(this) + " en " + toOutput + ".\n" + io.getColorCode("reset") );
writeAction( mundo.getMessages().getMessage("you.wear.item","$item",it.getOutputNameThe(this),"$limbs",toOutput,new Object[]{this,it,usedLimbs}) );
//habitacionActual.reportActionAuto ( this , null , "$1 se pone " + it.constructName2OneItem() + ".\n" , false );
habitacionActual.reportActionAuto ( this , null , mundo.getMessages().getMessage("someone.wears.item","$item",it.getOutputNameThe(this),"$limbs",toOutput,new Object[]{this,it,usedLimbs}) , false );
if ( wornItems == null ) wornItems = new Inventory(10000,10000);
try
{
wornItems.addItem(it);
}
catch ( WeightLimitExceededException wlee )
{
writeDenial(mundo.getMessages().getMessage("cant.wear.item.weight","$item",it.getOutputNameThe(this),new Object[]{this,it}));
//write( io.getColorCode("denial") + "No puedes vestir eso, pesa demasiado." + ".\n" + io.getColorCode("reset") );
return false;
}
catch ( VolumeLimitExceededException vlee )
{
writeDenial(mundo.getMessages().getMessage("cant.wear.item.volume","$item",it.getOutputNameThe(this),new Object[]{this,it}));
//write( io.getColorCode("denial") + "No puedes blandir eso, pesa demasiado." + ".\n" + io.getColorCode("reset") );
return false;
}
//ejecutar eventos onWear
try
{
it.execCode("onWear",new Object[] {this,usedLimbs} );
}
catch ( ScriptException te )
{
write( io.getColorCode("error") + "bsh.TargetError found at event onWear , item " + it + io.getColorCode("reset") + "\n" );
writeError(ExceptionPrinter.getExceptionReport(te));
}
return true;
}
/**
* @deprecated Use {@link #doWield(Item,boolean)} instead
*/
public boolean intentarBlandir ( Item it , boolean freeLimbsNeeded )
{
return doWield(it, freeLimbsNeeded);
}
/**
* Try to wield the given item instantly.
* Does not set the state to reflect the time taken to wield a weapon - use the higher level method wield() instead for that.
* @param it
* @param freeLimbsNeeded If true, the method fails if the limbs required to wield the weapon are not free. If false, we automatically
* remove items wielded in those limbs in order to wield the weapon.
* @return
*/
public boolean doWield ( Item it , boolean freeLimbsNeeded )
{
if ( ! ( it instanceof Weapon ) )
{
if ( it instanceof Wearable )
{
writeDenial(mundo.getMessages().getMessage("cant.wield.wearable","$item",it.getOutputNameThe(this),"$oa",((it.getGender())?"o":"a"),new Object[]{this,it}));
//write( io.getColorCode("denial") + "�Blandir " + it.constructName2OneItem(this) + "? Parece m�s adecuado vestir" + ((it.getGender())?"lo":"la") + ".\n" );
}
else
{
//write( io.getColorCode("denial") + "No parece que " + it.constructName2OneItem(this) + " sea un arma." + "\n" );
writeDenial(mundo.getMessages().getMessage("wield.non.weapon","$item",it.getOutputNameThe(this),new Object[]{this,it}));
}
return false;
}
Inventory ourLimbs = getFlattenedPartsInventory();
//ver si ya estamos blandiendo el item
for ( int i = 0 ; i < ourLimbs.size() ; i++ )
{
Item limb = ourLimbs.elementAt(i);
if ( limb.getRelationshipPropertyValueAsBoolean ( it , "wields" ) )
{
//write ( io.getColorCode("denial") + "Ya est�s blandiendo " + it.constructName2OneItem(this) + ".\n" );
writeDenial(mundo.getMessages().getMessage("wield.already.wielded","$item",it.getOutputNameThe(this),new Object[]{this,it}));
return false;
}
}
//intentar cumplir todos los limbs requeridos por el Weapon.
List requirements = ((Weapon)it).getLimbRequirementsList();
Vector usedLimbs = new Vector(); //los iremos marcando como usados
for ( int i = 0 ; i < requirements.size() ; i++ )
{
String requirementString = (String) requirements.get(i);
StringTokenizer st = new StringTokenizer ( requirementString , "$" );
Vector matchingLimbs = new Vector();
//determinar que miembros cumplen el requerimiento, poniendolos en matchingLimbs
while ( st.hasMoreTokens() )
{
Vector temp = ourLimbs.patternMatch ( st.nextToken() , false ).toEntityVector();
for ( int l = 0 ; l < temp.size() ; l++ )
if ( !matchingLimbs.contains( temp.elementAt(l) ) )
matchingLimbs.add(temp.elementAt(l) );
}
//si no hay ninguno que lo cumpla, nada, no podemos blandir.
if ( matchingLimbs.size() < 1 )
{
//write( io.getColorCode("denial") + "No parece adecuado para los de tu especie." + io.getColorCode("reset") + "\n" );
writeDenial(mundo.getMessages().getMessage("wield.no.suitable.limbs","$item",it.getOutputNameThe(this),new Object[]{this,it}));
return false;
}
int k;
//entre los miembros que cumplen el requerimiento, vemos si hay alguno libre
for ( k = 0 ; k < matchingLimbs.size() ; k++ )
{
Item thisLimb = (Item) matchingLimbs.get(k);
List vestidos = thisLimb.getRelatedEntitiesByValue("wields",true);
if ( vestidos.size() < 1 && !usedLimbs.contains(thisLimb) )
{
usedLimbs.add(thisLimb);
break;
}
}
if ( k == matchingLimbs.size() ) //no fuimos por el break, i.e. miembros ocupados
{
if ( !freeLimbsNeeded ) //Mobile auto-remove feature
{
//nos quitamos lo que llevemos en matchingLimbs(0)
Item busyLimb = (Item) matchingLimbs.get(0);
List vestidos = busyLimb.getRelatedEntitiesByValue("wields",true);
for ( int z = 0 ; z < vestidos.size() ; z++ )
{
if ( doUnwield ( (Item) vestidos.get(z) ) == false )
return false;
}
}
else //Usual for Players. Fracasa la funci�n.
{
for ( int n = 0 ; n < matchingLimbs.size() ; n++ )
{
Item current = ( Item ) matchingLimbs.get(n);
List vestidos = current.getRelatedEntitiesByValue("wields",true);
if ( vestidos.size() > 0 )
{
Item vestido = ( Item ) vestidos.get(0);
//write( io.getColorCode("information") + "Est�s blandiendo " + vestido.constructName2OneItem(this) + " en " + current.constructName2OneItem(this) + "." + io.getColorCode("reset") + "\n" );
writeInformation(mundo.getMessages().getMessage("you.use.limb.wielding","$item",vestido.getOutputNameThe(this),"$limb",current.getOutputNameThe(this),new Object[]{this,vestido,current.getOutputNameThe(this)}));
}
else
{
//write( io.getColorCode("information") + "Tienes libre " + current.constructName2OneItem(this) + "." + io.getColorCode("reset") + "\n" );
writeInformation(mundo.getMessages().getMessage("you.have.free.limb","$limb",current.getOutputNameThe(this),new Object[]{this,current}));
}
}
//write( io.getColorCode("denial") + "Tienes que guardar alg�n arma para poder blandir " + it.constructName2OneItem(this) + "." + io.getColorCode("reset") + "\n" );
writeDenial(mundo.getMessages().getMessage("wield.busy.limbs","$item",it.getOutputNameThe(this),new Object[]{this,it}));
return false;
}
}
}
//{si llegamos hasta aqu�, se dan todas las condiciones para blandir el item.}
//{s�lo tenemos que marcar el item como blandido y poner la relaci�n "wields" con el item en todos los miembros de usedLimbs.}
String toOutput = "";
for ( int i = 0 ; i < usedLimbs.size() ; i++ )
{
Item limb = (Item) usedLimbs.get(i);
limb.setRelationshipProperty ( it , "wields" , true );
if ( i == 0 )
toOutput += limb.getOutputNameThe(this);
else if ( i > 0 && i == usedLimbs.size() - 1 )
toOutput += " y " + limb.getOutputNameThe(this);
else
toOutput += ", " + limb.getOutputNameThe(this);
}
//write( io.getColorCode("action") + "Blandes " + it.constructName2OneItem(this) + " en " + toOutput + ".\n" + io.getColorCode("reset") );
writeAction( mundo.getMessages().getMessage("you.wield.item","$item",it.getOutputNameThe(this),"$limbs",toOutput,new Object[]{this,it,usedLimbs}) );
//habitacionActual.reportActionAuto ( this , null , "$1 blande " + it.constructName2OneItem() + ".\n" , false );
habitacionActual.reportActionAuto ( this , null , mundo.getMessages().getMessage("someone.wields.item","$item",it.getOutputNameThe(this),"$limbs",toOutput,new Object[]{this,it,usedLimbs}) , false );
if ( wieldedWeapons == null ) wieldedWeapons = new Inventory(10000,10000);
try
{
wieldedWeapons.addItem(it);
}
catch ( WeightLimitExceededException wlee )
{
//write( io.getColorCode("denial") + "No puedes blandir eso, pesa demasiado." + ".\n" + io.getColorCode("reset") );
writeDenial(mundo.getMessages().getMessage("cant.wield.item.weight","$item",it.getOutputNameThe(this),new Object[]{this,it}));
}
catch ( VolumeLimitExceededException vlee )
{
//write( io.getColorCode("denial") + "No puedes blandir eso, pesa demasiado." + ".\n" + io.getColorCode("reset") );
writeDenial(mundo.getMessages().getMessage("cant.wield.item.volume","$item",it.getOutputNameThe(this),new Object[]{this,it}));
}
return true;
}
/*Comando para guardar armas y quitarse armaduras.*/
public boolean intentarGuardar ( Item it )
{
//1. guardar armaduras
if ( it instanceof Wearable )
{
;
}
//end guardar armaduras
return false;
}
/**
* @deprecated Use {@link #doUnwear(Item)} instead
*/
public boolean desvestir ( Item it )
{
return doUnwear(it);
}
/**
* Unwears the given item, but doesn't change the state to reflect the time taken to unwear (use unwear() for that).
* @param it
* @return
*/
public boolean doUnwear ( Item it )
{
if ( wornItems == null ) return false;
boolean success = wornItems.removeItem(it);
if ( success )
{
List usedLimbs = new Vector();
Inventory ourLimbs = getFlattenedPartsInventory();
for ( int i = 0 ; i < ourLimbs.size() ; i++ )
{
Item curLimb = ourLimbs.elementAt(i);
if ( curLimb.getRelationshipPropertyValueAsBoolean(it,"wears") )
{
curLimb.setRelationshipProperty(it,"wears",false);
usedLimbs.add(curLimb);
}
}
//write ( io.getColorCode("action") + "Te quitas " + it.constructName2OneItem() + ".\n" + io.getColorCode("reset") );
writeAction ( mundo.getMessages().getMessage("you.unwear.item","$item",it.getOutputNameThe(this),new Object[]{this,it}) );
//habitacionActual.reportActionAuto ( this , null , "$1 se quita " + it.constructName2OneItem() + ".\n" , false );
habitacionActual.reportActionAuto ( this , null , mundo.getMessages().getMessage("someone.unwears.item","$item",it.getOutputNameThe(),new Object[]{this,it}) , false );
//ejecutar eventos onUnwear
try
{
it.execCode("onUnwear",new Object[] {this,usedLimbs} );
}
catch ( ScriptException te )
{
//write( io.getColorCode("error") + "bsh.TargetError found at event onUnwear , item " + it + io.getColorCode("reset") + "\n" );
writeError(ExceptionPrinter.getExceptionReport(te,"onUnwear, item " + it));
}
return true;
}
else
{
return false;
}
}
/**
* @deprecated Use {@link #doUnwield(Item)} instead
*/
public boolean guardarArma ( Item it )
{
return doUnwield(it);
}
/**
* Tries to unwield an item instantly.
* Does not reflect the state and its timer to represent the time taken to unwield.
* Use the higher-level method unwield(Item) for that.
* @param it
* @return
*/
public boolean doUnwield ( Item it )
{
if ( wieldedWeapons == null ) return false;
boolean success = wieldedWeapons.removeItem(it);
if ( success )
{
Inventory ourLimbs = getFlattenedPartsInventory();
for ( int i = 0 ; i < ourLimbs.size() ; i++ )
{
Item curLimb = ourLimbs.elementAt(i);
if ( curLimb.getRelationshipPropertyValueAsBoolean(it,"wields") )
{
curLimb.setRelationshipProperty(it,"wields",false);
}
}
//write ( io.getColorCode("action") + "Dejas de blandir " + it.constructName2OneItem() + ".\n" + io.getColorCode("reset") );
//habitacionActual.reportActionAuto ( this , null , "$1 deja de blandir " + it.constructName2OneItem() + ".\n" , false );
writeAction ( mundo.getMessages().getMessage("you.unwield.item","$item",it.getOutputNameThe(),new Object[]{this,it}) );
habitacionActual.reportActionAuto ( this , null , mundo.getMessages().getMessage("someone.unwields.item","$item",it.getOutputNameThe(),new Object[]{this,it}) , false );
return true;
}
else
{
return false;
}
}
//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;
}
//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);
}
//predicate-supporting
public String getPlurName ( Entity viewer )
{
return getName ( false , viewer );
}
//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);
}
//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") );
}
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 ( viewer ) );
}
else
{
return ( nItems + " " + getPlurName( viewer ) );
}
}
//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") );
}
else
{
return ( nItems + " " + getPlurName( 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 );
}
//predicate-supporting
public String constructName2True ( int nItems , Entity viewer )
{
if ( nItems == 1 )
{
return presentName ( getSingNameTrue(viewer) , mundo.getMessages().getMessage("art.def.m") , mundo.getMessages().getMessage("art.def.f") );
/*
String baseName = getSingNameTrue( viewer );
if ( baseName.startsWith("$"))
{
properName = true;
baseName = baseName.substring(1);
}
if ( properName )
return baseName;
if ( gender )
return ( "el " + baseName );
else
return ( "la " + baseName );
*/
}
else
{
return ( nItems + " " + getPlurNameTrue( viewer ) );
}
}
//predicate-supporting
public String constructName2OneItem ( Entity viewer )
{
return constructName2True ( 1 , viewer ) ;
}
//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 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 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, 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 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 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, 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 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 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, 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 );
}
//devuelve un miembro al azar para ser golpeado por un arma, teniendo en cuenta el volumen de los diferentes miembros.
//los de volumen cero no seran golpeados (dedos, etc.)
public Item getRandomLimbToHit ( )
{
Inventory limbs = getFlattenedPartsInventory();
if ( limbs == null || limbs.size() == 0 ) return null; //no se consideran miembros para este bicho
int volTot = limbs.getVolume();
if ( volTot == 0 ) return null; //no hay miembros golpeables
int volElegido = Math.abs ( aleat.nextInt() ) % volTot;
Item chosen = null;
int volsum = 0;
int j = 0;
while ( volsum <= volElegido )
{
chosen = limbs.elementAt(j);
volsum += chosen.getVolume();
j++;
}
return chosen;
}
//devuelve lo grave que es el da�o
public String estimateDamage ( int damAmt )
{
double percent = (double)damAmt / (double)maxhp * 100.0;
String result;
if ( percent < 5 )
result = mundo.getMessages().getMessage("damage.5",new Object[]{this});
else if ( percent < 10 )
result = mundo.getMessages().getMessage("damage.10",new Object[]{this});
else if ( percent < 18 )
result = mundo.getMessages().getMessage("damage.18",new Object[]{this});
else if ( percent < 25 )
result = mundo.getMessages().getMessage("damage.25",new Object[]{this});
else if ( percent < 33 )
result = mundo.getMessages().getMessage("damage.33",new Object[]{this});
else if ( percent < 40 )
result = mundo.getMessages().getMessage("damage.40",new Object[]{this});
else if ( percent < 50 )
result = mundo.getMessages().getMessage("damage.50",new Object[]{this});
else if ( percent < 60 )
result = mundo.getMessages().getMessage("damage.60",new Object[]{this});
else if ( percent < 70 )
result = mundo.getMessages().getMessage("damage.70",new Object[]{this});
else if ( percent < 80 )
result = mundo.getMessages().getMessage("damage.80",new Object[]{this});
else if ( percent < 90 )
result = mundo.getMessages().getMessage("damage.90",new Object[]{this});
else
result = mundo.getMessages().getMessage("damage.lethal",new Object[]{this});
return result;
}
public String estimateStatus ( )
{
//percent = % de da�o recibido
double percent = (double)(maxhp-hp) / (double)maxhp * 100.0;
String result;
if ( percent <= 0.1 )
result = mundo.getMessages().getMessage("woundstatus.1","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 5 )
result = mundo.getMessages().getMessage("woundstatus.5","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 10 )
result = mundo.getMessages().getMessage("woundstatus.10","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 18 )
result = mundo.getMessages().getMessage("woundstatus.18","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 25 )
result = mundo.getMessages().getMessage("woundstatus.25","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 33 )
result = mundo.getMessages().getMessage("woundstatus.33","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 40 )
result = mundo.getMessages().getMessage("woundstatus.40","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 50 )
result = mundo.getMessages().getMessage("woundstatus.50","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 60 )
result = mundo.getMessages().getMessage("woundstatus.60","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 70 )
result = mundo.getMessages().getMessage("woundstatus.70","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 80 )
result = mundo.getMessages().getMessage("woundstatus.80","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 90 )
result = mundo.getMessages().getMessage("woundstatus.90","$oa",(getGender()?"o":"a"),new Object[]{this});
else if ( percent < 100 )
result = mundo.getMessages().getMessage("woundstatus.100","$oa",(getGender()?"o":"a"),new Object[]{this});
else
result = mundo.getMessages().getMessage("woundstatus.lethal","$oa",(getGender()?"o":"a"),new Object[]{this});
return result;
}
public int getHP()
{
return hp;
}
public int getMaxHP()
{
return maxhp;
}
public int getMP()
{
return mp;
}
public int getMaxMP()
{
return maxmp;
}
public boolean getGender()
{
return gender;
}
public Object clone( )
{
//do it!
Mobile it = new Mobile();
copyMobileFieldsTo(it);
return it;
}
public void cast ( Spell s , Entity target )
{
Debug.println( this + " is actually tryin' to cast " + s );
int manaCost = (int) s.getTypicalManaCost ( this );
Debug.println("Mana Cost: " + manaCost);
if ( manaCost > mp )
{
//Debug.println("Mana Cost Flubbed!");
//write("No tienes suficiente man� para ejecutar ese hechizo.\n");
writeDenial(mundo.getMessages().getMessage("not.enough.mana","$spell",s.getUniqueName(),new Object[]{this,s,target}));
return;
}
else
{
mp -= manaCost;
if ( target != null )
setNewTarget ( target.getID() );
else
setNewTarget(-1);
boolean ejecutado = false;
try
{
ejecutado = s.execCode( "prepare" , new Object[] { this , target } );
}
catch ( ScriptException bshte)
{
//escribir("bsh.TargetError found at fail routine" );
;
writeError(ExceptionPrinter.getExceptionReport(bshte,"prepare()"));
}
if ( ejecutado ) return;
setNewState ( CASTING , generateCastTime( s ) );
setCurrentSpell(s);
getCurrentSpell().incrementUsage(this);
Debug.println("Cast state set!");
return;
}
}
public void manageEndOfCastState()
{
Debug.println("End of cast state!");
int origState = getState();
long origTimer = getPropertyTimeLeft("state");
if ( getSuccessFromProbability ( getCurrentSpell() ) )
{
if ( getTarget() == -1 )
getCurrentSpell().cast ( this , null ) ;
else
getCurrentSpell().cast ( this , mundo.getObject ( getTarget() ) );
//return true;
}
else
{
if ( getTarget() == -1 )
getCurrentSpell().fail ( this , null ) ;
else
getCurrentSpell().fail ( this , mundo.getObject ( getTarget() ) );
//return false;
}
/*
* if the spell casting hasn't changed the state/timer (it could change it, for example because the spell killed the caster!), then we change the state to
* IDLE so more commands can be accepted.
*/
if ( getState() == origState && getPropertyTimeLeft("state") == origTimer )
setNewState ( IDLE , 1 );
}
void interrupt ( String cause )
{
Debug.println("INTERRUPT!!!!!!!!!!!!");
switch ( getState() )
{
case MOVING:
write(mundo.getMessages().getMessage("interrupted.move","$cause",Character.toUpperCase(cause.charAt(0)) + cause.substring(1),new Object[]{this,cause}));
//write( Character.toUpperCase(cause.charAt(0)) + cause.substring(1) + " interrumpe tu intento de irte.\n" );
break;
case ATTACKING:
write(mundo.getMessages().getMessage("interrupted.attack","$cause",Character.toUpperCase(cause.charAt(0)) + cause.substring(1),new Object[]{this,cause}));
//write( Character.toUpperCase(cause.charAt(0)) + cause.substring(1) + " interrumpe tu intento de ataque.\n" );
break;
case CASTING:
write(mundo.getMessages().getMessage("interrupted.cast","$cause",Character.toUpperCase(cause.charAt(0)) + cause.substring(1),new Object[]{this,cause}));
//write( Character.toUpperCase(cause.charAt(0)) + cause.substring(1) + " interrumpe tu intento de hacer magia.\n" );
break;
}
}
//try to "poner (cosa) en (otracosa)" with two inventories (one for cosa and the other for otracosa).
//returns whether there has been a match.
public boolean putInside ( Inventory inv1 , Inventory inv2 , String arguments )
{
Vector[] patternMatchVectorSingSing = null;
//Vector[] patternMatchVectorSingPlur = null; //no podemos poner una cosa en varios sitios
Vector[] patternMatchVectorPlurSing = null;
//Vector[] patternMatchVectorPlurPlur = null;
boolean mirado = false;
patternMatchVectorSingSing = Matches.toEntityVectors(inv1.patternMatchTwo ( inv2 , arguments , false , false )); //en singular y singular
patternMatchVectorPlurSing = Matches.toEntityVectors(inv1.patternMatchTwo ( inv2 , arguments , true , false )); //en plural y singular
if ( patternMatchVectorSingSing != null && patternMatchVectorSingSing[0].size() > 0 ) //ponemos una cosa en un sitio
{
mirado = true;
Vector[] theVectors = patternMatchVectorSingSing;
Item ourContainer = (Item)(theVectors[1].elementAt(0));
Item ourItem = (Item)(theVectors[0].elementAt(0));
if ( checkPutInside(ourContainer) )
putInside(ourItem,ourContainer);
}
else if ( patternMatchVectorPlurSing != null && patternMatchVectorPlurSing[0].size() > 0 )
{
mirado = true;
Vector[] theVectors = patternMatchVectorPlurSing;
Item ourContainer = (Item)theVectors[1].elementAt(0);
if ( checkPutInside(ourContainer) )
{
for ( int i=0 ; i < theVectors[0].size() ; i++ )
{
Item ourItem = (Item)theVectors[0].elementAt(i);
putInside(ourItem,ourContainer);
} //end for
}
}
return mirado;
}
//check if we can put stuff inside the container
public boolean checkPutInside ( Item ourContainer )
{
if ( !ourContainer.isContainer() )
{
write ( io.getColorCode("denial") +
//"No parece muy �til poner cosas en " + ourContainer.constructName2True(1,this) + "." + io.getColorCode("reset")
mundo.getMessages().getMessage("cant.put.into.noncontainer","$container",ourContainer.constructName2True(1,this),new Object[]{this,ourContainer})
+ io.getColorCode("reset") );
return false;
}
else if ( ourContainer.isCloseable() && !ourContainer.isOpen() )
{
writeDenial (
mundo.getMessages().getMessage("cant.put.into.closed","$container",ourContainer.constructName2True(1,this),"$oa",((ourContainer.getGender())?"o":"a"),new Object[]{this,ourContainer})
);
//write ( io.getColorCode("denial") + ourContainer.constructName2True(1,this) + " est� cerrad" + ((ourContainer.getGender())?"o.":"a.") + io.getColorCode("reset") + "\n" );
return false;
}
return true;
}
//put inside action
public void putInside ( Item ourItem , Item ourContainer )
{
if ( ourItem == ourContainer )
{
//we can't put a container into itself!
writeDenial ( lenguaje.correctMorphologyWithoutTrimming ( mundo.getMessages().getMessage("cant.put.into.itself","$item",ourItem.getOutputNameThe(this),"$oa",((ourItem.getGender())?"o":"a"))));
return;
}
try
{
ourContainer.addItem(ourItem);
removeItem(ourItem);
boolean eventEnded = false;
//ejecutar eventos onPutInside
try
{
eventEnded = ourItem.execCode("onPutInside",new Object[] {this,ourItem,ourContainer} );
if ( !eventEnded )
eventEnded = ourContainer.execCode("onPutInside",new Object[] {this,ourItem,ourContainer} );
if ( !eventEnded )
eventEnded = this.execCode("onPutInside",new Object[] {this,ourItem,ourContainer} );
}
catch ( ScriptException te )
{
//write( io.getColorCode("error") + "bsh.TargetError found at event onPutInside , item number " + ourItem.getID() + io.getColorCode("reset") + "\n" );
writeError(ExceptionPrinter.getExceptionReport(te,"onPutInside, item " + ourItem));
}
if ( !eventEnded )
{
//write( io.getColorCode("action") + "Pones " + ourItem.constructName2True(1,this) + " en " + ourContainer.constructName2True(1,this) + "." + io.getColorCode("reset") + "\n" );
writeAction ( lenguaje.correctMorphologyWithoutTrimming( mundo.getMessages().getMessage("you.put.into","$item",ourItem.constructName2True(1,this),"$container",ourContainer.constructName2True(1,this),new Object[]{this,ourItem,ourContainer}) ) );
}
}
catch ( WeightLimitExceededException wle )
{
//write ( io.getColorCode("denial") + ourContainer.constructName2True(1,this) + " no puede soportar tanto peso." + io.getColorCode("reset") + "\n" );
writeDenial ( lenguaje.correctMorphologyWithoutTrimming ( mundo.getMessages().getMessage("cant.put.into.weight","$item",ourItem.constructName2True(1,this),"$container",ourContainer.constructName2True(1,this),new Object[]{this,ourItem,ourContainer})));
}
catch ( VolumeLimitExceededException vle )
{
//write ( io.getColorCode("denial") + ourItem.constructName2True(1,this) + " no cabe en " + ourContainer.constructName2True(1,this) + io.getColorCode("reset") + "\n" );
writeDenial ( lenguaje.correctMorphologyWithoutTrimming( mundo.getMessages().getMessage("cant.put.into.weight","$item",ourItem.constructName2True(1,this),"$container",ourContainer.constructName2True(1,this),new Object[]{this,ourItem,ourContainer})));
}
}
//action method
boolean getItem ( Item ourItem , Inventory inv , String toAppend )
{
try
{
if ( !ourItem.isGettable() )
{
//write( io.getColorCode("denial") + "No tiene mucho sentido intentar coger "+ ourItem.constructName2True(1,this) + ".\n" + io.getColorCode("reset") );
write( io.getColorCode("denial") + mundo.getMessages().getMessage("denial.get.ungettable","$item",ourItem.constructName2True(1,this) , new Object[]{this,ourItem} ) /*+ "\n"*/ + io.getColorCode("reset") );
return true;
}
//agregar item a inventario
addItem ( ourItem );
//Debug.println("Added: " + ourItem.constructName2(1,ourItem.getState()) );
//decir que lo ha cogido
//write( io.getColorCode("action") + lenguaje.gramaticalizar ( "Coges " + ourItem.constructName2True(1,this) + toAppend + "." ) + "\n" + io.getColorCode("reset") );
if ( toAppend == null || toAppend.length() < 1 )
write( io.getColorCode("action") + lenguaje.correctMorphology ( mundo.getMessages().getMessage("you.get.item","$item",ourItem.constructName2True(1,this)+toAppend,new Object[]{this,ourItem})) + "\n" + io.getColorCode("reset") );
else
write( io.getColorCode("action") + lenguaje.correctMorphology ( mundo.getMessages().getMessage("you.get.item.from.location","$item",ourItem.constructName2True(1,this),"$location",toAppend.trim(),new Object[]{this,ourItem,toAppend})) + "\n" + io.getColorCode("reset") );
//habitacionActual.informActionAuto ( this , null , "$1 coge " + ourItem.constructName2OneItem() + toAppend + ".\n" , false );
if ( toAppend == null || toAppend.length() < 1 )
habitacionActual.reportActionAuto ( this , null , mundo.getMessages().getMessage("someone.gets.item","$item", ourItem.getOutputNameThe(),new Object[]{this,ourItem} ) /*+ "\n"*/ , false );
else
habitacionActual.reportActionAuto ( this , null , mundo.getMessages().getMessage("someone.gets.item.from.location","$item", ourItem.getOutputNameThe(),"$location",toAppend.trim(),new Object[]{this,ourItem} ) /*+ "\n"*/ , false );
//ejecutar eventos onGet
try
{
ourItem.execCode("event_get","this: "+ ourItem.getID() + "\n" + "player: " + getID() );
ourItem.execCode("onGet",new Object[] {this} );
}
catch ( EVASemanticException exc )
{
write( io.getColorCode("error") + "EVASemanticException found at event_get , item number " + ourItem.getID() + io.getColorCode("reset") + "\n" );
}
catch ( ScriptException te )
{
//write( io.getColorCode("error") + "bsh.TargetError found at event onGet , item number " + ourItem.getID() + io.getColorCode("reset") + "\n" );
writeError(ExceptionPrinter.getExceptionReport(te,"onGet, item " + ourItem));
}
//velar por el principio de conservacion de la masa
inv.removeItem ( ourItem );
if ( inv == habitacionActual.getInventory() ) ourItem.removeRoomReference(habitacionActual);
ourItem.removeFromContainers(); //si estaba en un contenedor
//ejecutar descripci�n (pesa poquito, etc. etc.)
boolean execced = false;
try
{
execced = mundo.execCode("messageAfterGet",new Object[] {this,ourItem} );
}
catch ( ScriptException te )
{
//write( io.getColorCode("error") + "bsh.TargetError found at messageAfterGet , item number " + ourItem.getID() + io.getColorCode("reset") + "\n" );
writeError(ExceptionPrinter.getExceptionReport(te,"messageAfterGet, item " + ourItem));
}
if ( !execced )
{
//afterGet por defecto: descripci�n del �tem.
writeDescription(ourItem.getDescription(this) + "\n");
}
/*
* this has been externalised to the desconget.bsh library as of 2009-04-27
*
//describirlo
write( io.getColorCode("description") + ourItem.getDescription(this) + '\n' + io.getColorCode("reset") );
//dar una aproximacion del peso
double factorApr = 0.9+Math.random()/5;
int pesoApr;
pesoApr = (int)Math.round( factorApr*ourItem.getWeight() );
int pesoApr_kilos = pesoApr / 8;
int pesoApr_cuartos = (pesoApr % 8) /2 ;
String pesoDescription = "";
if ( pesoApr_kilos == 0 )
{
if ( pesoApr_cuartos == 0 )
{
pesoDescription = "Pesa muy poquito.";
}
else if ( pesoApr_cuartos == 2 )
{
pesoDescription = "Pesar� medio kilo.";
}
else if ( pesoApr_cuartos == 1 )
{
pesoDescription = "Pesar� un cuarto kilo, m�s o menos.";
}
else if ( pesoApr_cuartos == 3 )
{
pesoDescription = "Pesar� cerca de un kilo.";
}
}
else
{
if ( pesoApr_cuartos == 0 || pesoApr_cuartos == 1 )
{
pesoDescription = "Pesar� aproximadamente " + pesoApr_kilos + " kilo" + (pesoApr_kilos>1?"s":"") + ".";
}
else if ( pesoApr_cuartos == 2 || pesoApr_cuartos == 3 )
{
pesoDescription = "Debe de pesar algo m�s de " + pesoApr_kilos + " kilo" + (pesoApr_kilos>1?"s":"") + ".";
}
}
//write( io.getColorCode("description") + pesoDescription + io.getColorCode("reset") + "\n" );
writeDescription(pesoDescription+"\n");
*/
}
catch ( WeightLimitExceededException we )
{
//write( io.getColorCode("denial") + "�Llevas demasiado peso para coger "+ ourItem.constructName2True(1,this) + "!\n" + io.getColorCode("reset") );
write( io.getColorCode("denial") + mundo.getMessages().getMessage("cant.get.item.weight","$item",ourItem.constructName2True(1,this),new Object[]{this,ourItem} ) /*+ "\n"*/ + io.getColorCode("reset"));
}
catch ( VolumeLimitExceededException ve )
{
//write( io.getColorCode("denial") + "�Llevas objetos demasiado voluminosos para coger "+ ourItem.constructName2True(1,this) + "!\n" + io.getColorCode("reset") );
writeDenial( mundo.getMessages().getMessage("cant.get.item.volume","$item",ourItem.constructName2True(1,this),new Object[]{this,ourItem}) /*+ "\n"*/ );
}
return true;
}
protected boolean cogerItem ( String args , Inventory inv , String extraInfo )
{
boolean mirado = false;
String toAppend;
if ( extraInfo == null ) toAppend = "";
else toAppend = extraInfo;
if ( inv == null || inv.isEmpty() ) return false;
//Debug.println("cogerItem args: " + args + "Inv " + inv );
Vector patternMatchVectorSing = inv.patternMatch ( args , false ).toEntityVector(); //en singular
Vector patternMatchVectorPlur = inv.patternMatch ( args , true ).toEntityVector(); //en plural
if ( patternMatchVectorSing.size() > 0 ) //cogemos un objeto
{
Item ourItem = (Item)patternMatchVectorSing.elementAt(0);
mirado = true;
executeAction ( "get" , new Object[]
{ ourItem , inv , toAppend
} );
}
else if ( patternMatchVectorPlur.size() > 0 )
{
//no era en singular, probamos en plural.
Item ourItem;
mirado = true;
//coger todos los items
for ( int i = 0 ; i < patternMatchVectorPlur.size() ; i++ )
{
ourItem = (Item)patternMatchVectorPlur.elementAt(i);
executeAction ( "get" , new Object[]
{ ourItem , inv , toAppend
} );
}
}
return mirado;
}
/**
* Note: this method sets the state adequately if the action succeeds.
* It doesn't guarantee that it will be set if the action fails (although in some cases it does set it).
* @param actionName
* @param actionArgs
* @return
*/
boolean executeAction ( String actionName , Object[] actionArgs )
{
//ejecutado = execCode( "before" , new Object[] { io } , retval );
boolean ejecutado_algo = false;
//Preparar argumentos para m�todo de acci�n general
//Object[] generalArgs = new Object[actionArgs.length+2];
Object[] generalArgs = new Object[3];
generalArgs[0] = actionName;
generalArgs[1] = this;
//for ( int i = 0 ; i < actionArgs.length ; i++ )
// generalArgs[i+2] = actionArgs[i];
generalArgs[2] = actionArgs;
try
{
ejecutado_algo = mundo.execCode ( "before" , generalArgs );
}
catch ( ScriptException bshte)
{
write("bsh.TargetError found at general before method" );
bshte.printStackTrace();
writeError(ExceptionPrinter.getExceptionReport(bshte,"general before method"));
}
if ( ejecutado_algo ) return true;
//Argumentos para m�todo del sujeto: actionArgs
try
{
ejecutado_algo = this.execCode ( "before_" + actionName , actionArgs );
}
catch ( ScriptException bshte)
{
write("bsh.TargetError found at subject before method" );
bshte.printStackTrace();
writeError(ExceptionPrinter.getExceptionReport(bshte));
}
if ( ejecutado_algo ) return true;
Object[] do_args = new Object[actionArgs.length];
if ( actionArgs.length > 0 && actionArgs[0] instanceof SupportingCode )
{
//hay objeto directo
SupportingCode directObject = (SupportingCode) actionArgs[0];
do_args[0] = this;
for ( int i = 1 ; i < actionArgs.length ; i++ )
do_args[i] = actionArgs[i];
try
{
ejecutado_algo = directObject.execCode ( "before_do_" + actionName , do_args );
}
catch ( ScriptException bshte)
{
write("bsh.TargetError found at direct object before method" );
bshte.printStackTrace();
writeError(ExceptionPrinter.getExceptionReport(bshte));
}
if ( ejecutado_algo ) return true;
}
if ( actionArgs.length > 1 && actionArgs[1] instanceof SupportingCode )
{
//hay objeto indirecto, su m�todo s�lo sustituye el argumento 1.
do_args[1] = actionArgs[0];
SupportingCode indirectObject = (SupportingCode) actionArgs[1];
try
{
ejecutado_algo = indirectObject.execCode ( "before_io_" + actionName , do_args );
}
catch ( ScriptException bshte)
{
write("bsh.TargetError found at indirect object before method" );
bshte.printStackTrace();
writeError(ExceptionPrinter.getExceptionReport(bshte));
}
if ( ejecutado_algo ) return true;
}
//action actual execution
if ( actionName.equalsIgnoreCase("go") )
{
return go ( (Path) actionArgs[0] );
}
else if ( actionName.equalsIgnoreCase("get") )
{
return getItem ( (Item) actionArgs[0] , (Inventory) actionArgs[1] , (String) actionArgs[2] );
}
//se puede invocar multiples veces si el comando es de desvestir varias cosas
else if ( actionName.equalsIgnoreCase("unwear") )
{
setNewState(IDLE,5);
boolean retval = doUnwear ( (Item) actionArgs[0] );
if ( retval == false )
setNewState(IDLE,1);
return retval;
}
//se puede invocar multiples veces si el comando es de vestir varias cosas
else if ( actionName.equalsIgnoreCase("wear") )
{
setNewState(IDLE,5);
boolean retval = doWear ( (Item) actionArgs[0] , true );
if ( retval == false )
setNewState(IDLE,1);
return retval;
}
//se puede invocar multiples veces si el comando es de blandir varias cosas
else if ( actionName.equalsIgnoreCase("wield") )
{
setNewState(IDLE,5);
boolean retval = doWield ( (Item) actionArgs[0] , true );
if ( retval == false )
setNewState(IDLE,1);
return retval;
}
//se puede invocar multiples veces si el comando es de desenfundar varias armas
else if ( actionName.equalsIgnoreCase("unwield") )
{
setNewState(IDLE,5);
boolean retval = doUnwield ( (Item) actionArgs[0] );
if ( retval == false )
setNewState(IDLE,1);
return retval;
}
//se puede invocar multiples veces si el comando es de dejar varios objetos
else if ( actionName.equalsIgnoreCase("drop") )
{
setNewState(IDLE,1);
boolean retval = doDrop ( (Item) actionArgs[0] );
if ( retval == false )
setNewState(IDLE,1);
return retval;
}
return false;
}
//action wrappers
public boolean drop ( Item it )
{
boolean success = executeAction ( "drop" , new Object[]{it} );
if ( !success ) setNewState ( 1 /*IDLE*/ , 1 );
return success;
}
public boolean wear ( Item it )
{
boolean success = executeAction ( "wear" , new Object[]{it} );
if ( !success ) setNewState ( 1 /*IDLE*/ , 1 );
return success;
}
public boolean unwear ( Item it )
{
boolean success = executeAction ( "unwear" , new Object[]{it} );
if ( !success ) setNewState ( 1 /*IDLE*/ , 1 );
return success;
}
public boolean wield ( Item it )
{
boolean success = executeAction ( "wield" , new Object[]{it} );
if ( !success ) setNewState ( 1 /*IDLE*/ , 1 );
return success;
}
public boolean unwield ( Item it )
{
boolean success = executeAction ( "unwield" , new Object[]{it} );
if ( !success ) setNewState ( 1 /*IDLE*/ , 1 );
return success;
}
public boolean take ( Item it )
{
Inventory inv = null;
Entity location = it.getLocation();
if ( location instanceof Room ) inv = ((Room)location).getInventory();
else if ( location instanceof Item ) inv = ((Item)location).getContents();
if ( inv != null && inv.contains(it) )
return executeAction ( "get" , new Object[]{it,inv,""} );
else
return false;
}
/**
* @deprecated Use {@link #doDrop(Item)} instead
*/
boolean dejarItem ( Item ourItem )
{
return doDrop(ourItem);
}
/**
* Tries to drop an item instantly. This also includes unwearing/unwielding worn/wielded items.
* @param ourItem
* @return
*/
boolean doDrop ( Item ourItem )
{
try
{
//Aqu� ir� toda la parafernalia de mirar si est� maldito, etecepunto, etecepunto.
habitacionActual.addItem ( ourItem );
removeItem ( ourItem );
//habitacionActual.reportActionAuto ( this , null , "$1 deja " + ourItem.constructName2OneItem() + ".\n" , false );
habitacionActual.reportActionAuto ( this , null , mundo.getMessages().getMessage("someone.drops.item","$item",ourItem.constructName2True(1,this),new Object[]{this,ourItem}) , false );
//si es un arma que blandimos, dejar tambien de blandirla
if ( wieldedWeapons != null && wieldedWeapons.contains(ourItem) )
{
/*
wieldedWeapons.removeItem(ourItem);
escribir( io.getColorCode("action") + "Dejas de blandir " + ourItem.constructName2True(1,ourItem.getState()) + ".\n" + io.getColorCode("reset") );
*/
doUnwield(ourItem);
}
//si es un wearable que llevamos, dejar tambien de llevarlo
if ( wornItems != null && wornItems.contains(ourItem) )
{
doUnwear(ourItem);
}
//write( io.getColorCode("action") + "Dejas " + ourItem.constructName2True(1,this) + ".\n" + io.getColorCode("reset") );
writeAction ( mundo.getMessages().getMessage("you.drop.item","$item",ourItem.constructName2True(1,this),new Object[]{this,ourItem}));
}
catch ( WeightLimitExceededException wle )
{
/*esta excepci�n es absurda en este caso, nunca saldr� (l�mite de peso de habitaci�n, enorme)*/
//write( io.getColorCode("denial") + "No puedes dejar aqu� " + ourItem.constructName2True(1,this) + ", hay demasiado peso.\n" + io.getColorCode("reset") );
write( io.getColorCode("denial") + mundo.getMessages().getMessage("cant.drop.item.weight","$item",ourItem.constructName2True(1,this),new Object[]{this,ourItem} ) /*+ "\n"*/ + io.getColorCode("reset"));
return false;
}
catch ( VolumeLimitExceededException vle )
{
//write( io.getColorCode("denial") + "No puedes dejar aqu� " + ourItem.constructName2True(1,this) + ", no hay espacio suficiente.\n" + io.getColorCode("reset") );
write( io.getColorCode("denial") + mundo.getMessages().getMessage("cant.drop.item.volume","$item",ourItem.constructName2True(1,this),new Object[]{this,ourItem} ) /*+ "\n"*/ + io.getColorCode("reset"));
return false;
}
//ejecutar eventos onDrop
try
{
ourItem.execCode("onDrop",new Object[] {this} );
}
catch ( ScriptException te )
{
//write( io.getColorCode("error") + "bsh.TargetError found at event onDrop , item " + ourItem + io.getColorCode("reset") + "\n" );
writeError(ExceptionPrinter.getExceptionReport(te,"onDrop, item " + ourItem));
}
//setNewState( 1 /*IDLE*/, 1 );
//ZR_verbo = command;
return true;
}
protected boolean mirarItem ( String arguments , Inventory inv )
{
boolean mirado = false;
if ( inv == null || inv.isEmpty() ) return false;
Vector patternMatchVectorSing = inv.patternMatch ( arguments , false ).toEntityVector(); //en singular
Vector patternMatchVectorPlur = inv.patternMatch ( arguments , true ).toEntityVector(); //en plural
if ( patternMatchVectorSing.size() > 0 && !(((Item)patternMatchVectorSing.elementAt(0)).getDescription(this).equals("") ) ) //miramos un objeto
{
write( io.getColorCode("description") + ((Item)patternMatchVectorSing.elementAt(0)).getDescription(this) + io.getColorCode("reset") + "\n" );
mirado=true;
}
else if ( patternMatchVectorPlur.size() > 0 )
{
mirado=true;
//no era en singular, probamos en plural.
Item ourItem;
//mirar todos los items
for ( int i = 0 ; i < patternMatchVectorPlur.size() ; i++ )
{
ourItem = (Item)patternMatchVectorPlur.elementAt(i);
if ( !((Item)ourItem).getDescription(this).equals("") )
{
write( '\n' + "Miras " + ourItem.constructName2True ( 1 , this ) + ": " );
write( io.getColorCode("description") + ((Item)ourItem).getDescription(this) + io.getColorCode("reset") + "\n" );
}
}
}
return mirado;
} //end method mirar item
protected boolean mirarExtrasItems ( String arguments , Inventory inv )
{
boolean mirado = false;
String s;
if ( inv == null || inv.isEmpty() ) return false;
for ( int i = 0 ; i < inv.size() ; i++ ) //mirar item i
{
Debug.println("Seein' if item " + inv.elementAt(i) + " has extra.");
if ( ( s = inv.elementAt(i).getExtraDescription( arguments , this ) ) != null )
{
write(io.getColorCode("description")+s+io.getColorCode("reset")+"\n");
return true;
}
}
return false;
}
protected boolean mirarExtrasBichos ( String arguments , MobileList inv )
{
boolean mirado = false;
String s;
if ( inv == null || inv.isEmpty() ) return false;
for ( int i = 0 ; i < inv.size() ; i++ ) //mirar item i
{
Debug.println("Seein' if item " + inv.elementAt(i) + " has extra.");
if ( ( s = inv.elementAt(i).getExtraDescription( arguments , this ) ) != null )
{
write(io.getColorCode("description")+s+io.getColorCode("reset")+"\n");
return true;
}
}
return false;
}
protected boolean mirarBicho ( String arguments , MobileList ml ) //en realidad, lo mismo que el anterior.
//�Interfaz Referenciable para estas cosas [constructname...], y ReferenciableList en vez de EntityList?
{
boolean mirado = false;
if ( ml == null || ml.isEmpty() ) return false;
Vector patternMatchVectorSing = ml.patternMatch ( arguments , false ).toEntityVector(); //en singular
Vector patternMatchVectorPlur = ml.patternMatch ( arguments , true ).toEntityVector(); //en plural
if ( patternMatchVectorSing.size() > 0 && !(((Mobile)patternMatchVectorSing.elementAt(0)).getDescription(this)).equals("") ) //miramos un objeto
{
write( io.getColorCode("description") + ((Mobile)patternMatchVectorSing.elementAt(0)).getDescription(this) + io.getColorCode("reset") + '\n' );
mirado=true;
}
else if ( patternMatchVectorPlur.size() > 0 )
{
mirado=true;
//no era en singular, probamos en plural.
Mobile ourMob;
//mirar todos los items
for ( int i = 0 ; i < patternMatchVectorPlur.size() ; i++ )
{
ourMob = (Mobile)patternMatchVectorPlur.elementAt(i);
if ( !((Mobile)ourMob).getDescription(this).equals("") )
{
write( '\n' + "Miras " + ourMob.constructName2 ( 1 , this ) + ": " );
write( io.getColorCode("description") + ((Mobile)ourMob).getDescription(this) + io.getColorCode("reset") + "\n" );
}
}
}
return mirado;
} //end method mirar item
//el contenido se mira recursivamente.
protected boolean mirarContenido ( String arguments , Inventory inv )
{
boolean mirado = false;
if ( inv == null || inv.isEmpty() ) return false;
for ( int i = 0 ; i < inv.size() ; i++ )
{
//open condition added 2011-03-11
if ( inv.elementAt(i).isContainer() && inv.elementAt(i).isOpen() )
{
mirado = mirarItem ( arguments , inv.elementAt(i).getContents() ); //mirar el contenido
if ( mirado ) break;
}
}
if ( !mirado )
{
for ( int i = 0 ; i < inv.size() ; i++ )
{
//open condition added 2011-03-11
if ( inv.elementAt(i).isContainer() && inv.elementAt(i).isOpen() )
{
mirado = mirarContenido ( arguments , inv.elementAt(i).getContents() ); //llamada recursiva
if ( mirado ) break;
}
}
}
return mirado;
}
//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;
}
//notaci�n un poco inconsistente con la de Entity::copyEntityFields; pero bueno
public void copyMobileFieldsTo ( Mobile m )
{
m.copyEntityFields(this); //estados, propiedades, etc.
//Debug.println("Random from SOURCE item: " + getRandom());
m.aleat = getRandom();
m.habitacionActual = habitacionActual;
m.habitacionAnterior = habitacionAnterior;
m.lenguaje = lenguaje;
m.movingState_Path = movingState_Path;
m.mundo = mundo;
m.PSIanswers = PSIanswers;
m.PSIkeywords = PSIkeywords;
m.io = io;
m.caracteristicas = (Traits) caracteristicas.clone();
m.exitname = exitname;
m.extraDescriptions = extraDescriptions;
m.gender = gender;
m.idnumber = idnumber; //will have to change the ID later!
//it.inheritsFrom = 0; //creates an identical (strong inherit) item -> No weak inherit
//nay, identical copy
m.inheritsFrom = inheritsFrom;
if ( inventory != null )
m.inventory = (Inventory) inventory.clone();
else m.inventory = null;
//m.inventoryString = inventoryString;
//it.isInstanceOf = idnumber; //creates an identical (strong inherit) item
//nay, identical copy
m.isInstanceOf = isInstanceOf;
//m.isVirtual = isVirtual;
m.mobileType = mobileType;
if ( itsCode != null )
m.itsCode = itsCode.cloneIfNecessary();
if ( partsInventory != null )
m.partsInventory = (Inventory) partsInventory.clone();
else m.partsInventory = null;
if ( wieldedWeapons != null )
m.wieldedWeapons = (Inventory) wieldedWeapons.clone();
else m.wieldedWeapons = null;
if ( wieldingLimbs != null )
m.wieldingLimbs = (Inventory) wieldingLimbs.clone();
else
m.wieldingLimbs = null;
if ( wornItems != null )
m.wornItems = (Inventory) wornItems.clone();
else
m.wornItems = null;
if ( virtualInventory != null )
m.virtualInventory = (Inventory) virtualInventory.clone();
else
m.virtualInventory = null;
m.respondToPlur = respondToPlur;
m.respondToSing = respondToSing;
m.title = title;
m.hp = hp;
m.mp = mp;
m.maxhp = maxhp;
m.maxmp = maxmp;
m.descriptionList = new Description[descriptionList.length];
for ( int i = 0 ; i < m.descriptionList.length ; i++ )
{
m.descriptionList[i] = (Description) descriptionList[i].clone();
}
m.singNames = new Description[singNames.length];
for ( int i = 0 ; i < m.singNames.length ; i++ )
{
m.singNames[i] = (Description) singNames[i].clone();
}
m.plurNames = new Description[plurNames.length];
for ( int i = 0 ; i < m.plurNames.length ; i++ )
{
m.plurNames[i] = (Description) plurNames[i].clone();
}
//mob refs and only restrictions are obsolete, do not copy
//shallow!
m.extraDescriptionArrays = extraDescriptionArrays;
m.extraDescriptionNameArrays = extraDescriptionNameArrays;
}
/**
* Newer version of createNewInstance() that doesn't need old, unused parameters.
* @param cloneInventory Whether the inventory will be copied or left empty.
* @param cloneParts Whether the parts will be copied or left empty.
* @param uniqueName Unique name of the resulting Mobile.
* @return
*/
public Mobile createNewInstance ( boolean cloneInventory , boolean cloneParts , String uniqueName )
{
return createNewInstance ( mundo , cloneInventory , cloneParts , true , uniqueName );
}
public Mobile createNewInstance ( World mundo , boolean cloneInventory , boolean cloneParts , boolean cloneVirtual )
{
return createNewInstance ( mundo , cloneInventory , cloneParts , cloneVirtual , null );
}
//crea un nuevo Mobile que hereda de �ste y lo a�ade al mundo
public Mobile createNewInstance( World mundo , boolean cloneInventory , boolean cloneParts , boolean cloneVirtual , String uniqueName )
{
Mobile it = (Mobile) this.clone();
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);
}
boolean [][] limb_wielded_relationship_map = null;
boolean [][] limb_worn_relationship_map = null;
if ( (cloneParts || cloneInventory) )
{
//make relationship map to solve limbs/weapons cloning problem
Inventory parts = it.getFlattenedPartsInventory();
Inventory inv = it.getInventory();
if ( parts != null && inv != null )
{
limb_wielded_relationship_map = new boolean [parts.size()][inv.size()];
limb_worn_relationship_map = new boolean [parts.size()][inv.size()];
for ( int i = 0 ; i < parts.size() ; i++ )
{
Weapon w = it.getWieldedItem( parts.elementAt(i) );
//get index of w in inv
for ( int j = 0 ; j < inv.size() ; j++ )
{
if ( inv.elementAt(j).equals(w) )
{
limb_wielded_relationship_map[i][j]=true;
}
}
Wearable w2 = it.getWornItem( parts.elementAt(i) );
//get index of w in inv
for ( int j = 0 ; j < inv.size() ; j++ )
{
if ( inv.elementAt(j).equals(w2) )
{
limb_worn_relationship_map[i][j]=true;
}
}
}
}
}
if ( cloneInventory && it.inventory != null )
{
//poner inventario de copias
it.inventory = it.inventory.cloneCopyingItems(mundo,cloneInventory,cloneParts);
}
if ( cloneVirtual && it.virtualInventory != null )
{
it.virtualInventory = it.virtualInventory.cloneCopyingItems(mundo,cloneVirtual,cloneParts);
}
if ( cloneParts && it.partsInventory != null )
{
it.partsInventory = it.partsInventory.cloneCopyingItems(mundo,cloneInventory,cloneParts);
}
//wearable and wieldable stuff
/*
if ( cloneInventory && it.wieldedWeapons != null )
{
it.wieldedWeapons = it.wieldedWeapons.cloneCopyingItems(mundo,cloneInventory,cloneParts);
}
if ( cloneInventory && it.wornItems != null )
{
it.wornItems = it.wornItems.cloneCopyingItems(mundo,cloneInventory,cloneParts);
}
*/
//just clone them, will be emptied and refilled
if ( it.wieldedWeapons != null )
it.wieldedWeapons = (Inventory) it.wieldedWeapons.clone();
if ( it.wornItems != null )
it.wornItems = (Inventory) it.wornItems.clone();
if ( cloneParts || cloneInventory )
{
//load relationship map to solve limbs/weapons cloning problem
Inventory parts = it.getFlattenedPartsInventory();
Inventory inv = it.getInventory();
if ( it.wieldedWeapons == null ) it.wieldedWeapons = new Inventory(10000,10000);
if ( it.wornItems == null ) it.wornItems = new Inventory(10000,10000);
it.wieldedWeapons.empty();
it.wornItems.empty();
for ( int i = 0 ; i < parts.size() ; i++ )
{
for ( int j = 0 ; j < inv.size() ; j++ )
{
//reset wieldings
try
{
Weapon w = it.getWieldedItem ( parts.elementAt(i) );
if ( w != null )
parts.elementAt(i).setRelationshipProperty(w,"wields",false);
if ( limb_wielded_relationship_map[i][j] )
{
parts.elementAt(i).setRelationshipProperty(inv.elementAt(j),"wields",true);
it.wieldedWeapons.addItem(inv.elementAt(j));
Debug.println("Adding wielded item " + inv.elementAt(j) + " to " + it);
}
Wearable w2 = it.getWornItem ( parts.elementAt(i) );
if ( w2 != null )
parts.elementAt(i).setRelationshipProperty(w2,"wears",false);
if ( limb_worn_relationship_map[i][j] )
{
parts.elementAt(i).setRelationshipProperty(inv.elementAt(j),"wears",true);
it.wornItems.addItem(inv.elementAt(j));
Debug.println("Adding worn item " + inv.elementAt(j) + " to " + it);
}
}
catch ( WeightLimitExceededException wlee )
{
wlee.printStackTrace();
}
catch ( VolumeLimitExceededException vlee )
{
vlee.printStackTrace();
}
}
}
}
if ( uniqueName == null ) it.title = mundo.generateUnusedUniqueName(this.getUniqueName());
else it.title = uniqueName;
mundo.addMobileAssigningID ( it );
return it;
}
//respuesta al comando suicidarse
public void suicide()
{
Inventory weaponInv = getUsableWeapons();
Inventory natInv = getNaturalWeapons();
for ( int i = 0 ; i < weaponInv.size() ; i++ )
{
Weapon current = (Weapon) weaponInv.elementAt(i);
if ( ! ( natInv.contains(current) ) )
{
suicideWith ( current );
return;
}
}
//write("No est�s blandiendo ning�n arma �til para suicidarte.\n");
writeDenial(mundo.getMessages().getMessage("no.suicide.weapon",new Object[]{this}));
}
public void suicideWith ( Weapon w )
{
habitacionActual.reportAction ( this,null,new Entity[]{w} ,
mundo.getMessages().getMessage("someone.suicides",new Object[]{this,w}),
mundo.getMessages().getMessage("you.suicide",new Object[]{this,w}),
mundo.getMessages().getMessage("you.suicide",new Object[]{this,w}),
//"$1 se suicida con $3.\n",
//"Te suicidas con $3.\n",
//"Te suicidas con $3.\n",
true );
decreaseHP ( getHP() );
}
public EntityList getReachableEntities()
{
return getReachableEntities(false);
}
public EntityList getReachableEntities( boolean includeContainedItems )
{
EntityList possibleSpellTargets = new EntityList();
for ( int i = 0 ; i < habitacionActual.mobsInRoom.size() ; i++ )
{
possibleSpellTargets.addEntity ( habitacionActual.mobsInRoom.elementAt(i) );
}
Inventory myInv;
if ( includeContainedItems ) myInv = getFlattenedInventory();
else myInv = getInventory();
for ( int i = 0 ; i < myInv.size() ; i++ )
{
possibleSpellTargets.addEntity ( myInv.elementAt(i) );
}
Inventory roomInv;
if ( includeContainedItems ) roomInv = habitacionActual.getFlattenedInventory();
else roomInv = habitacionActual.getInventory();
for ( int i = 0 ; i < roomInv.size() ; i++ )
{
possibleSpellTargets.addEntity ( roomInv.elementAt(i) );
}
//add this mobile's parts as well
Inventory parts = this.getFlattenedPartsInventory();
for ( int i = 0 ; i < parts.size(); i++ )
{
possibleSpellTargets.addEntity( parts.elementAt(i) );
}
return possibleSpellTargets;
}
/**
*
* @param el1 An entity list.
* @param el2 Another entity list.
* @param arguments Arguments of a string command to be executed.
* @return Two parallel vectors containing the pairs of objects (o1,o2) such that o1 belongs to el1, o2 belongs to el2, and the objects pattern-match
* with the two arguments in order.
*/
protected List[] patternMatchPairs(EntityList el1, EntityList el2, String arguments) {
List[] result = new ArrayList[2];
ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList();
result[0] = list1;
result[1] = list2;
if ( el1 == null || el1.isEmpty() || el2 == null || el2.isEmpty() ) return result;
Vector[] patternMatchVectorSingSing = Matches.toEntityVectors(el1.patternMatchTwo ( el2 , arguments , false , false )); //en singular y singular
Vector[] patternMatchVectorSingPlur = Matches.toEntityVectors(el1.patternMatchTwo ( el2 , arguments , false , true )); //en singular y plural
Vector[] patternMatchVectorPlurSing = Matches.toEntityVectors(el1.patternMatchTwo ( el2 , arguments , true , false )); //en plural y singular
Vector[] patternMatchVectorPlurPlur = Matches.toEntityVectors(el1.patternMatchTwo ( el2 , arguments , true , true )); //en plural y plural
if ( patternMatchVectorSingSing != null && patternMatchVectorSingSing[0].size() > 0 )
{
list1.add( patternMatchVectorSingSing[0].get(0) );
list2.add( patternMatchVectorSingSing[1].get(0) );
}
else if ( patternMatchVectorSingPlur != null && patternMatchVectorSingPlur[0].size() > 0 )
{
for ( int i=0 ; i < patternMatchVectorSingPlur[1].size() ; i++ )
{
list1.add( patternMatchVectorSingPlur[0].get(0) );
list2.add( patternMatchVectorSingPlur[1].get(i) );
}
}
else if ( patternMatchVectorPlurSing != null && patternMatchVectorPlurSing[0].size() > 0 )
{
for ( int j=0 ; j < patternMatchVectorPlurSing[0].size() ; j++ )
{
list1.add( patternMatchVectorPlurSing[0].get(j) );
list2.add( patternMatchVectorPlurSing[1].get(0) );
}
}
else if ( patternMatchVectorPlurPlur != null && patternMatchVectorPlurPlur[0].size() > 0 )
{
for ( int i=0 ; i < patternMatchVectorPlurPlur[0].size() ; i++ )
{
for ( int j=0 ; j < patternMatchVectorPlurPlur[1].size() ; j++ )
{
list1.add( patternMatchVectorPlurPlur[0].get(i) );
list2.add( patternMatchVectorPlurPlur[1].get(j) );
}
}
}
return result;
}
/**
* @return The SoundClient associated with this Mobile if it's a Player and it has a sound-enabled client. Else, it returns null.
*/
private SoundClient getSoundClientIfAvailable()
{
if ( !(this instanceof Player) ) return null; //not player, doesn't have an input-output client to play midi
Player pl = (Player) this;
InputOutputClient io = pl.getClient();
if ( !(io instanceof MultimediaInputOutputClient) ) return null; //player is using client without multimedia capabilities
MultimediaInputOutputClient mio = (MultimediaInputOutputClient) io;
if ( !mio.isSoundEnabled() ) return null; //sound is disabled in the client
SoundClient sc = mio.getSoundClient();
return sc;
}
//multimedia
//TODO: version with exceptions (playMidi) and without (playMidiIfAvailable)
public boolean playMidiIfAvailable ( String midiFileName , int loopCount )
{
SoundClient sc = getSoundClientIfAvailable();
if ( sc == null ) return false;
try
{
sc.midiInit();
sc.midiPreload(midiFileName);
sc.midiOpen(midiFileName);
if ( loopCount != 0 )
sc.midiLoop( loopCount );
else
sc.midiStart();
return true;
}
catch ( Exception e )
{
return false;
}
}
public boolean playMidiIfAvailable ( URL u , int loopCount )
{
return playMidiIfAvailable ( u.toString() , loopCount );
}
//old version of this method
private boolean playMidiIfAvailable ( String midiFileName , boolean loop )
{
if ( loop )
return playMidiIfAvailable(midiFileName,-1);
else
return playMidiIfAvailable(midiFileName);
}
public boolean playMidiIfAvailable ( String midiFileName )
{
return playMidiIfAvailable(midiFileName,0);
}
public boolean playMidiIfAvailable ( URL u )
{
return playMidiIfAvailable ( u.toString() );
}
public boolean loopMidiIfAvailable ( String midiFileName )
{
return playMidiIfAvailable(midiFileName,Sequencer.LOOP_CONTINUOUSLY);
}
//multimedia
public boolean stopMidiIfAvailable ( )
{
SoundClient sc = getSoundClientIfAvailable();
if ( sc == null ) return false;
try
{
sc.midiInit();
sc.midiStop();
return true;
}
catch ( Exception e )
{
return false;
}
}
public boolean playAudioIfAvailable ( URL u )
{
return playAudioIfAvailable(u.toString());
}
public boolean playAudioIfAvailable ( String audioFileName )
{
SoundClient sc = getSoundClientIfAvailable();
if ( sc == null ) return false;
try
{
sc.audioStart(audioFileName);
return true;
}
catch ( Exception e )
{
return false;
}
}
public boolean playAudioIfAvailable ( URL u , int loopTimes )
{
return playAudioIfAvailable(u.toString() , loopTimes );
}
public boolean playAudioIfAvailable ( String audioFileName , int loopTimes )
{
SoundClient sc = getSoundClientIfAvailable();
if ( sc == null ) return false;
try
{
sc.audioStart(audioFileName,loopTimes);
return true;
}
catch ( Exception e )
{
return false;
}
}
public boolean stopAudioIfAvailable ( URL u )
{
return stopAudioIfAvailable ( u.toString() );
}
public boolean stopAudioIfAvailable ( String audioFileName )
{
SoundClient sc = getSoundClientIfAvailable();
if ( sc == null ) return false;
try
{
sc.audioStop(audioFileName);
return true;
}
catch ( Exception e )
{
return false;
}
}
public boolean stopAudioIfAvailable ( URL u , boolean fade )
{
return stopAudioIfAvailable ( u.toString() , fade );
}
public boolean stopAudioIfAvailable ( String audioFileName , boolean fade )
{
if ( ! fade ) return stopAudioIfAvailable ( audioFileName );
else
{
SoundClient sc = getSoundClientIfAvailable();
if ( sc == null ) return false;
try
{
sc.audioFadeOut(audioFileName,1.0);
return true;
}
catch ( Exception e )
{
return false;
}
}
}
public boolean playAudioIfAvailable ( URL u , int loopTimes , boolean fade )
{
return playAudioIfAvailable(u.toString() , loopTimes , fade );
}
public boolean playAudioIfAvailable ( String audioFileName , int loopTimes , boolean fade )
{
if ( !fade ) return playAudioIfAvailable ( audioFileName , loopTimes );
else
{
SoundClient sc = getSoundClientIfAvailable();
if ( sc == null ) return false;
try
{
sc.audioFadeIn(audioFileName,loopTimes,1.0,1.2);
return true;
}
catch ( Exception e )
{
return false;
}
}
}
public boolean setAudioGainIfAvailable ( String audioFileName , double gain )
{
SoundClient sc = getSoundClientIfAvailable();
if ( sc == null ) return false;
try
{
sc.audioSetGain ( audioFileName , gain );
return true;
}
catch ( Exception e )
{
return false;
}
}
public boolean setAudioGainIfAvailable ( URL u , double gain )
{
return setAudioGainIfAvailable ( u.toString() , gain );
}
/*
public boolean playMODIfAvailable ( URL modURL )
{
SoundClient sc = getSoundClientIfAvailable();
if ( sc == null ) return false;
try
{
sc.playMOD(modURL,1);
return true;
}
catch ( Exception e )
{
return false;
}
}
*/
/**
* Obtain a list with the singular reference names of the mobile, in order.
*/
public List getSingularReferenceNames()
{
return (List) ((ArrayList)respondToSing).clone();
}
/**
* Obtain a list with the plural reference names of the mobile, in order.
*/
public List getPluralReferenceNames()
{
return (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;
}
/**
* 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;
}
/**
* Returns a list of all the locations this Mobile is in.
* Since a Mobile can only be in one place at once, and that place must be a Room (not e.g.
* a container or another Mobile), this method always returns a list containing that room.
* @return
*/
public EntityList getLocations()
{
EntityList result = new EntityList();
result.addEntity(habitacionActual);
return result;
}
/**
* Returns the Room this Mobile is in.
* This is equivalent to getRoom(), but is added for convenience, since a similar getLocation()
* method also exists for Items (although in this latter case, the location need not be a Room).
*/
public Entity getLocation()
{
return habitacionActual;
}
/**
* Changes the Room this Mobile is in, doing all the necessary internal data structure updates.
* This is equivalent to setRoom(r), but is added for convenience, since a similar moveTo()
* method also exists for Items (although the latter can also take non-Room entities as
* parameter).
* @param r
*/
public void moveTo ( Room r )
{
setRoom(r);
}
public void meterObjetoEnZRSingular(Item obj) {
if ( obj.getGender() )
{
mentions.setLastMentionedObjectMS( obj.getBestReferenceName ( false ) );
//ZR_objeto_masculino_singular = obj.getBestReferenceName ( false );
}
else
{
mentions.setLastMentionedObjectFS( obj.getBestReferenceName ( false ) );
//ZR_objeto_femenino_singular = obj.getBestReferenceName ( false );
}
//ZR_objeto_singular = obj.getBestReferenceName ( false );
mentions.setLastMentionedObjectS( obj.getBestReferenceName ( false ) );
}
public void resetZRPlural() {
mentions.setLastMentionedObjectMP("");
mentions.setLastMentionedObjectFP("");
mentions.setLastMentionedObjectP("");
/*
ZR_objeto_masculino_plural = "";
ZR_objeto_femenino_plural = "";
ZR_objeto_plural = "";
*/
}
public void meterObjetoEnZRPlural(Item obj) {
if ( obj.getGender() )
{
/*
if ( !ZR_objeto_masculino_plural.equals("") )
ZR_objeto_masculino_plural += ", ";
ZR_objeto_masculino_plural += obj.getBestReferenceName ( true );
*/
if ( !mentions.getLastMentionedObjectMP().equals("") )
mentions.setLastMentionedObjectMP( mentions.getLastMentionedObjectMP() + ", ");
mentions.setLastMentionedObjectMP( mentions.getLastMentionedObjectMP() + obj.getBestReferenceName ( true ));
}
else
{
/*
if ( !ZR_objeto_femenino_plural.equals("") )
ZR_objeto_femenino_plural += ", ";
ZR_objeto_femenino_plural += obj.getBestReferenceName ( true );
*/
if ( !mentions.getLastMentionedObjectFP().equals("") )
mentions.setLastMentionedObjectFP( mentions.getLastMentionedObjectFP() + ", ");
mentions.setLastMentionedObjectFP( mentions.getLastMentionedObjectFP() + obj.getBestReferenceName ( true ));
}
if ( !mentions.getLastMentionedObjectP().equals("") )
mentions.setLastMentionedObjectP( mentions.getLastMentionedObjectP() + ", ");
mentions.setLastMentionedObjectP( mentions.getLastMentionedObjectP() + obj.getBestReferenceName ( true ));
/*
if ( !ZR_objeto_plural.equals("") )
ZR_objeto_plural += ", ";
ZR_objeto_plural += obj.getBestReferenceName ( true );
*/
}
public Mentions getMentions() {
return mentions;
}
public boolean executeParseCommandForTwoEntities ( Entity obj1 , Entity obj2 , String args1 , String args2 , List path1 , List path2 , boolean onWorld )
{
boolean ejecutado = false;
String fullArguments = args1 + " " + args2;
for ( int ip1 = path1.size()-1 ; ip1 >= 0 ; ip1-- )
{
for ( int jp1 = path2.size()-1 ; jp1 >= 0 ; jp1-- )
{
Entity currentObject1 = (Entity) path1.get(ip1);
Entity currentObject2 = (Entity) path2.get(jp1);
//ejecutar parseCommandOnContents() de objeto 1
if ( !onWorld && currentObject1 instanceof SupportingCode )
{
try
{
//parseCommandOnContents(Mobile,command,args,chain)
ejecutado = ejecutado || ((SupportingCode)currentObject1).execCode ( "parseCommandOnContentsObj1" , new Object[] { this , command , args1 , args2 , path1 , path2 , currentObject2 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsObj1(), command was " + command + " " + fullArguments + ", entity " + currentObject1 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandOnContentsObj1(), command was " + command + " " + fullArguments + ", entity " + currentObject1));
}
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)currentObject1).execCode ( "parseCommandOnContentsTwoObjects" , new Object[] { this , command , args1 , args2 , path1 , path2 , currentObject2 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsTwoObjects(), command was " + command + " " + fullArguments + ", entity " + currentObject1 + ", second object was " + currentObject2 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandOnContentsTwoObjects(), command was " + command + " " + fullArguments + ", entity " + currentObject1 + ", second object was " + currentObject2));
}
}
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)currentObject1).execCode( "parseCommandOnContentsGeneric", new Object[] { this , command, args1 , args2 , path1 , path2 , currentObject1 , currentObject2 , new Boolean(true) /*isFirst==true*/ } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsGeneric(), command was " + command + " " + fullArguments + ", entity " + currentObject1 + ", second object was " + currentObject2 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandOnContentsGeneric(), command was " + command + " " + fullArguments + ", entity " + currentObject1 + ", second object was " + currentObject2));
}
}
}
//ejecutar parseCommandOnContents() de objeto 2
if ( !onWorld && currentObject2 instanceof SupportingCode )
{
try
{
//parseCommandOnContents(Mobile,command,args,chain)
ejecutado = ejecutado || ((SupportingCode)currentObject2).execCode ( "parseCommandOnContentsObj2" , new Object[] { this , command , args1 , args2 , path1 , path2 , currentObject1 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsObj2(), command was " + command + " " + fullArguments + ", entity " + currentObject2 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandOnContentsObj2(), command was " + command + " " + fullArguments + ", entity " + currentObject2));
}
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)currentObject2).execCode ( "parseCommandOnContentsTwoObjects" , new Object[] { this , command , args1 , args2 , path1 , path2 , currentObject1 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsTwoObjects(), command was " + command + " " + fullArguments + ", entity " + currentObject1 + ", second object was " + currentObject2 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandOnContentsTwoObjects(), command was " + command + " " + fullArguments + ", entity " + currentObject1 + ", second object was " + currentObject2));
}
}
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)currentObject2).execCode( "parseCommandOnContentsGeneric", new Object[] { this , command, args1 , args2 , path1 , path2 , currentObject1 , currentObject2 , new Boolean(false) /*isFirst==false*/ } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsGeneric(), command was " + command + " " + fullArguments + ", first object was " + currentObject1 + ", second object was " + currentObject2 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandOnContentsGeneric(), command was " + command + " " + fullArguments + ", first object was " + currentObject1 + ", second object was " + currentObject2));
}
}
}
//ejecutar parseCommandOnContents() en mundo referido a objetos
if ( onWorld )
{
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || mundo.execCode ( "parseCommandOnContentsTwoObjects" , new Object[] { this , command , args1 , args2 , path1 , path2 , currentObject1 , currentObject2 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsTwoObjects() executed from world, command was " + command + " " + fullArguments + ", entity " + currentObject1 + ", second object was " + currentObject2 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"bsh.TargetError found at parseCommandOnContentsTwoObjects() executed from world, command was " + command + " " + fullArguments + ", entity " + currentObject1 + ", second object was " + currentObject2));
}
}
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || mundo.execCode( "parseCommandOnContentsGeneric", new Object[] { this , command, args1 , args2 , path1 , path2 , currentObject1 , currentObject2 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsGeneric() executed from world, command was " + command + " " + fullArguments + ", first object was " + currentObject1 + ", second object was " + currentObject2 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"bsh.TargetError found at parseCommandOnContentsGeneric() executed from world, command was " + command + " " + fullArguments + ", first object was " + currentObject1 + ", second object was " + currentObject2));
}
}
}
}
}
//standard (not "onContents") parseCommands:
if ( (path1.size() == 1 && path2.size() == 1) || this.getPropertyValueAsBoolean("containedItemsInScope") )
//in default mode, regular parseCommands are executed only for things NOT contained in anything (hence the path size check)
//in extended scope mode, also for contained items
{
// ejecutar parseCommand() de objeto 1
if ( !onWorld && obj1 instanceof SupportingCode )
{
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)obj1).execCode ( "parseCommandObj1" , new Object[] { this , command , args1 , args2 , obj2 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandObj1(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj1.getID() + ", second object was " + obj2.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandObj1(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj1.getID() + ", second object was " + obj2.getID()));
}
}
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)obj1).execCode ( "parseCommandTwoObjects" , new Object[] { this , command , args1 , args2 , obj2 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandTwoObjects(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj1.getID() + ", second object was " + obj2.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandTwoObjects(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj1.getID() + ", second object was " + obj2.getID()));
}
}
if ( !ejecutado )
{
try
{
//parseCommandGeneric ( Player aCreature , String verb , Sring args1 , Sring args2 , Entity obj1 , Entity obj2 , boolean isFirst )
ejecutado = ejecutado || ((SupportingCode)obj1).execCode ( "parseCommandGeneric" , new Object[] { this , command , args1 , args2 , obj1 , obj2 , new Boolean(true) } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandGeneric(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj1 + ", second object was " + obj2 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandGeneric(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj1 + ", second object was " + obj2));
}
}
} //obj1 instof suppcode
if ( ejecutado ) //c�digo hizo end()
{
//luego esto lo hara el codigo
setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
// ejecutar parseCommand() de objeto 2
if ( !onWorld && obj2 instanceof SupportingCode )
{
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)obj2).execCode ( "parseCommandObj2" , new Object[] { this , command , args1 , args2 , obj1 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandObj2(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj2.getID() + ", first object was " + obj1.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandObj2(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj2.getID() + ", first object was " + obj1.getID()));
}
}
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)obj2).execCode ( "parseCommandTwoObjects" , new Object[] { this , command , args1 , args2 , obj1 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandTwoObjects(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj2.getID() + ", first object was " + obj1.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandTwoObjects(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj2.getID() + ", first object was " + obj1.getID()));
}
}
if ( !ejecutado )
{
try
{
//parseCommandGeneric ( Player aCreature , String verb , Sring args1 , Sring args2 , Entity obj1 , Entity obj2 , boolean isFirst )
ejecutado = ejecutado || ((SupportingCode)obj2).execCode ( "parseCommandGeneric" , new Object[] { this , command , args1 , args2 , obj1 , obj2 , new Boolean(false) } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandGeneric(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj1 + ", second object was " + obj2 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandGeneric(), command was " + command + " " + args1 + " " + args2 + ", entity number " + obj1 + ", second object was " + obj2));
}
}
} //obj2 instof suppcode
if ( onWorld )
{
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || mundo.execCode ( "parseCommandTwoObjects" , new Object[] { this , command , args1 , args2 , obj1 , obj2 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandTwoObjects() executed from world, command was " + command + " " + args1 + " " + args2 + ", entity number " + obj2.getID() + ", first object was " + obj1.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"bsh.TargetError found at parseCommandTwoObjects() executed from world, command was " + command + " " + args1 + " " + args2 + ", entity number " + obj2.getID() + ", first object was " + obj1.getID()));
}
}
if ( !ejecutado )
{
try
{
//parseCommandGeneric ( Player aCreature , String verb , Sring args1 , Sring args2 , Entity obj1 , Entity obj2 , boolean isFirst )
ejecutado = ejecutado || mundo.execCode ( "parseCommandGeneric" , new Object[] { this , command , args1 , args2 , obj1 , obj2 } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandGeneric() executed from world, command was " + command + args1 + args2 + ", entity number " + obj1 + ", second object was " + obj2 + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"bsh.TargetError found at parseCommandGeneric() executed from world, command was " + command + args1 + args2 + ", entity number " + obj1 + ", second object was " + obj2));
}
}
}
}
return ejecutado;
}
/**
* Note: in practice there seems to be no difference at all between arguments and fullArguments - remove one of them?
* @param posiblesObjetivos
* @param arguments
* @param fullArguments
* @param onWorld
* @return
*/
public boolean resolveParseCommandForTwoEntities ( EntityList posiblesObjetivos , String arguments , String fullArguments , boolean onWorld )
{
boolean ejecutado = false;
List matches_ss = ParserMethods.parseReferencesToEntitiesInRecursive ( arguments,posiblesObjetivos,posiblesObjetivos,false,false);
List matches_sp = ParserMethods.parseReferencesToEntitiesInRecursive ( arguments,posiblesObjetivos,posiblesObjetivos,false,true);
List matches_ps = ParserMethods.parseReferencesToEntitiesInRecursive ( arguments,posiblesObjetivos,posiblesObjetivos,true,false);
List matches_pp = ParserMethods.parseReferencesToEntitiesInRecursive ( arguments,posiblesObjetivos,posiblesObjetivos,true,true);
List allMatches = new ArrayList();
allMatches.addAll(matches_ss);
allMatches.addAll(matches_sp);
allMatches.addAll(matches_ps);
allMatches.addAll(matches_pp);
//detect the case where the command does match two entities, but it matches one entity even better
//e.g. item1 "libro verde", "libro", "verde"
//item2 "libro rojo", "libro", "rojo"
//"coger el libro rojo" matches (item1,item2) with priority 2, but it matches item2 only with priority 1 (better).
if ( !allMatches.isEmpty() && matchedOneEntity )
{
int priority = ((SentenceInfo)allMatches.get(0)).getPriority();
//System.err.println("Args: " + arguments);
//System.err.println("One entity prio: " + oneEntityPriority);
//System.err.println("Two entity prio: " + ((SentenceInfo)allMatches.get(0)).getPriority() + " for " + allMatches.get(0));
if ( oneEntityPriority > 0 && priority > oneEntityPriority ) //the command matches two entities, but the best match is for one entity. Don't exec parseCommands for two entities.
{
matchedTwoEntities = false;
matchedTwoEntitiesPermissive = false;
return false;
}
}
matchedTwoEntitiesPermissive = ( allMatches.size() > 0 );
/**
* Store calls to parseCommands on two entities to avoid doing repeated invocations
* for (different args assignments of) the same entities.
*/
class TwoEntityParseCommandAttempt
{
private Entity obj1;
private Entity obj2;
private List path1;
private List path2;
public TwoEntityParseCommandAttempt(Entity obj1,Entity obj2,List path1,List path2)
{
this.obj1 = obj1;
this.obj2 = obj2;
this.path1 = path1;
this.path2 = path2;
}
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result
+ ((obj1 == null) ? 0 : obj1.hashCode());
result = prime * result
+ ((obj2 == null) ? 0 : obj2.hashCode());
result = prime * result
+ ((path1 == null) ? 0 : path1.hashCode());
result = prime * result
+ ((path2 == null) ? 0 : path2.hashCode());
return result;
}
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof TwoEntityParseCommandAttempt))
return false;
TwoEntityParseCommandAttempt other = (TwoEntityParseCommandAttempt) obj;
return this.obj1 == other.obj1
&& this.obj2 == other.obj2
&& this.path1.equals(other.path1)
&& this.path2.equals(other.path2);
}
}
Set attempts = new LinkedHashSet();
for ( int i = 0 ; i < allMatches.size() ; i++ )
{
SentenceInfo si = (SentenceInfo) allMatches.get(i);
String args1 = si.getArgs1();
String args2 = si.getArgs2();
Entity obj1 = si.getObj1();
Entity obj2 = si.getObj2();
List path1 = si.getPath1();
List path2 = si.getPath2();
TwoEntityParseCommandAttempt attempt = new TwoEntityParseCommandAttempt(obj1,obj2,path1,path2);
if ( getPropertyValueAsBoolean("multipleArgsMatches") || !attempts.contains(attempt) )
{
ejecutado = executeParseCommandForTwoEntities ( obj1 , obj2 , args1 , args2 , path1 , path2 , onWorld );
if ( !getPropertyValueAsBoolean("multipleArgsMatches") )
attempts.add(attempt);
}
if ( ejecutado ) //c�digo hizo end()
{
//luego esto lo hara el codigo
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
} //end for each possible match
//no end() has been hit: try parseCommands for one entity!
Set triedPaths = new LinkedHashSet();
for ( int i = 0 ; i < allMatches.size() ; i++ )
{
SentenceInfo si = (SentenceInfo) allMatches.get(i);
String args1 = si.getArgs1();
List path1 = si.getPath1();
if ( !triedPaths.contains(path1) )
{
ejecutado = resolveParseCommandForOneEntity ( posiblesObjetivos , args1 , fullArguments , onWorld , false );
triedPaths.add(path1);
}
if ( !ejecutado )
{
si = (SentenceInfo) allMatches.get(i);
String args2 = si.getArgs2();
List path2 = si.getPath2();
if ( !triedPaths.contains(path2) )
{
ejecutado = resolveParseCommandForOneEntity ( posiblesObjetivos , args2 , fullArguments , onWorld , false );
triedPaths.add(path2);
}
}
if ( ejecutado ) //c�digo hizo end()
{
//luego esto lo hara el codigo
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
}
return false;
}
public boolean resolveParseCommandForOneComponent ( EntityList posiblesObjetivos , String arguments )
{
boolean ejecutado = false;
for ( int i = 0 ; i < posiblesObjetivos.size() && !ejecutado ; i++ )
{
Entity currentEntity = posiblesObjetivos.get(i);
if
(
! ejecutado && (
( currentEntity instanceof Room && ((Room)currentEntity).getExtraDescription(arguments,this) != null ) ||
( currentEntity instanceof Item && ((Item)currentEntity).getExtraDescription(arguments,this) != null ) ||
( currentEntity instanceof Mobile && ((Mobile)currentEntity).getExtraDescription(arguments,this) != null )
)
)
{
try
{
//parseCommandOnComponent(Mobile,command,args,chain)
ejecutado = ejecutado || ((SupportingCode)currentEntity).execCode ( "parseCommandOnComponent" , new Object[] { this , command , arguments } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnComponent(), command was " + command + " " + arguments + ", entity " + currentEntity + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"bsh.TargetError found at parseCommandOnComponent(), command was " + command + " " + arguments + ", entity " + currentEntity));
}
}
}
if ( ejecutado ) //c�digo hizo end()
{
//luego esto lo hara el codigo
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
}
return ejecutado;
}
/**
* Executes all the one-entity parseCommands applicable with the current command to the given arguments and path to a matching entity.
* Note that the objects itself on which to call the parseCommands are taken from the path param.
* @param currentObject
* @param fullArguments
* @param path
* @return
*/
private boolean executeParseCommandForOneEntity ( String fullArguments , List path , boolean onWorld , boolean enableGenerics , boolean plural )
{
boolean ejecutado = false;
//TODO probably remove this if so onContents is executed always and not only for, well, contents
//removed. Replace this if if onContents is not to be executed on objects not contained in others
//if ( objetivoVector.size() > 1 )
//{
Entity currentObject;
for ( int i = path.size()-1; i >= 0 ; i-- )
{
currentObject = (Entity) path.get(i);
//ejecutar parseCommandOnContents() de objeto
if ( !onWorld && currentObject instanceof SupportingCode )
{
try
{
//parseCommandOnContents(Mobile,command,args,chain)
ejecutado = ejecutado || ((SupportingCode)currentObject).execCode ( "parseCommandOnContents" , new Object[] { this , command , fullArguments , path } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContents(), command was " + command + " " + fullArguments + ", entity " + currentObject + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandOnContents(), command was " + command + " " + fullArguments + ", entity " + currentObject));
}
if ( !ejecutado && enableGenerics )
{
try
{
ejecutado = ejecutado || ((SupportingCode)currentObject).execCode ( "parseCommandOnContentsGeneric" , new Object[] { this , command , fullArguments , "" , path , null , currentObject , null , new Boolean(true) } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsGeneric(), command was " + command + " " + fullArguments + ", entity number " + currentObject + ", second object was " + null + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandOnContentsGeneric(), command was " + command + " " + fullArguments + ", entity number " + currentObject + ", second object was " + null));
}
}
}
//lo mismo de mundo
if ( onWorld )
{
try
{
ejecutado = ejecutado || mundo.execCode ( "parseCommandOnContents" , new Object[] { this , command , fullArguments , path , currentObject } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContents() executed from world, command was " + command + " " + fullArguments + ", entity " + currentObject + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandOnContents() executed from world, command was " + command + " " + fullArguments + ", entity " + currentObject));
}
if ( !ejecutado && enableGenerics )
{
try
{
ejecutado = ejecutado || mundo.execCode ( "parseCommandOnContentsGeneric" , new Object[] { this , command , fullArguments , "" , path , null , currentObject , null } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsGeneric() executed from world, command was " + command + " " + fullArguments + ", entity number " + currentObject + ", second object was " + null + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandOnContentsGeneric() executed from world, command was " + command + " " + fullArguments + ", entity number " + currentObject + ", second object was " + null));
}
}
}
}
//}
Entity objetivo = (Entity) path.get(0);
//�ste ser� el objeto principal sobre el que ejecutemos el comando en singular (cualquiera, aunque no sea BSH) si hace referencia a un solo objeto
if ( objetivo instanceof Item )
{
if ( plural )
meterObjetoEnZRPlural((Item)objetivo);
else
meterObjetoEnZRSingular((Item)objetivo);
}
//THIS CHUNK OF CODE IS ABSOLUTE LEGACY
//"LOS INMORTALES" IS THE ONLY REASON TO KEEP IT
//para cada grupo de primeras palabras del string (dar, dar ca�a, dar ca�a al, dar ca�a al di�bolo) intentamos ejecutar c�digo EVA.
for ( int i = 0 ; i <= StringMethods.numToks (arguments,' ') && !ejecutado ; i++ )
{
Item ourItem;
if ( objetivo instanceof Item )
ourItem = (Item) objetivo;
else
continue;
try
{
if ( i == 0 ) ejecutado = ejecutado || ourItem.execCode ( "command_" + command , "this: " + ourItem.getID() + "\n" + "room: " + habitacionActual.getID() + "\n" + "location: inventory" + "\n" + "player: " + getID() );
else ejecutado = ejecutado || ourItem.execCode ( ( "command_" + command + "_" + StringMethods.getToks( arguments , 1, i , ' ' ) ).replace(' ','_') , "this: " + ourItem.getID() + "\n" + "room: " + habitacionActual.getID() + "\n" + "location: inventory" + "\n" + "player: " + getID() );
}
catch ( EVASemanticException exc )
{
write(io.getColorCode("error") + "EVASemanticException found at command " + ( command + StringMethods.getToks( arguments , 1, i , ' ' ) ).replace(' ','_') + ", item number " + ourItem.getID() + io.getColorCode("reset") );
}
}
//ejecutar parseCommand() de objeto
if ( !onWorld && objetivo instanceof SupportingCode )
{
//in default mode, the following if ensures that standard parseCommand's are not executed on objects that are inside containers.
//to define commands on those objects we have to define parseCommandOnContents.
//in extended scope mode, this check is bypassed.
if ( path.size() == 1 || this.getPropertyValueAsBoolean("containedItemsInScope") )
{
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)objetivo).execCode ( "parseCommand" , new Object[] { this , command , fullArguments } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommand(), command was " + command + " " + fullArguments + ", item number " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommand(), command was " + command + " " + fullArguments + ", entity " + objetivo));
}
}
if ( !ejecutado && enableGenerics )
{
try
{
ejecutado = ejecutado || ((SupportingCode)objetivo).execCode ( "parseCommandGeneric" , new Object[] { this , command , fullArguments , "" , objetivo , null , new Boolean(true) } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandGeneric(), command was " + command + " " + fullArguments + ", entity number " + objetivo + ", second object was " + objetivo + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandGeneric(), command was " + command + " " + fullArguments + ", entity number " + objetivo + ", second object was " + null));
}
}
}
}
//lo mismo de mundo
if ( onWorld )
{
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || mundo.execCode ( "parseCommand" , new Object[] { this , command , fullArguments , objetivo } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommand() executed from world, command was " + command + " " + fullArguments + ", item number " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommand() executed from world, command was " + command + " " + fullArguments + ", entity " + objetivo));
}
}
if ( !ejecutado && enableGenerics )
{
try
{
ejecutado = ejecutado || mundo.execCode ( "parseCommandGeneric" , new Object[] { this , command , fullArguments , "" , objetivo , null } );
}
catch ( ScriptException te )
{
//write(io.getColorCode("error") + "bsh.TargetError found at parseCommandGeneric() executed from world, command was " + command + " " + fullArguments + ", entity number " + objetivo + ", second object was " + objetivo + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te,"parseCommandGeneric() executed from world, command was " + command + " " + fullArguments + ", entity " + objetivo + ", second object was " + null));
}
}
}
return ejecutado;
}
/**
* @param objetivos_s
* @param objetivos_p
* @param arguments
* @param onWorld -> true if it's the world parsecommands for one entity, false if it's the entity parsecommands
* @param enableGenerics -> if true, parseCommand*Generic methods are also executed. If false, they aren't.
* @return true if an end() has been hit, false otherwise
*/
public boolean resolveParseCommandForOneEntity ( EntityList posiblesObjetivos , String arguments , String fullArguments , boolean onWorld , boolean enableGenerics )
{
boolean ejecutado = false;
Vector objetivos_s = ParserMethods.refersToEntityInRecursive ( arguments,posiblesObjetivos,false ).toPathVector();
Vector objetivos_p = ParserMethods.refersToEntityInRecursive ( arguments,posiblesObjetivos,true ).toPathVector();
//objetivos_s has the form: [ [pearl,chest,box] , [pearl,bottle] ]
//(each component is a path to a matched object, only the 1st (top priority) is really used).
//in the plural case, all components are used.
//TODO
//we can now migrate this to refersToEntityInRecursive. This returns a Vector of Vectors with paths to stuff.
//we can call parseCommandOnContents on the intermediate nodes in the path and finally parseCommand on the final entity
//(if the previous parseCommandOnContents have let us, of course).
//LET'S TRY TO F...ING DO THIS
//[pearl,box,chest] vector
matchedOneEntityPermissive = ( objetivos_s.size() + objetivos_p.size() > 0 );
if ( objetivos_s.size() > 0 )
{
Vector objetivoVector = (Vector) objetivos_s.get(0);
ejecutado = executeParseCommandForOneEntity(fullArguments,objetivoVector,onWorld,enableGenerics,false);
if ( ejecutado ) //c�digo hizo end()
{
//luego esto lo hara el codigo
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
}
else if ( objetivos_p.size() > 0 )
{
//no era en singular, probamos en plural.
Entity objetivo;
resetZRPlural();
for ( int w = 0 ; w < objetivos_p.size() ; w++ )
{
//begin copy-pasted from singular
Vector objetivoVector = (Vector) objetivos_p.get(w);
ejecutado = executeParseCommandForOneEntity(fullArguments,objetivoVector,onWorld,enableGenerics,true);
if ( ejecutado ) //c�digo hizo end()
{
//luego esto lo hara el codigo
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
/*
//removed so that onContents is also executed on object itself.
//Replace this if if it is to be executed strictly on contents only.
//if ( objetivoVector.size() > 1 )
//{
Entity currentObject;
for ( int i = objetivoVector.size()-1; i >= 0 ; i-- )
{
currentObject = (Entity) objetivoVector.get(i);
//ejecutar parseCommandOnContents() de objeto
if ( !onWorld && currentObject instanceof SupportingCode )
{
if ( !ejecutado )
{
try
{
//parseCommandOnContents(Mobile,command,args,chain)
ejecutado = ejecutado || ((SupportingCode)currentObject).execCode ( "parseCommandOnContents" , new Object[] { this , command , fullArguments , objetivoVector } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContents(), command was " + command + fullArguments + ", entity " + currentObject + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
}
if ( !ejecutado && enableGenerics )
{
try
{
ejecutado = ejecutado || ((SupportingCode)currentObject).execCode ( "parseCommandOnContentsGeneric" , new Object[] { this , command , fullArguments , "" , objetivoVector , null , currentObject , null , new Boolean(true) } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsGeneric(), command was " + command + fullArguments + ", entity number " + currentObject + ", second object was " + null + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
}
}
if ( onWorld )
{
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || mundo.execCode ( "parseCommandOnContents" , new Object[] { this , command , fullArguments , objetivoVector , currentObject } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContents() executed from world, command was " + command + fullArguments + ", entity " + currentObject + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
}
if ( !ejecutado && enableGenerics )
{
try
{
ejecutado = ejecutado || mundo.execCode ( "parseCommandOnContentsGeneric" , new Object[] { this , command , fullArguments , "" , objetivoVector , null , currentObject , null } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommandOnContentsGeneric() executed from world, command was " + command + fullArguments + ", entity number " + currentObject + ", second object was " + null + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
}
}
}
//}
objetivo = (Entity) objetivoVector.get(0);
//end copy-pasted from singular
//a�adimos a ZR plural.
if ( objetivo instanceof Item )
meterObjetoEnZRPlural((Item)objetivo);
//THIS CHUNK OF CODE IS ABSOLUTE LEGACY
//"LOS INMORTALES" IS THE ONLY REASON TO KEEP IT
//para cada grupo de primeras palabras del string (dar, dar ca�a, dar ca�a al, dar ca�a al di�bolo) intentamos ejecutar c�digo EVA.
for ( int j = 0 ; j <= StringMethods.numToks (arguments,' ') && !ejecutado ; j++ )
{
Item ourItem;
if ( objetivo instanceof Item )
ourItem = (Item) objetivo;
else
continue;
try
{
if ( j == 0 ) ejecutado = ejecutado || ourItem.execCode ( "command_" + command , "this: " + ourItem.getID() + "\n" + "room: " + habitacionActual.getID() + "\n" + "location: inventory" + "\n" + "player: " + getID() );
else ejecutado = ejecutado || ourItem.execCode ( ( "command_" + command + "_" + StringMethods.getToks( arguments , 1, j , ' ' ) ).replace(' ','_') , "this: " + ourItem.getID() + "\n" + "room: " + habitacionActual.getID() + "\n" + "location: inventory" + "\n" + "player: " + getID() );
}
catch ( EVASemanticException exc )
{
write(io.getColorCode("error") + "EVASemanticException found at command " + ( command + StringMethods.getToks( arguments , 1, j , ' ' ) ).replace(' ','_') + ", item number " + ourItem.getID() + io.getColorCode("reset") );
}
}
//ahora vamos con el c�digo BeanShell, m�s simple, simplemente ejecutamos la funci�n parseCommand.
if ( !onWorld && objetivo instanceof SupportingCode )
{
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)objetivo).execCode ( "parseCommand" , new Object[] { this , command , fullArguments } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommand(), command was " + command + fullArguments + ", item number " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
}
if ( !ejecutado && enableGenerics )
{
try
{
ejecutado = ejecutado || ((SupportingCode)objetivo).execCode ( "parseCommandGeneric" , new Object[] { this , command , fullArguments , "" , objetivo , null , new Boolean(true) } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommandGeneric(), command was " + command + fullArguments + ", entity number " + objetivo + ", second object was " + objetivo + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
}
}
if ( onWorld )
{
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || mundo.execCode ( "parseCommand" , new Object[] { this , command , fullArguments , objetivo } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommand() executed from world, command was " + command + fullArguments + ", item number " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
}
if ( !ejecutado && enableGenerics ) //this one was added 2011-10-04 - apparently missing before!
{
try
{
ejecutado = ejecutado || mundo.execCode ( "parseCommandGeneric" , new Object[] { this , command , fullArguments , "" , objetivo , null } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommandGeneric() executed from world, command was " + command + fullArguments + ", entity number " + objetivo + ", second object was " + objetivo + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
}
}
*/
}
if ( ejecutado )
{
//luego esto lo hara el codigo
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
} //end if pattern matching vector size not zero
return false; //no "end" has been hit
}
/**
* @param objetivos_s
* @param objetivos_p
* @param arguments
* @return true if an end() has been hit, false otherwise
*/
public boolean resolveParseCommandForOneEntity_old ( EntityList posiblesObjetivos , String arguments , String fullArguments )
{
boolean ejecutado = false;
Vector objetivos_s = ParserMethods.refersToEntityIn ( arguments,posiblesObjetivos,false ).toEntityVector();
Vector objetivos_p = ParserMethods.refersToEntityIn ( arguments,posiblesObjetivos,true ).toEntityVector();
//TODO
//we can now migrate this to refersToEntityInRecursive. This returns a Vector of Vectors with paths to stuff.
//we can call parseCommandOnContents on the intermediate nodes in the path and finally parseCommand on the final entity
//(if the previous parseCommandOnContents have let us, of course).
if ( objetivos_s.size() > 0 )
{
Entity objetivo = (Entity)objetivos_s.get(0);
//�ste ser� el objeto principal sobre el que ejecutemos el comando en singular (cualquiera, aunque no sea BSH) si hace referencia a un solo objeto
if ( objetivo instanceof Item )
meterObjetoEnZRSingular((Item)objetivo);
//THIS CHUNK OF CODE IS ABSOLUTE LEGACY
//"LOS INMORTALES" IS THE ONLY REASON TO KEEP IT
//para cada grupo de primeras palabras del string (dar, dar ca�a, dar ca�a al, dar ca�a al di�bolo) intentamos ejecutar c�digo EVA.
for ( int i = 0 ; i <= StringMethods.numToks (arguments,' ') && !ejecutado ; i++ )
{
Item ourItem;
if ( objetivo instanceof Item )
ourItem = (Item) objetivo;
else
continue;
try
{
if ( i == 0 ) ejecutado = ejecutado || ourItem.execCode ( "command_" + command , "this: " + ourItem.getID() + "\n" + "room: " + habitacionActual.getID() + "\n" + "location: inventory" + "\n" + "player: " + getID() );
else ejecutado = ejecutado || ourItem.execCode ( ( "command_" + command + "_" + StringMethods.getToks( arguments , 1, i , ' ' ) ).replace(' ','_') , "this: " + ourItem.getID() + "\n" + "room: " + habitacionActual.getID() + "\n" + "location: inventory" + "\n" + "player: " + getID() );
}
catch ( EVASemanticException exc )
{
write(io.getColorCode("error") + "EVASemanticException found at command " + ( command + StringMethods.getToks( arguments , 1, i , ' ' ) ).replace(' ','_') + ", item number " + ourItem.getID() + io.getColorCode("reset") );
}
}
//ejecutar parseCommand() de objeto
if ( objetivo instanceof SupportingCode )
{
try
{
ejecutado = ejecutado || ((SupportingCode)objetivo).execCode ( "parseCommand" , new Object[] { this , command , fullArguments } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommand(), command was " + command + " " + fullArguments + ", item number " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)objetivo).execCode ( "parseCommandGeneric" , new Object[] { this , command , fullArguments , "" , objetivo , null , new Boolean(true) } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommandGeneric(), command was " + command + " " + fullArguments + ", entity number " + objetivo + ", second object was " + objetivo + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
}
}
if ( ejecutado ) //c�digo hizo end()
{
//luego esto lo hara el codigo
setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
}
else if ( objetivos_p.size() > 0 )
{
//no era en singular, probamos en plural.
Entity objetivo;
resetZRPlural();
for ( int i = 0 ; i < objetivos_p.size() ; i++ )
{
objetivo = (Entity)objetivos_p.get(i);
//a�adimos a ZR plural.
if ( objetivo instanceof Item )
meterObjetoEnZRPlural((Item)objetivo);
//THIS CHUNK OF CODE IS ABSOLUTE LEGACY
//"LOS INMORTALES" IS THE ONLY REASON TO KEEP IT
//para cada grupo de primeras palabras del string (dar, dar ca�a, dar ca�a al, dar ca�a al di�bolo) intentamos ejecutar c�digo EVA.
for ( int j = 0 ; j <= StringMethods.numToks (arguments,' ') && !ejecutado ; j++ )
{
Item ourItem;
if ( objetivo instanceof Item )
ourItem = (Item) objetivo;
else
continue;
try
{
if ( j == 0 ) ejecutado = ejecutado || ourItem.execCode ( "command_" + command , "this: " + ourItem.getID() + "\n" + "room: " + habitacionActual.getID() + "\n" + "location: inventory" + "\n" + "player: " + getID() );
else ejecutado = ejecutado || ourItem.execCode ( ( "command_" + command + "_" + StringMethods.getToks( arguments , 1, i , ' ' ) ).replace(' ','_') , "this: " + ourItem.getID() + "\n" + "room: " + habitacionActual.getID() + "\n" + "location: inventory" + "\n" + "player: " + getID() );
}
catch ( EVASemanticException exc )
{
write(io.getColorCode("error") + "EVASemanticException found at command " + ( command + StringMethods.getToks( arguments , 1, i , ' ' ) ).replace(' ','_') + ", item number " + ourItem.getID() + io.getColorCode("reset") );
}
}
//ahora vamos con el c�digo BeanShell, m�s simple, simplemente ejecutamos la funci�n parseCommand.
if ( objetivo instanceof SupportingCode )
{
try
{
ejecutado = ejecutado || ((SupportingCode)objetivo).execCode ( "parseCommand" , new Object[] { this , command , fullArguments } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommand(), command was " + command + " " + fullArguments + ", item number " + objetivo.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( !ejecutado )
{
try
{
ejecutado = ejecutado || ((SupportingCode)objetivo).execCode ( "parseCommandGeneric" , new Object[] { this , command , fullArguments , "" , objetivo , null , new Boolean(true) } );
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at parseCommandGeneric(), command was " + command + " " + fullArguments + ", entity number " + objetivo + ", second object was " + objetivo + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
}
}
}
if ( ejecutado )
{
//luego esto lo hara el codigo
setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
} //end if pattern matching vector size not zero
return false; //no "end" has been hit
}
protected boolean hacerHechizo ( EntityList possibleTargets , SpellList possibleSpells ) //uses "arguments" attr
{
if ( possibleTargets == null || possibleTargets.isEmpty() ) return false;
boolean mirado = false;
Vector[] patternMatchVectorSingSing = Matches.toEntityVectors(possibleSpells.patternMatchTwo ( possibleTargets , arguments , false , false )); //en singular y singular
Vector[] patternMatchVectorSingPlur = Matches.toEntityVectors(possibleSpells.patternMatchTwo ( possibleTargets , arguments , false , true )); //en singular y plural
Vector[] patternMatchVectorPlurSing = Matches.toEntityVectors(possibleSpells.patternMatchTwo ( possibleTargets , arguments , true , false )); //en plural y singular
Vector[] patternMatchVectorPlurPlur = Matches.toEntityVectors(possibleSpells.patternMatchTwo ( possibleTargets , arguments , true , true )); //en plural y plural
if ( patternMatchVectorSingSing != null && patternMatchVectorSingSing[0].size() > 0 ) //hacemos un hechizo hacia un objetivo
{
mirado = true;
Vector[] theVectors = patternMatchVectorSingSing;
//OK, hacer el hechizo
Entity objetivo = (Entity) theVectors[1].elementAt(0);
//ADD ENEMY HERE JUSTIF COMBAT SPELL (SUBSTITUTE THAT COMMENT FOR IT)
/*
if ( !hasEnemy ( objetivo ) )
{
addEnemy(objetivo);
}
if ( !objetivo.hasEnemy(this) )
{
objetivo.addEnemy(this);
}
*/
cast ( (Spell)(theVectors[0].elementAt(0)) , objetivo );
}
else //try to cast with nullified target
{
Vector patternMatchSpellOnly = possibleSpells.patternMatch ( arguments , false ).toEntityVector();
if ( patternMatchSpellOnly != null && patternMatchSpellOnly.size() > 0 )
{
mirado = true;
cast ( (Spell) patternMatchSpellOnly.elementAt(0) , null );
}
}
return mirado;
} //end method hacer hechizo
/**
* Executes the parseCommand() methods that apply for the current command/arguments in a given scope.
* Returns true if execution of parseCommand() methods was terminated by an end(), and false otherwise.
* If execution was terminated by an end() and parseCommand() methods didn't explicitly update this Mobile's state, then this method updates the state and its timer to (IDLE,1).
* @param scope
* @return true if end() was hit, false otherwise.
*/
protected boolean runParseCommandMethods ( EntityList scope )
{
/*
* As of 2013-03-17, we split this method in the following way:
* - This method does the state handling (i.e. sets the state to IDLE and timer to 1 if the parseCommands hit an end() but the state was not changed).
* - The execution of the parseCommands themselves is delegated into the doRunParseCommandMethods.
*/
int origState = getState();
long origTimeLeft = getPropertyTimeLeft("state");
setProperty ( "originState" , origState ); //this is just for compatibility
boolean foundEnd = doRunParseCommandMethods(scope);
if ( foundEnd && getState() == origState && getPropertyTimeLeft("state") == origTimeLeft )
{
/*
* if the parseCommand methods have hit an end() (and thereby declared the command as processed) but
* they haven't touched the state, we set state to (IDLE,1) so that the next command will be processed as normal.
*/
setNewState ( IDLE , 1 );
}
return foundEnd;
}
/**
* Executes the parseCommand() methods that apply for the current command/arguments in a given scope.
* @param scope
* @return true if end() was hit, false otherwise.
*/
private boolean doRunParseCommandMethods(EntityList scope)
{
//***
//*** BEGIN EXECUTION OF parseCommand() METHODS
//***
boolean ejecutado = false;
//codigo bsh en el jugador
try
{
ReturnValue retval = new ReturnValue(null);
ejecutado = ejecutado || execCode( "parseCommand" , new Object[] { command , arguments } , retval );
if ( retval.getRetVal() != null )
{
commandstring = (String)retval.getRetVal();
//Debug.println("Command String Changed To " + (String)retval.getRetVal());
command = lenguaje.extractVerb(commandstring).trim(); //StringMethods.getTok(commandstring,1,' ').trim();
arguments = lenguaje.extractArguments(commandstring).trim(); //StringMethods.getToks(commandstring,2,StringMethods.numToks(commandstring,' '),' ').trim();
}
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at player's parseCommand, command was " + command + " " + arguments + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( ejecutado )
{
//luego esto lo hara el codigo
//setNewState( 1 /*IDLE*/, 1 );
mentions.setLastMentionedVerb(command);
return true;
}
//[04.03.04] Tocho grande de c�digo (ejecutar comando personalizado con items de
//inventario y con items de habitaci�n) sustituido por tocho m�s simple (ejecutar
//comando personalizado con objetivos)
ejecutado = false;
matchedOneEntity = false;
matchedTwoEntities = false;
matchedOneEntityPermissive = false;
matchedTwoEntitiesPermissive = false;
/*
Vector[] objetivos_ss = ParserMethods.refersToEntitiesIn ( arguments,posiblesObjetivos,posiblesObjetivos,false,false);
Vector[] objetivos_sp = ParserMethods.refersToEntitiesIn ( arguments,posiblesObjetivos,posiblesObjetivos,false,true);
Vector[] objetivos_ps = ParserMethods.refersToEntitiesIn ( arguments,posiblesObjetivos,posiblesObjetivos,true,false);
Vector[] objetivos_pp = ParserMethods.refersToEntitiesIn ( arguments,posiblesObjetivos,posiblesObjetivos,true,true);
*/
List matches_ss = ParserMethods.parseReferencesToEntitiesIn( arguments,scope,scope,false,false);
List matches_sp = ParserMethods.parseReferencesToEntitiesIn( arguments,scope,scope,false,true);
List matches_ps = ParserMethods.parseReferencesToEntitiesIn( arguments,scope,scope,true,false);
List matches_pp = ParserMethods.parseReferencesToEntitiesIn( arguments,scope,scope,true,true);
List allMatches = new ArrayList();
allMatches.addAll(matches_ss);
allMatches.addAll(matches_sp);
allMatches.addAll(matches_ps);
allMatches.addAll(matches_pp);
matchedTwoEntities = ( allMatches.size() > 0 );
Matches matches_s = ParserMethods.refersToEntityInRecursive ( arguments,scope,false );
Matches matches_p = ParserMethods.refersToEntityInRecursive ( arguments,scope,true );
matchedOneEntity = ( matches_s.size() > 0 || matches_p.size() > 0 );
if ( matches_s.getBestPriority() == 0 )
oneEntityPriority = matches_p.getBestPriority();
else if ( matches_p.getBestPriority() == 0 )
oneEntityPriority = matches_s.getBestPriority();
else oneEntityPriority = Math.min(matches_s.getBestPriority(),matches_p.getBestPriority());
//let's see if this works.
ejecutado = resolveParseCommandForTwoEntities ( scope , arguments , arguments , false );
if ( ejecutado ) //c�digo hizo end()
{
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
//ejecutar parseCommand sobre una entidad, if possible
if ( !matchedTwoEntitiesPermissive ) //TODO: add possibility of setting property so that parseCommands for one entity will also be executed when two are matched.
ejecutado = resolveParseCommandForOneEntity ( scope , arguments , arguments , false , true );
if ( ejecutado ) //c�digo hizo end()
{
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
//A.
//comandos sobre un componente: s�lo se ejecutan si no matchearon comandos con objetos
//("coger bast�n del suelo" debe ejecutarse antes como comando sobre objeto bast�n que sobre componente suelo)
//(also, comandos sobre componentes no se ejecutan si el verbo no es reconocido, para que funcione bien "coger espada y bast�n del suelo")
//(si no, har�amos: coger espada (OK), bast�n del suelo (comando sobre "suelo", pifia)
if ( !matchedOneEntity && !matchedTwoEntities && lenguaje.isVerb(command) )
{
EntityList posiblesObjetivosForComponents = (EntityList) scope.clone();
posiblesObjetivosForComponents.addEntity(this.getRoom()); //componentes pueden ser de habitaci�n
ejecutado = resolveParseCommandForOneComponent ( posiblesObjetivosForComponents , arguments );
if ( ejecutado ) //c�digo hizo end()
{
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
}
//primero vemos si hay una definicion especifica del comando en la habitacion, con o sin argumentos
//si la definicion esta especificada sin argumentos y hay argumentos, los dejamos en el data segment.
//(argumentos flexibles) <-- todo esto c�digo EVA
ejecutado = false;
try
{
ejecutado = habitacionActual.execCode("command_" + command + "_" + arguments.replace(' ' , '_' ), "this: " + habitacionActual.getID() + "\n" + "player: " + getID() );
if ( !ejecutado ) //no habia comando definido para esos argumentos concretos, probamos sin argumentos
{
if ( arguments != null ) ejecutado = habitacionActual.execCode("command_" + command , "this: " + habitacionActual.getID() + "\nargs: " + arguments + "\n" + "player: " + getID() );
else if ( arguments == null ) ejecutado = habitacionActual.execCode("command_" + command , "this: " + habitacionActual.getID() + "\n" + "player: " + getID() );
}
}
catch ( EVASemanticException exc )
{
write(io.getColorCode("error") + "EVASemanticException found at room command , room number " + habitacionActual.getID() + io.getColorCode("reset") );
}
//ahora vamos con el c�digo BeanShell, m�s simple, simplemente ejecutamos la funci�n parseCommand.
try
{
ejecutado = ejecutado || habitacionActual.execCode ( "parseCommand" , new Object[] { this , command , arguments } );
}
catch ( ScriptException te )
{
te.printStackTrace();
write(io.getColorCode("error") + "bsh.TargetError found at parseCommand(), command was " + command + " " + arguments + ", room number " + habitacionActual.getID() + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( ejecutado )
{
mentions.setLastMentionedVerb(command);
return true ;
}
//parseCommands de los objetos definidos en el mundo.
ejecutado = resolveParseCommandForTwoEntities ( scope , arguments , arguments , true );
if ( ejecutado ) //c�digo hizo end()
{
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
if ( !matchedTwoEntitiesPermissive ) //TODO: add possibility of setting property so that parseCommands for one entity will also be executed when two are matched.
ejecutado = resolveParseCommandForOneEntity ( scope , arguments , arguments , true , true );
if ( ejecutado ) //c�digo hizo end()
{
//setNewState( 1 , 1 );
mentions.setLastMentionedVerb(command);
return true;
}
//parseCommand() del mundo, lo �ltimo que se ejecuta antes de las respuestas por defecto del sistema.
try
{
ReturnValue retval = new ReturnValue(null);
ejecutado = ejecutado || mundo.execCode( "parseCommand" , new Object[] { this , command , arguments } , retval );
if ( retval.getRetVal() != null )
{
commandstring = (String)retval.getRetVal();
//Debug.println("Command String Changed To " + (String)retval.getRetVal());
command = lenguaje.extractVerb(commandstring).trim(); //StringMethods.getTok(commandstring,1,' ').trim();
arguments = lenguaje.extractArguments(commandstring).trim(); //StringMethods.getToks(commandstring,2,StringMethods.numToks(commandstring,' '),' ').trim();
}
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at world's parseCommand, command was " + command + " " + arguments + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( ejecutado )
{
//luego esto lo hara el codigo
//setNewState( 1 , 1 ); //idle state
mentions.setLastMentionedVerb(command);
return true;
}
return false;
}
public void cancelPending() {
commandQueue.removeAllElements();
}
public boolean oneTargetAction(String action, String arguments, EntityList posiblesObjetivos) {
Vector patternMatchVectorSing = new Vector();
Vector patternMatchVectorPlur = new Vector();
if ( posiblesObjetivos != null )
{
patternMatchVectorSing = posiblesObjetivos.patternMatch ( arguments , false ).toEntityVector(); //en singular
patternMatchVectorPlur = posiblesObjetivos.patternMatch ( arguments , true ).toEntityVector(); //en plural
}
if ( patternMatchVectorSing.size() > 0 )
{
Entity ourEntity = (Entity)patternMatchVectorSing.elementAt(0); //el de mas prioridad
boolean hecho = executeAction ( action , new Object[]
{ourEntity
} );
if ( ! hecho )
{
mentions.setLastMentionedVerb(command);
cancelPending();
setNewState(IDLE,1); //the action failed, so the player is ready to do more stuff.
return false;
}
else
{
//setNewState( 1 /*IDLE*/, 5 ); //action does it
mentions.setLastMentionedVerb(command);
return true;
}
}
else if ( patternMatchVectorPlur.size() > 0 )
{
for ( int i = 0 ; i < patternMatchVectorPlur.size() ; i++ )
{
Entity ourEntity = (Entity)patternMatchVectorPlur.elementAt(i);
boolean hecho = executeAction ( action , new Object[]
{ourEntity
} );
if ( ! hecho )
{
mentions.setLastMentionedVerb(command);
cancelPending();
if ( i == 0 ) setNewState(IDLE,1); //the action (even the first one) failed, so the player is ready to do more stuff.
return false;
}
}
//setNewState( 1 /*IDLE*/, 5 ); //action does it
mentions.setLastMentionedVerb(command);
return true;
}
else
{
//jugador.escribirDenegacionComando( io.getColorCode("denial") + "�Qu� pretendes quitarte?\n" + io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
setNewState(IDLE,1); //the action failed, so the player is ready to do more stuff.
return false;
}
}
protected boolean cogerContenidoEspecificandoContenedor(String args,
Inventory inv, String infoString) {
boolean mirado = false;
Vector patternMatchVectorSing = null; //containers s�lo en singular
//Debug.println("Args: " + args + " Inv: " + inv );
if ( inv != null && !inv.isEmpty() )
{
patternMatchVectorSing = inv.patternMatch( args , false ).toEntityVector(); //contenedor al fin
if ( patternMatchVectorSing != null && patternMatchVectorSing.size() > 0 ) //ponemos una cosa en un sitio
{
for ( int i = 0 ; i < patternMatchVectorSing.size() ; i++ )
{
Item ourContainer = (Item)patternMatchVectorSing.elementAt(i);
if ( ourContainer.isContainer() //container y abierto si se abre
&& !( ourContainer.isCloseable() && !ourContainer.isOpen() ) )
{
//Debug.println("Our container: " + ourContainer);
int ntokens = StringMethods.numToks ( args , ' ' );
//eliminar el nombre del contenedor... en el ejemplo, quitar� el de armario al encontrar sentido a "pilas"
//punto_division empieza en ntokens-2 porque uno nos lo cargamos fijo.
for ( int punto_division = ntokens-1 ; punto_division >= 1 ; punto_division-- )
{
//Debug.println("Division: " + StringMethods.getToks ( args , 1 , punto_division , ' ' ) );
//Debug.println("mirado: " + mirado);
mirado = mirado || cogerItem ( StringMethods.getToks ( args , 1 , punto_division , ' ' ) , ourContainer.getContents() , " " + mundo.getMessages().getMessage("get.prep.from") + " " + ourContainer.constructName2True ( 1 , this ) + infoString );
//Debug.println("called cogerItem. Now mirado is " + mirado);
if ( mirado ) break;
}
if ( mirado ) break;
}
}
}
}
return mirado;
}
private boolean cogerContenido(String args, Inventory inv, String infoString) {
boolean mirado = false;
if ( inv == null || inv.isEmpty() ) return false;
for ( int i = 0 ; i < inv.size() ; i++ )
{
if ( inv.elementAt(i).isContainer() && !( inv.elementAt(i).isCloseable() && !inv.elementAt(i).isOpen() ) )
{
String tempstring = infoString;
infoString += (" " + mundo.getMessages().getMessage("get.prep.from") + " ");
infoString += inv.elementAt(i).constructName2True ( 1 , this );
//para que muestre "coges la moneda EN el cofre", p.ej.
mirado = cogerItem ( args , inv.elementAt(i).getContents() , infoString );
if ( mirado ) break;
infoString = tempstring;
}
}
if ( !mirado )
{
for ( int i = 0 ; i < inv.size() ; i++ )
{
if ( inv.elementAt(i).isContainer() && !( inv.elementAt(i).isCloseable() && !inv.elementAt(i).isOpen() ) )
{
String tempstring = infoString;
infoString += (" " + mundo.getMessages().getMessage("get.prep.from") + " ");
infoString += inv.elementAt(i).constructName2True ( 1 , this );
mirado = cogerContenido ( args , inv.elementAt(i).getContents() , infoString );
if ( mirado ) break;
infoString = tempstring;
}
}
}
return mirado;
}
protected boolean cogerContenido(Inventory inv, String infoString) {
boolean mirado = false;
if ( inv == null || inv.isEmpty() ) return false;
for ( int i = 0 ; i < inv.size() ; i++ )
{
if ( inv.elementAt(i).isContainer() && !( inv.elementAt(i).isCloseable() && !inv.elementAt(i).isOpen() ) )
{
String tempstring = infoString;
String toConcat = (" " + mundo.getMessages().getMessage("get.prep.from") + " ") + inv.elementAt(i).constructName2True ( 1 , this );
infoString = toConcat + infoString;
//para que muestre "coges la moneda EN el cofre", p.ej.
mirado = cogerItem ( inv.elementAt(i).getContents() , infoString );
if ( mirado ) break;
infoString = tempstring;
}
}
if ( !mirado )
{
for ( int i = 0 ; i < inv.size() ; i++ )
{
if ( inv.elementAt(i).isContainer() && !( inv.elementAt(i).isCloseable() && !inv.elementAt(i).isOpen() ) )
{
String tempstring = infoString;
String toConcat = (" " + mundo.getMessages().getMessage("get.prep.from") + " ") + inv.elementAt(i).constructName2True ( 1 , this );
infoString = toConcat + infoString;
mirado = cogerContenido ( inv.elementAt(i).getContents() , infoString );
if ( mirado ) break;
infoString = tempstring;
}
}
}
return mirado;
}
protected boolean cogerItem(Inventory inv, String extraInfo) {
return cogerItem ( arguments , inv , extraInfo );
} //end method
protected boolean abrirPuertaConLlave(Inventory i1, Inventory i2) {
boolean mirado = false;
List[] pairsVector = patternMatchPairs ( i1 , i2 , arguments );
List puertas = pairsVector[0];
List llaves = pairsVector[1];
if ( puertas.size() == 0 ) return false; //no matching pairs present
for ( int i = 0 ; i < puertas.size() ; i++ )
{
Item ourDoor = (Item)puertas.get(i);
Item ourKey = (Item)llaves.get(i);
habitacionActual.reportAction(this,ourDoor,new Entity[]{ourKey},"$1 intenta abrir $2 con $3.\n","$1 intenta abrirte con $3.\n","Intentas abrir $2 con $3.\n",false);
write( io.getColorCode("action") + ((Item)ourDoor).unlock(ourKey,this) + io.getColorCode("reset") + "\n" );
}
return true;
}
protected boolean bloquearBichoConArma(MobileList ml, Inventory i) {
if ( i == null || i.isEmpty() || ml == null || ml.isEmpty() ) return false;
boolean mirado = false;
Vector[] patternMatchVectorSingSing = Matches.toEntityVectors(ml.patternMatchTwo ( i , arguments , false , false )); //en singular y singular
Vector[] patternMatchVectorSingPlur = Matches.toEntityVectors(ml.patternMatchTwo ( i , arguments , false , true )); //en singular y plural
Vector[] patternMatchVectorPlurSing = Matches.toEntityVectors(ml.patternMatchTwo ( i , arguments , true , false )); //en plural y singular
Vector[] patternMatchVectorPlurPlur = Matches.toEntityVectors(ml.patternMatchTwo ( i , arguments , true , true )); //en plural y plural
if ( patternMatchVectorSingSing != null && patternMatchVectorSingSing[0].size() > 0 ) //atacamos un bicho con un arma
{
mirado = true;
Vector[] theVectors = patternMatchVectorSingSing;
//OK, hacer el ataque
Mobile objetivo = (Mobile) theVectors[0].elementAt(0);
if ( !hasEnemy ( objetivo ) )
{
return false; //bloquearse de alguien que, el pobre, no nos pega
}
lastBlockWeapon = (Weapon)(theVectors[1].elementAt(0)); //guardamos el arma que se us� por si en un ataque posterior no se especifica cu�l usar
lastBlockedEnemy = objetivo; //idem con el bicho
block ( objetivo , (Weapon)(theVectors[1].elementAt(0)) );
}
else //no se especifica bicho y arma. Mirar si se especifica uno de ellos, al menos.
{
Vector patternMatchVectorSingBicho = ml.patternMatch ( arguments , false ).toEntityVector();
Vector patternMatchVectorSingArma = i.patternMatch ( arguments , false ).toEntityVector();
if ( patternMatchVectorSingBicho != null && patternMatchVectorSingBicho.size() > 0 )
{
Mobile objetivo = (Mobile) patternMatchVectorSingBicho.elementAt(0);
Weapon usada = null;
if ( lastBlockWeapon != null && wieldedWeapons.contains(lastBlockWeapon) )
{
usada = lastBlockWeapon;
}
else if ( wieldedWeapons != null && wieldedWeapons.size() > 0 )
{
usada = (Weapon) wieldedWeapons.elementAt(0);
}
if ( usada == null )
{
mirado = false;
}
else
{
mirado = true;
if ( !hasEnemy ( objetivo ) )
{
return false;
}
lastBlockWeapon = usada;
lastBlockedEnemy = objetivo;
block ( objetivo , usada );
}
}
else if ( patternMatchVectorSingArma != null && patternMatchVectorSingArma.size() > 0 )
{
Mobile objetivo = null;
Weapon usada = (Weapon) patternMatchVectorSingArma.elementAt(0);
if ( lastAttackedEnemy != null && habitacionActual.hasMobile ( lastAttackedEnemy ) )
{
objetivo = lastAttackedEnemy;
}
/*
else if ( getEnemies() != null && getEnemies().size() == 1 && habitacionActual.hasMobile((Mobile)getEnemies().get(0) ) )
{
//if there is a single enemy and it's in this room, there's no doubt we want to block him
objetivo = (Mobile) getEnemies().get(0);
}
*/
else if ( habitacionActual.getMobiles().size() == 2 && getEnemies() != null )
{
//if we are alone in the room with an enemy, the target is obviously that enemy.
if ( hasEnemy(habitacionActual.getMobiles().elementAt(0)) )
objetivo = habitacionActual.getMobiles().elementAt(0);
if ( hasEnemy(habitacionActual.getMobiles().elementAt(1)) )
objetivo = habitacionActual.getMobiles().elementAt(1);
}
if ( objetivo == null )
{
mirado = false;
}
else
{
mirado = true;
if ( !hasEnemy ( objetivo ) )
{
return false;
}
lastBlockWeapon = usada;
lastBlockedEnemy = objetivo;
block ( objetivo , usada );
}
}
else //bicho and arma unspecified
{
Mobile objetivo = null;
Weapon usada = null;
//assign a weapon
if ( lastBlockWeapon != null && wieldedWeapons.contains(lastBlockWeapon) )
{
usada = lastBlockWeapon;
}
else if ( wieldedWeapons != null && wieldedWeapons.size() > 0 )
{
usada = (Weapon) wieldedWeapons.elementAt(0);
}
//assign an enemy
if ( lastAttackedEnemy != null && habitacionActual.hasMobile ( lastAttackedEnemy ) )
{
objetivo = lastAttackedEnemy;
}
/*
else if ( getEnemies() != null && getEnemies().size() == 1 && habitacionActual.hasMobile((Mobile)getEnemies().get(0) ) )
{
//if there is a single enemy and it's in this room, there's no doubt we want to block him
objetivo = (Mobile) getEnemies().get(0);
}
*/
else if ( habitacionActual.getMobiles().size() == 2 && getEnemies() != null )
{
//if we are alone in the room with an enemy, the target is obviously that enemy.
if ( hasEnemy(habitacionActual.getMobiles().elementAt(0)) )
objetivo = habitacionActual.getMobiles().elementAt(0);
if ( hasEnemy(habitacionActual.getMobiles().elementAt(1)) )
objetivo = habitacionActual.getMobiles().elementAt(1);
}
if ( objetivo == null || usada == null )
{
mirado = false;
}
else
{
mirado = true;
if ( !hasEnemy ( objetivo ) )
{
return false;
}
lastBlockWeapon = usada;
lastBlockedEnemy = objetivo;
block ( objetivo , usada );
}
}
}
return mirado;
}
//return true if processed
protected boolean atacarBichoConArma(MobileList ml, Inventory i) {
if ( ml == null || ml.isEmpty() ) return false; //no one to attack
if ( i == null || i.isEmpty() )
{
//no weapons -> no podemos atacar
writeDenial ( mundo.getMessages().getMessage("no.attack.weapon") );
return true; //we have processed everything and given a message
}
boolean mirado = false;
Vector[] patternMatchVectorSingSing = Matches.toEntityVectors(ml.patternMatchTwo ( i , arguments , false , false )); //en singular y singular
Vector[] patternMatchVectorSingPlur = Matches.toEntityVectors(ml.patternMatchTwo ( i , arguments , false , true )); //en singular y plural
Vector[] patternMatchVectorPlurSing = Matches.toEntityVectors(ml.patternMatchTwo ( i , arguments , true , false )); //en plural y singular
Vector[] patternMatchVectorPlurPlur = Matches.toEntityVectors(ml.patternMatchTwo ( i , arguments , true , true )); //en plural y plural
if ( patternMatchVectorSingSing != null && patternMatchVectorSingSing[0].size() > 0 ) //atacamos un bicho con un arma
{
mirado = true;
Vector[] theVectors = patternMatchVectorSingSing;
//OK, hacer el ataque
Mobile objetivo = (Mobile) theVectors[0].elementAt(0);
if ( !hasEnemy ( objetivo ) )
{
addEnemy(objetivo);
}
if ( !objetivo.hasEnemy(this) )
{
objetivo.addEnemy(this);
}
lastAttackWeapon = (Weapon)(theVectors[1].elementAt(0)); //guardamos el arma que se us� por si en un ataque posterior no se especifica cu�l usar
lastAttackedEnemy = objetivo; //idem con el bicho
attack ( objetivo , (Weapon)(theVectors[1].elementAt(0)) );
//escribir( io.getColorCode("action") + ((Item)(theVectors[0].elementAt(0))).unlock( (Item)(theVectors[1].elementAt(0)) ) + io.getColorCode("reset") + "\n" );
}
else //no se especifica bicho y arma. Mirar si se especifica uno de ellos, al menos.
{
Vector patternMatchVectorSingBicho = ml.patternMatch ( arguments , false ).toEntityVector();
Vector patternMatchVectorSingArma = i.patternMatch ( arguments , false ).toEntityVector();
if ( patternMatchVectorSingBicho != null && patternMatchVectorSingBicho.size() > 0 ) //bicho specified, arma unspecified
{
Mobile objetivo = (Mobile) patternMatchVectorSingBicho.elementAt(0);
Weapon usada = null;
Debug.println("Wielded Weapons Size " + wieldedWeapons.size() );
Inventory usableWeapons = getUsableWeapons();
if ( lastAttackWeapon != null && usableWeapons.contains(lastAttackWeapon) )
{
usada = lastAttackWeapon;
}
else if ( usableWeapons != null && usableWeapons.size() > 0 )
{
Debug.println("Setting first weapon as used");
//como por aqu� todav�a ten�amos inventarios paralelos, con nulos y cosas irregulares, hacemos algo extra�o:
for ( int k = usableWeapons.size()-1 ; k >= 0 ; k-- )
{
if ( usableWeapons.elementAt(k) != null )
usada = (Weapon) usableWeapons.elementAt(k);
}
}
if ( usada == null )
{
mirado = false;
}
else
{
mirado = true;
if ( !hasEnemy ( objetivo ) )
{
addEnemy(objetivo);
}
if ( !objetivo.hasEnemy(this) )
{
objetivo.addEnemy(this);
}
lastAttackWeapon = usada;
lastAttackedEnemy = objetivo;
attack ( objetivo , usada );
}
}
else if ( patternMatchVectorSingArma != null && patternMatchVectorSingArma.size() > 0 ) //specified arma, but not bicho
{
Mobile objetivo = null;
Weapon usada = (Weapon) patternMatchVectorSingArma.elementAt(0);
if ( lastAttackedEnemy != null && habitacionActual.hasMobile ( lastAttackedEnemy ) )
{
objetivo = lastAttackedEnemy;
}
/*
else if ( getEnemies() != null && getEnemies().size() == 1 && habitacionActual.hasMobile((Mobile)getEnemies().get(0) ) )
{
//if there is a single enemy and it's in this room, there's no doubt we want to block him
objetivo = (Mobile) getEnemies().get(0);
}
*/
else if ( habitacionActual.getMobiles().size() == 2 && getEnemies() != null )
{
//if we are alone in the room with an enemy, the target is obviously that enemy.
if ( hasEnemy(habitacionActual.getMobiles().elementAt(0)) )
objetivo = habitacionActual.getMobiles().elementAt(0);
if ( hasEnemy(habitacionActual.getMobiles().elementAt(1)) )
objetivo = habitacionActual.getMobiles().elementAt(1);
}
if ( objetivo == null )
{
mirado = false;
}
else
{
mirado = true;
if ( !hasEnemy ( objetivo ) )
{
addEnemy(objetivo);
}
if ( !objetivo.hasEnemy(this) )
{
objetivo.addEnemy(this);
}
lastAttackWeapon = usada;
lastAttackedEnemy = objetivo;
attack ( objetivo , usada );
}
}
else //bicho and arma unspecified
{
Mobile objetivo = null;
Weapon usada = null;
Inventory usableWeapons = getUsableWeapons();
//assign weapon
if ( lastAttackWeapon != null && usableWeapons.contains(lastAttackWeapon) )
{
usada = lastAttackWeapon;
}
else if ( usableWeapons != null && usableWeapons.size() > 0 )
{
//como por aqu� todav�a ten�amos inventarios paralelos, con nulos y cosas irregulares, hacemos algo extra�o:
for ( int k = usableWeapons.size()-1 ; k >= 0 ; k-- )
{
if ( usableWeapons.elementAt(k) != null )
usada = (Weapon) usableWeapons.elementAt(k);
}
}
//assign enemy
if ( lastAttackedEnemy != null && habitacionActual.hasMobile ( lastAttackedEnemy ) )
{
objetivo = lastAttackedEnemy;
}
/*
else if ( getEnemies() != null && getEnemies().size() == 1 && habitacionActual.hasMobile((Mobile)getEnemies().get(0) ) )
{
//if there is a single enemy and it's in this room, there's no doubt we want to block him
objetivo = (Mobile) getEnemies().get(0);
}
*/
else if ( habitacionActual.getMobiles().size() == 2 && getEnemies() != null )
{
//if we are alone in the room with an enemy, the target is obviously that enemy.
if ( hasEnemy(habitacionActual.getMobiles().elementAt(0)) )
objetivo = habitacionActual.getMobiles().elementAt(0);
if ( hasEnemy(habitacionActual.getMobiles().elementAt(1)) )
objetivo = habitacionActual.getMobiles().elementAt(1);
}
if ( objetivo == null || usada == null )
{
mirado = false;
}
else
{
mirado = true;
if ( !hasEnemy ( objetivo ) )
{
addEnemy(objetivo);
}
if ( !objetivo.hasEnemy(this) )
{
objetivo.addEnemy(this);
}
lastAttackWeapon = usada;
lastAttackedEnemy = objetivo;
attack ( objetivo , usada );
}
}
}
//de momento, no tratamos atacar a varios bichos con un arma.
//oh, tal vez, si llega a haber alabardas o bastadas por el estilo...
//mas not at the moment (03.02.25)
/*
else if ( patternMatchVectorSingPlur != null && patternMatchVectorSingPlur[0].size() > 0 )
{
mirado = true;
Vector[] theVectors = patternMatchVectorSingPlur;
for ( int i=0 ; i < theVectors[1].size() ; i++ )
{
Mobile ourMob = (Item)theVectors[0].elementAt(0);
Weapon ourKey = (Item)theVectors[1].elementAt(i);
escribir ( '\n' + "Intentas abrir " + "con " + ourKey.constructName2True ( 1 , ourKey.getState() ) + ": ");
escribir( io.getColorCode("action") + ((Item)ourDoor).unlock(ourKey) + io.getColorCode("reset") + "\n" );
}
}
else if ( patternMatchVectorPlurSing != null && patternMatchVectorPlurSing[0].size() > 0 )
{
mirado = true;
Vector[] theVectors = patternMatchVectorPlurSing;
for ( int i=0 ; i < theVectors[0].size() ; i++ )
{
Item ourDoor = (Item)theVectors[0].elementAt(i);
Item ourKey = (Item)theVectors[1].elementAt(0);
escribir ( '\n' + "Intentas abrir" + " con " + ourKey.constructName2True ( 1 , ourKey.getState() ) + ": ");
escribir( io.getColorCode("action") + ((Item)ourDoor).unlock(ourKey) + io.getColorCode("reset") + "\n" );
}
}
else if ( patternMatchVectorPlurPlur != null && patternMatchVectorPlurPlur[0].size() > 0 )
{
mirado = true;
Vector[] theVectors = patternMatchVectorPlurPlur;
for ( int i=0 ; i < theVectors[0].size() ; i++ )
{
for ( int j = 0 ; j < theVectors[1].size() ; j++ )
{
Item ourDoor = (Item)theVectors[0].elementAt(i);
Item ourKey = (Item)theVectors[1].elementAt(j);
escribir ( '\n' + "Intentas abrir " + "con " + ourKey.constructName2True ( 1 , ourKey.getState() ) + ": ");
escribir( io.getColorCode("action") + ((Item)ourDoor).unlock(ourKey) + io.getColorCode("reset") + "\n" );
}
}
}
*/
return mirado;
} //end method atacar bicho con arma
protected boolean cerrarPuertaConLlave(Inventory i1, Inventory i2) {
boolean mirado = false;
List[] pairsVector = patternMatchPairs ( i1 , i2 , arguments );
List puertas = pairsVector[0];
List llaves = pairsVector[1];
if ( puertas.size() == 0 ) return false; //no matching pairs present
for ( int i = 0 ; i < puertas.size() ; i++ )
{
Item ourDoor = (Item)puertas.get(i);
Item ourKey = (Item)llaves.get(i);
habitacionActual.reportAction(this,ourDoor,new Entity[]{ourKey},"$1 intenta cerrar $2 con $3.\n","$1 intenta cerrarte con $3.\n","Intentas cerrar $2 con $3.\n",false);
write( io.getColorCode("action") + ((Item)ourDoor).lock(ourKey,this) + io.getColorCode("reset") + "\n" );
}
return true;
}
//fuerza un comando
public void forceCommand(String s)
{
forced = true;
force_string = s;
if ( getState() == 0 ) setNewState( IDLE,1 ); //Mobiles by default have no state if they haven't done anything yet.
}
public void enqueueCommand(String s)
{
commandQueue.add(s);
if ( getState() == 0 ) setNewState( IDLE,1 ); //Mobiles by default have no state if they haven't done anything yet.
}
public void setCommandString(String s)
{
commandstring=s;
}
public boolean separateSentences() {
Vector tokensYSeparadores = StringMethods.tokenizeWithComplexSeparators ( commandstring , StringMethods.STANDARD_SENTENCE_SEPARATORS() , true );
Vector tempCommandQueue = new Vector();
int nComillas=0;
String acum="";
for ( int i = 0 ; i < tokensYSeparadores.size() ; i++ )
{
String cur = (String)tokensYSeparadores.elementAt(i);
acum = acum + cur;
for ( int k = 0 ; k < cur.length() ; k++ )
if ( cur.charAt(k) == '\"' )
nComillas++;
if ( !(StringMethods.STANDARD_SENTENCE_SEPARATORS()).contains(cur) ) //not separator
{
if ( nComillas % 2 == 0 || i == tokensYSeparadores.size()-1 ) //n�mero par de comillas hasta aqu� o �ltimo token
{
tempCommandQueue.add(acum);
Debug.println("ADDED: " + acum);
acum="";
}
}
else if ( nComillas % 2 == 0 )
acum="";
}
//from the older version
tempCommandQueue.addAll ( commandQueue );
commandQueue = (Vector)tempCommandQueue.clone();
if ( !commandQueue.isEmpty() )
{
commandstring = (String)commandQueue.elementAt(0);
commandQueue.removeElementAt(0);
}
else
{
//comando nulo
return false;
}
return true;
}
/**
A pesar del nombre ambiguo (no se me ocurr�a ninguno mejor, la verdad) esta funci�n
s�lo sirve para cuando no se ejecuta un comando porque no se entiende lo que viene
despu�s (por ejemplo, "coger adfasfg" o "coger <algo que no hay en la habitaci�n o
el programa no reconoce>"). Cuando no se ejecuta por motivos ya del juego (no coges
porque llevas demasiado peso, no miras porque est�s ciego, etc.) no se debe usar esto,
ya que en caso de second-chance da un mensaje que es claramente de error.
*/
private void escribirDenegacionComando(String s) {
if ( secondChance ) //estamos en la segunda oportunidad, i.e. con verbo inventado...
{
escribirErrorNoEntiendo ( );
}
else write(s);
}
public boolean execCommand(String commandstring) {
//conservative mode check
//this feature is only implemented for Spanish pronouns
if ( "es".equals(lenguaje.getLanguageCode()) && getPropertyValueAsBoolean("noPronounDisambiguation") && matchedTwoEntitiesPermissive )
{
if ( firstWord(commandstring).toLowerCase().endsWith ( "las" ) && firstWord(commandstring).length() > 3
|| firstWord(commandstring).toLowerCase().endsWith ( "los" ) && firstWord(commandstring).length() > 3
|| firstWord(commandstring).toLowerCase().endsWith ( "la" ) && firstWord(commandstring).length() > 2
|| firstWord(commandstring).toLowerCase().endsWith ( "lo" ) && firstWord(commandstring).length() > 2 )
{
//the following is just to get $command:
commandstring = substitutePronounsInSentence(commandstring);
//commandstring = commandstring.trim();
//if ( !getPropertyValueAsBoolean("noVerbSpellChecking") )
// commandstring = lenguaje.correctVerb(commandstring); //ddone above
commandstring = lenguaje.substituteVerb ( commandstring );
commandstring = lenguaje.substituteAlias ( commandstring );
commandstring = commandstring.trim();
command = lenguaje.extractVerb(commandstring); //StringMethods.getTok(commandstring,1,' ').trim();
write ( io.getColorCode("denial") + mundo.getMessages().getMessage("ambiguous.pronoun","$command",command,new Object[]{this,commandstring}) + io.getColorCode("reset") );
mentions.setLastMentionedVerb ( lenguaje.extractVerb(substitutePronounsInSentence(commandstring)) );
cancelPending();
return false;
}
}
//Debug.println("CommandString: " + commandstring );
//commandstring es aqui ya el comando a ejecutar
//{comando no nulo}
String originalTrimmedCommandString = commandstring;
//substitution of pronouns and synonyms
//Debug.println("BEFORE SUBSTITUTION: " + commandstring);
commandstring = substitutePronounsInSentence(commandstring);
//Debug.println("AFTER SUBSTITUTION: " + commandstring);
//commandstring = commandstring.trim();
//commandstring = lenguaje.sustituirVerbos ( commandstring );
//if ( !getPropertyValueAsBoolean("noVerbSpellChecking") )
//commandstring = lenguaje.correctVerb(commandstring); //done above
commandstring = lenguaje.substituteVerb ( commandstring );
commandstring = lenguaje.substituteAlias ( commandstring );
commandstring = commandstring.trim();
command = lenguaje.extractVerb(commandstring); //StringMethods.getTok(commandstring,1,' ').trim();
//patch to undo synonym substitutions on command "decir"
if ( "decir".equalsIgnoreCase(command) )
{
commandstring = originalTrimmedCommandString;
}
arguments = lenguaje.extractArguments(commandstring).trim(); //StringMethods.getToks(commandstring,2,StringMethods.numToks(commandstring,' '),' ').trim();
//Debug.println("Definite command to exec: " + commandstring );
//for statistics only:
finalExecutedCommandLog.addElement(commandstring);
//Sistema de acciones
String actionName = "";
Object[] actionArgs = null;
EntityList posiblesObjetivos = getReachableEntities();
//*** EXECUTE parseCommand() METHODS
if ( runParseCommandMethods(posiblesObjetivos) ) return true;
Vector patternMatchVectorSing = ParserMethods.refersToEntityIn ( arguments,posiblesObjetivos,false ).toEntityVector();
Vector patternMatchVectorPlur = ParserMethods.refersToEntityIn ( arguments,posiblesObjetivos,true ).toEntityVector();
//si no estaba definido en la habitacion
if ( lenguaje.translateVerb(command,"en").equalsIgnoreCase( "go" ) ) //ir
{
actionName = "go";
actionArgs = new Object[1]; //en concreto, ser� un Path.
if ( StringMethods.numToks(commandstring,' ') < 2 )
{
write ( io.getColorCode("denial") + mundo.getMessages().getMessage("go.nowhere",new Object[]{this}) + io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
/*
else if ( StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase(mundo.getMessages().getMessage("direction.n"))
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("n") )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true,Path.NORTE ));
actionArgs[0] = habitacionActual.getExit ( true , Path.NORTE );
}
else if ( StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase(mundo.getMessages().getMessage("direction.s"))
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("s") )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true,Path.SUR ));
actionArgs[0] = habitacionActual.getExit ( true , Path.SUR );
}
else if ( StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase(mundo.getMessages().getMessage("direction.w"))
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("o") )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true,Path.OESTE ));
actionArgs[0] = habitacionActual.getExit ( true , Path.OESTE );
}
else if ( StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase(mundo.getMessages().getMessage("direction.e"))
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("e") )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true,Path.ESTE ));
actionArgs[0] = habitacionActual.getExit ( true , Path.ESTE );
}
else if ( StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("sudeste")
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("se")
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("sureste") )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true,Path.ESTE ));
actionArgs[0] = habitacionActual.getExit ( true , Path.SUDESTE );
}
else if ( StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("sudoeste")
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("so")
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("suroeste") )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true,Path.ESTE ));
actionArgs[0] = habitacionActual.getExit ( true , Path.SUROESTE );
}
else if ( StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("nordeste")
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("noreste")
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("ne") )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true,Path.ESTE ));
actionArgs[0] = habitacionActual.getExit ( true , Path.NORDESTE );
}
else if ( StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("noroeste")
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("no") )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true,Path.ESTE ));
actionArgs[0] = habitacionActual.getExit ( true , Path.NOROESTE );
}
else if ( StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("arriba")
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("ar") )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true,Path.ARRIBA ));
actionArgs[0] = habitacionActual.getExit ( true , Path.ARRIBA );
}
else if ( StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("abajo")
|| StringMethods.getTok( arguments , StringMethods.numToks( arguments,' ' ) , ' ' ).equalsIgnoreCase("ab") )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true,Path.ABAJO ));
actionArgs[0] = habitacionActual.getExit ( true , Path.ABAJO );
}
*/ //refactored 2014-02-17, let's see how it works.
actionArgs[0] = habitacionActual.getStandardExitMatchingArguments( arguments );
if ( actionArgs[0] != null )
mentions.setLastMentionedVerb(command);
//else
if ( actionArgs[0] == null || !((Path)actionArgs[0]).isValid() ) //changed to admit a custom exit to have a standard name
{
//Mirar las salidas personalizadas
actionArgs[0] = habitacionActual.getNonStandardExitMatchingArguments(arguments);
if ( actionArgs[0] != null )
mentions.setLastMentionedVerb(command);
//old. commented 2013-03-22
/*
for ( int i=0 ; i<habitacionActual.otherExits.length ; i++ )
{
if ( habitacionActual.isValidExit(false,i) && habitacionActual.getExit(false,i).matchExitCommand( arguments ) )
{
mentions.setLastMentionedVerb(command);
actionArgs[0] = habitacionActual.getExit ( false , i );
//return go (habitacionActual.getExit( false,i ));
}
}
*/
//si no hab�a ninguna salida
if ( actionArgs[0] == null )
{
escribirDenegacionComando(io.getColorCode("denial") +
mundo.getMessages().getMessage("go.where",new Object[]{this,arguments}) //"�C�mo? �Hacia d�nde quieres ir?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
}
} // FIN CMD IR
else if ( lenguaje.translateVerb(command,"en").equalsIgnoreCase( "return" ) ) //volver
{
//vuelve a la ultima habitacion visitada (habitacionAnterior)
actionName = "go";
actionArgs = new Object[1];
//mirar las salidas est�ndar
for ( int i = 0 ; i < habitacionActual.standardExits.length ; i++ )
{
if ( habitacionActual.isValidExit(true,i) && mundo.getRoom(habitacionActual.getExit(true,i).getDestinationID()) == habitacionAnterior )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( true , i ));
actionArgs[0] = habitacionActual.getExit ( true , i );
break;
}
}
//mirar las salidas personalizadas
if ( actionArgs[0] == null )
{
for ( int i = 0 ; i < habitacionActual.otherExits.length ; i++ )
{
if ( habitacionActual.isValidExit(false,i) && mundo.getRoom(habitacionActual.getExit(false,i).getDestinationID()) == habitacionAnterior )
{
mentions.setLastMentionedVerb(command);
//return go (habitacionActual.getExit( false , i ));
actionArgs[0] = habitacionActual.getExit ( false , i );
break;
}
}
}
//si no hemos hecho return al llegar aqu�, es que no hay salida que nos lleve a la habitaci�n anterior
if ( actionArgs[0] == null )
{
escribirDenegacionComando(io.getColorCode("denial") + mundo.getMessages().getMessage("cant.go.back",new Object[]{this,arguments}) + io.getColorCode("reset"));
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
} //FIN CMD VOLVER
else if ( lenguaje.translateVerb(command,"en").equalsIgnoreCase( "look" ) ) //mirar
{
if ( StringMethods.numToks(commandstring,' ') < 2 )
{
//mirar a secas (no extrades)
show_room(mundo);
setNewState( 1 /*IDLE*/, 1 );
mentions.setLastMentionedVerb(command);
return true;
}
else //miras algo en concreto
{
String s;
//extra descriptions habitaci�n
//long comparand = (long)this.getRelationshipState( habitacionActual )*((long)Math.pow(2,32)) + habitacionActual.getState();
if ( ( s = habitacionActual.getExtraDescription( arguments , this ) ) != null )
{
write(io.getColorCode("description")+s+io.getColorCode("reset")+"\n");
setNewState( 1 /*IDLE*/, 1 );
mentions.setLastMentionedVerb(command);
return true;
}
else
{
boolean mirado = false;
//intentar mirar extras de items de habitaci�n
Debug.println("Mirado init");
if ( !mirado ) mirado = mirarExtrasItems ( arguments , habitacionActual.itemsInRoom );
//intentar mirar extras de items de inventario -> �tal vez antes de los propios �tems?
Debug.println("Mirado="+mirado);
if ( !mirado ) mirado = mirarExtrasItems ( arguments , inventory );
//intentar mirar un item de habitaci�n.
Debug.println("Mirado="+mirado);
if ( !mirado ) mirado = mirarItem ( arguments , habitacionActual.itemsInRoom );
//contenido de items de habitaci�n.
Debug.println("Mirado="+mirado);
if ( !mirado ) mirado = mirarContenido ( arguments , habitacionActual.itemsInRoom );
//intentar mirar un item de inventario.
Debug.println("Mirado="+mirado);
if ( !mirado ) mirado = mirarItem ( arguments , inventory );
//contenido de items de inventario.
Debug.println("Mirado="+mirado);
if ( !mirado ) mirado = mirarContenido ( arguments , inventory );
//intentar mirar extras de bichos de la habitaci�n
Debug.println("Mirado="+mirado);
if ( !mirado ) mirado = mirarExtrasBichos ( arguments , this.getRoom().getMobiles() );
//intentar mirar un bicho de la habitaci�n
Debug.println("Mirado="+mirado);
if ( !mirado ) mirado = mirarBicho ( arguments , habitacionActual.mobsInRoom );
//intentar mirar partes del propio cuerpo
Debug.println("Mirado="+mirado);
if ( !mirado ) mirado = mirarItem ( arguments , getFlattenedPartsInventory() );
//intentar mirar extras propios
Debug.println("Mirado="+mirado);
MobileList yo = new MobileList();
yo.addElement(this);
//if ( !mirado ) mirado = mirarExtrasBichos ( arguments , yo );
if(!mirado) //no miramos nada.
{
escribirDenegacionComando(io.getColorCode("denial") +
mundo.getMessages().getMessage("look.what",new Object[]{this,arguments}) //"�Qu� pretendes mirar?\n"
+ io.getColorCode("reset"));
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
//added bugfix. without this, TU's can get negative if looking several times
setNewState( 1 /*IDLE*/, 1 );
//TODO Other actions don't do this...
return true;
}
}
}
} // FIN CMD MIRAR
else if ( lenguaje.translateVerb(command,"en").equalsIgnoreCase( "attack" ) ) //atacar
{
boolean mirado = false;
mirado = atacarBichoConArma ( habitacionActual.mobsInRoom , getUsableWeapons() );
if(!mirado) //no atacamos nada, no nos entiende.
{
if ( inventory.patternMatch ( arguments , false ) != null && inventory.patternMatch ( arguments , false ).size() > 0 )
{
escribirDenegacionComando(io.getColorCode("denial")+"Para atacar con un arma, primero has de blandirla.\n"+io.getColorCode("reset") );
}
escribirDenegacionComando(io.getColorCode("denial")+
mundo.getMessages().getMessage("attack.what",new Object[]{this,arguments}) //"�C�mo? �Atacar a qui�n?\n"
+io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
} //FIN CMD ATACAR
else if ( lenguaje.translateVerb(command,"en").equalsIgnoreCase( "block" ) || lenguaje.translateVerb(command,"en").equalsIgnoreCase( "defend" ) ) //bloquear, defender
{
boolean mirado = false;
mirado = bloquearBichoConArma ( habitacionActual.mobsInRoom , getUsableWeapons() );
if(!mirado) //no atacamos nada, no nos entiende.
{
escribirDenegacionComando(io.getColorCode("denial")+
mundo.getMessages().getMessage("block.what",new Object[]{this,arguments}) //"�C�mo? �Defenderse de qui�n?\n"
+io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
}
else if ( lenguaje.translateVerb(command,"en").equalsIgnoreCase( "dodge" ) ) //esquivar
{
boolean mirado = false;
mirado = esquivar();
if ( !mirado ) //ein?
{
escribirDenegacionComando(io.getColorCode("denial") +
mundo.getMessages().getMessage("dodge.what",new Object[]{this,arguments}) //"No te atacan. �Esquivar qu�?\n"
+io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
}
else if ( lenguaje.translateVerb(command,"en").equalsIgnoreCase( "open" ) ) //abrir
{
//Paso 1: Abrir con llave. [si hay dos objetos en la entrada, el 1� ser� la puerta
//y el 2� la llave, como en "abrir la puerta roja con la llave amarilla p�lida"
boolean mirado = false;
Vector[] patternMatchVectorSingSing = null;
Vector[] patternMatchVectorSingPlur = null;
Vector[] patternMatchVectorPlurSing = null;
Vector[] patternMatchVectorPlurPlur = null;
mirado = abrirPuertaConLlave ( habitacionActual.itemsInRoom , inventory );
//tratar de abrir con llave algo que est� en nuestro inventario, no en la habitaci�n.
if ( !mirado )
mirado = abrirPuertaConLlave ( inventory , inventory );
if ( !mirado ) //abrir a secas, sin llave (buscar un solo objeto en string)
{
if ( habitacionActual.itemsInRoom != null && !habitacionActual.itemsInRoom.isEmpty() )
{
patternMatchVectorSing = new Vector();
patternMatchVectorPlur = new Vector();
if ( habitacionActual.itemsInRoom != null )
{
patternMatchVectorSing = habitacionActual.itemsInRoom.patternMatch ( arguments , false ).toEntityVector(); //en singular
patternMatchVectorPlur = habitacionActual.itemsInRoom.patternMatch ( arguments , true ).toEntityVector(); //en plural
}
if ( patternMatchVectorSing.size() > 0 ) //miramos un objeto
{
Item ourItem = ((Item)patternMatchVectorSing.elementAt(0));
write( io.getColorCode("action") + ((Item)patternMatchVectorSing.elementAt(0)).abrir(this) + io.getColorCode("reset") + "\n" );
habitacionActual.reportAction(this,ourItem,null,"$1 intenta abrir $2.\n","$1 intenta abrirte.\n","Intentas abrir $2.\n",false);
mirado=true;
}
else if ( patternMatchVectorPlur.size() > 0 )
{
mirado=true;
//no era en singular, probamos en plural.
Item ourItem;
//mirar todos los items
for ( int i = 0 ; i < patternMatchVectorPlur.size() ; i++ )
{
ourItem = (Item)patternMatchVectorPlur.elementAt(i);
write ( mundo.getMessages().getMessage("you.try.open.from.floor","$item",ourItem.constructName2True ( 1 , this ),new Object[]{this,arguments} ));
//write( "Intentas abrir " + ourItem.constructName2True ( 1 , this ) + ": " );
habitacionActual.reportAction(this,ourItem,null,"$1 intenta abrir $2.\n","$1 intenta abrirte.\n","Intentas abrir $2.\n",false);
write( io.getColorCode("action") + ((Item)ourItem).abrir(this) + io.getColorCode("reset") + "\n" );
}
}
} //fin (si hay items)
if ( inventory != null && !inventory.isEmpty() )
{
patternMatchVectorSing = new Vector();
patternMatchVectorPlur = new Vector();
if ( inventory != null )
{
patternMatchVectorSing = inventory.patternMatch ( arguments , false ).toEntityVector(); //en singular
patternMatchVectorPlur = inventory.patternMatch ( arguments , true ).toEntityVector(); //en plural
}
if ( patternMatchVectorSing.size() > 0 ) //miramos un objeto
{
Item ourItem = ((Item)patternMatchVectorSing.elementAt(0));
mirado=true;
habitacionActual.reportAction(this,ourItem,null,"$1 intenta abrir $2.\n","$1 intenta abrirte.\n","Intentas abrir $2.\n",false);
write( io.getColorCode("action") + ((Item)patternMatchVectorSing.elementAt(0)).abrir(this) + io.getColorCode("reset") + "\n" );
}
else if ( patternMatchVectorPlur.size() > 0 )
{
mirado = true;
//no era en singular, probamos en plural.
Item ourItem;
//mirar todos los items
for ( int i = 0 ; i < patternMatchVectorPlur.size() ; i++ )
{
ourItem = (Item)patternMatchVectorPlur.elementAt(i);
//write( "Tratas de abrir " + ourItem.constructName2True ( 1 , this ) + " que llevas: " );
write ( mundo.getMessages().getMessage("you.try.open.from.inventory","$item",ourItem.constructName2True ( 1 , this ),new Object[]{this,arguments} ));
habitacionActual.reportAction(this,ourItem,null,"$1 intenta abrir $2 que lleva.\n","$1 intenta abrirte.\n","Intentas abrir $2 que llevas.\n",false);
write( io.getColorCode("action") + ((Item)ourItem).abrir(this) + io.getColorCode("reset") + "\n" );
}
}
} //fin (si tienes inventario)
} //end if single object in string
if(!mirado) //no abrimos nada.
{
escribirDenegacionComando(io.getColorCode("denial")+
mundo.getMessages().getMessage("open.what",new Object[]{this,arguments}) //"�Qu� pretendes abrir?\n"
+io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
setNewState( 1 /*IDLE*/, 1 );
return true;
}
} // FIN CMD ABRIR (estructura igual a mirar)
else if ( lenguaje.translateVerb(command,"en").equalsIgnoreCase( "close" ) ) //cerrar
{
//Paso 1: Cerrar con llave. [si hay dos objetos en la entrada, el 1� ser� la puerta
//y el 2� la llave, como en "cerrar la puerta roja con la llave amarilla p�lida"
boolean mirado = false;
mirado = cerrarPuertaConLlave ( habitacionActual.itemsInRoom , inventory );
//probar a cerrar; pero algo que est� en nuestro inventario
if ( !mirado )
mirado = cerrarPuertaConLlave ( inventory , inventory );
if ( !mirado ) //sera cerrar a secas (sin llave)
{
if ( habitacionActual.itemsInRoom != null && !habitacionActual.itemsInRoom.isEmpty() )
{
patternMatchVectorSing = new Vector();
patternMatchVectorPlur = new Vector();
if ( habitacionActual.itemsInRoom != null )
{
patternMatchVectorSing = habitacionActual.itemsInRoom.patternMatch ( arguments , false ).toEntityVector(); //en singular
patternMatchVectorPlur = habitacionActual.itemsInRoom.patternMatch ( arguments , true ).toEntityVector(); //en plural
}
if ( patternMatchVectorSing.size() > 0 /* && !(((Item)patternMatchVectorSing.elementAt(0)).getDescription(this).equals("")) */ ) //miramos un objeto
{
Item ourItem = ((Item)patternMatchVectorSing.elementAt(0));
write( io.getColorCode("action") + ((Item)patternMatchVectorSing.elementAt(0)).cerrar(this) + io.getColorCode("reset") + "\n" );
habitacionActual.reportAction(this,ourItem,null,"$1 intenta cerrar $2.\n","$1 intenta cerrarte.\n","Intentas cerrar $2.\n",false);
mirado=true;
}
else if ( patternMatchVectorPlur.size() > 0 )
{
mirado=true;
//no era en singular, probamos en plural.
Item ourItem;
//mirar todos los items
for ( int i = 0 ; i < patternMatchVectorPlur.size() ; i++ )
{
ourItem = (Item)patternMatchVectorPlur.elementAt(i);
//this is plain nonsense.
//if ( !((Item)ourItem).getDescription(this).equals("") )
//{
//write( "Intentas cerrar " + ourItem.constructName2True ( 1 , this ) + ": " );
write ( mundo.getMessages().getMessage("you.try.close.from.floor","$item",ourItem.constructName2True ( 1 , this ),new Object[]{this,arguments} ));
habitacionActual.reportAction(this,ourItem,null,"$1 intenta cerrar $2.\n","$1 intenta cerrarte.\n","Intentas cerrar $2.\n",false);
write( io.getColorCode("action") + ((Item)ourItem).cerrar(this) + io.getColorCode("reset") +"\n" );
//}
}
}
} //fin (si hay items)
if ( inventory != null && !inventory.isEmpty() )
{
patternMatchVectorSing = new Vector();
patternMatchVectorPlur = new Vector();
if ( inventory != null )
{
patternMatchVectorSing = inventory.patternMatch ( arguments , false ).toEntityVector(); //en singular
patternMatchVectorPlur = inventory.patternMatch ( arguments , true ).toEntityVector(); //en plural
}
if ( patternMatchVectorSing.size() > 0 /* && !(((Item)patternMatchVectorSing.elementAt(0)).getDescription(this).equals("") ) */ ) //miramos un objeto
{
mirado=true;
write( io.getColorCode("action") + ((Item)patternMatchVectorSing.elementAt(0)).cerrar(this) + io.getColorCode("reset") + "\n" );
}
else if ( patternMatchVectorPlur.size() > 0 )
{
mirado = true;
//no era en singular, probamos en plural.
Item ourItem;
//mirar todos los items
for ( int i = 0 ; i < patternMatchVectorPlur.size() ; i++ )
{
ourItem = (Item)patternMatchVectorPlur.elementAt(i);
if ( !ourItem.constructName2( 1 , this ).equals("") )
{
//write( "Tratas de cerrar " + ourItem.constructName2True ( 1 , this ) + " que llevas: " );
write ( mundo.getMessages().getMessage("you.try.close.from.inventory","$item",ourItem.constructName2True ( 1 , this ),new Object[]{this,arguments} ));
habitacionActual.reportAction(this,ourItem,null,"$1 intenta cerrar $2 que lleva.\n","$1 intenta cerrarte.\n","Intentas cerrar $2 que llevas.\n",false);
write( io.getColorCode("action") + ((Item)ourItem).cerrar(this) + io.getColorCode("reset") + "\n" );
}
}
}
} //fin (si tienes inventario)
}
if(!mirado) //no cerramos nada.
{
escribirDenegacionComando ( io.getColorCode("denial") +
mundo.getMessages().getMessage("close.what",new Object[]{this,arguments}) //"�Qu� pretendes cerrar?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
setNewState( 1 /*IDLE*/, 1 );
return true;
}
} // FIN CMD CERRAR (estructura igual a mirar)
//experimental
//else if ( command.equalsIgnoreCase( "poner" ) || command.equalsIgnoreCase( "meter" ) )
else if ( "put".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //poner, meter
{
boolean mirado = false;
//Paso 0: ponerme [algo de mi inventario]
//TODO: This case is very doubtful in multilanguage model, should probably be either removed or made optional (issue #244)
if ( command.equalsIgnoreCase( "poner" ) && ParserMethods.refersToEntity(arguments, this, false) ) //the player appears as an argument
{
if ( !oneTargetAction("wear",arguments,inventory) )
{
escribirDenegacionComando( io.getColorCode("denial") +
mundo.getMessages().getMessage("wear.what",new Object[]{this,arguments}) //"�Qu� pretendes vestir?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
}
//Paso 1: poner [algo de mi inventario] en [contenedor de la habitaci�n]
if ( !mirado && habitacionActual.itemsInRoom != null && !habitacionActual.itemsInRoom.isEmpty()
&& inventory != null && !inventory.isEmpty()
)
{
mirado = putInside ( inventory , habitacionActual.itemsInRoom , arguments );
} //end if (par inventario-habitaci�n)
//Paso 2: poner [algo de mi inventario] en [contenedor tambi�n del inventario]
if ( !mirado
&& inventory != null && !inventory.isEmpty()
)
{
mirado = putInside ( inventory , inventory , arguments );
} //end if (mirar par inventario-inventario)
if(!mirado) //no ponemos nada
{
escribirDenegacionComando( io.getColorCode("denial") +
mundo.getMessages().getMessage("put.what.where",new Object[]{this,arguments}) //"�C�mo? �Poner qu� d�nde?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
} // FIN CMD PONER (estructura parecida a abrir/cerrar con llave)
else if ( "take".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //coger
{
//TODO: This verb uses quite ancient things (that string that we are passing...) and should be updated to make
//an onGetFrom event. Perhaps use the devices that we used for the double parseCommands (search for onContentsGeneric, etc.)
//But have to think on how to integrate that with the action framework.
boolean mirado = false;
setNewState( 1 /*IDLE*/, 1 );
//Paso 0: cogerme (o sea, quitarme) [algo de mi inventario]
if ( ParserMethods.refersToEntity(arguments, this, false) ) //the player appears as an argument
{
if ( !oneTargetAction("unwear",arguments,getWornItems()) )
{
escribirDenegacionComando( io.getColorCode("denial") +
mundo.getMessages().getMessage("unwear.what",new Object[]{this,arguments}) //"�Qu� pretendes quitarte?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
}
if ( !mirado ) mirado = cogerContenidoEspecificandoContenedor ( arguments , habitacionActual.itemsInRoom , "" );
if ( !mirado ) mirado = cogerItem ( habitacionActual.itemsInRoom , null );
if ( !mirado ) mirado = cogerContenido ( habitacionActual.itemsInRoom , "" );
if ( !mirado ) mirado = cogerContenidoEspecificandoContenedor ( arguments , inventory , "" );
if ( !mirado ) mirado = cogerContenido ( inventory , "" );
if ( mirado )
{
mentions.setLastMentionedVerb(command);
return true;
}
else
{
escribirDenegacionComando( io.getColorCode("denial") +
mundo.getMessages().getMessage("get.what",new Object[]{this,arguments}) //"�Qu� pretendes coger?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
} //FIN CMD COGER
else if ( "drop".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //dejar
{
if ( !oneTargetAction("drop",arguments,inventory) )
{
escribirDenegacionComando( io.getColorCode("denial") +
mundo.getMessages().getMessage("drop.what",new Object[]{this,arguments}) //"�Qu� pretendes dejar?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
} //FIN CMD DEJAR
else if ( "inventory".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) && arguments.trim().length() < 1 ) //inventario. deja de valer poner inventario algo.
{
setNewState( 1 /*IDLE*/, 1 );
showInventory();
mentions.setLastMentionedVerb(command);
return true;
} //FIN CMD INVENTARIO
else if ( "spells".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) && arguments.trim().length() < 1 ) //hechizos. deja de valer poner hechizos algo.
{
if ( spellRefs != null )
{
write( io.getColorCode("information") + "Hechizos conocidos:\n" + io.getColorCode("reset") );
for ( int i = 0 ; i < spellRefs.size() ; i++ )
{
Spell current = (Spell)spellRefs.get(i);
write( io.getColorCode("information") + current.getUniqueName() + io.getColorCode("reset") + "\n" );
}
}
else
{
write( io.getColorCode("information") + "No sabes hacer magia.\n" );
}
setNewState( 1 /*IDLE*/, 1 );
mentions.setLastMentionedVerb(command);
return true;
} //END CMD SPELLS
else if ( "suicide".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //suicidar, suicidarse
//else if ( command.equalsIgnoreCase( "suicidar" ) || command.equalsIgnoreCase( "suicidarse" ) )
{
suicide();
//no necesitar�s zr con esto.
return true;
}
else if ( "unwear".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //desvestir
{
if ( !oneTargetAction("unwear",arguments,getWornItems()) )
{
escribirDenegacionComando( io.getColorCode("denial") +
mundo.getMessages().getMessage("unwear.what",new Object[]{this,arguments}) //"�Qu� pretendes quitarte?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
}
else if ( "wear".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //vestir
{
if ( !oneTargetAction("wear",arguments,inventory) )
{
escribirDenegacionComando( io.getColorCode("denial") +
mundo.getMessages().getMessage("wear.what",new Object[]{this,arguments}) //"�Qu� pretendes vestir?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
}
else if ( "wield".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //blandir
{
if ( !oneTargetAction("wield",arguments,inventory) )
{
escribirDenegacionComando( io.getColorCode("denial") +
mundo.getMessages().getMessage("wield.what",new Object[]{this,arguments}) //"�Qu� arma pretendes blandir?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
}
else if ( "unwield".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //enfundar
{
if ( !oneTargetAction("unwield",arguments,wieldedWeapons) )
{
escribirDenegacionComando( io.getColorCode("denial") +
mundo.getMessages().getMessage("unwield.what",new Object[]{this,arguments}) //"�Qu� arma enfundar?\n"
+ io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
}
else if ( "say".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //decir
{
//habitacionActual.informActionAuto ( this , null , "$1 dice \"" + arguments + "\"\n" );
//say(arguments);
//escribir("\n");
setNewState( 1 /*IDLE*/, 1 );
comandoDecir ( arguments );
mentions.setLastMentionedVerb(command);
return true;
}
else if ( command.equalsIgnoreCase( "salir" ) )
{
System.exit(0);
}
/*
else if ( command.equalsIgnoreCase( "debug" ) )
{
write("\nDebug Output:");
write("\nInventory:\n");
if ( inventory != null )
{
for ( int i = 0 ; i < inventory.size() ; i ++ )
{
write(inventory.elementAt(i).getID() + "");
}
}
//escribir("\nCurrent room inventory (raw string)");
//Debug.println(habitacionActual.getContents());
return true;
}
*/
else if ( "wait".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //esperar
{
if ( StringMethods.numToks(commandstring,' ') < 2 )
{
//esperar 1 UGT
setNewState( 1 /*IDLE*/, 1 );
mentions.setLastMentionedVerb(command);
return true;
}
else
{
int nsecs = 1;
try
{
nsecs = Integer.valueOf( arguments ).intValue();
}
catch ( NumberFormatException nfe )
{
}
setNewState( 1 /*IDLE*/, nsecs );
mentions.setLastMentionedVerb(command);
return true;
}
}
else if ( "talk".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //hablar
{
escribirDenegacionComando( io.getColorCode("denial") + "La mejor forma de hablar es decir algo.\n" + io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
/*
else if ( command.equalsIgnoreCase( "salvar" ) || command.equalsIgnoreCase("save")
|| command.equalsIgnoreCase( "cargar" ) || command.equalsIgnoreCase("load")
|| command.equalsIgnoreCase( "grabar" ) || command.equalsIgnoreCase("restaurar") )
*/
else if ( "load".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) || "save".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) ) //salvar, grabar, cargar, restaurar, save, load
{
escribirDenegacionComando( io.getColorCode("error") + "De momento, las opciones de salvar y cargar no est�n disponibles por texto en este interfaz. Puedes usar los men�s para ello.\n" + io.getColorCode("reset") );
cancelPending();
return false;
}
//else if ( command.equalsIgnoreCase("invocar") || command.equalsIgnoreCase("convocar") || command.equalsIgnoreCase("hacer") || command.equalsIgnoreCase("realizar") || command.equalsIgnoreCase("usar") || command.equalsIgnoreCase("utilizar") || command.equalsIgnoreCase("crear") || command.equalsIgnoreCase("ejecutar") || command.equalsIgnoreCase("pronunciar") || command.equalsIgnoreCase("conjurar") )
else if ( "invoke".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) || "convoke".equalsIgnoreCase(lenguaje.translateVerb(command,"en"))
|| "make".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) || "realize".equalsIgnoreCase(lenguaje.translateVerb(command,"en"))
|| "create".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) || "use".equalsIgnoreCase(lenguaje.translateVerb(command,"en"))
|| "execute".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) || "pronounce".equalsIgnoreCase(lenguaje.translateVerb(command,"en"))
|| "cast".equalsIgnoreCase(lenguaje.translateVerb(command,"en")) )
{
//try to cast spell
boolean mirado = false;
EntityList possibleSpellTargets = new EntityList();
for ( int i = 0 ; i < habitacionActual.mobsInRoom.size() ; i++ )
{
possibleSpellTargets.addEntity ( habitacionActual.mobsInRoom.elementAt(i) );
}
for ( int i = 0 ; i < inventory.size() ; i++ )
{
possibleSpellTargets.addEntity ( inventory.elementAt(i) );
}
//if ( habitacionActual.getInventory() != null )
//{
for ( int i = 0 ; i < habitacionActual.getInventory().size() ; i++ )
{
possibleSpellTargets.addEntity ( habitacionActual.getInventory().elementAt(i) );
}
//}
mirado = hacerHechizo ( possibleSpellTargets , getSpells() );
if(!mirado) //no atacamos nada, no nos entiende.
{
escribirDenegacionComando(io.getColorCode("denial")+mundo.getMessages().getMessage("cast.no.spell",new Object[]{this,arguments})+io.getColorCode("reset") );
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
else
{
mentions.setLastMentionedVerb(command);
return true;
}
}
//reconocemos el verbo; pero no tenemos npi de qu� hacer con �l...
//TODO remmed "else" from here.
else if ( lenguaje.isVerb ( command , true ) )
{
String origCommand = "";
if ( originalTrimmedCommandString != null )
origCommand = StringMethods.getTok(originalTrimmedCommandString,1,' ').trim();
//Debug.println("origCommand: " + origCommand +"ceremonia del te");
if ( !origCommand.endsWith("me") && !origCommand.endsWith("te") && !origCommand.endsWith("se") )
{
//escribirDenegacionComando ( io.getColorCode("denial") + "�C�mo? �" + commandstring + "?\n" + io.getColorCode("reset") );
escribirDenegacionComando ( io.getColorCode("denial") + mundo.getMessages().getMessage("undefined.action","$command",commandstring,new Object[]{this,commandstring}) + io.getColorCode("reset") );
}
else
{
//si el comando se refer�a al propio jugador, poner el string sin pronombres sustituidos, porque queda un poco feo que diga "�c�mo? �matar a jugador?"
//escribirDenegacionComando ( io.getColorCode("denial") + "�C�mo? �" + originalTrimmedCommandString + "?\n" + io.getColorCode("reset") );
escribirDenegacionComando ( io.getColorCode("denial") + mundo.getMessages().getMessage("undefined.action","$command",originalTrimmedCommandString,new Object[]{this,originalTrimmedCommandString}) + io.getColorCode("reset") );
}
mentions.setLastMentionedVerb(command);
cancelPending();
return false;
}
//si llegamos aqui, el verbo no es ninguno de los reconocidos, ni ninguno
//de los ejecutables en EVA, ni nada.
//Vemos a ver si es el nombre de un bicho para hablarle (Mar�a, hola)
else if ( !commandQueue.isEmpty() && ParserMethods.refersToEntityIn(command, this.getAllWorldMobiles(), false).size() > 0 )
{
String whatToSay = ((String)commandQueue.elementAt(0)).trim();
commandQueue.removeElementAt(0);
Mobile whomToSayItTo = (Mobile) ParserMethods.refersToEntityIn(command, this.getAllWorldMobiles(), false).toEntityVector().get(0);
return execCommand("decir a " + whomToSayItTo.getBestReferenceName(false) + "\"" + whatToSay + "\"");
}
//Si llegamos aqu�, no s�lo no es un verbo sino que no es una construcci�n tipo "Mar�a, hola".
//Ahora, si no lo hemos hecho ya, probamos
//a ver si es que ha habido una elipsis de verbo, a�adiendo el verbo de la zona
//de referencia.
else if ( !mentions.getLastMentionedVerb().equalsIgnoreCase( command ) &&
!command.matches("^"+mentions.getLastMentionedVerb()+"(_|\\b).*") /*for English phrasal verbs (1)*/ &&
lenguaje.isGuessable(mentions.getLastMentionedVerb()) )
{
//(1) to solve cases like: last mentioned = look, command = look_up, and we add an extra "look".
/*DON'T USE QUEUE, JUST EXEC'IT*/
/*
//aqui nos saltamos la cola de comandos cambiando el primero...
//por algo es un vector, no una autentica cola :)
Vector temp = (Vector)commandQueue.clone();
commandQueue = new Vector();
commandQueue.addElement(ZR_verbo + " " + commandstring);
commandQueue.addAll(temp);
nextCommandSecondChance = true;
return execCommand ( mundo );
*/
secondChance = true;
//System.err.println("Last mentioned verb: " + mentions.getLastMentionedVerb());
//System.err.println("Command: " + command);
return execCommand (mentions.getLastMentionedVerb() + " " + commandstring );
}
else
{
escribirErrorNoEntiendo();
}
//here, if actionName and actionArgs are set, execute action!!!
if ( ! actionName.equals("") )
{
return executeAction ( actionName , actionArgs );
}
return false;
}
public void show_room(World mundo) {
long comparand;
//escribir("\n");
//escribir(habitacionActual.getTitle()+"\n");
comparand = (long)this.getRelationshipState( habitacionActual )*((long)Math.pow(2,32)) + habitacionActual.getState();
//Debug.println("CMP: " + comparand);
//de momento el comparando viene a ser el estado de la habitacion.
write(/*" "+*/io.getColorCode("description")+habitacionActual.getDescription(this)+io.getColorCode("reset")+"\n");
//getitemdes
try
{
habitacionActual.execCode("event_showroom","this: " + habitacionActual.getID() + "\n" + "player: " + getID() + "\n" + "orig: " + habitacionAnterior );
habitacionActual.execCode("onShowRoom" , new Object[] {this} );
}
catch ( EVASemanticException exc )
{
write( io.getColorCode("error") + "EVASemanticException found at event_showroom , room number " + habitacionActual.getID() + io.getColorCode("reset") );
}
catch ( ScriptException bshte )
{
write( io.getColorCode("error") + "bsh.TargetError found onShowRoom , room number " + habitacionActual.getID() + ": " + bshte + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(bshte));
}
}
/**
* Substitutes pronouns AND aplies spell checking if enabled
*/
public String substitutePronounsInSentence(String commandstring) { //matalo con el cuchillo
StringTokenizer st = new StringTokenizer(commandstring);
String originalVerb = st.nextToken(); //matalo
String expandedString = lenguaje.substitutePronouns ( this , commandstring , mentions ); //mata Juanito con el cuchillo
String expandedVerbWithoutPronoun = firstWord ( expandedString ); //mata
//String expandedString = expandedVerb + " " + restWords(commandstring); //mata Juanito con el cuchillo
String workingString;
if ( /*!lenguaje.isVerb(originalVerb) &&*/ lenguaje.isVerb(firstWord(expandedVerbWithoutPronoun)) )
workingString = expandedString; //pronoun substitution was useful
else
workingString = commandstring; //first word could be something like "habla" or "bote", better not to expand it if not sure.
if ( !getPropertyValueAsBoolean("noVerbSpellChecking") )
{
return mundo.getSpellChecker().correctCommandString(workingString);
}
else
{
return workingString;
}
/*
String subs_command = substitutePronounsIfVerb ( StringMethods.getTok(commandstring,1,' ') );
commandstring = subs_command + " " + StringMethods.getToks(commandstring,2,StringMethods.numToks(commandstring,' '),' ');
return commandstring;
*/
}
/**
* Used for commands of the kind "Mar�a, hola" (to recognise mobile names as verbs)
* @return
*/
private EntityList getAllWorldMobiles() {
if ( mobilesCache == null )
mobilesCache = mundo.getAllMobiles();
return mobilesCache;
}
/**
* Moves the first command from the command queue to the commandstring attribute (command to be executed).
* Also handles the second chance flags if applicable.
* Returns false if for some reason no command was obtained.
* @return
*/
protected boolean obtainCommandFromQueue()
{
if ( nextCommandSecondChance )
{
secondChance = true; //estamos en un comando de segunda oportunidad
nextCommandSecondChance = false;
}
//quitar el primer elemento (cabeza) de commandQueue
commandstring = ((String)commandQueue.elementAt(0)).trim();
//Debug.println("(1) Command string set to " + (String)commandQueue.elementAt(0) );
commandQueue.removeElementAt(0);
//en la cola metemos sentencias simples; pero al sustituir los pronombres pueden
//dar lugar de nuevo a multiplicidad.
return separateSentences();
}
/**
* Executes the preprocessCommand() scripted method for the given input.
* @return true if preprocessCommand() has hit end(), false if not (thus if false we will contiune command execution).
*/
protected boolean runPreprocessCommand()
{
/*Llamada a preprocessCommand() configurable*/
boolean executed = false;
try
{
ReturnValue retval = new ReturnValue(null);
executed = mundo.execCode( "preprocessCommand" , new Object[] { this , commandstring } , retval );
if ( retval.getRetVal() != null )
{
commandstring = (String)retval.getRetVal();
//Debug.println("Command String Changed To " + (String)retval.getRetVal());
command = lenguaje.extractVerb(commandstring).trim(); //StringMethods.getTok(commandstring,1,' ').trim();
arguments = lenguaje.extractArguments(commandstring).trim(); //StringMethods.getToks(commandstring,2,StringMethods.numToks(commandstring,' '),' ').trim();
}
}
catch ( ScriptException te )
{
write(io.getColorCode("error") + "bsh.TargetError found at preprocessCommand, raw command was " + commandstring + ", error was " + te + io.getColorCode("reset") );
writeError(ExceptionPrinter.getExceptionReport(te));
}
if ( executed )
{
//luego esto lo hara el codigo
setNewState( 1 /*IDLE*/, 1 );
mentions.setLastMentionedVerb(command);
return true;
}
else
{
return false;
}
/*Fin de preprocessCommand()*/
}
/**
* Runs a command prefixed by "eval" (to evaluate scripted code for debugging) if applicable (i.e. if the current command really
* starts with "eval") and returns true. If not applicable, returns false.
* @return
*/
protected boolean runEvalIfApplicable()
{
if ( commandstring.startsWith( "eval " ) && Debug.isEvalEnabled() )
{
ReturnValue retVal = new ReturnValue(null);
arguments = StringMethods.getToks(commandstring,2,StringMethods.numToks(commandstring,' '),' ').trim();
try {
mundo.getAssociatedCode().evaluate(arguments,this,retVal);
} catch (ScriptException e) {
writeError(ExceptionPrinter.getExceptionReport(e));
}
this.write(""+retVal.getRetVal()+"\n");
return true;
}
return false;
}
/**
* Obtains an executes a command.
* The command can be obtained:
* - From the command queue,
* - From the "forced command" string.
* The subclass Player overrides this method in order to be able to obtain commands from logs or from client input as well.
*/
public boolean obtainAndExecCommand ( World mundo ) throws java.io.IOException
{
/*
* This loop is so that we can have metacommands that don't consume time.
* In normal cases, we execute a command and return from the function so only one iteration is ran.
* But when a metacommand is used, we do 'continue' so the function doesn't return (and no game time is consumed).
*/
for(;;)
{
secondChance = false; //luego se pone a true en obtainCommandFromQueue() si hace falta
//mirar si cola de comandos vacia
//el !forced es porque si hemos forzado un comando, pasa por delante de la cola
if ( !commandQueue.isEmpty() && !forced ) //obtain enqueued piece of command - this was not a directly input command so it is not subject to preprocessCommand and eval
{
if ( !obtainCommandFromQueue() ) return false;
}
else
{
if ( forced )
{
forced = false;
io.forceInput ( force_string , false );
commandstring = force_string;
}
else
{
return false; //we don't have a command.
}
//Process raw command:
/*Preparaci�n del comando:*/
if ( commandstring != null ) commandstring = commandstring.trim();
/*Llamada a preprocessCommand() configurable*/
if ( runPreprocessCommand() ) return true;
//comando nulo
if ( commandstring == null || commandstring.equals("") ) return false;
/*Comandos eval - continue porque no se ejecuta un comando normal, es un metacomando de fuera del mundo*/
if ( runEvalIfApplicable() ) continue;
/*Separate commands composed of several sentences. The sentences are placed in the queue. False is returned only if the command is actually
* empty (e.g. a command consisting only of commands)*/
if ( !separateSentences() ) return false;
}
//modular execCommand()
if ( commandstring.isEmpty() ) return false; //empty strings can result if, for example, input was ",something", etc.
return execCommand ( commandstring );
}
}
}