Jump to content

WEIDU - items basic coding problems


ptifab

Recommended Posts

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

 

Link to comment
Guest Gob Oafenplug
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.

Link to comment
Guest Gob Oafenplug

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.

Link to comment

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 by qwerty1234567
Link to comment
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 by ptifab
Link to comment
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).

Link to comment

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 by ptifab
Link to comment
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.)

Link to comment
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 

 

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...