Luke Posted August 15, 2019 Share Posted August 15, 2019 (edited) On 7/29/2019 at 4:33 PM, DavidW said: Yes. Is there any particular reason for that? In other words, how would you automate something like this Spoiler IF !StateCheck(SixthNearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(SixthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF !StateCheck(FifthNearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(FifthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF !StateCheck(FourthNearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(FourthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF !StateCheck(ThirdNearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(ThirdNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF !StateCheck(SecondNearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(SecondNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF !StateCheck(NearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(NearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(SixthNearestEnemyOf(Myself),STATE_BLUR) See(SixthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(FifthNearestEnemyOf(Myself),STATE_BLUR) See(FifthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(FourthNearestEnemyOf(Myself),STATE_BLUR) See(FourthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(ThirdNearestEnemyOf(Myself),STATE_BLUR) See(ThirdNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(SecondNearestEnemyOf(Myself),STATE_BLUR) See(SecondNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(NearestEnemyOf(Myself),STATE_BLUR) See(NearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF // Possibly something else... See(LastSeenBy(Myself)) THEN RESPONSE #100 Attack(LastSeenBy(Myself)) END I mean, 'Combine()' is really useful to generate False() blocks, but I cannot use it in this case since there are different triggers.... Actually, I can use it but then I would generate two attack blocks (one for STATE_MIRRORIMAGE and another one for STATE_BLUR), which is kinda bad..... Do you have any suggestions? Is defining two separate ACTIONs and manually create the False() blocks (i.e., without using 'Combine()) the only solution? That is: Spoiler TARGET=EnemiesInReverseOrder SixthNearestEnemyOf(Myself) FifthNearestEnemyOf(Myself) FourthNearestEnemyOf(Myself) ThirdNearestEnemyOf(Myself) SecondNearestEnemyOf(Myself) NearestEnemyOf(Myself) BEGIN_ACTION_DEFINITION Name(TargetMI) TRIGGER !StateCheck(scstarget,STATE_MIRRORIMAGE) ACTION RESPONSE #scsprob1 NoAction() END BEGIN_ACTION_DEFINITION Name(TargetBlur) TRIGGER StateCheck(scstarget,STATE_BLUR) ACTION RESPONSE #scsprob1 NoAction() END IF TRIGGER TargetBlock(EnemiesInReverseOrder) False() THEN DO Action(TargetMI) Action(TargetBlur) END Edited August 15, 2019 by Luke Quote Link to comment
DavidW Posted August 15, 2019 Author Share Posted August 15, 2019 I would do: IF TRIGGER TargetBlock(EnemiesInReverseOrder) StateCheck(scstarget,STATE_MIRROR_IMAGE) False() THEN DO Action(Literal) END IF TRIGGER TargetBlock(EnemiesInReverseOrder) StateCheck(scstarget,STATE_BLUR) False() THEN DO Action(Literal) END Quote Link to comment
Luke Posted August 16, 2019 Share Posted August 16, 2019 (edited) @DavidW No, your SSL code generates the following BAF file, which is not what I was looking for... Spoiler IF See(SixthNearestEnemyOf(Myself)) !StateCheck(SixthNearestEnemyOf(Myself),STATE_MIRRORIMAGE) False() THEN RESPONSE #100 END IF See(FifthNearestEnemyOf(Myself)) !StateCheck(FifthNearestEnemyOf(Myself),STATE_MIRRORIMAGE) False() THEN RESPONSE #100 END IF See(FourthNearestEnemyOf(Myself)) !StateCheck(FourthNearestEnemyOf(Myself),STATE_MIRRORIMAGE) False() THEN RESPONSE #100 END IF See(ThirdNearestEnemyOf(Myself)) !StateCheck(ThirdNearestEnemyOf(Myself),STATE_MIRRORIMAGE) False() THEN RESPONSE #100 END IF See(SecondNearestEnemyOf(Myself)) !StateCheck(SecondNearestEnemyOf(Myself),STATE_MIRRORIMAGE) False() THEN RESPONSE #100 END IF See(NearestEnemyOf(Myself)) !StateCheck(NearestEnemyOf(Myself),STATE_MIRRORIMAGE) False() THEN RESPONSE #100 END IF See(SixthNearestEnemyOf(Myself)) StateCheck(SixthNearestEnemyOf(Myself),STATE_BLUR) False() THEN RESPONSE #100 END IF See(FifthNearestEnemyOf(Myself)) StateCheck(FifthNearestEnemyOf(Myself),STATE_BLUR) False() THEN RESPONSE #100 END IF See(FourthNearestEnemyOf(Myself)) StateCheck(FourthNearestEnemyOf(Myself),STATE_BLUR) False() THEN RESPONSE #100 END IF See(ThirdNearestEnemyOf(Myself)) StateCheck(ThirdNearestEnemyOf(Myself),STATE_BLUR) False() THEN RESPONSE #100 END IF See(SecondNearestEnemyOf(Myself)) StateCheck(SecondNearestEnemyOf(Myself),STATE_BLUR) False() THEN RESPONSE #100 END IF See(NearestEnemyOf(Myself)) StateCheck(NearestEnemyOf(Myself),STATE_BLUR) False() THEN RESPONSE #100 END I need those See() triggers to be second last, immediately before False() – just like Combine() would do. Is there a way to achieve that? Moreover, it's still not clear for me what 'Action(Literal)' is supposed to do..... Edited August 16, 2019 by Luke Quote Link to comment
DavidW Posted August 16, 2019 Author Share Posted August 16, 2019 Oh, I see. Don’t know, then. Quote Link to comment
Luke Posted August 16, 2019 Share Posted August 16, 2019 6 minutes ago, DavidW said: Oh, I see. Don’t know, then. Guess this is the problem: why does TargetBlock() always come before all the other triggers defined in the IF TRIGGER part? If that was not the case, then your code would work... Quote Link to comment
DavidW Posted August 16, 2019 Author Share Posted August 16, 2019 No very deep reason. (But don't look for it to change: I touch the underlying code in SSL as rarely as I can possibly manage.) Ultimately SSL's development cycle is that features get added to it as and when I need them for some SCS purpose. The use case you're considering just isn't one I've particularly needed. Quote Link to comment
Luke Posted August 19, 2019 Share Posted August 19, 2019 (edited) @DavidW I see. To sum up: I could use Combine() => this will put the See() triggers in the right position but will also generate multiple attack blocks (useless, but not wrong). I could define multiple ACTIONs and manually put the False() triggers in the IF TRIGGER part => this won't generate multiple attack blocks but it's not very flexible (since I need to define lots of ACTIONs instead of using TriggerBlock()....). Spoiler BEGIN_ACTION_DEFINITION Name(TargetOption1) TRIGGER WeaponEffectiveVs(scstarget,MAINHAND) WeaponCanDamage(scstarget,MAINHAND) !StateCheck(scstarget,STATE_PANIC) CheckStatLT(scstarget,1,STONESKINS) !StateCheck(scstarget,STATE_CONFUSED) ACTION RESPONSE #scsprob1 NoAction() END BEGIN_ACTION_DEFINITION Name(AttackOneRound) TRIGGER !StateCheck(scstarget,STATE_REALLY_DEAD) ACTION RESPONSE #scsprob1 AttackOneRound(scstarget) END ////////////////////////////////////////////////////////////////// IF TRIGGER TargetBlock(EnemiesInOrder) TriggerBlock(IsWeaponUsable) !StateCheck(scstarget,STATE_PANIC) CheckStatLT(scstarget,1,STONESKINS) !StateCheck(scstarget,STATE_CONFUSED) THEN DO Combine() Action(AttackOneRound) END // Versus IF TRIGGER TargetBlock(EnemiesInReverseOrder) False() THEN DO Action(TargetOption1) END Alternatively: how much is difficult to define a "Combine()" command that does not generate a "LastSeenBy(Myself)" block? That will solve my issue Edited August 19, 2019 by Luke Quote Link to comment
Luke Posted August 19, 2019 Share Posted August 19, 2019 (edited) More questions. Could you provide additional details about Action(Literal)? Let's consider your example: Spoiler IF TRIGGER !See(NearestEnemyOf(Myself)) TargetBlock(PlayersInRandomOrder) !StateCheck(scstarget,STATE_INVISIBLE) THEN DO Action(Literal) MoveToObject(scstarget) END // Versus IF TRIGGER !See(NearestEnemyOf(Myself)) TargetBlock(PlayersInRandomOrder) !StateCheck(scstarget,STATE_INVISIBLE) THEN DO MoveToObject(scstarget) END The aforementioned SSL blocks generate the same BAF file, namely: Spoiler IF See(Player4) !See(NearestEnemyOf(Myself)) !StateCheck(Player4,STATE_INVISIBLE) THEN RESPONSE #100 MoveToObject(Player4) END IF See(Player5) !See(NearestEnemyOf(Myself)) !StateCheck(Player5,STATE_INVISIBLE) THEN RESPONSE #100 MoveToObject(Player5) END IF See(Player6) !See(NearestEnemyOf(Myself)) !StateCheck(Player6,STATE_INVISIBLE) THEN RESPONSE #100 MoveToObject(Player6) END IF See(Player3) !See(NearestEnemyOf(Myself)) !StateCheck(Player3,STATE_INVISIBLE) THEN RESPONSE #100 MoveToObject(Player3) END IF See(Player2) !See(NearestEnemyOf(Myself)) !StateCheck(Player2,STATE_INVISIBLE) THEN RESPONSE #100 MoveToObject(Player2) END IF See(Player1) !See(NearestEnemyOf(Myself)) !StateCheck(Player1,STATE_INVISIBLE) THEN RESPONSE #100 MoveToObject(Player1) END What am I missing? Edited August 19, 2019 by Luke Quote Link to comment
DavidW Posted August 19, 2019 Author Share Posted August 19, 2019 Precious little. It's syntactic sugar, basically. Quote Link to comment
DavidW Posted August 19, 2019 Author Share Posted August 19, 2019 6 hours ago, Luke said: how much is difficult to define a "Combine()" command that does not generate a "LastSeenBy(Myself)" block? That depends on how good your Perl coding is. The source code for ssl is in stratagems/ssl; I don't mind you modifying it provided you continue to give full credit, and of course you'd need to recompile and distribute the executable if you wanted to hot-compile ssl code at install time. (Though the other examples of SSL mods out there - all by Wisp, I think - do their compiling ahead of time, so that a live copy of ssl doesn't need to be distributed.) If what you actually meant was a request for *me* to modify SSL to do this: No, sorry. SSL isn't WEIDU: it's not a community resource, it's something I wrote for my own purposes which I'm happy for other people to use, but which I don't support in any stronger way. Quote Link to comment
Luke Posted August 20, 2019 Share Posted August 20, 2019 16 hours ago, DavidW said: Precious little. It's syntactic sugar, basically. What do you mean exactly? Why is it precious? Unfortunately, 'Action(Literal)' is still pointless for me ... When exactly should I use it? Quote Link to comment
Luke Posted August 20, 2019 Share Posted August 20, 2019 17 hours ago, DavidW said: That depends on how good your Perl coding is I see. Well, I don't know Perl but I may look at someday..... In the meantime, I found out a workaround: I'll stick with "Combine()" and then will delete the additional attack blocks using your function DELETE_SCRIPT_BLOCK: it's not very elegant but it should work..... Quote Link to comment
Luke Posted August 20, 2019 Share Posted August 20, 2019 (edited) OK, I fear I spotted a bug: if you compile the following SSL block Spoiler IF TRIGGER Target(LastSeenBy(Myself)) THEN DO Action(CustomAction) END the resulting BAF/BCS block won't have the See(LastSeenBy(Myself)) trigger ...... The same holds if you define a custom target for that in your .slb file, i.e.: Spoiler TARGET=LastSeen LastSeenBy(Myself) Edited August 20, 2019 by Luke Quote Link to comment
DavidW Posted August 20, 2019 Author Share Posted August 20, 2019 That's intentional: SSL explicitly avoids adding a See block for LastSeenBy(Myself), because in my use cases it's always redundant. If you want it for some reason, either put the See() command into your action definition explicitly, or else use %luke_myself_var% or something, and set that variable to LastSeenBy(Myself) in your TP2, so that it gets replaced in the BAF->BCS phase. (IIRC SSL doesn't evaluate WEIDU variables in the SSL->BAF phase.) Upthread: "Precious little" is an expression, roughly synonymous with "almost nothing". Action(Literal) is just a hardcoded action with no trigger conditions and no actions. Mostly it's syntactic sugar (i.e., language that makes code easier for humans to read but doesn't matter to the compiler); there are one or use cases (if you want to use probabilities in a literal action, notably). Quote Link to comment
Luke Posted August 21, 2019 Share Posted August 21, 2019 19 hours ago, DavidW said: That's intentional: SSL explicitly avoids adding a See block for LastSeenBy(Myself), because in my use cases it's always redundant. If you want it for some reason, either put the See() command into your action definition explicitly, or else use %luke_myself_var% or something, and set that variable to LastSeenBy(Myself) in your TP2, so that it gets replaced in the BAF->BCS phase. (IIRC SSL doesn't evaluate WEIDU variables in the SSL->BAF phase.) I see, thanks for clarifying. Thing is that I need it because of what I told you before, i.e., the automation of something like this Spoiler IF !StateCheck(SixthNearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(SixthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF !StateCheck(FifthNearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(FifthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF !StateCheck(FourthNearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(FourthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF !StateCheck(ThirdNearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(ThirdNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF !StateCheck(SecondNearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(SecondNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF !StateCheck(NearestEnemyOf(Myself),STATE_MIRRORIMAGE) See(NearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(SixthNearestEnemyOf(Myself),STATE_BLUR) See(SixthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(FifthNearestEnemyOf(Myself),STATE_BLUR) See(FifthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(FourthNearestEnemyOf(Myself),STATE_BLUR) See(FourthNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(ThirdNearestEnemyOf(Myself),STATE_BLUR) See(ThirdNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(SecondNearestEnemyOf(Myself),STATE_BLUR) See(SecondNearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF StateCheck(NearestEnemyOf(Myself),STATE_BLUR) See(NearestEnemyOf(Myself)) False() THEN RESPONSE #100 NoAction() END IF // Possibly something else... See(LastSeenBy(Myself)) THEN RESPONSE #100 Attack(LastSeenBy(Myself)) END Anyway, thank you for the workaround, it works. I opted for the following one: Spoiler IF TRIGGER Target(LastSeenBy(Myself)) See(scstarget) THEN DO Action(AttackOneRound) END 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.