Aller au contenu

Photo

Barkstrings revisited


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

#1
Clyordes

Clyordes
  • Members
  • 300 messages
All hail, scripting gods :innocent:

I thought I'd got this sorted in my previous mod, but on re-testing recently in putting the finishing touches to my latest project, its still an issue.

I want named companions to speak a short line of conversation when the PC you're controlling - or anyone else in teh party - I'm not fussy - enters a trigger.

DannJ kindly provided a script when I put out a request before - see below - but for some reason I'm still getting an issue with the text being duplicated if you're controlling a companion when the trigger is entered. 

Dann said it didn't occur in his mods & after a quick look at them in the toolset, I'm not sure what's different about my mods.

Here's his script:
// bark_comments
//
// Set variables on triggers as follows:
//
// Tag = [tag of companion who speaks - leave blank for first PC]
// BarkString = [floating text to display]

void main ()
{
object oNPC;
object oTrigger = GetEnteringObject();
string sBark = GetLocalString(OBJECT_SELF, "BarkString");
string sTag = GetLocalString(OBJECT_SELF, "Tag");
int iFlag = TRUE;

if (sTag == "")
oNPC = GetFirstPC();
else
oNPC = GetObjectByTag(sTag);

if ( oTrigger != oNPC)
return;

if (GetIsPC(oNPC) && oNPC != GetFirstPC())
iFlag = FALSE;

FloatingTextStringOnCreature(sBark, oNPC, iFlag);
// next line destroys trigger - makes it a single use
DestroyObject(OBJECT_SELF, 0.0, FALSE);
}

I'm not sure, but maybe there's a clue in the secret door scripts I use - one of the scriptsis below - as they seem to work fine whether the main PC or a companion is the one you're controlling when the trigger fires.

//:://////////////////////////////////////////////////
//:: TW_SEC_DOOR // TW Edit
//::    This is an OnEntered script for a generic trigger.
//::    When a PC enters the trigger area, it will perform
//::    a check to determine if the secret item is revealed,
//::    then make it appear if so.
//::
//::    Secret item to be revealed: Secret Wooden Door
//::    Checking for: SKILL_SEARCH
//::
//:: Copyright © 2002 Floodgate Entertainment
//:: Created By: Naomi Novik
//:: Created On: 12/08/2002
//:: Rewritten for NWN2 by Tzell Winterhaven
//:://////////////////////////////////////////////////

#include "tw_secret"


void main()
{
    object oEntered = GetEnteringObject();

    if (GetIsSecretItemRevealed()){return;}

    if ( DetectSecretItem(oEntered)) {
        if (!GetIsPC(oEntered)) {
            // If a henchman, alert the PC if we make the detect check
            object oMaster = GetMaster(oEntered);
            if (GetIsObjectValid(oMaster)
                && oEntered == GetAssociate(ASSOCIATE_TYPE_HENCHMAN, oMaster))
            {
            AssignCommand(oEntered, PlayVoiceChat(VOICE_CHAT_SEARCH));
            }
        } else {
            // It's a PC, reveal the item
            AssignCommand(oEntered, PlayVoiceChat(VOICE_CHAT_LOOKHERE));
            // RevealSecretItem("tw_sec_tdoor");
            RevealSecretItem("tw_sec_stdoor");
        }
    }
}

Anyone have any ideas?

One day maybe I'll find enough time to learn all this scripting voodoo stuff & work out what's going on myself - but in the mean time any help would be very gratefully received.

Cly.

#2
Morbane

Morbane
  • Members
  • 1 883 messages
iFlag should be FALSE


edit: nvm the second assignment does it...

Modifié par Morbane, 23 septembre 2012 - 10:20 .


#3
Dann-J

Dann-J
  • Members
  • 3 161 messages
Are you creating a single module or a campaign? I've had no problems with it in a single module, but I've never tested it in a campaign. Not that I can think of a reason why it wouldn't work in both.

I used that barkstring script extensively in Isle of Shrines, and it never failed for me during testing.

#4
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages
I think it's the business with the tag. The PC, of course, has no tag, but I'm not sure about player-created party members. I'm not really sure about regular companions, either. Sure, they have a tag in the blueprint, but the command here is GetObjectByTag. Are there any other instances of the companion lying around in limbo somewhere?

#5
Dann-J

Dann-J
  • Members
  • 3 161 messages
I've had no trouble getting regular companions via their blueprint tag (provided there's only one instance of them).

If the string is displaying at all, then oNPC would seem to be a valid object. If it's appearing twice, then (GetIsPC(oNPC) && oNPC != GetFirstPC()) is somehow not setting the 'broadcast to faction' flag to false.

There might be a better 'if' clause that determines whether oNPC is controlled by the first PC, but not the first PC character itself. Perhaps something like:

if ( oNPC == GetControlledCharacter(GetFirstPC()) && oNPC != GetFirstPC() )

Modifié par DannJ, 24 septembre 2012 - 12:50 .


#6
Morbane

Morbane
  • Members
  • 1 883 messages
iFlag should just be FALSE

