/* ** j###t ########## #### #### ** j###t ########## #### #### ** j###T "###L J###" ** ######P' ########## ######### ** ######k, ########## T######T ** ####~###L #### ** #### q###L ########## .##### ** #### \###L ########## #####" */ package key; import java.util.Enumeration; import java.util.StringTokenizer; import java.util.Hashtable; import java.util.Vector; import java.io.*; import java.lang.reflect.*; /** * Material * * The base class for most user-manipulatable objects */ public abstract class Material extends Atom implements Thing { private static final long serialVersionUID = -3366054986544050407L; public Material() { // objects typically start out // as publically moveable. getPermissionList().allow( Atom.moveAction ); } public Reference build( Player p ) { return( getThis() ); } public String[] wearLocations( Player p ) { return( new String[0] ); } //--- default implementations -------------------------------- public void use( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You cannot use the " + getFullPortrait( p ) + "." ); } public void wear( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { // the default implementation is to allow the player to // wear it defaultWear( p, args, ic, flags, item ); } protected final void defaultWear( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { String[] wl = wearLocations( p ); if( wl == null || wl.length == 0 ) { ic.send( "You may not wear the " + getFullPortrait( p ) + "." ); return; } Inventory i = p.getInventory(); // check all locations are free for( int j = 0; j < wl.length; j++ ) { Thing o = (Thing) i.getProperty( wl[j] ); if( o != null ) { ic.sendFailure( "You are already wearing the " + getFullPortrait( p ) + " on your " + wl[j] + "." ); return; } } // place it in all locations for( int j = 0; j < wl.length; j++ ) { i.setProperty( wl[j], this ); } ic.sendFeedback( "You are now wearing the " + getFullPortrait( p ) + "." ); } protected final void defaultRemove( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { String[] wl = wearLocations( p ); if( wl == null || wl.length == 0 ) { ic.send( "You may not wear the " + getFullPortrait( p ) + "." ); return; } Inventory i = p.getInventory(); boolean didRem = false; // check all locations are free for( int j = 0; j < wl.length; j++ ) { Thing o = (Thing) i.getProperty( wl[j] ); if( o == item ) { i.setProperty( wl[j], null ); didRem = true; } } if( didRem ) ic.sendFeedback( "You are no longer wearing the " + getFullPortrait( p ) + "." ); else ic.sendFeedback( "But you aren't wearing a " + getFullPortrait( p ) + "." ); } public void remove( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { defaultRemove( p, args, ic, flags, item ); } public void wield( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You cannot wield the " + getFullPortrait( p ) + "." ); } public void read( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You cannot read the " + getFullPortrait( p ) + "." ); } public void look( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You don't see anything of note" ); } /** * It is not real friendly to override this method in order * to hide the inspect information - it's very useful stuff. */ public void inspect( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { //ic.send( "You do not descry anything of note about the " + getFullPortrait( p ) + "." ); defaultInspect( p, args, ic, flags, item ); } public final static void anyAtomInspect( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom th ) { Reference owner = th.getOwnerReference(); StringBuffer sb = new StringBuffer( th.getId() ); Type type = Type.typeOf( th ); sb.append( " is" ); if( type != null ) { sb.append( ' ' ); sb.append( Grammar.aAn( type.getName() ) ); } if( owner.isValid() ) { sb.append( " owned by " ); sb.append( owner.getName() ); } sb.append( '.' ); ic.send( sb.toString() ); } public final static void standardInspect( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Thing th ) { ic.sendLine(); anyAtomInspect( p, args, ic, flags, (Atom) th ); ic.sendLine(); { Vector verbs = new Vector( 10, 10 ); // this is lots of fun. // scan through the methods on this object comparing // them to these defaults and see what has changed. Class ourClass = th.getClass(); Method[] localMethods = ourClass.getMethods(); for( int i = 0; i < localMethods.length; i++ ) { Method m = localMethods[i]; Class[] parameters = m.getParameterTypes(); if( parametersEquivalent( parameters, verbParameters ) ) { String mn = m.getName(); if( th.isMethodSpecial( m ) ) { // this one is different verbs.addElement( mn ); } } } if( verbs.size() == 0 ) ic.send( "No active verbs" ); else ic.send( "Verbs: ^h" + Grammar.enumerate( verbs.elements() ) + "^-" ); } ic.sendLine(); } protected final void defaultInspect( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { standardInspect( p, args, ic, flags, (Thing) item ); } public boolean isMethodSpecial( Method m ) { Class dc = m.getDeclaringClass(); return( dc != Material.class && !Modifier.isFinal( m.getModifiers() ) && !Modifier.isAbstract( m.getModifiers() ) ); } public void get( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { defaultGet( p, args, ic, flags, item ); } protected final void defaultGet( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { Room r = p.getLocation(); Inventory i = p.getInventory(); // ensure that we won't have to back out r.checkPermissionList( Container.removeFromAction ); i.checkPermissionList( Container.addToAction ); checkPermissionList( Atom.moveAction ); if( !i.canAdd() ) { ic.sendFailure( "You are carrying too much already." ); return; } try { r.remove( this ); i.add( this ); ic.sendFeedback( "You pick up the " + getFullPortrait( p ) + "." ); } catch( Exception e ) { throw new UnexpectedResult( e ); } } public void give( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { defaultGive( p, args, ic, flags, item ); } protected final void defaultGive( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { if( !args.hasMoreTokens() ) { ic.sendFailure( "Who do you want to give the " + getFullPortrait( p ) + " to?" ); return; } String pname = args.nextToken(); Player t = null; try { t = (Player) Command.getOnlinePlayer( p, ic, pname ); } catch( ClassCastException e ) { ic.sendFailure( "You may only give to single players" ); return; } if( t == null ) { ic.sendFailure( "No such player '" + pname + "'" ); return; } Inventory i = p.getInventory(); Inventory ti = t.getInventory(); // ensure that we won't have to back out i.checkPermissionList( Container.removeFromAction ); ti.checkPermissionList( Container.addToAction ); checkPermissionList( Atom.moveAction ); if( !ti.canAdd() ) { ic.sendFailure( p.HeShe() + " is carrying too much already." ); return; } try { i.remove( this ); ti.add( this ); ic.sendFeedback( "You give the " + getFullPortrait( p ) + " to " + t.getName() + "." ); if( t.connected() ) { t.send( p.getName() + " gives you a " + getFullPortrait( p ) + "." ); } } catch( Exception e ) { throw new UnexpectedResult( e ); } } public void drop( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { defaultDrop( p, args, ic, flags, item ); } protected final void defaultDrop( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { Room r = p.getLocation(); Inventory i = p.getInventory(); // ensure we won't have to back out r.checkPermissionList( Container.addToAction ); i.checkPermissionList( Container.removeFromAction ); checkPermissionList( Atom.moveAction ); if( !r.canAdd() ) { ic.sendFailure( "There is too much in this room to drop any more." ); return; } try { i.remove( this ); r.add( this ); ic.sendFeedback( "You put down " + getFullPortrait( p ) + "." ); } catch( CannotDropWhileWearingException e ) { ic.sendFailure( "You cannot drop " + getFullPortrait( p ) + " while you are wearing it." ); } catch( Exception e ) { throw new UnexpectedResult( e ); } } // META: eventually do a default method for this public void sit( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You cannot sit on the " + getFullPortrait( p ) + "." ); } // META: eventually do a default method for this public void stand( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You are not sitting on the " + getFullPortrait( p ) + "." ); } public void drink( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You cannot drink the " + getFullPortrait( p ) + "." ); } public void eat( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "The " + getFullPortrait( p ) + " is not edible." ); } public void open( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You cannot open the " + getFullPortrait( p ) + "." ); } public void close( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You cannot close the " + getFullPortrait( p ) + "." ); } public void fill( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You cannot fill the " + getFullPortrait( p ) + "." ); } public void lock( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You cannot lock the " + getFullPortrait( p ) + "." ); } public void unlock( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags, Atom item ) { ic.send( "You cannot unlock the " + getFullPortrait( p ) + "." ); } //--- proxy methods -------------------------------- public String getFullPortrait( Player p, Atom proxy ) { return( getFullPortrait( p ) ); } /* public final void use( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { use( p, args, ic, flags, this ); } public final void wear( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { wear( p, args, ic, flags, this ); } public final void remove( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { remove( p, args, ic, flags, this ); } public final void wield( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { wield( p, args, ic, flags, this ); } public final void read( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { read( p, args, ic, flags, this ); } public final void look( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { look( p, args, ic, flags, this ); } public final void get( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { get( p, args, ic, flags, this ); } public final void drop( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { drop( p, args, ic, flags, this ); } public final void sit( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { sit( p, args, ic, flags, this ); } public final void stand( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { stand( p, args, ic, flags, this ); } public final void drink( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { drink( p, args, ic, flags, this ); } public final void eat( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { eat( p, args, ic, flags, this ); } public final void open( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { open( p, args, ic, flags, this ); } public final void close( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { close( p, args, ic, flags, this ); } public final void fill( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { fill( p, args, ic, flags, this ); } public final void lock( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { lock( p, args, ic, flags, this ); } public final void unlock( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { unlock( p, args, ic, flags, this ); } public final void give( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { give( p, args, ic, flags, this ); } */ /** * This proxy method should be a fraction more expressive. * In particular, it should prefix the inspect screen by * some information detailing that this inspect is proxied, * and isn't completely representative of the object. * * MaterialContainer, the primary user of the proxy interface, * by default outputs an inspect for the container, followed * by the proxy inspect, thus providing complete information * about the object. public void inspect( Player p, StringTokenizer args, InteractiveConnection ic, Flags flags ) { inspect( p, args, ic, flags, this ); } */ //--- static section ------------------------------------------------- // // contains some static constants that are useful for the manipulation // of objects. // protected static transient Hashtable methods = new Hashtable(); protected static transient String available_verbs; protected static transient String defaultVerb; protected static transient Method defaultMethod; public static final Class[] verbParameters = { Player.class, StringTokenizer.class, InteractiveConnection.class, Flags.class, Atom.class }; public static boolean parametersEquivalent( Class[] a, Class[] b ) { if( a.length != b.length ) return( false ); for( int j = 0; j < a.length; j++ ) { if( a[j] != b[j] ) return( false ); } return( true ); } // place the methods from Thing into the hashtable static { Vector v = new Vector( 5, 5 ); try { Method m[] = Thing.class.getDeclaredMethods(); for( int i = 0; i < m.length; i++ ) { Class[] parameters = m[i].getParameterTypes(); if( parametersEquivalent( parameters, verbParameters ) ) { String name = m[i].getName(); Method meth = m[i]; methods.put( name, meth ); v.addElement( name ); if( defaultMethod == null ) { defaultMethod = meth; defaultVerb = name; } } } available_verbs = Grammar.commaSeperate( v.elements() ); } catch( Exception e ) { Log.debug( Material.class, "Could not initialise fields from Thing: " + e.toString() ); e.printStackTrace(); } } public static final String getDefaultVerb() { return( defaultVerb ); } public static final Method getMethod( String verb ) { return( (Method) methods.get( verb ) ); } public static final String getAvailableVerbs() { return( available_verbs ); } }