Page 1 of 1

Function event EQBC - New bots commands system (cmd,option and syntax flexible)

Posted: Fri Aug 25, 2017 8:48 pm
by moguay
I have build a new bots command concept, for orders more human
-with flexible send command to bots (/all, /me, /tar, /group, /<class name>)
-with flexible command syntax (ex /stick, /stick<option>, /stick <option>

Generally option use for most functions:
without option (just the cmd) = launch just one time the cmd
on = cmd is always maintain in full automatic
off = cmd is stopped

You can find the draft of all commands at this @ https://github.com/moguay/mq2-thf-macro ... ommands.md
Significantly reduces the number of aliases, increases the options possibilities (generic and specific), while remaining compatible with other code.
Good headache for those who seeks to understand a little.

Exemple with sticking cmd :

Code: Select all

/stickme     (stick all bots to the senders command)
/all /stick     (same with flex analysis)
/all /stickme   (same with flex analysis)
/all /stick me  (same with flex analysis)

/all /stick      (stick all bots)
/tar /stick      (stick target)
/rog /stick      (stick rogues)
/group /stick    (stick group)

Exemple for self command :

Code: Select all

/me /buff        (self buffing)
/me /buffon      (self buffing automatic)
/me /buffoff     (disable self buff)


The Draft of this new EQBC event CODE with just /stick command

Code: Select all

Sub Event_EQBC_NEW(EQBCSay,EQBCSender,EQBCCommand)

    /if (!${Bool[${EQBCCommand.Token[1, ]}]}) /return

    /if (${EQBCCommand.Token[1, ].Count[:]} == 3) {

        /if (!${Bool[${EQBCCommand.Token[2, ]}]}) /return

        /declare i int local
        /declare ME_CLASS       string  local ${Me.Class.ShortName}
        /declare ME_NAME        string  local ${Me.CleanName}
        /declare ME_ZONE        string  local ${Zone.ID}
        /declare ME_POS         string  local ${Me.Y},${Me.X},${Me.Z},${Me.Heading.Degrees}
        /declare ME_TYPE        string  local target
        /declare CLASS_LIST     string  local war|clr|pal|rng|shd|dru|mnk|brd|rog|shm|nec|wiz|mag|enc|bst|ber

        /declare hold_LIST      string  local 1|1|0|1
        /declare dps_LIST       string  local 0|0|LOW|MAX

        | NEW EQBC
        /declare ParamCount     int     local 1
        /declare WHO            string  local ${EQBCSender}
        /declare FOR            string  local ${EQBCCommand.Token[${ParamCount}, ].Token[1,:]}
        /declare TARGET         int     local ${Int[${EQBCCommand.Token[${ParamCount}, ].Token[2,:]}]}
        /declare ZONE           int     local ${Int[${EQBCCommand.Token[${ParamCount}, ].Token[3,:]}]}
        /declare POS            string  local ${EQBCCommand.Token[${ParamCount}, ].Token[4,:]}

        /varset EQBCCommand ${EQBCCommand.Right[-${Int[${Math.Calc[${EQBCCommand.Token[1, ].Length}+1]}]}]}

        /declare CMD            string  local ${EQBCCommand.Token[${ParamCount}, ]}
        /declare ARG            string  local
        :ARGLoop
        /varcalc ParamCount ${ParamCount}+1
        /if (${Bool[${EQBCCommand.Token[${ParamCount}, ]}]}) {
            /varset ARG ${ARG}|${EQBCCommand.Token[${ParamCount}, ]}|
            /goto :ARGLoop
        }
       
        | Exclude not in the same zone
        /if (!${Select[${CMD},rez,accept,zone,form,finditem,eq]} && !${Select[${ARG},it]} && ${ZONE}!=${ME_ZONE}) /return

        /if (!${FOR.Equal[ALL]} && !${FOR.Equal[${Me.CleanName}]}) {
            | Exclude if not the classes
            /if (${CLASS_LIST.Find[${FOR}]} && !${FOR.Equal[${Me.Class.ShortName}]}) {
                /return
            | Exclude not in group
            } else /if (${FOR.Equal[group]}) {
                | Find if in group
                /for i 0 to ${Group.Members}
                    /if (${Spawn[PC =${Group.Member[${i}].CleanName}].ID}!=${Spawn[PC =${EQBCSender}].ID} || ${Spawn[PC =${EQBCSender}].Distance} > 300) /return
                /next i
            | Exclude if not target
            } else /if (${FOR.Equal[tar]} && ${TARGET}!=${Me.ID}) {
                /return
            }
        }

        /if (${Bool[${ARG}]}) {
            /for i 1 to ${Math.Calc[${CLASS_LIST.Count[|]} + 1]}
                | Exclude if not the classes arg option
                /if (!${ARG.Find[|but|]}) {
                    /if (${ARG.Find[|${CLASS_LIST.Arg[${i},|]}|]} && !${Me.Class.ShortName.Equal[${CLASS_LIST.Arg[${i},|]}]}) /return
                } else {
                    /if (${ARG.Find[|${CLASS_LIST.Arg[${i},|]}|]} && ${Me.Class.ShortName.Equal[${CLASS_LIST.Arg[${i},|]}]}) /return
                }
            /next i
        }

|| Move commands
        /if (${Select[${CMD.Find[stick]},1,2]}) {
            /if ((${CMD.Find[me]} || ${CMD.Find[on]} || ${Select[${ARG.Arg[1,|]},NULL,on,me]}) && ${ZONE}==${ME_ZONE} && ${WHO.NotEqual[${Me.CleanName}]}) {
                                                    /multiline ; /docommand /${echo} -Sticking to [ ${Spawn[PC =${WHO}].CleanName} ];/squelch /face ID ${Spawn[PC =${WHO}].ID} fast;/squelch /stick ID ${Spawn[PC =${WHO}].ID} 10 moveback behindonce
                                                    /timed 10 /if (${Stick.Status.Equal[OFF]}) /bct ${WHO} NOT Sticking to [ ${Spawn[PC =${WHO}].CleanName} - ${Spawn[PC =${WHO}].Distance} - ${Spawn[PC =${WHO}].LineOfSight} - ${Zone.Name} ]
            } else /if ((${CMD.Find[off]} || ${ARG.Arg[1,|].Equal[off]}) && ${ZONE}==${ME_ZONE}) {
                                                    /squelch /stick off
                                                    /docommand /${echo} -STICK: off
            }
        }

|| Etc ...

/return


The code for defined and update MQ2 aliases

Code: Select all

|** AUTO REDEFINE ALIASES **|
    /if (!${Ini[..\MacroQuest.ini,Aliases,/me].Replace[$,].Replace[{,].Replace[},].Find[Me.CleanName:If]}) {
        /noparse /alias /me                             /bct ${Me.CleanName} ${Me.CleanName}:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/all].Replace[$,].Replace[{,].Replace[},].Find[all:If]}) {
        /noparse /alias /all                            /bc all:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/group].Replace[$,].Replace[{,].Replace[},].Find[group:If]}) {
        /noparse /alias /group                          /bc group:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/tar].Replace[$,].Replace[{,].Replace[},].Find[tar:If]}) {
        /noparse /alias /tar                            /bc tar:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/war].Replace[$,].Replace[{,].Replace[},].Find[war:If]}) {
        /noparse /alias /war                            /bc war:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/clr].Replace[$,].Replace[{,].Replace[},].Find[clr:If]}) {
        /noparse /alias /clr                            /bc clr:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/pal].Replace[$,].Replace[{,].Replace[},].Find[pal:If]}) {
        /noparse /alias /pal                            /bc pal:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/rng].Replace[$,].Replace[{,].Replace[},].Find[rng:If]}) {
        /noparse /alias /rng                            /bc rng:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/shd].Replace[$,].Replace[{,].Replace[},].Find[shd:If]}) {
        /noparse /alias /shd                            /bc shd:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/dru].Replace[$,].Replace[{,].Replace[},].Find[dru:If]}) {
        /noparse /alias /dru                            /bc dru:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/mnk].Replace[$,].Replace[{,].Replace[},].Find[mnk:If]}) {
        /noparse /alias /mnk                            /bc mnk:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/brd].Replace[$,].Replace[{,].Replace[},].Find[brd:If]}) {
        /noparse /alias /brd                            /bc brd:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/rog].Replace[$,].Replace[{,].Replace[},].Find[rog:If]}) {
        /noparse /alias /rog                            /bc rog:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/shm].Replace[$,].Replace[{,].Replace[},].Find[shm:If]}) {
        /noparse /alias /shm                            /bc shm:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/nec].Replace[$,].Replace[{,].Replace[},].Find[nec:If]}) {
        /noparse /alias /nec                            /bc nec:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/wiz].Replace[$,].Replace[{,].Replace[},].Find[wiz:If]}) {
        /noparse /alias /wiz                            /bc wiz:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/mag].Replace[$,].Replace[{,].Replace[},].Find[mag:If]}) {
        /noparse /alias /mag                            /bc mag:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/enc].Replace[$,].Replace[{,].Replace[},].Find[enc:If]}) {
        /noparse /alias /enc                            /bc enc:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/bst].Replace[$,].Replace[{,].Replace[},].Find[bst:If]}) {
        /noparse /alias /bst                            /bc bst:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/ber].Replace[$,].Replace[{,].Replace[},].Find[ber:If]}) {
        /noparse /alias /ber                            /bc ber:${If[${Target.ID},${Target.ID},]}:${Zone.ID}:${Me.Y.Int},${Me.X.Int},${Me.Z.Int},${Me.Heading.Degrees.Int}
    }
    /if (!${Ini[..\MacroQuest.ini,Aliases,/stop].Replace[$,].Replace[{,].Replace[},].Find[all::]}) {
        /alias /stop                                    /bc all::${Zone.ID}: off
    }

