Skip to content

Some tricks with tokens and quasi-interjections

chimericchimeric Member Posts: 1,163
edited September 2017 in General Modding
The token actions, SetToken and SetTokenObject, probably have more potential than I've given them credit for. They may be useful for some involved functions and manipulations with strings, especially in concert with SetName. This action can set the name of a creature to a string of your choice, which may be @ X from the TRA file, and the creature may be an invisible minion. Its original name may be @ Y. Later you'll fetch this string from the name for SetTokenObject. This way you may be able to change strings without rewriting either standards or your custom additions. Tokens aren't saved, but they don't always have to be. For instant actions and interactions they may still be useful, if you remember to give them content anew at the top of the script.

All that may be worth looking into, but as for me, I've used tokens to extend NPC interactions somewhat. As we know, NPC have their own dialogue files, but you aren't going to append to those for small incidents, especially if they are unpredictable and can happen any time. Their special scripts also aren't suited to hold responses to every action in every mod. But NPCs' reactions to events or words may be written out in the scripts of those functions themselves. This way you can get NPC to say something all or part of the time, and, in principle, even force reactions out of them, like, say, Jaheira attacking someone who assaults a non-aggressive bear. If you were to write provisos for this in Jaheira's own script, you would need to cover a lot of ground and likely require definite objects or a monticule of checks. And no one may ever attack a bear in the end. But if you refer to Jaheira inside the bear-attacking script of your new mechanic or scenario, then you've got that grizzly by both paws, so to speak: when that script runs, you have a situation all-ready.

I've only gone as far as to evoke responses to certain endless and maybe annoying versifyng that bards are going to engage in for a mechanic I'm preparing. The bulk of the script has all the cogs and gears, but I added a few "flair" lines. First, though, I had put some other lines to my TRA file, like so:
@1=~<HITTER>~

@2=~he~

@3=~she~

@4=~it~

@5=~his~

@6=~her~

@7=~its~

@8=~And on <HISHER> talons <GABBER>'s head... Eh...

@9=~Enduring woe and during wow, <HESHE>... ate that <HITTER>'s balaclau?~

@10=~I'm not sure about this one. It has a certain... je ne sais quoi.~

@11=~Shut up!~

@12=~Shut your pie hole!~

@13=~I am being tortured. I must have deserved it.~

@14=~There is no hope.~

Now, the purpose of the script is to make bards react to their offenders in a certain way, and the mechanic only needs LastHitter (actually LastHitter(LastSummonerOf(Myself)). Though the AREA slot of the AI is welcoming guests, control should always be from outside, by invisible minions, who will then pull the right strings and display the right strings, too.) But LastHitter is sexless and nameless. The standard tokens are empty outside of dialogues for anyone but CHARNAME. Thus, to describe the one who put the hurt on its master, the bard's little helper needs to fill in a little form very early in the script, on the top or just under, so that the token tags are all nice and filled and can be used downstream wherever. They will, of course, be set to something else when a conversation starts, so we are quite safe kidnapping them for this script run. This portion reads:
IF

True()

THEN

RESPONSE #1

SetTokenObject("GABBER",LastSummonerOf(Myself))
SetTokenObject("HITTER",LastHitter(LastSummonerOf(Myself)))
Continue()

END

IF

Gender(LastSummonerOf(Myself),MALE)

THEN

RESPONSE #1

SetToken("HESHE",@2)
Continue()
END

IF

Gender(LastSummonerOf(Myself),FEMALE)

THEN

RESPONSE #1

SetToken("HESHE",@3)
Continue()
END

IF

!Gender(LastSummonerOf(Myself),MALE)
!Gender(LastSummonerOf(Myself),FEMALE)

THEN

RESPONSE #1

SetToken("HESHE",@4)
Continue()
END

IF

Gender(LastHitter(LastSummonerOf(Myself)),MALE)

THEN

RESPONSE #1

SetToken("HISHER",@5)
Continue()
END

IF

Gender(LastHitter(LastSummonerOf(Myself)),FEMALE)

THEN

RESPONSE #1

SetToken("HISHER",@6)
Continue()
END

IF

!Gender(LastHitter(LastSummonerOf(Myself)),MALE)
!Gender(LastHitter(LastSummonerOf(Myself)),FEMALE)

THEN

RESPONSE #1

SetToken("HISHER",@7)
Continue()
END

Notice how, unlike in conversations, we can point our < HESHE > and < HISHER > tokens (and < HIMHER >, if it comes to that, and any number of custom ones) to different objects. In this case one is for the offender and the other is for LastSummonerOf of the minion, that is, the bard < him >self. The < HITTER > token did not exist in standards, so it had to be created in the TRA. The bard's commentary to the strike will run below in the script:
IF

(Conditions when hit)

THEN

RESPONSE #1

(Reaction)
DisplayString(LastSummonerOf(Myself),@8)
Continue()

RESPONSE #2

(Reaction)
DisplayString(LastSummonerOf(Myself),@9)
DisplayString(LastSummonerOf(Myself),@10)
Continue()

RESPONSE #7

(Reaction)
Continue()

END
I don't want the bard to babble ceaselessly, so about half of the time he will respond silently. (Of course, all of this is just print, though if I wanted to add some VerbalConstant commands to the first two blocks, I could do it without interfering with the bard's programme. VerbalConstant, unlike ActionOverride, does not interrupt actions.) The bard will "speak," that is, display lines that reflect the situation. For example, a barding woman called Felora hit by an otyugh would say one of these two lines: "And on its talons Felora's head... Eh..." or "Enduring woe and during wow, she... ate that Otyugh's balaclau?~ The second line would be followed by the self-commentary.

Now, for quasi-interjections from NPC (and these are real interactions, only outside of dialogue), I put a couple of provisos on the bottom of the script. This potion doesn't matter for the mechanic itself, which has by this point played out one way or another. The minion has done its job and is about to destroy itself. The final block will contain an unequivocal True() and DestroySelf(). But I can make it do a little extra work before it goes, in case there are art aficionados in the party. Kagain and Xan should be particularly appreciative. The tail of the script before the last block is as follows:
IF

InParty("kagain")
!StateCheck("kagain",CD_STATE_NOTVALID)
InMyArea("kagain")

THEN

RESPONSE #1
DisplayString("kagain",@11)
Continue()

RESPONSE #1
DisplayString("kagain",@12)
Continue()

RESPONSE #7
Continue()

END

IF

InParty("xan")
!StateCheck("xan",CD_STATE_NOTVALID)
InMyArea("xan")

THEN

RESPONSE #1
DisplayString("xan",@13)
Continue()

RESPONSE #1
DisplayString("xan",@14)
Continue()

RESPONSE #7
Continue()

END

I could force them into some actions, if they objected very strongly. I could also add more blocks for other NPC. I don't ever have to finish the string-displaying blocks with a DestroySelf() for the minion, I can always write Continue() and add more blocks, so long as the minion gets what is coming to it at the end. I can use tokens in others' strings too, with the same meaning or filled in differently. All of this post-action activity, like a gay home for the elderly, can frolic away an era.
Post edited by chimeric on
Sign In or Register to comment.