Jump to content

EXTSTATE.IDS unique appending


K4thos

Recommended Posts

I'm not really a programmer so this may be a bit silly question for someone with programming background, but help would be appreciated. I understand how states.ids / extstate.ids works. The concept behind them is quite powerfull (creating custom "mask" states by adding previously referenced states values). What I'd like to know is if it's possible to append into extstate.ids in a way to make all my new base and mask states undetectable by other mods that also append to this file (and follow the same rules as me for appending). Let's say for example that I want to append ALIGNMEN.IDS references and give them unique values, only detectable by my mod (yeah, I know, but it's just an example)

0x11 LAWFUL_GOOD
0x12 LAWFUL_NEUTRAL
0x13 LAWFUL_EVIL
0x21 NEUTRAL_GOOD
0x22 NEUTRAL
0x23 NEUTRAL_EVIL
0x31 CHAOTIC_GOOD
0x32 CHAOTIC_NEUTRAL
0x33 CHAOTIC_EVIL
0x01 MASK_GOOD
0x02 MASK_GENEUTRAL
0x03 MASK_EVIL
0x10 MASK_LAWFUL
0x20 MASK_LCNEUTRAL
0x30 MASK_CHAOTIC

Another mod using the same values (or values that would return true bitwise) would conflict with my mod. I'm looking for a way to create unique values on the fly based on still free value ranges. I think it would be a good idea to create a common code that could be used by modders for this purpose. Hope this makes sense. Any hints would be appreciated (since I can write weidu code myself) if something like this is even possible.

Link to comment

I don't really know how extstate.ids works. It looks like you can set these values via opcode #328, but the IESDP indicates the first entry is Chaotic Commands and not Prayer as I would expect from the listing in extstate.ids (unless the IESDP is out of date).

 

Regardless, the way bit fields work, each exclusive state requires its own bit. Bits 0 through 27 appear to already be taken, so there is only room for 4 more states:

 

0x10000000

0x20000000

0x40000000

0x80000000

 

If you were appending a new exclusive state, you would just choose whichever one of those values was free.

 

If you were adding a new combination of states, its value would be equal to the bitwise OR of all the component states.

 

 

(alignmen.ids is not a great comparison because it's not actually a bit field.)

Link to comment
so there is only room for 4 more states

that's unfortunate. Taking up 1 of only 4 available bits for the task I've been thinking of (grouping classes similarly to how IWD2 uses CLASSMSK.IDS) would be a bit excessive considering the only purpose of it is limiting amount of triggers needed. Thanks for explanation. That does make sense.

Link to comment

Even if you could extend EXTSTATE.IDS, how would you set those added states?

You could, however, replace most of the existing extstates, excluding the following:

0x00001000 STATE_SUPPRESS_HP_INFO // SpellState 35 has hardcoded function
0x00002000 STATE_BERSERK_ALWAYS_ACTIVE  // Opcodes 3*1, 247*1
0x00004000 STATE_SNEAK_ATTACK_IMMUNITY // Opcode 292*1
0x00008000 STATE_CYNICISM_EQUIPPED  //  Opcode 330*1
0x00020000 STATE_DEAFENED // Opcode 80
0x00010000 STATE_DOESNT_AWAKEN_ON_DAMAGE // Opcode 39*1

The rest(*) all just point to a specific SPLSTATE.IDS value, which you could re-purposed (though you would have to re-point every existing instance to another SpellState). This gives you 21-22 extstates you could map to classes through spellstates.

 

* STATE_UNSTUN_ON_DAMAGE was not linked to either Wake-on-Hit Sleep or Project Image, maybe there is another unstun-on-damage trigger I'm forgetting to check.

Taking up 1 of only 4 available bits for the task I've been thinking of (grouping classes similarly to how IWD2 uses CLASSMSK.IDS) would be a bit considering the only purpose of it is limiting amount of triggers needed.

The file has no other purpose than to simplify script triggers. All of its values can be checked individually with their equivalent CheckSpellState() trigger, and few, if any, of the current ones could really benefit from complex checks anyway.

Not sure what you mean by taking up 1 bit though, mirroring CLASSMSK.ids would take at least 11 bits, 12 bits if you added the Shaman Class.

Link to comment
Not sure what you mean by taking up 1 bit though, mirroring CLASSMSK.ids would take at least 11 bits, 12 bits if you added the Shaman Class.

misunderstood Mike's reply as 4 free ranges that can take up to 32 values each (please excuse my ignorance on this matter - I've never worked with bit values before, other than normal weidu flag bitwise operations on pre-existing values - even this without actually checking what decimal or hex value hides behind "BITx"). From what I understand now, after checking this table, is that there are 32 values total available in extstate.ids. That's even more limiting and not worth to rearrange existing ones for something that can be easily implemented in different ways (and was meant as a convenient thing, not something essential, in the first place). Once again thanks for explanation.

 

Since we're talking about bits here I have also a little question regarding PST:EE unique bit actions/triggers:

404 BitSet(S:Name*,S:Scope*,I:Bit*Bits)

This feature looks mighty interesting since it allows to set bit0-31 at will on different targets. This seems usefull for simplyifing long ass complicated scripts (used as an alternative for variables). From what I see PST:EE always uses ARE as a S:Scope. Is it possible to use CRE instead of ARE for setting up bits with this action?

Link to comment
This feature looks mighty interesting since it allows to set bit0-31 at will on different targets. This seems usefull for simplyifing long ass complicated scripts (used as an alternative for variables). From what I see PST:EE always uses ARE as a S:Scope. Is it possible to use CRE instead of ARE for setting up bits with this action?

 

just tested it myself.

- BitSet, BitCheck and BitClear works with all scopes (area, GLOBAL, LOCALS).

- Bitwise values detection works fine.

- Values are still valid after quitting/re-loading the game.

- Multiple S:Name* can be set for the same area and bit detection works for all of them separately.

 

Awesome feature all around. No problems with mods compatibility (simply use unique names). Hopefully Beamdog will eventually backport it into BG2:EE :)

 

