Jump to content

adding innate abilities from a dialogue


subtledoctor

Recommended Posts

Update.

 

SO, I learned that the target is not so important here; you would need to use "LastSummonerOf(Myself)" in the script of an invisible creature, but in a dialogue with that creature, the summoner is actually doing the talking. So you can just use "Myself." Nice.

 

Turns out I already had .spl files for most of the feats which use opcode 171 to grant the feat ability; other feats are just passive bonuses. so for the sake of consistency I just used "DO ~ApplySpellRES(D5SPL1,myself)~" in the dialogue and it all works perfectly.

 

Now I am turning to my psionic abilities. I don't have .spl files that grant these, and they are a bit more complicated: each discipline (say, Telepathy) has an innate ability that uses opcode 214 to use one of the various telepathy abilities listed in a .2da list.

 

Maybe you know Mind Thrust and Id Insinuation; the next time you choose a new feat, local variables will make Mental Domination available to you. If you choose it, I need to remove the Telepathy ability that references the .2da file with two available powers, and add the one that references the .2da file with three powers.

 

Making ~25 .spl files that use opcodes 171/172 for this, to use with "ApplySpellRES" would be kind of terrible. Much easier to handle it in the dialogue itself, with:

~DO AddSpecialAbility("D5SPL3") DO RemoveSpellRES("D5SPL2")~
But that isn't compiling - I'm getting a parse error at that line. Is some kind of particular phrasing necessary here?

 

I also tried

~DO ActionOverride(Myself AddSpecialAbility("D5SPL3")) DO RemoveSpellRES("D5SPL2")~
...but that doesn't work either.

 

Gah. I'm no good at this scripting stuff...

Link to comment

I'm not at my computer so I can't remember if the DO goes inside or outside the ~~... but DO attached to dialogue responses can initiate script actions. That is its purpose here.

 

I have it working with ApplySpellRES(), but when I replace that with AddSpecialAbility() (straight substitution, no other changes) I'm getting parse errors.

 

I realize this is hard to discuss without seeing the code, I'll post a snippet tonight.

Link to comment

Pretty sure you want some variation of:

 

BEGIN hagrid // start HAGRID.DLG

IF ~condition~ THEN BEGIN <<stateLabel>>
/* stateLabel could be a number or a label like 'HagridSaysImAWizard' - labels are converted into numbers during WeiDU COMPILE so they can only be used to refer to states in the same .D file or in other .D files that are listed in the same WeiDU COMPILE action */

  SAY @12345 /* Yer a wizard, Harry. */ /* the creature that has this DLG assigned to it will say this line */

  IF ~~ THEN REPLY @98765 /* Can you teach me some magic? */ /* An IF with blank condition ~~ is always available.  If you want to restrict this condition you can add a Global check inside the first ~~, for example. */
     DO ~AddSpecialAbility("D5SPL3") RemoveSpellRES("D5SPL2")~ /* perform these actions if the player chooses this reply */
  EXIT /* what to do next - in this case, end the dialogue */ 

  IF ~~ THEN REPLY @23432 /* That's physically impossible! */ /* An alternative reply the player can choose, again blank condition means it will always be available. */
  EXIT /* what to do next - in this case, end the dialogue ... you could instead GOTO HagridAsksWhatArePhysics */ 

END
Note there is no DO inside the string of actions; you can use spaces or tabs or new-lines between actions or even mash them all together, because all white space is ignored there unless it is in quotes.

 

As noted, you can replace EXIT with GOTO <<next stateLabel name or number>> if you want the dialogue to continue after.

 

http://www.weidu.org/~thebigg/README-WeiDU.html#transTriggerString is a good reference (see the syntax of the IF statement just above too).

Link to comment

Pretty sure you want some variation of:

 

BEGIN hagrid // start HAGRID.DLG

IF ~condition~ THEN BEGIN <<stateLabel>>
/* stateLabel could be a number or a label like 'HagridSaysImAWizard' - labels are converted into numbers during WeiDU COMPILE so they can only be used to refer to states in the same .D file or in other .D files that are listed in the same WeiDU COMPILE action */

  SAY @12345 /* Yer a wizard, Harry. */ /* the creature that has this DLG assigned to it will say this line */

  IF ~~ THEN REPLY @98765 /* Can you teach me some magic? */ /* An IF with blank condition ~~ is always available.  If you want to restrict this condition you can add a Global check inside the first ~~, for example. */
     DO ~AddSpecialAbility("D5SPL3") RemoveSpellRES("D5SPL2")~ /* perform these actions if the player chooses this reply */
  EXIT /* what to do next - in this case, end the dialogue */ 

  IF ~~ THEN REPLY @23432 /* That's physically impossible! */ /* An alternative reply the player can choose, again blank condition means it will always be available. */
  EXIT /* what to do next - in this case, end the dialogue ... you could instead GOTO HagridAsksWhatArePhysics */ 

END
Note there is no DO inside the string of actions; you can use spaces or tabs or new-lines between actions or even mash them all together, because all white space is ignored there unless it is in quotes.

 

As noted, you can replace EXIT with GOTO <<next stateLabel name or number>> if you want the dialogue to continue after.

 

http://www.weidu.org/~thebigg/README-WeiDU.html#transTriggerString is a good reference (see the syntax of the IF statement just above too).

 

