Jump to content

Weidu to check items' equipping effects


Recommended Posts

Sorry if this is an annoying "find my bug" question, but I can't see why this isn't working.  I'm trying to make a list of items that use opcode 42 to increase spell slots, like the Ring of Wizardry or Dak'kon's Blade, and record info about their particular effects.  I don't think something like GET_OFFSET_ARRAY2 is designed for global/equipping effects, so I'm checking the effects manually.  But it's weird - the code catches Dak'kon's Blade but not Rin08 or Ring40.  And as I say, I can't figure out why.

Here's the current code:

BEGIN ~test~

OUTER_SET generic_ind = 1
OUTER_SET mageslot_item_ind = 1
OUTER_SPRINT $mage_slot_items(~0~ ~0~ ~0~ ~0~) ~item~

COPY_EXISTING_REGEXP GLOB ~^.+\.itm$~ ~override~
  PATCH_IF (%SOURCE_SIZE% > 0x72) BEGIN
    SET slot_item = 0
    SET opcode = 0
    SET param1 = 0
    SET param2_byte1 = 0
    SET param2_byte2 = 0
    READ_LONG 0x6a eff_offset
    READ_SHORT 0x70 eff_count
    FOR (eff = 0; eff < (eff_count; ++eff) BEGIN
      READ_SHORT ((eff * 0x30) + eff_offset) opcode
      READ_LONG ((eff * 0x30) + eff_offset + 0x04) param1
      READ_BYTE ((eff * 0x30) + eff_offset + 0x08) param2_byte1
      READ_BYTE ((eff * 0x30) + eff_offset + 0x09) param2_byte2
      PATCH_IF (opcode = 42) BEGIN
        SET slot_item = 1
        PATCH_IF (param2_byte1 BAND 0b00000001 = 0b00000001) BEGIN
          SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~1~ ~%param1%~) ~%SOURCE_RES%~
          SET ++generic_ind
        END
        PATCH_IF (param2_byte1 BAND 0b00000010 = 0b00000010) BEGIN
          SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~2~ ~%param1%~) ~%SOURCE_RES%~
          SET ++generic_ind
        END
        PATCH_IF (param2_byte1 BAND 0b00000100 = 0b00000100) BEGIN
          SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~3~ ~%param1%~) ~%SOURCE_RES%~
          SET ++generic_ind
        END
        PATCH_IF (param2_byte1 BAND 0b00001000 = 0b00001000) BEGIN
          SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~4~ ~%param1%~) ~%SOURCE_RES%~
          SET ++generic_ind
        END
        PATCH_IF (param2_byte1 BAND 0b00010000 = 0b00010000) BEGIN
          SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~5~ ~%param1%~) ~%SOURCE_RES%~
          SET ++generic_ind
        END
        PATCH_IF (param2_byte1 BAND 0b00100000 = 0b00100000) BEGIN
          SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~6~ ~%param1%~) ~%SOURCE_RES%~
          SET ++generic_ind
        END
        PATCH_IF (param2_byte1 BAND 0b01000000 = 0b01000000) BEGIN
          SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~7~ ~%param1%~) ~%SOURCE_RES%~
          SET ++generic_ind
        END
        PATCH_IF (param2_byte1 BAND 0b10000000 = 0b10000000) BEGIN
          SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~8~ ~%param1%~) ~%SOURCE_RES%~
          SET ++generic_ind
        END
        PATCH_IF (param2_byte2 BAND 0b00000001 = 0b00000001) BEGIN
          SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~9~ ~%param1%~) ~%SOURCE_RES%~
          SET ++generic_ind
        END
      END
    END
    PATCH_IF slot_item = 1 BEGIN
      SET ++mageslot_item_ind
    END
  END
BUT_ONLY
	  
ACTION_PHP_EACH mage_slot_items AS ind => slot_item BEGIN
  PRINT ~%ind% %ind_1% %ind_2% %ind_3% %slot_item%~
END

I'm getting weird results:

  • mageslot_item_ind is being increased for every effect that returns true, instead of for every item that returns.  I want to increment this once per item.
  • ring08.itm, ring40.itm, amul16.itm, brac25.itm, and maybe others aren't being added to the array even though they have opcode 42 equipping effects
  • misc89.itm is handled properly, added to the array 9 times (once per spell level bonus) but wa2dak.itm gets 8 lines in the array instead of 4.

