-
Notifications
You must be signed in to change notification settings - Fork 0
Tutorial 4
Rooms are just objects like everything else but we need some extra control to handle exits and travelling between them.
To store the exits between rooms, we shall add a new property to the Generic Room that we created in the previous tutorial:
;moo.system.room:propadd( "exits", {} )
We shall create a @dig verb that will allow us to easily make new rooms and link locations together:
@verbadd $generic_programmer:@dig any any any
Verb code:
if #moo.args ~= 1 and #moo.args ~= 3 then
moo.notify( "Usage: @dig \"new room name\"" )
moo.notify( "Usage: @dig <exit> to \"new room name\"" )
moo.notify( "Usage: @dig <exit> to <room>" )
return
end
local RoomName = ""
local RoomObject = nil
local ExitSpec = ""
if #moo.args == 1 then
RoomName = moo.args[ 1 ]
RoomObject = moo.create( moo.system.room )
if RoomObject == nil then
moo.notify( "Unable to create room" )
else
RoomObject.name = RoomName
moo.notify( "Created room \"" .. RoomName .. "\" (#" .. RoomObject.id .. ")" )
end
return
end
ExitSpec = moo.args[ 1 ]
RoomName = moo.args[ 3 ]
RoomObject = moo.find( RoomName )
if RoomObject == nil then
RoomObject = moo.create( moo.system.room )
RoomObject.name = RoomName
moo.notify( "Created room \"" .. RoomName .. "\" (#" .. RoomObject.id .. ")" )
else
RoomName = RoomObject.name
end
if string.find( ExitSpec, "|" ) ~= nil then
Exit1, Exit2 = string.match( ExitSpec, "(.*)|(.*)" )
else
Exit1 = ExitSpec
Exit2 = nil
end
RoomExits1 = moo.here.exits
for Exit in string.gmatch( Exit1, "%a+" ) do
RoomExits1[ Exit ] = RoomObject
end
moo.here.exits = RoomExits1
RoomExits2 = RoomObject.exits
for Exit in string.gmatch( Exit2, "%a+" ) do
RoomExits2[ Exit ] = moo.here
end
RoomObject.exits = RoomExits2
Create a new 'go' verb for players to move about:
@verbadd $generic_player:go any none none
Verb code:
moo.programmer = moo.player
local Exit = moo.here.exits[ moo.dobjstr ]
if Exit == nil then
moo.notify( "You can't go that way" )
return
end
moo.player.location = Exit
Let us now create a second room and link to it, creating exits to the east (from the first room) and the west (from the second room):
@dig e|w to "The Second Room"
We can now move between the two rooms using the 'go' verb:
;moo.notify( moo.here.name )
The First Room
go e
;moo.notify( moo.here.name )
The Second Room
go w
;moo.notify( moo.here.name )
The First Room
It would be preferable to have the system print some feedback to the player as they move between rooms. Let's add a description to our generic thing:
@propadd $thing.description "You don't notice anything of interest"
Rather than just having a text string, we are going to add a description verb that can be overridden by objects to provide dynamic descriptions:
@verbadd $thing:description
Verb code:
return moo.object:prop( "description" ):value()
We can now add a basic 'look' verb:
@verbadd $generic_player:look none none none
Verb code:
moo.notify( moo.here.name )
moo.notify( moo.here:description() )
As we want this verb to be called automatically when the player moves between rooms, we can create verbs called 'enterfunc' and 'exitfunc' that will called internally by the system:
@verbadd $room:enterfunc
Verb code:
local Object, From = ...
if Object.player == true then
moo.object:tell( moo.player.name .. " has arrived" )
Object:look()
end
And exitfunc:
@verbadd $room:exitfunc
Verb code:
local Object, To = ...
if Object.player == true then
moo.object:tell( moo.player.name .. " has left" )
end
And finally, we need to add the verb to tell messages to the other players in a room:
@verbadd $room:tell
Verb code:
for k, v in ipairs( moo.caller:players() ) do
if v.id ~= moo.player.id then
v:notify( args[ 1 ] )
end
end
It would also be nice for the look verb to show what exits are available:
@edit $generic_player:look
Updated verb code:
moo.notify( moo.here.name )
moo.notify( moo.here:description() )
local ExitDesc = {}
local ExitNames = { n = "north", s = "south", e = "east", w = "west",
u = "up", d = "down" }
for k, v in pairs( moo.here.exits ) do
table.insert( ExitDesc, "To the " .. ExitNames[ k ] .. " is " .. v.name .. "." )
end
if #ExitDesc ~= 0 then
moo.notify( table.concat( ExitDesc, " " ) )
end
We can now move around like so:
look
The First Room
You don't notice anything of interest
To the east is The Second Room.
go e
The Second Room
You don't notice anything of interest
To the west is The First Room.
We have created a @dig verb to allow easy creation of new rooms and the exits between them. We've also added a look verb and a way of adding dynamic descriptions to objects that will be reported to players.
The next stage is adding support for multiple users to log into the system!