Jarno Mikkola Posted July 26, 2020 Share Posted July 26, 2020 4 hours ago, ptifab said: Everything is working, but i have a problem, the duration of the effect is not re-evaluated on each header (i have multiple spell level headers), does someone knows how to do that ? You just need to read the spell level and separate the different spell levels to different PATCH_IF's, on the same level. This is easy with LPF's... similar to this: READ_LONG 0x34 ~spell_level~ PATCH_IF (~spell_level~ = 1) BEGIN LPF ~ADD_SPELL_CFEFFECT~ INT_VAR opcode = 261 target = 1 parameter1 = 1 parameter2 = 1 timing = 4 duration = ~timer1 +6~ resist_dispel = 2 probability1 = 100 END PATCH_IF (~spell_level~ = 2) BEGIN LPF ~ADD_SPELL_CFEFFECT~ INT_VAR opcode = 261 target = 1 parameter1 = 2 parameter2 = 1 timing = 4 duration = ~timer2 +6~ resist_dispel = 2 probability1 = 100 END PATCH_IF (~spell_level~ = 3) BEGIN LPF ~ADD_SPELL_CFEFFECT~ INT_VAR opcode = 261 target = 1 parameter1 = 3 parameter2 = 1 timing = 4 duration = ~timer3 +6~ resist_dispel = 2 probability1 = 100 END PATCH_IF (~spell_level~ = 4) BEGIN LPF ~ADD_SPELL_CFEFFECT~ INT_VAR opcode = 261 target = 1 parameter1 = 4 parameter2 = 1 timing = 4 duration = ~timer4 +6~ resist_dispel = 2 probability1 = 100 END PATCH_IF (~spell_level~ = 5) BEGIN LPF ~ADD_SPELL_CFEFFECT~ INT_VAR opcode = 261 target = 1 parameter1 = 5 parameter2 = 1 timing = 4 duration = ~timer5 +6~ resist_dispel = 2 probability1 = 100 END PATCH_IF (~spell_level~ = 6) BEGIN LPF ~ADD_SPELL_CFEFFECT~ INT_VAR opcode = 261 target = 1 parameter1 = 6 parameter2 = 1 timing = 4 duration = ~timer6 +6~ resist_dispel = 2 probability1 = 100 END PATCH_IF (~spell_level~ = 7 OR ~spell_level~ = 8) BEGIN LPF ~ADD_SPELL_CFEFFECT~ INT_VAR opcode = 261 target = 1 parameter1 = 7 parameter2 = 1 timing = 4 duration = ~timer7 +6~ resist_dispel = 2 probability1 = 100 END END Quote Link to comment
Guest Gob Oafenplug Posted July 26, 2020 Share Posted July 26, 2020 5 hours ago, ptifab said: I have this function LAF statdesc_icon_ref STR_VAR bam_name = ~IUICOCLD~ RET icon_ref END COPY_EXISTING_REGEXP GLOB ~^.+\.spl$~ override PATCH_IF SOURCE_SIZE>0x71 BEGIN READ_LONG 0x64 abilities_off READ_SHORT 0x68 num_abilities READ_LONG 0x6a effects_off READ_SHORT 0x6e effects_ind icon_added = 0 FOR (i = 0; i < num_abilities; i += 1) BEGIN READ_SHORT (abilities_off + 0x28*i + 0x1e) num_features READ_SHORT (abilities_off + 0x28*i + 0x20) features_ind FOR (j = 0; j < num_features; j += 1) BEGIN READ_SHORT (effects_off + 0x30*(features_ind + j) + 0x00) opcode PATCH_IF opcode = 206 BEGIN // protection from spell READ_BYTE (effects_off + 0x30*(features_ind + j) + 0x0d) resist_dispel READ_LONG (effects_off + 0x30*(features_ind + j) + 0x0e) duration READ_ASCII (effects_off + 0x30*(features_ind + j) + 0x14) resource (8) PATCH_IF ~%resource%~ STRING_EQUAL_CASE ~SPWI213~ || ~%resource%~ STRING_EQUAL_CASE ~SPWI213D~ || ~%resource%~ STRING_EQUAL_CASE ~SPWI502~ || ~%resource%~ STRING_EQUAL_CASE ~SPWI502D~ || ~%resource%~ STRING_EQUAL_CASE ~SPWI614~ || ~%resource%~ STRING_EQUAL_CASE ~SPWI614D~ || ~%resource%~ STRING_EQUAL_CASE ~SPWI810~ || ~%resource%~ STRING_EQUAL_CASE ~SPWI810D~ || ~%resource%~ STRING_EQUAL_CASE ~SPPR250~ || ~%resource%~ STRING_EQUAL_CASE ~RR#WI502~ || ~%resource%~ STRING_EQUAL_CASE ~DVCKILL~ || ~%resource%~ STRING_EQUAL_CASE ~DVWCKILL~ || ~%resource%~ STRING_EQUAL_CASE ~DVCKILL2~ || ~%resource%~ STRING_EQUAL_CASE ~WAND13~ BEGIN PATCH_IF icon_added = 0 BEGIN LPF ADD_SPELL_EFFECT INT_VAR opcode = 142 target = 1 parameter2 = %icon_ref% resist_dispel = %resist_dispel% duration = %duration% insert_point = 99 END LPF ADD_SPELL_EFFECT INT_VAR opcode = 139 target = 1 parameter1 = RESOLVE_STR_REF(@1000117) timing = 1 resist_dispel = 2 insert_point = 99 END icon_added += 1 END END END END END END // END REGEXP BUT_ONLY Everything is working, but i have a problem, the duration of the effect is not re-evaluated on each header (i have multiple spell level headers), does someone knows how to do that ? You've set icon_added = 0 before reading any abilities. If CGameEffectImmunitySpell is found once (on the first ability) you set icon_added = 1 ... and then don't reset it to 0 before reading the next ability, so it skips all patching for the remainder. Move the guard variable reset deeper to fix this. Never pay heed to Jarnoposting. Quote Link to comment
ptifab Posted July 26, 2020 Author Share Posted July 26, 2020 I have tried all this afternoon, but with no results so far. Maybe the function is not set properly ? Quote Link to comment
Guest Gob Oafenplug Posted July 27, 2020 Share Posted July 27, 2020 Another bit of trouble you're having is in this line: READ_ASCII (effects_off + 0x30*(features_ind + j) + 0x14) resource (8) By default, READ_ASCII reads up until the first null, or eight characters, whichever is less. You've specified (8), a length, so it reads for a full eight characters even if that means reading nulls that'll never be part of a filename. If you're having trouble, it's usually helpful to add some temporary PATCH_PRINTs at various points to make sure the code is doing what you think it is. If you're still struggling, try this version, tweaked for clarity: LAF statdesc_icon_ref STR_VAR bam_name = ~IUICOCLD~ RET icon_ref END COPY_EXISTING_REGEXP GLOB ~^.+\.spl$~ override READ_LONG 0x64 abilities_off ELSE 0 READ_SHORT 0x68 num_abilities ELSE 0 READ_LONG 0x6a effects_off ELSE 0 FOR (i = 0; i < num_abilities; ++i) BEGIN READ_SHORT (abilities_off + 0x28 * i + 0x1e) num_features READ_SHORT (abilities_off + 0x28 * i + 0x20) features_ind FOR (j = 0; j < num_features; ++j) BEGIN READ_SHORT (effects_off + 0x30 * (features_ind + j) + 0x00) opcode PATCH_IF opcode = 206 BEGIN // CGameEffect_ImmunitySpell READ_BYTE (effects_off + 0x30 * (features_ind + j) + 0x0d) original_resist_dispel READ_LONG (effects_off + 0x30 * (features_ind + j) + 0x0e) original_duration READ_ASCII (effects_off + 0x30 * (features_ind + j) + 0x14) resource (8) NULL PATCH_MATCH ~%resource%~ WITH ~SPWI213~ ~SPWI213D~ ~SPWI502~ ~SPWI502D~ ~SPWI614~ ~SPWI614D~ ~SPWI810~ ~SPWI810D~ ~SPPR250~ ~RR#WI502~ ~DVCKILL~ ~DVWCKILL~ ~DVCKILL2~ ~WAND13~ BEGIN LPF ADD_SPELL_EFFECT INT_VAR opcode = 142 // CGameEffect_PortraitIcon target = 1 parameter2 = icon_ref resist_dispel = original_resist_dispel duration = original_duration insert_point = 99 END LPF ADD_SPELL_EFFECT INT_VAR opcode = 139 // CGameEffectDisplayString target = 1 parameter1 = RESOLVE_STR_REF(@1000117) timing = 1 resist_dispel = 2 insert_point = 99 END SET i = num_abilities // end outer loop over abilities SET j = num_features // end inner loop over effects END // various matches DEFAULT END // PATCH_MATCH END // IF 206 END // FOR j SET i = num_abilities // check only one ability for speed - if desired, uncomment to check all END // FOR i BUT_ONLY and see if that helps to illuminate you. Quote Link to comment
ptifab Posted July 27, 2020 Author Share Posted July 27, 2020 I'll try that and report to you, thanks for your time ! Quote Link to comment
Magus Posted July 27, 2020 Share Posted July 27, 2020 (edited) Allow me to show off: ACTION_DEFINE_ASSOCIATIVE_ARRAY fog_spells BEGIN ~%WIZARD_STINKING_CLOUD%~ => 1 ~%WIZARD_STINKING_CLOUD%D~ => 1 ~%WIZARD_CLOUDKILL%~ => 1 ~%WIZARD_CLOUDKILL%D~ => 1 ~%WIZARD_DEATH_FOG%~ => 1 ~%WIZARD_DEATH_FOG%D~ => 1 ~%WIZARD_INCENDIARY_CLOUD%~ => 1 ~%WIZARD_INCENDIARY_CLOUD%D~ => 1 ~%CLERIC_WRITHING_FOG%~ => 1 ~RR#WI502~ => 1 ~DVCKILL~ => 1 ~DVWCKILL~ => 1 ~DVCKILL2~ => 1 ~WAND13~ => 1 END COPY_EXISTING_REGEXP GLOB ~^.+\.spl$~ override GET_OFFSET_ARRAY ab_array SPL_V10_HEADERS PHP_EACH ab_array AS ab_ind => ab_off BEGIN added = 0 GET_OFFSET_ARRAY2 fx_array ab_off SPL_V10_HEAD_EFFECTS PHP_EACH fx_array AS fx_ind => fx_off BEGIN PATCH_IF added != 1 BEGIN READ_SHORT fx_off opcode READ_ASCII (fx_off + EFF_resource) resource (8) NULL TO_UPPER resource PATCH_IF opcode == OPCODE_protection_from_spell AND VARIABLE_IS_SET $fog_spells("%resource%") BEGIN READ_BYTE (fx_off + EFF_resistance) original_resist_dispel READ_LONG (fx_off + EFF_duration) original_duration header = (ab_ind + 1) insert_point = 99 target = TARGET_EFF_self LPF ADD_SPELL_EFFECT INT_VAR opcode = OPCODE_display_special_effect_icon parameter2 = icon_ref resist_dispel = original_resist_dispel duration = original_duration header insert_point target END LPF ADD_SPELL_EFFECT INT_VAR opcode = OPCODE_text_display_string parameter1 = RESOLVE_STR_REF(@1000117) timing = TIMING_instant resist_dispel = BYPASS_MR header insert_point target END added = 1 END END END END BUT_ONLY Testing required, of course. You might be able to trim it down further with CLONE_EFFECT, maybe. Edited July 27, 2020 by qwerty1234567 Quote Link to comment
ptifab Posted July 28, 2020 Author Share Posted July 28, 2020 (edited) 20 hours ago, qwerty1234567 said: Allow me to show off: ACTION_DEFINE_ASSOCIATIVE_ARRAY fog_spells BEGIN ~%WIZARD_STINKING_CLOUD%~ => 1 ~%WIZARD_STINKING_CLOUD%D~ => 1 ~%WIZARD_CLOUDKILL%~ => 1 ~%WIZARD_CLOUDKILL%D~ => 1 ~%WIZARD_DEATH_FOG%~ => 1 ~%WIZARD_DEATH_FOG%D~ => 1 ~%WIZARD_INCENDIARY_CLOUD%~ => 1 ~%WIZARD_INCENDIARY_CLOUD%D~ => 1 ~%CLERIC_WRITHING_FOG%~ => 1 ~RR#WI502~ => 1 ~DVCKILL~ => 1 ~DVWCKILL~ => 1 ~DVCKILL2~ => 1 ~WAND13~ => 1 END COPY_EXISTING_REGEXP GLOB ~^.+\.spl$~ override GET_OFFSET_ARRAY ab_array SPL_V10_HEADERS PHP_EACH ab_array AS ab_ind => ab_off BEGIN added = 0 GET_OFFSET_ARRAY2 fx_array ab_off SPL_V10_HEAD_EFFECTS PHP_EACH fx_array AS fx_ind => fx_off BEGIN PATCH_IF added != 1 BEGIN READ_SHORT fx_off opcode READ_ASCII (fx_off + EFF_resource) resource (8) NULL TO_UPPER resource PATCH_IF opcode == OPCODE_protection_from_spell AND VARIABLE_IS_SET $fog_spells("%resource%") BEGIN READ_BYTE (fx_off + EFF_resistance) original_resist_dispel READ_LONG (fx_off + EFF_duration) original_duration header = (ab_ind + 1) insert_point = 99 target = TARGET_EFF_self LPF ADD_SPELL_EFFECT INT_VAR opcode = OPCODE_display_special_effect_icon parameter2 = icon_ref resist_dispel = original_resist_dispel duration = original_duration header insert_point target END LPF ADD_SPELL_EFFECT INT_VAR opcode = OPCODE_text_display_string parameter1 = RESOLVE_STR_REF(@1000117) timing = TIMING_instant resist_dispel = BYPASS_MR header insert_point target END added = 1 END END END END BUT_ONLY Testing required, of course. You might be able to trim it down further with CLONE_EFFECT, maybe. @qwerty1234567 Weidu returns an integer conversion error with EFF_resource ? As i don't know exactly this part of code, do you have any tips to why it says that ? On 7/27/2020 at 9:58 AM, Guest Gob Oafenplug said: LAF statdesc_icon_ref STR_VAR bam_name = ~IUICOCLD~ RET icon_ref END COPY_EXISTING_REGEXP GLOB ~^.+\.spl$~ override READ_LONG 0x64 abilities_off ELSE 0 READ_SHORT 0x68 num_abilities ELSE 0 READ_LONG 0x6a effects_off ELSE 0 FOR (i = 0; i < num_abilities; ++i) BEGIN READ_SHORT (abilities_off + 0x28 * i + 0x1e) num_features READ_SHORT (abilities_off + 0x28 * i + 0x20) features_ind FOR (j = 0; j < num_features; ++j) BEGIN READ_SHORT (effects_off + 0x30 * (features_ind + j) + 0x00) opcode PATCH_IF opcode = 206 BEGIN // CGameEffect_ImmunitySpell READ_BYTE (effects_off + 0x30 * (features_ind + j) + 0x0d) original_resist_dispel READ_LONG (effects_off + 0x30 * (features_ind + j) + 0x0e) original_duration READ_ASCII (effects_off + 0x30 * (features_ind + j) + 0x14) resource (8) NULL PATCH_MATCH ~%resource%~ WITH ~SPWI213~ ~SPWI213D~ ~SPWI502~ ~SPWI502D~ ~SPWI614~ ~SPWI614D~ ~SPWI810~ ~SPWI810D~ ~SPPR250~ ~RR#WI502~ ~DVCKILL~ ~DVWCKILL~ ~DVCKILL2~ ~WAND13~ BEGIN LPF ADD_SPELL_EFFECT INT_VAR opcode = 142 // CGameEffect_PortraitIcon target = 1 parameter2 = icon_ref resist_dispel = original_resist_dispel duration = original_duration insert_point = 99 END LPF ADD_SPELL_EFFECT INT_VAR opcode = 139 // CGameEffectDisplayString target = 1 parameter1 = RESOLVE_STR_REF(@1000117) timing = 1 resist_dispel = 2 insert_point = 99 END SET i = num_abilities // end outer loop over abilities SET j = num_features // end inner loop over effects END // various matches DEFAULT END // PATCH_MATCH END // IF 206 END // FOR j SET i = num_abilities // check only one ability for speed - if desired, uncomment to check all END // FOR i BUT_ONLY and see if that helps to illuminate you. @Guest Gob Oafenplug The result is unfortunately the same as my code, it does not updates the duration. I must have missed something here... Edited July 28, 2020 by ptifab Quote Link to comment
Magus Posted July 28, 2020 Share Posted July 28, 2020 25 minutes ago, ptifab said: Weidu returns an integer conversion error with EFF_resource ? As i don't know exactly this part of code, do you have any tips to why it says that ? Because it's not defined. You'll need to define it and other used constants (or use IElib). Quote Link to comment
ptifab Posted July 28, 2020 Author Share Posted July 28, 2020 I just realized my mistake, i'm not used to that kinds of codes (using arrays and such), but i finally managed to make it work by effectively define parameters, thanks a lot @qwerty1234567 Quote Link to comment
ptifab Posted July 28, 2020 Author Share Posted July 28, 2020 (edited) Another question, how WEIDU does handle negative values in READ_BYTE parameter ? In my case, i want to add a portrait icon (my previous function), but only if value is not negative, but when i add this : READ_BYTE (fx_off + 0x04) original_p1 PATCH_IF original_p1 > 0 BEGIN // fail safe if value is negative don't add anything it doesn't seem to work, because the function still process its work. Edited July 28, 2020 by ptifab Quote Link to comment
DavidW Posted July 28, 2020 Share Posted July 28, 2020 Use READ_SBYTE, which interprets a byte as lying between -127 and +128. READ_BYTE interprets it as lying between 0 and 255. Quote Link to comment
ptifab Posted July 28, 2020 Author Share Posted July 28, 2020 16 minutes ago, DavidW said: Use READ_SBYTE, which interprets a byte as lying between -127 and +128. READ_BYTE interprets it as lying between 0 and 255. I have so much to learn... thank you @DavidW Quote Link to comment
DavidW Posted July 28, 2020 Share Posted July 28, 2020 22 hours ago, qwerty1234567 said: You might be able to trim it down further with CLONE_EFFECT, maybe. This works, I think (testing required). You need my extension of the ALTER_EFFECT family. DEFINE_PATCH_FUNCTION match_fog RET value BEGIN READ_ASCII 0x14 resource PATCH_MATCH "%resource%" WITH "\(%WIZARD_STINKING_CLOUD%D?\|%WIZARD_CLOUDKILL%D?\|%WIZARD_DEATH_FOG%D?\|%WIZARD_INCENDIARY_CLOUD%D?\|%CLERIC_WRITHING_FOG%\|RR#WI502\|DVCKILL2?\|DVWCKILL\|WAND13\)" BEGIN value=1 END DEFAULT value=0 END END COPY_EXISTING_REGEXP ".*\.spl$" override PATCH_IF INDEX_BUFFER ("\(%WIZARD_STINKING_CLOUD%\|%WIZARD_CLOUDKILL%\|%WIZARD_DEATH_FOG%\|%WIZARD_INCENDIARY_CLOUD%\|%CLERIC_WRITHING_FOG%\|RR#WI502\|DVCKILL\|DVWCKILL\|WAND13\)" >=0 BEGIN LPF CLONE_EFFECT INT_VAR multi_match=1 match_opcode=206 opcode=142 target=1 parameter2=icon_ref insert_point=99 STR_VAR match_function=match_fog END LPF CLONE_EFFECT INT_VAR multi_match=1 match_opcode=206 opcode=139 target=1 timing=1 parameter1=RESOLVE_STR_REF (@1000117) insert_point=99 STR_VAR match_function=match_fog END END BUT_ONLY You don't need the INDEX_BUFFER, it's there for performance. (COMBINING COPY_EXISTING with ALTER_EFFECT/CLONE_EFFECT can be slow.) Quote Link to comment
Jarno Mikkola Posted July 28, 2020 Share Posted July 28, 2020 54 minutes ago, ptifab said: it doesn't seem to work, because the function still process its work. Yeah... see the actual value is never negative, so you could just restrict it more, with: PATCH_IF (original_p1 > 0 AND original_p1 < 129 ) BEGIN Quote Link to comment
ptifab Posted July 28, 2020 Author Share Posted July 28, 2020 Thank you all for your help, i must say it's good to be helped like this ! My function is working as expected,thank you again ! 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.