It actually works out far better than I thought it was going to go. I currently have close to 100 "rooms" operating off of one script (well actually two because I couldn't get the cave room to reload itself)
Here's what I did...
First I'll start with my jumper script, it is basicly a script I use to transition from one cave room to the other. It also determines if a special room has been reached and if so, loads up the other room instead of the cave room. So basically the only purpose of this room is to jump immediately to a different room.
//******************************************************************************
(include "sci.sh")(include "game.sh") (script 200)
//******************************************************************************
(use "Controls")(use "Cycle")(use "Feature")(use "Game")(use "Main")(use "Obj")
//******************************************************************************
(instance public rm200 of Rm
(properties picture 800)
(method (init)
(super:init())
(self:setScript(RoomScript))
)// end method
)// end instance
//******************************************************************************
(instance RoomScript of Script
(properties)
(method (doit)
(super:doit())
UnLoad(rsPIC 800)
UnLoad(rsSCRIPT scriptNumber)
(switch(caveRoom) // list any special rooms as well as cave exits
(case 100 = caveRoom 24 // reset to defaults
= lastCaveRoom 3
= caveLevel 0
(send gRoom:newRoom(12))) // outside
(case 150 = caveRoom 1
= lastCaveRoom 4
= caveLevel 4
(send gRoom:newRoom(15))) // mushroom pool
(default (send gRoom:newRoom(13))) // Back to cave room
)
)// end doit method
)// end instance
//******************************************************************************
There are some pretty general global variables set. The current level of the caves, the current room of the caves, and the direction the previous room was.
caveLevel = 0 // current cave level
caveRoom = 24 // current cave room
lastCaveRoom = 3 // 0=downLadder, 1=north, 2=east, 3=south, 4=west,5=upLadder
And then comes the cave room script. Just to try and explain it as I go, it will probably be easier to break this down into sections. So we start with the local variables... the goDirections variables are declared and set to 0. There is also a doColor set of variables, these are going to be used to tell ego to observe the color if it needs to. In my case, I used these for the ladders. The ladder down is set in a hole in the middle of the room so the hole can't be walked on. Likewise the ladder going up needs to have the blocking controls set up as well just to make sure it doesn't get walked through.
//******************************************************************************
// rm013.sc
//******************************************************************************
(include "sci.sh")(include "game.sh") (script 13)
//*****************************************************************************
(use "main")(use "controls")(use "cycle")(use "game")(use "feature")(use "obj")
//*****************************************************************************
(local
goNorth = 0
goEast = 0
goSouth = 0
goWest = 0
doYellow = FALSE
doNavy = FALSE
)
//*****************************************************************************
Then, there is placing ego and this is where one of our global variables come in. Basically the lastcaveroom from above. It isn't really descriptive of what it stores but when I first made it I had a different idea.
(instance public rm013 of Rm
(properties picture scriptNumber)
(method (init)
(super:init())
= goToRoom 0
(self:setRegions(950)) // PnC Menu
(self:setScript(RoomScript))
(switch(lastCaveRoom)
(case 0 (send gEgo:posn(160 120)loop(3)))//come down ladder
(case 1 (send gEgo:posn(157 86)loop(2)))//north
(case 2 (send gEgo:posn(219 110)loop(1)))//east
(case 3 (send gEgo:posn(157 137)loop(3)))//south
(case 4 (send gEgo:posn(98 110)loop(0)))//west
(case 5 (send gEgo:posn(176 93)loop(0)))//come up ladder
)
Now comes the long boring part, I'll only show a bit of this just to get the point across. Here is where I declare the rooms and how they interconnect. I do this with a nested switch using the other two global variables. First depending on which level ego is on and then what room ego is in. Depending on the room as to which rooms connect to it. This is where our directional local variables come into play. The values given represent the pretend room numbers in the given direction. If the direction should be blocked off, then I leave the value set to 0. Before starting this, it would be a good idea to have your caves mapped out. Whenever you come to a room that needs something special in it, simply init it in that case. If you look, you'll see the ladders that I have up and running. Likewise, in those rooms, I also set the do color local variables I declared to true so that when I init the ego, I know whether or not he needs to be blocked by those colors.
Heres what I did for mapping prior to starting this
1 2 3 4 5 6
7 8 9 10 11 12
...
and then the boring bit of code. Again, this is highly abbreviated. I have a crap ton of rooms running off of this script, and each and every one of them has a case statement devoted to it.
(switch(caveLevel)
(case 0
(switch(caveRoom)
(case 24
= goNorth 18
= goEast 0
= goSouth 100 // to world map room 12
= goWest 23
)
(case 23
= goNorth 0
= goEast 24
= goSouth 0
= goWest 22
)
(case 22
= goNorth 16
= goEast 23
= goSouth 0
= goWest 0
)
(case 21
= goNorth 15
= goEast 0
= goSouth 0
= goWest 20
)
(case 6
= goNorth 0
= goEast 0
= goSouth 12
= goWest 0
(ladderDown:addToPic())
= doYellow TRUE
)
)// end caveRoom switch for level 0
)// end level 0 case
(case 1
(switch(caveRoom)
(case 34
= goNorth 28
= goEast 35
= goSouth 0
= goWest 0
)
(case 35
= goNorth 0
= goEast 0
= goSouth 0
= goWest 34
)
(case 18
= goNorth 0
= goEast 0
= goSouth 24
= goWest 0
(ladderUp:addToPic())
= doNavy TRUE
)
)// end caveroom switch
)// end caveLevel 1
)// end caveLevel switch
Now with everything more or less declared, or I at least know which way is what anyway. It is time to init our room blocks and our ego.
(if(== goNorth 0)
(northBlock:addToPic())
Graph(grDRAW_LINE 76 134 76 177 -1 -1 clWHITE)// y1 x1 y2 x2
)
(if(== goSouth 0)
(southBlock:addToPic())
Graph(grDRAW_LINE 137 138 137 177 -1 -1 clWHITE)// y1 x1 y2 x2
)
(if(== goEast 0)
(eastBlock:addToPic())
Graph(grDRAW_LINE 99 231 121 231 -1 -1 clWHITE)// y1 x1 y2 x2
)
(if(== goWest 0)
(westBlock:addToPic())
Graph(grDRAW_LINE 101 86 120 86 -1 -1 clWHITE)// y1 x1 y2 x2
)
SetUpEgo()
(if(doYellow)
(send gEgo:observeControl(ctlYELLOW)init())
)
(else
(if(doNavy)
(send gEgo:observeControl(ctlNAVY)init())
)
(else
(send gEgo:init())
)
)
)// end init method
)// end instance
Beyond that, the only thing I am really doing is resetting my global variables at room transitions. I have this bit in the RoomScripts Doit method. I know I space my code different than most, so I broke one down into separate lines...
(if(>(send gEgo:y) 145)
= caveRoom goSouth // reset our global variable to the value held in local variable
= lastCaveRoom 1 // remember this actually represents direction not a room number
= goToRoom 200 // off to the jumper script which reloads cave rooms or special rooms
)
(if(<(send gEgo:y) 77) = caveRoom goNorth = lastCaveRoom 3 = goToRoom 200)
(if(>(send gEgo:x) 233) = caveRoom goEast = lastCaveRoom 4 = goToRoom 200)
(if(<(send gEgo:x) 80) = caveRoom goWest = lastCaveRoom 2 = goToRoom 200)
and for the click on ladder interactions to illustrate how I handled the level variables. Of course I am using the point and click template hence all the coding about the cursor. This bit would be in the RoomScripts handleevent method...
// Click on View
(if((> (send pEvent:x) (ladderDown:nsLeft))and
(< (send pEvent:x) (ladderDown:nsRight))and
(> (send pEvent:y) (ladderDown:nsTop))and
(< (send pEvent:y) (ladderDown:nsBottom)))
(switch(gCurrentCursor)
(case 999 (send pEvent:type(evMOUSEBUTTON) claimed(FALSE))) // walk
(case 998 (send pEvent:type(evMOUSEBUTTON) claimed(TRUE))Print("There is a ladder here leading further down into the caves."))// look
(case 996 (send pEvent:type(evMOUSEBUTTON) claimed(TRUE))Print("The ladder has nothing to say."))// talk
(case 995 (send pEvent:type(evMOUSEBUTTON) claimed(TRUE))// get
(if(send gEgo:inRect(136 94 184 120))
(switch(caveLevel)
(case 0 = caveLevel 1 = caveRoom 18 = lastCaveRoom 0)// from level 0 to level 1 and into room 18 from ladder...
(case 1 = caveLevel 2 = caveRoom 4 = lastCaveRoom 0)
(case 2 = caveLevel 4 = caveRoom 4 = lastCaveRoom 0)// skipping a level ... just too much maze
)
= goToRoom 200
)
(else
Print("You need to stand in a better spot")
)
)// end case
(default (send pEvent:type(evMOUSEBUTTON) claimed(TRUE))Print("There is no reason to use that on the ladder."))// item
)// end current cursor switch
)// end if item
and that is how I did a massive cave labrynth with just 2 scripts... and again I would have only needed 1 if I could have gotten the room to send to itself. I am currently sitting at 10000 heap to go so I could easily grow this another hundred rooms if I was so inclined by simply adding more room number cases or levels in the init section at the top.