Aller au contenu

Photo

A total noob in NWN2 scripting - ga_faction_join


  • Veuillez vous connecter pour répondre
15 réponses à ce sujet

#1
Annassassin

Annassassin
  • Members
  • 5 messages

Calling all the ladies and gentlemen to impart their wisdom on an issue I'm having trouble with, but which seems so easy that it's not even funny, even to my eyes. It makes me feel stupid, not to say that couldn't be the case either way. I'm fully aware that I'm probably starting from way too difficult scripts, but I've been trying to tackle this one for so long and I am too stubborn to give up now.

 

Anyways, onto the topic:

 

---------------------------------------

 

// ga_faction_join
/*
    This script makes sTarget join a new faction.
sTarget - The target who's faction will change (see Target's note).
sTargetFaction - Either one of the 4 standard factions $COMMONER, $DEFENDER, $HOSTILE, $MERCHANT or
a target who's faction is to be joined (must be a creature)
*/
//  ChazM 2/25/05
// DBR 11/09/06 - TargetFactionMember was using wrong target string
 
#include "ginc_param_const"
#include "nw_i0_generic"
 
 
void main (string WGUARD, string $HOSTILE)
 
{
object oTarget = GetTarget(WGUARD);
int iFaction = GetStandardFaction($HOSTILE);
 
if (iFaction != -1) {
ChangeToStandardFaction(oTarget, iFaction);
PrintString ("Changed to standard faction " + $HOSTILE);
}
else {
object oTargetFactionMember = GetTarget($HOSTILE);
  ChangeFaction(oTarget, oTargetFactionMember);
PrintString ("Changed to same faction as " + GetName(oTarget));
}
 
AssignCommand(oTarget, DetermineCombatRound());
 
}
 
---------------------------------------
 
(sTarget is changed to WGUARD and sTargetFaction is changed to $HOSTILE from the template script)
 
I am trying here to change the faction of a creature, whose tag is WGUARD, from $COMMONER to $HOSTILE and I have no idea why it doesn't work! I've attached the script to a chest in the OnInventoryDisturbed thingy.
 
All sorts of help and insights into the matter are very appreciated!
 
Tanks, 
 
Anna


#2
rjshae

rjshae
  • Members
  • 4 491 messages

Why are you passing $HOSTILE as a variable? I believe it should be a constant defined in the include file.


  • Annassassin aime ceci

#3
kevL

kevL
  • Members
  • 4 061 messages

first, if you're going to rewrite/change a stock script, it's often wise to rename it.
( not always, but usually )

