subtledoctor Posted November 4, 2016 Share Posted November 4, 2016 I want to do something like this: COPY_EXISTING ~stuff~ ~overrride~ PATCH_IF (%variable% = 3) BEGIN [do stuff] END PATCH_IF (%varable% = 5) BEGIN [do other stuff] END ELSE BEGIN // if %variable% = any other value [do some different default stuff] END BUT_ONLYMy question is, more or less, does that work? given that there's an END closing out each conditional PATCH_IF section, can the ELSE reach back and know to incorporate more than one? Put another way: can we do this: PATCH_IF PATCH_IF PATCH_IF ELSE...or are we restricted to this: PATCH_IF ELSE Link to comment
Roxanne Posted November 4, 2016 Share Posted November 4, 2016 I want to do something like this: COPY_EXISTING ~stuff~ ~overrride~ PATCH_IF (%variable% = 3) BEGIN [do stuff] END PATCH_IF (%varable% = 5) BEGIN [do other stuff] END ELSE BEGIN // if %variable% = any other value [do some different default stuff] END BUT_ONLYMy question is, more or less, does that work? given that there's an END closing out each conditional PATCH_IF section, can the ELSE reach back and know to incorporate more than one? Put another way: can we do this: PATCH_IF PATCH_IF PATCH_IF ELSE...or are we restricted to this: PATCH_IF ELSE Link to comment
Jarno Mikkola Posted November 4, 2016 Share Posted November 4, 2016 Why would it be restricted to the second... of course you might want to ... PATCH_IF (%variable% = 3 AND NOT %variable% = 5) BEGIN patch stuff END PATCH_IF (%variable% = 5 AND NOT %variable% = 3) BEGIN patch stuff END ELSE BEGIN patch stuff END Link to comment
subtledoctor Posted November 4, 2016 Author Share Posted November 4, 2016 Jarno isn't that already encompassed by the "=" ? Question is, how does the "ELSE" know what it is referring to? Let's say I want to patch some items; if they are swords, I want to color them all red; if they are long swords they should do extra slashing damage, if they are bastard swords they should do extra crushing damage, and any other swords should default to giving an AC bonus. Pseudocode: COPY_EXISTING_REGEXP_GLOB ~all items~ PATCH_IF (%type% = swords) BEGIN [set color to red] END PATCH_IF (%proficiency% = long sword) BEGIN [add slashing damage] END PATCH_IF (%proficiency% = bastard sword) BEGIN [add crushing damage] END ELSE BEGIN [give AC bonus] END BUT_ONLYI want any item with %type% = sword and %proficiency% = katana or scimitar or short sword etc. to be colored red and give an AC bonus. In other words the ELSE should an alternative to anything involving %proficiency%, but should work in concert with the section involving %type%. Will the above code confuse Weidu? Link to comment
argent77 Posted November 4, 2016 Share Posted November 4, 2016 It depends on what you want to express with your code.This code construct is guaranteed to execute only one of the available IF/ELSE blocks: SET x = 1 PATCH_IF (x = 1) BEGIN // block executed SET x = 2 END ELSE PATCH_IF (x = 2) BEGIN // block NOT executed SET x = 3 END ELSE PATCH_IF (x = 3) // block NOT executed SET x = 4 END ELSE BEGIN // block NOT executed // ... END This code construct may execute one or more code blocks, depending on the condition: SET x = 1 PATCH_IF (x = 1) BEGIN // block executed SET x = 2 END PATCH_IF (x = 2) BEGIN // block executed SET x = 3 END PATCH_IF (x = 3) // block executed SET x = 4 END ELSE BEGIN // block NOT executed // ... END As you can see the second construct may introduce unintended effects if you're not careful.Btw, numeric variables don't have to be enclosed in percentages, so this code works just fine: READ_LONG 0x1234 value PATCH_IF (value = 77) BEGIN END Link to comment
subtledoctor Posted November 4, 2016 Author Share Posted November 4, 2016 Did you really mean to have two ELSE's up there? END ELSE ELSE PATCH_IF(Yeah I know about the %%s, I just included them to make the pseudocode more readable.) Link to comment
argent77 Posted November 4, 2016 Share Posted November 4, 2016 Did you really mean to have two ELSE's up there? END ELSE ELSE PATCH_IF No, that's a copy&paste error. It's been fixed. Link to comment
subtledoctor Posted November 4, 2016 Author Share Posted November 4, 2016 argent77, going back to your two examples (which are very elucidating, thank you)... if you change the first line to set x = 5in each case, would the final ELSE block execute? Link to comment
argent77 Posted November 4, 2016 Share Posted November 4, 2016 Yes. It should be obvious for the first example. The IF/ELSE construct of the second example is basically only a simplified version of the first example, so the ELSE block will always execute if the IF condition evaluates to false. You can also add ELSE blocks to the remaining IF constructs of the second example. In this case all ELSE blocks will be executed, one after another. Link to comment
Ardanis Posted November 4, 2016 Share Posted November 4, 2016 You can also use PATCH_MATCH for that purpose, it's more compact. x = 5 PATCH_MATCH x WITH 1 BEGIN PATCH_PRINT ~x=1~ END 2 BEGIN PATCH_PRINT ~x=2~ END DEFAULT // PATCH_PRINT ~x is neither 1 nor 2~ END Link to comment
agb1 Posted November 5, 2016 Share Posted November 5, 2016 The most straightforward (clear, unambiguous, readable), albeit inelegant, way to achieve this, would be to avoid the ELSE clause entirely (because it only applies to the previous IF), and instead use a variable and a final IF block. For example: SET DID_STUFF = 0 PATCH_IF (Condition A) DO X SET DID_STUFF = 1 END PATCH_IF (Condition B) DO Y SET DID_STUFF = 1 END PATCH_IF (DID_STUFF = 0) DO THE THING THAT YOU WANTED TO DO IN THE ELSE CLAUSE END Link to comment
Mike1072 Posted November 5, 2016 Share Posted November 5, 2016 That's more confusing. Use the control flow statements we have for this purpose. Link to comment
agb1 Posted November 5, 2016 Share Posted November 5, 2016 subtledoctor's first post had clauses that only tested one variable. His second post had clauses that test two different variables (type and proficiency). He wants a default clause that will only execute if all prior tests failed. An IF, IF, IF. ELSE series (without ELSE IF clauses) will execute the ELSE clause if the preceding IF test was false, regardless of what happened with the prior IF clauses. In subtledoctor's example from his second post (type / proficiency), that could result in the ELSE clause executing even if the conditions for more than one of the IF clauses was true simultaneously (specifically, if type = swords and proficiency = long sword, color would be red, slashing damage would apply, and the ELSE clause would also fire giving AC bonus - not wanted).PATTERN_MATCH will only execute one of the clauses - they are all mutually exclusive because they all test the same variable. This won't work if you want to test more than one variable or allow more than one clause to be executed.I think he wants something equivalent to this:If (condition A) // A is unrelated to B Do XElse If (condition B) Do YElse If (condition A and B) // both A and B can be true Do X and Y // duplicate action code from both of the clauses aboveElse // condition A and B are both false Do ZEndAn IF/ELSE IF/ELSE chain will only execute one of the clauses - they are all mutually exclusive. Unlike PATTERN_MATCH, this does allow testing different variables in each clause (each IF can test whatever you want). But to express "do 1 or more things that are not mutually exclusive, else if nothing was done, do this instead" using this format, you must test for each valid permutation of IF conditions and duplicate the actions in the clauses.So the above example works (with IF / ELSE IF / ELSE) formulation, but you have to duplicate the "Do X" and "Do Y" actions in the "both" clause. You also have to make sure you include all permutations in the IF/ELSE IF/ELSE IF chain. The duplication of action code inside the blocks is undesirable. My earlier suggestion (an IF/IF/IF chain, no ELSE, with a DID_STUFF variable to track what was done) avoids the duplication of action code, so I think it is a better solution for this kind of non-mutually-exclusive action series. If I have misunderstood subtledoctor's request or if I am wrong in any particular, please tell me. Just trying to help. Link to comment
subtledoctor Posted November 5, 2016 Author Share Posted November 5, 2016 No agb1 that is a very clear statement of exactly what I was looking for. And i can see how using a variable that way might be useful - in some circumstances. Though I don't think I need it for my intended use, now that I understand how ELSE PATCH_IF differs from merely using successive PATCH_IF clauses. My intended use, not to be mysterious, is to rewrite my Yet Another Revised Armor System. i want to do something like this: COPY_EXISTING_REGEXP GLOB ~^.+\.itm$~ ~override~ PATCH_IF (SOURCE_SIZE > 0x71) BEGIN READ_SHORT 0x1c type PATCH_IF (type = 2) BEGIN READ_LONG 0x22 appearance PATCH_IF (%appearance% = 16690) BEGIN // leather armors READ_LONG 0x08 gen_name_strref PATCH_IF (%gen_name_strref% = [hide armor]) BEGIN [do stuff to hide armors] END PATCH_IF (%gen_name_strref% = [studded leather]) BEGIN [do stuff to studded leather armors] END ELSE BEGIN [all non-hide, non-studded treated as basic leather armor] END END END END BUT_ONLYFrom what I gather from this thread, I need to add an ELSE to the clause for studded leather. Thanks folks! Link to comment
Mike1072 Posted November 5, 2016 Share Posted November 5, 2016 I think he wants something equivalent to this: If (condition A) // A is unrelated to B Do X Else If (condition B) Do Y Else If (condition A and B) // both A and B can be true Do X and Y // duplicate action code from both of the clauses above Else // condition A and B are both false Do Z End If that was what was needed, you could remove the duplicated actions like this: If (condition A || condition B) If (condition A) Do X End If (condition B) Do Y End End Else Do Z End However, the example with the type and proficiency is simpler: Let's say I want to patch some items; if they are swords, I want to color them all red; if they are long swords they should do extra slashing damage, if they are bastard swords they should do extra crushing damage, and any other swords should default to giving an AC bonus. Pseudocode: COPY_EXISTING_REGEXP_GLOB ~all items~ PATCH_IF (%type% = swords) BEGIN [set color to red] END PATCH_IF (%proficiency% = long sword) BEGIN [add slashing damage] END PATCH_IF (%proficiency% = bastard sword) BEGIN [add crushing damage] END ELSE BEGIN [give AC bonus] END BUT_ONLY If (type == swords) Set color to red If (proficiency == long_sword) Add slashing damage End Else If (proficiency == bastard_sword) Add crushing damage End Else Give AC bonus End End Link to comment
Recommended Posts
Archived
This topic is now archived and is closed to further replies.