Fine, I figured out what to do with colors. Briefly, when added color stops in a reply line, the rest of the line turns white, the color of the SAY state. It takes another color tag to turn the remainder of the line into the proper shade of red, which is 1D28FFA (color hex code). For example, this is the way to have the first words in yellow and the rest the usual reply color (the hex codes need to be prefaced with FF):
THEN REPLY ~^0xFF34E2EA (Use Kazaker's system)^- ^0xFF1D28FFA 50 gold.^-
The spaces need to be as I show here. Incidentally I discovered the engine doesn't want to see words in brackets: [This will not be shown]
But now I have another question, unrelated. How does LeaveAreaLUAEntry work? Do I need to set up an arrival point somehow if I want to teleport the party somewhere out of the area?
EDIT: Inserted a more exactly matching shade of red for the text (color hex code).
I want to apply a spell effect with Weidu to a creature instead of making it equip an item that casts the effects on it. Direct is better. @Galactygon told me about LPF ~ADD_SPELL_EFFECT~, I'll call on him here. Can I get an example? So far I have this:
COPY_EXISTING ~IRONELIT.cre~ ~override~ // Blacktalon Elite PATCH_IF (SOURCE_SIZE > 0x2d0) THEN BEGIN LPF ~ADD_CRE_EFFECT~ INT_VAR opcode = 146 target = 1 power = 1 timing = 9 duration = 0 resource = RESOLVE_STR_REF (~IRONE+_#~) resist_dispel = 0 END END BUT_ONLY
At Spellhold you told me to use ADD_SPELL_EFFECT, Galactygon. It took me a long time and a headache to figure out that was wrong. The Weidu documentation says nothing about this too, like it does about most things. I wish people would double-check before giving advice. I appreciate it, but a mistake like that can cost half a day's work to someone new to coding.
Well, the code above compiles and runs together with everything else, no errors, and an effect appears. It lacks version and signature (might not be important, never mind that) and the resource, the spell name, is wrong. I guess I have to get the string inside in some other way? It's a nested structure, too, the details are called "2nd level."
RESOLVE_STR_REF is used to transform .tlk text into numeric strref. "Resource" in spl/cre/etc. effects is an actual string, not a string reference - since it's a filename rather than in-game text. WeiDU functions use INT_VAR to define numeric variables and STR_VAR for strings.
When naming any files you should try avoiding using any of the characters $^.*+?[]\ that could be used in regexps. See more on regexps in WeiDU here.
You can also read the wikipedia entry on what regular expressions are in general here. There are some good examples there that you can adapt to WeiDU. They are not 100% the same, although they do overlap for the most part. For example, (foo|bar) would be written as \(foo\|bar\) in WeiDU which matches either the strings "foo" or "bar".
Thanks to you both. I'll try Ardanis' code. My personal suffix is _# though, there is no helping that.
Okay, I tried the code. It works and the creatures apply the effect to themselves, but you've got to select "Cast instantly" in the opcode 146. With "Cast normally" the creatures spawn unchanged and apply the spell to themselves a second later - even if the casting time is 0. I changed it manually, what is the parameter called for Weidu?
Thanks again. Now is the time to ask how I can replace a creature's item (equipped) with another? I have the code for adding an item, thanks to Imp at Spellhold, but Watchers need a new and antique helmet design.
You know, this is probably what wizardry is like. You pick a bit of syntax here, a bit there. But creativity begins later.
If you mean at install, then REPLACE_CRE_ITEM is much the same as adding one. If you mean randomly in-game, then it seems you've already figured the possibilities and limitations out on SHS.
I'm still figuring, but I guess the replace code ought to do it.
Say, you don't know what's up with the Ignore Reputation Breaking Point opcode, do you? It seems impossible to remove. I've tried all sorts of settings, it's just stuck. NPC complain furiously, with my mod anyway, but never start leaving again, whatever your reputation.
1. Anyone know how global variable timers are stored in EE/Shadowkeeper? A script setting a global timer for ONE_DAY reads 7200 seconds in GTIMES.IDS, but will read something along the lines of 1.48 million in EE keeper. If it was milliseconds it would just be 7.2 million so it can't be milliseconds. Is it seconds*205 or something?
2. How is success rate determined in the thief stronghold tasks and how would one go about altering it? One relevant file is SHTHLT01.DLG but I'm not sure what to change in that(if at all).
1. Anyone know how global variable timers are stored in EE/Shadowkeeper? A script setting a global timer for ONE_DAY reads 7200 seconds in GTIMES.IDS, but will read something along the lines of 1.48 million in EE keeper. If it was milliseconds it would just be 7.2 million so it can't be milliseconds. Is it seconds*205 or something?
It stores the exact in-game time that it will expire, in ticks, which are 15:1 second. 1.48M ~ Day 13, Hour 17.
On another topic: I think I finally found a way to Animate Dead. In a manner of shambling. To cast a spell on a corpse is still out of the question, but Animate Dead can be a preparation spell that turns all creatures that you slay while it lasts into undead or raises them as monsters. They have to be killed first, but once they have been, they will come back for you. This can be done with a contingency within a contingency: the first one triggers when anyone is in a custom spell state - the one for Animate Dead - and activates the second one, which can raise or replace the creature once it has died. Raising is better, because the creature can be changed at the same time to be Controlled and to be Undead but otherwise can stay as it was - even keep its name. His/her name.
Patch all flesh creatures with this contingency and there you have it.
Also when they come back for the second time they mutate so beautifully. The color of their clothes spreads to their bodies, a sort of shining meat-brass for the girl I experimented on, and there is nothing human about them anymore...
Oh yes, and companions should be killed as well and kept in the party as undead servants. Wouldn't an undead Edwin be even more useful?
Gameplay wise-I want a solo run. BUT I enjoy the banters and interjections.
So I can easily grab 6 party members, set 5 of them to passive, and just play my one solo guy. I can mod their minimum health to 1 and leave them as invincible non-combat "banter dummies".
The problem is experience, they will still leech it. Is there any way to flat-out multiply exp-received? If not, anyone know of a simple, easily reversible way to do this?
There's the obviously hard way, which is to alter all quest rewards and monster exp rewards in every .cre file which I'm not going to do.
Other than that, I can periodically tally up the exp that the party members have, and add them into the main character, removing any pre-join exp and individual quest exp, effectively simulating solo exp.
My question: does the order of states in a dialogue matter? I've always thought that states without conditions, triggers, ones only linked to from other states or other dialogues, can be placed anywhere - on top, on the bottom, in-between. The engine is not going to pick or display them except as linked, I thought. But it seems I was wrong. I'm rewriting the dialogues of Duke Belt and Duchess Liia, and I discovered that their states need to be on top of the file to work - even though they have no actual conditions. Like so, in Liia's file:
IF ~~ THEN BEGIN 0 /// from a ready TLK entry SAY ~As all of you know, this a special occasion for the city...~
Here she only continues after Belt, who starts that entire conversation. In Belt's file the first state ends with an EXTERN ~LIIA~ 0, prompting her to speak. And in my editing I had not renamed this state in Liia's, but I had moved it out of sight to the bottom of the pile, since this is not a top-level node. But it did not work there - instead Belt's file began to link to what was the new top node in Liia's file, even though it was not named 0 and its conditions were not even met! I had to bring up state 0 to the top again, and I'm afraid I'm going to have to move the other numbered states, none of them top-level, back to their places. Why is it happening?
Best way to update 2DA values based on row and column name?
Hopefully this is the right place to ask...
So, I've got both Sarvok67's Mega IWD Mod and Faith and Powers (FnP) installed. Since Sarevok57's mod increases max bow proficiencies for the built-in Archer kit to 7 ("Supreme Mastery"), I want the Archer-variants added by FnP to get the same benefit, and instead of just editing weapprof.2da by hand, I'm trying to do it with WeiDu, both so that I have it for future use and as a learning excercise.
When I saw the SET_2DA_ENTRY function in the WeiDU readme, I thought this would be easy:
BEGIN ~Adapt Faith and Powers kits to Sarvok67's Mega IWD Mod~ DESIGNATED 250
COPY_EXISTING ~weapprof.2da~ ~override~
// Elven Archer
SET_2DA_ENTRY ~CROSSBOW~ ~D5EARCH~ 7 // Not actual WeiDU code, sadly!
SET_2DA_ENTRY ~LONGBOW~ ~D5EARCH~ 7
SET_2DA_ENTRY ~SHORTBOW~ ~D5EARCH~ 7
// Halfling Slinger
SET_2DA_ENTRY ~SLING~ ~D5SLING~ 7
// Woodscout of Mielikki
SET_2DA_ENTRY ~LONGBOW~ ~D5_CR_MIELI~ 7
SET_2DA_ENTRY ~SHORTBOW~ ~D5_CR_MIELI~ 7
BUT_ONLY
Alas, that doesn't work. Turns out the name "SET_2DA_ENTRY" is a lie - that function doesn't actually understand the 2DA table format, it simply treats the input as space and newline separated data with no regard for what is a 2DA format header, column name, row name, and actual value... and thus requires numerical row and column indices as input (and a "minimum column count" that can be used as a hack to skip the 2DA header).
Based on the tutorials in the WeiDU readme, I've managed to piece together the following code to solve the task at hand:
DEFINE_PATCH_MACRO ~parse_2da_headers~ BEGIN
// Build the array $column_index, mapping from column names to their indices
COUNT_2DA_COLS columns
READ_2DA_ENTRIES_NOW rows (columns - 1)
FOR (column = 1; column < columns; ++column) BEGIN
READ_2DA_ENTRY_FORMER rows 0 (column - 1) name
SPRINT $column_index("%name%") "%column%"
END
// Build the array $row_index, mapping from row names to their indices
FOR (row = 0; row < (rows - 1); ++row) BEGIN
READ_2DA_ENTRY_FORMER rows (row + 1) 0 name
SPRINT $row_index("%name%") "%row%"
END
END
BEGIN ~Adapt Faith and Powers kits to Sarvok67's Mega IWD Mod~ DESIGNATED 250
COPY_EXISTING ~weapprof.2da~ ~override~
LAUNCH_PATCH_MACRO ~parse_2da_headers~
// Elven Archer
SET_2DA_ENTRY_LATER ~weapprof~ $row_index(LONGBOW) $column_index(D5EARCH) 7
SET_2DA_ENTRY_LATER ~weapprof~ $row_index(SHORTBOW) $column_index(D5EARCH) 7
SET_2DA_ENTRY_LATER ~weapprof~ $row_index(CROSSBOW) $column_index(D5EARCH) 7
// Halfling Slinger
SET_2DA_ENTRY_LATER ~weapprof~ $row_index(SLING) $column_index(D5SLING) 7
// Woodscout of Mielikki
SET_2DA_ENTRY_LATER ~weapprof~ $row_index(LONGBOW) $column_index(D5_CR_MIELI) 7
SET_2DA_ENTRY_LATER ~weapprof~ $row_index(SHORTBOW) $column_index(D5_CR_MIELI) 7
SET_2DA_ENTRIES_NOW ~weapprof~ columns
BUT_ONLY(The pre-processing factored out into a macro so I can re-use it if I add additional similar component to the mod.)
It seems to work... but feels excessively verbose and error-prone. (I had to tweak it a few times to stomp out off-by-one errors, that's what all the -1 and +1 are for.)
So I'm wondering if this is really the correct/best way to do this.
Is there no safer / more convenient way to accomplish this simple task?
My question: does the order of states in a dialogue matter?
Do you, by chance, use syntax like this?
COMPILE liia.d
COMPILE belt.d
I don't remember if it's supposed to be happening (WeiDU is not very systematic when it comes to cleaning memory), but sounds like WeiDU is compiling both files separately, i.e. when you get to the EXTERN liia 0, the contents of liia.dlg are reloaded and return whatever it currently has at the top.
If that's the case, then this should resolve the issue
It seems to work... but feels excessively verbose and error-prone. (I had to tweak it a few times to stomp out off-by-one errors, that's what all the -1 and +1 are for.)
So I'm wondering if this is really the correct/best way to do this.
Is there no safer / more convenient way to accomplish this simple task?
To @Ardanis : I'll try that. Usually I just compile the entire mod's folder, as you've taught me a long time ago, but that keeps turning my BAFs used to extend scripts into stand-alone BCS files just cluttering Override. So now I write things out line by line...
Hi there I have a question which I have so far found no answer to. Is it possible to remove or overide an ability for example with the clab file on level up? I'm trying to make a kit where certain abilities upgrade but for this to work I have to remove the less powerful version of the ability obtained at an earlier level. Any ideas how this can be done?
So far I have only been able to add abilities and this leads the kit to have the higher level version of an ability and at the same time keep the lower versions as well which is not satisfactory for the design of the kit.
If the ability is an SPL file, you can create a different Spell ability within that SPL for a higher caster level. Just look at one of the spells that scale, like Magic Missile.
If the ability is an SPL file, you can create a different Spell ability within that SPL for a higher caster level. Just look at one of the spells that scale, like Magic Missile.
I dont see how that can work very well for kit abilities. My example: On level 1 an ability is gained that applies a reapting EFF file permanantly. On level 5 that same ability is meant to upgrade in the frequency of EFF file repeating. Say from once every 10 rounds to once every 9 rounds. I just can't see a way so far to get rid of the first instance of the ability. I can add both but then I have the EFF file repeated twice within 10 rounds which is far too powerful.
The solution you suggest only works for abilities that are not permanant but are time limited, which defies my goal of having a passive class ability that is there all the time and which improves as you level up.
@fortyseven Lead every ability level with Opcode 321, target (self), resource (itself), probability1(100), all other fields 0(zero). This will remove its effects before applying them anew at the higher level.
Yup, do that. And while you're here, kjeron, do you know how to write the syntax the way Ardanis suggested? He says I ought to compile the dialogues in the form of
COMPILE liia.d belt.d
So, two of them after the same compile. But I don't see how to write it out this way, without quotes or tildas. We're talking about the tp2, right? I have them as
Comments
THEN REPLY ~^0xFF34E2EA (Use Kazaker's system)^- ^0xFF1D28FFA 50 gold.^-
The spaces need to be as I show here. Incidentally I discovered the engine doesn't want to see words in brackets: [This will not be shown]
But now I have another question, unrelated. How does LeaveAreaLUAEntry work? Do I need to set up an arrival point somehow if I want to teleport the party somewhere out of the area?
EDIT: Inserted a more exactly matching shade of red for the text (color hex code).
COPY_EXISTING ~IRONELIT.cre~ ~override~ // Blacktalon Elite
PATCH_IF (SOURCE_SIZE > 0x2d0) THEN BEGIN
LPF ~ADD_CRE_EFFECT~ INT_VAR opcode = 146 target = 1 power = 1 timing = 9 duration = 0 resource = RESOLVE_STR_REF (~IRONE+_#~) resist_dispel = 0 END
END
BUT_ONLY
At Spellhold you told me to use ADD_SPELL_EFFECT, Galactygon. It took me a long time and a headache to figure out that was wrong. The Weidu documentation says nothing about this too, like it does about most things. I wish people would double-check before giving advice. I appreciate it, but a mistake like that can cost half a day's work to someone new to coding.
Well, the code above compiles and runs together with everything else, no errors, and an effect appears. It lacks version and signature (might not be important, never mind that) and the resource, the spell name, is wrong. I guess I have to get the string inside in some other way? It's a nested structure, too, the details are called "2nd level."
40Ch (1036), 8 bytes.
Should be
RESOLVE_STR_REF is used to transform .tlk text into numeric strref. "Resource" in spl/cre/etc. effects is an actual string, not a string reference - since it's a filename rather than in-game text. WeiDU functions use INT_VAR to define numeric variables and STR_VAR for strings.
You can also read the wikipedia entry on what regular expressions are in general here. There are some good examples there that you can adapt to WeiDU. They are not 100% the same, although they do overlap for the most part. For example, (foo|bar) would be written as \(foo\|bar\) in WeiDU which matches either the strings "foo" or "bar".
Okay, I tried the code. It works and the creatures apply the effect to themselves, but you've got to select "Cast instantly" in the opcode 146. With "Cast normally" the creatures spawn unchanged and apply the spell to themselves a second later - even if the casting time is 0. I changed it manually, what is the parameter called for Weidu?
You know, this is probably what wizardry is like. You pick a bit of syntax here, a bit there. But creativity begins later.
If you mean randomly in-game, then it seems you've already figured the possibilities and limitations out on SHS.
Say, you don't know what's up with the Ignore Reputation Breaking Point opcode, do you? It seems impossible to remove. I've tried all sorts of settings, it's just stuck. NPC complain furiously, with my mod anyway, but never start leaving again, whatever your reputation.
I could sell it as a feature rather than a bug...
2. How is success rate determined in the thief stronghold tasks and how would one go about altering it? One relevant file is SHTHLT01.DLG but I'm not sure what to change in that(if at all).
1.48M ~ Day 13, Hour 17.
Patch all flesh creatures with this contingency and there you have it.
Also when they come back for the second time they mutate so beautifully. The color of their clothes spreads to their bodies, a sort of shining meat-brass for the girl I experimented on, and there is nothing human about them anymore...
Oh yes, and companions should be killed as well and kept in the party as undead servants. Wouldn't an undead Edwin be even more useful?
Gameplay wise-I want a solo run. BUT I enjoy the banters and interjections.
So I can easily grab 6 party members, set 5 of them to passive, and just play my one solo guy. I can mod their minimum health to 1 and leave them as invincible non-combat "banter dummies".
The problem is experience, they will still leech it. Is there any way to flat-out multiply exp-received? If not, anyone know of a simple, easily reversible way to do this?
There's the obviously hard way, which is to alter all quest rewards and monster exp rewards in every .cre file which I'm not going to do.
Other than that, I can periodically tally up the exp that the party members have, and add them into the main character, removing any pre-join exp and individual quest exp, effectively simulating solo exp.
IF ~~ THEN BEGIN 0 /// from a ready TLK entry
SAY ~As all of you know, this a special occasion for the city...~
Here she only continues after Belt, who starts that entire conversation. In Belt's file the first state ends with an EXTERN ~LIIA~ 0, prompting her to speak. And in my editing I had not renamed this state in Liia's, but I had moved it out of sight to the bottom of the pile, since this is not a top-level node. But it did not work there - instead Belt's file began to link to what was the new top node in Liia's file, even though it was not named 0 and its conditions were not even met! I had to bring up state 0 to the top again, and I'm afraid I'm going to have to move the other numbered states, none of them top-level, back to their places. Why is it happening?
Best way to update 2DA values based on row and column name?
Hopefully this is the right place to ask...So, I've got both Sarvok67's Mega IWD Mod and Faith and Powers (FnP) installed.
Since Sarevok57's mod increases max bow proficiencies for the built-in Archer kit to 7 ("Supreme Mastery"), I want the Archer-variants added by FnP to get the same benefit, and instead of just editing weapprof.2da by hand, I'm trying to do it with WeiDu, both so that I have it for future use and as a learning excercise.
When I saw the SET_2DA_ENTRY function in the WeiDU readme, I thought this would be easy:
BEGIN ~Adapt Faith and Powers kits to Sarvok67's Mega IWD Mod~ DESIGNATED 250 COPY_EXISTING ~weapprof.2da~ ~override~ // Elven Archer SET_2DA_ENTRY ~CROSSBOW~ ~D5EARCH~ 7 // Not actual WeiDU code, sadly! SET_2DA_ENTRY ~LONGBOW~ ~D5EARCH~ 7 SET_2DA_ENTRY ~SHORTBOW~ ~D5EARCH~ 7 // Halfling Slinger SET_2DA_ENTRY ~SLING~ ~D5SLING~ 7 // Woodscout of Mielikki SET_2DA_ENTRY ~LONGBOW~ ~D5_CR_MIELI~ 7 SET_2DA_ENTRY ~SHORTBOW~ ~D5_CR_MIELI~ 7 BUT_ONLY
Alas, that doesn't work. Turns out the name "SET_2DA_ENTRY" is a lie - that function doesn't actually understand the 2DA table format, it simply treats the input as space and newline separated data with no regard for what is a 2DA format header, column name, row name, and actual value... and thus requires numerical row and column indices as input (and a "minimum column count" that can be used as a hack to skip the 2DA header).
Based on the tutorials in the WeiDU readme, I've managed to piece together the following code to solve the task at hand:
DEFINE_PATCH_MACRO ~parse_2da_headers~ BEGIN // Build the array $column_index, mapping from column names to their indices COUNT_2DA_COLS columns READ_2DA_ENTRIES_NOW rows (columns - 1) FOR (column = 1; column < columns; ++column) BEGIN READ_2DA_ENTRY_FORMER rows 0 (column - 1) name SPRINT $column_index("%name%") "%column%" END // Build the array $row_index, mapping from row names to their indices FOR (row = 0; row < (rows - 1); ++row) BEGIN READ_2DA_ENTRY_FORMER rows (row + 1) 0 name SPRINT $row_index("%name%") "%row%" END END BEGIN ~Adapt Faith and Powers kits to Sarvok67's Mega IWD Mod~ DESIGNATED 250 COPY_EXISTING ~weapprof.2da~ ~override~ LAUNCH_PATCH_MACRO ~parse_2da_headers~ // Elven Archer SET_2DA_ENTRY_LATER ~weapprof~ $row_index(LONGBOW) $column_index(D5EARCH) 7 SET_2DA_ENTRY_LATER ~weapprof~ $row_index(SHORTBOW) $column_index(D5EARCH) 7 SET_2DA_ENTRY_LATER ~weapprof~ $row_index(CROSSBOW) $column_index(D5EARCH) 7 // Halfling Slinger SET_2DA_ENTRY_LATER ~weapprof~ $row_index(SLING) $column_index(D5SLING) 7 // Woodscout of Mielikki SET_2DA_ENTRY_LATER ~weapprof~ $row_index(LONGBOW) $column_index(D5_CR_MIELI) 7 SET_2DA_ENTRY_LATER ~weapprof~ $row_index(SHORTBOW) $column_index(D5_CR_MIELI) 7 SET_2DA_ENTRIES_NOW ~weapprof~ columns BUT_ONLY
(The pre-processing factored out into a macro so I can re-use it if I add additional similar component to the mod.)It seems to work... but feels excessively verbose and error-prone. (I had to tweak it a few times to stomp out off-by-one errors, that's what all the -1 and +1 are for.)
So I'm wondering if this is really the correct/best way to do this.
Is there no safer / more convenient way to accomplish this simple task?
If that's the case, then this should resolve the issue Nope, that's as far as you can do.
So far I have only been able to add abilities and this leads the kit to have the higher level version of an ability and at the same time keep the lower versions as well which is not satisfactory for the design of the kit.
COMPILE ~Wanted Charname/BELT.d~ EVAL
COMPILE ~Wanted Charname/LIIA.d~ EVAL
So I can't combine them.
Another thing: do you know how to put new states on top of a dialogue? APPEND puts them on the bottom.
The solution you suggest only works for abilities that are not permanant but are time limited, which defies my goal of having a passive class ability that is there all the time and which improves as you level up.
COMPILE liia.d
belt.d
So, two of them after the same compile. But I don't see how to write it out this way, without quotes or tildas. We're talking about the tp2, right? I have them as
COMPILE ~Wanted Charname/liia.d~ EVAL
COMPILE ~Wanted Charname/belt.d~ EVAL
COMPILE EVAL ~Wanted Charname/liia.d~ ~Wanted Charname/belt.d~
If not then I don't know.