I am not really sure what it is that you are trying to do exactly, but here goes...
To stop the ego from moving. In the ProgramControl() procedure or function as it would be known in any other language, there is this:
(send gEgo:setMotion(NULL))
This will stop the ego from moving. You don't really need it though if you call ProgramControl() because it will stop the ego for you. But if you do want to stop the ego anytime, that is how it is done. Likewise, just for info, if you ever want to stop a views animation you could send a call of setCycle(NULL).
There are some issues with your boomScript that you have posted here. I see that you have some stuff going on listed under a Handle Event method. The handle event method is primarily used to handle the user events, or more specifically the user's input events such as mouse clicks or typed commands like look room. Judging from what you have there. It almost looks like you would be better off with a doit method. That's the assumption that I am going to work under anyway.
So here goes with what it is I think you are trying to accomplish... Let me know if I have it wrong at all and I will adjust my example accordingly. So you have a bomb, item 18, and you can drop the bomb anywhere a la the code we worked out a few days ago. Now you want to be able to set off this bomb using a cigarette. After a few seconds or cycles the bomb goes off and depending on how close ego is as to whether or not he is affected.... I am assuming that the bombs placement is still up and working fine.
Now assuming that I have the scenario right, it sounds like we are going to need a couple of local variables assuming of course that the ego is not going to be able to leave the room until after this bomb goes off. Leaving the room and coming back would be a slightly different approach using globals and a timer etc. So for this, I am assuming local variables... Right after the uses("") at the top of the script and before the first instance:
(local
bombArmed = FALSE // has the bomb been armed
bombAble = FALSE // bomb has been armed and is ready to blow
)
Looking at your said statements, they seem to be in relative good order. I am going to rewrite the said arm bomb a bit, to include this new local variable.
(if(Said('arm/timebomb'))
(if(bombArmed)Print("The bomb is already lit, you should probably stay clear of it."))
(else // bomb not armed yet
(if(> (send gEgo:distanceTo(inventory2View)) 15)
(if(< (send gEgo:distanceTo(inventory2View)) 30)
Print("You light the cigarette on the time bomb.")
= bombArmed TRUE
(send gEgo:setScript(boom2Script))
)
(else Print("You're too far away. Get closer."))// more than 30 away
)
(else Print("You are too close. Back up a little."))// closer than 15
)
) // ends said arm timebomb
If you notice, I went ahead and bypassed the armScript, because just like you said, you don't need them both. Now here goes my attempt at your boomScript.
(instance boom2Script of Script
(properties)
(method (changeState newState)
= state newState
(switch (newState)
(case 0 = cycles 1)
(case 1 (inventory2View:view(34)setCycle(Fwd) loop(0)) // I am assuming that this is fuse burning view
= seconds 5)// how long before bomb is ready to explode
(case 2 = bombAble TRUE)// Tells our doit method to trigger...
) // end switch
)// end method
//**************************************
(method (doit) // using a doit method to explode the bomb...
(var dyingScript)
(super:doit())
(if(bombAble) // the timer on bomb has been reached ... it will do what follows
= bombAble FALSE // we only want to do it once, so turn this trigger variable back off
(if(< (send gEgo:distanceTo(inventory2View)) 50)
ProgramControl() // This should stop the ego if they are walking... if not you know what to do
// (send gEgo:setMotion(MoveTo inventory2View)) // not sure what this is doing here... going towards bomb?
(send gEgo:view(37)setCycle(End)cel(0)loop(0)) // again not sure what this view is doing, guessing bomb blowing up!!
= dyingScript ScriptID(DYING_SCRIPT)
(send dyingScript:
caller(36)
register("You blew yourself up. Good job. Way to die!")
)
(send gGame:setScript(dyingScript))
)// ends ego exploded....
(else
// ego more than 50 away... do nothing
)
= inventory2Room 0// reset the global variable
= inventory2Y 0 // reset the global variable
= inventory2Y 0 // reset the global variable
(inventory2View:posn(400 400)hide()) // get the item view off screen
)
)// end method
Ok, so assuming I have the scenario even halfway right, that should get you an exploding bomb that only effects ego if they are less than 50 away and occurs 5 seconds after the fuse has been lit.
But you mentioned using a rectangle to test for distance, not distance to. There are a few ways to do that, the simplest would be to just use your current global variables and do some math on them at runtime rather that set up new globals...
So here is the syntax for the in rectangle. Looking at the code you have posted, I am not really sure why yours isn't working. It seems sound. My only guess might be the 30 you are adding, that is actually pretty small rectangle all things considered. The ego is 20 wide itself. Oh also, as you have it, one corner of your rectangle is the corner of the bomb, so it is only looking at a rectangle to the below and to the right of the inventory2 view, not a rectangle around the bomb.
Anyway, without adding any new variables that we really don't need,
(if(send gEgo:inRect((- inventory2X 50) (- inventory2Y 25) (+ inventory2X 50) (+ inventory2Y 50)))
)// end ego in rectangle