Skip to content

General mod Questions thread

1131416181970

Comments

  • RaduzielRaduziel Member Posts: 4,714
    edited February 2018
    I need some help.

    I'm trying to build a macro based on @CamDawg 's SPELL_TO_INNATE
    DEFINE_PATCH_MACRO ~BLESS_OF_RECOGNITION~ BEGIN

    READ_LONG 0x64 ex_off ELSE 0
    READ_SHORT 0x68 glob_ex ELSE 0
    WRITE_SHORT 0x1C 4 //Type to "Innate"
    WRITE_LONG 0x34 1 //Spell Level to "1"
    FOR (j = 0; j < glob_ex; ++j) BEGIN
    WRITE_SHORT (ex_off + 0x0C + (0x28 * j)) 5 //Target to "Self"
    WRITE_LONG (ex_off + 0x0E + (0x28 * j)) 1 //Range to "1"
    WRITE_SHORT (ex_off + 0x12 + (0x28 * j)) 0 //Casting Time to "0"
    WRITE_SHORT (ex_off + 0x02 + (0x28 * j)) 0 //Location to "None"
    END
    READ_LONG 0x6e ca_off ELSE 0
    READ_SHORT 0x70 glob_ca ELSE 0
    FOR (k = 0; k < glob_ca; ++k) BEGIN
    WRITE_SHORT (ca_off + 0x0C + (0x30 * k)) 9 //Duration to "Permanent After Death"
    WRITE_SHORT (ca_off + 0x12 + (0x30 * k)) 2 //Target to "Pre-Target"
    WRITE_SHORT (ca_off + 0x0D + (0x30 * k)) 0 //Resistance to "Non-Magical"
    END
    END
    The second part of the macro (Duration, Target and Resistance) is not working: they should be set as 9, 2 and 0, but are the same as the COPY_EXISTING spell that I'm running the macro upon.

    What am I doing wrong?

    Thanks!
  • CamDawgCamDawg Member, Developer Posts: 3,438
    The offsets at 0x6e and 0x70 cover the global effects of a spell; you're looking for the effects attached to abilities. You'd need to loop within your ability loop to do it.

    There's absolutely no reason why you can't wrap macros in macros:
    DEFINE_PATCH_MACRO ~BLESS_OF_RECOGNITION~ BEGIN

    WRITE_SHORT 0x1C 4 //Type to "Innate"
    WRITE_LONG 0x34 1 //Spell Level to "1"
    LPF ALTER_SPELL_HEADER INT_VAR target = 5 range = 1 speed = 0 location = 0 END
    LPF ALTER_EFFECT INT_VAR target = 2 timing = 9 resist_dispel = 0 END

    END
  • RaduzielRaduziel Member Posts: 4,714
    That much cleaner and easier.

    And works.

    I'm feeling very stupid ATM, I'll hide in the shadows for a moment.

    Thanks, @CamDawg
  • ArunsunArunsun Member Posts: 1,592
    Is there a simple way to make a spell that reduces attack per round by an amount? Like, say, an AoE that reduces your number of attack per round by 0.5 while your in it?
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535

    @Luke93: I'm afraid that's hardcoded stuff. It's possible to make that visible, but only if Beamdog made a change to the source code. That's actually how IWD2 works by default.

    What a pity! I opened a feature request on Redmine. I do think this feature will be a nice addition to these games....
  • RaduzielRaduziel Member Posts: 4,714
    Arunsun said:

    Is there a simple way to make a spell that reduces attack per round by an amount? Like, say, an AoE that reduces your number of attack per round by 0.5 while your in it?

    Have you tried making a Cloudkill and changing Opcode12 for Opcode1?

    I did something similar for a Blindness-like spell and worked that way.
  • RaduzielRaduziel Member Posts: 4,714
    CamDawg said:

    The offsets at 0x6e and 0x70 cover the global effects of a spell; you're looking for the effects attached to abilities. You'd need to loop within your ability loop to do it.

    There's absolutely no reason why you can't wrap macros in macros:

    DEFINE_PATCH_MACRO ~BLESS_OF_RECOGNITION~ BEGIN

    WRITE_SHORT 0x1C 4 //Type to "Innate"
    WRITE_LONG 0x34 1 //Spell Level to "1"
    LPF ALTER_SPELL_HEADER INT_VAR target = 5 range = 1 speed = 0 location = 0 END
    LPF ALTER_EFFECT INT_VAR target = 2 timing = 9 resist_dispel = 0 END

    END
    If anyone's is interested I played a bit with this code CamDawg gave and make a macro that may be useful for making kits:
    // Thanks CamDawg for saving me with this

    DEFINE_PATCH_MACRO ~SPELL_TO_KIT_FEATURES~ BEGIN

    WRITE_SHORT 0x1C 4
    WRITE_LONG 0x34 1
    WRITE_LONG 0x22 00
    LPF ALTER_SPELL_HEADER INT_VAR projectile = 0 target = 5 range = 1 speed = 0 location = 0 END
    LPF DELETE_SPELL_EFFECT INT_VAR opcode_to_delete = 9 END
    LPF DELETE_SPELL_EFFECT INT_VAR opcode_to_delete = 50 END
    LPF DELETE_SPELL_EFFECT INT_VAR opcode_to_delete = 139 END
    LPF DELETE_SPELL_EFFECT INT_VAR opcode_to_delete = 141 END
    LPF DELETE_SPELL_EFFECT INT_VAR opcode_to_delete = 174 END
    LPF DELETE_SPELL_EFFECT INT_VAR opcode_to_delete = 215 END
    LPF ALTER_EFFECT INT_VAR target = 2 timing = 9 duration = 0 resist_dispel = 0 END

    END
    So, let's say you want a kit that is always under the effect of Death Ward.

    Just...
    COPY_EXISTING ~SPPR409.spl~ ~override\SPELLNAMEFORTHEKIT.spl~
    LPM SPELL_TO_KIT_FEATURES
    Hope it helps.
  • ArunsunArunsun Member Posts: 1,592
    Raduziel said:

    Arunsun said:

    Is there a simple way to make a spell that reduces attack per round by an amount? Like, say, an AoE that reduces your number of attack per round by 0.5 while your in it?

    Have you tried making a Cloudkill and changing Opcode12 for Opcode1?

    I did something similar for a Blindness-like spell and worked that way.
    The issue is not really making the AoE but reducing the number of attack per round. OPcode1 allows either setting to/incrementing by a positive number between .5 and 5 attacks per round, or set to a %. I could write less than 100% but that would obviously make the resulting number of attacks depend on the original number. Not sure about whether it's rounded up or down either.
    I'm looking for a way to make it so a character with 1 attack per round would be lowered to .5, for example, and a character with 2 attacks per rounds would be lowered to 1.5. A flat decrease.

    The only solution I can think of is using splprot.2da to check current APR and use set final to set it to that -0.5 but this is tedious :smiley:
  • The user and all related content has been deleted.
  • ArunsunArunsun Member Posts: 1,592

    Can opcode 1 not take a negative modifier? I thought it could.

    One option is to set base APR to 0.5. Bonuses from level/proficiency/spells will still apply pn top of that, and most people's base APR is 1, so it would act like an effective -.5 modifier.

    But it depends on what exactly you're doing with this. If this is an offensive thing that can be used against creatures with naturally high APR that could be way too powerful.

    At least in NI (and IESDP confirms) it only takes value 1 to 10, with 1 to 5 being positive integer 1 to 5 and 6 to 10 being 0.5 to 4.5. Haven't tried forcing the negative modifier though.
  • kjeronkjeron Member Posts: 2,367
    Negative values for opcode 1 scale the same as the positive values, they just aren't listed:
    -1 = -1
    -2 = -2
    -3 = -3
    -4 = -4
    -5 = -5
    -6 = -1/2
    -7 = -3/2
    -8 = -5/2
    -9 = -7/2
    -10 = -9/2
  • The user and all related content has been deleted.
  • ArdanisArdanis Member Posts: 1,736
    CamDawg said:


    There's absolutely no reason why you can't wrap macros in macros:

    Yo Dawg, I heard you like macros...
  • RaduzielRaduziel Member Posts: 4,714
    I have a question.

    Let's say I'm making a spell with Duration = 1 Round/lv that can be casted starting at level X.

    So the Duration for X = 6, for X+1 = 12, etc...

    Is there a way to automatically fill this? Because what I do is manually change every effect in every field and it can be a pain sometimes.

    Thanks!
  • The user and all related content has been deleted.
  • ArunsunArunsun Member Posts: 1,592
    edited February 2018
    Guys I'm going crazy with something that's probably stupid.

    I'm trying to create a pack of abilities with a global cooldown of 30 seconds and unlimited use. So if you use one, you won't be able to use any of them for 30 sec, and then once that time has expired you can cast another one.
    I proceeded with the classic Remove Spell (instant/permanent until death timing)+ Give Innate Ability (Delay/permanent with 30sec delay) combination, but for some reason the Remove Spell OPcode won't work. I litterally copy-pasted it from another spell from the game (Pocket Plane spell) and just changed the resource file and it won't work on my spell though it works perfectly well on the original spell (with the right resource). I tried changing the timings to Instant/Permanent, I tried putting the Remove Spell first, the Give Ability first (shouldn't matter since Give Ability is delayed), I tried changing the dispel/resistance to Natural/Nonmagical, it still won't work. Here are two screenshots, showing the Give Ability effect and the Remove Ability effect. Please tell me if you see anything wrong, I've been stuck on that for an hour.




    The Give Innate Ability however works very well, and thus my ability numbers keep going up.


    EDIT: Found a workaround since apparently Remove Spell was working on the spell I cast but not the others. Still curious as to why my former implentation wouldn't work though.
    Post edited by Arunsun on
  • The user and all related content has been deleted.
  • ArunsunArunsun Member Posts: 1,592

    @Arunsun for opcode 172 to work fully you need to make sure the filename of the spell being removed is 7 letters or less.

    Even though resources are up to 8 characters in just about every other field? Infinity Engine and its secret tricks :sweat:
  • The user and all related content has been deleted.
  • CamDawgCamDawg Member, Developer Posts: 3,438

    That's one reason I don't do x/level anymore when I make spells. I just do reasonable power bumps at 5/10/15/20, or 6/12/18 or something like that.

    Best way is probably to enlist Weidu, make a little temporary mod with

      PATCH_FOR_EACH level IN ~5~ ~6~ ~7~ [etc.] BEGIN
    LPF ALTER_SPELL_HEADER ...
    Copy the resulting file out of /override, then uninstall the mod. Change it later for the next thing. I have a little temp mod that I leep around got stuff like this, when I can write up the .tp2 code faster than I can edit things in NI.
    For the record, you can avoid this little dance through two methods. First is to copy (or copy_existing) with the no-backup option:
    COPY + ~mymod/foo.spl~ ~mymod/bar.spl~
    // WeiDU changes etc.
    The magic + sign means no backup--so if you uninstall this component, bar.spl remains. The bad news means that your changes are permanent, so always choose a destination file different than your source file, just in case.

    The no-backup idea can be extended to an entire component with the NO_LOG_RECORD flag:
    BEGIN ~making spells~ NO_LOG_RECORD

    COPY ~mymod/foo.spl~ ~mymod/temp/bar.spl~
    // WeiDU changes etc.
    A component set up this way never gets entered into weidu.log. It's the no-backup flag extended to an entire component. Same caution as above--changes are permanent, so I strongly suggest you route all output into new files.
  • RaduzielRaduziel Member Posts: 4,714
    edited February 2018
    Question:

    Let's say I have a kit and I don't want this kit to use an specific spell - so I remove it from the kits spellbook.

    Or I don't want it to be able to cast spells at all (like the Inquisitor).

    How do I remove specific spells or clear entirely the spellbook of a kit?

    The only way I know how to do this is applying an effect every single level (that's what I did with my Circle Enforcer and Spirit Redeemer).

    Is there a better, cleaner way of doing this?

    Thanks!

    Edit: I know that I can disable spellcasting for situations like the Inquisitor (I did it for my Undead Predator), the question is about cleaning (partially or entirely) a spellbook.
  • [Deleted User][Deleted User] Posts: 0
    edited February 2018
    The user and all related content has been deleted.
  • ArunsunArunsun Member Posts: 1,592
    edited February 2018
    I would like to make an HLA that modifies a dialog option (crafting dialog) and would need to change a local variable to do that.
    What OPcode should I use? 187 or 309? I remember one of them giving me troubles because it didn't work as it should but that was prior to v2.0 IIRC and I can't remember which it is. From what IESDP says both appear to be pretty similar except 187 can only be called through eff files and allows longer variable name (which I don't need).
    Is it safer to do it through another dialog?
  • RaduzielRaduziel Member Posts: 4,714

    For divine casters? It's either 1) apply the 172 effect every level (and watch out, canny players will level-up with the game on pause and memorize the spell before it disappears), or 2) devise a whole frackin' sphere system.

    To use an understatement, neither is perfect.

    Opcode 172 every level is what I'm using ATM. I was hoping for a more elegant solution.

    Thanks :)
  • The user and all related content has been deleted.
  • ArunsunArunsun Member Posts: 1,592
    edited February 2018

    Arunsun said:

    I would like to make an HLA that modifies a dialog option (crafting dialog) and would need to change a local variable to do that.
    What OPcode should I use? 187 or 309? I remember one of them giving me troubles because it didn't work as it should but that was prior to v2.0 IIRC and I can't remember which it is. From what IESDP says both appear to be pretty similar except 187 can only be called through eff files and allows longer variable name (which I don't need).
    Is it safer to do it through another dialog?

    Never done that through an opcode. Any way you start a dialog is probably going to go through a script first, and I just set locals in that script.
    Well I might not have expressed what I want to do clearly, but to sum it up:
    -The kit I am working on will have a potion crafting innate ability that will take the form of a dialog (much like T&B arcane crafting).
    -These potions will be specific to the kit and have one basic version (available from level 1) and one enhanced version.
    -For each potion you want to enhance you will have to pick an HLA, and that HLA modifies the dialog option within the dialog so that you will get to craft the enhanced version instead of the basic one.
    -But the HLA itself doesn't trigger the dialog so no way to change the local variable through a script.

    The options I am looking at right now are:
    -I create a one-state dialog that simply says "This potion type is now enhanced" and sets the variable, and the HLA triggers that dialog. This is the safe option, I know it works but it is less elegant than doing it invisibly
    -Or I could use these OPcodes. This option is better if it works, because it will do its job without showing anything to the player, but I am unsure whether they work as intended.


    EDIT: Just made the testing using opcode 309, it worked as intended. Oh and my night sleep reminded me of what was faulty in one of the OPcode: if you increment a local variable several times at once, only one incrementation will be taken into account. I encountered the issue while designing my warlock kit, I used the opcodes to increment the variables that served to say whether you still have an invocation to select, but when creating your character in BG2 for instance, you would get 4 incrementations on the "least invocation" variable, according to the level table, and only 1 was taken into account.
    Post edited by Arunsun on
  • BubbBubb Member Posts: 1,000
    I'm trying some AI scripting out, and there is one thing that is eluding me: object specifiers. IESDP gives this as an example: [ENEMY.0.0.MAGE]. I've tried to find some sort of documentation on these things, but I've never found any comprehensive guides, just passing references. Maybe I'm just really bad at google, but can someone link me to some explanation / help enlighten me on the topic? What is their format, what are the possible values, how do they work, etc. Thanks!
  • CamDawgCamDawg Member, Developer Posts: 3,438
    Sim's scripting guide is old but solid:

    These can be used to cut down the range of objects that return as valid from a trigger. They take the form [EA.GENERAL.RACE.CLASS.SPECIFIC.GENDER.ALIGN]. So, for example, instead of See([ANYONE]), you could use See([0.0.HUMAN.MAGE_ALL.0.0.MASK_GOOD]) to return any human good aligned mages.

  • ArunsunArunsun Member Posts: 1,592
    edited February 2018
    I am having issues with scripting a dialog state with actions.

    Here's what a typical block looks like:

    IF ~~ thunderbolt
    SAY ~Thunderbolt increases physical damage both dealt and received by 30%. You can brew 2 of them using any potion of strength you have available.~
    +~PartyHasItem("POTN44")~+ ~Brew using Potion of Strength~ DO ~CreateItem("ZKWTTHUN",2,0,0) ActionOverride(ZKWTBREW,TakePartyItem("POTN44"))~ +brew
    +~PartyHasItem("POTN03")~+ ~Brew using Potion of Hill Giant Strength~DO ~CreateItem("ZKWTTHUN",2,0,0) ActionOverride(ZKWTBREW,TakePartyItem("POTN03"))~ +brew
    +~PartyHasItem("POTN04")~+ ~Brew using Potion of Frost Giant Strength~DO ~CreateItem("ZKWTTHUN",2,0,0) ActionOverride(ZKWTBREW,TakePartyItem("POTN04"))~ +brew
    +~PartyHasItem("POTN05")~+ ~Brew using Potion of Fire Giant Strength~DO ~CreateItem("ZKWTTHUN",2,0,0) ActionOverride(ZKWTBREW,TakePartyItem("POTN05"))~ +brew
    +~PartyHasItem("POTN06")~+ ~Brew using Potion of Cloud Strength~DO ~CreateItem("ZKWTTHUN",2,0,0) ActionOverride(ZKWTBREW,TakePartyItem("POTN06"))~ +brew
    +~PartyHasItem("POTN07")~+ ~Brew using Potion of Storm Giant Strength~DO ~CreateItem("ZKWTTHUN",2,0,0) ActionOverride(ZKWTBREW,TakePartyItem("POTN07"))~ +brew
    +~PartyHasItem("POTN12")~+ ~Brew using Potion of Stone Giant Strength~DO ~CreateItem("ZKWTTHUN",2,0,0) ActionOverride(ZKWTBREW,TakePartyItem("POTN12"))~ +brew
    +~TRUE()~+~Brew something else~+brew



    What I want to do is basically to trade potions for other potions. ZKWTBREW is the creature I summon to trigger the dialog, and I thought it could serve as the thing that takes the potions for the party and then destroy them (didn't implement the destroy part yet since the TakePartyItem won't work for now).

    So, first question, is what I want to do doable staying into one dialog (i.e. using ActionOverride) or do I have to make a secondary dialog so that my created creature will actually be able to pick the items? If the first option's a yes, what am I doing wrong?

    Second question, IESDP says that TakePartyItem takes entire stacks at once, and it can't remove a single instance of an item if these items are stacked. Is there a workaround to that? A way to take a single item from a stack? Maybe using the GiveItem action? IESDP doesn't reference having this issue of taking entire stacks.
    Post edited by Arunsun on
  • RaduzielRaduziel Member Posts: 4,714
    edited February 2018
    @Arunsun

    Why not make it as a .spl?

    Thunderbolt

    Op214 (Op139 ~Choose the potion you want to use~)

    Spl1 Op123 (Resource: POTN03) / Op122 (Resource: ZKWTTHUN)
    Spl2 Op123 (Resource: POTN04) / Op122 (Resource: ZKWTTHUN)
    Spl3 Op123 (Resource: POTN05) / Op122 (Resource: ZKWTTHUN)
    Spl4 Op123 (Resource: POTN06) / Op122 (Resource: ZKWTTHUN)
    Spl5 Op123 (Resource: POTN07) / Op122 (Resource: ZKWTTHUN)
    Spl6 Op123 (Resource: POTN12) / Op122 (Resource: ZKWTTHUN)
    Spl7 Op123 (Resource: POTN44) / Op122 (Resource: ZKWTTHUN)

    Edit: You can even name every SplX as the name of the potion and use the potion BAM to make it even more intuitive.

    Edit: I think you can even use Op324 for AreaType != City, so this spell would not be able to be cast in a forest - what I think would make sense in an RP PoV.
Sign In or Register to comment.