edit: updated

Link to comment
I'm looking for a way to create unique values on the fly based on still free value ranges.

There's a bit of related code in DS, that allows to define stats/states as strings and have WeiDU resolve them either by looking up a matching entry in the .ids file or filling the first free slot if there was none existing.

https://github.com/Gibberlings3/SpellRevisions/blob/master/spell_rev/lib/ds.tph#L631

https://github.com/Gibberlings3/SpellRevisions/blob/master/spell_rev/lib/ds.tph#L1025

 

What I'd like to know is if it's possible to append into extstate.ids in a way to make all my new base and mask states undetectable by other mods

 

You could certainly skip appending.ids with new entries, so that other mods can't read them, but then 1) you risk other mods overwriting your additions and 2) they still could read your scripts and whatnot and deduce if you're using hidden values, assuming there'd be someone dedicated enough.

Link to comment

just tested it myself.

- BitSet, BitCheck and BitClear are meant to be used with current active areas only.

- CRE references are not supported but it doesn't really matter since you can use "MYAREA" to set unique S:Name* via local scripts etc. without worrying about area name

I don't understand this. What does this mean with regard to .cre files?

Link to comment

If you need to add a new spell state, use splstate.ids

Is there no limit to the amount of possibilities ? Well, if the limit is 4 million, and we use 1000, then it's limitless, but say if the limit lies in about 1028 and we are at (in vanilla game) 600, then it's not limitless. I am just picking these numbers from cheese.
Link to comment

 

If you need to add a new spell state, use splstate.ids

Is there no limit to the amount of possibilities ? Well, if the limit is 4 million, and we use 1000, then it's limitless, but say if the limit lies in about 1028 and we are at (in vanilla game) 600, then it's not limitless. I am just picking these numbers from cheese.

 

Yeah, totally cheese and extstate won't help you, because all extstate bits are converted into splstate bits internally.

The exact splstate limit is 256, of these, vanilla uses about half.

Sadly, you need a bit for every separate value. So, adding a single dword only increases the limit by 32.

Link to comment

The Bitwise Variable action/triggers work just fine for all scopes, they are no different from Variables set through other means.

*Whoosh* right over my head. I don't know what you're talking about. Can I assume that this is not something that would let me, say, flip an OriginalClass bit in offset 0x10 of a .cre?

Link to comment

Archived

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

×
×
  • Create New...