Jump to content

IWDEE: new IDS/2DA tables


CamDawg

Recommended Posts

Posted

New iDS/2DA files for IWDEE. I'll post some IDS defaults when I get home later.

 

IDS:

  • EXTSTATE.IDS used by the ExtStateCheck (0x40E1) trigger.
    Contains single bits of a bitfield. These 32 bits are simulating the HoW extended state field. In fact, our engine implements the extended states as a subset of the 256 spell states.
  • SPLSTATE.IDS used by the CheckSpellState (0x40E2) trigger.
    The actual spell states, as used by IWD2. The HoW extended states were fully mapped into these.
    I've deleted states that are used only in IWD2, it is recommended to use the same values as in IWD2 for the same state for better compatibility.
    The EE has some of these hardcdoded, don't change states without checking.
  • MAPNOTES.IDS used by AddMapNoteColor (308) action.
    The color values (frame indices) for the mapnote icon.

2da:

  • splprot.2da is used for stat/state based targeting and immunities. It could be used in opcodes and projectiles.
  • 7eyes.2da is used for opcode 335 (Seven Eyes), to determine which opcodes/spells are absorbed by a particular eye.
  • IWDPARTY.2da is used for determining which CRE make up the default party in IWD
  • HOWPARTY.2da is used for determining which CRE make up the default party in HoW
  • IWDPLOT.2da is used for determining which items will be removed from the party at the start of IWD via TakeItemListPartyNum("IWDPLOT",99)
  • HOWPLOT.2da is used for determining which items will be removed from the party at the start of HoW via TakeItemListPartyNum("HOWPLOT",99)
  • AREANODE.2da is used for determining which areas should use different pathfinding values for enemies

splprot.2da:

 

Borrowed from GemRB, this table externalizes spell protections. Every row is a protection type indexed by opcode 318/324/326 or a projectile's ids field

 

STAT is either a straight stat value (listed in stat.ids) or a pseudo stat of the to be targeted creature.

  • 0x100 - source equals target
  • 0x101 - source is not target
  • 0x102 - circlesize
  • 0x103 - use two rows of splprot.2da
  • 0x104 - negate 0x103
  • 0x105 - source and target morale match
  • 0x106 - areatype (like outdoors, forest, etc)
  • 0x107 - daytime
  • 0x108 - source and target ethical match
  • 0x109 - evasion
  • 0x10a - EA
  • 0x10b - GENERAL
  • 0x10c - RACE
  • 0x10d - CLASS
  • 0x10e - SPECIFIC
  • 0x10f - GENDER
  • 0x110 - ALIGNMENT
  • 0x111 - STATE
  • 0x112 - SPELL STATE
  • 0x113 - source and target allies
  • 0x114 - source and target enemies

VALUE is a number used to compare to the stat using a relational operator. Depending on the stat/operator it could be a bit value (hexadecimal is allowed).

If value is set to -1, then param1 of the calling spell will be used. So it is not needed to set up various lines for every value.

 

