Author Topic: Potentially Complicated Script  (Read 399 times)

Legacy_Junnest

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Potentially Complicated Script
« on: February 10, 2012, 10:08:03 pm »


               So I've been working on several modules and have worked on many in my NWN career, so I'm not horrible at scripting although I've not necessarily mastered it. But on this particular single-3 player module I have every script I need already written in except for one. First I'll state that this isn't an original concept, as it is heavily influenced by the X-Box 360/PS3 game Dark Souls. But what is needed of the script is this:

Upon using a placeable, the PC sits down to rest and all enemies (either on the module or in the area, whatever is easier) are respawned exactly where they were when they initially spawned (on module load). On use this also starts a conversation, but I can do that bit of scripting myself. I've spent two days trying to script this to no avail, and I would immensely appreciate any help that could be given. The only tag I can provide is that of the placeable: bonfire. I don't even have all the enemies made yet, but if a tag would make this scripting easier I have one enemy with the tag: SnowedGhoul.

If possible and if it doesn't cause any crashes I would appreciate it if the script was done to respawn all creatures on the module. But like I said, if it's too troublesome it can be done by area.

Again, it would be a HUGE help as I can't really move forward in creating this module unless I have this script working. But to any who may attempt it, take your time and my appreciation will be no less.
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Potentially Complicated Script
« Reply #1 on: February 10, 2012, 10:23:12 pm »


               I remember having posted an answer to this on the old forums.  What you would do is have each area's on-enter script capture the first couple seconds of entering enemies and storing their resref and location.  When the respawn is called only those creatures will respawn.
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Potentially Complicated Script
« Reply #2 on: February 10, 2012, 10:26:39 pm »


               Set up waypoints at each spawn location, all with the same tag, that have the creature ResRef on them that you want to spawn at that point.
On spawn you'll want to store the creature object on it that you last spawned there, so it can be ported back into place if still present, or remade if not.  The new creature object would then be stored.  It'd only take about 10 lines of script to do the whole module under that system.

I'm heading out for a bit now, but I'll write something up in a couple hours when I get back if you're curious how that would be scripted.
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Potentially Complicated Script
« Reply #3 on: February 10, 2012, 11:05:06 pm »


               

Failed.Bard wrote...

Set up waypoints at each spawn location, all with the same tag, that have the creature ResRef on them that you want to spawn at that point.
On spawn you'll want to store the creature object on it that you last spawned there, so it can be ported back into place if still present, or remade if not.  The new creature object would then be stored.  It'd only take about 10 lines of script to do the whole module under that system.

I'm heading out for a bit now, but I'll write something up in a couple hours when I get back if you're curious how that would be scripted.


Whether you manually put the creatures into the toolset and create waypoints at their start location or you put  waypoints into the toolset and create creatures at that those locations is just a matter of preference.

If you want this to work only in specified areas your respawn script  will look something like this:
(Note for the module only approach use the Module for oArea)

void RespawnCreatures(object oArea)
{
object oCreature;
string sResRef;
location lLoc;
int nCount = GetLocalInt(oArea, "RespawnNumber");
string sCount;
while(nCount--)
  {
  sCount = IntToString(nCount + 1);
  oCreature = GetLocalObject(oArea, "RespawnCreature" + sCount);
  if(GetIsObjectValid(oCreature)) DestroyObject(oCreature);
  sResRef = GetLocalString(oArea, "RespawnResRef" + sCount);
  lLoc = GetLocation(GetLocalObject(oArea, "RespawnLocation" + sCount));
  oCreature = CreateObject(OBJECT_TYPE_CREATURE, sResRef, lLoc);
  SetLocalObject(oArea, "RespawnCreature" + sCount, oCreature);
  }
}


Edit: Note that I used a waypoint to trigger lLoc, when I could have also used GetLocalLocation(), this is more for if you like a waypoint method more than a non-waypoint.
               
               

               


                     Modifié par WhiZard, 10 février 2012 - 11:21 .
                     
                  


            

Legacy_Junnest

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Potentially Complicated Script
« Reply #4 on: February 10, 2012, 11:29:34 pm »


               

Failed.Bard wrote...

