Jump to content

Final Bit


wizardmirth

Recommended Posts

The final part of my quest requires a bit of script I could not seem to figure out. I want to be able to do one of the folowing:

  1. determine if an ayleid gate is in up or down state (i.e. in open or closed state as having been activated via push block by player) -OR-
  2. determine if an activator (MyUniqueARSwitch01) has been activated (I can create a unique ARSwitch so that it can have a unique script if needed) -OR-
  3. how to set and determine a ref var inside one script to be used in another (e.g. set in push button script when door is open or closed to be referenced in another object script within OnActivate or OnTrigger block)

Basically I want to be able to determine and execute inside an independant object script: If ayleid gate is open then close gate (via MyUniqueARSwitchRef.activate). I think ref variables may be the key but I don't know how to set them in one script and use them inside an if statement in another. I think I need a working example to see how its done.

Link to comment
Share on other sites

The final part of my quest requires a bit of script I could not seem to figure out. I want to be able to do one of the folowing:
  1. determine if an ayleid gate is in up or down state (i.e. in open or closed state as having been activated via push block by player) -OR-
  2. determine if an activator (MyUniqueARSwitch01) has been activated (I can create a unique ARSwitch so that it can have a unique script if needed) -OR-
  3. how to set and determine a ref var inside one script to be used in another (e.g. set in push button script when door is open or closed to be referenced in another object script within OnActivate or OnTrigger block)

Basically I want to be able to determine and execute inside an independant object script: If ayleid gate is open then close gate (via MyUniqueARSwitchRef.activate). I think ref variables may be the key but I don't know how to set them in one script and use them inside an if statement in another. I think I need a working example to see how its done.

Ref variables migth be one option, but if I'm reading this right, and you want one door to detect if another door is open, and then to change the open state of the other door based on the state of the first, it might not be needed. If these doors are defined as doors in the CS (not activators) then you could simply use getopenstate and setopenstate with the defined references. If you're using activators for the gates, you may be able to just have a single script in the switch to operate both of them. Depending on how you're wanting this to go, you might even be able to get away with using a default switch, and using parenting to do the work. You should probably explain in more detail what exactly you want to happen when the player pushes the block. IE "When the player uses the switch door 1 opens, and door 2 closes. When the player presses the switch again door 1 closes and door 2 opens".

Link to comment
Share on other sites

What I Think I Need:

When the player pushes the block a variable is set that needs to be referenced in another script. 0 would probably be the default for closed and 1 for open. So if the player stood there and kept hitting the switch (opening and closing the door) the appropriate variable would be set each time and remembered by the game.

 

What Would Be Most Ideal but Probably Impossible:

Unless there's a way for a script to detect whether or not the gate object itself is in open or closed state, but since said gate does not function like a normal door and uses an activator I dont think that's possible.

 

Second Script to Reference Variable Set in First Script:

So when player activates next stage through a separate container object/script with OnActivate block (not in the switch itself or gate but different object/script in same cell) it will check to see if this gate is open and if it is it will activate the switch to close it.

 

Alternative Method:

I'm even thinking of using blank quest stages to do this. Any time the gate's playgroup forward or back (open or close animation) is activated, the script would be adapted to set one of two blank quest stages (would require new and unique object id so that shared scripts are not changed on the base objects). Since the door is closed by default and player cannot get past it short of using the console to cheat then the door/stage must be at least set to open before the player can even get to the container script which will need to know if the door is open or closed.

 

When the player opens and passes through the gate (who knows, maybe they will activate the switch again and close it behind them?) and then when the boss stage of the quest is activated via separate container script OnActivate, I want the gate to close if it isn't already closed. Either way it will not open again no matter what the player does (short of console cheat) until the boss is killed and OnDeath script runs. I know how to do all that except how to determine if this gate is closed or not, because if it's not then no closing is necessary. There won't be a switch on the ther side of the door so the player will have to fight to the death before he or she can escape.

 

I'd probably even settle for deactivating (breaking) the switch the first time its activated so that the door cannot be closed behind the player, but I need to know how to work around that so that the switch can be remotely closed again via the separate script.

