Difference between revisions of "Regions and Locales"

From SCI Wiki
Jump to navigationJump to search
 
m (1 revision)

Revision as of 17:46, 5 August 2013

Chapter 2 - Regions and Locales

If you want to have a common set of behavior (handling Said statements, doit methods, changeStates) that extend across rooms, regions and locales are what you need.

Locales

Locales are the simpler of the two. Basically, they allow you to specify a handleEvent method that can be used across multiple rooms. To create a locale, you need to create a new (empty) script, and put a public instance of the class Locale at the top of the script.

For example, suppose you have many rooms with snow. You want to only code up the responses to someone looking at snow once, you could write the following locale:

Code:
    /******************* Snow  locale *********************************************/
    (include "sci.sh")
    (include "game.sh")
    /******************************************************************************/
    (script 777)
    /******************************************************************************/
    (use "controls")
    (use "game")
    (use "main")
    (use "obj")
     

    (instance public snowLocale of Locale
        (properties)

        (method (handleEvent pEvent)
            (super:handleEvent(pEvent))
            (if(Said('look/snow'))
                Print("Look at all that nice snow.")
            )
        )
    )

And then, in the init method of each room where you have snow, you can add a call to setLocales.

For example:

Code:
(instance public rm001 of Rm
      (properties
            picture scriptNumber
            // Set up the rooms to go to/come from here
            north 0
            east 0
            south 0
            west 0
      )

      (method (init)
            (super:init())
            (self:setScript(RoomScript))
          
            (switch(gPreviousRoomNumber)

            // Set up ego's position if it hasn't come from any room
                  (default
                        (send gEgo:
                              posn(150 130)
                              loop(1)
                        )
                  )
            )
          
            // Set up the ego
            SetUpEgo()       
            (send gEgo:init())
 
            // Set up the snow locale
            (self:setLocales(777))

      )
)

You can specify multiple script numbers in the call to setLocales. The only requirement is that the first public instance in that script must be an instance of the Locale class.

You can specify multiple script numbers in the call to setLocales. The only requirement is that the first public instance in that script must be an instance of the Locale class.

Regions

Regions are very similar to Locales, except that they provide more functionality. Basically anything you can do in a room, you can do with a region too: apply a custom script that has not only handleEvent, but also doit, and changeState methods. Again, make a new script for your region, and ensure the first public instance in that script, is of the class Rgn.

Region example:

Code:
/******************* dog region ****           ********************************/
(include "sci.sh")
(include "game.sh")
/******************************************************************************/
(script 778)
(use "controls")
(use "feature")
(use "cycle")
(use "follow")
(use "wander")
(use "game")
(use "main")
(use "obj")

(local
    goneToBathroom = FALSE
)


(instance public dogRegion of Rgn
    (properties)
      (method (init)
        (super:init())
        (self:setScript(DogRegionScript))


        // Make a dog that follows you
        (aDog:
            ignoreControl(ctlWHITE)
            ignoreActors()
            setMotion(Follow gEgo 15)
            init()
        )
    )
)

(instance DogRegionScript of Script
    (properties)

    (method (changeState newState)
        (= state newState)
        (switch (newState)
            (case 0
                // nothing to do here.
            )
            (case 10
                // Make the dog walk to the edge of the screen
                (aDog:setMotion(MoveTo 0 150 DogRegionScript))
            )
            (case 11
                // And disappear
                (aDog:hide())
            )
        )
    )
 
    (method (doit)
        (super:doit())
        (if (not goneToBathroom)
            // Assuming that you gave all grass a green control colour...
            (if (& (aDog:onControl()) ctlGREEN)
                (= goneToBathroom TRUE)
                Print("The dog finds a nice patch of grass and goes to the bathroom")
            )
        )
    )

 

    (method (handleEvent pEvent)
        (super:handleEvent(pEvent))
     
        (if (Said('give/food/dog'))
            Print("You give food to the dog and he runs away")
            (self:changeState(10))
        )
    )
)

 
(instance aDog of Act
    (properties
        x 50
        y 150
        view 800
    )
)


To apply this to a room, in its init method, do:

Code:
            // Set up the dog region
            (self:setRegions(778))

When this region is applied to a room (via the setRegions method, which works just like setLocales), the dog will follow you around. If you give it food, it will run away. If it encounters a patch of grass, it will go to the bathroom. So pretty much any logic you put into a room, you can also put into a region that can be applied to any room.

Note that the room's methods are called before the regions', and the regions 'before the locales'. So if in a region you have a Said clause that is identical to one in a room, the room's Said clause will win.

 

< Previous: Chapter 1 - Advanced Said() Strings - Part 1 Next: Chapter 3 - Scripting Props and Acts >