Aller au contenu

Photo

What am I doing wrong here


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

#1
Shaun the Crazy One

Shaun the Crazy One
  • Members
  • 183 messages
Sorry to keep posting my faulty code, but I'm really stuck with this one.  I have a script that I've been putting on doors and triggers.  That is suppose to make NPCs speak strings and/or go hostile.  It compiles but when I run the game it doesn't alway work.  The NPC turns hostile sometimes, but the speak string has never worked.

I've been putting the script on triggers and door and setting the local variables in the variables proporty tab of the door or trigger.  I can't determine any pattern to when it does or does not work.

//reaction

/*
    This script handles the reaction of a specific character when an area or trigger 
    is entered or a door opened.  The tigger area or door should have local variables
    to determine the reaction of the character when the script is run.
    
    Variables:
        sCreatureTag - the tag of the creature or object to react
        sSpeakString - the line for the reacting character to speak, leave blank if no
            line should be spoken.
        iGoHostile - set as 1 to make the creature go hostile, 2 to also issue an attack
            command.
*/

//Shaun H. 2/12/11

#include "nw_i0_generic"

void main()
{
    //Check to make sure script's activator is the PC
    object oPC = GetEnteringObject();
    if (!GetIsPC(oPC)) return;
    
    //Run only once
    int DoOnce = GetLocalInt(OBJECT_SELF,"DoOnce");
    if(DoOnce == TRUE) return;
    SetLocalInt(OBJECT_SELF,"DoOnce",TRUE);

    //Get Target 1
    object oTarget = GetObjectByTag(GetLocalString(OBJECT_SELF,"sCreatureTag"));
    
    //Speak string
    string sLine = GetLocalString(OBJECT_SELF,"sSpeakString");
    if(StringCompare(sLine,"") != 0) SpeakString(sLine);
    
    //Faction change
    int iFaction = GetLocalInt(OBJECT_SELF,"iGoHostile");
    if(iFaction > 0) ChangeFaction(oTarget,GetObjectByTag("Hostile"));
    if(iFaction == 2)
    {
        AssignCommand(oTarget, ActionAttack(oPC));
        AssignCommand(oTarget, DetermineCombatRound(oPC));
    }
}


#2
Kaldor Silverwand

Kaldor Silverwand
  • Members
  • 1 598 messages
A few suggestions from just looking at the script.

GetEnteringObject will work for triggers, but will not work for doors.

I generally use GetNearestObjectByTag rather than GetObjectByTag since GetNearest will search only the area you are in, which is generally what you want. You may be getting some other creature with the same tag in another area of the module.

For the SpeakString your main problem is that triggers can't talk, so use:
if (sLine != "") AssignCommand(oTarget, SpeakString(sLine));

The faction changing looks ok, although I think you can use the standard factions with ChangeFaction, so you don't really need the hostile object.

Regards

#3
Clyordes

Clyordes
  • Members
  • 300 messages
Hi Shaun,
Personally, I'm rubbish at scripting, but I've made a lot of use of the recently updated version of Lilac Soul's script creator nwvault.ign.com/View.php .
It couldn't be much simpler to use, and I'm sure I've used it to produce similar effects to the ones you're talking about.

Can't say how it compares to other generators on the vault as its the first one I tried & it does the job fine for me (on the whole - Kaldor & co have had to come to the rescue once or twice to help me out over the years).:unsure:

Cly.

#4
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages
I agree with Kaldor on why the barkstring isn't working. For the faction thing, you can use ChangeToStandardFaction(sp?), if they're just going hostile. With my custom factions, I end up using AdjustReputation.

A ClearAllActions in the mix somewhere might help, too.

#5
Shaun the Crazy One

Shaun the Crazy One
  • Members
  • 183 messages
Thanks for all the feedback guys. This may just require trial and error though.
-According to the description GetEnteringObject should work with doors, but to be honest I'm not sure that's true.
-I do think the tags may be an issue, I think using GetNearestObjectByTag is the first thing I'll try.
-I know in C you can't compare strings with ordinary comparators, that's why I used the StringCompare function. I think I used it right, but my C is a bit rusty. I not sure the if statement is even necessary though, maybe I'll just remove it.
-So SpeakString only works on the triggering object. Can't believe I missed that. The fact that there was no object feild should have tipped me off. Thanks for pointing that out.
-For the ChangeFaction command "hostile" is a faction pig, in my experience it's the most reliable way to change a creature's faction.