Re: Function event EQBC - New bots commands system (cmd,option and syntax flexible)

Posted: Sat Aug 26, 2017 11:55 am
by Denizen
Thanks for the "good headache"

Re: Function event EQBC - New bots commands system (cmd,option and syntax flexible)

Posted: Sat Aug 26, 2017 5:37 pm
by moguay
I have a little better to offer today
A scan to parse and retrieve options, commands when nested, ex / cothraid> cmd: coth option: raid

I will publish this for you when I have tested, to hate me a little more.

It is quite simple, it is written like this:
and you can launch stickon, stickme,stick or stickoff with or without space after stick...

Code: Select all

/for i ${CMD.Length} downto 2
            /varset COMMAND ${CMD.Left[${i}]}
            /varset OPTION |${CMD.Right[-${i}]}${ARG}

            /if (${Select[${COMMAND},stick]}) {
                /if (${Select[${OPTION.Arg[1,|]},on,me,NULL]} && ${WHO.NotEqual[${Me.CleanName}]}) {
blabla ...
                } else /if (${Select[${OPTION.Arg[1,|]},off]}) {
blabla ...
                }
            }
           
and some others commands....

/next i

Re: Function event EQBC - New bots commands system (cmd,option and syntax flexible)

Posted: Sat Sep 02, 2017 5:51 pm
by moguay
Probably it will not be the final code of the new EQBC function
in this version, many change, fix

