class Object:
def MoveTo(self, dest):
if self.container:
self.container.Remove(self)
self.container = dest
dest.Add(self)
if ( !pObject->MoveTo(pCreature) )
{
apCreature->PutOutput( "You can't seem to pick it up.\r\n" );
}
else …
if ( !pCreature->MoveTo(pLocation, &Message) )
{
apCreature->PutOutput( "You're unable to enter it.\r\n" );
}
else …
Room.add ch
Room.add item
list = []
ch.push list
dude = Character.new
magic = dude.cast(:refresh)
# What do we do with our fireball? At this point it's a bit undecided but I think this is elegant.
# Let's assume it was cast on self.
dude.absorb(magic)
effect = dude.cast(:enchant_weapon)
item.absorb(effect)
dude.spell_book do |spell|
magic = dude.cast(spell)
### Do something with each spell that can be cast? Maybe for the purpose of gathering information?
### Maybe for mock casts for AI to judge actual effect of spellcast?
magic.inspect
end
fire = dude.cast(:fireball)
ice = dude.cast(:frostlance)
fireice = fire.combine(ice)
enemy.absorb(fireice)
class ExitImpl extends GroovyMudObject implements Exit{
String direction;
String arrivalDirection;
ObjectLocation destination;
transient View view
void go(object, String args) {
if(shortNames.contains(args) || direction == args){
def event = new MovementEvent(object.currentContainer, destination, object as Alive, this)
object.fireEvent(event);
event = new MessageEvent(scope: EventScope.ROOM_SCOPE)
event.setScope(EventScope.ROOM_SCOPE);
event.setSource(object);
event.setSourceMessage("You go ${direction}.");
event.setScopeMessage(object.getDepartureMessage(this));
movingObject.fireEvent(event);
registry.mudObjectAttendant.moveToLocation(object, destination)
def otherExit = movingObject.currentContainer.getExit(arrivalDirection)
ArrivalEvent arriveEvent = new ArrivalEvent(scope: EventScope.ROOM_SCOPE, direction: otherExit)
arriveEvent.setSource(object)
arriveEvent.setSourceMessage(null)
arriveEvent.setScopeMessage(object.getArrivalMessage(otherExit))
movingObject.fireEvent(arriveEvent)
movingObject.look()
return true
}
return false
}
}
class DoorImpl extends ExitImpl {
MudObjectAttendant objectAttendant
boolean open = false
transient DoorImpl otherDoor = null;
def open(obj, String args){
boolean consume = shortNames.contains(args)
if(!open && consume){
sendMessageToRoom(obj, "You open the ${direction} door.", "${obj.name} opens the ${direction} door.")
doorEvent(obj, true)
}else if(consume){
sendMessageToPlayer(obj, "You try to open the ${direction} door but it is already open.")
}
return consume
}
private def doorEvent(obj, boolean op){
this.setOpen op
if(otherDoor == null){
DoorImpl od = findOtherDoor(arrivalDirection, destination)
od.setOpen op
if(!od.otherDoor){
od.setOtherDoor this
this.setOtherDoor od
}
od = null
}
sendMessageToRoom(otherDoor, "", "The ${otherDoor.direction} door ${op ? 'opens' : 'closes'}.")
fireDoorEvent(obj)
}
def close(obj, String args){
boolean consume = shortNames.contains(args)
if(open && consume){
sendMessageToRoom(obj, "You close the ${direction} door.", "${obj.name} closes the ${direction} door.")
doorEvent(obj, false)
}else if(consume){
sendMessageToPlayer(obj, "You try to close the ${direction} door but it is already closed.")
}
return consume
}
DoorImpl findOtherDoor(String direction, ObjectLocation location){
def otherRoom = objectAttendant.findOrClone(location)
def od = null
if(otherRoom != null){
def otherExit = otherRoom.getExit(direction)
if(otherExit instanceof DoorImpl){
od = otherExit
}
}
return od
}
void fireDoorEvent(player){
DoorEvent openEvent = new DoorEvent(source:this, targetRoomLocation: destination,
targetDirection: arrivalDirection, open: this.open)
fireEvent(openEvent)
}
void go(player, String args) {
if(getOpen()){
super.go(player, args)
if(otherDoor == null){
otherDoor = findOtherDoor(arrivalDirection, destination)
}
}else{
sendMessageToRoom(player, "You try to go ${getDirection()} but the door is closed!",
"${player.getName()} tries to go ${getDirection()} but the door is closed!")
}
}
}
begin
ch.enter(exit)
rescue ObjActionFail => FailMsg
ch.print(FailMsg) ### Probably that the door is closed.
end
World.do_something(character, args);
do_something(character, "stuff");
Personally, I'm leaning toward the world.move() paradigm. I don't think game entities should be aware of other game entities in the way that the first two options would allow. Assuming dudes and rooms are part of the world, this keeps encapsulation intact, since world is only manipulating its own properties. However, I've seen the last paradigm a lot recently, and I'm not sure what to make of that. To me, a command interpreter would be part of the engine, same as the world, and it seems like bad encapsulation to allow one to muck about with the other. Maybe I'm looking at it from the wrong point of view, though?
Note that I'm not just asking in relation to movement. I'd like opinions about commands/actions in general, and where you think they fit.
Edit: My example was a failure. I shouldn't be posting so late. What I really meant to say was this: