Script and .erf questions

Back again… I’ve made some progress on importing .erf files. However, it seems that the toolset will only use one at a time. Specifically, I can only get the first .hak listed in the window to render. For example, when I use the giant frog hak, it must be listed in the “0” slot of the hak window and nothing listed after it will show. But when I elevate the snake hak to the “0” slot, it renders, but the giant frog is lost. It must be some setting that I’m not aware of or I must be doing something wrong. Any thoughts and advice would be much appreciated.

Also, I am trying to use a ladder to get out of a cellar. I want to use the ga_area_transition script, but cannot figure out the correct syntax. I want to transition to a waypoint called wp_cellarout and I want it to be a party transition, so that should be set to TRUE. Take a look at the screenshot and let me know what I’ve screwed up. It took me an entire Saturday morning to figure out the correct syntax for a journal entry through trial and error. There’s got to be a community resource that shows noobies like me what right looks like…

Thanks!

1 Like

You are getting a compilation error because you’re giving the wrong type of argument to StandardAttemptAreaTransition, it requires an object as second argument and you’re giving it a string instead.

That script is a conversation script meant to be called with arguments (that can be used from the conversation editor), something you can’t do while slotting it on the on use event of a placeable.

Here’s how that script would have to be used, in a conversation, in your specific case:

If you wanted to call it from an on use script, then you’d have to make a new script that looks something like this:

#include "ginc_param_const"
#include "ginc_transition"

void main()
{
	object oPC = GetLastUsedBy();
	object oDestination = GetWaypointByTag("wp_cellarout");
	if (oDestination == OBJECT_INVALID) oDestination = GetObjectByTag("wp_cellarout");
	StandardAttemptAreaTransition(oPC, oDestination, TRUE);
}
1 Like

Clangeddin, thanks for schooling me on the script! Sorry for showing my ignorance, but as I’ve said before, I’m a total noobie to the scripting world. Your response does make me ask a few more questions however. As amateurish as they may be, what’s the difference btw the argument types? What’s an object versus a string? How are they distinguished? And how do I tell what scripts are for use with conversations and which are for use with placeables?

I know I’m probably a royal PIA with these questions… Honestly not my intent. I just want to get my head around scripting and have a working understanding to build a few more mods. I know I’ll never be an expert, I just want to be proficient.

And thanks for the on use script!

1 Like

We all start from somewhere :). The first time I tried to do stuff I also had no clue. People were talking about putting integer variables on creatures and I was like what…? So no worries, you’ll get there.

About the questions,

a conversation script has the name ga_* or gc_* in the beginning of its name. ga_* scripts are action scripts and gc_* scripts are conditionals. These are just the stock ones. You can name yours as you like, and even write ones without parameters and still use them in convos. I am quite certain that some stock ones even come without parameters, but it’s rare since they’ll at least want to check on which object they want to apply the action or condition.

The difference between variables.
An integer is a numeric value. Note that bool values also don’t exist, so we usually use integer -1 for false.
A string is a word, or character. If we need to get technical, char variables don’t exist in nwnscript. Meaning that the syntax char c = ‘A’ is not valid. Every character or array of characters is a string. A string is comonly used to identify tags. For example string sNPC = GetObjectByTag(“JON”);
An object is an object of your world. A waypoint, an NPC, a companion etc.
A struct is a collection of variables (Used rarely)

I hope that covers it :slight_smile: . Keep trying and it will be fine!

2 Likes

No worries, I’m actually not a programmer myself (I studied economics, not informatics), so I understand very well the plight of those who approach scripting without much knowledge even though they’d like to implement all their ideas as hobbysts. There was a time when I was asking all the time about NWscripting too.

As for the answers themselves, I was about to type them, but then I saw andysks’s message appear so I’ll just leave that to him (did I just assume his gender?! :stuck_out_tongue: )

1 Like

You can always complete my answer as I am certain it will be incomplete :smiley: . On the side note, I started modding as a cook and then studies software engineering because of the fascination I got while modding.

1 Like

I’m pretty sure that Integer 0 stands for FALSE though, not -1.

Well… you probably meant

string sNPC = "JON"; 
object oNPC = GetObjectByTag(sNPC);

here.

@angry_yard_gnome this might help a bit:
https://neverwintervault.org/forums/neverwinter-nights-2/nwn2-tutorials/basic-scripting-not-so-basic

1 Like

Of course, 0 is false. I was writing without thinking there for a moment.

1 Like

