Skip to content

General mod Questions thread

1444547495070

Comments

  • RaduzielRaduziel Member Posts: 4,714
    edited March 2019
    Ulb wrote: »
    @Raduziel
    Are you talking about swapping the palette of the actual animation or is this solely about the inventory bam? If it's the later, you could also simply extract it as graphics and then edit those with a tool like gimp or photoshop and rebuild the bam. It's very straight forward and will probably yield better results.

    @Ulb

    Only the inventory. The game already gives the animation per se. The inventory is given for the black bear and the brown bear, but not for the polar bear (even if in IWD a druid can shapeshif into a polar bear).

    I've tried editing it using a image editor and NI - both result were ugly as punching a kid (you can see it a few posts above).

    @argent77 I'll give it a try and will report to you (through PM or at NI's thread to keep this one clean). Thanks!
  • RaduzielRaduziel Member Posts: 4,714
    How do I remove a spell from the game?

    I'm combining several spells into one, so I don't want those spells to-be-combined to be available at chargen and for Sorcerer/Shamans at level up.

    I also want to search every store and container to remove the scrolls from those spells and replace with the new spell I'm creating.

    Thanks!
  • The user and all related content has been deleted.
  • RaduzielRaduziel Member Posts: 4,714
    Do not remove spells from the game! :fearful:

    To remove its availability at CharGen, just append it to hidespl.2da. (And note, that file has a different number of columns in different games.) To remove scrolls you can patch stores and containers (there are macros, I think), or just overwrite the scroll with another, valid one (my incredibly lazy alternate method :lol: )

    @subtledoctor

    That's what I meant, lol.

    Can you teach me to do the lazy-overwrite way?

    The problem with it, I think, is that a store that sells "Spell A and Spell B", both to be replaced, would display two entries of the same item "Spell C". Or am I wrong?

    That's why I was thinking about removing the old ones and adding the new one.
  • The user and all related content has been deleted.
  • RaduzielRaduziel Member Posts: 4,714
    edited March 2019
    Thanks!

    I'll take a look soon, at the moment I'm building the new spells per se.

    Probably the macros can be found at G3's forum, right? I'll take a look there.

    Again, thanks!

    Edit:

    @subtledoctor

    Do you know if I can do something like the following:
    
    ACTION_FOR_EACH scroll IN ((SCROLLS LIST)) BEGIN
    
    
    ACTION_IF FILE_CONTAINS scroll BEGIN
    
    COPY_EXISTING_REGEXP ~.*\.sto~ ~override~
    ADD_STORE_ITEM ~newscroll~ BEFORE ~%scroll%~ #0 #0 #0 ~IDENTIFIED~ #2
    REMOVE_STORE_ITEM ~%scroll%~
    BUT_ONLY IF_CHANGES
    
    END
    END
    
  • GwendolyneGwendolyne Member Posts: 461
    edited March 2019
    Don't waste your time, use the code I wrote for 1pp update:

    // Jahaboam (Dock)
    ACTION_IF (FILE_EXISTS_IN_GAME ~dshop02.sto~ AND FILE_EXISTS_IN_GAME ~shld01a.itm~) BEGIN
    	COPY_EXISTING ~dshop02.sto~ ~override~
    		LPF REPLACE_STORE_ITEM INT_VAR number_in_stock = 3 STR_VAR old_item = SHLD01 new_item = SHLD01A flags = IDENTIFIED END	// Small shield
    		LPF REPLACE_STORE_ITEM INT_VAR number_in_stock = 2 STR_VAR old_item = SHLD03 new_item = SHLD03A flags = IDENTIFIED END	// Medium shield
    		LPF REPLACE_STORE_ITEM INT_VAR number_in_stock = 2 STR_VAR old_item = SHLD05 new_item = SHLD05A flags = IDENTIFIED END	// Large shield
    		LPF REPLACE_STORE_ITEM INT_VAR number_in_stock = 3 STR_VAR old_item = SHLD08 new_item = SHLD08A flags = IDENTIFIED END	// Buckler
    	BUT_ONLY
    END
    

    WeiDU functions save a lot of coding lines.
  • RaduzielRaduziel Member Posts: 4,714
    edited March 2019
    @Gwendolyne Thanks!

    But don't I need the name of the store and item to use this code?

    Wait
    ACTION_FOR_EACH scroll IN ((SCROLLS LIST)) BEGIN
    
    ACTION_IF FILE_EXISTS_IN_GAME ~%scroll%~ BEGIN
    	COPY_EXISTING_REGEXP ~.*\.sto~ override
    		LPF REPLACE_STORE_ITEM INT_VAR number_in_stock = 2 STR_VAR old_item = scrolltobereplaced1 new_item = newscroll1 flags = IDENTIFIED END
    		LPF REPLACE_STORE_ITEM INT_VAR number_in_stock = 2 STR_VAR old_item = scrolltobereplaced2 new_item = newscroll1 flags = IDENTIFIED END
    		LPF REPLACE_STORE_ITEM INT_VAR number_in_stock = 2 STR_VAR old_item = scrolltobereplaced3 new_item = newscroll1 flags = IDENTIFIED END
    		LPF REPLACE_STORE_ITEM INT_VAR number_in_stock = 2 STR_VAR old_item = scrolltobereplaced4 new_item = newscroll1 flags = IDENTIFIED END
    	BUT_ONLY
    END
    END
    

    Do you mean like that?

    Don't it also create the issue of double entries of the same item at the stores?
    Post edited by Raduziel on
  • The user and all related content has been deleted.
  • RaduzielRaduziel Member Posts: 4,714
    FILE_EXISTS_IN_GAME - FILE_EXISTS will check whether the file is on your hard drive. :hushed:

    Fixed, thanks for noticing!
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited March 2019
    Bubb wrote: »
    @Raduziel: p1 = 50, p2 = 2 is correct, I've tested it by modifying some boots of haste. How are you applying the opcode and to what creature are you doing so?

    I also have some problems with
    p2 = Set % of
    

    In particular, (opcode #73 - Attack damage modifier) if I set p1 = 50 and p2 = 2, the damage output of my targeted creature doesn't seem to be reduced by 50% :( ...... (even if I put p1 = "-50".....) Am I missing something?

    On the other hand, everything seems to work fine if I use opcode #332 (Stat: Specific Damage Modifier), p1 = "-50"..... But I'd like to alter the base damage so that "X damage resisted" doesn't get displayed in the combat log.....
  • kjeronkjeron Member Posts: 2,367
    Luke93 wrote: »
    In particular, (opcode #73 - Attack damage modifier) if I set p1 = 50 and p2 = 2, the damage output of my targeted creature doesn't seem to be reduced by 50% :( ...... (even if I put p1 = "-50".....) Am I missing something?

    On the other hand, everything seems to work fine if I use opcode #332 (Stat: Specific Damage Modifier), p1 = "-50"..... But I'd like to alter the base damage so that "X damage resisted" doesn't get displayed in the combat log.....
    Opcode 73 modifies that specific stat (#50 DAMAGEBONUS), the stats final value is added to weapon damage. You can use it to apply a negative increment value to reduce the damage dealt (min:1), but not by a percentage.
    Opcode 332 meanwhile does modify total damage.
  • GoidaGoida Member Posts: 118
    Does anyone know how to make Weidu recognize zero-length strings? I'm looking for a way to find creatures who don't have anything in their Override script field (0x248).

    And is there an example of a mod that puts items in stores of such-and-such type? For example, custom swords should only appear in stores that don't have stealing and do both buy and sell and so on. I would have a look at the code there.
  • switswit Member, Translator (NDA) Posts: 495
    READ_ASCII 0x248 ~script~ (8) NULL
    PATCH_IF (~%script%~ STR_EQ ~~) OR (~%script%~ STR_EQ ~NONE~) BEGIN
    	//do your patching
    END
    
  • GoidaGoida Member Posts: 118
    edited March 2019
    swit wrote: »
    READ_ASCII 0x248 ~script~ (8) NULL
    PATCH_IF (~%script%~ STR_EQ ~~) OR (~%script%~ STR_EQ ~NONE~) BEGIN
    	//do your patching
    END
    

    Thank you. It works, but I also need to phase out (remove) the script in the override slot.

    COPY_EXISTING_REGEXP GLOB ~.*\.CRE~ ~override~

    READ_BYTE 0x272 race /// gnolls
    READ_ASCII 0x248 override (8) NULL /// have a useless override script
    READ_ASCII 0x250 class (8) NULL /// and usually nothing on the class level

    PATCH_IF race = 110 & (~%override%~ STRING_EQUAL_CASE ~GNOLLF~) & ((~%class%~ STRING_EQUAL_CASE ~~) OR (~%class%~ STRING_EQUAL_CASE ~NONE~)) /// so if that's the case...

    THEN BEGIN

    WRITE_ASCII 0x248 ~~ /// empty the override level
    WRITE_ASCII 0x250 ~GNOLLF~ /// move the script to the class level

    END

    BUT_ONLY

    That's the gist of it. How do I fill override with nothing? Writing ~~ doesn't change anything.
  • GoidaGoida Member Posts: 118
    Why doesn't this work?
    COPY_EXISTING_REGEXP GLOB ~.*\.STO~ ~override~
    
    READ_BYTE  0x8 type
    READ_SHORT 0x10 kind
    
    PATCH_IF
    
    type = 0 & ((kind BAND 0b0001000001101111) =  0b0000000000000111)
    
    THEN BEGIN...
    

    Is the syntax mistaken or am I using selection criteria no store satisfies?
  • RaduzielRaduziel Member Posts: 4,714
    edited March 2019
    Miss me?

    Ok, I have a scroll that I want to turn into another scroll. To do it I'm doing the following:
    LAF   RES_NUM_OF_SPELL_NAME STR_VAR	spell_name = ~WIZARD_RADUZIEL_FIRESHIELD~ RET spell_1 = spell_res END
    LAF   RES_NUM_OF_SPELL_NAME STR_VAR	spell_name = ~WIZARD_RADUZIEL_EMOTION~    RET spell_2 = spell_res END
    LAF   RES_NUM_OF_SPELL_NAME STR_VAR	spell_name = ~WIZARD_RADUZIEL_SYMBOL~     RET spell_3 = spell_res END
    
    COPY_EXISTING ~SCRL1W.itm~ ~override/SCRLFSD.itm~
    SAY NAME1 @9999275 SAY NAME2 @9999275 SAY UNIDENTIFIED_DESC @9999277 SAY DESC @9999277
    LPF ALTER_ITEM_EFFECT INT_VAR match_opcode = ~-1~ STR_VAR resource = EVAL ~%spell_1%~ END
    LPF ALTER_ITEM_EFFECT STR_VAR icon = EVAL ~%spell_1%A~                                END
    
    COPY_EXISTING ~SCRL1W.itm~ ~override/SCRLEMO.itm~
    SAY NAME1 @9999278 SAY NAME2 @9999278 SAY UNIDENTIFIED_DESC @9999280 SAY DESC @9999280
    LPF ALTER_ITEM_EFFECT INT_VAR match_opcode = ~-1~ STR_VAR resource = EVAL ~%spell_2%~ END
    LPF ALTER_ITEM_EFFECT STR_VAR icon = EVAL ~%spell_2%A~                                END
    
    COPY_EXISTING ~SCRL9F.itm~ ~override/SCRLSYM.itm~
    SAY NAME1 @9999281 SAY NAME2 @9999281 SAY UNIDENTIFIED_DESC @9999283 SAY DESC @9999283
    LPF ALTER_ITEM_EFFECT INT_VAR match_opcode = ~-1~ STR_VAR resource = EVAL ~%spell_3%~ END
    LPF ALTER_ITEM_EFFECT STR_VAR icon = EVAL ~%spell_3%A~                                END
    
    CLEAR_ARRAYS
    

    But nothing is happening. The new scroll has the correct name and description, but the Cast Spell/Learn Spell keeps referring themselves to the old spell, and I've changed the wrong icon (the icon was a long shot, but I could swear that at least the opcode would be altered properly).

    The results are attached so you can see and laugh.

    What am I doing wrong?

    Thanks.
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited March 2019
    Goida wrote: »
    Why doesn't this work?
    COPY_EXISTING_REGEXP GLOB ~.*\.STO~ ~override~
    
    READ_LONG  0x8 type
    READ_LONG 0x10 kind
    

    Offsets 0x8 and 0x10 are 4-byte long ---> https://gibberlings3.github.io/iesdp/file_formats/ie_formats/sto_v1.htm#storv1_0_Header

    Moreover, instead of writing 0b0001000001101111 you can use BIT0 | BIT1 | BIT2 | BIT3 and so forth ("|" stands for Bitwise OR, also known as BOR........)
  • BubbBubb Member Posts: 1,001
    edited March 2019
    Goida wrote: »

    That's the gist of it. How do I fill override with nothing? Writing ~~ doesn't change anything.

    I believe you need to specify a size for WeiDU to pad the field with NULLs. Try this:
    WRITE_ASCII 0x248 ~~ #8
    

    Also note that in most cases, the engine simply sets a script slot to "None" when it wants to clear it. Actually, I think certain opcodes are specifically rigged to not allow you to make script references NULL, so take caution. It will probably work just fine, but there might be a small chance that the engine doesn't account for this possibility somewhere...
  • kjeronkjeron Member Posts: 2,367
    @Raduziel
    ALTER_ITEM_EFFECT defaults both 'check_headers' and 'check_globals' to 0 (ignore).
    ALTER_EFFECT defaults both to 1 (check).
    Either use ALTER_ITEM_EFFECT with "INT_VAR check_headers = 1",
    or use ALTER_EFFECT with "INT_VAR check_globals = 0".
  • GwendolyneGwendolyne Member Posts: 461
    edited March 2019
    @Raduziel

    Try this;
    LPF ALTER_ITEM_EFFECT INT_VAR check_headers = 1 STR_VAR resource = EVAL ~%spell_2%~ END
    

    or
    LPF ALTER_EFFECT STR_VAR resource = EVAL ~%spell_2%~ END
    


    Oops. Ninja-ed by @kjeron
  • [Deleted User][Deleted User] Posts: 0
    edited March 2019
    The user and all related content has been deleted.
    Post edited by [Deleted User] on
  • RaduzielRaduziel Member Posts: 4,714
    @kjeron @Gwendolyne @subtledoctor

    Thanks! You're all invited to Aurora's birthday party.
  • GoidaGoida Member Posts: 118
    Luke93 wrote: »

    Offsets 0x8 and 0x10 are 4-byte long ---> https://gibberlings3.github.io/iesdp/file_formats/ie_formats/sto_v1.htm#storv1_0_Header

    Moreover, instead of writing 0b0001000001101111 you can use BIT0 | BIT1 | BIT2 | BIT3 and so forth ("|" stands for Bitwise OR, also known as BOR........)

    So how would that look?

    type = 0 & ((kind BIT0 | BIT1 | BIT2 | BIT3 | BIT5 | BIT 6))... What?

    Also, the 4 byte length means 32 bits, but I'm using READ_SHORT to get the first 16 bits. They are the only ones that matter for me - Fence is bit 12, I think, and all the rest can be what they like. From what I understand, reading just the beginning of a field omits the remainder, and it's less confusing this way.
    Bubb wrote: »

    I believe you need to specify a size for WeiDU to pad the field with NULLs. Try this:
    WRITE_ASCII 0x248 ~~ #8
    

    Yeah, I kind of figured this on my own. :) Writing "None" there with #8 is the ticket. Empty script slots show as "None" in Near Infinity. Thanks.

  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited March 2019
    @Goida

    If you want to patch all STO that can buy fenced goods, then:
    COPY_EXISTING_REGEXP GLOB ~.*\.STO~ ~override~
    
    READ_LONG  0x8 type
    READ_LONG 0x10 kind
    
    PATCH_IF	(%SOURCE_SIZE% > 0x9b)	BEGIN	// Sanity check
    PATCH_IF
    type == 0 && ((kind BAND BIT12) ==  BIT12)
    
    THEN BEGIN...
    
  • GoidaGoida Member Posts: 118
    edited March 2019
    @Luke93 I'll try that. Thanks!

    Edit: okay, it worked. But the scope may be a little too broad. The item currently appears in all store-stores that buy, sell, identify, don't buy stolen goods and where there is no stealing option. A lot do. I would like to narrow the scope to stores that buy wands. Any idea how to read that? Do I have to go with an OR through every "Store purchases" offset looking for number 35 for wands? But then, I don't know how many offsets there will be.

    And another question I'd like to broadcast here, just to be on the safe side. Probabilities of effects. I've heard that 100 is never rolled. So, then, if I wanted 1% chance, I would write 100-99? Or 0-0? Is there a difference?
    Post edited by Goida on
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited March 2019
    Goida wrote: »
    And another question I'd like to broadcast here, just to be on the safe side. Probabilities of effects. I've heard that 100 is never rolled. So, then, if I wanted 1% chance, I would write 100-99? Or 0-0? Is there a difference?

    Have a look at this.....
    Post edited by _Luke_ on
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited March 2019
    kjeron wrote: »
    Opcode 73 modifies that specific stat (#50 DAMAGEBONUS), the stats final value is added to weapon damage. You can use it to apply a negative increment value to reduce the damage dealt (min:1), but not by a percentage.

    How can I prevent that DAMAGEBONUS drops below a certain threshold? I successfully added stat #50 to SLPPROT.2da and the following spell effects to my SPL:
    LPF ADD_SPELL_EFFECT
    INT_VAR
    	opcode = 318
    	target = 2
    	parameter1 = "-8"
    	parameter2 = STAT DAMAGEBONUS < specified value
    	duration = 1
    STR_VAR
    	resource = EVAL ~%SOURCE_RES%~
    END
    
    LPF ADD_SPELL_EFFECT
    INT_VAR
    	opcode = 73	      // Attack damage bonus
    	target = 2       // Preset target
    	parameter1 = "-2"
    	duration = 24       // 4 rounds
    END
    

    However, this isn't working (i.e., the target is always immune to opcode #73.....)
  • kjeronkjeron Member Posts: 2,367
    edited March 2019
    Stats read by splprot are unsigned.
    -8 = 4294967288
    It takes 3 rows to work:
    row#A                         50                          -8                       3
    row#B                         50                          0x80000000               0
    row#C                         0x104                       row#A                    row#B
    

    The first row is: Greater than 4294967288 (-8).
    The second row is: Less than or equal to 2147483648 (-2147483648, highest negative value), in hex because its value easier to remember.
    The third row is: Not (first row or second row) - this is the one you would use in op318.
    The end result is: True if current value is between:
    (-2117483648 and -8) == (2147483648 and 4294967288).
    Post edited by kjeron on
  • _Luke__Luke_ Member, Mobile Tester Posts: 1,535
    edited March 2019
    @kjeron

    OK, here's my code:
    /**
     * Converts any decimal number into a hexadecimal number
     */
    DEFINE_ACTION_FUNCTION TO_HEX_NUMBER
    INT_VAR
    	value     = 0   // the decimal number
    	minDigits = 1   // min. number of digits in return value (not counting sign)
    	prefix    = 0   // whether to return number with "0x" prefix
    RET
    	hexNumber       // returned as string without prefix
    BEGIN
    	ACTION_IF (minDigits < 1) BEGIN OUTER_SET minDigits = 1 END
    	ACTION_IF (minDigits > 8) BEGIN OUTER_SET minDigits = 8 END
    	OUTER_TEXT_SPRINT hexNumber ~~
    	ACTION_DEFINE_ARRAY digit BEGIN ~0~ ~1~ ~2~ ~3~ ~4~ ~5~ ~6~ ~7~ ~8~ ~9~ ~a~ ~b~ ~c~ ~d~ ~e~ ~f~ END
    
    	ACTION_IF (value < 0) BEGIN
    		OUTER_SET signed = 1
    		OUTER_SET value = 0 - value
    	END ELSE BEGIN
    		OUTER_SET signed = 0
    	END
    
    	OUTER_WHILE (value != 0) BEGIN
    		OUTER_SET curDigit = value BAND 0xf
    		OUTER_SET value = value BLSR 4
    		OUTER_TEXT_SPRINT hexDigit $EVAL digit(~%curDigit%~)
    		OUTER_TEXT_SPRINT hexNumber ~%hexDigit%%hexNumber%~
    	END
    
    	OUTER_WHILE (STRING_LENGTH ~%hexNumber%~ < minDigits) BEGIN
    		OUTER_TEXT_SPRINT hexNumber ~0%hexNumber%~
    	END
    
    	ACTION_IF (prefix) BEGIN
    		OUTER_TEXT_SPRINT hexNumber ~0x%hexNumber%~
    	END
    
    	ACTION_IF (signed) BEGIN
    		OUTER_TEXT_SPRINT hexNumber ~-%hexNumber%~
    	END
    END
    
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    
    /**
     * Adds a new entry to SPLPROT.2DA and returns its index. If an identical entry already exists it will return 
     * the index of that entry instead.
     * INT_VAR stat     A code from STATS.IDS or an extended stat code starting at 0x100 (256).
     * STR_VAR value    Either a numeric value that is evaluated by "stat", or a default value "*" for specific stats.
     *                  (Note: "-1" indicates a user-defined value.)
     * STR_VAR relation Specifies how to evaluate the value.
     *                  (Note: Not all extended stats require a relation code. Use "*" in this case.)
     * RET index        Entry number that can be used to refer to this operation in various effect opcodes.
     *                  Returns -1 on error.
     */
    DEFINE_ACTION_FUNCTION ADD_SPLPROT_ENTRY
    INT_VAR
    	stat      = "-1"
    STR_VAR
    	value     = "*"
    	relation  = "*"
    RET
    	index
    BEGIN
    	OUTER_SET index = "-1"
    
    	ACTION_IF (stat >= 0) BEGIN
    	LAF TO_HEX_NUMBER INT_VAR value = stat RET hexNumber END
    	OUTER_TEXT_SPRINT valueHex ~0x%hexNumber%~
    	ACTION_IF (~%value%~ STRING_EQUAL ~~) BEGIN
    		OUTER_TEXT_SPRINT value ~*~
    	END
    	ACTION_IF (~%relation%~ STRING_EQUAL ~~) BEGIN
    		OUTER_TEXT_SPRINT relation ~*~
    	END
    
    	ACTION_IF (FILE_EXISTS_IN_GAME ~splprot.2da~) BEGIN
    		COPY_EXISTING ~splprot.2da~ ~override~
    		READ_2DA_ENTRIES_NOW table 4
    		// Search for identical entries
    		FOR (idx = 0; idx < table; idx += 1) BEGIN
    			READ_2DA_ENTRY_FORMER table idx 1 curStat
    			PATCH_IF (~%stat%~ STRING_EQUAL ~%curStat%~ OR ~%valueHex%~ STRING_EQUAL_CASE ~%curStat%~) BEGIN
    			READ_2DA_ENTRY_FORMER table idx 2 curValue
    			PATCH_IF (~%value%~ STRING_EQUAL ~%curValue%~) BEGIN
    				READ_2DA_ENTRY_FORMER table idx 3 curRelation
    				PATCH_IF (~%relation%~ STRING_EQUAL ~%curRelation%~) BEGIN
    				SET index = idx
    				SET idx = table
    				END
    			END
    			END
    		END
    
    		PATCH_IF (index < 0) BEGIN
    			// Add new entry
    			PATCH_IF (stat >= 0x100) BEGIN
    			TEXT_SPRINT line ~%table%        %valueHex%        %value%         %relation%~
    			END ELSE BEGIN
    			TEXT_SPRINT line ~%table%        %stat%          %value%         %relation%~
    			END
    			INSERT_2DA_ROW table 4 ~%line%~
    			SET index = table
    		END
    		BUT_ONLY
    	END
    	END
    END
    
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    
    LAF ADD_SPLPROT_ENTRY
    INT_VAR
    	stat = 50	// STAT DAMAGEBONUS
    STR_VAR
    	value = ~-8~		// User-defined value
    	relation = ~3~		// Greater
    RET
    	index
    END
    
    OUTER_SET index1 = index
    
    LAF ADD_SPLPROT_ENTRY
    INT_VAR
    	stat = 50	// STAT DAMAGEBONUS
    STR_VAR
    	value = ~0x80000000~		// Highest negative value - 2147483648
    	relation = ~0~		// Less than or equal
    RET
    	index
    END
    
    OUTER_SET index2 = index
    
    LAF ADD_SPLPROT_ENTRY
    INT_VAR
    	stat = 0x104	// negate 0x103 (where 0x103 - use two rows of splprot.2da)
    STR_VAR
    	value = ~index1~		// 
    	relation = ~index2~		// 
    RET
    	index
    END
    
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    
    LPF ADD_SPELL_EFFECT
    INT_VAR
    	opcode = 318				// Protection from spell
    	target = 2
    	parameter2 = index			// Not match entries
    STR_VAR
    	resource = EVAL ~%SOURCE_RES%~
    END
    

    I guess there are 2 problems:
    • row#B is 'Less than or equal specified value' (but param1 is unused, so this is probably fine...)
    • row#C is 'Not match entries -1 or -1'
Sign In or Register to comment.