much simpler than having a test - unless you plan on your mod being multi player - make iFlag = FALSE in all instances

#7
Dann-J

Dann-J
  • Members
  • 3 161 messages
You need the 'broadcast to faction' flag set to TRUE if you want to be able to see the floating text when a companion fires it. Otherwise only the creature who barks can see it, so only those barkstrings the first PC triggers would show up.

It only has to be FALSE if the player is possessing a companion, in which case the text appears for both the player and the companion (ie. twice). The game doesn't recognise that the two are one and the same.

#8
kevL

kevL
  • Members
  • 4 052 messages
i got it to behave as follows:

void main()
{
  object oEnter = GetEnteringObject();
  if (!GetIsObjectValid(GetFactionLeader(oEnter))) return;

  object oBarker = GetObjectByTag("kg_ct_Tiera");

  int iBroadcast = FALSE;
  if ((oEnter == oBarker && oEnter != GetControlledCharacter(GetFirstPC()))
      || (oEnter == GetFirstPC() && oBarker != GetControlledCharacter(GetFirstPC())))
    iBroadcast = TRUE;

  string sBark = "BarkString";
  FloatingTextStringOnCreature(sBark, oBarker, iBroadcast);
}


I also wanted to see what happens with SoZ-playerCreated char's. not nice at all: they caused either a double bark or no bark at all. ( everything was checked with both controlled and uncontrolled oEnters ) Above, relies simply on the Barker not being the FirstPC ... btw, for anyone who doesn't like using GetFirstPC() for arbitrary usage, this might be convenient,

// returns the truePC object of faction oCreature
object kL_GetPC(object oCreature)
{
  object oMaster = GetMaster(oCreature);
  while (GetIsObjectValid(oMaster))
  {
    oCreature = oMaster;
    oMaster = GetMaster(oMaster);
  }

  if (GetIsOwnedByPlayer(oCreature) || GetIsRosterMember(oCreature))
  {
    oCreature = GetFactionLeader(oCreature);
    oCreature = GetOwnedCharacter(oCreature);

    return oCreature;
  }

  return OBJECT_INVALID;
}

:\\

#9
Clyordes

Clyordes
  • Members
  • 300 messages
Thanks for the thoughts so far folks - much appreciated.

Just ran a couple of tests & think I may have an idea why it works in DannJ's own adventure (maybe):
The situation:
3 characters in party - PC, companion 1 (C1) & companion 2 (C2).
Trigger set to fire barkstring when C2 enters

If player in control of PC - all works fine - floaty text appears above C2 as he enters trigger

If player controls C2 - all works fine again

If player controls C1 - floaty text is duplicated when C2 enters trigger

Does that help?

Also - the adventure is a campaign, but I've been testing these scripts in a module.
The companions only have one instance of themselves in the adventure

Does that help at all?

Cly.

#10
Clyordes

Clyordes
  • Members
  • 300 messages
KevL - just seen your post but have to get to work - dang this real life :-)

#11
kevL

kevL
  • Members
  • 4 052 messages
np, i got some aliens to bust up :)

it's that big IF statement that's key

#12
kevL

kevL
  • Members
  • 4 052 messages
// clean'd

// the commented code is useful for ditching GetFirstPC



object kL_GetPC(object oCreature);



void main()

{

  object oEnter = GetEnteringObject();

  if (!GetIsObjectValid(GetFactionLeader(oEnter)))

//  object oPC = kL_GetPC(oEnter);

//  if (!GetIsObjectValid(oPC))

    return;



  object oPC = GetFirstPC();

  object oBarker = GetObjectByTag("kg_ct_Tiera");



  int iBroadcast = FALSE;



  object oControl = GetControlledCharacter(oPC);

  if ((oEnter == oBarker && oEnter != oControl)

      || (oEnter == oPC && oBarker != oControl))

    iBroadcast = TRUE;



  string sBark = "BarkString";

  FloatingTextStringOnCreature(sBark, oBarker, iBroadcast);

}



object kL_GetPC(object oCreature)

{

  object oMaster = GetMaster(oCreature);

  while (GetIsObjectValid(oMaster))

  {

    oCreature = oMaster;



    oMaster = GetMaster(oMaster);

  }



  if (GetIsOwnedByPlayer(oCreature))

  {

    return oCreature;

  }

  else if (GetIsRosterMember(oCreature))

  {

    oCreature = GetFactionLeader(oCreature);

    oCreature = GetOwnedCharacter(oCreature);



    return oCreature;

  }

  else

  {

    return OBJECT_INVALID;

  }

}


#13
Clyordes

Clyordes
  • Members
  • 300 messages
Just tested your latest code - took me a moment to change "kg_ct_Tiera" to the tag of the companion I wanted to bark, but once I did - Awesome! - many thanks KevL

You really ought to submit it to the vault - it definitely does something that NWN2 can't do at the moment - regular speech triggers teleport the main PC to the trigger if you walk into it while controlling a companion, and the only other scripts I've seen duplicate text (at least for me) if a companion triggers them.

I don't know how much scripting knowledge it took to put that code together, but as far as I'm concerned - You are indeed - a scripting god.