FWIW most BASIC compilers used to use -1 for FALSE internally. That was in the days before .net appeared.

TR

I’ve asked far more stupid questions when it comes to scripting than you, so I don’t think you have to worry. Both kevL_s and Aqvilinus have helped me a tremendous amount these last two years when I’ve been working on my modules, and I’m eternally grateful for their support! I still don’t grasp scripting fully, but I’m finally beginning to understand at least some basic things. And nowadays I have so many scripts made from guys here on the forums and on discord, that I manage to do most of what I want. I just copy and paste a lot of things, and then change strings or object names…

1 Like

I think that’s what I had in mind when posting my reply.

@angry_yard_gnome I’ve said this often and I think it is the best advise I can give to new scripters. There are a lot of ga_* and gc_* scripts. Probably 99% of any simple thing you want to do exists in the form of such a script. Sure, scripting a special AI for you boss is not there, but how often do you need such a thing?

So, whenever you want something to happen, use a conversation. For example, you want the PC to get experience when entering a new area. Instead of writing a script, write a dialogue which fires (from a trigger) when the PC enters the area. Like a description. And in the dialogue call ga_give_xp. Job done. And every time you do such a thing, take a look into the script you’re using to see how it’s done.

1 Like

FWIW In NwN 1 I would write an OnEnter script for a generic trigger to do that job and as the last act of that script, destroy the trigger that called it. This is assuming we are talking about a sp module. By destroying the trigger (using DestroyObject(OBJECT_SELF) with whatever short delay you want) you ensure the script is only called once.

TR

1 Like

“Specifically, I can only get the first .hak listed in the window to render.”

For creatures, the appearances.2da file controls what can appear in the toolset. For placeable objects it’s placeables.2da, for tilesets it’s tilesets.2da and tiles.2da etc.

It’s likely the various haks have their own copies of one of more of these 2da files. Only one of each 2da can be used however. So basically there are more than one of a 2da, and they are conflicting.

@andysks Yes, you’re totally right. There are a lot of ga and gc scripts that most of the time does what you want to do. I’ve often copied things from those scripts when I’ve made my own variations of simple scripts (but that was when I finally grasped the most basic things about scripting. When everything’s new and you don’t understand scripting at all, like for me one or two years ago, it can be hard to copy and write your own stuff). I also would recommend using Lilac Soul’s Script Generator, since that also helps with basic stuff.
@Tarot_Redhand When it comes to making a trigger that destroys itself. I’ve actually never done that. I always use an integer that tells when the script has been used instead.

@kamal AH HA! Thank you! That actually makes sense even to me with my severely limited knowledge! Now that begs the question of how do I modify the .2da file to have both creatures show? TBH, I have opened and looked around at a few .2da’s, but was totally intimidated and afraid of mucking things up and not being able to fix it, so I just left well enough alone. IIRC, the .2da’s are in simple spreadsheet format, .xls or .csv-like files, right?

To all, THANKS for the help and advice. I made the same discovery that andysks pointed out… There do appear to be hundreds of canned scripts for nearly any action. Now it’s just a matter of finding the right one. Very good to know that ga_* and gc_* scripts apply to conversations. Probably would have taken me a week to figure that out on my own. It’s helpful that almost all of the scripts have some description of what they do written right into the script itself. But is there a catalog or list that not only shows which are convo scripts and which are action scripts, but also what they’re intended to do? For example if you want an NPC to join a players group at some point in a convo, what script(s) are appropriate for that? Seems horribly time consuming to have to open scripts at random to see what each one does.

Have a look at the toolset guide from @rjshae. The third volume of it has two sections you need: one named “Action Scripts” and the other named “Condition Scripts”.
https://neverwintervault.org/project/nwn2/other/tool/nwn2-toolset-guide


1 Like
  • look through the haks and copy out any .2da files to a temporary directory.
  • make sure they’re copies because the originals will serve as backups.
  • append an incremental numeral to any filenames that are the same (eg. appearance.2da / appearance1.2da) so they can reside in the same directory
  • open duplicates in WinMerge and/or Yata – yata can serve as a frontend for Winmerge
  • resolve and merge any conflicts down into the base 2da that you’re going to use for real (eg. appearance.2da)
  • finally, package all of your new base 2das into a new .hak and when you associate it with your module make sure it’s the “tophak” – listed at the top* of your .haks list

 
* The tophak takes priority over other haks.

 
ps. although spreadsheet programs will work if you know what yer doing, I don’t recommend using them for 2das …

1 Like