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.
Barkstrings revisited
Débuté par
Clyordes
, sept. 23 2012 09:27
#1
Posté 23 septembre 2012 - 09:27
#2
Posté 23 septembre 2012 - 10:18
iFlag should be FALSE
edit: nvm the second assignment does it...
edit: nvm the second assignment does it...
Modifié par Morbane, 23 septembre 2012 - 10:20 .
#3
Posté 23 septembre 2012 - 10:55
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.
I used that barkstring script extensively in Isle of Shrines, and it never failed for me during testing.
#4
Posté 23 septembre 2012 - 11:06
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
Posté 24 septembre 2012 - 12:37
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() )
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
Posté 24 septembre 2012 - 02:42
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
much simpler than having a test - unless you plan on your mod being multi player - make iFlag = FALSE in all instances
#7
Posté 24 septembre 2012 - 04:02
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.
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
Posté 24 septembre 2012 - 06:06
i got it to behave as follows:
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,
:\\
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
Posté 24 septembre 2012 - 06:11
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.
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
Posté 24 septembre 2012 - 06:12
KevL - just seen your post but have to get to work - dang this real life :-)
#11
Posté 24 septembre 2012 - 06:18
np, i got some aliens to bust up 
it's that big IF statement that's key
it's that big IF statement that's key
#12
Posté 24 septembre 2012 - 03:58
// 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
Posté 25 septembre 2012 - 07:35
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.
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
Posté 25 septembre 2012 - 08:47
/ one *slightly tarnished* halo for sale
that day ain't here yet.
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)Clyordes wrote...
I don't know how much scripting knowledge it took to put that code together ...
that day ain't here yet.
#15
Posté 26 septembre 2012 - 06:13
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
Posté 26 septembre 2012 - 06:54
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...
#17
Posté 26 septembre 2012 - 09:00
here's a novelty:
void main()
{
object oBarker = GetObjectByTag("kg_ct_Tiera");
AssignCommand(oBarker, SpeakString("BarkString"));
DestroyObject(OBJECT_SELF);
}
#18
Posté 26 septembre 2012 - 09:03
I toyed around with FoatingText some more and basically conclude it should be in the broken functions list ...
#19
Posté 26 septembre 2012 - 10:43
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
Posté 27 septembre 2012 - 06:10
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.
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
Posté 27 septembre 2012 - 06:30
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 ....
(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
Posté 29 septembre 2012 - 11:43
Seems - to be working 
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.
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
Posté 30 septembre 2012 - 10:48
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
Posté 02 octobre 2012 - 12:22
- 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
Posté 02 octobre 2012 - 01:31
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.
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.





Retour en haut






