AvA Posted September 5 Share Posted September 5 Dear all, getting your character recognized by the game world for what he/she is makes for an immersive experience. Or quite the contrary if failing to do so... I got a kit which should be addressed differently than it's base class, much like the Blackguard not getting the same options as a Paladin. Just this time it is a Ranger kit. I started with patching the ranger cabin or so called "stronghold". // Search for Ranger class check, and append a check to not have the new non-rangerly kit REPLACE_TRIGGER_TEXT ~uhmay01~ ~Class(Player1,RANGER_ALL)[%TAB% %LNL%%MNL%%WNL%]~ ~Class(Player1,RANGER_ALL)%TAB% %LNL%%MNL%%WNL%!Kit(Player1,NEWKIT)%TAB% %LNL%%MNL%%WNL%~ REPLACE_TRIGGER_TEXT ~uhmay01~ ~Class(Player1,RANGER)[%TAB% %LNL%%MNL%%WNL%]~ ~Class(Player1,RANGER)%TAB% %LNL%%MNL%%WNL%!Kit(Player1,NEWKIT)%TAB% %LNL%%MNL%%WNL%~ // If original check was negated we have to negate our kit check as well REPLACE_TRIGGER_TEXT ~uhmay01~ ~!Class(Player1,RANGER_ALL)[%TAB% %LNL%%MNL%%WNL%]+!Kit(Player1,NEWKIT)[%TAB% %LNL%%MNL%%WNL%]~ ~!Class(Player1,RANGER_ALL)%TAB% %LNL%%MNL%%WNL%Kit(Player1,NEWKIT)%TAB% %LNL%%MNL%%WNL%~ REPLACE_TRIGGER_TEXT ~uhmay01~ ~!Class(Player1,RANGER)[%TAB% %LNL%%MNL%%WNL%]+!Kit(Player1,NEWKIT)[%TAB% %LNL%%MNL%%WNL%]~ ~!Class(Player1,RANGER)%TAB% %LNL%%MNL%%WNL%Kit(Player1,NEWKIT)%TAB% %LNL%%MNL%%WNL%~ But the shortcomings are obvious. When the original condition was part of an OR(%number%) gate that will need additional fixing. The class check tends to be in the first position, which would make for an easy test, but I guess that cannot be relied on. Is there a smart way to detect the position in an OR gate and increase the number by 1? In my search I stumbled across REFACTOR_TRIGGER which seems to address the issue but comes with several conditions, if not warnings, attached. So I was wondering if anyone has some best practice example, or if experience shows to better not mess with such things on the large scale. Quote Link to comment
jastey Posted September 5 Share Posted September 5 I wouldn't know a way to do this "blindly" and fail safe, it would be very cool if that existed. Quote Link to comment
AvA Posted September 8 Author Share Posted September 8 So far I got fairly good results with REFACTOR_TRIGGER - if the new statement is implicitly connected by AND: COPY_EXISTING_REGEXP GLOB ~^.+\.dlg~ ~override~ //Parse through all dlg files PATCH_IF (RESOURCE_CONTAINS ~%SOURCE_FILE%~ ~Class(Player1,RANGER)~) BEGIN // Check if file is relevant to speed install up tremendously DECOMPILE_AND_PATCH BEGIN REFACTOR_TRIGGER ~Class(Player1,RANGER)~ ~Class(Player1,RANGER) !Kit(Player1,NEWKIT)~ //Replace trigger respecting OR and ! END DECOMPILE_AND_PATCH BEGIN //Recommended by refactor trigger to fix whitespace END END BUT_ONLY All the triggers I inspected look correct, OR gets expanded and negation is handled correctly. But I have no clue how to use it correctly, when the new and old statements shall be connected via OR. I tried: <OR(2) Class(Player1,RANGER) !Kit(Player1,NEWKIT)> But the OR is recognized as statement of its own and gets negated, which is easy to fix, but gets messy if the original expression was already part of an OR. Luckily, class checks are used so sparsely that the latter issue occurs in only 2 files. Guess I'll patch those manually for the time being. But it feels like we are so close to do it dynamically for full compatibility. Quote Link to comment
lynx Posted September 8 Share Posted September 8 Why not only check for the kit? The IDs are unique ... which then means a simple find&replace would be sufficient. Quote Link to comment
AvA Posted Monday at 09:20 PM Author Share Posted Monday at 09:20 PM You are right, that finding the kit works straight forward. The trick is to make the capture and replace case sensitive. Say we want a "Blackranger" to be treated just like a Blackguard. First, it should not be recognized as a Ranger anymore, we can use: REFACTOR_TRIGGER ~Class(Player1,RANGER)~ ~Class(Player1,RANGER) !Kit(Player1,EvilRanger)~ 1.(check) Ranger AND not EvilRanger can pass. Class(Player1,RANGER) => Class(Player1,RANGER) !Kit(Player1,EvilRanger) 2. (check) No Ranger can pass, unless of kit EvilRanger: !Class(Player1,RANGER) => OR(2) Kit(Player1,EvilRanger) !Class(Player1,RANGER) 3.(check) Ranger AND not EvilRanger can pass. OR(3) ConditionA Class(Player1,RANGER) !ConditionC => OR(3) ConditionA !ConditionC !Kit(Player1,EvilRanger) OR(3) ConditionA !ConditionC Class(Player1,RANGER) 4. (check) No Ranger can pass, unless of kit EvilRanger: OR(x) ConditionA !Class(Player1,RANGER) ConditionC => OR(4) ConditionA !Class(Player1,RANGER) Kit(Player1,EvilRanger) !ConditionC That's 4 out of 4! Kudos to REFACTOR_TRIGGER. Now for the second round: The kit should be detected like a Blackguard. But REFACTOR_TRIGGER uses boolean algebra for AND connection between statements. I could not find mention of how to switch it to OR. I thought I could prime it by running a Blackguard -> OR(1) Blackguard first, but it detects that as unnecessary and gets rid of it before doing any changes. Calling OR explicitly is even worse than using just search and replace. Cases 5 to 7 seem doable but 8 is currently beyond my RegExp magic, but yours may be stronger of cause. Follwing are the not so useful results of: REFACTOR_TRIGGER ~Kit(Player1,BLACKGUARD)~ ~OR(2) Kit(Player1,BLACKGUARD) Kit(Player1,EvilRanger)~ 5. (check) If a blackguard can pass so should the evilranger. Kit(Player1,BLACKGUARD) => OR(2) Kit(Player1,BLACKGUARD) Kit(Player1,EvilRanger) 6. Neither a blackguard nor the evilranger shall pass. !Kit(Player1,BLACKGUARD) => OR(3) !Kit(Player1,EvilRanger) !Kit(Player1,BLACKGUARD) !OR(2) //what the heck is this... //should have been !Kit(Player1,BLACKGUARD) !Kit(Player1,EvilRanger) 7. If a blackguard can pass so should the evilranger. OR(3) ConditionA Kit(Player1,BLACKGUARD) !ConditionC => OR(3) ConditionA !ConditionC Kit(Player1,EvilRanger) OR(3) ConditionA !ConditionC Kit(Player1,BLACKGUARD) OR(3) ConditionA !ConditionC OR(2) //should have been OR(4) ConditionA Kit(Player1,BLACKGUARD) Kit(Player1,EvilRanger) !ConditionC 8. Neither a blackguard nor the evilranger shall pass. OR(3) ConditionA !Kit(Player1,BLACKGUARD) !ConditionC => OR(5) ConditionA !OR(2) !Kit(Player1,BLACKGUARD) !Kit(Player1,EvilRanger) !ConditionC //should have been OR(3) ConditionA !Kit(Player1,BLACKGUARD) ConditionC OR(3) ConditionA !Kit(Player1,EvilRanger) ConditionC Quote Link to comment
lynx Posted Tuesday at 06:11 AM Share Posted Tuesday at 06:11 AM For 10pp I had to resort to perl and reimplementing a parser (still based on regex though). 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.