Link to comment
Share on other sites

Stop complicating things, it's nice that you're thinking of alternative methods, but when asking for help, it's best to explain what you want to accomplish clearly before trying to explain how. What exactly do you want to happen. Give me a run through, step by step. And is the door you're using (not the switch) listed under doors or activators in the CS?
Link to comment
Share on other sites

Sorry. These are the standard activators/gates found in most alyeid ruins and are standard in the CS. One is set to parent of the other and both have their own scripts attached to their base objects.

 

Player activates gate, it opens. Slim chance player also might close the gate behind them for unknown reasons (point is, it's possible). They walk over to a special container with script attached that triggers boss fight scene when they activate it. Part of this script asks if gate is open. If the gate is open then the switch is activated to close it. Either way the player will be trapped in the room until boss is defeated as there is no activator on that side of the gate

 

Why ask if gate is closed? Because if it's not then activating switch via script will open it.

Link to comment
Share on other sites

Sorry. These are the standard activators/gates found in most alyeid ruins and are standard in the CS. One is set to parent of the other and both have their own scripts attached to their base objects.

 

Player activates gate, it opens. Slim chance player also might close the gate behind them for unknown reasons (point is, it's possible). They walk over to a special container with script attached that triggers boss fight scene when they activate it. Part of this script asks if gate is open. If the gate is open then the switch is activated to close it. Either way the player will be trapped in the room until boss is defeated as there is no activator on that side of the gate

 

Why ask if gate is closed? Because if it's not then activating switch via script will open it.

Alright, since we dont want to play around with any of the scripts on the doors or triggers, we'll need to use logic to determine if the door is open. For this we use a marker. The point of this is so that when the player crosses through the doorway it tells a quest script that the door is open. You'll need to use a light with a radius of 512 to place the marker so that only the edge of the ligh radius touches the inside face of the door. You'll then need to place a marker at that exact spot. You can then use a distance check in the quest script to detect if the player is within 512 of the marker. Then you just need to tell the script on the chest to close the door. Make sure the distance check is run only durring the quest stage, you will need a blank stage for this. Make it so that the chest won't activate until that stage has been cleared.

 

*edit*

Meaning that the part of the script which checks distance to the marker is only running durring a quest stage where they are supposed to enter the area. When they come close to the marker when it is that stage, make the script advance the quest to a blank stage. Then make the chest only work if that stage has been cleared. You can even use "switchref.setdestroyed to 1" once the player has crossed through the door once to prevent the player from using the switch multiple times.

Link to comment
Share on other sites

The only problem is that the player can still activate the switch from inside the gate and close it behind them. After some thought I've decided to move the activator further away so that it's not possible to close it again and have enough time to enter the room before it closes. Now there's no need to know what state the gate is in when activating the scripted container as the gate has to be open. I only have to flag the activator as persistent and give it a reference ID for the container script to close it again. That and use a GetSelf reference in the container script since the gate's default script checks to see if player is activating.

 

The other option would have been to, as you mentioned, to setdestroyed on the activator after first use, but that didn't fit in with my vision for the quest. Initially, I think I wanted to know how to use variables set in one script and referenced in another and this was what I thought would be my reason for learning it. Apparently that's a whole other post, when and if I get there. For now I have everything I need to finish this quest and just need to apply finishing touches. You'll have to let me know what you think once it's up.

Setting and using variables stored in other scripts can be a tricky matter, not complicated, but doesn't always work, especially when it involves something which is already scripted (like switches). Basically what you would do is define a short in the quest script. Then you would use GetQuestVariable (IE. "if <questname>.<Variable name> == 1" ) and then set it in a similar way "set <questname>.<variable> to 1" (I think). You might want to take a look at some of the game's arena scripts since they use quite a bit of this.

 

Alternatively you can use things like faction ranks, and dispositions between a null NPC (An NPC placed in an empty, unreachable cell) and another NPC. Using an alternate method complicates things a little, but can be a bit more effective if you need to have several NPCs with same scripting behaving differently, or in the case of dispositions, multiple copies of the same NPC behaving differently.

Link to comment
Share on other sites

Setting and using variables stored in other scripts can be a tricky matter, not complicated, but doesn't always work, especially when it involves something which is already scripted (like switches). Basically what you would do is define a short in the quest script. Then you would use GetQuestVariable (IE. "if <questname>.<Variable name> == 1" ) and then set it in a similar way "set <questname>.<variable> to 1" (I think). You might want to take a look at some of the game's arena scripts since they use quite a bit of this.

 

Alternatively you can use things like faction ranks, and dispositions between a null NPC (An NPC placed in an empty, unreachable cell) and another NPC. Using an alternate method complicates things a little, but can be a bit more effective if you need to have several NPCs with same scripting behaving differently, or in the case of dispositions, multiple copies of the same NPC behaving differently.

 

This is definfitely going into my notes as this will no doubt be useful. Thanks.

Link to comment
Share on other sites

This is definfitely going into my notes as this will no doubt be useful. Thanks.

Yeah, it can be used for alot of the logic functions within a mod. Just keep in mind as to how well changes to these variables work between different cases. If you have a unique script which needs to talk to another unique script, the quest variable method works well. If you have multiple scripts determining actions on one NPC, or one NPC determining how multiple scripts function faction ranks can prove more useful in that they can also cause package changes based on those factions. However if you have multiple copies of the same NPC using factions will make them all behave the same since ranks are determined at the base NPC. For this, using dispositions does the trick since one NPC will always have the same disposition toward another NPC unless that disposition has been changed. Dispositions can also store numbers up to 100 instead of just using ranks (you just need to make sure that you zero out the disposition (moddisposition -100) before using it in such a way). Dispositions are stored on individual instances of NPCs, and may allow more variation than what is normally possible with outside referencing.

 

While most of this is largly for use in controlling NPCs, it can be used in other scripts to act as some of the logic checks. You can place hidden factions on the player to store numbers or as flags to initiate parts of a quest that might need to be repeated (as repeatable stages doesn't work). For instance, if you wanted to make a reeatable delivery quest, you could use faction ranks on the player to determine if the player has what they're supposed to deliver, and if you wanted, you could even adjust what is being delivered and who to, without using quest stages or journal entries. Quest targets and conversations can also work off of factions, which makes this sort of thing possible without a vast amount of scripting needed to detect and control the various states. And interestingly enough, the same system could be adapted to make NPCs work as delivery boys without interfering with the player state. There's a reason why I like using faction ranks, a single faction with a few ranks can control alot of things in a reliable manner. You could still script it all with quest variables, but it may require setting up multiple variables along multiple scripts, and being able to read those variables at a source (like with converstaions).

Link to comment
Share on other sites

I've already managed a bit of basic faction exploitation to control how enemies/npcs act around each other and the player. I've also already thought of using quest stages to set certain variables, although for my purposes I found it unreliable since discovering that quest stages can't be back-indexed. Their results, for example journal updates, will appear, but the stage number itself can't be reversed. Maybe using factions instead would work for that such purpose. Basically it would seem that anything that can be referenced without having to be declared in a script can be used in some way as a check for scripts. Since I like having options, I'm glad that the system is as flexible as it is.

 

Since you're feeling so helpful, there were a couple of minor things I still have not been able to figure out regarding my quest mod. I tried using mysecondarymonsterref.moddisposition player 100 to try and get the one-time enemy friendly to pc again inside OnDeath script for the big baddie. Is this possible or not because its typically a non-yeildable creature? I notice you mentioned that you need to

make sure that you zero out the disposition (moddisposition -100)
first, or is that only regarding using it as a reference? I'd imagine in any case.

 

The other minor thing was trying to get a playmagiceffect or playmagicshadervisuals (pms or pme) to play on an object inside the same script, that was just enabled by the same script. It doesn't work unless the script is somehow reactived again and the object is already enabled. Actually I've only proved this with npcs so far but actually want to do it for a set duration with the suddenly enabled object. Will a getsecondspassed set up (with doonce catch) work so that both commands (enable and then pme or pms) are not executed immediately one right after the other? That's my impression although I've not had time to test this for myself yet.

Link to comment
Share on other sites

Archived

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...