For those who did not understand why integrate the exact coordinates of the sender. This allows all the bots to have accurate information and not the one on the server, often inaccurate or imprecise.
So here is why, I integrate this directly with the aliases and receive in the POS var.
Another solution would be to use NetBots to have this information, but this will not be exactly the same for everyone. (Because of the client + Macroquest running on the tic system, OnPulse)

Code: Select all

Sub Event_EQBC_NEW(EQBCSay,EQBCSender,EQBCCommand)

    /if (!${Bool[${EQBCCommand.Token[1, ]}]}) /return

    | FILTER for new command system only
    /if (${EQBCCommand.Token[1, ].Count[:]} == 3) {
        /if (!${Bool[${EQBCCommand.Token[2, ]}]}) /return

|| DEFINED VAR
        | TEMP VAR
        /declare i              int     local
       
        | SELF VAR
        /declare ME_CLASS       string  local ${Me.Class.ShortName}
        /declare ME_NAME        string  local ${Me.CleanName}
        /declare ME_ZONE        string  local ${Zone.ID}
        /declare ME_POS         string  local ${Me.Y},${Me.X},${Me.Z},${Me.Heading.Degrees}

        | EQBC VAR
        /declare ParamCount     int     local 1
        /declare WHO            string  local ${EQBCSender}
        /declare FOR            string  local ${EQBCCommand.Token[${ParamCount}, ].Token[1,:]}
        /declare TARGET         int     local ${Int[${EQBCCommand.Token[${ParamCount}, ].Token[2,:]}]}
        /declare ZONE           int     local ${Int[${EQBCCommand.Token[${ParamCount}, ].Token[3,:]}]}
        /declare POS            string  local ${EQBCCommand.Token[${ParamCount}, ].Token[4,:]}
       
        | CLASS VAR
        /declare bTANK          bool    local ${Bool[${Select[${ME_CLASS},WAR,SHD,PAL]}]}
        /declare bMELEE         bool    local ${Bool[${Select[${ME_CLASS},ROG,BER,BRD,MNK,RNG,WAR,PAL,SHD,BST]}]}
        /declare bSUP           bool    local ${Bool[${Select[${ME_CLASS},DRU,ENC,MAG,SHM]}]}
        /for i 1 to ${Math.Calc[${CLASS_LIST.Count[|]} + 1]}
            /declare b${CLASS_LIST.Arg[${i},|].Upper} bool local ${Bool[${Select[${ME_CLASS},${CLASS_LIST.Arg[${i},|].Upper}]}]}
        /next i
       
        | LIST VAR
        /declare CLASS_LIST     string  local war|clr|pal|rng|shd|dru|mnk|brd|rog|shm|nec|wiz|mag|enc|bst|ber
        /if (!${Defined[BOTS_LIST]}) {
            /declare BOTS_LIST  string global ${NetBots.Client.Replace[ ,|]}}
        }

        | COMMAND VAR
        /varset EQBCCommand ${EQBCCommand.Right[-${Int[${Math.Calc[${EQBCCommand.Token[1, ].Length}+1]}]}]}
        /declare COMMAND        string  local
        /declare CMD            string  local ${EQBCCommand.Token[${ParamCount}, ]}
        /if (${CMD.Find[/]} == 1) /varset CMD ${CMD.Right[-1]}
        | OPTIONS VAR
        /declare ARG            string  local
        /declare OPTION         string  local
        /declare OPTION1        string  local
        /declare OPTION2        string  local
        | BOTS VAR
        /declare ARG2           string  local
        /declare CONJONCTION    bool    local FALSE
       
