As you know, when you make a CRE and set its kit to, say, Barbarian, it doesn't automatically get the Barbarian Rage ability (unless it joins the party). Moreover, if you set its level to, say, 7, you need to manually set its base thac0 to 13 and its saving throws to their correct values (provided that you intend to make a legal Barbarian....)
Now, my question is: what about the attacks per round? Should I leave them at 1 and then the engine will automatically set them to their correct value? What about if there are some opcodes #233?
Doubt it. Well I mean sure you could append rows to the file, but why? The entries point to proficiency stats in STATS.IDS, and you can't add any more of those. So any new WEAPPROF entries would point to nothing and be meaningless.
Yeah, you're right.
Anyway, it's possible to add new entries to STATS.ids and then set them via opcode #233..... The real problem is that there's probably no way of coding what those custom stats grant according to the number of + your CRE has in them......
Anyway, it's possible to add new entries to STATS.ids and then set them via opcode #233..... The real problem is that there's probably no way of coding what those custom stats grant according to the number of + your CRE has in them......
Opcode 233 can only modify a set selection of STATS, #89 - 134. However, every one of those stats (89-134) can be used as a functional proficiency, they are just currently used for other purposes. Even the weapon styles are functional proficiency stats, for example if you wanted to give an off-hand-only weapon two-weapon proficiency instead of it's normal proficiency.
edit - most of them will no longer show up on the record screen, after people complained about seeing empty entries from certain spells that used them as scripting stats.
Maybe this the wrong place, but tracking down mods based on memory can be a pain with various places they are archived, and Spellhold and Gibberlings sporadically going down. But does anyone remember which mod(s) made Proficiency APR bonuses universal for non-warrior classes? The other aspect of this mod was it replaced Warrior APR progression with bonuses grant through the CLAB files upon level 7 and 13. I wish to look through mods coding for my own purposes but I'm having a hell of a time tracking it down.
Opcodes 171 and 172 do not use timing mode 9. They have only 3 functional timing modes: 1/4/7. Instant, Delayed(seconds), Delayed(ticks). All others effectively convert to one of these.
The same holds for opcode #72 (Set IDS state), doesn't it?
The same holds for opcode #72 (Set IDS state), doesn't it?
Opcode 72 is a bit more complicated. If you don't want to risk breaking things, you should treat it the same, and only use timing modes 1/4/7.
The problem with it, is that when multiple instances of the opcode are applied at the same time, all but the last one is effectively treated as using timing mode 1 anyway, making permanent changes to the creature.
There are also circumstances in the game which will do the same - making any temporary changes to these IDS states permanent. One such is summoning a creature - any temporary changes to it's GENDER that are present when it is summoned are made permanent.
I suspect the mechanics behind these events are linked, but it's beyond my scope.
I was asking because I'd like to tweak WIZARD_POLYMORPH_SELF (and related spells). In particular, I'd like to provide different forms, one of them being an UNDEAD (i.e., having all the bonuses provided by RING95.itm). So in order not to trick the AI I add opcode #72 (timing mode 2, GENERAL = UNDEAD) to the creature weapon........
But if I do this, then I need to add opcode #72 to all the other forms (including the Human one) and set GENERAL back to 1 (i.e., HUMANOID), otherwise I'll be permanently flagged as an UNDEAD.....
The only problem is that the caster of WIZARD_POLYMORPH_SELF must be HUMANOID or the spell will overwrite its original GENERAL... But this should not be a problem since the AI is not supposed to cast that spell, isn't it (even if we take into account SCS)?
Alternatively, I could add a dummy spellstate and edit all scripts that make use of the trigger !General([object],UNDEAD) and add something like !CheckSpellState([object],DUMMY_SPELLSTATE)............
But this solution does sound pretty complicated, right?
I was asking because I'd like to tweak WIZARD_POLYMORPH_SELF (and related spells). In particular, I'd like to provide different forms, one of them being an UNDEAD (i.e., having all the bonuses provided by RING95.itm). So in order not to trick the AI I add opcode #72 (timing mode 2, GENERAL = UNDEAD) to the creature weapon........
Loading the game with an equipped opcode #72 was another situation that can make the change permanent.
But if I do this, then I need to add opcode #72 to all the other forms (including the Human one) and set GENERAL back to 1 (i.e., HUMANOID), otherwise I'll be permanently flagged as an UNDEAD.....
There's another issue to consider - if your character gets kills, any delayed effect to revert their GENERAL will be removed, leaving them UNDEAD permanently after you raise them.
But this should not be a problem since the AI is not supposed to cast that spell, isn't it (even if we take into account SCS)?
The AI has no reason to cast WIZARD_POLYMORPH_SELF, because they can just forcibly cast the specific abilities to polymorph into each form, which there is no reason they cannot do that. Whether or not any actually do, I don't know.
Alternatively, I could add a dummy spellstate and edit all scripts that make use of the trigger !General([object],UNDEAD) and add something like !CheckSpellState([object],DUMMY_SPELLSTATE)
This would likely be the most practical solution, but you still run the risk of not catching scripts installed after your mod.
The AI has no reason to cast WIZARD_POLYMORPH_SELF, because they can just forcibly cast the specific abilities to polymorph into each form, which there is no reason they cannot do that.
I don't agree. Polymorph self requires one spellcasting action (which can be interrupted by damage or cause spellcasting failure) to gain the polymorph abilities, and then another to use them. Sure, you could fake or ignore the original casting of Polymorph Self, but then (a) you're cheating, and (b) you need to use a variable or something to keep track of whether the spell is still active. Much easier just to cast the spell, gain the abilities, and then use HaveSpell to determine if you've got them at a given time.
(I don't currently use Polymorph Self in SCS, and as far as I know it's not in any other AI either, but that's how I'd use it if I ever introduced it.)
There's another issue to consider - if your character gets kills, any delayed effect to revert their GENERAL will be removed, leaving them UNDEAD permanently after you raise them.
True. This means I need to add opcode #232 (timing = 2, param2 = 'Target dies', resource = ~MYSPL~, where MYSPL sets GENERAL back to 1) to each creature weapon........
I don't think it would make sense for that trigger to be in an OR block, so this should be safe.
I put General(Myself,UNDEAD) in OR() blocks all the time.
My general advice is that all this looks fairly dangerous: wholesale search-and-replace on the entire script system, and a condition that isn’t removed automatically but has to be caught manually, all for a fairly minor AI improvement (the AI very rarely checks the UNDEAD status of its targets, because most players aren’t undead).
My general advice is that all this looks fairly dangerous: wholesale search-and-replace on the entire script system, and a condition that isn’t removed automatically but has to be caught manually,
A spellstate would be automatically removed, that's the whole point of using it over opcode 72.
FWIW for SCS scripts this should be irrelevant anyway (provided you install your mod before SCS), because I do charm/hold/etc immunity by putting a spellstate on the protecting item. (So if you've got an item that gives immunity to hold, SCS will flag it with the ITEM_HOLD spellstate, and will check for that spellstate before casting Hold Person.
How can I take into account Hold Person (and related spells) and Charm Person (and related spells)? Moreover, we should probably exclude the object 'Myself' from the regexp........
I don't know if either of these can be done with REPLACE_TEXTUALLY. The 'Myself' could probably be done with REPLACE_EVALUATE, but I don't know about the others, because I think what really needs to be matched there is the 'See/Detect' trigger with objects like [0.HUMANOID], which would need to account for OR() blocks.
FWIW for SCS scripts this should be irrelevant anyway (provided you install your mod before SCS)...
That's the plan. As I said, this is mainly for SoD since I play the other two games with your mod. Moreover, it seems that no vanilla script (e.g., MAGE7, MAGE8 and so fourth) makes use of those triggers.....
Speaking of this, what Polymorph_Self-like spells does SCS use?
How can I take into account Hold Person (and related spells) and Charm Person (and related spells)? Moreover, we should probably exclude the object 'Myself' from the regexp........
I don't know if either of these can be done with REPLACE_TEXTUALLY. The 'Myself' could probably be done with REPLACE_EVALUATE, but I don't know about the others, because I think what really needs to be matched there is the 'See/Detect' trigger with objects like [0.HUMANOID], which would need to account for OR() blocks.
What do you mean exactly with 'OR() blocks'? Are you saying that, e.g., See([regexp.HUMANOID]) should be put in an OR() block together with !CheckSpellState([regexp],DUMMY_SPLSTATE) ? But this cannot work because I am HUMANOID (if I don't use opcode #72), so the See trigger returns true ---> the OR() block returns true and WIZARD_HOLD_PERSON is wasted.....
Oh, wait, there may be an alternative: what about giving the creature weapon some key splstates/stats via opcode #328 or opcode #233 as equipping effects (timing mode = 2)? For example: RESIST_FEAR (to counter opcode #24), CHAOTIC_COMMAND (to counter opcodes #39, #5, #128), CLERIC_FREE_ACTION (to counter opcodes #175, #109) (am I missing something?)
Yes, sure, there is still the possibility that some spells will be wasted in any case (if the AI doesn't check for those splstates), but, after a quick look at some scripts, this seems to be intentional, right ( @Ardanis ?)
Oh, wait, there may be an alternative: what about giving the creature weapon some key splstates/stats via opcode #328 or opcode #233 as equipping effects (timing mode = 2)? For example: RESIST_FEAR (to counter opcode #24), CHAOTIC_COMMAND (to counter opcodes #39, #5, #128), CLERIC_FREE_ACTION (to counter opcodes #175, #109) (am I missing something?)
That will work, except you will still be triggering them to cast Remove Magic, as it assumes those stats/states accompany dispellable effects.
I would not use CLERIC_FREE_ACTION, as CHAOTIC_COMMANDS already handles those opcodes, and you should still be subject to targeting by spells such as Slow. Level Drain: NEGATIVE_PLANE_PROTECTION // Scripting State 3 Slay: DEATH_WARD // Scripting State 2, but this also blocks Disintigration, which undead are subject to, though I don't think you'll come across it in SoD.
What do you mean exactly with 'OR() blocks'? Are you saying that, e.g., See([regexp.HUMANOID]) should be put in an OR() block together with !CheckSpellState([regexp],DUMMY_SPLSTATE) ? But this cannot work because I am HUMANOID (if I don't use opcode #72), so the See trigger returns true ---> the OR() block returns true and WIZARD_HOLD_PERSON is wasted.....
If See([0.HUMANOID]) is already in an OR() block, REPLACE_TEXTUALLY will break that OR() block, because it will put !CheckSpellState(object,DUMMY_SPLSTATE) into that OR() block. Unlike !General(), it is normal for See() to be in an OR() block.
Oh, wait, there may be an alternative: what about giving the creature weapon some key splstates/stats via opcode #328 or opcode #233 as equipping effects (timing mode = 2)? For example: RESIST_FEAR (to counter opcode #24), CHAOTIC_COMMAND (to counter opcodes #39, #5, #128), CLERIC_FREE_ACTION (to counter opcodes #175, #109) (am I missing something?)
That will work, except you will still be triggering them to cast Remove Magic, as it assumes those stats/states accompany dispellable effects.
I completely forgot about this, damn it..... That's why we NEED an additional parameter for those triggers, i.e., something like this:
Comments
Moreover, if you set its level to, say, 7, you need to manually set its base thac0 to 13 and its saving throws to their correct values (provided that you intend to make a legal Barbarian....)
Now, my question is: what about the attacks per round?
Should I leave them at 1 and then the engine will automatically set them to their correct value? What about if there are some opcodes #233?
Anyway, it's possible to add new entries to STATS.ids and then set them via opcode #233..... The real problem is that there's probably no way of coding what those custom stats grant according to the number of + your CRE has in them......
However, every one of those stats (89-134) can be used as a functional proficiency, they are just currently used for other purposes. Even the weapon styles are functional proficiency stats, for example if you wanted to give an off-hand-only weapon two-weapon proficiency instead of it's normal proficiency.
edit - most of them will no longer show up on the record screen, after people complained about seeing empty entries from certain spells that used them as scripting stats.
Thanks!
If you don't want to risk breaking things, you should treat it the same, and only use timing modes 1/4/7.
The problem with it, is that when multiple instances of the opcode are applied at the same time, all but the last one is effectively treated as using timing mode 1 anyway, making permanent changes to the creature.
There are also circumstances in the game which will do the same - making any temporary changes to these IDS states permanent. One such is summoning a creature - any temporary changes to it's GENDER that are present when it is summoned are made permanent.
I suspect the mechanics behind these events are linked, but it's beyond my scope.
I see.
I was asking because I'd like to tweak WIZARD_POLYMORPH_SELF (and related spells). In particular, I'd like to provide different forms, one of them being an UNDEAD (i.e., having all the bonuses provided by RING95.itm). So in order not to trick the AI I add opcode #72 (timing mode 2, GENERAL = UNDEAD) to the creature weapon........
But if I do this, then I need to add opcode #72 to all the other forms (including the Human one) and set GENERAL back to 1 (i.e., HUMANOID), otherwise I'll be permanently flagged as an UNDEAD.....
The only problem is that the caster of WIZARD_POLYMORPH_SELF must be HUMANOID or the spell will overwrite its original GENERAL... But this should not be a problem since the AI is not supposed to cast that spell, isn't it (even if we take into account SCS)?
Alternatively, I could add a dummy spellstate and edit all scripts that make use of the trigger
!General([object],UNDEAD)
and add something like!CheckSpellState([object],DUMMY_SPELLSTATE)
............But this solution does sound pretty complicated, right?
(I don't currently use Polymorph Self in SCS, and as far as I know it's not in any other AI either, but that's how I'd use it if I ever introduced it.)
I guess it'd be something like:
My general advice is that all this looks fairly dangerous: wholesale search-and-replace on the entire script system, and a condition that isn’t removed automatically but has to be caught manually, all for a fairly minor AI improvement (the AI very rarely checks the UNDEAD status of its targets, because most players aren’t undead).
Moreover, all of this is needed only for SoD because I assume SCS is able to recognize (somehow) if a certain effect is dispellable or not. Right?
How can I take into account Hold Person (and related spells) and Charm Person (and related spells)? Is this enough/good/safe?
Moreover, we should probably exclude the object 'Myself' from the regexp........
Speaking of this, what Polymorph_Self-like spells does SCS use?
Oh, wait, there may be an alternative: what about giving the creature weapon some key splstates/stats via opcode #328 or opcode #233 as equipping effects (timing mode = 2)? For example: RESIST_FEAR (to counter opcode #24), CHAOTIC_COMMAND (to counter opcodes #39, #5, #128), CLERIC_FREE_ACTION (to counter opcodes #175, #109) (am I missing something?)
Yes, sure, there is still the possibility that some spells will be wasted in any case (if the AI doesn't check for those splstates), but, after a quick look at some scripts, this seems to be intentional, right ( @Ardanis ?)
I would not use CLERIC_FREE_ACTION, as CHAOTIC_COMMANDS already handles those opcodes, and you should still be subject to targeting by spells such as Slow.
Level Drain: NEGATIVE_PLANE_PROTECTION // Scripting State 3
Slay: DEATH_WARD // Scripting State 2, but this also blocks Disintigration, which undead are subject to, though I don't think you'll come across it in SoD.
CheckStatGT(LastSeenBy(Myself),0,CLERIC_CHAOTIC_COMMANDS,Dispellable)
Thanks for reminding me about Level Drain and Death Ward, but at this point is probably better to edit the scripts (or give up .......)