that said, the $HOSTILE isn't used correctly. use PARAM_HOSTILE
( WGUARD prob. isn't either )


But why don't you either (a)use the stock script or (B) rewrite it completely with a new filename?

eg. If you know it's always going to be tag="WGUARD" and STANDARD_FACTION_HOSTILE ...

// 'guard_go_hostile'

#include "nw_i0_generic"
void main()
{
    object oGuard = GetNearestObjectByTag("WGUARD");
    ChangeToStandardFaction(oGuard, STANDARD_FACTION_HOSTILE);

    AssignCommand(oGuard, DetermineCombatRound());
}


ok, here's where i think you're thinking incorrectly. ga_* scripts are intended to go into dialogs, where the initial parameters can be set -- WGUARD & $HOSTILE. The 'dialog-parser' then converts those into usable strings. A script in the onDisturbed event of a chest should not use a ga_ action script .. that is, there is no magic that takes or converts the initial parameters: in this case you have to script from scratch, as above.
  • Annassassin aime ceci

#4
Tchos

Tchos
  • Members
  • 5 054 messages

If the script is on a chest, it will not work, because you've adapted a conversation script which expects parameters to be passed to it in the actions tab of the conversation node.  Instead, you need to remove the "string WGUARD, string $HOSTILE" from the function declaration, and give those parameters directly in the script.  There are other ways, but that'll be the simplest way to get you started.  "WGUARD" will need to be in quotes.

 

I see others have responded in the meantime, so I'll stop here.


  • GCoyote et Annassassin aiment ceci

#5
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages

Factions can be screwy, because the original NWN faction system (and scripts) don't always align with the way factions are handled in NWN2.  If I were you, I'd make a separate faction for your guards, and then use the change reputation functions to make the guard faction hostile to the player.  If the guard is just switched to the hostile faction, it might also attack any commoners or non-switched defender guards that are in the area.


  • Annassassin aime ceci

#6
Annassassin

Annassassin
  • Members
  • 5 messages

I posted this late at night my time, so I apologize for the time it took to answer and thank you for the incredibly quick replies! I'll address some of the questions regarding my silly intentions and points raised by you.

 

 

Why are you passing $HOSTILE as a variable? I believe it should be a constant defined in the include file.

 

Because umm... I just followed the script's instructions. Which apparently aren't as simple and descriptive as they seemed to me.

 

 

 

first, if you're going to rewrite/change a stock script, it's often wise to rename it.
( not always, but usually )

that said, the $HOSTILE isn't used correctly. use PARAM_HOSTILE
( WGUARD prob. isn't either )


But why don't you either (a)use the stock script or ( B) rewrite it completely with a new filename?

eg. If you know it's always going to be tag="WGUARD" and STANDARD_FACTION_HOSTILE ...
 

// 'guard_go_hostile'

#include "nw_i0_generic"
void main()
{
    object oGuard = GetNearestObjectByTag("WGUARD");
    ChangeToStandardFaction(oGuard, STANDARD_FACTION_HOSTILE);

    AssignCommand(oGuard, DetermineCombatRound());
}
ok, here's where i think you're thinking incorrectly. ga_* scripts are intended to go into dialogs, where the initial parameters can be set -- WGUARD & $HOSTILE. The 'dialog-parser' then converts those into usable strings. A script in the onDisturbed event of a chest should not use a ga_ action script .. that is, there is no magic that takes or converts the initial parameters: in this case you have to script from scratch, as above.

 

 

I did in fact save the script under another name instead of modifying the stock script. I don't think it even let me modify it. I just failed to mention it above <.<

 

Welllll, it's good to know that ga_* refers to scripts fired by dialogs this early on. Thanks a lot for the script! 

 

 

If the script is on a chest, it will not work, because you've adapted a conversation script which expects parameters to be passed to it in the actions tab of the conversation node.  Instead, you need to remove the "string WGUARD, string $HOSTILE" from the function declaration, and give those parameters directly in the script.  There are other ways, but that'll be the simplest way to get you started.  "WGUARD" will need to be in quotes.

 

I see others have responded in the meantime, so I'll stop here.

 

I didn't know it was a dialog script, but now I do, so all is good. Regarding the quotes, that's a very good thing to know, thank you.

 

 

Factions can be screwy, because the original NWN faction system (and scripts) don't always align with the way factions are handled in NWN2.  If I were you, I'd make a separate faction for your guards, and then use the change reputation functions to make the guard faction hostile to the player.  If the guard is just switched to the hostile faction, it might also attack any commoners or non-switched defender guards that are in the area.

 

Good to know about the factions, yet fortunately, the problem doesn't apply here, cause WGUARD isn't a townguard NPC or such, but rather a construct guardian assigned to guard the aforementioned chest.

 

Thank you all a whole lot for all your help and advice!

 

Anna

 

EDIT: As a side note, it's alive! Thanks to you all once again.


Modifié par Annassassin, 09 décembre 2014 - 10:25 .

  • rjshae aime ceci

#7
Tchos

Tchos
  • Members
  • 5 054 messages

Good that it's working.  Don't be concerned about a coding question seeming silly.  I'm sure that anyone here who knows the answer to an honest scripting question will answer it without judgement, or refer you to another post where it may have been answered before.

 

Here's a little extra background info on why your tag WGUARD needed to be in quotes in this case, but not necessarily in other cases.  Here, you're telling it a value (a tag, which is a string) directly, and strings are put in quotes.  Other times you may use a variable that represents the actual value.  You can define a variable within your script.

GetNearestObjectByTag("WGUARD");

can be the same as

string WGUARD = "WGUARD";
GetNearestObjectByTag(WGUARD);

So now WGUARD is a variable that has a value of "WGUARD".  But the name of the variable doesn't need to be WGUARD to have the same effect.  In fact, it's more common in these scripts to use a particular naming convention to represent what kind of value a variable contains.  For instance, you'd put an "s" in front of a string variable, like sWGUARD.  Also, it's more common to name the variable as a category of what it does rather than the expected value, so you might see something more like:

string sGuardTag = "WGUARD";
GetNearestObjectByTag(sGuardTag);

This does the same thing as above, and this sort of thing is useful for things you might want to do later.


  • Annassassin aime ceci

#8
Annassassin

Annassassin
  • Members
  • 5 messages

Thanks for the additional info on the quotation marks. Now that I think on it, I think I've read it previously in some Basic Scripting Tutorials or something... just goes to show that you don't learn everything on one reading. Or several, even.

 

However, I've another problem, for which I possibly should create a topic of its own, but:

 

I've set waypoints for an NPC to follow and they do, well and good. I added a couple of premade scripts on it, namely the one that randomizes the order in which the NPC goes through them and one where they're supposed to pause for a while and face the direction the waypoint is facing. The latter script doesn't seem to work for me, for some reason, even when deleting the other from the file. However, that's not the problem I'm most concerned about, but the fact that when you talk to the wandering NPC, they don't go back to following the waypoints, instead just standing there. I did find a command to reset the waypoint patrolling, but I can't figure out how to use it. I have all the pieces of the puzzle, but I have no idea how to build the puzzle out of them, if you will. Or well, at least I think I have all the pieces.

 

Cheers,

 

Anna



#9
rjshae

rjshae
  • Members
  • 4 491 messages

The standard creature heartbeat script is supposed to kick the NPC back into walking the waypoints a few seconds after it is no longer in a conversation. Are you using a custom heartbeat script, per chance?


  • Annassassin aime ceci

#10
Annassassin

Annassassin
  • Members
  • 5 messages

Yes, I am. I suppose I should've figured that out <.<

 

It was the aforementioned script changes, I suppose I should've just added them onto a copy of the stock script. It's a bit messy, though. Thanks for helping with this thing, again.

 

Anna



#11
rjshae

rjshae
  • Members
  • 4 491 messages

I don't think you need to modify the stock heartbeat script; there's a way to set up a script that runs whenever the NPC reaches a waypoint. IIRC, it's a variable that you set on the NPC.


  • Annassassin aime ceci

#12
Annassassin

Annassassin
  • Members
  • 5 messages

Would you happen to know and/or remember which variable that would be? I still know very little about this whole Toolset and Scripting thing, learning as I go. And by bombarding more knowledgeable people with questions, naturally.

 

Anna



#13
rjshae

rjshae
  • Members
  • 4 491 messages

Here you go.


  • Annassassin aime ceci

#14
kevL

kevL
  • Members
  • 4 061 messages

also,

look in your NPC's onHeartbeat event slot. That's the filename of the script that runs onHeartbeat.

walkwaypoints are not simple. That said, this is the codeblock that restarts a stalled NPC's walkwaypoints routine:
 

else if (GetWalkCondition(NW_WALK_FLAG_CONSTANT))
{
    WalkWayPoints();
}

The default onHB script is 'nw_c2_default1'.

If you can trace the GetWalkCondition(NW_WALK_FLAG_CONSTANT) it should end up at the variable that Rj noted [edit, thinking ...]. it's not simple, so first just check what script runs from NPC's heartbeat event -- is it 'nw_c2_default1', or if not then look at what conditions are required in the script to get to a WalkWayPoints() call (if it even exists).

 

 

 

ps. Sry didn't notice the posts several up, but same applies.



#15
kevL

kevL
  • Members
  • 4 061 messages

in 'x0_i0_walkway', function GetNextWalkWayPoint()

a call is made to ExecuteScript(sScript, oCreature) - this is the "scripted waypoint"

It looks like sScript can vary depending on whether it's day or not (if they're spec'd differently) and can be overridden by an onSpawn variable. It also looks like the NW_WALK_FLAG_PAUSED variable* needs to be unset (if it was set) before WalkWayPoints() does anything.

 

* Rj, these are bitwise

const string sWalkwayVarname       = "NW_WALK_CONDITION"; // bit flags, see below

// If set, the creature's waypoints have been initialized.
const int NW_WALK_FLAG_INITIALIZED = 0x00000001;
// If set, the creature will walk its waypoints constantly, moving on in each OnHeartbeat event.
// Otherwise, it will walk to the next only when triggered by an OnPerception event. [kL_note: huh.]
const int NW_WALK_FLAG_CONSTANT    = 0x00000002;
// Set when the creature is walking day waypoints.
const int NW_WALK_FLAG_IS_DAY      = 0x00000004;
// Set when the creature is walking back
const int NW_WALK_FLAG_BACKWARDS   = 0x00000008;
// Set to Turn off WWP
const int NW_WALK_FLAG_PAUSED      = 0x00000010;

Anyway, need more information ....



#16
Dann-J

Dann-J
  • Members
  • 3 161 messages

 

And let's not forget the stickied thread on these very forums:

 

http://forum.bioware...ypoints-repost/


  • rjshae aime ceci