|| STRUCTURE ARG AND ARG2
        :ARGLoop
        /varcalc ParamCount ${ParamCount}+1
        /if (${Bool[${EQBCCommand.Token[${ParamCount}, ]}]}) {
            /if (${Select[${EQBCCommand.Token[${ParamCount}, ]},but,and,not,nor,for,or,yet,so]}) /varset CONJONCTION TRUE
            /if (${CONJONCTION} || ${BOTS_LIST.Find[${EQBCCommand.Token[${ParamCount}, ].Replace[!,]}]} || ${CLASS_LIST.Find[${EQBCCommand.Token[${ParamCount}, ].Replace[!,]}]}) {
                /varset ARG2 ${ARG2}|${EQBCCommand.Token[${ParamCount}, ]}|
            } else /if (${Bool[${ARG2}]}) {
                /varset ARG2 ${ARG2}|${EQBCCommand.Token[${ParamCount}, ]}|
            } else {
                /varset ARG ${ARG}|${EQBCCommand.Token[${ParamCount}, ]}|
            }
            /goto :ARGLoop
        }

        | Only this list can be casted in different zone, all other is blocked
        /if (!${Select[${CMD},rez,accept,zone,form,finditem,eq]} && ${ZONE}!=${ME_ZONE}) /return

|| GLOBAL FOR Exclusion
        /if (!${FOR.Equal[all]}) {
            | Exclude if not me
            /if (${FOR.Equal[me]} && !${WHO.Equal[${Me.CleanName}]}) {
                | exclude for prevent bad couple FOR/CMD
                /if (!${Select[${CMD},stick]}) /return
            | Exclude if not the classes
            } else /if (${CLASS_LIST.Find[${FOR}]} && !${FOR.Equal[${ME_CLASS}]}) {
                /return
            | Exclude not in group
            } else /if (${FOR.Equal[group]}) {
                | Find if in group
                /for i 0 to ${Group.Members}
                    /if (${Spawn[PC =${Group.Member[${i}].CleanName}].ID}!=${Spawn[PC =${EQBCSender}].ID} || ${Spawn[PC =${EQBCSender}].Distance} > 300) /return
                /next i
            | Exclude if not target
            } else /if (${FOR.Equal[tar]} && ${TARGET}!=${Me.ID}) {
                /return
            }
        }