Now - on with the bug testing......

Cly.

#14
kevL

kevL
  • Members
  • 4 052 messages
/ one *slightly tarnished* halo for sale


Clyordes wrote...

I don't know how much scripting knowledge it took to put that code together ...

you don't srsly wanna know. Okay, there isn't day spent in the toolset when I don't fold my arms and stare blankly at the screen, thinking "is this worth it?" I keep doing it because i Believe someday I'll know all the bugs & be familiar with all the anomalies and i can just sit down and code and spawn blueprints and tweak terrain (as advertised)

that day ain't here yet.

#15
Clyordes

Clyordes
  • Members
  • 300 messages
:unsure: Something's not right.

I don't know why, as I tested it with a 3 person party last night before I posted I I could have sworn it worked fine, but now its not:
If the main PC walks through the trigger - all's good
If the player is controlling the companion named in the trigger script when they enter the trigger - all's fine
If the player is controlling another companion in the party, the barkstring is duplicated.

How could that suddenly not work right?

Also, I need to add a line that stops the trigger firing for everyone who walks into the trigger - but hopefully I can pinch that from Dannj's script & see where it works in this one.

Will test again tonight to clarify what's going on - as I really don't understand how it could change - I'm assuming I just didn't test properly last night

Cly.

#16
Morbane

Morbane
  • Members
  • 1 883 messages

Clyordes wrote...

I'm assuming I just didn't test properly last night


That sounds like a test to try and duplicate - test the test. 

But it sounds a bit like the script failed - not that you tested wrong - because how could you do that if it is in the game, then it must be possible to happen again.

So, sometimes I think too much goes into scripts for things like triggers, in-game it is over in 5 seconds. But alas; esthetics...

:whistle:

#17
kevL

kevL
  • Members
  • 4 052 messages
here's a novelty:

void main()
{
  object oBarker = GetObjectByTag("kg_ct_Tiera");
  AssignCommand(oBarker, SpeakString("BarkString"));

  DestroyObject(OBJECT_SELF);
}


#18
kevL

kevL
  • Members
  • 4 052 messages
I toyed around with FoatingText some more and basically conclude it should be in the broken functions list ...

#19
Dann-J

Dann-J
  • Members
  • 3 161 messages

kevL wrote...

here's a novelty:

void main()
{
  object oBarker = GetObjectByTag("kg_ct_Tiera");
  AssignCommand(oBarker, SpeakString("BarkString"));

  DestroyObject(OBJECT_SELF);
}


Good idea. I've been increasingly leaning towards SpeakString instead of floating text. The nTalkVolume parameter can be changed to determine the distance from which you can 'hear' the string.

http://www.nwnlexico....php/Talkvolume

#20
Clyordes

Clyordes
  • Members
  • 300 messages
KevL:
void main()
{
object oBarker = GetObjectByTag("kg_ct_Tiera");
AssignCommand(oBarker, SpeakString("BarkString"));

DestroyObject(OBJECT_SELF);
}

Seems to work - this morning at least :-)

Will try again when I get back from work tonight & see what I can do with it

Cly.

#21
kevL

kevL
  • Members
  • 4 052 messages
yeh .. it floats, it's a lot less finicky than FloatingText ( that's for sure ), I notice FloatingText appears static while SpeakStrings drift up ... but i'm sure FloatingText is a throwback from NwN because of the way it doesn't handle roster members well and SpeakString effectively supercedes it

(if anyone wants to play with their floating text more, see 'ftext_styles.2da' - tho i leave mine as is 'cause i like it)

and if you need any he'p with those local_strings haller away at us ....

#22
Clyordes

Clyordes
  • Members
  • 300 messages
Seems - to be working :o

Now to see if I can implement a world map to navigate between the islands that the adventure's set among.

I'm really glad I don't do this for a living - I'd be broke!


Cly.

#23
Dann-J

Dann-J
  • Members
  • 3 161 messages

Clyordes wrote...
If the main PC walks through the trigger - all's good
If the player is controlling the companion named in the trigger script when they enter the trigger - all's fine
If the player is controlling another companion in the party, the barkstring is duplicated.


Argh! That's the one scenario I never tested, and you're right - the script in my module also fails if you're possessing a party member who isn't the barkstring target. Although better to get the string twice than not at all.

I'll certainly be using SpeakString in the future. Unless the story revolves around a group of stuttering companions.

#24
kevL

kevL
  • Members
  • 4 052 messages
- what makes me think it's borked is when the Broadcast flag is switched to try and make it appear only once, it doesn't appear at all

#25
Dann-J

Dann-J
  • Members
  • 3 161 messages
No - because setting it to false only makes it visible to the one character who speaks it. If an actual human being isn't in possession of that character at the time, then no-one sees the text (except for your computer).

The function is certainly borked though, as it can't figure out that sometimes a companion is being possessed by a player, making them two party members at once. It then sends the text both to the companion (which is pointless in a single-player game) and to the player possessing them, resulting in the stutter rap.

Perhaps the function is intended for multi-player games where there are no non-player companions, so every party member has a living person controlling them.