Skip to content

General mod Questions thread

1363739414270

Comments

  • [Deleted User][Deleted User] Posts: 0
    edited February 2019
    The user and all related content has been deleted.
    Post edited by [Deleted User] on
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    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?
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    Is it possible to add a custom entry to WEAPPROF.2da? If so, how?
  • The user and all related content has been deleted.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535

    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......
  • kjeronkjeron Member Posts: 2,367
    edited January 2019
    Luke93 said:

    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.
  • ReddbaneReddbane Member Posts: 222
    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.
  • The user and all related content has been deleted.
  • The user and all related content has been deleted.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited January 2019
    kjeron said:


    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?
  • ReddbaneReddbane Member Posts: 222
    @subtledoctor
    Thanks!
  • kjeronkjeron Member Posts: 2,367
    Luke93 said:

    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.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited January 2019
    @kjeron

    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?
  • kjeronkjeron Member Posts: 2,367
    Luke93 said:

    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.
    Luke93 said:

    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.
    Luke93 said:

    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.
    Luke93 said:

    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.
  • DavidWDavidW Member Posts: 823
    kjeron said:

    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.)

  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited January 2019
    kjeron said:

    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........
    kjeron said:

    This would likely be the most practical solution, but you still run the risk of not catching scripts installed after your mod.

    May I ask you for help?
    I guess it'd be something like:
    COPY_EXISTING_REGEXP ~.*\.bcs~ ~override~
      DECOMPILE_AND_PATCH BEGIN
        REPLACE_TEXTUALLY EXACT_MATCH ~!General([regexp],UNDEAD)~ ~!General([regexp],UNDEAD)
    !CheckSpellState([regexp],MY_DUMMY_SPLSTATE)~
      END
    BUT_ONLY
    Post edited by _Luke_ on
  • kjeronkjeron Member Posts: 2,367
    COPY_EXISTING_REGEXP ~.*\.bcs~ ~override~
      DECOMPILE_AND_PATCH BEGIN
        REPLACE_TEXTUALLY
    	 ~!General(\([^,]+\),UNDEAD)~
    	 ~!General(\1,UNDEAD)
    	!CheckSpellState(\1,MY_DUMMY_SPLSTATE)~
      END
    BUT_ONLY
    I don't think it would make sense for that trigger to be in an OR block, so this should be safe.
  • DavidWDavidW Member Posts: 823
    kjeron said:


    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).

  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    DavidW said:

    kjeron said:


    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.
    We're replacing !General (notice the Not in front). Having said that, I think I should exclude 'Myself' from that regexp ( @kjeron is it possible :) ?)

    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?
  • kjeronkjeron Member Posts: 2,367
    DavidW said:

    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.
    DavidW said:

    (the AI very rarely checks the UNDEAD status of its targets, because most players aren’t undead).

    Maybe in vanilla, but the EE scripts check it quite a bit. Especially since they have to account for Hexxat now.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited January 2019
    kjeron said:

    COPY_EXISTING_REGEXP ~.*\.bcs~ ~override~
      DECOMPILE_AND_PATCH BEGIN
        REPLACE_TEXTUALLY
    	 ~!General(\([^,]+\),UNDEAD)~
    	 ~!General(\1,UNDEAD)
    	!CheckSpellState(\1,MY_DUMMY_SPLSTATE)~
      END
    BUT_ONLY
    I don't think it would make sense for that trigger to be in an OR block, so this should be safe.
    Thanks!

    How can I take into account Hold Person (and related spells) and Charm Person (and related spells)? Is this enough/good/safe?
    COPY_EXISTING_REGEXP ~.*\.bcs~ ~override~
      DECOMPILE_AND_PATCH BEGIN
        REPLACE_TEXTUALLY
    	 ~!Kit(\([^,]+\),INQUISITOR)~
    	 ~!Kit(\1,INQUISITOR)
    	!CheckSpellState(\1,MY_DUMMY_SPLSTATE)~
      END
    BUT_ONLY


    Moreover, we should probably exclude the object 'Myself' from the regexp........
  • ArdanisArdanis Member Posts: 1,736
    There's REFACTOR_TRIGGER or something, that works correctly with OR() blocks at the expense of increased processing time.
  • DavidWDavidW Member Posts: 823
    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.
  • kjeronkjeron Member Posts: 2,367
    Luke93 said:

    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.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    DavidW said:

    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?
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    kjeron said:

    Luke93 said:

    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.....
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited January 2019
    @kjeron

    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 ?)
  • kjeronkjeron Member Posts: 2,367
    Luke93 said:

    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.
  • kjeronkjeron Member Posts: 2,367
    Luke93 said:

    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.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited January 2019
    kjeron said:

    Luke93 said:

    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:

    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 :( .......)
Sign In or Register to comment.