@Raduziel: p1 = 50, p2 = 2 is correct, I've tested it by modifying some boots of haste. How are you applying the opcode and to what creature are you doing so?
@Raduziel: p1 = 50, p2 = 2 is correct, I've tested it by modifying some boots of haste. How are you applying the opcode and to what creature are you doing so?
A spell that gives some mental immunities (fear and charm). I'm applying it to a PC in IWDEE with a kit that is immune only to Level Drain and Cold Damage. The spell is attached (I've just tested with p1 = 4 and p2 = 1 and yet the character moves normally).
The .tpa of the kit that receives this effect can be found here.
I mean the only option that's appropriate - the only fragments choice we have. I know it's possible to use for fragments any others, even ghouls flying around and dropping all over the place... The TRAP_SKULL animation doesn't have an INI. Maybe it doesn't do anything that's so special so it doesn't need one? So what would I need to do to add my own simple animation in the next free slot? Your suggestion with 0411 changes an existing slot, I take it. And the INI file needs a preset name in any case, yes?
A lot of the [effect] animations are hardcoded, hence no INI file.
However, it would look almost identical to the file 0410.INI, just with the changes I mentioned (brightness, light_source, multiply_blend, resref).
The name of the INI file is the ANIMATE.IDS slot in hexadecimal, without the leading "0x".
0410.INI represents slot 0x0410 in ANIMATE.IDS. (TRAP_GLYPH)
Find a unoccupied slot in ANIMATE.IDS between 0x0000 and 0x0FFF, skipping those I listed above (they are used by the various hardcoded projectile explosions), as well as any slots that already have a corresponding INI file.
So there is no way to make sure my slot choice doesn't override or gets overriden by others? None of the usual Weidu compatibility stuff?
Right. So I'm putting an INI named 7102 in override with custom references. 0x7102 is a valid slot, right? 0x7100 and 0x7101 are taken up by basilisks, and that's what I'm seeing with my file too.
P.S. And also I want to rewrite one string in the TLK, that unfortunate "Spell Ineffective" message. I'm going to change it to "Unharmed." REPLACE_TEXTUALLY would do it, I think, but what to copy over first? Dialog.tlk is not in override...
I want to make sure I have a good grasp of the multiclass / dualclass systems before I screw around with them in EEex, so here's some questions / assertions:
1) As the IESDP states, dualclass characters are differentiated by one of the 3-8 bits in the CRE's flags being set.
2) If invalid combinations are forced via EEKeeper, it seems that the kit value at offset 0x244 links to the baseclass that it is supposed to affect. Is there any functionality here, or is it purely visual? Also, if a kit is forced that does not pair with the character's baseclass, what happens?
3) Say we have a dual classed character, Fighter 9 / Mage 10. What level are mage spells effectively cast at?
Tagging @kjeron because he knows things no mortal should
2) If invalid combinations are forced via EEKeeper, it seems that the kit value at offset 0x244 links to the baseclass that it is supposed to affect. Is there any functionality here, or is it purely visual? Also, if a kit is forced that does not pair with the character's baseclass, what happens?
A creature's kit, regardless of class:
- affects it's usability using the kit's unusability flags.
- applies hardcoded aspects (specialist save bonus/penalty, shadowdancer hips, barbarian backstab immunity, wildmage surges/bonus spells/casting level)
- is still detectable as the creature's kit through scripts/splprot/opcodes
A multiclass creature with a single class kit matching one of it's respective base classes will run the kit's CLAB file when leveling in the kit's base class. It will ignore the kit's proficiency and HLA entries. Updates the record screen name of only the base class of the kit.
A multiclass creature with a valid multiclass kit will run the CLAB file of each of it's base classes, ignoring the Kit's CLAB file. It will respect the kit's proficiency and HLA entries. It will ignore the kit's HP/level entry. Updates the record screen name of each class and the desc.
3) Say we have a dual classed character, Fighter 9 / Mage 10. What level are mage spells effectively cast at?
Wizard:10 (Mage level), Priest:1, Innate:10 (Average rounded up)
That's an issue I have with some kits on Deities of Faêrun. If a single-class cleric kit uses d10 as Hit Die and multiclasses with Ranger or Fighter, the multiclass version of the kit will ignore the HP entry I give and use a d9 as Hit Die.
@Bubb
If you're looking at extending the kit limit - kit occupying rows 256+ of Kitlist.2da currently crash when they attempt to lookup their CLAB file from kitlist.2da.
Those kit's that do not look up their CLAB file in kitlist.2da don't have this issue - those being the 8 specialists, wildmage, barbarian, and proper mutliclass kits.
Kit rows 16388+ in KITLIST.2da are either ignored or crash, same group as above.
Kit rows 32771+ in KITLIST.2da crash the game at startup regardless.
P.S. And also I want to rewrite one string in the TLK, that unfortunate "Spell Ineffective" message. I'm going to change it to "Unharmed." REPLACE_TEXTUALLY would do it, I think, but what to copy over first? Dialog.tlk is not in override...
That might be confusing if and when players see that in contexts other than your use case...
- Player casts Bless
- feedback: "Unharmed"
- Player: wha?
You are right. Maybe another choice. I'll wait for @kjeron to explain what I'm doing wrong with the animation, though I'm sorry to have to bug him. I also would like to know how container ownership works.
So there is no way to make sure my slot choice doesn't override or gets overriden by others? None of the usual Weidu compatibility stuff?
Well, if a mod just randomly decides to overwrite any IDS entry it wants despite the alternative, then there is only one thing anyone can do about it - don't use that mod.
This will find an unused slot for you and make the necessary edits (fill in the BAM and PRO filenames, and replace the label if "SHRAPNEL" isn't suitable for you).
DEFINE_ACTION_FUNCTION GET_ANIMATE_SLOT INT_VAR min = 0 max = 0xffff STR_VAR label = ~~ RET ids string BEGIN
OUTER_SET ids = ~-1~
OUTER_SPRINT string ~~
ACTION_IF ~%label%~ STRING_EQUAL ~~ OR !(~%label%~ STRING_CONTAINS_REGEXP ~ ~) BEGIN
FAIL ~Invalid ANIMATE label (%label%)~
END
ACTION_IF FILE_CONTAINS_EVALUATED (~ANIMATE.IDS~ ~[%WNL%^]\(0x[0-9A-Z]+\|[0-9]+\)[ %TAB%]+%label%[ %TAB%%WNL%$]~) BEGIN
OUTER_SET ids = IDS_OF_SYMBOL (~ANIMATE~ ~%label%~)
OUTER_SET min = ids OUTER_SET max = ids + 1
END
OUTER_FOR (i = min; i < max + 1; ++i) BEGIN
ACTION_MATCH i WITH 2 3 4 1312 2320 2576 2592 2608 2624 2640 2817 2819 2820 2656 3088 BEGIN END DEFAULT
// Those are the only unlisted ANIMATE entries that I'm aware of having a hardcoded purpose.
OUTER_SPRINT hex ~~
OUTER_SET d = i
OUTER_FOR (j = 0; j < 4; ++j) BEGIN
OUTER_SET r = d MODULO 16
OUTER_SET d = d / 16
OUTER_PATCH_SAVE h ~ ~ BEGIN WRITE_BYTE 0 (r < 10 ? 0x30 + r : 0x37 + r) END
OUTER_SPRINT hex ~%h%%hex%~
END
ACTION_IF ids < 0 BEGIN
ACTION_IF (FILE_EXISTS_IN_GAME ~%hex%.INI~) OR (FILE_CONTAINS_EVALUATED (~ANIMATE.IDS~ ~[%WNL%^]\(0x%hex%\|%i%\)[ %TAB%]+.+~)) BEGIN
END ELSE BEGIN
APPEND ~ANIMATE.IDS~ ~0x%hex% %label%~
OUTER_SPRINT string ~%hex%~
OUTER_SET ids = i
OUTER_SET i = max
END
END ELSE BEGIN
OUTER_SPRINT string ~%hex%~
END
END
END
ACTION_IF ids = ~-1~ BEGIN
WARN ~No available slots between %min% and %max%~
END
END
LAF GET_ANIMATE_SLOT INT_VAR min = 0 max = 0x1000 STR_VAR label = ~SHRAPNEL~ RET ids string END
OUTER_SET resref = ~(desired bam filename no extension)~
COPY_EXISTING ~0410.INI~ ~override/%string%.INI~
REPLACE_TEXTUALLY ~\(%WNL%resref=\).+~ ~\1%resref%~
REPLACE_TEXTUALLY ~\(%WNL%brightest=\)~ ~\10~
REPLACE_TEXTUALLY ~\(%WNL%light_source=\)~ ~\10~
REPLACE_TEXTUALLY ~\(%WNL%multiply_blend=\)~ ~\10~
// The last three are just to remove transparency and added brightness - so black is black.
COPY_EXISTING ~(projectile).pro~ override
WRITE_SHORT 0x212 ids
P.S. And also I want to rewrite one string in the TLK, that unfortunate "Spell Ineffective" message. I'm going to change it to "Unharmed." REPLACE_TEXTUALLY would do it, I think, but what to copy over first? Dialog.tlk is not in override...
I agree with @subtledoctor , something like "Unaffected" would be more appropriate.
The string is defined in row# 130 of ENGINEST.2DA (the labels in this file aren't reliable - the row number is the actual determining factor.)
COPY_EXISTING ~ENGINEST.2DA~ override
COUNT_2DA_COLS cols
READ_2DA_ENTRIES_NOW READ cols
READ_2DA_ENTRY_FORMER READ (130 + 1) 1 strref
// +1 because the file only has 2 columns, so one of the header rows get's included in the count.
BUT_ONLY
STRING_SET strref @1 // tra file with @1=~Unaffected~
Thanks, kjeron. Now to check if the animation displays correctly...
Who can tell me how to patch stores with my items only if they have the right bits set? E.g. sells items, buys items and not a fence? The offset for all of those things is 0x10.
@kjeron: Not sure if any of this will be relevant / new news for you, but typing stuff out helps me organize my thoughts, so here I go. If any of this is wrong, please correct me:
Ok, a long look at the CLAB code confirms that only kits with an IDS value with bit 14 set, (0x4??? in hex), actually get their CLAB file looked-up from KITLIST.2DA.
The engine uses hardcoded CLAB file resrefs for base classes / kits that don't satisfy the above. An Illusionist multiclass will apply CLABMA08.2DA on level-up, though it's a hardcoded resref in this case, as the kit's IDS value is 0x400; the CLAB is stated as CLABMA08.2DA in KITLIST.2DA, but it is non-functional.
If the given kit does not pair with any of the creature's classes, its CLAB is not run. If a kit is found to be valid, and it pairs with the leveling class, its CLAB is applied instead of the base classes'.
Could you specify the source files for a kit's proficiency, HLA, and HP/level entries? Just to make sure I got them all - thanks
@Bubb That all matches observations.
One extra note - at chargen/dualclass, when selecting a kit, you are really selecting a row# from KITLIST.2DA. The kitid actually applied to the creature is that row's final column, which then determines which row of KITLIST.2DA all other values are pulled from. This is how the specialists/wildmage/barbarian assign their kitid, but it also works for any other kit (but not row#0).
- If the last column of row#4 (Cavalier) was changed to 0x4020, you would become a Blackguard when selecting Cavalier at chargen.
The 6th (from 0) column of KITLIST.2da defines the column(-1) of WEAPPROF.2da that is used by the kit.
- BERSERKER lists 29, so it uses the 30th column of WEAPPROF.2da.
Kit's proficiency selection is further limited to the proficiency available to their base class, but not their proficiency limit.
- A cleric kit cannot become proficient with swords unless sword proficiency was made available to the base cleric class, but could grandmaster in maces. The former is an EE-only bug, introduced in v1.3(BG2EE) and v2.0(others).
HLA files are defined in LUABBR.2DA, HP/level is defined in HPCLASS.2DA
The first column is either a CLASSID(possibly hardcoded, never checked) or a kit's ROWNAME (1st column) from KITLIST.2DA. The ROWNAME is linked to each KITID through the final column of KITLIST.2DA. It is NOT linked to the kit's label in KIT.IDS. Again, exceptions are made for the 10 hardcoded kits (specialists,wildmage,barbarian). (case is ignored, Blackguard = BLACKGUARD)
- KITID 0x80 (Conjurer) will always use the "CONJURER" entry in LUABBR.2DA/HPCLASS.2DA.
Please note, if you intend to 'fix' this, it may break a bunch of kit mods that assume the trueclass CLAB tables will be used.
Anything I implement with EEex will either be implemented by default because it doesn't break existing mechanics, or will be implemented with a specific flag that enables the feature on a per-instance basis by the modder. Nothing will break if you use EEex, that would just be absurd and make no one want to use it
You mean...
- WEAPPROF.2DA (proficiencies for every class and kit)
- LUFI01.2DA (HLAs for trueclass fighter - for all classes/kits see LUABBR.2DA)
- HPWAR.2DA (hit dice for warriors... for all classes/kits see HPCLASS.2DA)
Yes, that's what I was looking for. Thanks!
@kjeron: All good info... slowly but surely things are coming into focus.
I ask these questions because I intend to create a new base class that is treated radically different by the existing systems, allowing for a IWD2 type character, or simply a character with any combination of classes and as many kits as they wish. Will be crazy, I probably am crazy...
Comments
A spell that gives some mental immunities (fear and charm). I'm applying it to a PC in IWDEE with a kit that is immune only to Level Drain and Cold Damage. The spell is attached (I've just tested with p1 = 4 and p2 = 1 and yet the character moves normally).
The .tpa of the kit that receives this effect can be found here.
Thanks, @Bubb
Still it moves normally.
I've altered from Opcode 126 to 176.
Still it moves normally.
Damn.
@subtledoctor I'm using 176 because I want it to bypass Free Action. The character is not under any effect other than the attached spell.
Target = 9 was a desperate attempt. Everything was coded as target = 2 (header is Self).
Things are coded that way because I took True Sight as a base.
---
I'll edit the projectile and will report back here.
Thanks!
Anyway, I'll recode the damn thing.
I type shskull there. It's one of the duds.
So there is no way to make sure my slot choice doesn't override or gets overriden by others? None of the usual Weidu compatibility stuff?
Right. So I'm putting an INI named 7102 in override with custom references. 0x7102 is a valid slot, right? 0x7100 and 0x7101 are taken up by basilisks, and that's what I'm seeing with my file too.
P.S. And also I want to rewrite one string in the TLK, that unfortunate "Spell Ineffective" message. I'm going to change it to "Unharmed." REPLACE_TEXTUALLY would do it, I think, but what to copy over first? Dialog.tlk is not in override...
1) As the IESDP states, dualclass characters are differentiated by one of the 3-8 bits in the CRE's flags being set.
2) If invalid combinations are forced via EEKeeper, it seems that the kit value at offset 0x244 links to the baseclass that it is supposed to affect. Is there any functionality here, or is it purely visual? Also, if a kit is forced that does not pair with the character's baseclass, what happens?
3) Say we have a dual classed character, Fighter 9 / Mage 10. What level are mage spells effectively cast at?
Tagging @kjeron because he knows things no mortal should
- affects it's usability using the kit's unusability flags.
- applies hardcoded aspects (specialist save bonus/penalty, shadowdancer hips, barbarian backstab immunity, wildmage surges/bonus spells/casting level)
- is still detectable as the creature's kit through scripts/splprot/opcodes
A multiclass creature with a single class kit matching one of it's respective base classes will run the kit's CLAB file when leveling in the kit's base class. It will ignore the kit's proficiency and HLA entries. Updates the record screen name of only the base class of the kit.
A multiclass creature with a valid multiclass kit will run the CLAB file of each of it's base classes, ignoring the Kit's CLAB file. It will respect the kit's proficiency and HLA entries. It will ignore the kit's HP/level entry. Updates the record screen name of each class and the desc.
That's an issue I have with some kits on Deities of Faêrun. If a single-class cleric kit uses d10 as Hit Die and multiclasses with Ranger or Fighter, the multiclass version of the kit will ignore the HP entry I give and use a d9 as Hit Die.
Never understood where the hell it came from.
If you're looking at extending the kit limit - kit occupying rows 256+ of Kitlist.2da currently crash when they attempt to lookup their CLAB file from kitlist.2da.
Those kit's that do not look up their CLAB file in kitlist.2da don't have this issue - those being the 8 specialists, wildmage, barbarian, and proper mutliclass kits.
Kit rows 16388+ in KITLIST.2da are either ignored or crash, same group as above.
Kit rows 32771+ in KITLIST.2da crash the game at startup regardless.
You are right. Maybe another choice. I'll wait for @kjeron to explain what I'm doing wrong with the animation, though I'm sorry to have to bug him. I also would like to know how container ownership works.
This will find an unused slot for you and make the necessary edits (fill in the BAM and PRO filenames, and replace the label if "SHRAPNEL" isn't suitable for you).
I agree with @subtledoctor , something like "Unaffected" would be more appropriate.
The string is defined in row# 130 of ENGINEST.2DA (the labels in this file aren't reliable - the row number is the actual determining factor.)
Who can tell me how to patch stores with my items only if they have the right bits set? E.g. sells items, buys items and not a fence? The offset for all of those things is 0x10.
Ok, a long look at the CLAB code confirms that only kits with an IDS value with bit 14 set, (0x4??? in hex), actually get their CLAB file looked-up from KITLIST.2DA.
The engine uses hardcoded CLAB file resrefs for base classes / kits that don't satisfy the above. An Illusionist multiclass will apply CLABMA08.2DA on level-up, though it's a hardcoded resref in this case, as the kit's IDS value is 0x400; the CLAB is stated as CLABMA08.2DA in KITLIST.2DA, but it is non-functional.
If the given kit does not pair with any of the creature's classes, its CLAB is not run. If a kit is found to be valid, and it pairs with the leveling class, its CLAB is applied instead of the base classes'.
Could you specify the source files for a kit's proficiency, HLA, and HP/level entries? Just to make sure I got them all - thanks
One extra note - at chargen/dualclass, when selecting a kit, you are really selecting a row# from KITLIST.2DA. The kitid actually applied to the creature is that row's final column, which then determines which row of KITLIST.2DA all other values are pulled from. This is how the specialists/wildmage/barbarian assign their kitid, but it also works for any other kit (but not row#0).
- If the last column of row#4 (Cavalier) was changed to 0x4020, you would become a Blackguard when selecting Cavalier at chargen.
The 6th (from 0) column of KITLIST.2da defines the column(-1) of WEAPPROF.2da that is used by the kit.
- BERSERKER lists 29, so it uses the 30th column of WEAPPROF.2da.
Kit's proficiency selection is further limited to the proficiency available to their base class, but not their proficiency limit.
- A cleric kit cannot become proficient with swords unless sword proficiency was made available to the base cleric class, but could grandmaster in maces. The former is an EE-only bug, introduced in v1.3(BG2EE) and v2.0(others).
HLA files are defined in LUABBR.2DA, HP/level is defined in HPCLASS.2DA
The first column is either a CLASSID(possibly hardcoded, never checked) or a kit's ROWNAME (1st column) from KITLIST.2DA. The ROWNAME is linked to each KITID through the final column of KITLIST.2DA. It is NOT linked to the kit's label in KIT.IDS. Again, exceptions are made for the 10 hardcoded kits (specialists,wildmage,barbarian). (case is ignored, Blackguard = BLACKGUARD)
- KITID 0x80 (Conjurer) will always use the "CONJURER" entry in LUABBR.2DA/HPCLASS.2DA.
Anything I implement with EEex will either be implemented by default because it doesn't break existing mechanics, or will be implemented with a specific flag that enables the feature on a per-instance basis by the modder. Nothing will break if you use EEex, that would just be absurd and make no one want to use it
Yes, that's what I was looking for. Thanks!
@kjeron: All good info... slowly but surely things are coming into focus.
I ask these questions because I intend to create a new base class that is treated radically different by the existing systems, allowing for a IWD2 type character, or simply a character with any combination of classes and as many kits as they wish. Will be crazy, I probably am crazy...