The code by itself it correct, but you are aware who will get the ability in this case. Make sure it is the one you intended it to be, otherwise you need to identify the cre, e.g by ActionOverride("TheCreToGetTheSpell",AddSpecialAbility("D5SPL3")) ActionOverride("TheCreToGetTheSpell",RemoveSpellRES("D5SPL2"))

It is often found in actions (erroneously) coded into dialogues that the action is not executed for the NPC it was intended for.

As an alternative you may just use the dialogue to set a global/local/area-global and have a script do the action.

 

PS In your example above HAGRID willbe the target for the Ability - this may not be the intention, I assume it was aimed at the one he was talking to instead?

 

Like this

BEGIN hagrid

 

IF NumTimesTalkedTo(0)~ THEN BEGIN MayJoin

SAY~You want me to join?~

IF~~THEN REPLY~Yes.~DO~JoinParty()~EXIT

IF~~THEN REPLY~No.~DO~EscapeArea()~EXIT

IF~InParty("Jaheira")~THEN REPLY~Yes, but Jaheira has to leave the party in this case.~DO~ActionOverride("Jaheira",LeaveParty()) JoinParty()~EXIT

END

The join or Escape actions are NOT done by PC, who gives the answer, but by hagrid - he *owns* the dialogue at the moment the DO is triggered.

Link to comment

As I mentioned above, in the case of an invisible creature, we don't have to be worried about this, right? The creature's override script initiates a dialogue with "LastSummonerOf(Myself)"... so when the player clicks the REPLY lines in-game, the DO action will affect that LastSummonerOf.

 

Right?

Link to comment

You would need to use DO ~ActionOverride(LastSummonerOf(Myself), AddSpecialAbility(...)) ActionOverride(LastSummonerOf(Myself), RemoveSpellRES(...))~ in that case.

 

Myself is the creature with dialogue attached (the summoned invisible creature). LastSummonerOf(Myself) therefore is the player.

Link to comment

ApplySpellRES(S:RES*, O:Target)

This action causes the active creature to cast the specified spell at the target object.

 

RemoveSpellRES(S:RES*)

This action removes one memorised indtance of the specified spell from the spellbook of the active creature.

 

ApplySpellRES doesn't need an ActionOverride if you're OK with the caster being the invisible creature and if you put LastSummonerOf(Myself) as the second parameter.

 

RemoveSpellRES needs an ActionOverride because it only has one parameter, the spell resource reference, no target.

Link to comment

SO, I learned that the target is not so important here; you would need to use "LastSummonerOf(Myself)" in the script of an invisible creature, but in a dialogue with that creature, the summoner is actually doing the talking. So you can just use "Myself." Nice.

I missed this. If Myself == the summoner during the dialogue, then you don't need LastSummonerOf. But I would think that Myself would be the player only if the dialog is in Player1.DLG, not in "invisible creature's DLG file" ... is that what you are doing?

Link to comment

Okay, I have access to the files now! So, in answer to questions, I am:

- casting "d5_feat.spl"

- which triggers "d5_feat.eff"

- which summons "d5_feat.cre"

- which has "d5_feat.bcs" as its override script

- which looks like this:

 

 

IF
    Class(LastSummonerOf(Myself),THIEF)
    Kit(LastSummonerOf(Myself),D5_PSYPHER)
    NumTimesTalkedTo(0)
THEN
    RESPONSE #100
    SetGlobal("D5_FPSI","GLOBAL",1)
    SetNumTimesTalkedTo(1)
    ActionOverride(LastSummonerOf(Myself),StartDialogOverride("d5_psyph",Myself))
END
 
IF
    True()
THEN
    RESPONSE #100
    SetGlobal("D5_FPSI","GLOBAL",0)
    SetNumTimesTalkedTo(0)
    DestroySelf()               // reset global variable, then destroy self
END

 

 

 

Note, it uses "ActionOverride(LastSummonerOf(Myself))" because the script belongs to the invisicre.

 

The dialog initiated comes from "d5_psyph.d" which I assume compiles to "d5_psych.dlg." That looks like this:

 

 

BEGIN ~D5_PSYPH~

IF ~Global("D5_FPSI","GLOBAL",1)~ THEN BEGIN d5_psyph
 SAY ~Choose an ability:~
 IF ~GlobalLT("D5_PS102","LOCALS",1)~ THEN REPLY @20606 GOTO d5_psyph_1    //    id insinuation
 IF ~Global("D5_PS102","LOCALS",1)~ THEN REPLY @20609 GOTO d5_psyph_2    //    domination
END
 
IF ~~ THEN BEGIN d5_psyph_1 // id insinuation
 SAY @20607
 IF ~~ THEN REPLY ~Choose this feat~ DO ~IncrementGlobal("D5_PS102","LOCALS",1)~ DO ~ApplySpellRES(D5_PSA2,Myself)~ EXIT
 IF ~~ THEN REPLY ~Pick a different feat~ GOTO d5_psyph
END
IF ~~ THEN BEGIN d5_psyph_2 // domination
 SAY @20610
 IF ~~ THEN REPLY ~Choose this feat~ DO ~IncrementGlobal("D5_PS103","LOCALS",1)~ DO ~AddSpecialAbility("D5PS103") DO ~RemoveSpellRES("D5PSA02")~ EXIT
 IF ~~ THEN REPLY ~Pick a different feat~ GOTO d5_psyph
END

 

 

 

...Aaaaand, wait for it - it all works now. The parse error was from an unclosed quote " that I had missed.

 

Anyway, thanks for sharing, folks!

Link to comment

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...