Regions and Locales

From SCI Wiki
Jump to navigationJump to search

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 *********************************************/
(script 777)
;;;******************************************************************************/
(include sci.sh)
(include game.sh)
;;;******************************************************************************/
(use controls)
(use game)
(use main)
(use obj)

(instance 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 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 &tmp button)
		(super init:)
		(self setScript: RoomScript)

		(switch gPreviousRoomNumber
			; Set up ego's position if it hasn't come from any room
			(else 
				(gEgo posn: 150 130 loop: 1)
			)
		)

		; Set up the ego
		(SetUpEgo)
		(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.

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 ************************************/
(script 778)
;;;******************************************************************************/
(include sci.sh)
(include game.sh)
;;;******************************************************************************/
(use controls)
(use feature)
(use cycle)
(use follow)
(use wander)
(use game)
(use main)
(use obj)

(local
	goneToBathroom = FALSE
)

(instance 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)
			(0
				; Nothing to do here.
			)
			(10
				; Make the dog walk to the edge of the screen...
				(aDog setMotion: MoveTo 0 150 DogRegionScript)
			)
			(11
				; ...and disappear
				(aDog hide:)
			)
		)
	)

	(method (doit)
		(super doit:)
		(if (not goneToBathroom)
			; Assuming that you gave all grass a green control colour...
			(if (and (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 >