Jump to content

[EE] Free Proficiency / Scripting State slots


K4thos

Recommended Posts

I'm trying to find a way to reliably detect values of several new skills added to the game (set via scripts based on character's stats, increased via doing something in game, maybe even adjustable like Thief skills in GUI on level up since GUI in EE is written in pure Lua). Those extra skills needs to be then checked in dialogues and scripts.

 

So the first intuition was to just set them as LOCALS variables associated with NPC. Unfortunately something like this:

TriggerOverride(LastTalkedToBy,GlobalGT("K#Skill_Intimidate","LOCALS",10))

doesn't work with OR trigger since it's actually a combination of 2 triggers (NextTriggerObject and GlobalGT).

 

--------

 

Another options I've tried are new EE engine triggers:

0x40E1 ExtendedStateCheck(O:Object*,I:State*extstate)
Returns true only if the specified object is in the state specified (uses EXTSTATE.IDS).

0x40E2 CheckSpellState(O:Object*,I:State*splstate)
Returns true only if the specified object is in the state specified (uses SPELLSTATE.IDS). Spell states can be set via opcode 328.

 

Both seems to be useless for this purpose since they can only check modal state of the state (true/false).

 

--------

 

So the last option I can think of:

0x4044 CheckStat(O:Object*,I:Value*,I:StatNum*Stats)
Returns true only if the specified object has the statistic in the 3rd parameter at the value of the 2nd parameter.

0x4045 CheckStatGT(O:Object*,I:Value*,I:StatNum*Stats)
Returns true only if the specified object has the statistic in the 3rd parameter greater than the value of the 2nd parameter.

0x4046 CheckStatLT(O:Object*,I:Value*,I:StatNum*Stats)
Returns true only if the specified object has the statistic in the 3rd parameter less than the value of the 2nd parameter.

This is exactly what I need and these stats can be set via:

#233 (0xE9) Stat: Proficiency Modifier

works for 19 unused (in original BG2) Extra Proficiency slots

#282 (0x11A) Script: Scripting State Modifier

several unused (in original BG2) scripting states.

 

--------

 

The problem is that what was unused in original BG2 and works with above mentioned opcodes (entries from stats.ids):

116 EXTRAPROFICIENCY2
117 EXTRAPROFICIENCY3
118 EXTRAPROFICIENCY4
119 EXTRAPROFICIENCY5
120 EXTRAPROFICIENCY6
121 EXTRAPROFICIENCY7
122 EXTRAPROFICIENCY8
123 EXTRAPROFICIENCY9
124 EXTRAPROFICIENCY10
125 EXTRAPROFICIENCY11
126 EXTRAPROFICIENCY12
127 EXTRAPROFICIENCY13
128 EXTRAPROFICIENCY14
129 EXTRAPROFICIENCY15
130 EXTRAPROFICIENCY16
131 EXTRAPROFICIENCY17
132 EXTRAPROFICIENCY18
133 EXTRAPROFICIENCY19
134 EXTRAPROFICIENCY20
160 SCRIPTINGSTATE5
161 SCRIPTINGSTATE6
162 SCRIPTINGSTATE7
163 SCRIPTINGSTATE8
164 SCRIPTINGSTATE9
165 SCRIPTINGSTATE10

In EE engine games is actually in use by several spells. Here are values from stats.ids:

116 WIZARD_SPELL_DEFLECTION
117 PROTECTION_FROM_EVIL
118 TRUE_SIGHT
119 CLERIC_CHAOTIC_COMMANDS
120 CLERIC_INSECT_PLAGUE
121 CLERIC_BLADE_BARRIER
122 CLERIC_PHYSICAL_MIRROR
123 CLERIC_SHIELD_OF_THE_ARCHONS
124 CLERIC_REGENERATION
125 WIZARD_FIRE_SHIELD
126 WIZARD_PROTECTION_FROM_MAGIC_ENERGY
127 WIZARD_MISLEAD
128 WIZARD_PROTECTION_FROM_MAGIC_WEAPONS
129 WIZARD_SPELL_TURNING
130 WIZARD_PROTECTION_FROM_THE_ELEMENTS
131 CLERIC_FREE_ACTION
132 WIZARD_KHELBENS_WARDING_WHIP
133 CLERIC_DEFENSIVE_HARMONY
134 EXTRAPROFICIENCY20
160 DEFENSIVE_MODIFIER
161 STRENGTH_MODIFIER
162 WIZARD_SPELL_IMMUNITY
163 WIZARD_PROTECTION_FROM_ENERGY
164 WIZARD_SPELL_TRAP
165 WIZARD_IMPROVED_ALACRITY

Searching these stats usage in Near Infinity gives me several matches for those EXTRAPROFICIENCY slots. Very frustrating considering all this is used for is TRUE/FALSE spell detection check and there are EE exclusive dedicated opcodes for those using extstate.ids and splstate.ids.

 

--------

 

Ok, so now a question. Is there really no way to set new detectable value in EE engine that could be checked inside OR trigger? Technically I could patch all instances of opcode 233 (Proficiency Modifier) when it comes to stats 116-134 to use opcode 328 (Set State) and also update scripts and dialogues to use correct trigger (CheckSpellState instead of CheckStat) but other mods probably expects those values used by BG2:EE, so it doesn't sound like a safe option (the mod is meant to be installed early so other mods can patch content added by it).

 

From what I see there is a single free state in BG2:EE:

134 EXTRAPROFICIENCY20

 

I need at least 5 of them.

 

Any ideas how to solve this issue? Maybe someone is aware about other free slots that could be used for this purpose? Or maybe there is some way to add new stats into stats.ids and detect them somehow? (that's what Tobex allows but it doesn't seem to work in EE engine)

Link to comment

OR() ignores the NextTriggerObject/TriggerOverrider trigger, you can do this:

OR(2)
 TriggerOverride(LastTalkedToBy,GlobalGT("K#Skill_Intimidate","LOCALS",10))
 TriggerOverride(LastTalkedToBy,GlobalGT("K#Skill_Diplomacy","LOCALS",10))
Link to comment

not sure if I understand, kjeron. If it ignores it then how the engine will be able to get the trigger object for GlobalGT in your code? (that's what NextTriggerObject/TriggerOverrider is used for). Will it correctly get the local value from the LastTalkedToBy? Please post how below example block should be constructed to work correctly (from what I understand it's not possible inside single dialogue response check):

OR(4)
  CheckStatGT(LastTalkedToBy,17,INT)
  Global("someVar","GLOBAL",1)
  TriggerOverride(LastTalkedToBy,GlobalGT("K#Skill_Intimidate","LOCALS",10))
  TriggerOverride(LastTalkedToBy,GlobalGT("K#Skill_Diplomacy","LOCALS",10))
Link to comment

All those ExtraProficiency stats are used by Detectable Spells on pre-EE (SR, SCS, maybe Spellpack) and for the now-official version of Detectable Spells in the EEs.

 

With the exception of 134. The Eldritch Magic mod is currently using stat 134, though I gace the author some code to use a higher byte of stat 113 instead. My mods use several bits in a higher byte (the 4th byte) of stat 134... I have no idea how that interacts with the CheckStatGT trigger.

 

I'd prefer that anything involving triggers use other stats or states besides proficiencies. Proficiency 134, in particular, can be used in 32 different, independent ways by using bit equality in splprot.2da... it would be a shame for a single use of a script trigger to conflict with those 32 potential mods. Unfortunately there is no trigger to check bit equality, only =, <, and >. So it seems like state would be better used for scripting applications.

 

In particular, you can create new spellstates in splstate.ids for this kind of use in the new EE engine...

Link to comment

subtledoctor, as mentioned above this is no longer a problem for my mod since I can use LOCALS just fine. But this:

All those ExtraProficiency stats are used by Detectable Spells on pre-EE (SR, SCS, maybe Spellpack) and for the now-official version of Detectable Spells in the EEs.

sounds like a waste of valuable detectable states (which can receive proper values) for modders when it's only used for TRUE/FALSE checks (from what I see both SCS and vanilla SoD AI scripts use those proficiency slots just to check if few spells are active). That's what new patch 2.x CheckSpellState trigger, and Set State opcode should be used for. Unless that splprot.2da suddenly changes it - can't say I understand how it works. In vanilla engine there are 19 free detectable states with values. With Tobex installed there are unlimited amount of such states available. In EE there is just one EXTRAPROFICIENCY20...

 

Since we have actual Beamdog devs here on G3 - any chance for freeing up all those EXTRAPROFICIENCY slots and using splstate.ids for detectable spells instead? It may be too late for this now though since these states have been occupied for some time by BG2:EE (not sure when exactly spells have been patched to use them), so some mods may already reference them.

 

In particular, you can create new spellstates in splstate.ids for this kind of use in the new EE engine...

You mean 200 new splstate.ids entries just to detect 5 new skills + tens of trigger variations in dialogues to detect them? That would be silly and you can't expect anyone to follow such suggestion when there are stats that can receive proper values and can be checked without problems in scripts and dialogues. Thankfully the locals solution seems valid since the only reason why I needed stats.ids entries was due to assumption that locals would not work with OR blocks (timing is not needed).

Link to comment

subtledoctor, as mentioned above this is no longer a problem for my mod since I can use LOCALS just fine. But this:

All those ExtraProficiency stats are used by Detectable Spells on pre-EE (SR, SCS, maybe Spellpack) and for the now-official version of Detectable Spells in the EEs.

sounds like a waste of valuable detectable states (which can receive proper values) for modders when it's only used for TRUE/FALSE checks (from what I see both SCS and vanilla AI scripts use those proficiency slots just to check if few spells are active). That's what new patch 2.x CheckSpellState trigger, and Set State opcode should be used for. Unless that splprot.2da suddenly changes it - can't say I understand how it works.

The EE's have (very) slowly been transitioning from proficiency/scriptstates to Spellstates.

For example, Armor of Faith, while the spell still sets both proficiency 110 and SPLSTATE 2, all scripts have been updated to only check SPLSTATE 2.

The problem is backwards compatibility, and forcing people to migrate to Spellstates (of which there are also a limited amount, and some wasted slots as well (duplicating hardcoded STATS like HELD and WEB, 3 different states for rage, separate states for each bard song).)

 

Either way, any (permanent) value that will only be checked in scripts/dialogues would be wasted on a proficiency/scriptingstate. Local Variables are the way to go. Their biggest drawback is that they cannot hold a duration.

Link to comment

What I was trying to say was, those 19 other proficiencies are not in fact "available" in pre-EE games. I mean technically they are in a bare vanilla install, but several mods (including very popular ones like SR, SCS) use those proficiencies for detectable spells.

 

Yes, this is indeed very wasteful. But, in the old days it was the only really feasible way to do it. As kjeron said the EEs are transitioning to the spellstate system, but backwards compatibility is the issue.

 

I'm not clear on exactly what you want to do, so I can't say whether states would be sufficient. I will say from some experience that adding skills to the game is not something I would do lightly, because there is no mechanism to display your current value in such a skill.

 

The Tracking stat is currently unused, except for a mod in development using it for psionics. But the issue as I said is you can't easily check how many PSPs you have.

 

The best idea I had for that kind of thing is to repurpose Lore, si ce that is displayed in the record sheet. But even then it only gets you one added skill. Adding five... not something I would try.

Link to comment

