subtledoctor Posted November 15, 2016 Author Share Posted November 15, 2016 Perfect. I should be ready to actually code it up this weekend. Link to comment
subtledoctor Posted November 29, 2016 Author Share Posted November 29, 2016 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
subtledoctor Posted November 29, 2016 Author Share Posted November 29, 2016 Roxanne do you have anything to say? Not sure why you seem to be spamming my thread with empty posts... (Maybe there's a reason, I'm just saying it confuses me.) Link to comment
Avenger Posted November 29, 2016 Share Posted November 29, 2016 DO is a weidu keyword, what does it do inside a string? Link to comment
subtledoctor Posted November 29, 2016 Author Share Posted November 29, 2016 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
agb1 Posted November 29, 2016 Share Posted November 29, 2016 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
Roxanne Posted November 29, 2016 Share Posted November 29, 2016 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
subtledoctor Posted November 29, 2016 Author Share Posted November 29, 2016 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
agb1 Posted November 29, 2016 Share Posted November 29, 2016 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
subtledoctor Posted November 30, 2016 Author Share Posted November 30, 2016 I'm not sure that's correct. Because, why does ApplySpellRES work without specifying LastSummonerOf as a target? Link to comment
agb1 Posted November 30, 2016 Share Posted November 30, 2016 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
agb1 Posted November 30, 2016 Share Posted November 30, 2016 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
Fiann of the Silver Hand Posted November 30, 2016 Share Posted November 30, 2016 This mod does what you want, I think; specifically, the totemic druid kit. Applies some bonuses via dialog choice at character start (postgen), then at level 13 adds more based on the previous choice. http://www.mediafire.com/file/vj699du6a4ka55j/phord_druidkits.zip Link to comment
subtledoctor Posted November 30, 2016 Author Share Posted November 30, 2016 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
Recommended Posts
Archived
This topic is now archived and is closed to further replies.