Author Topic: The nature of calling one script with another  (Read 346 times)

Legacy_Sarcose

  • Newbie
  • *
  • Posts: 34
  • Karma: +0/-0
The nature of calling one script with another
« on: February 28, 2012, 02:55:33 am »


               [questions separated out because of my longwindedness]

Hi again, I hope my constant questions about my climbing script aren't bothering anyone. And if this should all be in one thread let me know. But each thread covers a different concept, so here goes:

Now let's say for my climbing script, which I know a lot of the excellent scripters on this forum know about because I have been pestering you a lot, which uses two placeables that can be clicked to go from one to another (using waypoints next to the placeables actually), and also has multiple checks and falling,

let's say I want to call a script in the middle of this climbing.

I handle the natural climbing with a while loop that checks a distance variable on the placeable. In the future I plan to implement a far more robust system to handle calling extra scripts, say I find a secret door or run into another ledge and get the option to land on it instead. Not wanting to rewrite it all right now, I'm just going to run an extra script at some point in the climbing action. I can do that with optional variables on the placeable - one for the "coordinate" along the checks and one for the name of the script, then put a small aside in the loop (if nCheck = nScriptcoord, run sScript). Easy.

--QUESTIONS ARE HERE--
What is difficult for me to grasp right now is how it would interact with the script. If it calls a conversation (say you run into a secret door and are immediately given the option to enter it without continuing) does it interrupt the script? CAN I interrupt the script - and further, can I "pause" the script, return to it later? If I'm in the middle of a loop will I risk breaking it when I come back to it? This script has some thirty declared variables so far, maybe more. Can I preserve them during this whole process if I need to?
--QUESTIONS ARE ^HERE--

