devSin Posted October 19, 2006 Share Posted October 19, 2006 I think Baldur.bcs gets away with it because the default behavior is to just do nothing (so for the majority of the game, it's really just returning false or silently failing). (At least, this was my assumption; it's one of the things I never really desired to investigate.) It's necessary to use Continue() very carefullyI wonder if the engine would treat the script differently if the Continue() blocks weren't identical. It knows enough to not flush the queue if it hits the same block on the next run, but I don't know how it tracks this. I have seen Continue() work reasonably when the same variable was used between multiple different blocks, but I can't remember exactly what my tests were (and they would have been very brief). Link to comment
Kulyok Posted October 19, 2006 Share Posted October 19, 2006 I know Continue() works fine for all five blocks of AR1000.baf in Xan mod: IF !G("O#XanSpawn",1) !Dead("O#Xan") G("O#XanJoined",0) XPLT(Player1,280001) THEN RESPONSE #100 ActionOverride("O#Xan",DestroySelf()) CreateCreature("O#Xan09",[2745.321],4) SG("O#XanSpawn",1) Continue() END etc. I suppose the reason is that each block has different experience requirements, i.e. no two blocks cannot be True at the same time. Link to comment
Avenger Posted October 19, 2006 Share Posted October 19, 2006 Wha? LOCALS wouldn't work in ANY area script? Link to comment
jastey Posted October 19, 2006 Share Posted October 19, 2006 i.e. no two blocks cannot be True at the same time.Assuming you mean "no two blocks can be True at the same time", this not leading to multiple spawnings seems somehow... logical? Link to comment
devSin Posted October 19, 2006 Share Posted October 19, 2006 Wha?LOCALS wouldn't work in ANY area script? Area and info point objects cannot set or get LOCALS variables. Using LOCALS outside an actor script (or SetGlobal() outside ActionOverride() on a valid actor) does nothing (this should be true for any other AI object I forgot). Link to comment
cmorgan Posted October 19, 2006 Share Posted October 19, 2006 (or SetGlobal() outside ActionOverride() on a valid actor) does nothing I am not sure I understand: In a mythical AR0100.BAF, set up to EXTEND_BOTTOM ~AR0100.are~ IF InParty("imoen") // should work Global("Garbage1","AR0100",1) // should work Global("Garbage2","MYAREA",1) // should work Global("Garbage3","LOCALS",1) // can't work as it is not being run on a specific object Global("Garbage4","GLOBAL",1) // works everywhere THEN RESPONSE #100 SetGlobal("Garbage1","AR0100",2)//works SetGlobal("Garbage1","AR0200",1)// we don't think works SetGlobal("Garbage2","MYAREA",2) // should work SetGlobal("Garbage3","LOCALS",1) // can't work as it is not run on specific object ActionOverride("imoen",SetGlobal("Garbage3","LOCALS",1)) // should work fine to set a LOCALS value on imoen SetGlobal("Garbage4","GLOBAL",1) // works everywhere Continue() //keep on going END IF OnCreation()//any actions here would be interfered with if the block above is true the first time the script is run, unless the block contains a Continue(). If more than one block can be true after a Continue(), they are each evaluated true and the cumulative actions taken, until either the end of the script is reached, or a block which reads true but does not have a Continue() loops the script back to the beginning. Is this a correct summary of the conversation so far? Link to comment
devSin Posted October 19, 2006 Share Posted October 19, 2006 For the first statement, yes, except "MYAREA" will definitely work. The second is the question. I do not believe that is the behavior, but it's not something I ever looked into. Continue() most certainly should NOT be causing triggers to spontaneously return true (IIRC, most BG and ID scripts make heavy use of Continue() with no issues at all). The mystery is exactly when and how the engine executes actions, how long it takes, and how hard it tries to avoid doing something stupid like evaluating Global() in subsequent blocks when already running a SetGlobal() action from previous blocks. Since SetGlobal() should be executed instantly, this shouldn't ever be a problem, but apparently it is. Link to comment
Kulyok Posted October 20, 2006 Share Posted October 20, 2006 Assuming you mean "no two blocks can be True at the same time", this not leading to multiple spawnings seems somehow... logical? Right. Link to comment
King Diamond Posted October 20, 2006 Author Share Posted October 20, 2006 The mystery is exactly when and how the engine executes actions, how long it takes, and how hard it tries to avoid doing something stupid like evaluating Global() in subsequent blocks when already running a SetGlobal() action from previous blocks. Since SetGlobal() should be executed instantly, this shouldn't ever be a problem, but apparently it is. Then we should ask Avenger about the exact mechanism of how engine handles and executes various actions 'coz I think he's the only person (really?) who studies disassembled code... 2Avenger Have you taken a look into that matter already? Does engine execute all actions instantly, in a single thread, or start separate threads for some actions without waiting for them in a main script running thread(that definitely would take some extra time to complete)? Link to comment
Avenger Posted October 20, 2006 Share Posted October 20, 2006 Nah, i looked only into effect opcodes. And i have only theoretical assumptions about variable handling. Theoretically, 'LOCALS' could work exactly like 'MYAREA' in area scripts. Actually, GemRB works like that. I'll test if LOCALS truly a dummy scope for area scripts, this would fix an incompatibility with IE (the snippet i supplied was from DLTC and it worked differently under GemRB, because GemRB executed the action block, while IE didn't). Link to comment
devSin Posted October 20, 2006 Share Posted October 20, 2006 It would be better if "LOCALS" were contextual, but it isn't in IE. As Smoketest pointed out, it will only get and set from an actor's EFF structs and should fail everywhere else. Link to comment
WizWom Posted October 20, 2006 Share Posted October 20, 2006 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. Well, yes, Baldur.BCS contains 2 blocks to keep Nalia from giving her spiel about being orphaned and forced to marry a cretin. But if you notice, they contain checks to make sure the area they set a variable for is the current area. They could have made it a bit simpler, by using an "OR" for the area, and a "MYAREA" style global check/set. Link to comment
Smoketest Posted October 20, 2006 Share Posted October 20, 2006 I did one better by moving all area-checking blocks from BALDUR.BCS to the the target area script and removing the now unnecessary area check. This can be done with a few Nalia blocks, the block that gives XP for finding Montaron's body, the block the sets a variable if the Trademeet Genies are dead or have left the area, and so on. I also moved romance compatibility checks to the pertinant CRE scripts. You can also remove the romance-killing blocks that execute if, for example, an NPC is imprisoned or has been out of the party for more than three game days. Link to comment
WizWom Posted October 20, 2006 Share Posted October 20, 2006 Which leaves multi-area spawns, and talking items. I'd say the talking items could be put in the dplayer scripts, since I don't think they are supposed to talk in cases of NPCs weilding them when not in the party. And then they don't have to check anything but whether the item is equipped and the timer has expired. Link to comment
SimDing0 Posted October 21, 2006 Share Posted October 21, 2006 dplayer scripts are useless since they get turned off with the party AI. Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.