Author Topic: SCI0: testFlag woes  (Read 529 times)

0 Members and 1 Guest are viewing this topic.

Offline robbo007

SCI0: testFlag woes
« on: November 19, 2025, 12:13:33 PM »
Hi guys,
I'm using the testFlag and setFlag procedures from LSL3. When combining with them with Blk's it seems to to generate a crash when returning to the room. Not an Object error.

This checks to see if ego has got the Homebrew Klub membership. If he does, ignore the block at the bathroom door. At the end of my changeState I'm setting the flag and ignoring the block. This works fine but when ego comes back into the room I get the crash. It does look like its something to do with the testing of the flag and ignoring the block in the init part.

End of ChangeState:
Code: [Select]
        (SetFlag gotMembership) ;got membership flag set
(gEgo ignoreBlocks: blockToilet)
                        (= seconds 2)

This is in my Init:
Code: [Select]
(if (TestFlag gotMembership)
            (gEgo ignoreBlocks: blockToilet)
        else
            (gEgo observeBlocks: blockToilet)
        )

This is in my Roomscript:
Code: [Select]
(instance blockToilet of Blk
(properties
top 153
left 9
bottom 160
right 3
)
)

These are in my main.sc

Code: [Select]
(procedure (SetFlag flag)
(= [gFlagArray (/ flag 16)]
(| [gFlagArray (/ flag 16)] (>> $8000 (mod flag 16)))
)
)

Code: [Select]
(procedure (TestFlag flag)
(return
(if (& [gFlagArray (/ flag 16)] (>> $8000 (mod flag 16))) 1 else 0)
)
)



Offline Kawa

Re: SCI0: testFlag woes
« Reply #1 on: November 19, 2025, 12:34:12 PM »
Looking at Actor.sc, I can see a potential issue that matches your error.

Code: [Select]
(method (observeBlocks)
;; Set the blocks (class Block) which an actor cannot be inside of.
;Make sure there is a set for the blocks.
(if (not blocks)
(= blocks (Set new:))
)
(blocks add: &rest)
)

(method (ignoreBlocks)
;; Delete specified blocks from those which an actor must stay out of.
(blocks delete:&rest)
(if (blocks isEmpty:)
(blocks dispose:)
(= blocks 0)
)
)

Notice this: observeBlocks makes sure there is a blocks, but ignoreBlocks does not. If no other blocks are observed before the toilet block is ignored, (blocks delete:&rest) will fail with a null-pointer exception not-an-object error.

An easy fix would be to always observe the toilet block, and then immediately remove it if the flag tests true:
Code: [Select]
(gEgo observeBlocks: blockToilet)         ;ensures gEgo::blocks is a valid Set
(if (TestFlag gotMembership)
(gEgo ignoreBlocks: blockToilet)  ;this should not be able to fail now
)

Offline robbo007

Re: SCI0: testFlag woes
« Reply #2 on: November 19, 2025, 12:38:19 PM »
Thanks Kawa. I will try that but I also managed to use ignoreControl like this. They sorta both work in the same way right?

Code: [Select]
(if (& (gEgo onControl:) ctlRED)
    (if (TestFlag gotMembership) ; Allow access to room 40 - do nothing, let Larry pass through
    (gEgo ignoreControl: ctlRED)
    else
        (if (not seenMsgRed)
            (= seenMsgRed 1)
            (gEgo
                posn: (gEgo xLast:) (gEgo yLast:) ; Move ego to its previous position
                setMotion: 0 ; Stop any current movement
                observeControl: ctlRED ; Make ego observe control flag ctlRED
                forceUpd: ; Force immediate screen update
            )
            (aNerdScript changeState: 3 register: 101)
        )
    )
)

Offline Kawa

Re: SCI0: testFlag woes
« Reply #3 on: November 19, 2025, 12:47:19 PM »
They sorta both work in the same way right?
ignoreControls is nothing like ignoreBlocks. For starters it uses a straight number, not a pointer.


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

Page created in 0.036 seconds with 18 queries.