Other possible outcomes of finding a secret door or extra ledge to land on: you reach the secret door (which I can just run a check within for instance the script climb_secretdoor1) and find it, but fall before you enter it. Player gets a message pertaining to finding the door, and then the door is flagged for the PC and his allies. I can probably figure that out if I figure out the above questions - I just wanted to describe my possible uses for this script to better help you envision what I want.
[2: you could theoretically, with a persistent enough system for checking these placeable variables, fudge up an interrupt system for each check of the climb to ask if you want to continue or go back. This would not be the most ideal way to do this, however, but the option exists - or maybe you can change directions and climb somewhere else. I might be wrong on that second one though, just because my system might not be flexible enough yet. But the option is, again, something I'll be considering]

[[for my first session I'm just going to run a script on one specific climb that automatically finds a secret door, a "cinematic event" sort of with no challenge, but in the future I plan on detecting the state of a player's search mode and implementing an actual check along with an additional delay, the purpose of which is discussed in my climbing combat thread, to account for searching.]]
               
               

               


                     Modifié par Sarcose, 28 février 2012 - 03:00 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
The nature of calling one script with another
« Reply #1 on: February 29, 2012, 05:38:50 am »


               

Sarcose wrote...

--QUESTIONS ARE HERE--
What is difficult for me to grasp right now is how it would interact with the script. If it calls a conversation (say you run into a secret door and are immediately given the option to enter it without continuing) does it interrupt the script? CAN I interrupt the script - and further, can I "pause" the script, return to it later? If I'm in the middle of a loop will I risk breaking it when I come back to it? This script has some thirty declared variables so far, maybe more. Can I preserve them during this whole process if I need to?
--QUESTIONS ARE ^HERE--


Calling a script from another script via ExecuteScript just executes the script called before the rest of the executing script is called. It will not 'pause' the script, or 'interrupt' it, but you can set a local that the executing script checks and acts on - by, for instance, returning out.

You basically treat any executed script as you would the main script that executed it when it comes to functions you can use. GetSpellID will still return the same id, for example, and you can use the same object-getting functions (GetLastUsedBy in an onused, for example). The one main potential difference is default variables like OBJECT_SELF, if you specify a different executor.

Funky
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
The nature of calling one script with another
« Reply #2 on: February 29, 2012, 07:21:20 pm »


               

FunkySwerve wrote...
 
You basically treat any executed script as you would the main script that executed it when it comes to functions you can use. GetSpellID will still return the same id, for example, and you can use the same object-getting functions (GetLastUsedBy in an onused, for example). The one main potential difference is default variables like OBJECT_SELF, if you specify a different executor.

Funky



Even GetSpellID will not work correctly, if you change the object the script is running on.   Many of the accessor functions use OBJECT_SELF to retrive the data.   So if your script is running in the Spell Event and you  Execute a script on another Object, even though you are still technically still in the Spell event,  You will not be able to get the correct data via GetSpellID untill you return exicution back to the Object that initiated the Event.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
The nature of calling one script with another
« Reply #3 on: March 01, 2012, 04:44:27 am »


               Doesn't suprise me, but I've never had cause to test that, so I learned something. '<img'> The important takeaway is that, so long as the executor is the same, you can use all the same functions. With another executor, all bets are off, and many of those functions would no longer make any sense - for instance, calling GetLastOpenedBy when you've made a pc the executor.
When you opt for a differentr executor like that, you'd just have to pass data between the two script via local variables.

Funky
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
The nature of calling one script with another
« Reply #4 on: March 01, 2012, 05:38:50 am »


               Well, There are times where the game switches the event on you, In cases where it does it helps to understand what is going on if you want to get some of the accesor functions back.

Example:  ip:Unique Power, Unique Power(SelfOnly)....   all cast the same impact script from a Cast Spell Event. The impact script changes the SpellEvent into a ModuleEvent running on the module, where you no longer have access to the SpellEvent accessor functions.  Now if you wanted access to the GetSpellId function, you could just add a SetLocalInt in the impact script. That would cause a little bit of extra overhead for every unique power used.     If you only need the access to the SpellEvent Functions in a few scripts you could just move there execution back to the SpellEvent  with something like:

if(OBJECT_SELF != GetItemActivator() )
{
  ExecuteScript("Name of this script",GetItemActivator());
  return;
}

and you would then once again have access to the SpellEvent accessor functions.  

of cource you may have to start using GetLastSpellCaster() in place of  GetItemActivator()  if the Module Accessor function are no longer good at that point.  Looks to be a major flaw in my if statment above, lol.  But you get the Idea.
               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
The nature of calling one script with another
« Reply #5 on: March 13, 2012, 01:35:05 pm »


               While ambiguously on the topic of ExecuteScript.

ExecuteScript is made even more useful if you use plugins such as ResMan.

I modified my default onCreature damage, death, and heartbeat scripts, to check for local strings on the creature in question, and use that string, as the name of a script.

Then, the script either exists as an internal resource, or as an externalsources resource for resman.
This allows me to have as many customized heartbeat/event scripts for creatures, without having to modify the creatures blueprint.

ExecuteScript also comes with the added bonus, that it doesnt validate that the script exists at build time. (at least in the cases where you provide a string variable).

It can also allow you to bypass IDENTIFIER_LIST_FULL Errors during build, by spanning large scripts across 2 or more scripts.
(Streamlining or Boot-strapping)

The one thing to be aware of

If you 'ExecuteScript'  from an onDamaged script - you can use GetLastDamagedBy(); inside the script being Executed, and be 100% assured that it will return the correct value. (because its all linear, and single threaded)

The only exception to this, is if you were to call
DelayCommand(3.00,ExecuteScript("myScript",OBJECT_SELF));

DelayCommand, in effect will make it possible for 'GetLastDamagedBy()' to return the incorrect value.
Because 3 seconds after the damage event is fired, it is entirely possible, that the 'Last Damager' has changed, since the event was fired.


Delayed Commands while having this unfortunate side-effect, can also help reduce script related computational lag. (caused by large loops) - Which can be useful.
Examine the Scripting Include files for Pentagrams and Drawing or whatever it is called.

These functions, draw pentagrams and other geometric shapes via loops and complex mathematical equations.
If they were done within the Loop, without the use of DelayCommand - then we would find that players could not even walk or interact with other objects - while the shape was being drawn.

Because they use DelayCommand, they do however appear to be 'non' blocking, which results in players being able to play happilly with minimum lag spikes.


(Sorry - kinda went off on a tangent about DelayCommand - but just wanted to point out some benefits and risks associated with its use)