As for what SPLPROT.2da does, basically it just lets you trigger spells, or protect from spells, based on a stat check... without involving scripting. It allowed me to finally implement real new dynamic stat bonuses that don't depend on baldur.bcs... and extra bonuses for weapon styles, like auto shield bash... and I'm going to use it for a real armored casting system that can allow arcane casters to use different kinds of armor based on kit, or on level, or on feats or HLAs, etc.

 

Basically it's catnip for tweak modders ;)

Link to comment
What I was trying to say was, those 19 other proficiencies are not in fact "available" in pre-EE games. I mean technically they are in a bare vanilla install, but several mods (including very popular ones like SR, SCS) use those proficiencies for detectable spells.

true. Tobex revolutionized it at the end of life cycle though, so it's no longer a problem there (you can add for example stat 1269 and it's still perfectly detectable and can be set with all range of bitwise operations). I'm still salty that the EE engine didn't start with Tobex as a base but vanilla BG2:ToB.

 

I'm not clear on exactly what you want to do, so I can't say whether states would be sufficient. I will say from some experience that adding skills to the game is not something I would do lightly, because there is no mechanism to display your current value in such a skill.

(...)

The best idea I had for that kind of thing is to repurpose Lore, si ce that is displayed in the record sheet. But even then it only gets you one added skill. Adding five... not something I would try.

EE GUI is written in Lua. All I need to implement more skills for level up and/or to present them in Record screen is a feature that already exists in PST:EE and may (or may not) be added in the next patch. Even if Infinity_GetScriptVarInt won't be there, setting hidden skills via DPLAYER scripts based on several stats and other factors is easier to maintain than using tons of different Triggers for dialogues that needs to check if dialogue option should show up (in case I change mind how particular skill should work in relation to factors that contribute to it).

 

SPLPROT.2da sounds interesting. Is there full documentation for it somewhere?

Link to comment

The problem is backwards compatibility, and forcing people to migrate to Spellstates (of which there are also a limited amount, and some wasted slots as well (duplicating hardcoded STATS like HELD and WEB, 3 different states for rage, separate states for each bard song).)

Yes, the problem has always been that multiple mods have already been using DS for a long time - SCS, RR, aTweaks, BP, Questpack, since recently SR as well (but only to address the needs of AI mods), and also Ascension, Kelsey, Kiara-Zaya and no idea if there're others. Three latter mods have very old and outdated version and are auto-remapped if detected, so it's not impossible, but 1) those are fairly small in scope and 2) two of them were already on radar by the time I showed up to update DS code.

 

If you want to change the detection table, you really need to get at least DavidW and Wisp to agree to update their AI source written in SSL.

 

PS Even before EEs I never felt like trying to force the change. Spellstates merely complicated it even further, because they've been first introduced in IWDEE that I never participated in and therefore had little impact on how it should've been done.

Link to comment

I think most of ToBEx is in the EEs at this point... no?

 

SPLPROT.2da sounds interesting. Is there full documentation for it somewhere?

The basics are here:

http://gibberlings3.net/forums/index.php?showtopic=26809&p=228874&do=findComment&comment=228874

 

I tried to put together some easily adaptable code here:

https://forums.beamdog.com/discussion/62352/how-to-do-stuff-in-weidu/p1

 

And this is also very interesting in relation to splprot:

https://forums.beamdog.com/discussion/63633/usability-of-stats-values-255#latest

Link to comment
I think most of ToBEx is in the EEs at this point... no?

not exactly. At least not features I really care about:

353 DialogueSetGlobal(S:Name*,S:Area*,I:Value*)
354 DialogueIncrementGlobal(S:Name*,S:Area*,I:Value*)
355 DialogueSG(S:Name*,I:Num*)