My intent is:

  • generic_ind should be incremented for every spell level increased in every found opcode 42 effect
  • mageslot_item_ind should be incremented once per item that contains any opcode 42 effects
  • param1 should record the number of bonus slots at each level.  This seems to be working.
Link to comment

There is one opening parenthesis too many in the FOR declaration, but that would just cause a syntax error.

I think the issue is with operator precedence of the binary and (BAND) and the comparison operator (=). BAND has a lower precedence, so the comparison (=) is evaluated first (and always evaluated to 1). Try surrounding all BAND expressions with parentheses:

PATCH_IF ((param2_byte1 BAND 0b00000001) = 0b00000001) BEGIN

 

Edited by argent77
Link to comment
1 hour ago, subtledoctor said:

I don't think something like GET_OFFSET_ARRAY2 is designed for global/equipping effects, so I'm checking the effects manually.

I think GET_OFFSET_ARRAY should work, see ITM_V10_GEN_EFFECTS. Also, there are BIT1-BIT31 constants, to make the code more readable.

Link to comment
Guest Gob Oafenplug

You might want to check attached .EFFs and spell doubling effects also.

OUTER_SET generic_ind = 1
OUTER_SET mageslot_item_ind = 1
OUTER_TEXT_SPRINT $mage_slot_items(0 0 0 0) item
COPY_EXISTING_REGEXP GLOB ~^.+\.ITM$~ override
  SET slot_item = 0
  PATCH_IF SOURCE_SIZE > 0x72 BEGIN
    GET_OFFSET_ARRAY glob_fx ITM_V10_GEN_EFFECTS
    PHP_EACH glob_fx AS idx => off BEGIN
      PATCH_IF SHORT_AT off == 42 BEGIN
        SET slot_item = 1
        READ_LONG off + 0x04 effectAmount
        READ_LONG off + 0x08 dwFlags
        FOR (spell_level = 1; spell_level < 10; ++spell_level) BEGIN
          PATCH_IF dwFlags & (2 ** (spell_level - 1)) BEGIN
            TEXT_SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~%spell_level%~ ~%effectAmount%~) ~%SOURCE_RES%~
            SET ++generic_ind
          END
        END
        PATCH_IF dwFlags == 0 BEGIN
          TEXT_SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ DOUBLE_ALL ~%effectAmount%~) ~%SOURCE_RES%~
          SET ++generic_ind
        END
      END ELSE
      PATCH_IF SHORT_AT off == 177 || SHORT_AT off == 326 BEGIN
        READ_ASCII off + 0x14 eff_res (8) NULL
        INNER_PATCH_FILE ~%eff_res%.EFF~ BEGIN
          PATCH_IF LONG_AT 0x010 == 42 BEGIN
            SET slot_item = 1
            READ_LONG 0x1c effectAmount
            READ_LONG 0x20 dwFlags
            FOR (spell_level = 1; spell_level < 10; ++spell_level) BEGIN
              PATCH_IF dwFlags & (2 ** (spell_level - 1)) BEGIN
                TEXT_SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ ~%spell_level%~ ~%effectAmount%~) ~%SOURCE_RES%~
                SET ++generic_ind
              END
            END
            PATCH_IF dwFlags == 0 BEGIN
              TEXT_SPRINT $mage_slot_items(~%generic_ind%~ ~%mageslot_item_ind%~ DOUBLE_ALL ~%effectAmount%~) ~%SOURCE_RES%~
              SET ++generic_ind
            END
          END
        END
      END
    END
  END
  PATCH_IF slot_item = 1 BEGIN
    SET ++mageslot_item_ind
  END
BUT_ONLY

ACTION_PHP_EACH mage_slot_items AS ind => slot_item BEGIN
  PRINT ~%ind_0% %ind_1% %ind_2% %ind_3% %slot_item%~
END

 

Link to comment
11 hours ago, argent77 said:

operator precedence of the binary and (BAND) and the comparison operator (=)

And, that fixed it.  Beautiful!  Thanks all.

10 hours ago, Guest Gob Oafenplug said:

You might want to check attached .EFFs and spell doubling effects also.

Yup, I'm getting to that stuff.  Just didn't make sense to move on to the edge cases yet when the basic function wasn't working.

Link to comment

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...