Author Topic: Region allowing the switching of Ego characters  (Read 9205 times)

0 Members and 1 Guest are viewing this topic.

Offline Doan Sephim

Region allowing the switching of Ego characters
« on: May 20, 2017, 09:57:36 PM »
While dusting off Betrayed Alliance to put together an update to rid it of many bugs, I came across an idea that I hadn't implemented, but had plans to work on later.

For fun, I fixed it up a bit and now it's up and working pretty well.

What this allows you to do is click on a button to switch characters. Each character will have his own inventory and the items will be transferred correctly each time. It remembers the X and Y position for each character as well as the room number.

A feature NOT included is what happens if the characters are in the same room.

Here's the code:
Code: [Select]
/******************************************************************************/
/*                         Ego-Switching Region                               */
/*                           by Ryan Slattery                                 */
/*              Originally Designed For Betrayed Alliance Book 2              */
/******************************************************************************/
(include "sci.sh")
(include "game.sh")
/******************************************************************************/
(script 205)
/******************************************************************************/
(use "Controls")
(use "Cycle")
(use "Feature")
(use "Game")
(use "Main")
(use "Obj")

(local

myEvent                      /* Used in the Doit method to track the mouse over the switch button */
buttonOpen = 0               /* Used so that the Doit method doesn't send constant signals cancelling the button animation */

roomToggleNumber             /* Intermediary variable allowing the change of gSwitchedRoomNumber before calling gRoom:newRoom command */
characterXYToggle[2] = (0 0) /* Intermediary variable allowing the change of posn before asigning new gPrevXY variables */
itemIteration                /* Used to switch all items from one character to a room or from a room to the other character */
                             /* Items stored for Male Ego in Rm 205 and for Female Ego in Rm 210 */
                             /* IMPORTANT - remember to change the item Iteration # as you add items */

)
/******************************************************************************/
(instance public egoSwitchRegion of Rgn
    (properties)
    (method (init)
        (super:init())
        (switcher:init()ignoreActors()setPri(15))
    )
   
    (method (handleEvent pEvent)
        (super:handleEvent(pEvent))
       
        (if((Said('switch'))
            or
            (if(==(send pEvent:type())evMOUSEBUTTON)
                (if((> (send pEvent:x) (switcher:nsLeft))and
                    (< (send pEvent:x) (switcher:nsRight))and
                    (> (send pEvent:y) (switcher:nsTop))and
                    (< (send pEvent:y) (switcher:nsBottom)))
                )
            ))

            /* Remove and Give Items based on who is being used */
            (for (= itemIteration 0) (< itemIteration 19) (++itemIteration)
                (if(gAnotherEgo) /* Switching from Female Ego */
                    (if(== (send gEgo:has(itemIteration)) 1)
                        (send gEgo:put(itemIteration 210)) // Items stored in Room 210
                    )
                    (if(== (IsOwnedBy(itemIteration 205)) 1) /* Items stored in Rm 205 given to Male Ego */
                        (send gEgo:get(itemIteration))
                    )
                )(else /* Switching from Male Ego */
                    (if(== (send gEgo:has(itemIteration)) 1)
                        (send gEgo:put(itemIteration 205)) // Items stored in Room 205
                    )
                    (if(== (IsOwnedBy(itemIteration 210)) 1) /* Items stored in Rm 210 given to Female Ego */
                        (send gEgo:get(itemIteration))
                    )
                )
            )

            (if(gAnotherEgo)
                = gAnotherEgo 0 /* Male character */
                = gEgoView 0
                = gEgoStoppedView 903
            )(else
                = gAnotherEgo 1 /* Female character */
                = gEgoView 342
                =gEgoStoppedView 903 // Haven't drawn it yet
            )
            /* Get Room Number Variables saved and set up for room switch */
            = roomToggleNumber gSwitchedRoomNumber // saves variable for newRoom call
            = gSwitchedRoomNumber gRoomNumber      // saves current room as the new switched room

            /* Get Ego's X/Y position saved and set up for room switch */
            = characterXYToggle[0] (send gEgo:x)
            = characterXYToggle[1] (send gEgo:y)
            (send gEgo:posn((gPrevXY[0])(gPrevXY[1]))hide()) //wondering if this works without setting Up Ego in this script
            = gPrevXY[0] characterXYToggle[0]
            = gPrevXY[1] characterXYToggle[1]
           
            (send gRoom:newRoom(roomToggleNumber))
        )
    )
   
    (method (doit)
        (super:doit)
        (= myEvent Event:new(evNULL))
        (if ( checkEvent(myEvent (-(switcher:nsLeft)5) (switcher:nsRight) (+(switcher:nsTop)10) (+(switcher:nsBottom)10)) )
            (if(not(buttonOpen))
                (switcher:setCycle(End))
                = buttonOpen 1
            )
        )(else
            (if(buttonOpen)
                (switcher:setCycle(Beg))
                = buttonOpen 0
            )
        )
       
        (send myEvent:dispose())
    )
)
(procedure (checkEvent pEvent x1 x2 y1 y2)
    (if(    (> (send pEvent:x) x1)
        and (< (send pEvent:x) x2)
        and (> (send pEvent:y) y1)
        and (< (send pEvent:y) y2)
       )
       return(TRUE)
     )(else
       return(FALSE)
    )
)
/******************************************************************************/
(instance switcher of Prop
    (properties y 15 x 30 view 573 loop 2)
)
Global variables that I added include:
gAnotherEgo (used as a variable to determine which character is in use "0" for "main" ego, "1" for other ego)
gEgoStoppedView (This is used so a character when stopped doesn't feel like he or her is stopping mid-step)
gSwitchedRoomNumber (Used to hold the room Number of the Ego character not in current use)
gPrevXY[2] (Used to hold the X/Y positions of the Ego not in current use)

Attached is the View used in the script. The script is under 1 Kb, so it won't take up much heap. Enjoy


Artificial Intelligence Competition

Offline troflip

Re: Region allowing the switching of Ego characters
« Reply #1 on: May 20, 2017, 10:21:24 PM »
Seems useful, I sort of had to deal with something similar in Void Quest, but I didn't know the proper way to do it.

But I don't get why you're doing all that stuff with the inventory. Why are you transferring items between the room and the egos? Why do you need to transfer any items at all?

(also... Sierra script...)

Check out my website: http://icefallgames.com
Groundhog Day Competition

Offline Kawa

Re: Region allowing the switching of Ego characters
« Reply #2 on: May 21, 2017, 11:13:02 AM »
Regarding the inventory, it may be a good idea to check Larry 3 and 5.

Offline Doan Sephim

Re: Region allowing the switching of Ego characters
« Reply #3 on: May 21, 2017, 12:38:16 PM »
I don't get why you're doing all that stuff with the inventory. Why are you transferring items between the room and the egos? Why do you need to transfer any items at all?

(also... Sierra script...)
The inventory stuff is because it wouldn't make much sense to have a shared inventory. This allows each character his own items. The code stores each character's items in a different room allowing a switching of inv items depending on which ego is in current use.

I'm not sure what "Sierra script" means...It's been a few years since I was active here.

Offline troflip

Re: Region allowing the switching of Ego characters
« Reply #4 on: May 21, 2017, 01:28:34 PM »
Ah, yeah, I was thinking you could just switch the (User alterEgo?) property to one of two different ego instances. That would handle the inventory without any extra work I think, but then you'd need to be really careful everywhere in your code to use gEgo (when it's always specific to the first ego) vs gOtherEgo (when it's for the other ego) vs (User alterEgo?) (when the code applies to the one the player is currently controlling). Might be difficult/tedious to get right.


Sierra Script is the new version of the syntax supported by SCI Companion 3. It's what we should be posting here so as not to confuse new users. I converted it to Sierra Script for you:

Code: [Select]
;;; Sierra Script 1.0 - (do not remove this comment)

; Ego-Switching Region
; by Ryan Slattery
; Originally Designed For Betrayed Alliance Book 2

(script# 205)
(include sci.sh)
(include game.sh)
(use Controls)
(use Cycle)
(use Feature)
(use Game)
(use Main)
(use Obj)

(public
egoSwitchRegion 0
)

(local
myEvent ; Used in the Doit method to track the mouse over the switch button
buttonOpen =  0 ; Used so that the Doit method doesn't send constant signals cancelling the button animation
roomToggleNumber ; Intermediary variable allowing the change of gSwitchedRoomNumber before calling gRoom:newRoom command
[characterXYToggle 2] = [0 0] ; Intermediary variable allowing the change of posn before asigning new gPrevXY variables
itemIteration
; Used to switch all items from one character to a room or from a room to the other character
; Items stored for Male Ego in Rm 205 and for Female Ego in Rm 210
; IMPORTANT - remember to change the item Iteration # as you add items

)

(instance egoSwitchRegion of Rgn
(properties)

(method (init)
(super init:)
(switcher init: ignoreActors: setPri: 15)
)

(method (handleEvent pEvent)
(super handleEvent: pEvent)
(if
(or
(Said 'switch')
(if (== (pEvent type?) evMOUSEBUTTON)
(if
(and
(> (pEvent x?) (switcher nsLeft?))
(< (pEvent x?) (switcher nsRight?))
(> (pEvent y?) (switcher nsTop?))
(< (pEvent y?) (switcher nsBottom?))
)
)
)
)
; Remove and Give Items based on who is being used
(for ( (= itemIteration 0)) (< itemIteration 19)  ( (++ itemIteration)) (if gAnotherEgo
; Switching from Female Ego
(if (== (gEgo has: itemIteration) 1)
(gEgo put: itemIteration 210) ; Items stored in Room 210
)                                         
(if (== (IsOwnedBy itemIteration 205) 1)
(gEgo get: itemIteration) ; Items stored in Rm 205 given to Male Ego
)
else
; Switching from Male Ego
(if (== (gEgo has: itemIteration) 1)
(gEgo put: itemIteration 205) ; Items stored in Room 205
)                                         
(if (== (IsOwnedBy itemIteration 210) 1)
(gEgo get: itemIteration) ; Items stored in Rm 210 given to Female Ego
)
))
(if gAnotherEgo
(= gAnotherEgo 0) ; Male character
(= gEgoView 0)
(= gEgoStoppedView 903)
else
(= gAnotherEgo 1) ; Female character
(= gEgoView 342)
(= gEgoStoppedView 903) ; Haven't drawn it yet
)                       
; Get Room Number Variables saved and set up for room switch
(= roomToggleNumber gSwitchedRoomNumber) ; saves variable for newRoom call
(= gSwitchedRoomNumber gRoomNumber)    ; saves current room as the new switched room
; Get Ego's X/Y position saved and set up for room switch
(= [characterXYToggle 0] (gEgo x?))
(= [characterXYToggle 1] (gEgo y?))
(gEgo posn: [gPrevXY 0] [gPrevXY 1] hide:)       ; wondering if this works without setting Up Ego in this script
(= [gPrevXY 0] [characterXYToggle 0])
(= [gPrevXY 1] [characterXYToggle 1])
(gRoom newRoom: roomToggleNumber)
)
)

(method (doit)
(super doit:)
(= myEvent (Event new: evNULL))
(cond
(
(checkEvent
myEvent
(- (switcher nsLeft?) 5)
(switcher nsRight?)
(+ (switcher nsTop?) 10)
(+ (switcher nsBottom?) 10)
)
(if (not buttonOpen)
(switcher setCycle: End)
(= buttonOpen 1)
)
)
(buttonOpen (switcher setCycle: Beg) (= buttonOpen 0))
)
(myEvent dispose:)
)
)

(procedure (checkEvent pEvent x1 x2 y1 y2)
(if
(and
(> (pEvent x?) x1)
(< (pEvent x?) x2)
(> (pEvent y?) y1)
(< (pEvent y?) y2)
)
(return TRUE)
else
(return FALSE)
)
)


(instance switcher of Prop
(properties
y 15
x 30
view 573
loop 2
)
)

« Last Edit: May 21, 2017, 02:14:42 PM by troflip »
Check out my website: http://icefallgames.com
Groundhog Day Competition

Offline Collector

Re: Region allowing the switching of Ego characters
« Reply #5 on: May 21, 2017, 06:52:27 PM »
Doan, You can look through some of the threads here where the actual syntax Sierra used was determined and Phil incorporated it into Companion 3. While it will still support the syntax that Brian devised for Studio, Companion 3 can convert the Studio scripting to Sierra's and that is what is being encouraged for consistency.
KQII Remake Pic

Offline Kawa

Re: Region allowing the switching of Ego characters
« Reply #6 on: May 21, 2017, 07:11:32 PM »
Just for reference, here's my result of studying how Larry 5 did it:

Code: [Select]
;; MAIN.SC
;; =======

(procedure (SelectEgo who)
(switch who
(23
(= gEgo Larry)
(= gIsLarry 1)
(User alterEgo: gEgo)
(gEgo setUpInv:)
)
(24
(= gEgo Patti)
(= gIsLarry 0)
(User alterEgo: gEgo)
(gEgo setUpInv:)
)
)
)

;; (class LSL5 of Game
(method (startRoom param1)
((ScriptID DISPOSECODE_SCRIPT) doit: param1)
(cond
((== param1 200) ; Limousine
(Inv release:)
(gEgo setUpInv:)
)
((IsOneOf
param1
160 ; PornProdCorp Lobby
170 ; Larry's office
180 ; File room
190 ; Outside PPC
; Basically, any place that you control Larry in.
)
(if (not gIsLarry)
; We're not currently Larry, but we should be.
(DisposeScript 24)
(Inv release:)
(gIconBar curInvIcon: 0)
(gIconBar curIcon: (gIconBar at: 0))
(SelectEgo 23)
)
)
(gIsLarry
; We are now Larry, but should be Patti.
(DisposeScript 23)
(Inv release:)
(gIconBar curInvIcon: 0)
(gIconBar curIcon: (gIconBar at: 0))
(SelectEgo 24)
)
)
(gIconBar enable:)
(super startRoom: param1)
; Camcorder stuff left out.
)


;; LARRY.SC and PATTI.SC
;; =====================

;; (class Larry/Patti of Ego
(method (setUpInv)
((ScriptID 19 0) doit: 23) ; or 24 for Patti
)


;; LLINVITEM.SC
;; ============

(method (doit param1)
(switch param1
(23
(Inv
add:
Camcorder
Battery_Charger
; ...
invLook
invHand
invSelect
invHelp
ok
eachElementDo: #highlightColor global141
eachElementDo: #lowlightColor global139
eachElementDo: #init
state: 2048
)
)
(24
(Inv
add:
DataMan
Reverse_Biaz_DataPak
P__C__Hammer_DataPak
; ...
invLook
invHand
invSelect
invHelp
ok
eachElementDo: #highlightColor global141
eachElementDo: #lowlightColor global139
eachElementDo: #init
state: 2048
)
)
)
)

Offline Doan Sephim

Re: Region allowing the switching of Ego characters
« Reply #7 on: May 21, 2017, 08:50:03 PM »
Sierra Script is the new version of the syntax supported by SCI Companion 3. It's what we should be posting here so as not to confuse new users. I converted it to Sierra
Good to know. Being absent from the forums for 3 years or so, there is obviously a lot for me to get caught up on. I hadn't even downloaded the newest version of Companion yet. I'm excited to see the new features.

Of course, coming from a guy who still uses Internet Explorer on occasion, migrating to newer/better things is a struggle for me, especially since I've become so familiar with SCIStudio and Brian's syntax.

Just for reference, here's my result of studying how Larry 5 did it:
Very cool. I've have to reference that moving forward. Having never played any of the Larry games I was unaware of this. I thought I was creating something rather unique (at least I've never seen it before), but I guess not :)

Offline Kawa

Re: Region allowing the switching of Ego characters
« Reply #8 on: May 21, 2017, 09:12:59 PM »
Not very unique at all if you consider Maniac Mansion and Day of the Tentacle which, unlike Larry 3 and 5, let you switch at any point.

Offline Doan Sephim

Re: Region allowing the switching of Ego characters
« Reply #9 on: May 21, 2017, 09:39:33 PM »
Not very unique at all if you consider Maniac Mansion and Day of the Tentacle which, unlike Larry 3 and 5, let you switch at any point.
True enough. I haven't seen any fan-made games feature or even attempt a dual-ego game play mode, so I thought it might be interesting to open it up as an option. If there are better ways to do it than what I have developed here, that's good to hear. When it comes down to it, the success of such a feature is in the implementation of the puzzle/gameplay, not the background scaffolding (coding).

Also, and this will reveal my shame, I've also never played Maniac Mansion or Day of the Tentacle.

Offline Kawa

Re: Region allowing the switching of Ego characters
« Reply #10 on: May 21, 2017, 10:48:44 PM »
In MM, you have three kids, one forced and the others chosen from a larger set on startup. At any point you can switch to another kid, and give items to eachother. Who you pick changes certain puzzles.

In DOTT, you play three fixed kids (though the original idea was to let you choose), where one is in the past, one in the future, and one in the present. Initially, only one is available but you quickly unlock the past kid, and then the future. You can pass items to eachother freely, as long as the kids can reach their time machines -- the future kid initially cannot do so easily.

Offline lskovlun

Re: Region allowing the switching of Ego characters
« Reply #11 on: May 21, 2017, 11:08:47 PM »
Just for reference, here's my result of studying how Larry 5 did it:
We encountered a problem with this scheme in ScummVM: When one ego disappears, the pointer to it is left dangling, and it only happens to work because LARRY.SC and PATTI.SC are loaded at the exact same address and have similar enough layouts to make it work by chance. Using this method without fixing the bug could lead to some very surprising results. In the end, we used a hackworkaround for LSL5 that resets the ego value in the appropriate spot.

Offline Kawa

Re: Region allowing the switching of Ego characters
« Reply #12 on: May 22, 2017, 04:18:09 AM »
Looking at ScummVM, you must mean stopGroop's client property.

Offline lskovlun

Re: Region allowing the switching of Ego characters
« Reply #13 on: May 22, 2017, 02:13:02 PM »
Looking at ScummVM, you must mean stopGroop's client property.
That's the one, yes.


SMF 2.0.19 | SMF © 2021, Simple Machines
Simple Audio Video Embedder

Page created in 0.04 seconds with 23 queries.