needed for instant global variable change detection in dialogues. Not present unless SetGlobal has been updated to work instantly in dialogues (really doubt it since I can't find any mention of it).

0x411B Eval(S:Expression*,I:Type*ArgType,I:Loc*)
New
Overwrites the (Loc)th argument of type Type from ARGTYPE.IDS (INT integer, or STR string) in the next trigger with the value returned by Expression. This trigger does not evaluate and does not count as a trigger in an OR() block. This trigger does not overwrite values of the Assign(), NextTriggerObject() and OR() triggers. The NextTriggerObject() trigger ignores this trigger.
    Expression is a math expression that can use the following symbols:
    = + - * / % ^ ( )
    min(x, y), max(x, y), avg(x, y)
    ceil(x), floor(x), round(x)
    abs(x)
    reciprocal(x)
    sqrt(x), pow(x, y)
    log(x), log10(x)
    sin(x), cos(x), tan(x), sinh(x), cosh(x), tanh(x), asin(x), acos(x), atan(x), atan2(x)
    Custom: and(x, y), or(x, y), band(x, y), bor(x, y)
    Any text in Expression of form #<num> and @<num> is replaced by the integer and string values, respectively, stored in local trigger block variables of index "num". Avoid using integer variables in expressions of string type. Avoid using string variables in expressions of integer type. The range of "num" is 0 to 24.
0x411C E(I:Num1*,I:Num2*)
0x411D GT(I:Num1*,I:Num2*)
0x411E LT(I:Num1*,I:Num2*)
New
Compares "Num1" to "Num2", where E is equals, GT is greater than, and LT is less than. To make use of these triggers, the 0x411B Eval() trigger should be used prior to this trigger.

tired of those 1000+ lines of codes scripts to achieve something tricky? Yep, you can write them in few lines with Tobex.

356 Assign(S:Statement*,I:Type*ArgType,I:Local*)
356 AssignFromObject(S:Statement*,O:Object*,I:Type*ArgType,I:Local*)
New
Assigns a value determined by Statement of the type Type from ARGTYPE.IDS (INT integer, or STR string) to a local action block variable. The general form of Statement is "prefix[params]". If Object is specified, the value of Statement is determined relative to Object instead of the object that owns the script. This action is ignored by prior Eval() actions.

    "prefix" can be:

prefix     description     params type     examples
c     assigns a constant value     integer or string     c[1], c[FOO]
e     assigns the value of an expression     expression (see action 0x411B Eval() for format)     e[6 + 7]
id     assigns the index of a IDS file value     file.value     id[EA.CHARMED]
s     assigns the value of the stat specified of the current object     STATS.IDS name     s[LEVEL]
sp     assigns the value of the special value specified (of the current object, if applicable)     ASGNSPEC.IDS name     sp[SPRITE_PT_X]
tn     assigns the value of a 2DA file value by coordinates     file.x.y     tn[IMPORT01.0.0]
ts     assigns the value of a 2DA file value by column and row name     file.column.row     tn[IMPORT01.ITEMS.1]
v     assigns the value of a variable     name.scope     v[foo.GLOBAL]

    "params" values containing #<num> and @<num> are replaced by the integer and string values, respectively, stored in local action block variables of index "num". Avoid using integer variables in expressions of string type. Avoid using string variables in expressions of integer type. The range of "num" is 0 to 24.

how about using 2da and ids tables in scripts?

 

And of course TobEx expands the use of STATS.IDS to support new hard-coded stats and custom stats for modmaker use.

 

Here is full reference: http://readme.classicadventuresmod.com/TobExReference.html

 

edit: those Eval and Assign functions exists as both Triggers and Actions btw.

Link to comment

 

I think most of ToBEx is in the EEs at this point... no?

not exactly. At least not features I really care about:

353 DialogueSetGlobal(S:Name*,S:Area*,I:Value*)
354 DialogueIncrementGlobal(S:Name*,S:Area*,I:Value*)
355 DialogueSG(S:Name*,I:Num*)
needed for instant global variable change detection in dialogues. Not present unless SetGlobal has been updated to work instantly in dialogues (really doubt it since I can't find any mention of it).

 

 

Afaik, DLG response flags bit 9 (Execute immediate) allows you to execute non-blocking script actions immediately.

Link to comment

Archived

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

×
×
  • Create New...