All IG code should use the interface of LocatedEntity when dealing
with any entity, rather than sometimes requiring Entity. Add virtual
functions to the interface where required, and modify all other interfaces
to stop them using Entity. This makes the code way cleaner, and much better
de-coupled.
* common/Identified.cpp, common/Identified.h:
Flatten down the base classes into one called Router.
* client/CharacterClient.cpp, client/CreatorClient.cpp,
rulesets/BaseMind.cpp, rulesets/Character.cpp,
rulesets/Creator.cpp, rulesets/Entity.cpp,
rulesets/LocatedEntity.cpp, rulesets/MemEntity.cpp,
rulesets/Plant.cpp, rulesets/Stackable.cpp,
rulesets/Thing.cpp, rulesets/World.cpp,
server/Account.cpp, server/Admin.cpp,
server/Connection.cpp, server/ExternalMind.cpp,
server/Lobby.cpp, server/Master.cpp,
server/Peer.cpp, server/Player.cpp,
server/ServerRouting.cpp, server/SlaveClientConnection.cpp,
server/TrustedConnection.cpp, tests/LocatedEntitytest.cpp,
tests/ThingupdatePropertiestest.cpp: Update all the operation
routing classes to use the modified base class correctly.
* rulesets/Character.cpp, rulesets/Entity.cpp, rulesets/Plant.cpp,
rulesets/Stackable.cpp: Fix up places that use the property
manager interface. Fix explicit reference to DynamicProperty.
* common/TypeNode.h, common/TypeNode.cpp: Move TypeNode into
its own files.
* common/Makefile.am, common/inheritance.cpp, common/inheritance.h:
Add the new files to the build and remove the old implementation.
* client/Py_CreatorClient.cpp, rulesets/Character.cpp,
rulesets/Entity.cpp, rulesets/MemMap.cpp,
rulesets/MindFactory.cpp, rulesets/Py_Mind.cpp,
rulesets/Py_Thing.cpp, rulesets/Stackable.cpp,
server/WorldRouter.cpp: Fix up the includes for all code that
uses TypeNode.
* rulesets/Entity.h: Remove an old experimental type class, and clean
up includes.
* client/Py_CreatorClient.cpp, rulesets/MemMap.cpp,
rulesets/MindFactory.cpp, rulesets/Py_Mind.cpp,
rulesets/Py_Thing.cpp, rulesets/Stackable.cpp,
server/WorldRouter.cpp: Add necessary includes.
* common/inheritance.cpp, common/inheritance.h: Introduce a type
node class as a carrier for all information, including default
values for a type.
* rulesets/Entity.h, rulesets/Entity.cpp, rulesets/Character.cpp:
Use a TypeNode pointer rather than a string giving the type
of an entity.
* client/Py_CreatorClient.cpp, rulesets/MemMap.cpp, rulesets/MemMap.h,
rulesets/MindFactory.cpp, rulesets/MindFactory.h,
rulesets/Py_Mind.cpp, rulesets/Py_Thing.cpp, rulesets/Stackable.cpp,
rulesets/World.cpp, server/PersistantThingFactory.h,
server/Restorer_impl.h, server/WorldRouter.cpp:
Adapt all the code that deals with types. Set the type pointer
up correctly in BaseMind.
* server/EntityFactory.cpp: Initialise the TypeNode pointer on new
entities.
* tests/inheritancetest.cpp: Adapt the test to cope with TypeNode.
* rulesets/Character.cpp, rulesets/Creator.cpp, rulesets/Entity.cpp,
rulesets/Entity.h, rulesets/Pedestrian.cpp, rulesets/Py_Thing.cpp,
rulesets/Stackable.cpp, rulesets/Thing.cpp, rulesets/World.cpp:
Remove m_world member variable from all Entity classes, and
access the world manager object as a singleton.
* rulesets/BaseMind.cpp, rulesets/Character.cpp, rulesets/Food.cpp,
rulesets/Plant.cpp, rulesets/Stackable.cpp, rulesets/Thing.cpp:
Remove script override calls from the individual C++ operation
methods, as script overrides are now done centrally.
* rulesets/Stackable.cpp: Report an error if a divide op has
args with the wrong ID.
* rulesets/Character.h, rulesets/Character.cpp: Add function
to check if an entity is in the characters inventory.
* rulesets/Character.cpp: First pass at implementing filters
for combine and divide ops from the client.
* common/BaseEntity.h, common/BaseEntity.cpp: Add an integer ID
member variable, and accessor, and require it to be initialised
along with string ID in constructor.
* common/const.cpp, common/const.h: Add a const for the integer value
of the world ID.
* rulesets/Area.cpp, rulesets/Area.h, rulesets/BaseMind.cpp,
rulesets/BaseMind.h, rulesets/Character.cpp, rulesets/Character.h,
rulesets/Creator.cpp, rulesets/Creator.h, rulesets/Entity.cpp,
rulesets/Entity.h, rulesets/Food.cpp, rulesets/Food.h,
rulesets/Line.cpp, rulesets/Line.h, rulesets/MemEntity.cpp,
rulesets/MemEntity.h, rulesets/Plant.cpp, rulesets/Plant.h,
rulesets/Stackable.cpp, rulesets/Stackable.h, rulesets/Structure.cpp,
rulesets/Structure.h, rulesets/Thing.cpp, rulesets/Thing.h,
rulesets/World.cpp, rulesets/World.h: Add integer ID handling to
constructors of all in-game entity classes.
* rulesets/MemMap.cpp: Initialise integer ID of entities in the mind
map.
* rulesets/MindFactory.cpp, rulesets/MindFactory.h: Handle integer
ID when constructing mind objects.
* server/EntityFactory.cpp, server/EntityFactory.h,
server/PersistantThingFactory_impl.h: Handle integer
ID when contructing entity objects.
* server/Restoration.cpp, server/Restoration.h, server/Restorer.h,
server/Restorer_impl.h: Handle integer ID when restoring from
database.
* server/WorldRouter.cpp: Assign integer ID when constructing the
world.
* common/BaseEntity.cpp, common/BaseEntity.h, common/inheritance.cpp,
common/inheritance.h, rulesets/BaseMind.cpp, rulesets/BaseMind.h,
rulesets/Character.cpp, rulesets/Character.h, rulesets/Entity.cpp,
rulesets/Food.cpp, rulesets/Plant.cpp, rulesets/Stackable.cpp,
rulesets/Thing.cpp, rulesets/World.cpp, server/Account.cpp,
server/Admin.cpp, server/Connection.cpp, server/server.cpp:
Remove the subscription mechanism as it is no longer necessary
now that operations have class numbers.
* common/inheritance.h: Set the correct objtype on the Root meta class.
* rulesets/Character.cpp, rulesets/Food.cpp, rulesets/Plant.cpp,
rulesets/Stackable.cpp, rulesets/Thing.cpp, server/Account.cpp,
server/Admin.cpp, server/Connection.cpp, tools/AdminClient.cpp,
tools/cycmd.cpp: Switch to renamed copyAttr() method from
Atlas-C++.
* common/BaseWorld.h, rulesets/Character.cpp, rulesets/Py_World.cpp,
rulesets/PythonThingScript.cpp, rulesets/Stackable.cpp,
rulesets/Thing.cpp, rulesets/World.cpp, server/Account.cpp,
server/Admin.cpp, server/Connection.cpp, server/EntityFactory.cpp,
server/Restoration.cpp, server/WorldRouter.cpp, server/WorldRouter.h:
Rename some functions in the World interface so they make more
sense.
* rulesets/Entity.cpp, rulesets/Entity.h: Add destroyed flag to
Entity so we can tell if its no longer in the world.
* server/WorldRouter.cpp: Cut down the special case handling of
delete ops as we can now broadcast ops from entities that
have been removed from the world.
* rulesets/Entity.cpp, rulesets/Entity.h: Make get(), set(), and
addToMessage() non-virtual, and convert them to using new property
mechanism. Add the necessary properties in the constructor.
* rulesets/Area.cpp, rulesets/Area.h, rulesets/Character.cpp,
rulesets/Character.h, rulesets/Line.cpp, rulesets/Line.h,
rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Stackable.cpp,
rulesets/Stackable.h, rulesets/World.cpp, rulesets/World.h:
Remove virtual get() set() and addToMessage() methods. These
are now entirely in Entity.
* rulesets/World.cpp, rulesets/World.h: Remove some functions
for handling terrain data now handled by properties.
Clean up Set code to get rid of nasty unnecessary exception
try / catch block.
* server/Lobby.cpp: Add some debugging messages.
* server/CommServer.cpp: Tweak select loop so that closed connections
are cleaned up as soon as they are detected.
* rulesets/World.cpp: Make demo terrain a bit more mountainous.
* Convert entire codebase over to using Atlas-C++ 0.4.90, as
start of transition to 0.6 API.
* server/EntityFactory.cpp, rulesets/Python_API.h,
rulesets/Python_API.cpp, rulesets/PythonThingScript.h,
rulesets/PythonThingScript.cpp, rulesets/PythonMindScript.cpp,
rulesets/Py_World.cpp, rulesets/Py_Thing.h, rulesets/Py_Thing.cpp,
rulesets/Py_Operation.cpp, rulesets/Py_Map.cpp,
rulesets/Py_Location.cpp, rulesets/Movement.h,
rulesets/MemMap_methods.h, rulesets/MemMap.h, rulesets/MemMap.cpp,
rulesets/Entity.cpp, rulesets/BaseMind.cpp,
client/Py_CreatorClient.cpp:
Rename all references from thing to entity, as thing is
no longer the base class for IG entities.
* rulesets/World.h, rulesets/World.cpp, rulesets/Thing.h,
rulesets/Structure.h, rulesets/Stackable.h, rulesets/Stackable.cpp,
rulesets/Plant.h, rulesets/Plant.cpp, rulesets/Missile.h,
rulesets/Line.h, rulesets/Line.cpp, rulesets/Food.h,
rulesets/Food.cpp, rulesets/Creator.h, rulesets/Character.h,
rulesets/Character.cpp, rulesets/Area.h, rulesets/Area.cpp:
Add a typedef for the parent class of all entity classes.
* rulesets/Plant.h, rulesets/Plant.cpp:
Add in code to fully integrate hardcoded attributes.
* server/Restoration.cpp: Send restored entities a setup op, so the
AI gets initialised as if the entity had just been created.
* Clean up member variable names.
* rulesets/mason/mind/SkelMind.py: Get skeleton to recognise
settlers.
* rulesets/World.h, rulesets/World.cpp, rulesets/Stackable.h,
rulesets/Stackable.cpp, rulesets/Plant.h,
rulesets/Plant.cpp, rulesets/Line.h, rulesets/Line.cpp,
rulesets/Entity.h, rulesets/Entity.cpp, rulesets/Character.h,
rulesets/Character.cpp, rulesets/Area.h, rulesets/Area.cpp,
common/type_utils.h, rulesets/Py_Thing.cpp, rulesets/Py_Mind.cpp,
client/Py_CreatorClient.cpp: Modify the way entities are queried
to avoid return by value, and use references instead.
* client/CommClient.cpp, client/CreatorClient.cpp,
client/ObserverClient.cpp, client/Py_CreatorClient.cpp,
common/BaseEntity.cpp, common/BaseEntity.h,
common/types.h, rulesets/Area.cpp, rulesets/BaseMind.cpp,
rulesets/Character.cpp, rulesets/Entity.cpp,
rulesets/Food.cpp, rulesets/Line.cpp,
rulesets/MemMap.cpp, rulesets/Pedestrian.cpp,
rulesets/Plant.cpp, rulesets/Py_Mind.cpp,
rulesets/Py_Object.cpp, rulesets/Py_Thing.cpp,
rulesets/Python_API.cpp, rulesets/Stackable.cpp,
rulesets/Thing.cpp, rulesets/World.cpp,
server/Account.cpp, server/Admin.cpp, server/CommClient.cpp,
server/CommServer.cpp, server/Connection.cpp,
server/EntityFactory.cpp, server/Lobby.cpp,
server/Persistance.cpp, server/Player.cpp,
server/ServerRouting.cpp, server/WorldRouter.cpp:
Switch to using Element as name for Atlas::Message::Object,
to avoid name clashes on Object, and bring into line with
the way Atlas-C++ will be.
* common/globals.cpp: Only persist this sessions command line
options if the user is overriding the installation directory.
* cyphesis.vconf, client/Py_CreatorClient.cpp,
client/Py_CreatorClient.h, client/client.cpp:
Add client functionality to allow diferent scripts to be run to
perform different functions on the server.
* client/CharacterClient.cpp: Add debug option.
* rulesets/Character.h: Make mind operation functions virtual,
so they can be overridden.
* common/BaseWorld.h, server/WorldRouter.cpp,
server/WorldRouter.h: Add server functions to search for
entities by name or type.
* rulesets/Creator.h, rulesets/Creator.cpp: Allow creator to
specify a look without an id to search for entities with
a given name or type.
* client/CreatorClient.cpp, client/CreatorClient.h,
client/ObserverClient.cpp, client/ObserverClient.h,
client/Py_CreatorClient.cpp, rulesets/basic/editor.py,
rulesets/mason/define_world.py:
Add support for looking for entities in the world by name or
type from client script, so client scripts can modify existing
world.
* rulesets/Entity.cpp, rulesets/Movement.cpp,
rulesets/Py_Object.cpp, rulesets/Py_Operation.cpp,
rulesets/Py_Oplist.cpp, rulesets/Python_API.cpp,
rulesets/Stackable.cpp, rulesets/Thing.cpp,
rulesets/World.cpp, server/Account.cpp,
server/CommServer.cpp, server/Connection.cpp,
server/Player.cpp, server/ServerRouting.cpp,
server/server.cpp, tools/cycmd.cpp,
tools/cywatchdog.cpp: Code formatting cleanups.
* rulesets/basic/world/objects/tools/Bow.py: Fix up bow so it now
fires correctly.
* tools/cyloadrules.cpp, server/server.cpp,
aiclient/ClientConnection.cpp, client/ClientConnection.cpp,
common/inheritance.h: Use const iterators and references
whenever possible.
* client/CommClient.cpp, client/CreatorClient.cpp,
client/ObserverClient.cpp, client/Py_CreatorClient.cpp,
common/BaseEntity.cpp, common/BaseEntity.h,
common/types.h, rulesets/Area.cpp, rulesets/BaseMind.cpp,
rulesets/Character.cpp, rulesets/Entity.cpp,
rulesets/Food.cpp, rulesets/Line.cpp,
rulesets/MemMap.cpp, rulesets/Pedestrian.cpp,
rulesets/Plant.cpp, rulesets/Py_Mind.cpp,
rulesets/Py_Object.cpp, rulesets/Py_Thing.cpp,
rulesets/Python_API.cpp, rulesets/Stackable.cpp,
rulesets/Thing.cpp, rulesets/World.cpp,
server/Account.cpp, server/Admin.cpp, server/CommClient.cpp,
server/CommServer.cpp, server/Connection.cpp,
server/EntityFactory.cpp, server/Lobby.cpp,
server/Persistance.cpp, server/Player.cpp,
server/ServerRouting.cpp, server/WorldRouter.cpp:
Switch to using Fragment as name for Atlas::Message::Object,
to avoid name clashes on Object.
* common/BaseEntity.h: Make BaseEntity inherit from SigC::Object,
so signals and callbacks can be used, and add destroyed
signal.
* common/accountbase.h, physics/BBox.h, physics/Quaternion.h,
physics/Vector3D.h, rulesets/MemMap_methods.h,
rulesets/Movement.cpp, rulesets/Plant.h,
rulesets/Py_Operation.cpp, rulesets/PythonMindScript.cpp,
rulesets/PythonThingScript.cpp, rulesets/Script.cpp,
common/inheritance.cpp: Cleaned up Atlas::Message::Object
use, and excessive use of "using ...".
* rulesets/Movement.h, rulesets/Pedestrian.h:
Use forward declarations rather than including Move.h
* server/Account.cpp, server/Account.h, server/Connection.cpp,
server/Connection.h: Use destroyed signal to ensure references
to in game entities are removed when those entities are
destroyed. Ensure Connection is only destroyed once.
* ALL: Cleaned up headers into correct order.
* common/log.h, common/log.cpp: Write some logging code which
handles message of different types using syslog or standard
error, depending on whether we are running as a daemon.
* ALL: Switched to using log() for all output.
* client/ObserverClient.cpp, server/Account.cpp, server/Connection.h,
server/Routing.h: Formatting cleanup
* client/Py_CreatorClient.cpp, rulesets/Area.cpp, rulesets/Area.h,
rulesets/Character.cpp, rulesets/Character.h, rulesets/Entity.cpp,
rulesets/Entity.h, rulesets/Line.cpp, rulesets/Line.h,
rulesets/Plant.cpp, rulesets/Plant.h, rulesets/Py_Mind.cpp,
rulesets/Py_Thing.cpp, rulesets/Stackable.cpp, rulesets/Stackable.h:
Replace operator[] with get() method for querying attributes.
Make this get() method const, and re-write the internals so
that it more cleanly handles attributes.
* common/BaseWorld.h: Re-write world.getObject() so that it
no longer uses std::map::operator[], as the old method was
inserting NULLs into the world dictionary when non-existant
entities were queried.
* rulesets/Character.cpp: Clean up outstanding issues when movement
position is supplied, and is very close to being correct, and
clarify comments about movement when neither destination nor
source are provided.
* rulesets/Character.cpp: Modify mind2body interface so that setting
the TO of ops is done in the individual handlers, and copying
the operation globally is avoided.
* rulesets/MemMap_methods.h: Remove dodgy debug code.
* rulesets/Pedestrian.cpp: Clarify movement fixme.
* rulesets/Py_Operation.cpp: Clarify operation time handler fixme.
* rulesets/Stackable.cpp: Clarify fixme's in combine and divide
handlers.
* server/CommServer.cpp: Remove redundant fixme.
* server/Connection.cpp, server/ServerRouting.cpp,
server/ServerRouting.h, server/ServerRouting_methods.h,
server/server.cpp:
Move inline ServerRouting::getObject into class header.
* server/WorldRouter.cpp, server/WorldRouter.h:
Clean up includes, and move updateTime into the main body of the
file. Clean up code formatting when handling maps and dictionaries.
Clarify error output and comments about NULL objects in the world
dictionary.
* server/WorldRouter.cpp: Eliminate unnecessary call to opEnumerate()
and enhance debugging output.
* server/Player.cpp: Correct the use of string.compare() in older
versions of libstdc++.
* common/types.h: Added enumeration for other operations, not
handled by the core, but considered valid. Added new type
for storing mapping between operation parents and their
enumerated type.
* common/op_switch.h: Separate handling of operations known to
be invalid from operations which are valid, but not explicitly
added to the core.
* common/inheritance.h, common/inheritance.cpp, common/custom.cpp:
Provide global operation mapping where enumeration of operations
can be looked up. Install all types handled by the core, and
types known to be used in scripts.
* common/BaseEntity.h, common/BaseEntity.cpp: Add object specific
operation mapping where operation types each object is subscribed
to can be enumerated, and others are rejected. Add mechanism
so that objects can add to the mapping, this subscribing to
operations. This makes enumerating operations much cheaper, and
eliminates the overhead of handling ops an object has no interest
in.
* rulesets/Thing.h, rulesets/Thing.cpp: Add mechanism so scripts
can subscribe to operations.
* rulesets/Character.h, rulesets/Character.cpp:
Add subscription mechanism for ops going to and from
the mind.
* rulesets/BaseMind.h, rulesets/BaseMind.cpp:
Add subscription mechanism for sight and sound perception
operations sub operations, and provide an interface to it
for scripts.
* server/Connection.cpp, server/Admin.cpp, server/Account.cpp,
rulesets/World.cpp, rulesets/World.h, rulesets/Thing.cpp,
rulesets/Stackable.cpp, rulesets/Plant.cpp, rulesets/Food.cpp,
rulesets/Character.cpp, rulesets/BaseMind.cpp:
Add subscriptions to operations for all core base classes.
* rulesets/Python_API.cpp: When script is created, go through
methods, and subscribe to the operations which are handled by
them.
* rulesets/Character.cpp: When calculating orientation of a walking
character, assume it is standing upright.
* physics/Vector3D.h: Add versions of mag() and distance() which
omit the square root calculations, so that when their values
are only used for comparison, the expensive square root
calculations can be ommited. Add new version of collision
and range checking functions which provide the optimal
interface to the application. Add versions of methods which
modify this rather than creating a new operation to eliminate
wasted copies.
* physics/Quaternion.cpp: Make use of faster interface provided
by Vector3D.
* physics/BBox.h: Add new version of collision checking function
which provides optimal interface to the application.
* modules/Location.h, modules/Location.cpp: Add new functions
to optimally calculate the distance between any two entities.
* modules/Location.h: Re-write collision and range functions to
make much more optimal use of Vector3D, BBox and distance
functionality.
* rulesets/Py_Vector3D.cpp, rulesets/Pedestrian.cpp,
rulesets/Movement.cpp, rulesets/Entity.cpp, rulesets/Character.cpp:
Eliminate implicit copies from vector arithmetic.
* rulesets/Pedestrian.cpp, rulesets/MemMap.cpp, common/const.h:
Re-write code which uses magnitude of vectors to use the square
of the magnitude instead, as it is much cheaper to calculate.
* server/Persistance.cpp, server/Connection.cpp, server/Admin.cpp,
server/Account.cpp, rulesets/Thing.h, rulesets/Thing.cpp,
rulesets/Stackable.cpp, rulesets/Py_Location.cpp,
rulesets/Entity.h, rulesets/Entity.cpp, rulesets/Creator.cpp,
rulesets/Character.cpp, common/BaseEntity.h, common/BaseEntity.cpp:
Get rid of flags used to determine object type, and get rid
of use of C style casts to cast between object pointers.
Replace both with dynamic casts. Clean up some stray casts
left behind from older versions of object structure.
* physics/Vector3D.cpp: Added note explaining when to use
Vector3D::relMag() instead of mag().
rulesets/EntityFactory.cpp, rulesets/MindFactory.cpp,
rulesets/Stackable.cpp, server/Account.cpp, server/Admin.cpp,
server/CommClient.h, server/CommServer.cpp, server/CommServer.h,
server/Connection.cpp, server/ExternalMind.cpp,
server/Persistance.cpp, server/Persistance.h,
server/ServerRouting.cpp, server/WorldRouter.cpp,
server/server.cpp: Removed unused includes and code. Added some
FIXMEs.
* rulesets/Thing.cpp: Added TO and FROM to faked Sight(Create()) ops.
* server/OOG_Thing.cpp, server/OOG_Thing.h: Marked files as removed.
Al Riddoch <alriddoch@zepler.org>
* TODO: Update on important issues which allow easy DOS attacks.
* client/ClientConnection.cpp, client/ClientConnection.h:
Cleaned up unused code from ClientConnection class.
* client/client.cpp: Removed monitoring section of client
so it simply exits once the world is initialised.
* rulesets/basic/mind/goals/humanoid/werewolf.py:
Started work on dynamic goals for playing werewolf.
* rulesets/werewolf/define_world.py: Added in the mayor, who runs
werewolf games.
* common/BaseEntity.h: Made id of entity private, and implemented
accessors.
Al Riddoch <alriddoch@zepler.org>
atlas object inheritance tree.
* server/Connection.cpp: Added code to allow client to query
atlas object inheritance using get ops.
* example/client/InheritanceClient.*: Added example client which
queries the inheritance tree of the server.
* rulesets/MemMap.h, rulesets/Py_Map.cpp: Made hooks lists private,
and added methods to access them.
* server/Account.cpp, server/Lobby.h: Added correct handling of OOG
look ops when looking at own characters, other accounts, or the
lobby.
* server/ServerRouting.h: Added function to generate serial numbers
for operations.
* server/WorldRouter.cpp: Assign genuine serial number to all
in game operations as they are pulled off the queue.
* Cleaned up header file multiple inclusion checks for uniqueness,
and made sure of ISO compliant use of std::string.
Al Riddoch <alriddoch@zepler.org>
server/CommServer.h: Added support for server "name" which
defaults to the hostname of the server machine, but is
customisable in the config. This can be used in preference to
IP address when doing lookups with the metaserver.
* server/Lobby.h, server/ServerRouting.h, server/Account.h,
server/Account.cpp, rulesets/Stackable.h, rulesets/Stackable.cpp,
rulesets/Python_API.cpp, rulesets/Py_Object.cpp, rulesets/Plant.cpp,
rulesets/Pedestrian.cpp, rulesets/Entity.h, rulesets/Entity.cpp,
rulesets/Character.h, rulesets/Character.cpp, common/BaseEntity.h,
common/BaseEntity.cpp: Modied asObect() and addToObject()
methods to make them more efficient.
* modules/Location.h, modules/Location.cpp: Removed old obsolete
Message::Object based addToObject() method.
* rulesets/Thing.cpp: Optimised apperance/disappearance code.
Al Riddoch <alriddoch@zepler.org>