|| CLASSES AND BOTS Exclusion
        /if (${Bool[${ARG2}]}) {
            /declare ANALYSIS_LIST  string  local
            /declare bEXCLUDE       string  local FALSE
            | Exclude if not the classes arg option
            /for i 1 to ${Math.Calc[${CLASS_LIST.Count[|]} + 1]}
                | Add explicit and implicit class in list
                /if (${ARG2.Find[|!${CLASS_LIST.Arg[${i},|]}|]} || (${CONJONCTION} && ${ARG2.Find[|${CLASS_LIST.Arg[${i},|]}|]})) {
                    /varset ANALYSIS_LIST ${ANALYSIS_LIST}!${CLASS_LIST.Arg[${i},|]}|
                    | Fast explicit out
                    /if (${ME_CLASS.Equal[${CLASS_LIST.Arg[${i},|]}]}) /return
                } else /if (${ARG2.Find[|${CLASS_LIST.Arg[${i},|]}|]}) {
                    /varset ANALYSIS_LIST ${ANALYSIS_LIST}${CLASS_LIST.Arg[${i},|]}|
                }
            /next i
            | Exclude if not the name arg option
            /for i 1 to ${NetBots.Counts}
                | Add explicit and implicit name in list
                /if (${ARG2.Find[|!${NetBots.Client[${i}]}|]} || (${CONJONCTION} && ${ARG2.Find[|${NetBots.Client[${i}]}|]})) {
                    /varset ANALYSIS_LIST ${ANALYSIS_LIST}!${NetBots.Client[${i}]}|
                    | Fast explicit out
                    /if (${ME_NAME.Equal[${NetBots.Client[${i}]}]}) /return
                } else /if (${ARG2.Find[|${NetBots.Client[${i}]}|]}) {
                    /varset ANALYSIS_LIST ${ANALYSIS_LIST}${NetBots.Client[${i}]}|
                }
            /next i
            /if (${Bool[${ANALYSIS_LIST}]}) {
                /for i 1 to ${Math.Calc[${ANALYSIS_LIST.Count[|]} + 1]}
                    | Analysis explicit exclude (not really necessary if Fast explicit out work)
                    /if (${ANALYSIS_LIST.Arg[${i},|].Find[!]} == 1) {
                        /if (${Select[${ANALYSIS_LIST.Arg[${i},|]},!${ME_CLASS},!${ME_NAME}]}) /return
                    | Analysis implicit exclude
                    } else {
                        /if (${Select[${ANALYSIS_LIST.Arg[${i},|]},${ME_CLASS},${ME_NAME}]}) {
                            /varset bEXCLUDE FALSE_FORCED
                        } else {
                            /if (${bEXCLUDE.NotEqual[FALSE_FORCED]}) /varset bEXCLUDE TRUE
                        }
                    }
                /next i
                /if (${bEXCLUDE.Equal[TRUE]}) /return
            }
        }

|| COMMANDS by CLASSES Exclusion
        /if (${CMD.Find[tank]}                                              && !${bTANK})  /return
        /if (${CMD.Find[mel]}                                               && !${bMELEE}) /return
        /if (${CMD.Find[sup]}                                               && !${bSUP})   /return
        /if ((${CMD.Find[wiz]} || ${CMD.Find[nuke]} || ${CMD.Find[aoe]})    && !${bWIZ]})  /return
        /if (${CMD.Find[nec]}                                               && !${bNEC]})  /return
        /if (${CMD.Find[mez]}                                               && !${bENC})   /return
        /if (${CMD.Find[stun]}                                              && !${bPAL})   /return

|| COMMAND AND OPTION Analysis
        /for i ${CMD.Length} downto 2
            /varset COMMAND ${CMD.Left[${i}]}
            /varset OPTION |${CMD.Right[-${i}]}${ARG}
            /varset OPTION1 ${OPTION.Arg[1,|]}
            /varset OPTION2 ${OPTION.Arg[2,|]}
         