I'm heading out for a bit now, but I'll write something up in a couple hours when I get back if you're curious how that would be scripted.


That would be awesome if you could, since I've had so much trouble with this script I feel like I've become actually worse at scripting (honestly, didn't think that was possible). But like I said, I've spent two days on this so I can wait as long as it would take you to throw a script together. Take your time, and thanks again for helping me and my crappy scripting abilities. '<img'>
               
               

               
            

Legacy_Junnest

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Potentially Complicated Script
« Reply #5 on: February 10, 2012, 11:32:44 pm »


               

WhiZard wrote...

Failed.Bard wrote...

Set up waypoints at each spawn location, all with the same tag, that have the creature ResRef on them that you want to spawn at that point.
On spawn you'll want to store the creature object on it that you last spawned there, so it can be ported back into place if still present, or remade if not.  The new creature object would then be stored.  It'd only take about 10 lines of script to do the whole module under that system.

I'm heading out for a bit now, but I'll write something up in a couple hours when I get back if you're curious how that would be scripted.


Whether you manually put the creatures into the toolset and create waypoints at their start location or you put  waypoints into the toolset and create creatures at that those locations is just a matter of preference.

If you want this to work only in specified areas your respawn script  will look something like this:
(Note for the module only approach use the Module for oArea.


Edit: Note that I used a waypoint to trigger lLoc, when I could have also used GetLocalLocation(), this is more for if you like a waypoint method more than a non-waypoint.


 I'll test is out as soon as possible, and if Failed.Bard throws a script together I'll see which one of yours is more convenient for this module. Regardless, I think I can put this script to use for certain miniboss characters to only spawn when a certain area's placeable is used. Thanks for this. '<img'>
               
               

               
            

Legacy_WhiZard

  • Hero Member
  • *****
  • Posts: 2149
  • Karma: +0/-0
Potentially Complicated Script
« Reply #6 on: February 11, 2012, 12:02:10 am »


               

Junnest wrote...
 I'll test is out as soon as possible, and if Failed.Bard throws a script together I'll see which one of yours is more convenient for this module. Regardless, I think I can put this script to use for certain miniboss characters to only spawn when a certain area's placeable is used. Thanks for this. '<img'>


The best scripting option is based on what specifically you want to accomplish.   My way is based off of servers needing areas to respawn, and not wanting to put in a bunch of waypoints with resrefs stored in the variables, especially if they want to swap creatures.  Failed Bard will give you a shorter script but one that is based on placing, naming and inserting resrefs into all locations; a simple copy and paste if all creatures are the same.
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Potentially Complicated Script
« Reply #7 on: February 11, 2012, 12:34:47 am »


                 This is what I came up with for it.
// Added the object type check so you can execute the script on one of the specific
// waypoints you want to respawn.
// Example use:  ExecuteScript ("respawn", GetWaypointByTag ("WP_GOBLIN_CAVES"));
// This script can be used for both initial spawning and respawning.

void main()
{
  object oWP, oCreature;
  string sTag;
  int i;

  if (GetObjectType (OBJECT_SELF) == OBJECT_TYPE_WAYPOINT)
       {
         sTag = GetTag (OBJECT_SELF);
       }
     else sTag = "WP_GENERIC_SPAWN_TAG_HERE";

  while (GetIsObjectValid (oWP = GetObjectByTag (sTag, i++)))
       {
         oCreature = GetLocalObject (oWP, "CREATURE");
         if (GetIsObjectValid (oCreature)) DestroyObject (oCreature);

         oCreature = CreateObject (OBJECT_TYPE_CREATURE, GetLocalString (oWP, "RESREF"), GetLocation (oWP));
         SetLocalObject (oWP, "CREATURE", oCreature);
       }

               
               

               
            

Legacy_Junnest

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Potentially Complicated Script
« Reply #8 on: February 11, 2012, 07:07:35 am »


               So it looks like now I just have to see how long it would really take to implement Failed.Bard's script per creature compared to yours, WhiZard, and see how the time consumption weighs with the necessity to have the script work module-wide. I'm about to knock out, so I'll test these both as soon as I wake up tomorrow and I'll get back to you. Thank you both very much.

As for the scripts themselves, I just have one short/quick question for the each of you if you have the time to answer (and I hope it's just my sleep deprived mind that wants to ask since the answers to these questions should be quite obvious). For your script, WhiZard, would that be placed on the OnUse for the placeable since the locations are already defined by the waypoints? And Failed.Bard, I would need a version of that script per creature, correct? And that script would be placed?... I'm not even going to make an attempt at guessing as to not further embarrass myself. Haha.
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Potentially Complicated Script
« Reply #9 on: February 11, 2012, 08:29:17 am »


               

Junnest wrote...

So it looks like now I just have to see how long it would really take to implement Failed.Bard's script per creature compared to yours, WhiZard, and see how the time consumption weighs with the necessity to have the script work module-wide. I'm about to knock out, so I'll test these both as soon as I wake up tomorrow and I'll get back to you. Thank you both very much.

As for the scripts themselves, I just have one short/quick question for the each of you if you have the time to answer (and I hope it's just my sleep deprived mind that wants to ask since the answers to these questions should be quite obvious). For your script, WhiZard, would that be placed on the OnUse for the placeable since the locations are already defined by the waypoints? And Failed.Bard, I would need a version of that script per creature, correct? And that script would be placed?... I'm not even going to make an attempt at guessing as to not further embarrass myself. Haha.


  You'd need a version of the waypoint per creature, not of the script.  If you use it just for global spawning and respawning, based on a single spawn waypoint tag, then it would go in the OnModuleLoad and OnPlayerRest scripts.
  Just have the module execute the script instead of a waypoint. Eg:  ExecuteScript ("respawn", GetModule() );

 To make up a spawning point, you'd have to do this:
  - Edit - Copy a standard waypoint
  - Name it for the creature type in question (Let's say...  Goblin Archer)
  - Set the tag to the one you're using for all the spawn points
  - Set the RESREF string variable on the waypoint (for a goblin archer...  nw_goblinb)
 
Then just place the waypoint where you want to creature to spawn, including the orientation you want.  You can add as many as you want, likely you won't have to worry about possible TMI errors unless you get more than a thousand waypoints.
  
  Hope that helps explain it.
               
               

               
            

Legacy_Junnest

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Potentially Complicated Script
« Reply #10 on: February 11, 2012, 04:36:04 pm »


               Ah, okay. Right now it isn't working fully but I am least of all educated in the workings of variables as I've only used the same pattern over and over again to forge quests, so I'm assuming I wrote the variable in wrong on the waypoint. I'll tell you everything I did anyway just in case I made any other mistakes, which is actually pretty likely.

First I copy/pasted your script into the OnModuleLoad and OnPlayerRest of the module, and just in case threw the "ExecuteScript ("respawn", GetModule() );" in front of each, and renamed the "WP_GENERIC_SPAWN_TAG_HERE" to "WP_CSPAWN". I made and placed a waypoint, named it "Snowed Ghoul (weaponless)" and edited the tag to "WP_CSPAWN". Then for the variable, this is where some confusion came in (if I didn't make a mistake already, I certainly made one here)...
As I mentioned, I am not great with variables so expect some pretty dumb errors here. The first variable I set was "snowedghoul001, string, 0". The test didn't work obviously, so I set it to "snowedghoul001, string, 1", which I doubt would have worked as it didn't. Lastly I threw in "WP_CSPAWN, string, snowedghoul001" but that hadn't worked either.

Sorry to have you coming back and explaining all of this to me, as I'm sure you've provided me more than enough of the information I should need to get this script working. I'm just that bad at them. '<img'>
               
               

               
            

Legacy_Junnest

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Potentially Complicated Script
« Reply #11 on: February 11, 2012, 06:01:07 pm »


               One thing I wanted to quickly add, as I've just discovered. I've put ten or so scripts in this module and was saving the OnUse placeable script to cause the PC to rest for last since I imagined that would be the easiest to implement. I guess I'm having bad luck because it's turned out far more annoying than I thought based on my scripting abilities, though I feel it really is simple and I'm just bad at this.

All I'm trying to accomplish is having the PC sit down to rest, whether it's ForceRest with a sit down animation or the actual rest animation (doesn't matter), and give the PC a full 100% recovery so I am trying to include the spell greater restoration, and accomplish all of this regardless of enemy status (they could even be attacking the PC at the time for all I care). Though the latter portion doesn't matter all that much, I just for some reason can't get a sit-down-and-rest script to compile properly.
               
               

               
            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Potentially Complicated Script
« Reply #12 on: February 12, 2012, 12:57:25 am »


               

Junnest wrote...

Ah, okay. Right now it isn't working fully but I am least of all educated in the workings of variables as I've only used the same pattern over and over again to forge quests, so I'm assuming I wrote the variable in wrong on the waypoint. I'll tell you everything I did anyway just in case I made any other mistakes, which is actually pretty likely.

First I copy/pasted your script into the OnModuleLoad and OnPlayerRest of the module, and just in case threw the "ExecuteScript ("respawn", GetModule() );" in front of each, and renamed the "WP_GENERIC_SPAWN_TAG_HERE" to "WP_CSPAWN". I made and placed a waypoint, named it "Snowed Ghoul (weaponless)" and edited the tag to "WP_CSPAWN". Then for the variable, this is where some confusion came in (if I didn't make a mistake already, I certainly made one here)...
As I mentioned, I am not great with variables so expect some pretty dumb errors here. The first variable I set was "snowedghoul001, string, 0". The test didn't work obviously, so I set it to "snowedghoul001, string, 1", which I doubt would have worked as it didn't. Lastly I threw in "WP_CSPAWN, string, snowedghoul001" but that hadn't worked either.

Sorry to have you coming back and explaining all of this to me, as I'm sure you've provided me more than enough of the information I should need to get this script working. I'm just that bad at them. '<img'>


This is what you'd need to put in for the variable, based on that creature resref you're trying.
RESREF, string, snowedghoul001

It looks like you did the rest of it properly, based on what you posted.
               
               

               


                     Modifié par Failed.Bard, 12 février 2012 - 12:57 .
                     
                  


            

Legacy_Failed.Bard

  • Hero Member
  • *****
  • Posts: 1409
  • Karma: +0/-0
Potentially Complicated Script
« Reply #13 on: February 12, 2012, 01:02:40 am »


               

Junnest wrote...

One thing I wanted to quickly add, as I've just discovered. I've put ten or so scripts in this module and was saving the OnUse placeable script to cause the PC to rest for last since I imagined that would be the easiest to implement. I guess I'm having bad luck because it's turned out far more annoying than I thought based on my scripting abilities, though I feel it really is simple and I'm just bad at this.

All I'm trying to accomplish is having the PC sit down to rest, whether it's ForceRest with a sit down animation or the actual rest animation (doesn't matter), and give the PC a full 100% recovery so I am trying to include the spell greater restoration, and accomplish all of this regardless of enemy status (they could even be attacking the PC at the time for all I care). Though the latter portion doesn't matter all that much, I just for some reason can't get a sit-down-and-rest script to compile properly.


  I don't know a way to bypass the default rest check that bioware uses, while still using the rest key.  For my mod I ended up adding a rest tool to player tool 1 to get around that, since in my system you only have to be out of sight of an enemy to start resting.
  I'm not sure why you'd want to allow a full healing instant rest in combat, but you'd likely have to move it to a seperate tool or feat as well to accomplish it.
               
               

               
            

Legacy_Junnest

  • Jr. Member
  • **
  • Posts: 50
  • Karma: +0/-0
Potentially Complicated Script
« Reply #14 on: February 12, 2012, 01:40:35 am »


               Thank you so much for the script and helping me figure it out. I'll be using both of your scripts and credit the both of you. They should work wonders across the module.

As for resting: I don't mind using the default rest check, rather it's that I just can't compile a script properly that consists of an placeable triggering the PC to rest OnUse. This is what I have, and the current error I'm receiving is an "invalid declaration type" on the first bracket.

void ActionRest(int bCreatureToEnemyLineOfSightCheck = TRUE);
 {
   object oPC = GetLastUsedBy();

   ActionCastSpellAtObject(SPELL_GREATER_RESTORATION, oPC, METAMAGIC_ANY, TRUE, 0, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);

   ActionStartConversation(oPC, "", TRUE, FALSE);
 }