aigleborgne Posted March 21, 2023 Share Posted March 21, 2023 Hi, I have to parse 2 arrays of string that executes the same code, with one of them beeing conditionnal: ACTION_FOR_EACH ~file~ ~a~ ~b~ ~c~ BEGIN ACTION_IF FILE_EXISTS_IN_GAME ~%file%.cre~ BEGIN COPY_EXISTING ~%file%.cre~ ~override~ // do some stuff BUT_ONLY_IF_IT_CHANGES END END ACTION_IF sometest = 1 BEGIN ACTION_FOR_EACH ~file~ ~d~ ~e~ ~f~ BEGIN ACTION_IF FILE_EXISTS_IN_GAME ~%file%.cre~ BEGIN COPY_EXISTING ~%file%.cre~ ~override~ // do some stuff BUT_ONLY_IF_IT_CHANGES END END END It is quite ugly, and considering there are dozens of block code like this one, something must be done. Is it possible to build a string array variable and use it in ACTION_IF ? In a typical language, you would something like: let array = [ 'a', 'b', 'c' ]; if (sometest == 1) array = [ ...array, 'd', 'e', 'f' ]; for (let f in array) { // do something } I need to something like this in WEIDU but don't know how. If it isn't possible, I guess I'll have to use a function with file parameter. I'd like to do it in the most concise and elegant way. Quote Link to comment
jmerry Posted March 21, 2023 Share Posted March 21, 2023 If you're iterating over an array, that's ACTION_PHP_EACH, or PHP_EACH/PATCH_PHP_EACH if you already have a resource loaded. Here's an example component of mine that uses it: // // // Elemental protection spells increment resistances // Last updated: 3.0 // BEGIN @20000 DESIGNATED 200 GROUP @2 ACTION_CLEAR_ARRAY resistance ACTION_FOR_EACH name IN ~SUN_SOUL_GREATER_SUN~ ~TALOS_STORMSHIELD~ ~CLERIC_ARMOR_OF_FAITH~ ~CLERIC_RESIST_FIRE~ ~CLERIC_PROTECTION_FROM_FIRE~ ~CLERIC_PROTECTION_FROM_LIGHTNING~ ~CLERIC_AURA_OF_FLAMING_DEATH~ ~WIZARD_WRAITH_FORM~ ~WIZARD_PROTECTION_FROM_FIRE~ ~WIZARD_PROTECTION_FROM_COLD~ ~WIZARD_FIRE_SHIELD_BLUE~ ~WIZARD_FIRE_SHIELD_RED~ ~WIZARD_PROTECTION_FROM_ELECTRICITY~ ~WIZARD_PROTECTION_FROM_ACID~ ~WIZARD_PROTECTION_FROM_MAGIC_ENERGY~ ~WIZARD_PROTECTION_FROM_THE_ELEMENTS~ ~WIZARD_PROTECTION_FROM_ENERGY~ BEGIN OUTER_SET num = IDS_OF_SYMBOL (~SPELL~ ~%name%~) ACTION_IF (num > 0) BEGIN LAF RES_NUM_OF_SPELL_NAME STR_VAR spell_name="%name%" RET res=spell_res END OUTER_SPRINT $resistance(~%name%~) ~%res%~ END END ACTION_PHP_EACH resistance AS name => res BEGIN COPY_EXISTING ~%res%.SPL~ ~override~ LPF ALTER_SPELL_EFFECT INT_VAR match_opcode=27 parameter2=0 END LPF ALTER_SPELL_EFFECT INT_VAR match_opcode=28 parameter2=0 END LPF ALTER_SPELL_EFFECT INT_VAR match_opcode=29 parameter2=0 END LPF ALTER_SPELL_EFFECT INT_VAR match_opcode=30 parameter2=0 END LPF ALTER_SPELL_EFFECT INT_VAR match_opcode=31 parameter2=0 END BUT_ONLY IF_EXISTS // IDS may have dud entries END // Change elemental resistance effects to "increment" mode. First, build an array - in this case, elemental resistance spells, drawing from SPELL.IDS to convert symbolic names to resource names. Then I iterate over those spells and make the changes I want, converting all elemental resistance effects to "increment" mode. Quote Link to comment
argent77 Posted March 21, 2023 Share Posted March 21, 2023 You could simplify the code like this: ACTION_DEFINE_ASSOCIATIVE_ARRAY my_files BEGIN ~a~ => 1 ~b~ => 1 ~c~ => 1 ~d~ => ~%sometest%~ ~e~ => ~%sometest%~ ~f~ => ~%sometest%~ END ACTION_PHP_EACH my_files AS file => condition BEGIN ACTION_IF (condition) BEGIN COPY_EXISTING ~%file%.cre~ ~override~ // Do your stuff... BUT_ONLY IF_EXISTS END END If "sometest" is only defined after the array definition, then this code might be more suitable: ACTION_DEFINE_ASSOCIATIVE_ARRAY my_files BEGIN ~a~ => 0 ~b~ => 0 ~c~ => 0 ~d~ => 1 ~e~ => 1 ~f~ => 1 END ACTION_PHP_EACH my_files AS file => condition BEGIN ACTION_IF (NOT condition || sometest && condition) BEGIN COPY_EXISTING ~%file%.cre~ ~override~ // Do your stuff... BUT_ONLY IF_EXISTS END END Quote Link to comment
aigleborgne Posted March 21, 2023 Author Share Posted March 21, 2023 (edited) 20 minutes ago, argent77 said: If "sometest" is only defined after the array definition, then this code might be more suitable: ACTION_DEFINE_ASSOCIATIVE_ARRAY my_files BEGIN ~a~ => 0 ~b~ => 0 ~c~ => 0 ~d~ => 1 ~e~ => 1 ~f~ => 1 END ACTION_PHP_EACH my_files AS file => condition BEGIN ACTION_IF (NOT condition || sometest && condition) BEGIN COPY_EXISTING ~%file%.cre~ ~override~ // Do your stuff... BUT_ONLY IF_EXISTS END END Thanks a lot, I really like the second solution as it is more concise. It can still be simplify a bit by inversion and you don't need "&& condition": ACTION_DEFINE_ASSOCIATIVE_ARRAY my_files BEGIN ~a~ => 1 ~b~ => 1 ~c~ => 1 ~d~ => 0 ~e~ => 0 ~f~ => 0 END ACTION_PHP_EACH my_files AS file => do BEGIN ACTION_IF (do || sometest) BEGIN // Do your stuff... END END Good use of an associative array to add some logic ! I was too narrow mind with a tradionnal approach but we must be creative with WEIDU limitations Edited March 21, 2023 by aigleborgne 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.