subtledoctor Posted August 9, 2020 Share Posted August 9, 2020 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. Quote Link to comment
argent77 Posted August 9, 2020 Share Posted August 9, 2020 (edited) 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 August 9, 2020 by argent77 Quote Link to comment
Magus Posted August 9, 2020 Share Posted August 9, 2020 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. Quote Link to comment
Guest Gob Oafenplug Posted August 9, 2020 Share Posted August 9, 2020 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 Quote Link to comment
subtledoctor Posted August 10, 2020 Author Share Posted August 10, 2020 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. Quote Link to comment
Recommended Posts
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.