Jump to content

Continue() is very dangerous


King Diamond

Recommended Posts

It's necessary to use Continue() very carefully....

 

So, here's a code:

IF
Global("wmSpawnJoluv","GLOBAL",0)
THEN
RESPONSE #100
	CreateCreature("wmart1",[1337.1751],4) // Joluv
	SetGlobal("wmSpawnJoluv","GLOBAL",1)
	Continue()
END

IF
Global("wmSpawnJoluv","GLOBAL",0)
THEN
RESPONSE #100
	CreateCreature("wmart1",[1337.1751],4) // Joluv
	SetGlobal("wmSpawnJoluv","GLOBAL",1)
	Continue()
END

IF
Global("wmSpawnJoluv","GLOBAL",0)
THEN
RESPONSE #100
	CreateCreature("wmart1",[1337.1751],4) // Joluv
	SetGlobal("wmSpawnJoluv","GLOBAL",1)
	Continue()
END

Do you know what results will it produce?

There will be all 3 Joluv's spawned :)

All those SetGlobal()'s just don't take effect if the code is in the same pass. But if we remove the very 1st Continue() (that will force to end the 1st code pass) all triggers below will work as it should be.

 

:)

Link to comment

Yeah, you can think of the script parser as a statemachine, and the state is not reset until the script is restarted (i.e. when the end of the script is hit, or a block evaluates as true).

 

It should probably be noted down explicitly though, I'll add it in the next update.

Link to comment

So if we add an action to an area script that uses OnCreation() then we should use EXTEND_BOTTOM, make sure we do not use OnCreation ourselves (easy enough to get around), and not add gratuitous Continue() to blocks for compatability...

 

back to switch files again!

 

EDIT: After reading your response below, Smoketest, I think I will hold off on changes until I have a chance to do some more code-reading. I think I understand you :). For Tutu, this is a non-issue; BG1 NPC adds two blocks to area scripts that have no OnCreation() calls, and no extant Tutu mods add this kind of behavior - the difficulty is making things more "BGT friendly", where I know that people have.

 

Plus, eventually I will need to understand this in order to assist BG2 projects.

Link to comment

Nah, just avoid using non-instant actions in your OnCreation() block and you'll be fine. Bioware does it all the time in their area scripts, and so do I. There is often a variable set to prevent the block from executing again, but this variable isn't typically used in the rest of the script so if a Continue() is used there's no problem. (The variable is usually named EnteredARxxxx or similar.)

 

OnCreation() is handy for doing things like Explore() and DisplayStringHead() and anything else you want done at the moment of area entry, and that might look odd if it took place several seconds later. If you use multiple OnCreation() blocks in an area script, it's good to chain them together with Continue() or they might not execute properly.

 

Edit: OnCreation() is an instance trigger, like Die(). If it doesn't get a chance to execute in a timely fashion, it won't execute at all. This is why Bioware universally places it at the top of their scripts. If you're going to EXTEND_BOTTOM, you probably shouldn't use OnCreation().

Link to comment

Talking about OnCreation()

 

local area variables also don't work correctly with triggers besides OnCreation()

Like this, if you use it as area script:

 

IF
 OnCreation()
 Global("Spawn","LOCALS",0)
THEN
 RESPONSE #100
Setglobal("Spawn","LOCALS",1)
Createcreature("ERGGNM01",[303.348],3)
END

Link to comment
IF
 OnCreation()
 Global("Spawn","LOCALS",0)
THEN
 RESPONSE #100
Setglobal("Spawn","LOCALS",1)
Createcreature("ERGGNM01",[303.348],3)
END

The quick fix for this is to use either

IF
 OnCreation()
 Global("Spawn","FW2700",0)
THEN
 RESPONSE #100
Setglobal("Spawn","FW2700",1)
Createcreature("ERGGNM01",[303.348],3)
END

or

IF
 OnCreation()
 Global("Spawn","MYAREA",0)
THEN
 RESPONSE #100
Setglobal("Spawn","MYAREA",1)
Createcreature("ERGGNM01",[303.348],3)
END

 

Right? (or am I taking this off-topic)

Link to comment
Well, LOCALS are reserved for CREs, from what I see in all Bioware scripts, so I never use them in area scripts.
Yeah, if anything other than an actor tries to set or get a LOCALS variable, nothing at all will happen (in the case of the trigger, it should always be false).
Link to comment

I know. That's because setting a LOCALS creates an EFF attached to the creature running the script, and such a mechanism doesn't work on areas.

 

 

cmorgan,

 

The area referenced in a variable must match an actual area resource name, though MYAREA will work in any given area since it's a context mask. That is, if MYAREA is set/modified in AR0300 the game will attach the variable to AR0300.ARE; if set/modified in AR0400 it will be attached to AR0400.ARE, and so on. Thus you could use MYAREA in all your area scripts if you wanted, but only in scripts working on variables in the area they are attached to. If you need to reference another area's variable you need to use that area's resource name.

Link to comment
The area referenced in a variable must match an actual area resource name, though MYAREA will work in any given area since it's a context mask. That is, if MYAREA is set/modified in AR0300 the game will attach the variable to AR0300.ARE; if set/modified in AR0400 it will be attached to AR0400.ARE, and so on. Thus you could use MYAREA in all your area scripts if you wanted, but only in scripts working on variables in the area they are attached to. If you need to reference another area's variable you need to use that area's resource name.
Do you know the exact limitations of referencing external (currently unloaded resource) variables? E.g., I don't think the game successfully checks if Global("MyVar","AR0204",1) when you're in AR1000?
Link to comment

@Smoketest - thank you! That makes sense to me.

 

@DevSin - I really hope that there is a trick to doing that referencing; currently I have not been successful (just as you say) but if it is possible to reference another area's set area variable it would mean I can remove the only block I add to baldur.bcs. I would prefer a "non-nuclear" option.

Link to comment
The area referenced in a variable must match an actual area resource name, though MYAREA will work in any given area since it's a context mask. That is, if MYAREA is set/modified in AR0300 the game will attach the variable to AR0300.ARE; if set/modified in AR0400 it will be attached to AR0400.ARE, and so on. Thus you could use MYAREA in all your area scripts if you wanted, but only in scripts working on variables in the area they are attached to. If you need to reference another area's variable you need to use that area's resource name.
Do you know the exact limitations of referencing external (currently unloaded resource) variables? E.g., I don't think the game successfully checks if Global("MyVar","AR0204",1) when you're in AR1000?

I can't vouch for area scripts because I haven't tested them, but I know the global script, BALDUR.BCS, can do it. It sets variables in at least one area. Sub-areas might be able to read/modify variables in their master area, but again, I haven't tested it yet. Or if I did, it was months/years ago and I've forgotten.

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...