@Clyordes I do have Lilac Soul's script creator but I prefer to use it as a learning tool.

Thanks all for the feedback, I'll try making these changes now.

#6
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
You can compare strings as in

if ( "xxx" == "xxx" ) would always be true and works just fine.

if ( sVariable != "" ) would test true if sVariable is not empty. Use things like that all the time.

I really very rarely use stringcompare, and find getting the strings position is far more often useful if you need to see if a string contains something. There is a very strange regular expression type function which also can be of use in conversations.

Modifié par painofdungeoneternal, 25 janvier 2012 - 08:17 .


#7
Kaldor Silverwand

Kaldor Silverwand
  • Members
  • 1 598 messages
I'd be very surprised if GetEnteringObject is updated when a door is opened, which is when I think you want this to happen. It might be updated when the PC actually goes through the door, but that would be too late for what you are doing, wouldn't it? I think you want to check for who is using the door so that when the door is opened the NPC's go hostile to the opener.

Regards

#8
kevL

kevL
  • Members
  • 4 078 messages
for object oPC, could do

object oPC = GetEnteringObject();
if (!GetIsObjectValid(oPC)) oPC = GetClickingObject();

nb. The descriptions of those two functions say they are nearly if not exactly identical ....

// The value returned by this function depends on the object type of the caller:
// 1) If the caller is a door it returns the object that last
//    triggered it.
// 2) If the caller is a trigger, area of effect, module, area or encounter it
//    returns the object that last entered it.
// * Return value on error: OBJECT_INVALID
//  When used for doors, this should only be called from the OnAreaTransitionClick
//  event.  Otherwise, it should only be called in OnEnter scripts.
object GetEnteringObject();

// Use this in a trigger's OnClick event script to get the object that last
// clicked on it.
// This is identical to GetEnteringObject.
object GetClickingObject();


#9
The Fred

The Fred
  • Members
  • 2 516 messages

Shaun the Crazy One wrote...
-According to the description GetEnteringObject should work with doors, but to be honest I'm not sure that's true.

When you go through a door transition, yes. I don't think when you open it, though - probably GetLastOpenedBy (though I think they are meant to be synonymous).

Shaun the Crazy One wrote... 
-I know in C you can't compare strings with ordinary comparators, that's why I used the StringCompare function.

That is true, but in NWN(2) script you can indeed just use a double equals, ==.

Shaun the Crazy One wrote... 
-For the ChangeFaction command "hostile" is a faction pig, in my experience it's the most reliable way to change a creature's faction.

For standard factions, ChangeToStandardFaction() has always worked for me. Your approach ought to work too, though.

Shaun the Crazy One wrote...  
@Clyordes I do have Lilac Soul's script creator but I prefer to use it as a learning tool.

Never trust code to write more code. Where would it end? AFAIK, Lilac's is OK, but an inanimate object will never have the zen or ki mastery required to be a true scripting genius.

#10
Shaun the Crazy One

Shaun the Crazy One
  • Members
  • 183 messages
Thanks for all the feedback.  The inconsistance was indeed due to using GetObjectByTag rather than GetNearestObjectByTag.  I finaly got it working, the new script is:

#include "nw_i0_generic"

void main()
{
    //Check to make sure script's activator is the PC
    object oPC = GetEnteringObject();
    if (!GetIsPC(oPC)) oPC = GetLastOpenedBy();
    if (!GetIsPC(oPC)) return;
    
    //Run only once
    int DoOnce = GetLocalInt(OBJECT_SELF,"DoOnce");
    if(DoOnce == TRUE) return;
    SetLocalInt(OBJECT_SELF,"DoOnce",TRUE);
    
    //Get Target 1
    object oTarget = GetNearestObjectByTag(GetLocalString(OBJECT_SELF,"sCreatureTag"));
    
    //Speak string
    string sLine = GetLocalString(OBJECT_SELF,"sSpeakString");
    if(StringCompare(sLine,"") != 0) AssignCommand(oTarget, SpeakString(sLine));
    
    //Faction change
    int iFaction = GetLocalInt(OBJECT_SELF,"iGoHostile");
    if(iFaction > 0) ChangeFaction(oTarget,GetObjectByTag("Hostile"));
    if(iFaction == 2)
    {
        AssignCommand(oTarget, ActionAttack(oPC));
        AssignCommand(oTarget, DetermineCombatRound(oPC));
    }
}