aigleborgne Posted March 24, 2023 Share Posted March 24, 2023 Hi, I want to pass arrays as function parameters. I have looked at this thread which works nice for associative arrays: In my case, I have simple arrays. First patch function: DEFINE_PATCH_FUNCTION disease_immunity BEGIN DEFINE_ARRAY spells BEGIN ~SPWI409~ ~FL#CSDIS~ END DEFINE_ARRAY opcodes BEGIN 101 END DEFINE_ARRAY icons BEGIN 14 130 END DEFINE_ARRAY strings BEGIN 39752 54337 END LPF ADD_IMMUNITY_CRE_ITM_SPL STR_VAR opcodes=~opcodes~ icons=~icons~ strings=~strings~ spells=~spells~ END END Called function: DEFINE_PATCH_FUNCTION ADD_IMMUNITY_CRE_ITM_SPL STR_VAR icons = ~~ strings = ~~ animations = ~~ spells = ~~ BEGIN PATCH_FOR_EACH value IN %opcodes% BEGIN PATCH_PRINT ~op=%value%~ END END This doesn't work. PATCH_FOR_EACH seems to accept only raw values. As for caller, I was wondering if I could write without intermediate variables for short arrays. Something like this: LPF ADD_IMMUNITY_CRE_ITM_SPL STR_VAR opcodes=~100 110 120~ icons=~36~ strings=~10050 5680~ spells=~spells~ END If I can't evaluate these values as array, is there a way to split string into array ? Or, string parsing with REGEXP match, something like that. WEIDU is really lacking a good documentation. Quote Link to comment
aigleborgne Posted March 24, 2023 Author Share Posted March 24, 2023 (edited) I have found a solution: LPF ADD_IMMUNITY_CRE_ITM_SPL STR_VAR opcodes=~opcodes~ icons=~14 130~ strings=~strings~ spells=~spells~ END PATCH_PHP_EACH EVAL ~%opcodes%~ AS _ => value BEGIN PATCH_PRINT ~op=%value%~ END PATCH_PHP_EACH EVAL ~%icons%~ AS _ => value BEGIN PATCH_PRINT ~icon=%value%~ END Finally, it works automatically Edited March 24, 2023 by aigleborgne Quote Link to comment
aigleborgne Posted March 24, 2023 Author Share Posted March 24, 2023 I was partially wrong with last post: LPF ADD_IMMUNITY_CRE_ITM_SPL STR_VAR opcodes=~opcodes~ icons=~14 130~ strings=~strings~ spells=~spells~ END icons don't get evaluated as array. I thought it worked, but I might had some interferences in my code. Quote Link to comment
jmerry Posted March 24, 2023 Share Posted March 24, 2023 Well, yeah. DEFINE_ARRAY parses a space-delimited list of strings to an array. Using "icons=~14 130~" in your list of arguments just sets that particular string variable to the six-character string "14 130". It's not an array, and the space is part of the string. Quote Link to comment
aigleborgne Posted March 24, 2023 Author Share Posted March 24, 2023 31 minutes ago, jmerry said: Well, yeah. DEFINE_ARRAY parses a space-delimited list of strings to an array. Using "icons=~14 130~" in your list of arguments just sets that particular string variable to the six-character string "14 130". It's not an array, and the space is part of the string. I found out, but is there a way to parse or convert a string into array ? API seems very very limited... Quote Link to comment
argent77 Posted March 24, 2023 Share Posted March 24, 2023 If you just want to evaluate the elements inside the string, then this code may suffice: INNER_PATCH ~%icons%~ BEGIN REPLACE_EVALUATE ~[^ %TAB%]+~ BEGIN PATCH_PRINT ~Processing string value: "%MATCH0%"~ END ~%MATCH0%~ END Quote Link to comment
aigleborgne Posted March 25, 2023 Author Share Posted March 25, 2023 20 hours ago, argent77 said: If you just want to evaluate the elements inside the string, then this code may suffice: INNER_PATCH ~%icons%~ BEGIN REPLACE_EVALUATE ~[^ %TAB%]+~ BEGIN PATCH_PRINT ~Processing string value: "%MATCH0%"~ END ~%MATCH0%~ END Thanks, it worked very well. Although I couldn't patch inside, probably because INNER_PATCH. I wrapped it into a function: DEFINE_PATCH_FUNCTION STRING_TO_ARRAY STR_VAR string = "" // string with space separator RET_ARRAY array BEGIN CLEAR_ARRAY array SET i=0 INNER_PATCH ~%string%~ BEGIN REPLACE_EVALUATE ~[^ %TAB%]+~ BEGIN SPRINT $array("%i%") "%MATCH0%" i+=1 END ~%MATCH0%~ END END Then: LPF STRING_TO_ARRAY STR_VAR string=EVALUATE_BUFFER "%opcodes%" RET_ARRAY array END PATCH_PHP_EACH array AS _ => opcode BEGIN // Immunity to effect PATCH_PRINT ~Immunity to effect [%opcode%]~ LPF ADD_CRE_EFFECT INT_VAR opcode=101 target=1 timing=9 parameter2=EVALUATE_BUFFER "%opcode%" END END But it doesn't work, I can't see what param2 value is written by function ADD_CRE_EFFECT but it isn't the value that are correctly displayed in console: Immunity to effect [25] Immunity to effect [78] I don't fully understand difference with this code (that works): PATCH_FOR_EACH ~effect~ IN ~90~ ~91~ BEGIN LPF ADD_CRE_EFFECT INT_VAR opcode=101 target=1 timing=9 parameter2=EVALUATE_BUFFER "%effect%" END END Quote Link to comment
aigleborgne Posted March 26, 2023 Author Share Posted March 26, 2023 I feel rather stupid about this one, but finally, it makes sense.I have just found out what was wrong by replacing ADD_CRE_EFFECT by a dummy function. LPF ADD_CRE_EFFECT INT_VAR opcode=101 target=1 timing=9 parameter2=EVALUATE_BUFFER "%opcode%" END I can't evaluate a variable named opcode because opcode is already an input parameter. So, WEIDU is using variable shadowing. As far as I understand, local function starts in INIT_VAR of LPF, whereas in a typical language, parameters are always evaluated before going inside a function. Quote Link to comment
marchitek Posted March 26, 2023 Share Posted March 26, 2023 (edited) 2 hours ago, aigleborgne said: I feel rather stupid about this one, but finally, it makes sense.I have just found out what was wrong by replacing ADD_CRE_EFFECT by a dummy function. LPF ADD_CRE_EFFECT INT_VAR opcode=101 target=1 timing=9 parameter2=EVALUATE_BUFFER "%opcode%" END I can't evaluate a variable named opcode because opcode is already an input parameter. So, WEIDU is using variable shadowing. As far as I understand, local function starts in INIT_VAR of LPF, whereas in a typical language, parameters are always evaluated before going inside a function. That's interesting. I haven't known that, could be quite error prone. I also have some "typical language" habits and what I noticed is that with WeiDU it is often required to split things into smaller steps. In this case you would like to have maybe something like this: SPRINT parameter2 EVALUATE_BUFFER "%opcode%" LPF ADD_CRE_EFFECT INT_VAR opcode=101 target=1 timing=9 parameter2 END You can also switch order of parameters in function invocation but this not seems like good idea. Edited March 26, 2023 by marchitek Quote Link to comment
subtledoctor Posted March 26, 2023 Share Posted March 26, 2023 Neither here nor there: don’t need EVALUATE_BUFFER for integer variables in functions, only for string variables. AFAIK. Quote Link to comment
aigleborgne Posted March 27, 2023 Author Share Posted March 27, 2023 On 3/26/2023 at 2:56 PM, subtledoctor said: Neither here nor there: don’t need EVALUATE_BUFFER for integer variables in functions, only for string variables. AFAIK. Thanks, I removed all of them! I have also learned a few other things: DEFINE_PATCH_FUNCTION STRING_TO_ARRAY STR_VAR string = "" // string with space separator RET_ARRAY array BEGIN CLEAR_ARRAY array SET i=0 INNER_PATCH ~%string%~ BEGIN REPLACE_EVALUATE ~[^ %TAB%]+~ BEGIN SPRINT $array("%i%") "%MATCH0%" i+=1 END ~%MATCH0%~ END END Considering this function, and multiple calls: LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array END LPF STRING_TO_ARRAY STR_VAR string="" RET_ARRAY array END It appears that array is not cleared at all if empty. I need to add a clear in between: LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array END CLEAR_ARRAY array LPF STRING_TO_ARRAY STR_VAR string="" RET_ARRAY array END I assume I have to keep the same name for returned variable between caller and called function. Something like: LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array1 END PATCH_PHP_EACH array1 AS _ => v BEGIN PATCH_PRINT ~Loop 1, value = %v%~ END LPF STRING_TO_ARRAY STR_VAR string="" RET_ARRAY array2 END PATCH_PHP_EACH array2 AS _ => v BEGIN PATCH_PRINT ~Loop 2, value = %v%~ END But I can't do that. Returning variable is very special in WEIDU and not very intuitive. At this point, I think that I could remove CLEAR_ARRAY in STRING_TO_ARRAY function as it does probably nothing, at least in my tests. Well, it isn't entirely true, as it works when I have array with at least one value: LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array END PATCH_PHP_EACH array AS _ => v BEGIN PATCH_PRINT ~Loop 1, value = %v%~ END LPF STRING_TO_ARRAY STR_VAR string="4" RET_ARRAY array END PATCH_PHP_EACH array AS _ => v BEGIN PATCH_PRINT ~Loop 2, value = %v%~ END Of course, I could add a test to skip empty string, but in my mind, it shouldn't be necessary. It is a common thing to have empty array and you shouldn't test its length before a loop. Quote Link to comment
argent77 Posted March 27, 2023 Share Posted March 27, 2023 1 hour ago, aigleborgne said: I assume I have to keep the same name for returned variable between caller and called function. Something like: LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array1 END PATCH_PHP_EACH array1 AS _ => v BEGIN PATCH_PRINT ~Loop 1, value = %v%~ END LPF STRING_TO_ARRAY STR_VAR string="" RET_ARRAY array2 END PATCH_PHP_EACH array2 AS _ => v BEGIN PATCH_PRINT ~Loop 2, value = %v%~ END But I can't do that. Returning variable is very special in WEIDU and not very intuitive. You can assign the return value of a function to another variable: LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array1 = array END // PATCH_PHP_EACH array1 AS _ => v BEGIN ... LPF STRING_TO_ARRAY STR_VAR string="" RET_ARRAY array2 = array END // PATCH_PHP_EACH array2 AS _ => v BEGIN ... Quote Link to comment
aigleborgne Posted March 27, 2023 Author Share Posted March 27, 2023 1 hour ago, argent77 said: You can assign the return value of a function to another variable: LPF STRING_TO_ARRAY STR_VAR string="1 2 3" RET_ARRAY array1 = array END // PATCH_PHP_EACH array1 AS _ => v BEGIN ... LPF STRING_TO_ARRAY STR_VAR string="" RET_ARRAY array2 = array END // PATCH_PHP_EACH array2 AS _ => v BEGIN ... Thanks again, your knowledge is limitless 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.