|| Tank commands
            /if (${Select[${COMMAND},tank]}) {
                /declare TankTarget_LIST    string  local 0|${ME_NAME}  |${ME_NAME} |${ME_NAME}
                /declare TankType_LIST      string  local 0|target      |aoe        |target
                /if (${Select[${OPTION1},off]}) {
                                                        /varset PetHoldType GO
                                                        /interrupt
                                                        /attack off
                                                        /docommand /${echo} -TANK off
                } else {
                                                        /attack on
                                                        /varset Message 1
                                                        /docommand /${echo} -TANK ${TankType_LIST.Arg[${Select[${OPTION1},off,on,aoe,NULL]},|].Replace[ ,]}
                }
                                                        /varset TankTarget ${TankTarget_LIST.Arg[${Select[${OPTION1},off,on,aoe,NULL]},|].Replace[ ,]}
                                                        /varset TankType ${TankType_LIST.Arg[${Select[${OPTION1},off,on,aoe,NULL]},|].Replace[ ,]}
                /return
            }
           
|| Attack commands
            /if (${Select[${COMMAND},atk,attack,on,allon,mel,stun,sup,wiz,nuke,aoe,nec,it]}) {
                /if (${bTANK} && ${Bool[${TankTarget}]}) /return
                /if (${strMainTank.Find[${Me.CleanName}]} && ${FarmType.Equal[0]} && !${Select[${COMMAND},it]}) /return
               
                /declare AtkTarget_LIST     string  local 0|${TARGET}   |999999     |${TARGET}
                /declare AtkType_LIST       string  local 0|${ME_CLASS} |${ME_CLASS}|${ME_CLASS}

                /if (${Select[${OPTION1},guard]}) {
                    /if (${FOR.Equal[me]} && ${WHO.Equal[${Me.CleanName}]}) {
                                                        /docommand /${echo} -ATK guard
                                                        /call command-${COMMAND}
                                                        /return
                    }
                } else /if (${Select[${OPTION1},off]}) {
                                                        /varset PetHoldType GO
                                                        /interrupt
                                                        /attack off
                                                        /docommand /${echo} -ATK off
                } else {
                                                        /attack on
                                                        /varset Message 1
                                                        /docommand /${echo} -ATK on
                }
                | Repace all TargetSupID,TargetWizardID,TargetNecromancerID by TargetCastID
                /if (${COMMAND.Find[stun]})             /varset StunType            ${AtkType_LIST.Arg[${Select[${OPTION1},off,on,it,NULL]},|].Replace[ ,]}
                /if (${bSUP} || ${bWIZ} || ${bNEC})     /varset SupType             ${AtkType_LIST.Arg[${Select[${OPTION1},off,on,it,NULL]},|].Replace[ ,]}
                /if (${bSUP})                           /varset TargetSupID         ${AtkTarget_LIST.Arg[${Select[${OPTION1},off,on,it,NULL]},|].Replace[ ,]}
                /if (${bWIZ})                           /varset TargetWizardID      ${AtkTarget_LIST.Arg[${Select[${OPTION1},off,on,it,NULL]},|].Replace[ ,]}
                /if (${bNEC})                           /varset TargetNecromancerID ${AtkTarget_LIST.Arg[${Select[${OPTION1},off,on,it,NULL]},|].Replace[ ,]}
                /if (${bMELEE} || ${bTANK})             /varset MeleeType           ${AtkType_LIST.Arg[${Select[${OPTION1},off,on,it,NULL]},|].Replace[ ,]}
                /if (${bMELEE} || ${bTANK})             /varset TargetMeleeID       ${AtkTarget_LIST.Arg[${Select[${OPTION1},off,on,it,NULL]},|].Replace[ ,]}
                /return
            }
             
|| Move commands
            /if (${Select[${COMMAND},stick]}) {
                /if (${Select[${OPTION1},on,me,NULL]} && ${WHO.NotEqual[${Me.CleanName}]}) {
                                                        /multiline ; /docommand /${echo} -Sticking to [ ${Spawn[PC =${WHO}].CleanName} ];/squelch /face ID ${Spawn[PC =${WHO}].ID} fast;/squelch /stick ID ${Spawn[PC =${WHO}].ID} 10 moveback behindonce
                                                        /timed 10 /if (${Stick.Status.Equal[OFF]}) /bct ${WHO} NOT Sticking to [ ${Spawn[PC =${WHO}].CleanName} - ${Spawn[PC =${WHO}].Distance} - ${Spawn[PC =${WHO}].LineOfSight} - ${Zone.Name} ]
                } else /if (${Select[${OPTION1},off]}) {
                                                        /squelch /stick off
                                                        /docommand /${echo} -STICK: off
                }
                /return
            }
           
|| Your other command ....
           
            /next i
      }
/return