RELATION is an index to a relational operator

  • 0 - less or equal
  • 1 - equal
  • 2 - less
  • 3 - greater
  • 4 - greater or equal
  • 5 - not equal
  • 6 - binary less or equal (stat doesn't contain extra bits not in value)
  • 7 - binary more or equal (stat contains all bits of value)
  • 8 - binary match (at least one bit is common)
  • 9 - binary not match (none of the bits are common)
  • 10 - binary more (stat contains at least one bit not in value)
  • 11 - binary less (stat doesn't contain all the bits of value)

7eyes.2da

 

This table lists options to opcode 335 (Seven Eyes). Each row stands for an eye effect (the labels are only informal, the engine uses the row index).

 

STATE - a spell state associated with the eye

STRREF - strref printed when the eye absorbs a spell

numeric columns (extendable at will)

  • an opcode
  • an opcode/param2 pair separated by a *
  • a spell resref

The eye will absorb the incoming opcode/spell and vanish. In case of an opcode, any effect coming from the same spell will be ignored as well.

 

iwdparty/howparty.2da

 

Default starting creature files for a new IWD or HoW game:

2DA V1.0

    CHAR
0       BPARTY01
1       BPARTY02
2       BPARTY03
3       BPARTY04
4       BPARTY05
5       BPARTY06

IWDPLOT/HOWPLOT.2da

 

List of items to be deleted for new games in IWD or HoW, respectively:

2DA V1.0
MIRROR
      ITEMS     
1    CDYOUNGN
2    DGEM01
3    DGEM02
4    DGEM03
5    DGEM04
6    DGEM05
7    DGEM06
8    DGEM07
9    DGEM08
10    DGEM09
11    DGEM10
12    KEYBRON
13    KEYCOPP
14    KEYDUNG
15    KEYELEC
16    KEYGOLD
17    KEYPLAT
18    KEYSILV
19    MIRROR
20    MIRROR2
21    MJOURN
22    SYMHELM
23    TORN
24    WEREAMUL
25    WYLFINS

AREANODE.2da

 

This file can be used to adjust the pathfinding nodes used by enemies in the specified areas. The first column represents the area name. The second column represents the value which will be used for enemy pathfinding nodes in that area. Changing this value below 8000 is not recommended.

2DA V1.0
0
        VALUE
AR9300  8000
AR6001  8000
AR9604  8000
AR8011  8000
Posted

I thought the inclusion of the two pseudostats in splprot.2da

0x103 - use two rows of splprot.2da

0x104 - negate 0x103

were a nifty thing to do.

 

I take it that when you use those in the STAT column, the following 2 columns become pointers listing the two row numbers that apply (am just guessing as it's not explicitly described). I am also figuring that you can do a series of nesting with 0x103 and 0x104. For example, when looking for breathing creatures (line 47), it first looks at lines 32 (Undead or Fungus) and 27 (is golem; RACE=144). Then line 32 points to two other rows, 1 (is UNDEAD; GENERAL=4) and 11 (is MYCONID; RACE=164). So you get 3 different conditions with one, which is really really cool.

 

Basically, it would be possible to cover nearly every condition except perhaps obscure conditions such as int <= x or HaveSpellObject() or variable=x (which are on my long-term wish list :) ).

 

I have some questions that I missed when reading the first post:

 

Is there a hardcoded limit to the number of rows in splprot.2da? Can you add your own nifty rows or is patching to the last value more recommended (ADD_SPELL style)?

 

Is there a hardcoded limit to the number of columns in 7EYES.2da? I still don't quite understand how this works, I'll ask that in the other thread.

 

Also, there is a part I do not completely understand, concerning EXTSTATE.IDS and SPLSTATE.IDS where you mention EXTSTATE as a subset of 256 spell states.

  • EXTSTATE.IDS used by the ExtStateCheck (0x40E1) trigger.

    Contains single bits of a bitfield. These 32 bits are simulating the HoW extended state field. In fact, our engine implements the extended states as a subset of the 256 spell states.

Does this mean that one of the SPLSTATE.IDS entries is hardcoded to reserve 32 hardcoded state bits (EXTSTATE.IDS) which are then accessed via various scripting blocks? Or is there a separation of SPLSTATE.IDS and EXTSTATE.IDS? I am figuring that these are read straight off the effects list of the .cre, as there is no equivalent change in the .cre format. Am genuinely curious about this. Thanks for any answers.
Posted

You are correct about the 2 row operators (the 2 column values become pointers to 2 rows).

The "stat <rel> value" conditions are also supported by using -1 as the value data. In this case, Param1 of the effect will become the value.

Here are the traditional IDS targeting values (using these could completely simulate BG2)

 

EA 0x10a -1 1

GENERAL 0x10b -1 1
RACE 0x10c -1 1
CLASS 0x10d -1 1
SPECIFIC 0x10e -1 1
GENDER 0x10f -1 1
ALIGNMENT 0x110 -1 8
KIT 152 -1 8
The extstate bits are mapped into the Splstate bits (they are also hardcoded). This is to have full compatibility with HoW (and make the converter's job a cakewalk).
The effects modify internal stats (not just the set state fx, but of course a few other opcodes modify spell states directly - these are always extstates too). The splstate holding stats don't have a base value (not saved in the cre, just like iwd had no such thing). So the base stats are starting off as zero, and an effect with permanent (1) timing would still linger around (since there is no base stat to modify like a hit and run fx).
I hope i answered everything.
I believe splprot lines can go up to 256, but i don't remember adding any hard limit.
Splstates are hard limited at 256.
7eyes: There isn't a hardcoded limit in column counts, but other factors like the 2da implementation or the editor you load the 2da can limit it somewhat.
Posted

Thanks for your answers Avenger. I was able to add 1000 lines to SPLPROT.2da and get line 1000 to work so the good news is it's practically limitless. The bad news is that you have to have every line filled ("rownum * * *" is enough) otherwise adding "1000 0x10b 4 1" (for example) will not work. So patching it ADD_SPELL style is recommended.

 

I was able to get some IWD2 conditions work (like INT < param1), so that makes this a powerful opcode that opens up new possibilities. One can in theory avoid all the hassle of typing new lines by allowing the "special" field to be used to type in any stat if the second column is set to -1 (analogous to how you implemented param1 behavior with the third column).

 

Could recommend at some point adding these lines as well:

newrownum 0x111 -1 8 (if the target is any param1 state from the STATE.IDS)

newrownum+1 0x111 -1 9 (exclude the target if their state matches param1)

Which compares the bitfield value of param1 to the STATE.IDS. That makes additional rows like "is blinded" unnecessary.

 

I've noticed though that add effects list doesn't trigger the added effects if placed in front of opcodes 210 (stun 90 hp) and 217 (unconsciousness 20 hp) and when looking for STATE_STUNNED and STATE_SLEEPING. I think this has more to do with opcodes 210 and 217 not changing the internal STATEs when applied.

 

See the two attached images on what I mean. Otherwise, most of the other states work (haven't tested all of them) when using the above two added lines to SPLPROT.2da.

post-90-0-30483200-1417550987_thumb.jpg

post-90-0-19397600-1417550997_thumb.jpg

Posted

We kept the old lines in iwdee to have maximum compatibility with mods, otherwise yeah, we would have condensed the states with the -1 feature.

In new projects, we'll likely use it as you mentioned.

 

Opcode 210 and 217 fire a new opcode internally, which is preceded by the splprot check. So, yeah, due to internal working, you cannot immediately check the states caused by those.

 

Your first example should work with the direct stun opcode.

Posted

It's not a big loss concerning opcodes 210 and 217 since they are now properly softcoded with new HPLT possibilities.

 

Yes, my first example works with the stun opcode (#45) perfectly.

Posted

I'm currently in the middle of writing a datatype for Near Infinity, which translates SPLPROT.2DA data into human-readable entries to replace the current hardcoded list. While doing so I've noticed that the following entries in SPLPROT.2DA don't match NI's current hardcoded descriptions:

           STAT       VALUE      RELATION // Automatic translation                  currently used descriptions (based on DLTCEP info)
33         0x110      2          9        // IDS != [bit] ALIGNMENT/MASK_GENEUTRAL  (originally "Good")
34         0x110      2          8        // IDS = [bit] ALIGNMENT/MASK_GENEUTRAL   (originally "Not good")
35         0x110      1          9        // IDS != [bit] ALIGNMENT/MASK_GOOD       (originally "Neutral")
36         0x110      1          8        // IDS = [bit] ALIGNMENT/MASK_GOOD        (originally "Not neutral")
...
39         0x10d      7          1        // IDS = CLASS/FIGHTER_MAGE               (originally "Paladin")
40         0x10d      7          5        // IDS != CLASS/FIGHTER_MAGE              (originally "Not Paladin")
...
59         0x110      0x20       9        // IDS != [bit] ALIGNMENT/MASK_LCNEUTRAL  (originally "Lawful")
60         0x110      0x20       8        // IDS = [bit] ALIGNMENT/MASK_LCNEUTRAL   (originally "Not lawful")

I can understand that alignment checks might have changed in IWDEE. However, lines 39 and 40 don't really make sense to me (Paladin is defined as 6 in CLASS.IDS). Am I interpreting the values correctly?

 

Second question: STAT 0x107 is defined as daytime. Which IDS file is used for this check?

Posted

Well, the alignment checks result in exactly the same effect. good = 1, neutral = 2, evil = 3, so the binary 1 is not set when neutral. (Please check all other alignment rows based on this knowledge).

 

The paladin check looks like a bug, wonder if it is used.

 

Daytime is most likely timeofday.ids, but the engine doesn't necessary have to have an IDS file. I think there is a feet circle size check too.

Posted

Well, the alignment checks result in exactly the same effect. good = 1, neutral = 2, evil = 3, so the binary 1 is not set when neutral. (Please check all other alignment rows based on this knowledge).

You are right. The automatic translation is somewhat misleading regarding bit operations. I'll try to come up with a less confusing interpretation.

 

The Paladin check is used in the "Cloud of Pestilence" spell, as Paladins are immune to magical disease.

 

GemRB appears to use a simple flag for determining day or night, and judging from this comment, daytime checks in IWD:EE don't seem to work yet.

Posted

the bug originated from your gemrb work, whence the table is from. In iwd2 the paladins are at 7. ;)

Posted

Do you know of any spells that would use daytime?

I don't think there are any. Original IWD defines IDs 86 and 87 for daytime-related states, but I don't know if they're actually used in any of the game resources. These IDs are still undefined in IWD:EE's splprot.2da.

Posted

the bug originated from your gemrb work, whence the table is from. In iwd2 the paladins are at 7. ;)

 

Then it is wrong in gemrb too. (splprot cannot be the same in iwd2 and iwd/how)

Posted

Of course, but I've already fixed that. We were also missing the checks for evasion and had bugs in the deafness ones. Not sure if that has propagated to iwdee.

Posted

Another question regarding SPLPROT.2DA.

Entry 47 is defined as follows: "Not match entries 32 or 27", where entry 32 contains another indirection "Not match entries 1 or 11".
Fully expanded, it results into: Not match (Not match (GENERAL/UNDEAD or RACE/MYCONID) or RACE/GOLEM).
The static description is "Breathing", which should exclude all of the aforementioned races. However, expanded entry 47 contains a double negative, which results in a "Some of them are breathing". Or is it processed differently by the game engine?

Entry 48 is similar: "Match entries 32 or 27"
and results into: Match (Not match (GENERAL/UNDEAD or RACE/MYCONID) or RACE/GOLEM).
The static description is "Not breathing", which should exclude all but the aforementioned races. This rule also doesn't fully match the static description.

Archived

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

×
×
  • Create New...