//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
// Projet: MQ2Melee.cpp     |// Updated by Wasted on 02April2008
// Author: s0rCieR          |// Updated by Jobey on 08November2008
//                          |// Updated by htw on 26November2008
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
// SHOW_ABILITY:    0=0ff, 1=Display every ability that plugin use.
// SHOW_ATTACKING:  0=0ff, 1=Display Attacking Target
// SHOW_ENRAGING:   0=0ff, 1=Display Enrage/Infuriate
// SHOW_FEIGN:      0=0ff, 1=Display Fallen Detected
// SHOW_OVERRIDE:   0=0ff, 1=Display Override Warning
// SHOW_STICKING:   0=0ff, 1=Display Stick Arguments
// SHOW_SWITCHING:  0=0ff, 1=Display Switch Melee/Range
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
// Distribution of this code in compile form without source code is prohebited.
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
#define   PLUGIN_NAME  "MQ2Melee"   // Plugin Name
#define   PLUGIN_DATE   20090412    // Plugin Date
#define   PLUGIN_VERS      4.951    // Plugin Version

#define   SHOW_ABILITY         0
#define   SHOW_ATTACKING       1
#define   SHOW_CASTING         0
#define   SHOW_CONTROL         0
#define   SHOW_ENRAGING        1
#define   SHOW_FEIGN           1
#define   SHOW_OVERRIDE        1
#define   SHOW_PROVOKING       0
#define   SHOW_STICKING        1
#define   SHOW_STUNNING        0
#define   SHOW_SWITCHING       1

#define   NOID                -1
#define   delay              250

enum {
    Nokey              =0,    // WinClick(KeyState) nokey pressed
    Shiftkey           =1,    // WinClick(KeyState) Shiftkey pressed
    Ctrlkey          =256,    // WinClick(KeyState) Ctrlkey pressed
};

enum {
    Tiny               =0,    // Container Size - Tiny
    Small              =1,    // Container Size - Small
    Medium             =2,    // Container Size - Medium
    Large              =3,    // Container Size - Large
    Giant              =4,    // Container Size - Giant
    Huge               =5,    // Container Size - Huge
};

enum {
    st_x          =0x0000,    // SpawnType: NONE
    st_cn         =0x0020,    // SpawnType: CORPSENPC
    st_cp         =0x0010,    // SpawnType: CORPSEPLAYER
    st_wn         =0x0008,    // SpawnType: PETNPC
    st_wp         =0x0004,    // SpawnType: PETPLAYER
    st_n          =0x0002,    // SpawnType: NPC
    st_p          =0x0001,    // SpawnType: PLAYER
};

enum {
    inv_range         =11,    // Inventory.Range      Slot ID
    inv_primary       =13,    // Inventory.Primary    Slot ID
    inv_secondary     =14,    // Inventory.Secondary  Slot ID
    inv_ammo          =22,    // Inventory.Ammo       Slot ID
};

#ifndef PLUGIN_API
#include "../MQ2Plugin.h"
PreSetup(PLUGIN_NAME);
PLUGIN_VERSION(PLUGIN_VERS);
#include <map>
#include <string>
#include "../Blech/Blech.h"
#endif PLUGIN_API

//MoveUtils 9.x
void (*fStickCommand)(PSPAWNINFO pChar, PCHAR szLine);
bool* pbStickOn;
PLUGIN_API bool bMULoaded = false;
bool bMUPointers = false;

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

bool      DebugReady    = false;           // Use for debuffing Ability->Ready();
bool      BardClass     = false;           // Bard Class?
bool      Silenced      = false;           // Silenced?
long      BuffMax       = 25;              // Maximum Number of Buffs
long      SongMax       = 12;              // Maximum Number of Songs
long      GemsMax       = 10;              // Maximum Number of Gems
short     PET_BUTTONS   = 14;              // Number of buttons on Pet UI window

long      InvSlot       =NOID;            // slot # where item is found
PCONTENTS InvCont       =NULL;            // slot content pointer

bool      Sticking      =false;           // Stick Saved State On/Off?
char      StickArg[128] ={0};             // Stick Saved Arguments

char      Reserved[MAX_STRING];           // string buffer
char      Workings[MAX_STRING];           // string buffer

typedef   VOID  (__cdecl *Function)(VOID);
struct    infodata {long i,t; } *pinfodata;

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

#define   d_assassin1      10898
#define   d_assassin2      10899
#define   d_assassin3      10900
#define   d_ashenhand       4508
#define   d_heelofkanji     8473
#define   d_silentfist      4507
#define   d_thunderkick     4511
#define   d_cleaveanger     5043
#define   d_cleaverage      5037

#define   i_disarm            16
#define   i_forage            27
#define   i_intimidation      71
#define   i_kick              30
#define   i_mend              32
#define   i_taunt             73
#define   i_harmtouch        6000


infodata  callchal={552   ,4},  // aa: call of challenge
cmmding ={8000  ,3},  // disc: commanding voice
cryhavoc={8003  ,3},  // disc: cry havoc
escape  ={102   ,4},  // aa: escape
fistswu ={8002  ,3},  // disc: fists of wu
btlleap ={611   ,4},  // aa: battle leap
gutpunch={3732  ,4},  // aa: gut punch
sharmtou={6000  ,4},  // aa: harmtouch

feignid ={420   ,4},  // aa: imitate death
feigndp ={428   ,4},  // aa: death peace
feignsa ={366   ,5},  // spell: feign death
feignsb ={3685  ,5},  // spell: comatose
feignsc ={1460  ,5},  // spell: death peace
feignsd ={10306 ,5},  // spell: last breath
feignse ={10307 ,5},  // spell: last breath rk ii
feignsf ={10308 ,5},  // spell: last breath rk iii
feignsg ={15223 ,5},  // spell: rigor mortis
feignsh ={15224 ,5},  // spell: rigor mortis rk ii
feignsi ={15225 ,5},  // spell: rigor mortis rk iii
feignsj ={15190 ,5},  // spell: last gasp
feignsk ={15191 ,5},  // spell: last gasp rk ii
feignsl ={15192 ,5},  // spell: last gasp rk iii

feral1  ={247   ,4},  // aa: feral swipe

honora  ={10173 ,5},  // spell: challenge for honor
honorb  ={10174 ,5},  // spell: challenge for honor rk ii
honorc  ={10175 ,5},  // spell: challenge for honor rk iii
honord  ={14954 ,5},  // spell: trial for honor
honore  ={14955 ,5},  // spell: trial for honor rk ii
honorf  ={14956 ,5},  // spell: trial for honor rk iii
honorg  ={19068 ,5},  // spell: Charge for Honor
honorh  ={19069 ,5},  // spell: Charge for Honor rk ii
honori  ={19070 ,5},  // spell: Charge for Honor rk iii

joltbera={4934  ,3},  // disc: diversive strike
joltberb={4935  ,3},  // disc: distracting strike
joltberc={4936  ,3},  // disc: confusing strike
joltberd={6171  ,3},  // disc: baffling strike
joltbere={10920 ,3},  // disc: jarring strike
joltberf={10921 ,3},  // disc: jarring strike rk ii
joltberg={10922 ,3},  // disc: jarring strike rk iii
joltberh={14186 ,3},  // disc: jarring smash
joltberi={14187 ,3},  // disc: jarring smash rk ii
joltberj={14188 ,3},  // disc: jarring smash rk iii

joltbst1={362   ,4},  // aa: roar of thunder

joltrng1={1741  ,5},  // spell: jolt
joltrng2={1296  ,5},  // spell: cinder jolt
joltrng3={10086 ,3},  // disc: jolting kicks
joltrng4={10087 ,3},  // disc: jolting kicks rk ii
joltrng5={10088 ,3},  // disc: jolting kicks rk iii

layhand ={6001  ,4},  // aa: lay on hands

leop1   ={6752  ,3},  // disc: leopard claw
leop2   ={6727  ,3},  // disc: dragon fang
leop3   ={10944 ,3},  // disc: clawstriker flurry
leop4   ={10945 ,3},  // disc: clawstriker flurry rk ii
leop5   ={10946 ,3},  // disc: clawstriker flurry rk iii
leop6   ={14796 ,3},  // disc: wheel of fists
leop7   ={14797 ,3},  // disc: wheel of fists rk ii
leop8   ={14798 ,3},  // disc: wheel of fists rk iii
leop9   ={18901 ,3},  // disc: whorl of fists
leop10  ={18902 ,3},  // disc: whorl of fists rk ii
leop11  ={18903 ,3},  // disc: whorl of fists rk iii

mendpet1={58    ,4},  // aa: mend companion
mendpet2={418   ,4},  // aa: replenish companion

potfast0={77789 ,7},  // potion: Distillate of Divine Healing I
potfast1={77790 ,7},  // potion: Distillate of Divine Healing II
potfast2={77791 ,7},  // potion: Distillate of Divine Healing III
potfast3={77792 ,7},  // potion: Distillate of Divine Healing IV
potfast4={77793 ,7},  // potion: Distillate of Divine Healing V
potfast5={77794 ,7},  // potion: Distillate of Divine Healing VI
potfast6={77795 ,7},  // potion: Distillate of Divine Healing VII
potfast7={77796 ,7},  // potion: Distillate of Divine Healing VIII
potfast8={77797 ,7},  // potion: Distillate of Divine Healing IX
potfast9={77798 ,7},  // potion: Distillate of Divine Healing X
potfast10={35930 ,7}, // potion: Distillate of Divine Healing XI
potfast11={35935 ,7}, // potion: Distillate of Divine Healing XII
potfast12={35940 ,7}, // potion: Distillate of Divine Healing XIII
potfast13={40554 ,7}, // potion: Distillate of Divine Healing XIV

potover0={77779 ,7},  // potion: Distillate of Celestial Healing I
potover1={77780 ,7},  // potion: Distillate of Celestial Healing II
potover2={77781 ,7},  // potion: Distillate of Celestial Healing III
potover3={77782 ,7},  // potion: Distillate of Celestial Healing IV
potover4={77783 ,7},  // potion: Distillate of Celestial Healing V
potover5={77784 ,7},  // potion: Distillate of Celestial Healing VI
potover6={77785 ,7},  // potion: Distillate of Celestial Healing VII
potover7={77786 ,7},  // potion: Distillate of Celestial Healing VIII
potover8={77787 ,7},  // potion: Distillate of Celestial Healing IX
potover9={77788 ,7},  // potion: Distillate of Celestial Healing X
potover10={35931 ,7}, // potion: Distillate of Celestial Healing XI
potover11={35936 ,7}, // potion: Distillate of Celestial Healing XII
potover12={35941 ,7}, // potion: Distillate of Celestial Healing XIII
potover13={40555 ,7}, // potion: Distillate of Celestial Healing XIV

powera  ={10260 ,5},  // spell: challenge for power
powerb  ={10261 ,5},  // spell: challenge for power rk ii
powerc  ={10262 ,5},  // spell: challenge for power rk iii
powerd  ={15163 ,5},  // spell: trial for power
powere  ={15164 ,5},  // spell: trial for power rk ii
powerf  ={15165 ,5},  // spell: trial for power rk iii
powerg  ={19316 ,5},  // spell: Charge for Power 
powerh  ={19317 ,5},  // spell: Charge for Power rk ii
poweri  ={19318 ,5},  // spell: Charge for Power rk iii

prowar_a={4608  ,3},  // disc: provoke
prowar_b={4681  ,3},  // disc: bellow
prowar_c={4682  ,3},  // disc: berate
prowar_d={4697  ,3},  // disc: incite
prowar_e={5015  ,3},  // disc: bellow of the mastruq
prowar_f={5016  ,3},  // disc: ancient: chaos cry
prowar_g={6173  ,3},  // disc: bazu bellow
prowar_h={10974 ,3},  // disc: scowl
prowar_i={10975 ,3},  // disc: scowl rk ii
prowar_j={10976 ,3},  // disc: scowl rk iii
prowar_k={15360 ,3},  // disc: sneer
prowar_l={15361 ,3},  // disc: sneer rk ii
prowar_m={15362 ,3},  // disc: sneer rk iii
prowar_n={19531 ,3},  // disc: jeer rk i
prowar_o={19532 ,3},  // disc: jeer rk ii
prowar_p={19533 ,3},  // disc: jeer rk iii
prowar_q={19537 ,3},  // disc: Bazu Bluster
prowar_r={19538 ,3},  // disc: Bazu Bluster Rk. II
prowar_s={19539 ,3},  // disc: Bazu Bluster Rk. III

throata={10968 ,3},    // disc: throat jab
throatb={10969 ,3},    // disc: throat jab rk ii
throatc={10970 ,3},    // disc: throat jab rk iii

opstrkea={15375 ,3},  // disc: opportunistic strike
opstrkeb={15376 ,3},  // disc: opportunistic strike rk ii
opstrkec={15377 ,3},  // disc: opportunistic strike rk iii

rake1   ={8782  ,3},  // disc: rake
rake2   ={14158 ,3},  // disc: harrow
rake3   ={14159 ,3},  // disc: harrow rk ii
rake4   ={14160 ,3},  // disc: harrow rk iii

strikea ={4659  ,3},  // disc: sneak attack
strikeb ={4685  ,3},  // disc: thief's vengeance
strikec ={4686  ,3},  // disc: assasin strike
striked ={5017  ,3},  // disc: kyv strike
strikee ={5018  ,3},  // disc: ancient chaos strike
strikef ={6174  ,3},  // disc: daggerfall
strikeg ={8470  ,3},  // disc: razor arc
strikeh ={15133, 3},  // disc: swiftblade
strikei ={15134, 3},  // disc: swiftblade rk ii
strikej ={15135, 3},  // disc: swiftblade rk iii

stunbera={4931  ,3},  // disc: head strike
stunberb={4932  ,3},  // disc: head pummel
stunberc={4933  ,3},  // disc: head crush
stunberd={6170  ,3},  // disc: mind strike
stunbere={10917 ,3},  // disc: temple blow
stunberf={10918 ,3},  // disc: temple blow rk ii
stunberg={10919 ,3},  // disc: temple blow rk iii
stunberh={14183 ,3},  // disc: temple strike
stunberi={14184 ,3},  // disc: temple strike rk ii
stunberj={14185 ,3},  // disc: temple strike rk iii

stunmnk1={469   ,4},  // aa: stunning kick
stunmnk2={600   ,4},  // aa: resounding kick

stunpal1={73    ,4},  // aa: divine stun
stunpal2={702   ,4},  // aa: hand of disruption
stunpal3={3826  ,4},  // aa: force of disruption

stunpala={216   ,5},  // spell: stun
stunpalb={123   ,5},  // spell: holy might
stunpalc={3975  ,5},  // spell: force of akera
stunpald={3245  ,5},  // spell: force of akilae
stunpale={4977  ,5},  // spell: ancient force of chaos
stunpalf={5284  ,5},  // spell: force of piety
stunpalg={5299  ,5},  // spell: ancient force of jeron
stunpalh={10158 ,5},  // spell: sacred force
stunpali={10159 ,5},  // spell: sacred force rk ii
stunpalj={10160 ,5},  // spell: sacred force rk iii
stunpalk={11851 ,5},  // spell: force of prexus
stunpall={14942 ,5},  // spell: solemn force
stunpalm={14943 ,5},  // spell: solemn force rk ii
stunpaln={14944 ,5},  // spell: solemn force rk iii
stunpalo={14984 ,5},  // spell: Force of Timorous
stunpalp={14985 ,5},  // spell: Force of Timorous  rk ii
stunpalq={14986 ,5},  // spell: Force of Timorous  rk iii
stunpalr={19056 ,5},  // spell: Devout Force
stunpals={19057 ,5},  // spell: Devout Force rk ii
stunpalt={19058 ,5},  // spell: Devout Force rk iii
stunpalu={19098 ,5},  // spell: Force of the Crying Seas
stunpalv={19099 ,5},  // spell: Force of the Crying Seas ii
stunpalw={19100 ,5},  // spell: Force of the Crying Seas rk iii

terrora ={1223  ,5},  // spell: terror of death
terrorb ={1224  ,5},  // spell: terror of terris
terrorc ={3405  ,5},  // spell: terror of thule
terrord ={5329  ,5},  // spell: terror of discord
terrore ={10257 ,5},  // spell: terror of vergalid
terrorf ={10258 ,5},  // spell: terror of vergalid rk ii
terrorg ={10259 ,5},  // spell: terror of vergalid rk iii
terrorh ={15160 ,5},  // spell: terror of the Soulbleeder
terrori ={15161 ,5},  // spell: terror of the Soulbleeder rk ii
terrorj ={15162 ,5},  // spell: terror of the Soulbleeder rk iii
terrorl ={19313 ,5},  // spell: Terror of Jelvalak
terrorm ={19314 ,5},  // spell: Terror of Jelvalak rk ii
terrorn ={19315 ,5},  // spell: Terror of Jelvalak rk iii

thiefeye={8001  ,3},  // disc: thief's eye
tstone  ={5225  ,3},  // disc: throw stone
twisted ={670   ,4},  // aa: twisted shank

volleya ={6754  ,3},  // disc: rage volley
volleyb ={6729  ,3},  // disc: destroyer's volley
volleyc ={10926 ,3},  // disc: giant slayer's volley
volleyd ={10927 ,3},  // disc: giant slayer's volley rk ii
volleye ={10928 ,3},  // disc: giant slayer's volley rk iii
volleyf ={11928 ,3},  // disc: annihilator's volley
volleyg ={11929 ,3},  // disc: annihilator's volley rk ii
volleyh ={11930 ,3},  // disc: annihilator's volley rk iii
volleyi ={14195 ,3},  // disc: decimator's volley
volleyj ={14196 ,3},  // disc: decimator's volley rk ii
volleyk ={14197 ,3},  // disc: decimator's volley rk iii
volleyl ={18216 ,3},  // disc: Eradicator's Volley
volleym ={18217 ,3},  // disc: Eradicator's Volley Rk. II
volleyn ={18218 ,3},  // disc: Eradicator's Volley Rk. III

sbkstab ={8     ,2},  // skill: backstab
sbash   ={10    ,2},  // skill: bash
sbegging={67    ,2},  // skill: begging
sdisarm ={16    ,2},  // skill: disarm
sdrpunch={21    ,2},  // skill: dragon punch
sestrike={23    ,2},  // skill: eagle strike
sfeign  ={25    ,2},  // skill: feign death
sflykick={26    ,2},  // skill: flying kick
sforage ={27    ,2},  // skill: forage
sfrenzy ={74    ,2},  // skill: frenzy
shide   ={29    ,2},  // skill: hide
sintim  ={71    ,2},  // skill: intimidation
skick   ={30    ,2},  // skill: kick
smend   ={32    ,2},  // skill: mend
sppocket={48    ,2},  // skill: pick pockets
srndkick={38    ,2},  // skill: round kick
ssensetr={62    ,2},  // skill: sense trap
sslam   ={111   ,2},  // skill: slam
ssneak  ={42    ,2},  // skill: sneak
staunt  ={73    ,2},  // skill: taunt
stigclaw={52    ,2};  // skill: tigerclaw

PCHAR pAGGRO[]={
    "aggro",
    "[ON/OFF]?",
    "${If[${Select[${Me.Class.ShortName},WAR,PAL,SHD]},1,0]}",
    "${If[${meleemvi[plugin]},1,0]}",
};

PCHAR pAGGRP[]={
    "aggropri",
    "[ID] Primary (Aggro)?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${meleemvi[aggro]},1,0]}",
};

PCHAR pAGGRS[]={
    "aggrosec",
    "[ID] Offhand (Aggro)?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${meleemvi[aggro]} && ${meleemvi[aggropri]},1,0]}",
};

PCHAR pARROW[]={
    "arrow",
    "[ID] item?",
    "0",
    "${If[${meleemvi[plugin]} && (${Me.Skill[archery]} || ${Me.Skill[throwing]}),1,0]}",
};

PCHAR pASSAS[]={
    "assasinate",
    "Sneak/Hide/Behind/Strike/Stab [ON/OFF]?",
    "${If[${Me.Skill[backstab]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${meleemvi[backstab]},1,0]}",
};

PCHAR pBKOFF[]={
    "backoff",
    "[#] Life% Below? 0=0ff",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && !${meleemvi[aggro]},1,0]}",
};

PCHAR pBSTAB[]={
    "backstab",
    "[ON/OFF]?",
    "${If[${Me.Skill[backstab]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[backstab]},1,0]}",
};

PCHAR pBASHS[]={
    "bash",
    "[#] Bash 0=0ff",
    "${If[${Me.Skill[bash]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[bash]},1,0]}",
};

PCHAR pBGING[]={
    "begging",
    "[ON/OFF]?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[begging]},1,0]}",
};

PCHAR pBOWID[]={
    "bow",
    "[ID] spell/disc/aa/item?",
    "0",
    "${If[${meleemvi[plugin]} && ${Me.Skill[archery]},1,0]}",
};

PCHAR pCALLC[]={
    "callchallenge",
    "[ON/OFF]?",
    "${If[${Me.AltAbility[call of challenge]},1,0]}",
    "${If[${meleemvi[plugin]} && ${Me.AltAbility[call of challenge]},1,0]}",
};

PCHAR pGTPUN[]={
    "gutpunch",
    "[ON/OFF]?",
    "${If[${Me.AltAbility[gut punch]},1,0]}",
    "${If[${meleemvi[plugin]} && ${Me.AltAbility[gut punch]},1,0]}",
};

PCHAR pOSTRK[]={
    "opportunisticstrike",
    "[ON/OFF]?",
    "${If[${Me.AltAbility[opportunistic strike]},1,0]}",
    "${If[${meleemvi[plugin]} && ${Me.AltAbility[opportunistic strike]},1,0]}",
};

PCHAR pTTJAB[]={
    "throatjab",
    "[ON/OFF]?",
    "${If[${Me.AltAbility[throat jab]},1,0]}",
    "${If[${meleemvi[plugin]} && ${Me.AltAbility[throat jab]},1,0]}",
};

PCHAR pBTLLP[]={
    "battleleap",
    "[ON/OFF]?",
    "${If[${Me.AltAbility[Battle Leap]},1,0]}",
    "${If[${meleemvi[plugin]} && ${Me.AltAbility[Battle Leap]},1,0]}",
};

PCHAR pCHFOR[]={
    "challengefor",
    "[ON/OFF]?",
    "${If[${Me.Book[challenge for honor]} || ${Me.Book[challenge for honor rk. ii]} || ${Me.Book[challenge for honor rk. iii]} || ${Me.Book[trial for honor]} || ${Me.Book[trial for honor rk. ii]} || ${Me.Book[trial for honor rk. iii]} || ${Me.Book[charge for honor]} || ${Me.Book[charge for honor rk. ii]} || ${Me.Book[charge for honor rk. iii]} || ${Me.Book[challenge for power]} || ${Me.Book[challenge for power rk. ii]} || ${Me.Book[challenge for power rk. iii]} || ${Me.Book[trial for power]} || ${Me.Book[trial for power rk. ii]} || ${Me.Book[trial for power rk. iii]} || ${Me.Book[charge for honor]} || ${Me.Book[charge for honor rk. ii]} || ${Me.Book[charge for honor rk. iii]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[aggro]} && (${Me.Book[challenge for honor]} || ${Me.Book[challenge for honor rk. ii]} || ${Me.Book[challenge for honor rk. iii]} || ${Me.Book[trial for honor]} || ${Me.Book[trial for honor rk. ii]} || ${Me.Book[trial for honor rk. iii]} || ${Me.Book[charge for honor]} || ${Me.Book[charge for honor rk. ii]} || ${Me.Book[charge for honor rk. iii]} || ${Me.Book[challenge for power]} || ${Me.Book[challenge for power rk. ii]} || ${Me.Book[challenge for power rk. iii]} || ${Me.Book[trial for power]} || ${Me.Book[trial for power rk. ii]} || ${Me.Book[trial for power rk. iii]}) || ${Me.Book[charge for honor]} || ${Me.Book[charge for honor rk. ii]} || ${Me.Book[charge for honor rk. iii]},1,0]}",
};

PCHAR pCOMMG[]={
    "commanding",
    "[#] Endu% Above? 0=0ff",
    "${If[${Me.CombatAbility[commanding voice]},60,0]}",
    "${If[${meleemvi[plugin]} && ${Me.CombatAbility[commanding voice]},1,0]}",
};

PCHAR pCRYHC[]={
    "cryhavoc",
    "[#] Endu% Above? 0=0ff",
    "${If[${Me.CombatAbility[cry havoc]},60,0]}",
    "${If[${meleemvi[plugin]} && ${Me.CombatAbility[cry havoc]},1,0]}",
};

PCHAR pDISRM[]={
    "disarm",
    "[ON/OFF]?",
    "${If[${Me.Skill[disarm]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[disarm]},1,0]}",
};

PCHAR pDWNF0[]={
    "downflag0",
    "[ON/OFF] downflag0?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit0].Length},1,0]}",
};

PCHAR pDWNF1[]={
    "downflag1",
    "[ON/OFF] downflag1?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit1].Length},1,0]}",
};

PCHAR pDWNF2[]={
    "downflag2",
    "[ON/OFF] downflag2?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit2].Length},1,0]}",
};

PCHAR pDWNF3[]={
    "downflag3",
    "[ON/OFF] downflag3?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit3].Length},1,0]}",
};

PCHAR pDWNF4[]={
    "downflag4",
    "[ON/OFF] downflag4?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit4].Length},1,0]}",
};

PCHAR pDWNF5[]={
    "downflag5",
    "[ON/OFF] downflag5?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit5].Length},1,0]}",
};

PCHAR pDWNF6[]={
    "downflag6",
    "[ON/OFF] downflag6?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit6].Length},1,0]}",
};

PCHAR pDWNF7[]={
    "downflag7",
    "[ON/OFF] downflag7?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit7].Length},1,0]}",
};

PCHAR pDWNF8[]={
    "downflag8",
    "[ON/OFF] downflag8?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit8].Length},1,0]}",
};

PCHAR pDWNF9[]={
    "downflag9",
    "[ON/OFF] downflag9?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit9].Length},1,0]}",
};

PCHAR pDWNF10[]={
    "downflag10",
    "[ON/OFF] downflag10?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit10].Length},1,0]}",
};

PCHAR pDWNF11[]={
    "downflag11",
    "[ON/OFF] downflag11?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit11].Length},1,0]}",
};

PCHAR pDWNF12[]={
    "downflag12",
    "[ON/OFF] downflag12?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit12].Length},1,0]}",
};

PCHAR pDWNF13[]={
    "downflag13",
    "[ON/OFF] downflag13?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit13].Length},1,0]}",
};

PCHAR pDWNF14[]={
    "downflag14",
    "[ON/OFF] downflag14?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit14].Length},1,0]}",
};

PCHAR pDWNF15[]={
    "downflag15",
    "[ON/OFF] downflag15?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[downshit15].Length},1,0]}",
};

PCHAR pDRPNC[]={
    "dragonpunch",
    "[ON/OFF]?",
    "${If[${Me.Skill[dragon punch]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[dragon punch]},1,0]}",
};

PCHAR pEAGLE[]={
    "eaglestrike",
    "[ON/OFF]?",
    "${If[${Me.Skill[eagle strike]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[eagle strike]},1,0]}",
};

PCHAR pERAGE[]={
    "enrage",
    "[ON/OFF]?",
    "1",
    "${If[${meleemvi[plugin]},1,0]}",
};

PCHAR pESCAP[]={
    "escape",
    "[#] Life% Below? 0=0ff",
    "${If[${Me.AltAbility[escape]},20,0]}",
    "${If[${meleemvi[plugin]} && !${meleemvi[aggro]} && ${Me.AltAbility[escape]},1,0]}",
};

PCHAR pEVADE[]={
    "evade",
    "[#] [ON/OFF]?",
    "${If[${Me.Skill[hide]} && ${Me.Class.ShortName.Equal[ROG]},1,0]}",
    "${If[${meleemvi[plugin]} && !${meleemvi[aggro]} && ${Me.Skill[hide]} && ${Me.Class.ShortName.Equal[ROG]},1,0]}",
};

PCHAR pFEIGN[]={
    "feigndeath",
    "[#] Life% Below? 0=0ff",
    "${If[${Select[${Me.Class.ShortName},SHD,NEC,MNK]},30,0]}",
    "${If[${meleemvi[plugin]} && !${meleemvi[aggro]} && ${Select[${Me.Class.ShortName},SHD,NEC,MNK]},1,0]}",
};

PCHAR pFACES[]={
    "facing",
    "[ON/OFF] Face Target (Range)?",
    "1",
    "${If[${meleemvi[plugin]} && ${meleemvi[range]},1,0]}",
};

PCHAR pFALLS[]={
    "falls",
    "[ON/OFF] Auto-Feign?",
    "0",
    "${If[${meleemvi[plugin]} && !${meleemvi[aggro]} && ${Me.Class.ShortName.Equal[MNK]},1,0]}",
};

PCHAR pFERAL[]={
    "feralswipe",
    "[ON/OFF]?",
    "${If[${Me.AltAbility[feral swipe]},1,0]}",
    "${If[${meleemvi[plugin]} && ${Me.AltAbility[feral swipe]},1,0]}",
};

PCHAR pFISTS[]={
    "fistsofwu",
    "[#] Endu% Above? 0=0ff",
    "${If[${Me.CombatAbility[fists of wu]},60,0]}",
    "${If[${meleemvi[plugin]} && ${Me.CombatAbility[fists of wu]},1,0]}",
};

PCHAR pFLYKC[]={
    "flyingkick",
    "[ON/OFF]?",
    "${If[${Me.Skill[flying kick]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[flying kick]},1,0]}",
};

PCHAR pFORAG[]={
    "forage",
    "[ON/OFF]?",
    "0",
    "${If[${meleemvi[plugin]} && ${Me.Skill[forage]},1,0]}",
};

PCHAR pFRENZ[]={
    "frenzy",
    "[ON/OFF]?",
    "${If[${Me.Skill[frenzy]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[frenzy]} && ${Me.Skill[frenzy]},1,0]}",
};

PCHAR pHARMT[]={
    "harmtouch",
    "[ON/OFF]?",
    "${If[${Me.Skill[harm touch]}!=255,1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[harm touch]}!=255,1,0]}",
};

PCHAR pHIDES[]={
    "hide",
    "[ON/OFF]?",
    "0",
    "${If[${meleemvi[plugin]} && ${Me.Skill[hide]},1,0]}",
};

PCHAR pHOLF0[]={
    "holyflag0",
    "[ON/OFF] holyflag0?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit0].Length},1,0]}",
};

PCHAR pHOLF1[]={
    "holyflag1",
    "[ON/OFF] holyflag1?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit1].Length},1,0]}",
};

PCHAR pHOLF2[]={
    "holyflag2",
    "[ON/OFF] holyflag2?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit2].Length},1,0]}",
};

PCHAR pHOLF3[]={
    "holyflag3",
    "[ON/OFF] holyflag3?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit3].Length},1,0]}",
};

PCHAR pHOLF4[]={
    "holyflag4",
    "[ON/OFF] holyflag4?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit4].Length},1,0]}",
};

PCHAR pHOLF5[]={
    "holyflag5",
    "[ON/OFF] holyflag5?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit5].Length},1,0]}",
};

PCHAR pHOLF6[]={
    "holyflag6",
    "[ON/OFF] holyflag6?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit6].Length},1,0]}",
};

PCHAR pHOLF7[]={
    "holyflag7",
    "[ON/OFF] holyflag7?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit7].Length},1,0]}",
};

PCHAR pHOLF8[]={
    "holyflag8",
    "[ON/OFF] holyflag8?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit8].Length},1,0]}",
};

PCHAR pHOLF9[]={
    "holyflag9",
    "[ON/OFF] holyflag9?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit9].Length},1,0]}",
};

PCHAR pHOLF10[]={
    "holyflag10",
    "[ON/OFF] holyflag10?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit10].Length},1,0]}",
};

PCHAR pHOLF11[]={
    "holyflag11",
    "[ON/OFF] holyflag11?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit11].Length},1,0]}",
};

PCHAR pHOLF12[]={
    "holyflag12",
    "[ON/OFF] holyflag12?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit12].Length},1,0]}",
};

PCHAR pHOLF13[]={
    "holyflag13",
    "[ON/OFF] holyflag13?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit13].Length},1,0]}",
};

PCHAR pHOLF14[]={
    "holyflag14",
    "[ON/OFF] holyflag14?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit14].Length},1,0]}",
};

PCHAR pHOLF15[]={
    "holyflag15",
    "[ON/OFF] holyflag15?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvs[holyshit15].Length},1,0]}",
};

PCHAR pINFUR[]={
    "infuriate",
    "[ON/OFF]?",
    "1",
    "${If[${meleemvi[plugin]},1,0]}",
};

PCHAR pINTIM[]={
    "intimidation",
    "[ON/OFF]?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[intimidation]},1,0]}",
};

PCHAR pJOLTS[]={
    "jolt",
    "Every [#] of Hits,0=0ff",
    "0",
    "${If[${meleemvi[plugin]} && !${meleemvi[aggro]} && ${Select[${Me.Class.ShortName},BER,BST,RNG]},1,0]}",
};

PCHAR pKICKS[]={
    "kick",
    "[ON/OFF]?",
    "${If[${Me.Skill[kick]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[kick]},1,0]}",
};

PCHAR pLHAND[]={
    "layhand",
    "[#] MyLife% Below? 0=0ff",
    "${If[${Me.AltAbility[Lay on Hands]},1,0]}",
    "${If[${meleemvi[plugin]} && ${Me.AltAbility[Lay on Hands]},1,0]}",
};

PCHAR pLCLAW[]={
    "leopardclaw",
    "[#] Endu% Above? 0=0ff",
    "${If[${Me.CombatAbility[leopard claw]} || ${Me.CombatAbility[dragon fang]} || ${Me.CombatAbility[clawstriker's flurry]} || ${Me.CombatAbility[clawstriker's flurry rk. ii]} || ${Me.CombatAbility[clawstriker's flurry rk. iii]} || ${Me.CombatAbility[wheel of fists]} || ${Me.CombatAbility[wheel of fists rk. ii]} || ${Me.CombatAbility[wheel of fists rk. iii]},60,0]}",
    "${If[${meleemvi[plugin]} && (${Me.CombatAbility[leopard claw]} || ${Me.CombatAbility[dragon fang]} || ${Me.CombatAbility[clawstriker's flurry]} || ${Me.CombatAbility[clawstriker's flurry rk. ii]} || ${Me.CombatAbility[clawstriker's flurry rk. iii]} || ${Me.CombatAbility[wheel of fists]} || ${Me.CombatAbility[wheel of fists rk. ii]} || ${Me.CombatAbility[wheel of fists rk. iii]}),1,0]}",
};

PCHAR pMELEE[]={
    "melee",
    "[ON/OFF] Melee Mode? 0=0ff",
    "${If[${Select[${Me.Class.ShortName},WAR,PAL,RNG,SHD,MNK,BRD,ROG,BST,BER]},1,0]}",
    "${If[${meleemvi[plugin]},1,0]}",
};

PCHAR pMELEP[]={
    "meleepri",
    "[ID] Primary (Melee)?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && !${meleemvi[aggro]},1,0]}",
};

PCHAR pMELES[]={
    "meleesec",
    "[ID] Offhand (Melee)?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && !${meleemvi[aggro]},1,0]} && ${meleemvi[meleepri]}",
};

PCHAR pMENDS[]={
    "mend",
    "[#] MyLife% Below? 0=0ff",
    "${If[${Me.Skill[mend]},1,0]}",
    "${If[${meleemvi[plugin]} && ${Me.Skill[mend]},1,0]}",
};

PCHAR pPETAS[]={
    "petassist",
    "[ON/OFF] Assist Me?",
    "${If[${Select[${Me.Class.ShortName},SHD,DRU,SHM,NEC,MAG,ENC,BST]},1,0]}",
    "${If[${meleemvi[plugin]} && ${Select[${Me.Class.ShortName},SHD,DRU,SHM,NEC,MAG,ENC,BST]},1,0]}",
};

PCHAR pPETDE[]={
    "petdelay",
    "[#] # Sec Delay Before Engaging?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[petassist]} && ${Select[${Me.Class.ShortName},SHD,DRU,SHM,NEC,MAG,ENC,BST]},1,0]}",
};

PCHAR pPETRN[]={
    "petrange",
    "[#] Target/Pet in this range?",
    "75",
    "${If[${meleemvi[plugin]} && ${meleemvi[petassist]} && ${Select[${Me.Class.ShortName},SHD,DRU,SHM,NEC,MAG,ENC,BST]},1,0]}",
};

PCHAR pPETMN[]={
    "petmend",
    "[#] Mend Pet Life % Below 0=0ff?",
    "20",
    "${If[${meleemvi[plugin]} && ${meleemvi[petassist]} && ${Me.AltAbility[mend companion]} && ${Select[${Me.Class.ShortName},SHD,DRU,SHM,NEC,MAG,ENC,BST]},1,0]}",
};

PCHAR pPICKP[]={
    "pickpocket",
    "[ON/OFF]?",
    "${If[${Me.Skill[pick pockets]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[pick pockets]},1,0]}",
};

PCHAR pPLUGS[]={
    "plugin",
    "[ON/OFF]?",
    "1",
    "1",
};

PCHAR pPOKER[]={
    "poker",
    "[ID] item?",
    "0",
    "${If[${meleemvi[plugin]} && ${Me.Skill[backstab]},1,0]}",
};

PCHAR pHFAST[]={
    "pothealfast",
    "[#] MyLife% Below? 0=0ff (FAST)",
    "${If[${meleemvi[idpothealfast]},30,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[idpothealfast]},1,0]}",
};

PCHAR pHOVER[]={
    "pothealover",
    "[#] MyLife% Below? 0=0ff (OVER)",
    "${If[${meleemvi[idpothealover]},60,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[idpothealover]},1,0]}",
};

PCHAR pPRVKO[]={
    "provokeonce",
    "[ON/OFF]?",
    "${If[${Select[${Me.Class.ShortName},WAR,PAL,SHD,MNK,BER]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[aggro]} && ${Select[${Me.Class.ShortName},WAR,PAL,SHD,MNK,BER]},1,0]}",
};

PCHAR pPRVKM[]={
    "provokemax",
    "[#] Counter? ,1=try once, 0=0ff",
    "${If[${Select[${Me.Class.ShortName},WAR,PAL,SHD,MNK,BER]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[aggro]} && ${Select[${Me.Class.ShortName},WAR,PAL,SHD,MNK,BER]},1,0]}",
};

PCHAR pPRVKE[]={
    "provokeend",
    "[#] Stop when Target Life% Below?",
    "${If[${Select[${Me.Class.ShortName},WAR,PAL,SHD,MNK,BER]},20,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[aggro]} && ${meleemvi[provokemax]} && ${Select[${Me.Class.ShortName},WAR,PAL,SHD,MNK,BER]},1,0]}",
};

PCHAR pPRVK0[]={
    "provoke0",
    "[ID] spell/disc/aa/item?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[aggro]} && ${meleemvi[provokemax]} && ${Select[${Me.Class.ShortName},WAR,PAL,SHD,MNK,BER]},1,0]}",
};

PCHAR pPRVK1[]={
    "provoke1",
    "[ID] spell/disc/aa/item?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[aggro]} && ${meleemvi[provokemax]} && ${Select[${Me.Class.ShortName},WAR,PAL,SHD,MNK,BER]},1,0]}",
};

PCHAR pRAVOL[]={
    "ragevolley",
    "[#] Endu% Above? 0=0ff",
    "${If[${Me.CombatAbility[rage volley]} || ${Me.CombatAbility[destroyer's volley]} || ${Me.CombatAbility[giantslayer's volley]} || ${Me.CombatAbility[giantslayer's volley rk. ii]} || ${Me.CombatAbility[giantslayer's volley rk. iii]} || ${Me.CombatAbility[annihilator's volley]} || ${Me.CombatAbility[annihilator's volley rk. ii]} || ${Me.CombatAbility[annihilator's volley rk. iii]} || ${Me.CombatAbility[decimator's volley]} || ${Me.CombatAbility[decimator's volley rk. ii]} || ${Me.CombatAbility[decimator's volley rk. iii]} || ${Me.CombatAbility[Eradicator's Volley]} || ${Me.CombatAbility[Eradicator's Volley rk. ii]} || ${Me.CombatAbility[Eradicator's Volley rk. iii]},60,0]}",
    "${If[${meleemvi[plugin]} && (${Me.CombatAbility[rage volley]} || ${Me.CombatAbility[destroyer's volley]} || ${Me.CombatAbility[giantslayer's volley]} || ${Me.CombatAbility[giantslayer's volley rk. ii]} || ${Me.CombatAbility[giantslayer's volley rk. iii]} || ${Me.CombatAbility[annihilator's volley]} || ${Me.CombatAbility[annihilator's volley rk. ii]} || ${Me.CombatAbility[annihilator's volley rk. iii]} || ${Me.CombatAbility[decimator's volley]} || ${Me.CombatAbility[decimator's volley rk. ii]} || ${Me.CombatAbility[decimator's volley rk. iii]} || ${Me.CombatAbility[Eradicator's Volley]} || ${Me.CombatAbility[Eradicator's Volley rk. ii]} || ${Me.CombatAbility[Eradicator's Volley rk. iii]}),1,0]}",
};

PCHAR pRAKES[]={
    "rake",
    "[#] Endu% Above? 0=Off",
    "${If[${Me.CombatAbility[rake]} || ${Me.CombatAbility[harrow]} || ${Me.CombatAbility[harrow rk. ii]} ${Me.CombatAbility[harrow rk. iii]},60,0]}",
    "${If[${meleemvi[plugin]} && (${Me.CombatAbility[rake]} || ${Me.CombatAbility[harrow]} || ${Me.CombatAbility[harrow rk. ii]} ${Me.CombatAbility[harrow rk. iii]}),1,0]}",
};

PCHAR pRANGE[]={
    "range",
    "[#] Max Range? 0=0ff",
    "0",
    "${If[${meleemvi[plugin]},1,0]}",
};

PCHAR pRESUM[]={
    "resume",
    "[#] Life% Above? 100=0ff",
    "20",
    "${If[${meleemvi[plugin]} && !${meleemvi[aggro]},1,0]}",
};

PCHAR pRKICK[]={
    "roundkick",
    "[ON/OFF]?",
    "${If[${Me.Skill[round kick]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[round kick]},1,0]}",
};

PCHAR pSENSE[]={
    "sensetraps",
    "[ON/OFF]?",
    "0",
    "${If[${meleemvi[plugin]} && ${Me.Skill[sensetraps]},1,0]}",
};

PCHAR pSHIEL[]={
    "shield",
    "[ID] item?",
    "0",
    "${If[${meleemvi[plugin]} && ${Me.Skill[bash]},1,0]}",
};

PCHAR pSLAMS[]={
    "slam",
    "[ON/OFF]?",
    "${If[${Me.Skill[slam]}!=255,1,0]}",
    "${If[${meleemvi[plugin]} && ${Me.Skill[slam]}!=255,1,0]}",
};

PCHAR pSNEAK[]={
    "sneak",
    "[ON/OFF]?",
    "0",
    "${If[${meleemvi[plugin]} && ${Me.Skill[sneak]},1,0]}",
};

PCHAR pSTAND[]={
    "standup",
    "[ON/OFF] Authorize to StandUp?",
    "0",
    "${If[${meleemvi[plugin]},1,0]}",
};

PCHAR pSTIKKB[]={
    "stickbreak",
    "0=Normal, 1=Allow BreakOnKB",
    "0",
    "${If[${meleemvi[plugin]} && ${Stick.Status.NotEqual[NULL]},1,0]}",
};

PCHAR pSTIKNR[]={
    "sticknorange",
    "0=Normal, 1=No Range Check",
    "0",
    "${If[${meleemvi[plugin]} && ${Stick.Status.NotEqual[NULL]},1,0]}",
};

PCHAR pSTIKR[]={
    "stickrange",
    "[#] Target in Range? 0=0ff",
    "${If[${Stick.Status.NotEqual[NULL]},75,0]}",
    "${If[${meleemvi[plugin]} && ${Stick.Status.NotEqual[NULL]} && ${meleemvi[stickrange]},1,0]}",
};

PCHAR pSTIKD[]={
    "stickdelay",
    "[#] Sec to Wait Target in Range?",
    "0",
    "${If[${meleemvi[plugin]} && ${Stick.Status.NotEqual[NULL]},1,0]}",
};

PCHAR pSTIKM[]={
    "stickmode",
    "[ON/OFF] Use stickcmd from ini?",
    "0",
    "${If[${meleemvi[plugin]} && ${Stick.Status.NotEqual[NULL]},1,0]}",
};

PCHAR pSTRIK[]={
    "strike",
    "Use best sneak attack disc [ON/OFF]?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${meleemvi[backstab]} && ${meleemvi[idstrike]},1,0]}",
};

PCHAR pSTRIKM[]={
    "strikemode",
    "[ON/OFF] Use strikecmd from ini?",
    "0",
    "${If[${meleemvi[plugin]} && ${Stick.Status.NotEqual[NULL]},1,0]}",
};

PCHAR pSTUNS[]={
    "stunning",
    "[#] Target Life% Below? 0=0ff",
    "0",
    "${If[${meleemvi[plugin]},1,0]}",
};

PCHAR pSTUN0[]={
    "stun0",
    "[ID] spell/disc/aa/item?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[stunning]},1,0]}",
};

PCHAR pSTUN1[]={
    "stun1",
    "[ID] spell/disc/aa/item?",
    "0",
    "${If[${meleemvi[plugin]} && ${meleemvi[stunning]},1,0]}",
};

PCHAR pTAUNT[]={
    "taunt",
    "[ON/OFF]?",
    "${If[${Me.Skill[taunt]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${meleemvi[aggro]} && ${Me.Skill[taunt]},1,0]}",
};

PCHAR pTHIEF[]={
    "thiefeye",
    "[ON/OFF]?",
    "${If[${Me.CombatAbility[thief's eye]},60,0]}",
    "${If[${meleemvi[plugin]} && ${Me.CombatAbility[thief's eye]},1,0]}",
};

PCHAR pTHROW[]={
    "throwstone",
    "[#] Endu% Above? 0=0ff",
    "0",
    "${If[${meleemvi[plugin]} && ${Me.CombatAbility[throw stone]},1,0]}",
};

PCHAR pTIGER[]={
    "tigerclaw",
    "[ON/OFF]?",
    "${If[${Me.Skill[tiger claw]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.Skill[tiger claw]},1,0]}",
};

PCHAR pTWIST[]={
    "twistedshank",
    "[ON/OFF]?",
    "${If[${Me.AltAbility[twisted shank]},1,0]}",
    "${If[${meleemvi[plugin]} && ${meleemvi[melee]} && ${Me.AltAbility[twisted shank]},1,0]}",
};

PCHAR UI_PetBack = "back";
PCHAR UI_PetAttk = "attack";

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

DWORD         AACheck(DWORD id);
DWORD         AAPoint(DWORD index);
BOOL          AAReady(DWORD index);
LONG          Aggroed(DWORD id);
FLOAT         AngularDistance(float h1, float h2);
DOUBLE        AngularHeading(PSPAWNINFO t, PSPAWNINFO s);
BOOL          CACheck(DWORD id);
BOOL          CAPress(DWORD id);
BOOL          Casting(PCHAR command);
BOOL          CursorEmpty();
LONG          Discipline();
BOOL          Equip(DWORD ID, long SlotID);
BOOL          Equipped(DWORD id);
LONG          Evaluate(PCHAR zFormat, ...);
LONG          ItemCounts(DWORD ID, long B=0, long E=NUM_INV_SLOTS);
PCONTENTS     ItemLocate(DWORD ID, long B=0, long E=NUM_INV_SLOTS, long SlotID=NOID);
LONG          OkayToEquip(long Size=NOID);
LONG          PackFind(long Size);
PMQPLUGIN     Plugin(PCHAR PluginName);
VOID*         PluginEntry(PCHAR PluginName, PCHAR FuncName);
BOOL          SKCheck(DWORD id);
BOOL          SKReady(DWORD id);
BOOL          SKPress(DWORD id);
PCONTENTS     SlotContent(long SlotID);
LONG          SpawnMask(PSPAWNINFO x);
BOOL          SpellCheck(DWORD id);
LONG          SpellGemID(DWORD ID, LONG slotid=NOID);
BOOL          SpellReady(DWORD ID, LONG SlotID=NOID);
BOOL          Stick(PCHAR command);
LONG          Unequip(long SlotID);
VOID          WinClick(CXWnd *Wnd, PCHAR ScreenID, PCHAR ClickNotification, DWORD KeyState);
PSTR          WinTexte(CXWnd *Wnd, PCHAR ScreenID, PSTR Buffer);

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

VOID Announce(DWORD Wanted, PCHAR Format, ...) {
    char Output[MAX_STRING]={0}; va_list vaList; va_start(vaList,Format); vsprintf(Output,Format,vaList);
    if(Output[0]) {
        DWORD Result=0; PMQPLUGIN pPlugin=pPlugins;
        while(pPlugin) {
            fMQIncomingChat Request=(fMQIncomingChat)GetProcAddress(pPlugin->hModule,"OnMeleeChat");
            if(Request) Result|=Request(Output,Wanted);
            pPlugin=pPlugin->pNext;
        }
        if(!Result && Wanted) WriteChatf(Output);
    }
}

#define GetSpawnID(spawnid) (PSPAWNINFO)GetSpawnByID(spawnid)
#define TargetIT(X) *(PSPAWNINFO*)ppTarget=X

static inline BOOL WinState(CXWnd *Wnd) {
    return (Wnd && ((PCSIDLWND)Wnd)->Show);
}

static inline BOOL TypePack(PCONTENTS Item) {
    return(Item && Item->Item->Type==ITEMTYPE_PACK);
}

static inline PSPAWNINFO Target() {
    if(ppTarget) return (PSPAWNINFO)pTarget;
    return NULL;
}

static inline BOOL TargetType(DWORD mask) {
    return (SpawnMask(Target())&mask);
}

static inline BOOL TargetID(DWORD ID) {
    if(ID && pTarget) return (ID==Target()->SpawnID);
    return false;
}

static inline float SpeedRun(PSPAWNINFO x) {
    if(x && x->Mount) return x->Mount->SpeedRun;
    if(x) return x->SpeedRun;
    return 0.0f;
}

static inline BOOL SpawnType(PSPAWNINFO x, DWORD mask) {
    return (SpawnMask(x)&mask);
}

static inline PSPAWNINFO SpawnMe() {
    return GetCharInfo()->pSpawn;
}

static inline PSPAWNINFO SpawnMount() {
    return SpawnMe()?SpawnMe()->Mount:NULL;
}

static inline PSPAWNINFO SpawnPet() {
    return (SpawnMe() && (LONG)SpawnMe()->PetID>0)?(PSPAWNINFO)GetSpawnByID(SpawnMe()->PetID):NULL;
}

static inline DWORD StandState() {
    return SpawnMe()?SpawnMe()->StandState:0;
}

static inline BOOL Stackable(PCONTENTS Item) {
    return (Item && Item->Item->Type==ITEMTYPE_NORMAL && ((EQ_Item*)Item)->IsStackable());
}

static inline LONG StackUnit(PCONTENTS Item) {
    return (!Stackable(Item))?1:Item->StackCount;
}

static inline BOOL IsStunned() {
    return (GetCharInfo() && GetCharInfo()->Stunned);
}

static inline BOOL IsStanding() {
    if(SpawnMount()) return true;
    return StandState()==STANDSTATE_STAND;
}

static inline BOOL IsSneaking() {
    return (SpawnMe() && SpawnMe()->Sneak);
}

static inline BOOL IsInvisible() {
    return (SpawnMe() && SpawnMe()->HideMode);
}

static inline BOOL IsGrouped() {
    return (GetCharInfo() && GetCharInfo()->pGroupInfo);
}

static inline BOOL IsFeigning() {
    return StandState()==STANDSTATE_FEIGN;
}

static inline BOOL IsCasting() {
    return (SpawnMe() && SpawnMe()->CastingData.SpellID != -1);
}

static inline BOOL InRange(PSPAWNINFO a, PSPAWNINFO b, float d) {
    if(!a || !b) return false;
    return (DistanceToSpawn(a,b)<=d);
}

static inline BOOL InGame() {
    return (gbInZone && gGameState==GAMESTATE_INGAME && SpawnMe() && GetCharInfo2() && GetCharInfo() && GetCharInfo()->Stunned!=3);
}

static inline CXWnd* XMLChild(CXWnd* window, PCHAR screenid) {
    if(window) return window->GetChildItem(screenid);
    return NULL;
}

static inline BOOL XMLEnabled(CXWnd* window) {
    return (window && ((PCSIDLWND)window)->Enabled);
}

static inline PCONTENTS ContAmmo() {
    if(PCHARINFO2 Me=GetCharInfo2()) return Me->Inventory.Ammo;
    return NULL;
}

static inline PCONTENTS ContPrimary() {
    if(PCHARINFO2 Me=GetCharInfo2()) return Me->Inventory.Primary;
    return NULL;
}

static inline PCONTENTS ContRange() {
    if(PCHARINFO2 Me=GetCharInfo2()) return Me->Inventory.Range;
    return NULL;
}

static inline PCONTENTS ContSecondary() {
    if(PCHARINFO2 Me=GetCharInfo2()) return Me->Inventory.Secondary;
    return NULL;
}

static inline BOOL PokerType(PCONTENTS item) {
    return (item && item->Item->ItemType==2);
}

static inline BOOL ShieldType(PCONTENTS item) {
    return(item && item->Item->ItemType==8);
}

static inline BOOL TwohandType(PCONTENTS item) {
    if(item) {
        if(item->Item->ItemType==1)   return true;
        if(item->Item->ItemType==4)   return true;
        if(item->Item->ItemType==35)  return true;
    }
    return false;
}

DWORD AACheck(DWORD id) {
    if(pAltAdvManager)
        if(PCHARINFO2 Me=GetCharInfo2())
            if(_AALIST* AAList=Me->AAList)
                if(id)
                    for(DWORD nAbility=0; nAbility<AA_CHAR_MAX_REAL; nAbility++)
                        if(LONG AAIndex=AAList[nAbility].AAIndex)
                            if(PALTABILITY ability=pAltAdvManager->GetAltAbility(AAIndex))
                                if(ability->ID==id) return AAIndex;
    return false;
}

DWORD AAPoint(DWORD index) {
    if(PCHARINFO2 Me=GetCharInfo2())
        if(_AALIST* AAList=Me->AAList)
            if(index)
                for(DWORD nAbility=0; nAbility<AA_CHAR_MAX_REAL; nAbility++)
                    if(index==AAList[nAbility].AAIndex)
                        return  AAList[nAbility].PointsSpent;
    return 0;
}

BOOL AAReady(DWORD index) {
    int result = 0;
    if (pAltAdvManager)
    {
        if (index)
            if (PALTABILITY ability = pAltAdvManager->GetAltAbility(index))
            {
                //unsigned long i = 0;
                //i = pAltAdvManager->GetCalculatedTimer(pPCData, ability);
                //DebugSpew("ability timer: %d", i);
                if (pAltAdvManager->GetCalculatedTimer(pPCData, ability) > 0)
                {
                    pAltAdvManager->IsAbilityReady(pPCData,ability,&result);
                    //DebugSpew("result: %d", result);
                }
            }
    }
    return (result < 0);
}

LONG Aggroed(DWORD id) {
    if(PSPAWNINFO self=SpawnMe())
        if(PSPAWNINFO kill=GetSpawnID(id))
            if(PSPAWNINFO targ=Target()) {
                if(targ==kill && self->SpawnID==self->TargetOfTarget)  return  1; // im on hott
                if(fabs(AngularHeading(kill,self))<8.0f)       return  1; // it's facing me
                if(FindSpeed(kill)>0.0f && kill->HPCurrent<20) return -1; // it's moving
                if(InRange(self,targ,25.0f))                   return -1; // close enough
            }
            return 0;
}

FLOAT AngularDistance(float h1, float h2) {
    if(h1 == h2) return 0.0;
    if(fabs(h1 - h2) > 256.0) * (h1 < h2?&h1:&h2) += 512.0;
    return (fabs(h1 - h2) > 256.0)?(h2 - h1):(h1 - h2);
}

DOUBLE AngularHeading(PSPAWNINFO t, PSPAWNINFO s) {
    double Head=t->Heading-(float)atan2(s->X - t->X, s->Y - t->Y) * 256.0 / PI;
    if(Head > 256.0f) Head -= 512.0f; else if(Head < -256.0f) Head += 512.0f;
    return Head;
}

BOOL CACheck(DWORD id) {
    if(PCHARINFO2 Me=GetCharInfo2())
        if(DWORD* CombatAbilities=Me->CombatAbilities)
            if(id)
                for(DWORD nCombat=0; nCombat<NUM_COMBAT_ABILITIES; nCombat++)
                    if(id==CombatAbilities[nCombat]) return true;
    return false;
}

BOOL CAPress(DWORD id) {
    pCharData->DoCombatAbility(id);
    return true;
}

BOOL Casting(PCHAR command) {
    typedef void (__cdecl *fCALL)(PSPAWNINFO,PCHAR);
    if(fCALL request=(fCALL)PluginEntry("mq2cast","CastCommand")) {
        Announce(SHOW_CASTING,"%s::Casting [\ay%s\ax].",PLUGIN_NAME,command);
        request(NULL,command);
        return true;
    }
    return false;
}

VOID Command(PCHAR zFormat,...) {
    CHAR zOutput[MAX_STRING]={0}; va_list vaList; va_start(vaList,zFormat);
    vsprintf(zOutput,zFormat,vaList);
    if(zOutput[0]) EzCommand(zOutput);
}

BOOL CursorEmpty() {
    if(PCHARINFO2 Me=GetCharInfo2())
        if(!Me->Cursor)
            if(!Me->CursorPlat)
                if(!Me->CursorGold)
                    if(!Me->CursorSilver)
                        if(!Me->CursorCopper)
                            return true;
    return false;
}

LONG Discipline() {
    char temps[MAX_STRING];
    PSPELL spell=GetSpellByName(WinTexte((CXWnd*)pCombatAbilityWnd,"CAW_CombatEffectLabel",temps));
    return (spell)?spell->ID:0;
}

BOOL Equip(DWORD ID, long SlotID) {
    if(!(SlotID < NUM_INV_SLOTS)) return false;                   // invalid destination slot id for equipping item to
    if(!OkayToEquip())      return false;                         // can't equip item right casting or cursor not free
    PCONTENTS fITEM=ItemLocate(ID,BAG_SLOT_START,NUM_INV_SLOTS);  // assume that equipping item is in a backpack first
    if(!fITEM) fITEM=ItemLocate(ID,0,BAG_SLOT_START);             // was'nt found check if already equipped somewhere
    if(!fITEM)              return false;                         // was'nt found can't equip something we dont have
    if(InvSlot != SlotID) {
        // check class, level, deity and race to see if we have rights to equip this items.
        if(!(fITEM->Item->Classes&(1<<((GetCharInfo2()->Class)-1))))                      return false;
        if(fITEM->Item->RequiredLevel > GetCharInfo2()->Level)                            return false;
        if(fITEM->Item->Diety && !(fITEM->Item->Diety&(1<<(GetCharInfo2()->Deity-200))))  return false;
        long MyRace=(DWORD)GetCharInfo2()->Race;
        switch((DWORD)MyRace) {
      case 128: MyRace=12;    break;
      case 130: MyRace=13;    break;
      case 330: MyRace=14;    break;
      case 522: MyRace=15;    break;
      default:  MyRace--;
        }
        if(!(fITEM->Item->Races&(1<<MyRace))) return false;
        if(SlotID==inv_primary && TwohandType(fITEM) && ContSecondary()) if(!Unequip(inv_secondary)) return false;
        if(SlotID==inv_secondary && TwohandType(ContPrimary()))           if(!Unequip(inv_primary))   return false;
        long dSLOT=0;
        if(PCONTENTS dCONT=GetCharInfo2()->InventoryArray[SlotID]) {
            if(InvSlot<NUM_INV_SLOTS) dSLOT=InvSlot;
            else {
                PCONTENTS fPACK=GetCharInfo2()->InventoryArray[(InvSlot-262)/10+BAG_SLOT_START];
                if(fPACK && fPACK->Item->SizeCapacity >= dCONT->Item->Size) dSLOT=InvSlot;
                else dSLOT=PackFind(dCONT->Item->Size);
            }
            if(!dSLOT) return false;
        }
        char buffer[16];
        sprintf(buffer,"InvSlot%d",SlotID);
        pInvSlotMgr->MoveItem(InvSlot,NUM_INV_SLOTS,1,1);
        WinClick((CXWnd*)pInventoryWnd,buffer,"leftmouseup",Nokey);
        if(dSLOT) pInvSlotMgr->MoveItem(NUM_INV_SLOTS,dSLOT,1,1);
    }
    return true;
}

BOOL Equipped(DWORD id) {
    if(id)
        for(int i=0; i<BAG_SLOT_START; i++)
            if(PCONTENTS Cont=GetCharInfo2()->InventoryArray[i])
                if(id==Cont->Item->ItemNumber) return true;
    return false;
}

LONG Evaluate(PCHAR zFormat, ...) {
    char zOutput[MAX_STRING]={0}; va_list vaList; va_start(vaList,zFormat);
    vsprintf(zOutput,zFormat,vaList); if(!zOutput[0]) return 1;
    //DebugSpewAlways("E[%s]",zOutput);
    ParseMacroData(zOutput);
    //DebugSpewAlways("R[%s]",zOutput);
    return atoi(zOutput);
}

LONG ItemCounts(DWORD ID, long B, long E) {
    long Count=0; InvSlot=NOID; InvCont=NULL;
    for(int iSlot=B; iSlot<E; iSlot++) {
        if(PCONTENTS cSlot=GetCharInfo2()->InventoryArray[iSlot]) {
            if(ID==cSlot->Item->ItemNumber) {
                Count+=StackUnit(cSlot);
                if(!InvCont) {
                    InvCont=cSlot;
                    InvSlot=iSlot;
                }
            } else if(TypePack(cSlot)) {
                for(int iPack=0; iPack<cSlot->Item->Slots; iPack++) {
                    if(PCONTENTS cPack=cSlot->Contents[iPack]) {
                        if(ID==cPack->Item->ItemNumber) {
                            Count+=StackUnit(cPack);
                            if(!InvCont) {
                                InvCont=cPack;
                                InvSlot=262+iPack+(iSlot-BAG_SLOT_START)*10;
                            }
                        }
                    }
                }
            }
        }
    }
    return Count;
}

PCONTENTS ItemLocate(DWORD ID, long B, long E, long SlotID) {
    if(SlotID!=NOID)
        if(PCONTENTS find=SlotContent(SlotID))
            if(find->Item->ItemNumber==ID) {
                InvSlot=SlotID;
                return find;
            }
            for(int iSlot=B; iSlot<E; iSlot++)
                if(PCONTENTS cSlot=GetCharInfo2()->InventoryArray[iSlot]) {
                    if(ID==cSlot->Item->ItemNumber) {
                        InvSlot=iSlot;
                        return cSlot;
                    }
                    if(TypePack(cSlot)) {
                        for(int iPack=0; iPack<cSlot->Item->Slots; iPack++)
                            if(PCONTENTS cPack=cSlot->Contents[iPack])
                                if(ID==cPack->Item->ItemNumber) {
                                    InvSlot=(iSlot-BAG_SLOT_START)*10+iPack+262;
                                    return cPack;
                                }
                    }
                }
                InvSlot=NOID;
                return NULL;
}

LONG ItemTimer(PCONTENTS pItem) {
    if(pItem->Item->Clicky.TimerID!=0xFFFFFFFF) return GetItemTimer(pItem);
    if(pItem->Item->Clicky.SpellID!=0xFFFFFFFF) return 0;
    return 999999;
}

LONG OkayToEquip(long Size) {
    if(!CursorEmpty() || IsCasting()) return false;
    if(Size!=NOID) return PackFind(Size);
    return true;
}

LONG PackFind(long Size) {
    long pSIZE=10;
    long pSLOT=0;
    for(int iSlot=BAG_SLOT_START; iSlot < NUM_INV_SLOTS; iSlot++) {
        if(PCONTENTS cSlot=GetCharInfo2()->InventoryArray[iSlot]) {
            if(TypePack(cSlot) && cSlot->Item->Combine != 2 &&
                Size <= cSlot->Item->SizeCapacity && (!pSLOT || cSlot->Item->SizeCapacity < pSIZE)) {
                    for(int iPack=0; iPack < cSlot->Item->Slots; iPack++) {
                        if(!cSlot->Contents[iPack]) {
                            pSLOT=(iSlot-BAG_SLOT_START)*10+iPack+262;
                            pSIZE=cSlot->Item->SizeCapacity;
                            break;
                        }
                    }
            }
        } else if(!pSLOT) pSLOT=iSlot;
    }
    return pSLOT;
}

PMQPLUGIN Plugin(PCHAR PluginName) {
    long Length=strlen(PluginName)+1;
    PMQPLUGIN pLook=pPlugins;
    while(pLook && strnicmp(PluginName,pLook->szFilename,Length)) pLook=pLook->pNext;
    return pLook;
}

VOID* PluginEntry(PCHAR PluginName, PCHAR FuncName) {
    if(PMQPLUGIN pLook=Plugin(PluginName))
        if(void* entry=GetProcAddress(pLook->hModule,FuncName))
            return entry;
    return NULL;
}

BOOL SKCheck(DWORD id) {
    if(id<100 && (pSkillMgr->pSkill[id]->Activated && GetCharInfo2()->Skill[id]))     return true;
    if(id>100 && id<128 && GetCharInfo2()->Skill[id]!=0xFF && strlen(szSkills[id])>3) return true;
    return false;
}

BOOL SKReady(DWORD id) {
    if(id<100)
    {
        // 15 = disarm, 25=fd
        //DebugSpew("id %d alttimer: %d", id, pSkillMgr->pSkill[id]->AltTimer);
        if(pSkillMgr->pSkill[id]->AltTimer == 2)
        {
            //DebugSpew("gbAltTimerReady: %s", gbAltTimerReady ? "true" : "false");
            return gbAltTimerReady ? true : false;
        }
        //DebugSpew("id %d - EQADDR_DOABILITYAVAIL: %s", id, EQADDR_DOABILITYAVAILABLE[id] ? "true" : "false");
        return EQADDR_DOABILITYAVAILABLE[id] ? true : false;
    }
    if(id==111) return gbAltTimerReady?true:false;
    if(id==105 || id==107) return LoH_HT_Ready();
    return false;
}

BOOL SKPress(DWORD id) {
    pCharData1->UseSkill((unsigned char)id,(EQPlayer*)pCharData1);
    return true;
}

PCONTENTS SlotContent(long SlotID) {
    if(SlotID>0) {
        long InvSlot=NOID;
        long SubSlot=NOID;
        if(!(SlotID < NUM_INV_SLOTS)) {
            InvSlot=BAG_SLOT_START+(SlotID-262)/10;
            SubSlot=(SlotID-1)%10;
        }
        else InvSlot=SlotID;
        if(InvSlot<NUM_INV_SLOTS) {
            if(PCONTENTS cSlot=GetCharInfo2()->InventoryArray[InvSlot]) {
                if(SubSlot<0) return cSlot;
                if(PCONTENTS cPack=cSlot->Contents[SubSlot]) return cPack;
            }
        }
    }
    return NULL;
}

LONG SpawnMask(PSPAWNINFO x) {
    if(!x)                        return st_x;
    if(x->Type==SPAWN_PLAYER)     return st_p;
    if(x->Type==SPAWN_CORPSE)     return x->Deity?st_cp:st_cn;
    if(x->Type!=SPAWN_NPC)        return st_x;
    if(strstr(x->Name,"s_Mount")) return st_x;
    if(!x->MasterID)              return st_n;
    PSPAWNINFO m=GetSpawnID(x->MasterID);
    return (!m || m->Type!=SPAWN_PLAYER)?st_wn:st_wp;
}

BOOL SpellCheck(DWORD ID) {
    if(ID)
        if(PCHARINFO2 Me=GetCharInfo2())
            for(DWORD nSlot=0; nSlot<NUM_BOOK_SLOTS; nSlot++)
                if(ID==Me->SpellBook[nSlot])
                    return true;
    return false;
}

LONG SpellGemID(DWORD ID, LONG SlotID) {
    if(PCHARINFO2 Me=GetCharInfo2()) {
        if(SlotID!=NOID && ID==Me->MemorizedSpells[SlotID]) return SlotID;
        for(LONG GEM=0; GEM<GemsMax; GEM++)
            if(ID==Me->MemorizedSpells[GEM])
                return GEM;
    }
    return NOID;
}

BOOL SpellReady(DWORD ID, LONG SlotID) {
    if(pCastSpellWnd)
        if(PCHARINFO2 Me=GetCharInfo2()) {
            DWORD GemID=(SlotID!=NOID)?SlotID:SpellGemID(ID);
            if(GemID<(DWORD)GemsMax)
                if(Me->MemorizedSpells[GemID]==ID)
                    if((LONG)((PEQCASTSPELLWINDOW)pCastSpellWnd)->SpellSlots[GemID]->spellicon!=NOID)
                        if(BardClass || (LONG)((PEQCASTSPELLWINDOW)pCastSpellWnd)->SpellSlots[GemID]->spellstate!=1)
                            return true;
        }
        return false;
}

bool HandleMoveUtils(void)
{
    bMUPointers = false;
    fStickCommand = NULL;
    pbStickOn = NULL;
    if (PMQPLUGIN pLook=Plugin("mq2moveutils"))
    {
        fStickCommand = (void (*)(PSPAWNINFO pChar, PCHAR szLine))GetProcAddress(pLook->hModule, "StickCommand");
        pbStickOn = (bool *)GetProcAddress(pLook->hModule, "bStickOn");
    }
    if (fStickCommand && pbStickOn) 
    {
        bMUPointers = true;
        return true;
    }
    return false;
}

unsigned char PetButtonEnabled(char* pszButtonName)
{
    int i = 0;
    for (i = 0; i < PET_BUTTONS; i++)
    {
        if (((PEQPETINFOWINDOW)pPetInfoWnd)->pButton[i])
        {
            if (((PEQPETINFOWINDOW)pPetInfoWnd)->pButton[i]->Wnd.WindowText->Text[0])
            {
                if (!stricmp(((PEQPETINFOWINDOW)pPetInfoWnd)->pButton[i]->Wnd.WindowText->Text, pszButtonName))
                {
                    return ((PEQPETINFOWINDOW)pPetInfoWnd)->pButton[i]->Wnd.Enabled;
                }
            }
        }
    }
    return 0;
}

BOOL Stick(PCHAR command)
{
    char szPasser[MAX_STRING] = {0};
    //typedef void (__cdecl *fCALL)(PSPAWNINFO, PCHAR);
    //if (fCALL request = (fCALL)PluginEntry("mq2moveutils", "StickCommand"))
    if (bMULoaded && bMUPointers)
    {
        if (command[0])
        {
            Announce(SHOW_STICKING, "%s::Sticking [\ay%s\ax].", PLUGIN_NAME, command);
            fStickCommand(SpawnMe(), command);
            sprintf(szPasser, "/stick %s", command);
            //DebugSpew("MQ2Melee Stick call: %s", command);
        }
        else if (*pbStickOn)
        {
            fStickCommand(SpawnMe(), "off");
            sprintf(szPasser, "/stick off");
            //DebugSpew("MQ2Melee Stick call: off");
        }
        Sticking = *pbStickOn;
        //Sticking = (command[0]) ? true : false;
        strcpy(StickArg, *pbStickOn ? command : "OFF");
        return true;
    }
    return false;
}

DWORD TimeSince(DWORD Timer) {
    if(Timer) return (DWORD)clock()-Timer;
    return 0;
}

LONG Unequip(long SlotID) {
    if(SlotID<NUM_INV_SLOTS) {
        PCONTENTS uCONT=GetCharInfo2()->InventoryArray[SlotID];
        if(!uCONT) return true;
        if(long uDEST=OkayToEquip(uCONT->Item->Size)) {
            pInvSlotMgr->MoveItem(SlotID,NUM_INV_SLOTS,1,1);
            pInvSlotMgr->MoveItem(NUM_INV_SLOTS,uDEST,1,1);
            return true;
        }
    }
    return false;
}

VOID WinClick(CXWnd *Wnd, PCHAR ScreenID, PCHAR ClickNotification, DWORD KeyState) {
    if(Wnd) if(CXWnd *Child=Wnd->GetChildItem(ScreenID)) {
        BOOL KeyboardFlags[4];
        *(DWORD*)&KeyboardFlags=*(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags;
        *(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags=KeyState;
        SendWndClick2(Child,ClickNotification);
        *(DWORD*)&((PCXWNDMGR)pWndMgr)->KeyboardFlags=*(DWORD*)&KeyboardFlags;
    }
}

PSTR WinTexte(CXWnd *Wnd, PCHAR ScreenID, PSTR Buffer) {
    Buffer[0]=0;
    if(Wnd)
        if(CXWnd *Child=(CXWnd*)Wnd->GetChildItem(ScreenID))
            GetCXStr(Child->WindowText,Buffer,2047);
    return Buffer;
}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

class Ability {
    CHAR   COMM[16];    // Ability Cast Command
    DWORD  REUSE;       // Ability Reuse Time
    DWORD  READY;       // Ability Ready
    LONG   INDEX;       // Ability Index
    PSPELL EFFECT;      // Ability Spell Effect
    enum { UNKNOWN, ITEM, SKILL, DISC, AA, SPELL, CLICKY, POTION };

public:
    LONG   ID;          // Ability ID
    LONG   TYPE;        // Ability Type
    CHAR   NAME[128];   // Ability Name
    BOOL   SEARCH;      // Ability Searched

    BOOL Avail() {
        SEARCH=1;
        EFFECT=0;
        if(ID>NOID) {
            if(TYPE==SKILL || TYPE==UNKNOWN) {
                if(SKCheck(ID)) {
                    strcpy(NAME,szSkills[ID]);
                    REUSE=(ID==i_forage)?101750:delay*3;
                    TYPE=SKILL;
                    return true;
                }
            }
            if(TYPE==DISC || TYPE==UNKNOWN) {
                if(CACheck(ID)) {
                    if(PSPELL spell=GetSpellByID(ID)) {
                        strcpy(NAME,spell->Name);
                        EFFECT=spell;
                        REUSE=spell->CastTime+spell->RecastTime+delay*6;
                        TYPE=DISC;
                        return true;
                    }
                }
            }
            if(TYPE==AA || TYPE==UNKNOWN) {
                if(long AAIndex=AACheck(ID)) {
                    if(PALTABILITY ability=pAltAdvManager->GetAltAbility(AAIndex)) {
                        if(PSPELL spell=GetSpellByID(ability->SpellID)) {
                            strcpy(NAME,pCDBStr->GetString(ability->nName,1,NULL));
                            sprintf(COMM,"%d|ALT",ID);
                            EFFECT=spell;
                            REUSE=pAltAdvManager->GetCalculatedTimer(pPCData,ability)*1000+spell->CastTime+delay*3;
                            INDEX=AAIndex;
                            TYPE=AA;
                            return true;
                        }
                    }
                }
            }
            if(TYPE==SPELL || TYPE==UNKNOWN) {
                if(SpellCheck(ID)) {
                    if(PSPELL spell=GetSpellByID(ID)) {
                        strcpy(NAME,spell->Name);
                        sprintf(COMM,"%d|GEM5",ID);
                        EFFECT=spell;
                        REUSE=spell->CastTime+spell->RecastTime+delay*3;
                        TYPE=SPELL;
                        return true;
                    }
                }
            }
            if(TYPE==POTION || TYPE==CLICKY || TYPE==ITEM || TYPE==UNKNOWN) {
                if(PCONTENTS find=ItemLocate(ID)) {
                    INDEX=InvSlot;
                    strcpy(NAME,find->Item->Name);
                    TYPE=ITEM;
                    if(PSPELL spell=GetSpellByID(find->Item->Clicky.SpellID)) {
                        sprintf(COMM,"%d|ITEM",ID);
                        EFFECT=spell;
                        REUSE=find->Item->Clicky.TimerID*1000+find->Item->CastTime+delay*3;
                        TYPE=(find->Item->ItemType==21)?POTION:CLICKY;
                    }
                    return true;
                }
            }
        }
        return false;
    }

    BOOL Found() {
        if(!SEARCH) Avail();
        return (ID>0 && TYPE != UNKNOWN) ? true : false;
    }

    LONG Check(string test) {
        if(!Found())                return 0x01;  // Ability Not Found
        if((DWORD)clock() <= READY) return 0x02;  // Ability Not Refreshed
        if(TYPE==SKILL)
        {
            if(SpawnMount())
            {
                switch(ID)
                {
                    case i_disarm:        break;
                    case i_harmtouch:     break;
                    case i_intimidation:  break;
                    case i_kick:          break;
                    case i_mend:          break;
                    case i_taunt:         break;
                    default:              return 0x03;  // Ability Do Not Work on Mount
                }
            }
            if(!SKReady(ID))        return 0x13;  // Ability Not Ready
        }
        else if(EFFECT)
        {
            if(!IsStanding())       return 0x05;  // Not Standing
            if(IsStunned())         return 0x06;  // Stunned
            if(TYPE > DISC)
            {
                if(IsInvisible())     return 0x04;  // Will Break Invisiblity
                if(Silenced)          return 0x07;  // Silenced
            }
            if(IsCasting())         return 0x08;  // already casting
            if(WinState((CXWnd*)pSpellBookWnd)) return 0x09;  // spellbook open
            if (EFFECT->CARecastTimerID && TYPE != AA && EFFECT->CARecastTimerID != -1)
            {
                //DebugSpew("EFFECT->CARecastTimerID Name: %s  ID: %d Type: %dVal: %d", NAME, ID, TYPE, EFFECT->CARecastTimerID);
                if(((unsigned long)pPCData->GetCombatAbilityTimer(EFFECT->CARecastTimerID) - (unsigned long)time(NULL)) < 0) return 0x16; // dicipline timer not ready
            }
            if((long)EFFECT->ReagentId[0]>0 && ItemCounts(EFFECT->ReagentId[0]) < (long)EFFECT->ReagentCount[0])        return 0x0A;  // out of reagent
            if(EFFECT->EnduranceCost && GetCharInfo2()->Endurance < EFFECT->EnduranceCost)                              return 0x0B;  // out of endurance
            if(EFFECT->Mana && GetCharInfo2()->Mana < EFFECT->Mana)                                                     return 0x0C;  // out of mana
            if(!EFFECT->SpellType)
            {
                if(!pTarget)                                                                                              return 0x0D;  // no target
                float SpellRange=(EFFECT->Range)?EFFECT->Range:EFFECT->AERange;
                if(SpellRange && !InRange(SpawnMe(),(PSPAWNINFO)pTarget,SpellRange))                                      return 0x0E;  // out of range
            }
            else if(EFFECT->DurationValue1>0)
            {
                if(EFFECT->DurationWindow)
                {
                    for(int s=0; s<SongMax; s++)
                    {
                        if(PSPELL buff=GetSpellByID(GetCharInfo2()->ShortBuff[s].SpellID))
                        {
                            if(EFFECT->ID==buff->ID)        return 0x0F; // already have
                            if(!BuffStackTest(EFFECT,buff)) return 0x10; // not stacking
                        }
                    }
                }
                else
                {
                    for(int b=0; b<BuffMax; b++)
                    {
                        if(PSPELL buff=GetSpellByID(GetCharInfo2()->Buff[b].SpellID))
                        {
                            if(EFFECT->ID==buff->ID)        return 0x0F; // already have
                            if(!BuffStackTest(EFFECT,buff)) return 0x10; // not stacking
                        }
                    }
                }
            }
            if(TYPE>DISC && !Evaluate("${If[${Cast.Ready[%s]},1,0]}",COMM)) return 0x11; // mq2cast not ready
            if(TYPE==AA) {
                if(!AAReady(INDEX))       return 0x13;  // Ability Not Ready
            } else if(TYPE==SPELL) {
                if(!pCastSpellWnd)        return 0x12;  // No Casting Spell Bar
                INDEX=SpellGemID(ID,INDEX);
                if(!SpellReady(ID,INDEX)) return 0x13;  // Ability Not Ready
            } else if(TYPE==POTION || TYPE==CLICKY) {
                PCONTENTS find=ItemLocate(ID,0,NUM_INV_SLOTS,INDEX);
                INDEX=InvSlot;
                if(!find || !find->Charges || ItemTimer(find)) return 0x13;  // Ability Not Ready
                if(!CursorEmpty())        return 0x14;  // Cursor Not Empty
            }
        }
        if(!test.empty() && !Evaluate((PCHAR)test.c_str())) return 0x15; // User Condition Abort
        return 0x00;
    }

    BOOL Ready(string test) {
        LONG Result=Check(test);
        if(DebugReady && Result) {
            PCHAR Message="";
            switch(Result) {
        case 0x01:  Message="NOT FOUND";                break;
        case 0x02:  Message="NOT REFRESHED";            break;
        case 0x03:  Message="NOT WORKING ON MOUNT";     break;
        case 0x04:  Message="WILL BREAK INVISIBILITY";  break;
        case 0x05:  Message="NOT STANDING";             break;
        case 0x06:  Message="STUNNED";                  break;
        case 0x07:  Message="SILENCED";                 break;
        case 0x08:  Message="ALREADY CASTING";          break;
        case 0x09:  Message="SPELLBOOK OPEN";           break;
        case 0x0A:  Message="OUT OF REAGENT";           break;
        case 0x0B:  Message="OUT OF ENDURANCE";         break;
        case 0x0C:  Message="OUT OF MANA";              break;
        case 0x0D:  Message="NO TARGET";                break;
        case 0x0E:  Message="OUT OF RANGE";             break;
        case 0x0F:  Message="ALREADY BUFFED WITH THIS"; break;
        case 0x10:  Message="BUFF NOT STACKING";        break;
        case 0x11:  Message="MQ2CAST NOT READY/FOUND";  break;
        case 0x12:  Message="NO SPELL BAR";             break;
        case 0x13:  Message="ABILITY NOT READY";        break;
        case 0x14:  Message="CURSOR NOT EMPTY";         break;
        case 0x15:  Message="USER CONDITION ABORT";     break;
        case 0x16:  Message="TIMER NOT READY";          break;
            }
            Announce(DebugReady,"Ability[%d][%d][%s] <<%s>>.",ID,TYPE,NAME,Message);
        }
        return (!Result);
    }

    BOOL Press() {
        BOOL Casted=false;
        if(Found() && (DWORD)clock()>READY) {
            Announce(SHOW_ABILITY,"%s::Activate [\ay%s\ax].",PLUGIN_NAME,NAME);
            if(TYPE==SKILL)     Casted=SKPress(ID);
            else if(TYPE==DISC) Casted=CAPress(ID);
            else if(TYPE>=AA)   Casted=Casting(COMM);
            if(Casted) READY=(DWORD)clock()+REUSE;
        }
        return Casted;
    }

    void Setup(LONG id, LONG type) {
        ID=id;            // Ability ID?
        TYPE=type;        // Ability Type?
        NAME[0]=0;        // Ability Name?
        COMM[0]=0;        // Ability Command?
        SEARCH=false;     // Ability Searched?
        READY=0;          // Ability Ready Time
        INDEX=NOID;       // Ability Index
        EFFECT=NULL;      // Ability Spell Effect
    }

    Ability(LONG id, LONG type) {
        Setup(id,type);
    }

    Ability() {
        Setup(0,UNKNOWN);
    }
};

class Option {
public:
    PCHAR    K;  // key?
    PCHAR    H;  // help?
    PCHAR    D;  // default?
    PCHAR    S;  // show?
    string  *C;  // condition?
    Ability *A;  // ability?
    LONG    *V;  // value?
    Function F;  // function?
    BOOL     U;  // update?

    Option(PCHAR k, PCHAR h, PCHAR d, PCHAR s, Function f, string *c) {
        K=k; H=h; D=d; S=s; F=f; U=false; C=c; A=NULL; V=NULL;
    }

    Option(PCHAR k, PCHAR h, PCHAR d, PCHAR s, Function f, Ability *a) {
        K=k; H=h; D=d; S=s; F=f; U=false; C=NULL; A=a; V=NULL;
    }

    Option(PCHAR k, PCHAR h, PCHAR d, PCHAR s, Function f, LONG *v) {
        K=k; H=h; D=d; S=s; F=f; U=false; C=NULL; A=NULL; V=v;
    }

    void Write() {
        if(K[0] && !C && Evaluate(S)) {
            long value=(A)?A->ID:(V)?*V:0;
            if(value>0) WriteChatf("%s::%s (\ag%d\ax) \ay%s\ax.",PLUGIN_NAME,K,value,H);
            else        WriteChatf("%s::%s (\ar0\ax) \ay%s\ax." ,PLUGIN_NAME,K,H);
        }
    }

    void Setup(PCHAR value) {
        if(C) *C=value;
        else if(A) A->Setup(atol(value),0);
        else if(V) {
            if(!stricmp("false",value) || !stricmp("off",value))    *V=0;
            else if(!stricmp("true",value) || !stricmp("on",value)) *V=1;
            else *V=atol(value);
        }
        if(F) this->F();
    }

    void *Value() {
        if(A) return &A->ID;
        else if(V) return V;
        else if(C) return C;
        return NULL;
    }

    long Ready() {
        if(A) return A->Ready("");
        return NOID;
    }

    void Reset() {
        if(K[0]) {
            if(C) *C=D;
            else {
                strcpy(Reserved,D);
                if(Reserved[0]) ParseMacroData(Reserved);
                long value=atol(Reserved);
                if(A) A->Setup(value,0);
                else if(V) *V=value;

            }
            if(F) this->F();
        }
    }
};

typedef map<string,Option> Liste;     // declare a type so more easy to refer
Liste     CmdListe;                   // settings from command or ini
Liste     IniListe;                   // settings from ini only
Liste     VarListe;                   // settings from var liste

CHAR      section[256];               // ini section

LONG      doAGGRO,
doASSASINATE,
doBACKOFF,
doBACKSTAB,
doBASH,
doBEGGING,
doCALLCHALLENGE,
doGUTPUNCH,
doTHROATJAB,
doOPPORTUNISTICSTRIKE,
doBATTLELEAP,
doCHALLENGEFOR,
doCOMMANDING,
doCRYHAVOC,
doDISARM,
doDRAGONPUNCH,
doEAGLESTRIKE,
doENRAGE,
doESCAPE,
doEVADE,
doFEIGNDEATH,
doFACING,
doFALLS,
doFERALSWIPE,
doFISTSOFWU,
doFLYINGKICK,
doFORAGE,
doFRENZY,
doHARMTOUCH,
doHIDE,
doINFURIATE,
doINTIMIDATION,
doJOLT,
doKICK,
doLAYHAND,
doLEOPARDCLAW,
doMELEE,
doMEND,
doPETASSIST,
doPETDELAY,
doPETRANGE,
doPETMEND,
doPICKPOCKET,
doSKILL,
doSTRIKE,
doPROVOKEMAX,
doPROVOKEONCE,
doPROVOKEEND,
doRAGEVOLLEY,
doRAKE,
doRANGE,
doRESUME,
doROUNDKICK,
doSENSETRAP,
doSLAM,
doSNEAK,
doSTAB,
doSTAND,
doSTICKBREAK,
doSTICKDELAY,
doSTICKRANGE,
doSTICKNORANGE,
doSTICKMODE,
doSTRIKEMODE,
doSTUNNING,
doTAUNT,
doTHIEFEYE,
doTHROWSTONE,
doTIGERCLAW,
doTWISTEDSHANK,
doDOWNFLAG[16],
doPOTHEALFAST,
doPOTHEALOVER,
doHOLYFLAG[16];

LONG      elARROWS,
elAGGROPRI,
elAGGROSEC,
elMELEEPRI,
elMELEESEC,
elPOKER,
elRANGED,
elSHIELD;

string    ifBACKSTAB,
ifBASH,
ifBEGGING,
ifCALLCHALLENGE,
ifBATTLELEAP,
ifGUTPUNCH,
ifTHROATJAB,
ifOPPORTUNISTICSTRIKE,
ifCHALLENGEFOR,
ifCOMMANDING,
ifCRYHAVOC,
ifDISARM,
ifDRAGONPUNCH,
ifEAGLESTRIKE,
ifEVADE,
ifFALLS,
ifFERALSWIPE,
ifFISTSOFWU,
ifFLYINGKICK,
ifFORAGE,
ifFRENZY,
ifHARMTOUCH,
ifHIDE,
ifINTIMIDATION,
ifJOLT,
ifKICK,
ifLAYHAND,
ifLEOPARDCLAW,
ifMEND,
ifPICKPOCKET,
ifPOTHEALFAST,
ifPOTHEALOVER,
ifPROVOKE,
ifRAGEVOLLEY,
ifRAKE,
ifROUNDKICK,
ifSENSETRAP,
ifSLAM,
ifSNEAK,
ifSTRIKE,
ifSTUNNING,
ifTAUNT,
ifTHIEFEYE,
ifTHROWSTONE,
ifTIGERCLAW,
ifTWISTEDSHANK,
DOWNSHIT[16],
HOLYSHIT[16],
StickCMD,
StrikeCMD;

Ability   idBACKSTAB,
idBASH,
idBEGGING,
idCALLCHALLENGE,
idBATTLELEAP,
idGUTPUNCH,
idTHROATJAB,
idOPPORTUNISTICSTRIKE,
idCHALLENGEFOR,
idCOMMANDING,
idCRYHAVOC,
idDISARM,
idDRAGONPUNCH,
idEAGLESTRIKE,
idESCAPE,
idFEIGN[2],
idFERALSWIPE,
idFISTSOFWU,
idFLYINGKICK,
idFORAGE,
idFRENZY,
idHARMTOUCH,
idHIDE,
idINTIMIDATION,
idJOLT,
idKICK,
idLAYHAND,
idLEOPARDCLAW,
idMEND,
idPETMEND,
idPICKPOCKET,
idPOTHEALFAST,
idPOTHEALOVER,
idPROVOKE[2],
idRAGEVOLLEY,
idRAKE,
idROUNDKICK,
idSENSETRAP,
idSLAM,
idSNEAK,
idSTUN[2],
idSTRIKE,
idTAUNT,
idTIGERCLAW,
idTHIEFEYE,
idTHROWSTONE,
idTWISTEDSHANK;

DWORD     Shrouded       =false;        // True when shrouded.
bool      Binded         =false;        // Attack Key is Binded?
bool      Loaded         =false;        // Loaded?
bool      Moving         =false;        // Moving?
bool      Immobile       =false;        // Immobilized?
bool      AutoFire       =false;        // True when autofire is on.
bool      HaveBash       =false;        // Have Two Hand Bash?
bool      HaveHold       =false;        // Have Pet Hold?
DWORD     BrokenFD       =0;            // Timer for Broken Feign Death

float     Travel         =0.0f;         // Travel Speed?
long      Health         =0;            // Current Health

DWORD     MeleeTime      =0;            // Melee Pulse Timer
long      MeleeTarg      =0;            // Melee Target ID
long      MeleeType      =0;            // Melee Target Type
long      MeleeFlee      =0;            // Melee Target Fleeing?
long      MeleeLife      =0;            // Melee Target Life %
long      MeleeCast      =0;            // Melee Target Cast ?
long      MeleeSize      =0;            // Melee Name Size
char      MeleeName[64]  ={0};          // Melee Name

double    MeleeSpeed     =0.0f;         // Melee Target Speed
double    MeleeBack      =0.0f;         // Melee Target Angle Back
double    MeleeView      =0.0f;         // Melee Target Angle View
double    MeleeDist      =0.0f;         // Melee Distance to Target
double    MeleeKill      =0.0f;         // Melee Distance to Use Ability

long      onEVENT        =false;        // Ranged=0x8000,Begging=0x2000,PickPocket=0x1000,Feign=0x0040,Hide=0x0020,Backoff=0x0010,Infuriate=0x0002,Enrage=0x0001
long      onSTICK        =false;        // Do Stick? (turn false when stick command is issue)
long      onBELOW        =false;        // Below Flag? (turn false when no more provoke counter)
long      onCHALLENGEFOR =false;        // Challenge Flag? (turn to false when use once)

DWORD     NPC_TYPE       =0x000A;       // NPC TYPE
char      MeleeKey[32];                 // Plugin Melee Key
char      RangeKey[32];                 // Plugin Range Key

DWORD     PetInDist      =0;            // Pet Target in Range
DWORD     PetOnAttk      =0;            // Pet Seen Attacking TimeStamp?
DWORD     PetOnHold      =0;            // Pet Hold?
DWORD     PetOnWait      =0;            // Pet Wait Assist Delay TimeStamp
DWORD     PetTarget      =0;            // Pet Target ID

DWORD     TimerAttk      =0;            // Timer Attk
DWORD     TimerBack      =0;            // Timer BackOff/Escape/Feign
DWORD     TimerMove      =0;            // Timer Move
DWORD     TimerLife      =0;            // Timer Life (Target his dieing)
DWORD     TimerFace      =0;            // Face Time Stamp when started
DWORD     TimerStik      =0;            // Stik Time Stamp when started
DWORD     TimerStun      =0;            // Timer Stun

long      SwingHits      =0;            // Total Hits
long      TakenHits      =0;            // Under Hits

long      doHOLY=0;                     // Holy Shits while meleeing?
long      doDOWN=0;                     // Down Shits while downtime?

Blech    *pMeleeEvent=0;                // blech event list
bool      ColorArray[512];              // blech color filtering
bool      IdlingArray[256];             // animation array while idle
bool      AttackArray[256];             // animation array while attacking

long      SaveList[50];                 // saved event list
long      SaveIndx;                     // saved event counters

DWORD     HiddenTimer     =0;           // Last TimeStamp for Hide
DWORD     SilentTimer     =0;           // Last TimeStamp for Sneak

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

class MQ2MeleeType *pMeleeTypes=0;
class MQ2MeleeType : public MQ2Type {
private:
    long isKill;
    char Tempos[MAX_STRING];
public:
    enum Information {
        Enable=1,
        Combat=2,
        Casted=3,
        Engage=4,
        Status=5,
        Target=6,
        DiscID=7,
        Enrage=8,
        Infuriate=9,
        AggroMode=10,
        MeleeMode=11,
        RangeMode=12,
        BackAngle=13,
        ViewAngle=14,
        Immobilize=15,
        Ammunition=16,
        BackStabbing=17,
        GotAggro=18,
        Hidden=19,
        Silent=20,
        NumHits=21,
    };
    MQ2MeleeType():MQ2Type("Melee") {
        TypeMember(Enable);
        TypeMember(Combat);
        TypeMember(Casted);
        TypeMember(Status);
        TypeMember(Target);
        TypeMember(DiscID);
        TypeMember(GotAggro);
        TypeMember(AggroMode);
        TypeMember(MeleeMode);
        TypeMember(RangeMode);
        TypeMember(Enrage);
        TypeMember(Infuriate);
        TypeMember(BackAngle);
        TypeMember(ViewAngle);
        TypeMember(Immobilize);
        TypeMember(Ammunition);
        TypeMember(BackStabbing);
        TypeMember(Hidden);
        TypeMember(Silent);
        TypeMember(NumHits);
    }
    bool GetMember(MQ2VARPTR VarPtr, PCHAR Member, PCHAR Index, MQ2TYPEVAR &Dest) {
        PMQ2TYPEMEMBER pMember=MQ2MeleeType::FindMember(Member);
        isKill=false; if(doSKILL) if(MeleeTarg) isKill=true;
        if(pMember) switch((Information)pMember->ID) {
    case Enable:
        Dest.DWord=doSKILL;
        Dest.Type=pBoolType;
        return true;
    case Combat:
        Dest.DWord=isKill;
        Dest.Type=pBoolType;
        return true;
    case Casted:
        Dest.Int=(isKill && MeleeCast)?labs((DWORD)clock()-MeleeCast):60000;
        Dest.Type=pIntType;
        return true;
    case Status:
        Tempos[0]=0;
        if(isKill) strcat(Tempos,"ENGAGED ");
        else strcat(Tempos,"WAITING ");
        if(*EQADDR_ATTACK) strcat(Tempos, "MELEE ");
        else if(onEVENT&0x8000) strcat(Tempos,"RANGE ");
        if(onEVENT&0x0001) strcat(Tempos,"ENRAGE ");
        if(onEVENT&0x0002) strcat(Tempos,"INFURIATE ");
        if(onEVENT&0x0010) strcat(Tempos,"BACKING ");
        if(onEVENT&0x0020) strcat(Tempos,"ESCAPING ");
        if(onEVENT&0x0040) strcat(Tempos,"FEIGNING ");
        if(onEVENT&0x0200) strcat(Tempos,"EVADING ");
        if(onEVENT&0x0400) strcat(Tempos,"FALLING ");
        if(onEVENT&0x1000) strcat(Tempos,"STEALING ");
        if(onEVENT&0x2000) strcat(Tempos,"BEGGING ");
        Dest.Type=pStringType;
        Dest.Ptr=Tempos;
        return true;
    case Target:
        Dest.Int=isKill?MeleeTarg:0;
        Dest.Type=pIntType;
        return true;
    case DiscID:
        Dest.DWord=Discipline();
        Dest.Type=pIntType;
        return true;
    case GotAggro:
        Dest.DWord=(Aggroed(MeleeTarg)>0);
        Dest.Type=pBoolType;
        return true;
    case AggroMode:
        Dest.DWord=doAGGRO;
        Dest.Type=pBoolType;
        return true;
    case MeleeMode:
        Dest.DWord=doMELEE;
        Dest.Type=pBoolType;
        return true;
    case RangeMode:
        Dest.DWord=doRANGE;
        Dest.Type=pBoolType;
        return true;
    case Enrage:
        Dest.DWord=onEVENT&0x0001;
        Dest.Type=pBoolType;
        return true;
    case Infuriate:
        Dest.DWord=onEVENT&0x0002;
        Dest.Type=pBoolType;
        return true;
    case BackAngle:
        Dest.Float=pTarget?AngularDistance(((PSPAWNINFO)pTarget)->Heading,SpawnMe()->Heading):0.0f;
        Dest.Type=pFloatType;
        return true;
    case ViewAngle:
        Dest.Float=pTarget?(float)AngularHeading(SpawnMe(),(PSPAWNINFO)pTarget):0.0f;
        Dest.Type=pFloatType;
        return true;
    case Immobilize:
        Dest.DWord=Immobile;
        Dest.Type=pBoolType;
        return true;
    case Ammunition:
        Dest.DWord=ItemCounts(elARROWS);
        if(PCONTENTS r=GetCharInfo2()->Inventory.Ammo)
            if(r->Item->ItemNumber != elARROWS)
                if(r->Item->ItemType==7 || r->Item->ItemType==19 || r->Item->ItemType==27)
                    Dest.DWord=ItemCounts(r->Item->ItemNumber);
        Dest.Type=pIntType;
        return true;
    case BackStabbing:
        Dest.DWord=doBACKSTAB;
        Dest.Type=pBoolType;
        return true;
    case Hidden:
        Dest.Int=TimeSince(HiddenTimer);
        Dest.Type=pIntType;
        return true;
    case Silent:
        Dest.Int=TimeSince(SilentTimer);
        Dest.Type=pIntType;
        return true;
    case NumHits:
        Dest.DWord=SwingHits;
        Dest.Type=pIntType;
        return true;
        }
        strcpy(Tempos,"NULL");
        Dest.Type=pStringType;
        Dest.Ptr=Tempos;
        return true;
    }
    bool ToString(MQ2VARPTR VarPtr, PCHAR Destination) {
        strcpy(Destination,"TRUE");
        return true;
    }
    bool FromData(MQ2VARPTR &VarPtr, MQ2TYPEVAR &Source) {
        return false;
    }
    bool FromString(MQ2VARPTR &VarPtr, PCHAR Source) {
        return false;
    }
    ~MQ2MeleeType() { }
};

BOOL DataMelee(PCHAR Index, MQ2TYPEVAR &Dest) {
    Dest.Type=pMeleeTypes;
    Dest.DWord=1;
    return true;
}

BOOL datameleemvb(PCHAR Index, MQ2TYPEVAR &Dest) {
    Dest.Type=pIntType;
    Dest.Int=NOID;
    Liste::iterator c;
    if(VarListe.end()!=(c=VarListe.find(Index)))
        Dest.Int=(*c).second.Ready();
    return true;
}

BOOL datameleemvi(PCHAR Index, MQ2TYPEVAR &Dest) {
    Dest.Type=pIntType;
    Dest.DWord=0;
    Liste::iterator c;
    if(CmdListe.end()!=(c=CmdListe.find(Index))) {
        if(long *V=(long*)(*c).second.Value()) Dest.DWord=*V;
        return true;
    }
    if(VarListe.end()!=(c=VarListe.find(Index))) {
        if(long *V=(long*)(*c).second.Value()) Dest.DWord=*V;
        return true;
    }
    return true;
}

BOOL datameleemvs(PCHAR Index, MQ2TYPEVAR &Dest) {
    Dest.Type=pStringType;
    Dest.Ptr=&Workings;
    Liste::iterator c=IniListe.find(Index);
    if(IniListe.end()!=c) {
        if(string *S=(string*)(*c).second.Value())
            strcpy(Workings,S->c_str());
    } else Workings[0]=0;
    return true;
}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

void AbilityFind(Ability *thisone, infodata *first, ...) {
    infodata *c=first;
    va_list  marker;
    va_start(marker,first);
    while(c) {
        thisone->Setup(c->i,c->t);
        if(thisone->Avail()) break;
        thisone->ID=0;
        c=va_arg(marker,infodata *);
    }
    va_end(marker);
}

void AttackON() {
    if(*EQADDR_ATTACK || onEVENT&0xFFF7 || IsFeigning() || !doMELEE || !TargetID(MeleeTarg)) return;
    EzCommand("/attack on");
    TimerAttk=(DWORD)clock();
}

void AttackOFF() {
    if(*EQADDR_ATTACK) EzCommand("/attack off");
}

bool BashCheck() {
    if(ShieldType(ContSecondary())) return true;
    if(TwohandType(ContPrimary()))  return HaveBash;
    return (elSHIELD && ItemCounts(elSHIELD) && OkayToEquip(Giant));
}

void BashPress() {
    long savedpri=0; long savedoff=0; BOOL got2hand=false;
    if(PCONTENTS pri=ContPrimary()) {
        got2hand=TwohandType(pri);
        savedpri=pri->Item->ItemNumber;
    }
    if(PCONTENTS off=ContSecondary()) savedoff=off->Item->ItemNumber;
    if(elSHIELD && ItemCounts(elSHIELD) && OkayToEquip(Giant)) Equip(elSHIELD,inv_secondary);
    if(ShieldType(ContSecondary()) || (got2hand && HaveBash)) idBASH.Press();
    if(savedoff) Equip(savedoff,inv_secondary);
    if(savedpri) Equip(savedpri,inv_primary);
}

void Configure() {
    long Class=GetCharInfo2()->Class;
    long Races=GetCharInfo2()->Race;
    long Level=GetCharInfo2()->Level;
    sprintf(INIFileName,"%s\\%s_%s.ini",gszINIPath,EQADDR_SERVERNAME,GetCharInfo()->Name);
    sprintf(section,"%s_%d_%s_%s",PLUGIN_NAME,Level,pEverQuest->GetRaceDesc(Races),pEverQuest->GetClassDesc(Class));
    Shrouded=GetCharInfo2()->Shrouded; if(!Shrouded) section[strlen(PLUGIN_NAME)]=0;
    BuffMax=15;
    if(GetAAIndexByName("Embrace of the Dark Reign"))   BuffMax++;
    else if(GetAAIndexByName("Embrace of the Keepers")) BuffMax++;
    BuffMax+=(AAPoint(GetAAIndexByName("Mystical Attuning")))/5;
    if(SpawnMe()->Level>71) BuffMax++;
    if(SpawnMe()->Level>74) BuffMax++;
    HaveHold=GetAAIndexByName("Pet Discipline")?true:false;
    HaveBash=GetAAIndexByName("2 Hand Bash")?true:false;
    BardClass=false;
    char keys[MAX_STRING*5];
    char temp[MAX_STRING];
    Liste::iterator c,i;
    Liste::iterator ec=CmdListe.end();
    Liste::iterator ei=IniListe.end();
    for(c=CmdListe.begin(); c!=ec; c++) (*c).second.Reset();
    for(i=IniListe.begin(); i!=ei; i++) (*i).second.Reset();

    idCHALLENGEFOR.Setup(0,0);
    idFEIGN[0].Setup    (0,0);
    idFEIGN[1].Setup    (0,0);
    idFERALSWIPE.Setup  (0,0);
    idJOLT.Setup        (0,0);
    idLEOPARDCLAW.Setup (0,0);
    idPETMEND.Setup     (0,0);
    idPROVOKE[0].Setup  (0,0);
    idPROVOKE[1].Setup  (0,0);
    idRAGEVOLLEY.Setup  (0,0);
    idRAKE.Setup        (0,0);
    idSTRIKE.Setup      (0,0);
    idSTUN[0].Setup     (0,0);
    idSTUN[1].Setup     (0,0);

    AbilityFind(&idBACKSTAB,&sbkstab,0);
    AbilityFind(&idBASH,&sbash,0);
    AbilityFind(&idBEGGING,&sbegging,0);
    AbilityFind(&idDISARM,&sdisarm,0);
    AbilityFind(&idDRAGONPUNCH,&sdrpunch,0);
    AbilityFind(&idEAGLESTRIKE,&sestrike,0);
    AbilityFind(&idFLYINGKICK,&sflykick,0);
    AbilityFind(&idFORAGE,&sforage,0);
    AbilityFind(&idFRENZY,&sfrenzy,0);
    AbilityFind(&idHARMTOUCH,&sharmtou,0);
    AbilityFind(&idHIDE,&shide,0);
    AbilityFind(&idINTIMIDATION,&sintim,0);
    AbilityFind(&idKICK,&skick,0);
    AbilityFind(&idLAYHAND,&layhand,0);
    AbilityFind(&idMEND,&smend,0);
    AbilityFind(&idPICKPOCKET,&sppocket,0);
    AbilityFind(&idROUNDKICK,&srndkick,0);
    AbilityFind(&idSENSETRAP,&ssensetr,0);
    AbilityFind(&idSLAM,&sslam,0);
    AbilityFind(&idSNEAK,&ssneak,0);
    AbilityFind(&idTAUNT,&staunt,0);
    AbilityFind(&idTIGERCLAW,&stigclaw,0);
    AbilityFind(&idCALLCHALLENGE,&callchal,0);
    AbilityFind(&idGUTPUNCH,&gutpunch,0);
    AbilityFind(&idBATTLELEAP,&btlleap,0);
    AbilityFind(&idESCAPE,&escape,0);
    AbilityFind(&idTWISTEDSHANK,&twisted,0);
    AbilityFind(&idTHROWSTONE,&tstone,0);
    AbilityFind(&idCOMMANDING,&cmmding,0);
    AbilityFind(&idFISTSOFWU,&fistswu,0);
    AbilityFind(&idTHIEFEYE,&thiefeye,0);
    AbilityFind(&idCRYHAVOC,&cryhavoc,0);
    AbilityFind(&idPOTHEALOVER,&potover13,&potover12,&potover11,&potover10,&potover9,&potover8,&potover7,&potover6,&potover5,&potover4,&potover3,&potover2,&potover1,&potover0,0);
    AbilityFind(&idPOTHEALFAST,&potfast13,&potfast12,&potfast11,&potfast10,&potfast9,&potfast8,&potfast7,&potfast6,&potfast5,&potfast4,&potfast3,&potfast2,&potfast1,&potfast0,0);
    doSTAB=0;
    switch(Class) {
    case  1: // WAR
        AbilityFind(&idPROVOKE[1],&prowar_s,&prowar_r,&prowar_q,&prowar_p,&prowar_o,&prowar_n,&prowar_m,&prowar_l,&prowar_k,&prowar_j,&prowar_i,&prowar_h,&prowar_g,&prowar_f,&prowar_e,&prowar_d,&prowar_c,&prowar_b,&prowar_a,0);
        AbilityFind(&idOPPORTUNISTICSTRIKE,&opstrkec,&opstrkeb,&opstrkea,0);
        AbilityFind(&idTHROATJAB,&throatc,&throatb,&throata,0);
        break;
    case  3: // PAL
        AbilityFind(&idCHALLENGEFOR,&honori,&honorh,&honorg,&honorf,&honore,&honord,&honorc,&honorb,&honora,0);
        AbilityFind(&idPROVOKE[0],&stunpal3,&stunpal2,&stunpal1,0);
        AbilityFind(&idPROVOKE[1],&stunpalw,&stunpalv,&stunpalu,&stunpalt,&stunpals,&stunpalr,&stunpalq,&stunpalp,&stunpalo,&stunpaln,&stunpalm,&stunpall,&stunpalk,&stunpalj,&stunpali,&stunpalh,&stunpalg,&stunpalf,&stunpale,&stunpald,&stunpalc,&stunpalb,&stunpala,0);
        AbilityFind(&idSTUN[0],&stunpal3,&stunpal2,&stunpal1,0);
        AbilityFind(&idSTUN[1],&stunpalw,&stunpalv,&stunpalu,&stunpalt,&stunpals,&stunpalr,&stunpalq,&stunpalp,&stunpalo,&stunpaln,&stunpalm,&stunpall,&stunpalk,&stunpalj,&stunpali,&stunpalh,&stunpalg,&stunpalf,&stunpale,&stunpald,&stunpalc,&stunpalb,&stunpala,0);
        break;
    case  4: // RNG
        AbilityFind(&idJOLT,&joltrng5,&joltrng4,&joltrng3,&joltrng2,&joltrng1,0);
        break;
    case  5: // SHD
        AbilityFind(&idFEIGN[0],&feignsl,&feignsk,&feignsj,&feignsi,&feignsh,&feignsg,&feignsf,&feignse,&feignsd,&feignsc,&feignsb,&feignsa,0);
        AbilityFind(&idFEIGN[1],&feigndp,0);
        AbilityFind(&idCHALLENGEFOR,&poweri,&powerh,&powerg,&powerf,&powere,&powerd,&powerc,&powerb,&powera,0);
        AbilityFind(&idPROVOKE[1],&terrorn,&terrorm,&terrorl,&terrorj,&terrori,&terrorh,&terrorg,&terrorf,&terrore,&terrord,&terrorc,&terrorb,&terrora,0);
        break;
    case  7: // MNK
        AbilityFind(&idFEIGN[0],&sfeign,0);
        AbilityFind(&idFEIGN[1],&feignid,0);
        AbilityFind(&idPROVOKE[0],&stunmnk2,&stunmnk1,0);
        AbilityFind(&idSTUN[0],&stunmnk2,&stunmnk1,0);
        AbilityFind(&idLEOPARDCLAW,&leop11,&leop10,&leop9,&leop8,&leop7,&leop6,&leop5,&leop4,&leop3,&leop2,&leop1,0);
        break;
    case  8: // BRD
        BardClass=true;
        break;
    case  9: // ROG
        AbilityFind(&idSTRIKE,&strikej,&strikei,&strikeh,&strikeg,&strikef,&strikee,&striked,&strikec,&strikeb,&strikea,0);
        switch(AAPoint(GetAAIndexByName("Seized Opportunity"))) {
    case 74: doSTAB=512; break;
    case 60: doSTAB=256; break;
    case 39: doSTAB=192; break;
    case 18: doSTAB=128; break;
    default: doSTAB=64;  break;
        }
        break;
    case 11: // NEC
        AbilityFind(&idFEIGN[0],&feignsc,&feignsb,&feignsa,0);
        AbilityFind(&idFEIGN[1],&feigndp,0);
        AbilityFind(&idPETMEND,&mendpet2,&mendpet1,0);
        break;
    case 13: // MAG
        AbilityFind(&idPETMEND,&mendpet2,&mendpet1,0);
        break;
    case 15: // BST
        AbilityFind(&idRAKE,&rake4,&rake3,&rake2,&rake1,0);
        AbilityFind(&idFERALSWIPE,&feral1,0);
        AbilityFind(&idPETMEND,&mendpet1,&mendpet2,0);
        AbilityFind(&idJOLT,&joltbst1,0);
        break;
    case 16: // BER
        AbilityFind(&idJOLT,&joltberj,&joltberi,&joltberh,&joltberg,&joltberf,&joltbere,&joltberd,&joltberc,&joltberb,&joltbera,0);
        AbilityFind(&idRAGEVOLLEY,&volleyn,&volleym,&volleyl,&volleyk,&volleyj,&volleyi,&volleyh,&volleyg,&volleyf,&volleye,&volleyd,&volleyc,&volleyb,&volleya,0);
        AbilityFind(&idPROVOKE[1],&stunberj,&stunberi,&stunberh,&stunberg,&stunberf,&stunbere,&stunberd,&stunberc,&stunberb,&stunbera,0);
        AbilityFind(&idSTUN[1],&stunberj,&stunberi,&stunberh,&stunberg,&stunberf,&stunbere,&stunberd,&stunberc,&stunberb,&stunbera,0);
        break;
    }
    if(GetPrivateProfileString(section,NULL,"",keys,sizeof(keys),INIFileName)) {
        PCHAR pkeys=keys;
        while(pkeys[0]) {
            if(GetPrivateProfileString(section,pkeys,"",temp,sizeof(temp),INIFileName)) {
                _strlwr(pkeys);
                if(ec!=(c=CmdListe.find(pkeys)))      (*c).second.Setup(temp);
                else if(ei!=(i=IniListe.find(pkeys))) (*i).second.Setup(temp);
            }
            pkeys+=strlen(pkeys)+1;
        }
    }
    Loaded=true;
}

void Exporting() {
    char output[MAX_STRING];
    char defval[MAX_STRING];
    Liste::iterator c,e;
    WritePrivateProfileString(section,NULL,NULL,INIFileName);
    e=CmdListe.end();
    for(c=CmdListe.begin(); c!=e; c++) {
        output[0]=0;
        if((*c).second.C)
            if(string *S=(string*)(*c).second.Value())
                strcpy(output,S->c_str());
        if((*c).second.A || (*c).second.V)
            if(long *V=(long*)(*c).second.Value())
                itoa(*V,output,10);
        if(output[0]) {
            strcpy(defval,(*c).second.D);
            if(defval[0]) ParseMacroData(defval);
            if(strcmp(output,"0") || strcmp(output,defval))
                WritePrivateProfileString(section,(*c).second.K,output,INIFileName);
        }
    }
    e=IniListe.end();
    for(c=IniListe.begin(); c!=e; c++) {
        output[0]=0;
        if((*c).second.C)
            if(string *S=(string*)(*c).second.Value())
                strcpy(output,S->c_str());
        if((*c).second.A || (*c).second.V)
            if(long *V=(long*)(*c).second.Value())
                itoa(*V,output,10);
        if(output[0]) {
            strcpy(defval,(*c).second.D);
            if(defval[0]) ParseMacroData(defval);
            if(strcmp(output,"0") || strcmp(output,defval))
                WritePrivateProfileString(section,(*c).second.K,output,INIFileName);
        }
    }
    sprintf(output,"%1.3f",PLUGIN_VERS); WritePrivateProfileString(section,"version",output,INIFileName);
}

void MapInsert(Liste *MyList, Option MyOption)
{
    MyList->insert(Liste::value_type(MyOption.K,MyOption));
}

void MeleeHelp()
{
    WriteChatf("%s::-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-", PLUGIN_NAME);
    WriteChatf("%s::Version [\ag%1.3f\ax] Loaded!", PLUGIN_NAME, PLUGIN_VERS);
    WriteChatf("%s::-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-", PLUGIN_NAME);
    for(Liste::iterator i=CmdListe.begin(); i!=CmdListe.end(); i++) (*i).second.Write();
    WriteChatf("%s::-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-", PLUGIN_NAME);
    if (NULL == PluginEntry("mq2cast", "CastCommand"))
    {
        WriteChatf("%s::Required Latest [\arMQ2Cast\ax] for AA/SPELL/ITEM casting.", PLUGIN_NAME);
    }
    if (NULL == PluginEntry("mq2moveutils", "StickCommand"))
    {
        WriteChatf("%s::Required Latest [\arMQ2MoveUtils\ax] for MOVEMENT.", PLUGIN_NAME);
    }
}

void PetSEEN()
{
    PetOnAttk = (unsigned long)clock() + 6000;
    PetOnHold = false;
}

void PetBACK()
{
    PetOnHold = true;
    if (doPETASSIST && pPetInfoWnd && PetButtonEnabled(UI_PetBack))
    {
        Announce(SHOW_CONTROL, "%s::Command [\ay%s\ax].", PLUGIN_NAME, "/pet back");
        EzCommand("/pet back");
    }
}

void PetATTK()
{
    PetSEEN();
    if (doPETASSIST && pPetInfoWnd && !(onEVENT&0x0003) && MeleeTarg && PetButtonEnabled(UI_PetAttk))
    {
        Announce(SHOW_CONTROL,"%s::Command [\ay%s\ax].",PLUGIN_NAME,"/pet attack");
        if (!TargetID(MeleeTarg))
        {
            PSPAWNINFO Current = Target();
            TargetIT(GetSpawnID(MeleeTarg));
            EzCommand("/pet attack");
            if (Current) Command("/squelch /target id %d", Current->SpawnID);
        }
        else
        {
            EzCommand("/pet attack");
        }
        PetTarget = MeleeTarg;
    }
}

void StickReset(void)
{
    TimerStik = 0;
    if (Sticking) Stick("");
    StickArg[0] = 0;
    onSTICK = (doMELEE && !(onEVENT&0x8000) && (doSTICKRANGE || doSTICKNORANGE) && bMULoaded); // x && x && !ranged && moveutils_loaded
}

void RangeReset()
{
    if (!doRANGE && AutoFire) EzCommand("/autofire");
    if (!doRANGE && (onEVENT&0x8000)) onEVENT&=0x7FFF;
}

void OtherReset()
{
    MeleeTarg = 0;
    MeleeType = 0;
    MeleeLife = 0;
    MeleeCast = 0;
    MeleeFlee = 0;
    TimerBack = 0;
    TimerLife = 0;
    TimerFace = 0;
    TimerStun = 0;
    PetTarget = 0;
    PetOnWait = 0;
    SwingHits = 0;
    TakenHits = 0;
    onEVENT = 0;
    doDOWN = 0;
    doHOLY = 0;
}

void MeleeReset()
{
    if(!doMELEE && *EQADDR_ATTACK)
    {
        AttackOFF();
        StickReset();
    }
}

void AggroReset()
{
    int onAGGRO = (doAGGRO && IsGrouped());
    onCHALLENGEFOR = (onAGGRO && idCHALLENGEFOR.Found());
    onBELOW = (onAGGRO && doPROVOKEMAX) ? doPROVOKEMAX : 0;
    if (doMELEE)
    {
        if (LONG PW = (IsGrouped() && doAGGRO) ? elAGGROPRI : elMELEEPRI) Equip(PW, inv_primary);
        if (LONG SW = (IsGrouped() && doAGGRO) ? elAGGROSEC : elMELEESEC) Equip(SW, inv_secondary);
    }
}

VOID SneakOFF() {
    if(IsSneaking() && idSNEAK.Found()) idSNEAK.Press();
}

VOID HideOFF() {
    if(IsInvisible() && idHIDE.Found()) idHIDE.Press();
}

BOOL StabCheck() {
    if(elPOKER && OkayToEquip(Giant) && PokerType(ItemLocate(elPOKER))) return true;
    return PokerType(ContPrimary());
}

void StabPress() {
    long saveid=0;
    if(elPOKER && OkayToEquip(Giant) && ItemLocate(elPOKER,0,NUM_INV_SLOTS,InvSlot)) {
        if(PCONTENTS pri=ContPrimary())
            if(pri->Item->ItemNumber!=elPOKER) {
                saveid=pri->Item->ItemNumber;
                Equip(elPOKER,inv_primary);
            }
    }
    if(PokerType(ContPrimary())) {
        idBACKSTAB.Press();
        SwingHits++;
    }
    if(saveid) Equip(saveid,inv_primary);
}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

PLUGIN_API VOID ThrowIT(PSPAWNINFO pChar, PCHAR Cmd) {
    if(gbRangedAttackReady && pTarget && TargetType(NPC_TYPE) &&
        !InRange(SpawnMe(),(PSPAWNINFO)pTarget,35) &&
        fabs(AngularHeading(SpawnMe(),(PSPAWNINFO)pTarget))<50 &&
        LineOfSight(SpawnMe(),(PSPAWNINFO)pTarget)) {

            // test if we could do ranged with current ammo/range configuration
            long crT=99; long crI=0; long caT=99; long caI=0; long caQ=0;
            if(PCONTENTS r=ContRange()) {
                crI=r->Item->ItemNumber;
                crT=r->Item->ItemType;
            }
            if(PCONTENTS a=ContAmmo()) {
                caI=a->Item->ItemNumber;
                caT=a->Item->ItemType;
                if(caT == 7 || caT == 19 || caT == 27) caQ=ItemCounts(caI);
            }
            if(!(caI && ((caT == 27 && crT == 5) || (caI == crI && (caT == 7 || caT == 19))))) {
                if(!OkayToEquip(Giant)) return;

                // grab information about user defined range/ammunition
                long erT=99; long eaT=99; long eaQ=0;
                if(PCONTENTS r=ItemLocate(elRANGED)) erT=r->Item->ItemType;
                if(PCONTENTS a=ItemLocate(elARROWS)) {
                    eaT=a->Item->ItemType;
                    if(eaT == 7 || eaT == 19 || eaT == 27) eaQ=ItemCounts(elARROWS);
                }

                // find equipping scenario (bow+arrow) or (throw/throw).
                long EquipRangeID=0; long EquipArrowID=0;
                if((crT == 5 || erT == 5) && (caT == 27 || eaT == 27)) {
                    EquipRangeID=(crT== 5)?crI:elRANGED;
                    EquipArrowID=(caT==27)?caI:elARROWS;
                }
                else if((caQ > 2 && (caT == 7 || caT == 19)) || (eaQ > 2 && (eaT == 7 || eaT == 19)))
                {
                    EquipRangeID=(caQ>2 &&(caT==7 || caT==19))?caI:elARROWS;
                    EquipArrowID=(caQ>2 &&(caT==7 || caT==19))?caI:elARROWS;
                }
                else return;

                // load equipping scenario found!
                if(EquipRangeID && EquipArrowID) {
                    if(crI!=EquipRangeID) Equip(EquipRangeID,inv_range);
                    if(caI!=EquipArrowID) Equip(EquipArrowID,inv_ammo);
                    if(EquipArrowID==EquipRangeID && !ContRange()) {
                        WinClick((CXWnd*)pInventoryWnd,"InvSlot22","leftmouseup",Ctrlkey);  // pick one from ammo
                        WinClick((CXWnd*)pInventoryWnd,"InvSlot11","leftmouseup",Shiftkey); // fill one in range
                    }
                }
            }

            // more sanity double check in case we didnt exchange stuff
            PCONTENTS rSlot=ContRange();  if(!rSlot) return;
            PCONTENTS aSlot=ContAmmo();   if(!aSlot) return;
            long rType=rSlot->Item->ItemType; if(!(rType == 5 || rType == 7  || rType == 19)) return;
            long aType=aSlot->Item->ItemType; if(!(aType == 7 || aType == 19 || aType == 27)) return;
            long aKind=aSlot->Item->ItemNumber; long rKind=rSlot->Item->ItemNumber;
            if(!((aType == 27 && rType == 5) || (aType!=27 && rKind == aKind))) return;

            // good time to reload ammunitions?
            if(OkayToEquip()) {
                while(aSlot->StackCount < 80 && ItemCounts(aKind,BAG_SLOT_START)>0) {
                    ItemLocate(aKind,BAG_SLOT_START);
                    pInvSlotMgr->MoveItem(InvSlot,NUM_INV_SLOTS,1,1);
                    WinClick((CXWnd*)pInventoryWnd,"InvSlot22","leftmouseup",Shiftkey);
                    if(!CursorEmpty()) pInvSlotMgr->MoveItem(NUM_INV_SLOTS,InvSlot,1,1);
                }
                if(aType != 27 && aKind == rKind) {
                    while(rSlot->StackCount < 80 && ItemCounts(aKind,BAG_SLOT_START)>0) {
                        ItemLocate(aKind,BAG_SLOT_START);
                        pInvSlotMgr->MoveItem(InvSlot,NUM_INV_SLOTS,1,1);
                        WinClick((CXWnd*)pInventoryWnd,"InvSlot22","leftmouseup",Shiftkey);
                        WinClick((CXWnd*)pInventoryWnd,"InvSlot11","leftmouseup",Shiftkey);
                        if(!CursorEmpty()) pInvSlotMgr->MoveItem(NUM_INV_SLOTS,InvSlot,1,1);
                    }
                }
            }

            // fire ranged attack if NPC on Target still in range and preserve the range slot.
            do_ranged(SpawnMe(),"");
            if(crI) if(rKind!=crI) if(OkayToEquip()) Equip(crI,inv_range);
    }
}

PLUGIN_API void Override(PSPAWNINFO pChar, char* Cmd)
{
    Announce(SHOW_OVERRIDE, Cmd, PLUGIN_NAME);
    MeleeTime = (unsigned long)clock() + delay;
    AttackOFF();
    if(AutoFire)
    {
        AutoFire = false;
        EzCommand("/autofire");
    }
    PetBACK();
    StickReset();
    OtherReset();
}

PLUGIN_API void Melee(PSPAWNINFO pChar, char* Cmd)
{
    char Tmp[MAX_STRING]; char Var[MAX_STRING]; char Set[MAX_STRING]; BYTE Parm=1; bool Help=true;
    Liste::iterator c; Liste::iterator ec=CmdListe.end();
    do {
        GetArg(Tmp,Cmd,Parm++); _strlwr(Tmp);
        GetArg(Var,Tmp,1,FALSE,FALSE,FALSE,'=');
        GetArg(Set,Tmp,2,FALSE,FALSE,FALSE,'=');
        if(Var[0]) {
            c=CmdListe.find(Var);
            if(ec!=c) {
                (*c).second.Setup(Set);
                (*c).second.Write();
                Help=false;
            } else if(!Set[0] && (!stricmp(Var,"on") || !stricmp(Var,"off"))) {
                if(ec!=(c=CmdListe.find("plugin"))) (*c).second.Setup(Var);
                Help=false;
            } else if(!Set[0] && (!stricmp(Var,"reload") || !stricmp(Var,"load"))) {
                WriteChatf("%s::Loading...",PLUGIN_NAME);
                Configure();
                Help=false;
            } else if(!Set[0] && !stricmp(Var,"save")) {
                WriteChatf("%s::Saving...",PLUGIN_NAME);
                Exporting();
                Help=false;
            } else if(!Set[0] && !stricmp(Var,"key")) {
                char buffer[MAX_STRING]; KeyCombo combo;
                DescribeKeyCombo(pKeypressHandler->NormalKey[FindMappableCommand("AUTOPRIM")],buffer);
                WriteChatf("%s::\ayATTACK\ax binded to [\ay%s\ax]",PLUGIN_NAME,buffer);
                GetMQ2KeyBind("MELEE",false,combo);
                DescribeKeyCombo(combo,buffer);
                WriteChatf("%s::\ayMELEE\ax  binded to [\ay%s\ax]",PLUGIN_NAME,buffer);
                GetMQ2KeyBind("RANGE",false,combo);
                DescribeKeyCombo(combo,buffer);
                WriteChatf("%s::\ayRANGE\ax  binded to [\ay%s\ax]",PLUGIN_NAME,buffer);
                Help=false;
            } else if(!Set[0] && !stricmp(Var,"reset")) {
                Override(NULL,"%s::Resetting...");
                Help=false;
            } else {
                WriteChatf("%s::Unsupported Argument <\ar%s\ax>",PLUGIN_NAME,Var);
                break;
            }
        }
    } while(strlen(Tmp));
    if(Help) MeleeHelp();
}

PLUGIN_API void KillThis(PSPAWNINFO pChar, char* Cmd)
{
    if (doSKILL && pTarget && !TargetID(MeleeTarg) && TargetType(NPC_TYPE) && InGame())
    {
        if (IsFeigning()) EzCommand("/stand");
        StickReset();
        OtherReset();
        AggroReset();
        MeleeTarg = ((PSPAWNINFO)pTarget)->SpawnID;
        strcpy(MeleeName,((PSPAWNINFO)pTarget)->DisplayedName);
        MeleeSize = strlen(MeleeName)+1;
        MeleeType = SpawnMask((PSPAWNINFO)pTarget);
        onEVENT|=0x0008;
        Announce(SHOW_ATTACKING,"%s::Attacking [\ay%s\ax].",PLUGIN_NAME,MeleeName);
    }
}

PLUGIN_API VOID EnrageON(PSPAWNINFO pChar, PCHAR Cmd) {
    if(long val=atol(Cmd)) if(val!=MeleeTarg) return;
    if(doSKILL && doENRAGE && MeleeTarg && InGame()) {
        PSPAWNINFO KillTarg=GetSpawnID(MeleeTarg);
        if(!(onEVENT&0x0001)) {
            if(!(onEVENT&0x0002)) PetBACK();
            onEVENT|=0x0001;
            Announce(SHOW_ENRAGING,"MQ2Melee::\arENRAGE\ax detected, taking action!");
        }
        if(*EQADDR_ATTACK && onEVENT&0x0003 && SpawnType(KillTarg,NPC_TYPE)) {
            double Back=fabs(AngularDistance(KillTarg->Heading,SpawnMe()->Heading));
            double View=fabs(AngularHeading(SpawnMe(),KillTarg));
            if(Back > 92 || View > 60 || onEVENT&0x0002) {
                onEVENT|=0x0008;
                AttackOFF();
            }
        }
    }
}

PLUGIN_API VOID EnrageOFF(PSPAWNINFO pChar, PCHAR Cmd) {
    if(long val=atol(Cmd)) if(val!=MeleeTarg) return;
    if(doSKILL && doENRAGE && MeleeTarg && onEVENT&0x0001 && InGame()) {
        onEVENT&=0xFFFE;
        if(TargetID(PetTarget)) PetATTK();
        Announce(SHOW_ENRAGING,"MQ2Melee:: \agENRAGE\ax ended, taking action!");
    }
}

PLUGIN_API VOID InfuriateON(PSPAWNINFO pChar, PCHAR Cmd) {
    if(long val=atol(Cmd)) if(val!=MeleeTarg) return;
    if(doSKILL && doINFURIATE && MeleeTarg && InGame()) {
        if(!(onEVENT&0x0002)) {
            if(!(onEVENT&0x0001)) PetBACK();
            onEVENT|=0x0002;
            Announce(SHOW_ENRAGING,"MQ2Melee::\arINFURIATE\ax detected, taking action!");
        }
        if(*EQADDR_ATTACK) {
            AttackOFF();
            onEVENT|=0x0008;
        }
    }
}

PLUGIN_API VOID InfuriateOFF(PSPAWNINFO pChar, PCHAR Cmd) {
    if(long val=atol(Cmd)) if(val!=MeleeTarg) return;
    if(doSKILL && doINFURIATE && MeleeTarg && onEVENT&0x0002 && InGame()) {
        onEVENT&=0xFFFD;
        if(TargetID(PetTarget)) PetATTK();
        Announce(SHOW_ENRAGING,"MQ2Melee:\agINFURIATE\ax ended, taking action!");
    }
}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

void DowntimeHandle()
{
    if(doSENSETRAP && idSENSETRAP.Ready(ifSENSETRAP)) idSENSETRAP.Press();
    if(!MeleeTarg && (DWORD)clock()>TimerAttk && Immobile) {
        if(doDOWNFLAG[doDOWN] && DOWNSHIT[doDOWN].size()) EzCommand((PCHAR)DOWNSHIT[doDOWN].c_str());
        for(long x=1; x<16; x++) {
            long n=(x+doDOWN)&15;
            if(doDOWNFLAG[n]) {
                doDOWN=n;
                break;
            }
        }
        if (doFORAGE && idFORAGE.Ready(ifFORAGE))
        {
            idFORAGE.Press();
        }
        else if (doSNEAK && !IsSneaking() && idSNEAK.Ready(ifSNEAK))
        {
            idSNEAK.Press();
        }
        else if (doHIDE && !IsInvisible() && idHIDE.Ready(ifHIDE))
        {
            idHIDE.Press();
        }
    }
}

void MeleeHandle()
{
    // check opened windows that wont let us perform any melee actions.
    if(!BardClass  && WinState((CXWnd*)pCastingWnd))  return;
    if(WinState((CXWnd*)pSpellBookWnd))               return;
    if(WinState((CXWnd*)pLootWnd))                    return;
    if(WinState((CXWnd*)pBankWnd))                    return;
    if(WinState((CXWnd*)pMerchantWnd))                return;
    if(WinState((CXWnd*)pTradeWnd))                   return;
    if(WinState((CXWnd*)pGiveWnd))                    return;
    Silenced=false;

    // check detrimental buff that wont let ya perform melee actions.
    for(int b=0; b<BuffMax; b++) {
        long SpellID=GetCharInfo2()->Buff[b].SpellID;
        if(SpellID<1) continue;
        if(PSPELL spell=GetSpellByID(SpellID))
            for(int a=0; a<12; a++) switch(spell->Attrib[a]) {
        case 22: return;        // charmed
        case 23: return;        // feared
        case 31: return;        // mesmerized
        case 40: return;        // invulnerable
        case 96: Silenced=true; // silenced
            }
    }

    // check detrimental song that wont let ya perform melee actions.
    for(int s=0; s<SongMax; s++) {
        long SpellID=GetCharInfo2()->ShortBuff[s].SpellID;
        if(SpellID<1) continue;
        if(PSPELL spell=GetSpellByID(SpellID))
            for(int a=0; a<12; a++) switch(spell->Attrib[a]) {
        case 22: return;        // charmed
        case 23: return;        // feared
        case 31: return;        // mesmerized
        case 40: return;        // invulnerable
        case 96: Silenced=true; // silenced
            }
    }

    // check our health and perform some healing action if we can
    if((Health=GetCurHPS()*100/GetMaxHPS())<100) {
        Ability *UseThis=NULL;
        if(doMEND && Health<=doMEND && idMEND.Ready(ifMEND))                  UseThis=&idMEND;
        else if(doLAYHAND && Health<=doLAYHAND && idLAYHAND.Ready(ifLAYHAND)) UseThis=&idLAYHAND;
        else if(doPOTHEALFAST && Health<=doPOTHEALFAST && idPOTHEALFAST.Ready(ifPOTHEALFAST)) UseThis=&idPOTHEALFAST;
        else if(doPOTHEALOVER && Health<=doPOTHEALOVER && idPOTHEALOVER.Ready(ifPOTHEALOVER)) UseThis=&idPOTHEALOVER;
        if(UseThis) {
            if(UseThis->ID == idLAYHAND.ID) {
                PSPAWNINFO TargetSave=pTarget?(PSPAWNINFO)pTarget:NULL;
                *(PSPAWNINFO*)ppTarget=SpawnMe();
                idLAYHAND.Press();
                *(PSPAWNINFO*)ppTarget=TargetSave;
            } else UseThis->Press();
        }
    }

    // check if we are stunned, if so we can't perform any melee actions
    if (IsStunned()) return;

    // check if we still have a killing target or we acquiring a new one
    if ((pTarget && TargetType(NPC_TYPE)) && (*EQADDR_ATTACK || onEVENT&0x8000))
    {
        if (!MeleeTarg)
        {
            KillThis(NULL, "");
        }
        else if (!TargetID(MeleeTarg))
        {
            Override(NULL,"%s::\arTARGET SWITCH\ax taking actions.");
            return;
        }
        TimerAttk = (DWORD)clock()+delay*12;
    }
    if (MeleeTarg)
    {
        if (PSPAWNINFO Tar = GetSpawnID(MeleeTarg))
        {
            if (!MeleeLife || Tar->HPCurrent < MeleeLife) TimerLife = (DWORD)clock() + 1500;
            MeleeLife = Tar->HPCurrent;
        }
    }

    // check if we should standup from an interrupted feign death
    if(BrokenFD && (DWORD)clock()>BrokenFD) {
        BrokenFD=false;
        if(IsFeigning()) {
            Announce(SHOW_FEIGN,"%s::\arFAILED FEIGN DEATH\ax taking action!",PLUGIN_NAME);
            EzCommand("/stand");
            return;
        }
    }

    // check it's a good time to perform some downtime actions?
    if(!IsCasting()) DowntimeHandle();

    // check it's a good time to drop combat?
    Ability *FeignDeath=NULL;
    if(idFEIGN[0].Ready(""))      FeignDeath=&idFEIGN[0];
    else if(idFEIGN[1].Ready("")) FeignDeath=&idFEIGN[1];
    Health=GetCurHPS()*100/GetMaxHPS();
    if(!doAGGRO && !(onEVENT&0x0FF0) && !IsFeigning() && !IsInvisible()) {
        bool fTime=(doFEIGNDEATH && Health<=doFEIGNDEATH && FeignDeath);
        bool eTime=(doESCAPE     && Health<=doESCAPE     && idESCAPE.Ready(""));
        bool bTime=(doBACKOFF    && Health<=doBACKOFF);

        if(fTime || eTime || bTime) {
            if(*EQADDR_ATTACK) {
                onEVENT|=0x0008;
                AttackOFF();
            } else {
                if(fTime)      onEVENT|=0x0040;
                else if(eTime) onEVENT|=0x0020;
                else if(bTime) onEVENT|=0x0010;
                if(onEVENT&0x0020)      idESCAPE.Press();
                else if(onEVENT&0x0040) FeignDeath->Press();
            }
            return;
        }
    }

    // check it's a good time to resume combat?
    if((IsFeigning() || IsInvisible() || onEVENT&0x0FF0) && !(onEVENT&0x4000))
    {
        if(!TimerBack) TimerBack=(DWORD)clock()+delay;
        else if((DWORD)clock()>TimerBack && (doAGGRO || (onEVENT&0x0FF0 && Health>doRESUME)))
        {
            if((IsInvisible() || onEVENT&0x0220) && (!IsInvisible() || !(onEVENT&0x0020))) onEVENT&=0xFDDF;
            if((IsFeigning()  || onEVENT&0x0440) && (!IsFeigning() || (IsFeigning() && doSTAND)))
            {
                onEVENT&=0xFBBF;
                EzCommand("/stand");
                StickReset();
                return;
            }
            onEVENT&=0xF99F;
            TimerBack=false;
        }
    }
    // end resume

    // time to handle dummy pet, check mending, check we have target in range, etc...
    if (doPETASSIST && MeleeTarg )
    {
        PSPAWNINFO Pet=SpawnPet();
        PSPAWNINFO Tar=GetSpawnID(MeleeTarg);
        if ( Pet && Tar )
        {
            if ( doPETMEND && Pet->HPCurrent<=doPETMEND && idPETMEND.Ready("") ) idPETMEND.Press();
            PetInDist=( !doPETRANGE || InRange(Pet,Tar,(FLOAT)doPETRANGE) );
            if ( !PetOnWait && PetInDist ) PetOnWait=(DWORD)clock()+doPETDELAY*1000;
            if ( PetOnWait && (DWORD)clock()>PetOnWait && PetInDist )
            {
                if ( (DWORD)clock()>TimerLife || !IdlingArray[Tar->Animation & 0xFF] )
                {
                    if ( (DWORD)clock()>PetOnAttk ) PetATTK();
                }
            }
        }
    }
    // end pet

    // hold on?
    if(!MeleeTarg || !TargetID(MeleeTarg) || !IsStanding() || onEVENT&0x0FF2) // this event is never referenced elsewhere
    {
        if(*EQADDR_ATTACK) AttackOFF();
        return;
    }

    // target is in range? could we engage and kill it?  
    // ***** hard-coded override if we are more than 250 away  ****
    if((MeleeDist = DistanceToSpawn(SpawnMe(), (PSPAWNINFO)pTarget)) > 250)
    {
        Override(NULL, "");
        return;
    }
    // end 250 range enforce

    MeleeSpeed = fabs(FindSpeed((PSPAWNINFO)pTarget));
    MeleeBack  = fabs(AngularDistance(((PSPAWNINFO)pTarget)->Heading,SpawnMe()->Heading));
    MeleeView  = fabs(AngularHeading(SpawnMe(),(PSPAWNINFO)pTarget));
    MeleeFlee  = (MeleeFlee || (MeleeLife<=85 && MeleeSpeed>25.0f && IsMobFleeing(SpawnMe(),(PSPAWNINFO)pTarget)));
    MeleeKill  = ((PSPAWNINFO)pTarget)->AvatarHeight+12.0f;
    //Sticking=Evaluate("$If[$Stick.Active},1,0]}");
    if (bMULoaded && bMUPointers) Sticking = *pbStickOn;

    // are we discing? if so time to promote some actions?
    long disc = Discipline();
    if(disc && !(onEVENT&0x7007)) switch(disc)
    {
    case d_ashenhand:      // Ashenhand Discipline?
        if(doMELEE && MeleeDist<MeleeKill && idEAGLESTRIKE.Ready("")) idEAGLESTRIKE.Press(); break;
    case d_silentfist:     // Silentfist Discipline?
        if(doMELEE && MeleeDist<MeleeKill && idDRAGONPUNCH.Ready("")) idDRAGONPUNCH.Press(); break;
    case d_thunderkick:    // Thunderkick Discipline?
    case d_heelofkanji:    // Heel of Kanji?
        if(doMELEE && MeleeDist<MeleeKill && idFLYINGKICK.Ready("")) idFLYINGKICK.Press(); break;
    case d_assassin1:
    case d_assassin2:
    case d_assassin3:
        if(doMELEE && MeleeDist<MeleeKill && MeleeView<60 && MeleeBack<doSTAB && idBACKSTAB.Ready("") && StabCheck()) StabPress(); break;
    }

    // scripted rogue sequence striking/assasination codes
    if(doASSASINATE && doBACKSTAB && doMELEE && onSTICK>0 && !SwingHits && !TakenHits && MeleeSpeed<2.0f && !*EQADDR_ATTACK && StabCheck())
    {
        if(!Moving && Immobile)
        {
            if(!IsSneaking() && idSNEAK.Ready("")) idSNEAK.Press();
            if(!IsInvisible() && idHIDE.Ready("")) idHIDE.Press();
            if(IsSneaking() && TimeSince(SilentTimer)>1000 && IsInvisible() && TimeSince(HiddenTimer)>1000)
            {
                if (doSTRIKEMODE)    /// strikemode = 1
                {
                    strcpy(Reserved,StrikeCMD.c_str()); // copy our strike ini command to Reserved
                    ParseMacroData(Reserved); // parse out TLO evaluations
                }
                else   // strikemode not set
                {
                    if(doSTAB>191) sprintf(Reserved,"%2.2f id %d !front"    ,MeleeKill-3.0f,MeleeTarg);
                    else           sprintf(Reserved,"%2.2f id %d behindonce",MeleeKill-3.0f,MeleeTarg);
                }
                if(!Sticking && strcmp(Reserved,StickArg))
                {
                    Stick(Reserved);
                    return;
                }
                if(MeleeDist>MeleeKill || MeleeView>60 || MeleeBack>doSTAB)
                {
                    SwingHits++;
                }
                else if(idBACKSTAB.Ready("") && TimeSince(HiddenTimer)>3000)
                {
                    if (Sticking) Stick("");
                    if (doSTRIKE && idSTRIKE.Ready(ifSTRIKE)) idSTRIKE.Press();
                    else StabPress();
                }
            }
        }
        if(Sticking && (SwingHits || TakenHits || !IsSneaking() || !IsInvisible())) Stick("");
        return;
    }
    // end rogue striking/assasination

    // jolting times!
    if(doJOLT && !doAGGRO && SwingHits>doJOLT && idJOLT.Ready(ifJOLT))
    {
        idJOLT.Press();
        SwingHits=1;
    }
    //end jolt

    // handle melee
    if(doMELEE && !(onEVENT&0x8000))
    {
        if(onEVENT&0x0008 && !(onEVENT&0xF007) && !*EQADDR_ATTACK) AttackON();

        // start stick processing
        if(onSTICK)      // would have value if StickReset called, or set by itself
        {
            if(onSTICK > 0) // value would be positive from StickReset
            {
                // if no timer (set here) -- if (no range set or distance to target less than stick range, set timer
                if(!TimerStik) if(!doSTICKRANGE || doSTICKNORANGE || MeleeDist<doSTICKRANGE) TimerStik=(DWORD)clock()+doSTICKDELAY*1000;
                // if not moving and not sticking and (no delay or timer is up) and no range set or distance to target less than stick range
                // set onstick negative so below if is processed
                // *** if a range is set and we are greater than this range, this may cause those "open space" problems
                if(Immobile && !Sticking && (!doSTICKDELAY || (DWORD)clock()>TimerStik) && (!doSTICKRANGE || doSTICKNORANGE || MeleeDist<doSTICKRANGE)) onSTICK=-1;
            }
            if(onSTICK<0)        // set negative by above in cases where we should stick
            {
                if(doSTICKMODE)        // if we have a custom stick command, use this
                {
                    strcpy(Reserved,StickCMD.c_str()); // copy our ini command to Reserved
                    ParseMacroData(Reserved);          // parse out TLO evaluations
                }
                else       // else melee decides how to process stick as follows
                {
                    long type=Aggroed(MeleeTarg); // set to 1 if cases acceptable to attack (on hott, within range)
                    bool swim=(SpawnMe()->UnderWater==5); // use "uw" arg if underwater
                    bool stab=(type<1 && doBACKSTAB && doSTAB<192); // use "behind" if not aggro and strike option enabled, else !front
                    bool tank=(type>0 || (!IsInvisible() && (doAGGRO || !GetCharInfo()->pGroupInfo))); // use "moveback" if tank and aggro, else process stab
                    double dist=MeleeKill-3.0f-(MeleeFlee*3.0f); // stick numeric parameter for distance
                    sprintf(Reserved,"%2.2f id %d%s%s", dist, MeleeTarg, MeleeFlee ? "" : (tank ? " moveback" : (!stab ? " !front" : " behind")), swim ? " uw" : "");
                }
                //if(strcmp(Reserved,StickArg)) Stick(Reserved); // issue command if its not the same as the last issued (stickarg set to last arg given to Stick()??
                // most likely because if we are sticking and want to change the type of stick we issue, but this will fail if stick got
                // shut off and the arg never reset properly, so lets check also if we are not sticking by checking moveutils actual status
                if (bMULoaded && bMUPointers)  // if moveutils is loaded
                {
                    if (strcmp(Reserved, StickArg) || (!doSTICKBREAK && !*pbStickOn)) Stick(Reserved);
                }
            }
        }
        // end stick processing

        // not behind enraged/infuriated target?
        if(onEVENT&0x0003 && *EQADDR_ATTACK)
        {
            if(MeleeBack > 92 || onEVENT&0x0002)
            {
                if(MeleeBack > 92) Announce(SHOW_ENRAGING,"%s::\arNOT BEHIND\ax enraged target, taking action!",PLUGIN_NAME);
                onEVENT|=0x0008;
                AttackOFF();
                return;
            }
        }

        // check target is in melee range?
        if(MeleeDist<MeleeKill)
        {
            // attack is off, good time for stealing/begging or evading?
            if(!*EQADDR_ATTACK)
            {
                onEVENT&=0xBFFF;
                if(!MeleeFlee)
                {
                    if(doPICKPOCKET && idPICKPOCKET.Ready(ifPICKPOCKET))
                    {
                        idPICKPOCKET.Press();
                        onEVENT|=0x1008;
                    }
                    else if(doBEGGING && !IsInvisible() && idBEGGING.Ready(ifBEGGING))
                    {
                        idBEGGING.Press();
                        onEVENT|=0x2008;
                    }
                    if(doEVADE && !doAGGRO && Immobile && !IsInvisible() && idHIDE.Ready(ifEVADE))
                    {
                        idHIDE.Press();
                        onEVENT|=0x0208;
                    }
                    else if(doFALLS && !doAGGRO && FeignDeath->Ready(ifFALLS))
                    {
                        FeignDeath->Press();
                        onEVENT|=0x0408;
                    }
                }
                if(onEVENT&0x0001 && !(onEVENT&0xFFF6) && MeleeBack<92)
                {
                    Announce(SHOW_ENRAGING,"%s::\agBEHIND\ax TARGET kicking attack ON!!!",PLUGIN_NAME);
                    onEVENT&=0xFFF6; AttackON(); onEVENT|=0x0009;
                }
            }
            else   // attack is on so lets do some dps?
            {
                if(doBACKSTAB && MeleeBack<doSTAB && MeleeView<60 && idBACKSTAB.Ready(ifBACKSTAB) && StabCheck()) StabPress();
                if(doFLYINGKICK && idFLYINGKICK.Ready(ifFLYINGKICK)) idFLYINGKICK.Press();
                if(doDRAGONPUNCH && idDRAGONPUNCH.Ready(ifDRAGONPUNCH)) idDRAGONPUNCH.Press();
                if(doEAGLESTRIKE && idEAGLESTRIKE.Ready(ifEAGLESTRIKE)) idEAGLESTRIKE.Press();
                if(doTIGERCLAW && idTIGERCLAW.Ready(ifTIGERCLAW)) idTIGERCLAW.Press();
                if(doROUNDKICK && idROUNDKICK.Ready(ifROUNDKICK)) idROUNDKICK.Press();
                if(doBASH && idBASH.Ready(ifBASH) && BashCheck()) BashPress();
                if(doSLAM && idSLAM.Ready(ifSLAM)) idSLAM.Press();
                if(doFRENZY && idFRENZY.Ready(ifFRENZY)) idFRENZY.Press();
                if(doKICK && idKICK.Ready(ifKICK)) idKICK.Press();
                if(!disc && Immobile && !IsInvisible() && !MeleeFlee)
                {
                    if(doPICKPOCKET   && idPICKPOCKET.Ready(ifPICKPOCKET))                    onEVENT|=0x4008;
                    if(doBEGGING      && idBEGGING.Ready(ifBEGGING))                          onEVENT|=0x4008;
                    if(doFALLS        && !doAGGRO && FeignDeath->Ready(ifFALLS))              onEVENT|=0x4008;
                    if(doEVADE        && !(doAGGRO || !IsGrouped()) && idHIDE.Ready(ifEVADE)) onEVENT|=0x4008;
                    if(onEVENT&0x4000 && *EQADDR_ATTACK) AttackOFF();
                }

                if(MeleeDist < 15)
                {
                    if(doDISARM && idDISARM.Ready(ifDISARM)) idDISARM.Press();
                }
            }
            if(doINTIMIDATION && idINTIMIDATION.Ready(ifINTIMIDATION)) idINTIMIDATION.Press();
            if(doTAUNT && doAGGRO && idTAUNT.Ready(ifTAUNT)) idTAUNT.Press();
        }
        //end target is in range

        if(MeleeFlee) SneakOFF();
        if(onEVENT&0x3000) onEVENT&=0xCFFF;
    }
    // end handle melee

    // handle ranged?
    if(doRANGE || onEVENT&0x8000)
    {
        // should we face target? not moving, stopped >2sec, facing>2sec and not sticking?
        if(doFACING && Immobile && (DWORD)clock()>TimerFace && !Sticking)
        {
            if(MeleeView>30) Face(SpawnMe(),"");
            TimerFace=(DWORD)clock()+delay*8;
        }
        // are we in good ranged for ranged?
        if(MeleeDist<(doRANGE?doRANGE:250) && MeleeDist>35 && MeleeDist>MeleeKill+20)
        {
            if(!AutoFire && gbRangedAttackReady) ThrowIT(NULL,"");
            if(*EQADDR_ATTACK)
            {
                if(Sticking) Stick("");
                onEVENT|=0x8000;
                AttackOFF();
                Announce(SHOW_SWITCHING,"%s::Switching [\ayRange\ax].",PLUGIN_NAME);
            }
        }
        else if(!*EQADDR_ATTACK) // target too close? or too far?
        {
            if(AutoFire)
            {
                EzCommand("/autofire");
                AutoFire=false;
            }
            if(Immobile && onEVENT&0x8000)
            {
                onEVENT&=0x7FF7;
                if(doMELEE)
                {
                    StickReset();
                    onEVENT|=0x0008;
                    AttackON();
                    Announce(SHOW_SWITCHING,"%s::Switching [\ayMelee\ax].",PLUGIN_NAME);
                }
            }
        }
    }

    // time to handle spell casting?
    if(!TargetID(MeleeTarg) || MeleeDist>200) return;
    long MyEndu=GetCharInfo2()->Endurance*100/GetMaxEndurance();

    // should we stun that target?
    if(doSTUNNING && MeleeLife<=doSTUNNING)
    {
        Ability *UseThis=NULL;
        if(idSTUN[0].Ready(ifSTUNNING))      UseThis=&idSTUN[0];
        else if(idSTUN[1].Ready(ifSTUNNING)) UseThis=&idSTUN[1];
        if(UseThis)
        {
            Announce(SHOW_STUNNING,"%s::Stunning [\ay%s\ax].",PLUGIN_NAME,MeleeName);
            UseThis->Press();
        }
    }

    // are we grouped?
    if(IsGrouped())
    {
        // Time to build and maintain aggro?
        if(doAGGRO)
        {
            LONG HaveAggro=Aggroed(MeleeTarg);

            // should we challenge for to maintain aggro over time?
            if(doCHALLENGEFOR && onCHALLENGEFOR && HaveAggro==1 && idCHALLENGEFOR.Ready(ifCHALLENGEFOR)) {
                Announce(SHOW_PROVOKING,"%s::Challenging [\ay%s\ax].",PLUGIN_NAME,MeleeName);
                idCHALLENGEFOR.Press();
                onCHALLENGEFOR--;
            }

            // should we provoke at least once and/or when aggro is lost?
            if(onBELOW && MeleeLife>doPROVOKEEND && MeleeDist<100 && (HaveAggro<1 || (doPROVOKEONCE && onBELOW==doPROVOKEMAX)))
            {
                Ability *UseThis=NULL;
                if(idPROVOKE[0].Ready(ifPROVOKE))      UseThis=&idPROVOKE[0];
                else if(idPROVOKE[1].Ready(ifPROVOKE)) UseThis=&idPROVOKE[1];
                if(UseThis)
                {
                    Announce(SHOW_PROVOKING,"%s::Provoking [\ay%s\ax].",PLUGIN_NAME,MeleeName);
                    UseThis->Press();
                    onBELOW--;
                }
            }
        }

        // should we use short duration melee buff?
        if(GetCharInfo2()->Endurance>200)
        {
            if(doCOMMANDING && MyEndu>doCOMMANDING && idCOMMANDING.Ready(ifCOMMANDING)) idCOMMANDING.Press();
            if(doFISTSOFWU  && MyEndu>doFISTSOFWU  && idFISTSOFWU.Ready(ifFISTSOFWU))   idFISTSOFWU.Press();
            if(doCRYHAVOC   && MyEndu>doCRYHAVOC   && idCRYHAVOC.Ready(ifCRYHAVOC) && disc!=d_cleaverage && disc!=d_cleaveanger) idCRYHAVOC.Press();
            if(doTHIEFEYE   && MyEndu>doTHIEFEYE   && idTHIEFEYE.Ready(ifTHIEFEYE))     idTHIEFEYE.Press();
        }
    }

    // should we use zerker volley?
    if(doRAGEVOLLEY && MyEndu>doRAGEVOLLEY && MeleeDist<175 && idRAGEVOLLEY.Ready(ifRAGEVOLLEY)) idRAGEVOLLEY.Press();

    // is target close enough for those?
    if(MeleeDist < 50)
    {
        if(doRAKE && MyEndu>doRAKE && idRAKE.Ready(ifRAKE)) idRAKE.Press();
        if(doFERALSWIPE && idFERALSWIPE.Ready(ifFERALSWIPE)) idFERALSWIPE.Press();
        if(doLEOPARDCLAW && MyEndu>doLEOPARDCLAW && idLEOPARDCLAW.Ready(ifLEOPARDCLAW)) idLEOPARDCLAW.Press();
        if(doTHROWSTONE && MyEndu>doTHROWSTONE && idTHROWSTONE.Ready(ifTHROWSTONE)) idTHROWSTONE.Press();
        if(doCALLCHALLENGE && idCALLCHALLENGE.Ready(ifCALLCHALLENGE)) idCALLCHALLENGE.Press();
        if(doGUTPUNCH && idGUTPUNCH.Ready(ifGUTPUNCH)) idGUTPUNCH.Press();
        if(doBATTLELEAP && idBATTLELEAP.Ready(ifBATTLELEAP)) idBATTLELEAP.Press();
        if(doTWISTEDSHANK && idTWISTEDSHANK.Ready(ifTWISTEDSHANK)) idTWISTEDSHANK.Press();
        if(doTHROATJAB && idTHROATJAB.Ready(ifTHROATJAB)) idTHROATJAB.Press();
        if(doOPPORTUNISTICSTRIKE && idOPPORTUNISTICSTRIKE.Ready(ifOPPORTUNISTICSTRIKE)) idOPPORTUNISTICSTRIKE.Press();
    }

    // time to handle holy shit?
    if(doHOLYFLAG[doHOLY] && HOLYSHIT[doHOLY].size()) EzCommand((PCHAR)HOLYSHIT[doHOLY].c_str());
    for(long x=1; x<16; x++)
    {
        long n=(x+doHOLY)&15;
        if(doHOLYFLAG[n])
        {
            doHOLY=n;
            break;
        }
    }
}

void KeyMelee(PCHAR NAME, BOOL Down)
{
    if(Down && pTarget)
    {
        if(!doSKILL) EzCommand("/keypress AUTOPRIM");
        else if(!MeleeTarg) KillThis(NULL,"");
        else Override(NULL,"%s::\arOVERRIDE\ax taking actions!");
    }
}

void KeyRange(PCHAR NAME, BOOL Down)
{
    if(Down && pTarget)
    {
        if(!doSKILL) EzCommand("/keypress RANGED");
        else ThrowIT(NULL,"");
    }
}

void Bindding(bool BindMode)
{
    if(BindMode)
    {
        if(!Binded)
        {
            KeyCombo  MeleeCombo, RangeCombo;
            RemoveMQ2KeyBind("MELEE"); AddMQ2KeyBind("MELEE",KeyMelee); ParseKeyCombo(MeleeKey,MeleeCombo); SetMQ2KeyBind("MELEE",false,MeleeCombo);
            RemoveMQ2KeyBind("RANGE"); AddMQ2KeyBind("RANGE",KeyRange); ParseKeyCombo(RangeKey,RangeCombo); SetMQ2KeyBind("RANGE",false,RangeCombo);
            Binded=true;
        }
    }
    else if(Binded)
    {
        RemoveMQ2KeyBind("MELEE");
        RemoveMQ2KeyBind("RANGE");
        Binded=false;
    }
}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

void __stdcall AUTOFIREOFF(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    AutoFire=false;
    if(AutoFire) KeyMelee("",true);
}

void __stdcall AUTOFIREON(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    if(pTarget && TargetType(NPC_TYPE) && InGame()) AutoFire=true;
}

void __stdcall CASTING(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    if(doSKILL && MeleeTarg && !strnicmp(pValues->Value,MeleeName,MeleeSize)) MeleeCast=(DWORD)clock();
}

void __stdcall ENRAGEON(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    if(MeleeTarg && !strnicmp(pValues->Value,MeleeName,MeleeSize)) EnrageON(NULL,"");
}

void __stdcall ENRAGEOFF(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    if(MeleeTarg && !strnicmp(pValues->Value,MeleeName,MeleeSize)) EnrageOFF(NULL,"");
}

void __stdcall INFURIATEON(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    if(MeleeTarg && !strnicmp(pValues->Value,MeleeName,MeleeSize)) InfuriateON(NULL,"");
}

void __stdcall INFURIATEOFF(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    if(MeleeTarg && !strnicmp(pValues->Value,MeleeName,MeleeSize)) InfuriateOFF(NULL,"");
}

void __stdcall PETATTK(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    PetSEEN();
}

void __stdcall PETBACK(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    if(HaveHold) {
        Announce(SHOW_CONTROL,"%s::Command [\ay%s\ax].",PLUGIN_NAME,"/pet hold on");
        EzCommand("/pet hold on");
        if(PetOnAttk) PetOnAttk=(DWORD)clock()+1000;
        PetOnHold=true;
    }
}

void __stdcall PETHOLD(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    PetOnHold=true;
}

void __stdcall FALLEN(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    if(!doSKILL || ((long)pData && strnicmp(pValues->Value,GetCharInfo()->Name,strlen(GetCharInfo()->Name)+1))) return;
    Announce(SHOW_FEIGN,"%s::\arFAILED FEIGN DEATH\ax taking action!",PLUGIN_NAME);
    EzCommand("/stand");
}

void __stdcall BROKEN(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    if(doSKILL) BrokenFD=(DWORD)clock()+1;
}

void __stdcall RESUME(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    if(doSKILL) BrokenFD=0;
}

void __stdcall SNEAKON(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    SilentTimer=(DWORD)clock();
}

void __stdcall SNEAKOFF(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    SilentTimer=0;
}

void __stdcall HIDEON(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    HiddenTimer=(DWORD)clock();
}

void __stdcall HIDEOFF(unsigned int ID, void *pData, PBLECHVALUE pValues) {
    HiddenTimer=0;
}

//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=//

PLUGIN_API VOID InitializePlugin() {
    NPC_TYPE=GetPrivateProfileInt("Settings","SpawnType",0x000A,INIFileName);
    GetPrivateProfileString("Settings","MeleeKeys","z",MeleeKey,sizeof(MeleeKey),INIFileName);
    GetPrivateProfileString("Settings","RangeKeys","x",RangeKey,sizeof(RangeKey),INIFileName);
    CmdListe.clear();
    MapInsert(&CmdListe,Option(pAGGRO[0],pAGGRO[1],pAGGRO[2],pAGGRO[3],AggroReset,&doAGGRO));
    MapInsert(&CmdListe,Option(pAGGRP[0],pAGGRP[1],pAGGRP[2],pAGGRP[3],NULL      ,&elAGGROPRI));
    MapInsert(&CmdListe,Option(pAGGRS[0],pAGGRS[1],pAGGRS[2],pAGGRS[3],NULL      ,&elAGGROSEC));
    MapInsert(&CmdListe,Option(pARROW[0],pARROW[1],pARROW[2],pARROW[3],NULL      ,&elARROWS));
    MapInsert(&CmdListe,Option(pASSAS[0],pASSAS[1],pASSAS[2],pASSAS[3],NULL      ,&doASSASINATE));
    MapInsert(&CmdListe,Option(pBKOFF[0],pBKOFF[1],pBKOFF[2],pBKOFF[3],NULL      ,&doBACKOFF));
    MapInsert(&CmdListe,Option(pBSTAB[0],pBSTAB[1],pBSTAB[2],pBSTAB[3],NULL      ,&doBACKSTAB));
    MapInsert(&CmdListe,Option(pBASHS[0],pBASHS[1],pBASHS[2],pBASHS[3],NULL      ,&doBASH));
    MapInsert(&CmdListe,Option(pBGING[0],pBGING[1],pBGING[2],pBGING[3],NULL      ,&doBEGGING));
    MapInsert(&CmdListe,Option(pCALLC[0],pCALLC[1],pCALLC[2],pCALLC[3],NULL      ,&doCALLCHALLENGE));
    MapInsert(&CmdListe,Option(pGTPUN[0],pGTPUN[1],pGTPUN[2],pGTPUN[3],NULL      ,&doGUTPUNCH));
    MapInsert(&CmdListe,Option(pOSTRK[0],pOSTRK[1],pOSTRK[2],pOSTRK[3],NULL      ,&doOPPORTUNISTICSTRIKE));
    MapInsert(&CmdListe,Option(pTTJAB[0],pTTJAB[1],pTTJAB[2],pTTJAB[3],NULL      ,&doTHROATJAB));
    MapInsert(&CmdListe,Option(pBTLLP[0],pBTLLP[1],pBTLLP[2],pBTLLP[3],NULL      ,&doBATTLELEAP));
    MapInsert(&CmdListe,Option(pCHFOR[0],pCHFOR[1],pCHFOR[2],pCHFOR[3],NULL      ,&doCHALLENGEFOR));
    MapInsert(&CmdListe,Option(pCOMMG[0],pCOMMG[1],pCOMMG[2],pCOMMG[3],NULL      ,&doCOMMANDING));
    MapInsert(&CmdListe,Option(pCRYHC[0],pCRYHC[1],pCRYHC[2],pCRYHC[3],NULL      ,&doCRYHAVOC));
    MapInsert(&CmdListe,Option(pDISRM[0],pDISRM[1],pDISRM[2],pDISRM[3],NULL      ,&doDISARM));
    MapInsert(&CmdListe,Option(pDWNF0[0],pDWNF0[1],pDWNF0[2],pDWNF0[3],NULL      ,&doDOWNFLAG[0]));
    MapInsert(&CmdListe,Option(pDWNF1[0],pDWNF1[1],pDWNF1[2],pDWNF1[3],NULL      ,&doDOWNFLAG[1]));
    MapInsert(&CmdListe,Option(pDWNF2[0],pDWNF2[1],pDWNF2[2],pDWNF2[3],NULL      ,&doDOWNFLAG[2]));
    MapInsert(&CmdListe,Option(pDWNF3[0],pDWNF3[1],pDWNF3[2],pDWNF3[3],NULL      ,&doDOWNFLAG[3]));
    MapInsert(&CmdListe,Option(pDWNF4[0],pDWNF4[1],pDWNF4[2],pDWNF4[3],NULL      ,&doDOWNFLAG[4]));
    MapInsert(&CmdListe,Option(pDWNF5[0],pDWNF5[1],pDWNF5[2],pDWNF5[3],NULL      ,&doDOWNFLAG[5]));
    MapInsert(&CmdListe,Option(pDWNF6[0],pDWNF6[1],pDWNF6[2],pDWNF6[3],NULL      ,&doDOWNFLAG[6]));
    MapInsert(&CmdListe,Option(pDWNF7[0],pDWNF7[1],pDWNF7[2],pDWNF7[3],NULL      ,&doDOWNFLAG[7]));
    MapInsert(&CmdListe,Option(pDWNF8[0],pDWNF8[1],pDWNF8[2],pDWNF8[3],NULL      ,&doDOWNFLAG[8]));
    MapInsert(&CmdListe,Option(pDWNF9[0],pDWNF9[1],pDWNF9[2],pDWNF9[3],NULL      ,&doDOWNFLAG[9]));
    MapInsert(&CmdListe,Option(pDWNF10[0],pDWNF10[1],pDWNF10[2],pDWNF10[3],NULL      ,&doDOWNFLAG[10]));
    MapInsert(&CmdListe,Option(pDWNF11[0],pDWNF11[1],pDWNF11[2],pDWNF11[3],NULL      ,&doDOWNFLAG[11]));
    MapInsert(&CmdListe,Option(pDWNF12[0],pDWNF12[1],pDWNF12[2],pDWNF12[3],NULL      ,&doDOWNFLAG[12]));
    MapInsert(&CmdListe,Option(pDWNF13[0],pDWNF13[1],pDWNF13[2],pDWNF13[3],NULL      ,&doDOWNFLAG[13]));
    MapInsert(&CmdListe,Option(pDWNF14[0],pDWNF14[1],pDWNF14[2],pDWNF14[3],NULL      ,&doDOWNFLAG[14]));
    MapInsert(&CmdListe,Option(pDWNF15[0],pDWNF15[1],pDWNF15[2],pDWNF15[3],NULL      ,&doDOWNFLAG[15]));
    MapInsert(&CmdListe,Option(pDRPNC[0],pDRPNC[1],pDRPNC[2],pDRPNC[3],NULL      ,&doDRAGONPUNCH));
    MapInsert(&CmdListe,Option(pEAGLE[0],pEAGLE[1],pEAGLE[2],pEAGLE[3],NULL      ,&doEAGLESTRIKE));
    MapInsert(&CmdListe,Option(pERAGE[0],pERAGE[1],pERAGE[2],pERAGE[3],NULL      ,&doENRAGE));
    MapInsert(&CmdListe,Option(pESCAP[0],pESCAP[1],pESCAP[2],pESCAP[3],NULL      ,&doESCAPE));
    MapInsert(&CmdListe,Option(pEVADE[0],pEVADE[1],pEVADE[2],pEVADE[3],NULL      ,&doEVADE));
    MapInsert(&CmdListe,Option(pFEIGN[0],pFEIGN[1],pFEIGN[2],pFEIGN[3],NULL      ,&doFEIGNDEATH));
    MapInsert(&CmdListe,Option(pFACES[0],pFACES[1],pFACES[2],pFACES[3],NULL      ,&doFACING));
    MapInsert(&CmdListe,Option(pFALLS[0],pFALLS[1],pFALLS[2],pFALLS[3],NULL      ,&doFALLS));
    MapInsert(&CmdListe,Option(pFERAL[0],pFERAL[1],pFERAL[2],pFERAL[3],NULL      ,&doFERALSWIPE));
    MapInsert(&CmdListe,Option(pFISTS[0],pFISTS[1],pFISTS[2],pFISTS[3],NULL      ,&doFISTSOFWU));
    MapInsert(&CmdListe,Option(pFLYKC[0],pFLYKC[1],pFLYKC[2],pFLYKC[3],NULL      ,&doFLYINGKICK));
    MapInsert(&CmdListe,Option(pFORAG[0],pFORAG[1],pFORAG[2],pFORAG[3],NULL      ,&doFORAGE));
    MapInsert(&CmdListe,Option(pFRENZ[0],pFRENZ[1],pFRENZ[2],pFRENZ[3],NULL      ,&doFRENZY));
    MapInsert(&CmdListe,Option(pHARMT[0],pHARMT[1],pHARMT[2],pHARMT[3],NULL      ,&doHARMTOUCH));
    MapInsert(&CmdListe,Option(pHIDES[0],pHIDES[1],pHIDES[2],pHIDES[3],NULL      ,&doHIDE));
    MapInsert(&CmdListe,Option(pHOLF0[0],pHOLF0[1],pHOLF0[2],pHOLF0[3],NULL      ,&doHOLYFLAG[0]));
    MapInsert(&CmdListe,Option(pHOLF1[0],pHOLF1[1],pHOLF1[2],pHOLF1[3],NULL      ,&doHOLYFLAG[1]));
    MapInsert(&CmdListe,Option(pHOLF2[0],pHOLF2[1],pHOLF2[2],pHOLF2[3],NULL      ,&doHOLYFLAG[2]));
    MapInsert(&CmdListe,Option(pHOLF3[0],pHOLF3[1],pHOLF3[2],pHOLF3[3],NULL      ,&doHOLYFLAG[3]));
    MapInsert(&CmdListe,Option(pHOLF4[0],pHOLF4[1],pHOLF4[2],pHOLF4[3],NULL      ,&doHOLYFLAG[4]));
    MapInsert(&CmdListe,Option(pHOLF5[0],pHOLF5[1],pHOLF5[2],pHOLF5[3],NULL      ,&doHOLYFLAG[5]));
    MapInsert(&CmdListe,Option(pHOLF6[0],pHOLF6[1],pHOLF6[2],pHOLF6[3],NULL      ,&doHOLYFLAG[6]));
    MapInsert(&CmdListe,Option(pHOLF7[0],pHOLF7[1],pHOLF7[2],pHOLF7[3],NULL      ,&doHOLYFLAG[7]));
    MapInsert(&CmdListe,Option(pHOLF8[0],pHOLF8[1],pHOLF8[2],pHOLF8[3],NULL      ,&doHOLYFLAG[8]));
    MapInsert(&CmdListe,Option(pHOLF9[0],pHOLF9[1],pHOLF9[2],pHOLF9[3],NULL      ,&doHOLYFLAG[9]));
    MapInsert(&CmdListe,Option(pHOLF10[0],pHOLF10[1],pHOLF10[2],pHOLF10[3],NULL      ,&doHOLYFLAG[10]));
    MapInsert(&CmdListe,Option(pHOLF11[0],pHOLF11[1],pHOLF11[2],pHOLF11[3],NULL      ,&doHOLYFLAG[11]));
    MapInsert(&CmdListe,Option(pHOLF12[0],pHOLF12[1],pHOLF12[2],pHOLF12[3],NULL      ,&doHOLYFLAG[12]));
    MapInsert(&CmdListe,Option(pHOLF13[0],pHOLF13[1],pHOLF13[2],pHOLF13[3],NULL      ,&doHOLYFLAG[13]));
    MapInsert(&CmdListe,Option(pHOLF14[0],pHOLF14[1],pHOLF14[2],pHOLF14[3],NULL      ,&doHOLYFLAG[14]));
    MapInsert(&CmdListe,Option(pHOLF15[0],pHOLF15[1],pHOLF15[2],pHOLF15[3],NULL      ,&doHOLYFLAG[15]));
    MapInsert(&CmdListe,Option(pINFUR[0],pINFUR[1],pINFUR[2],pINFUR[3],NULL      ,&doINFURIATE));
    MapInsert(&CmdListe,Option(pINTIM[0],pINTIM[1],pINTIM[2],pINTIM[3],NULL      ,&doINTIMIDATION));
    MapInsert(&CmdListe,Option(pJOLTS[0],pJOLTS[1],pJOLTS[2],pJOLTS[3],NULL      ,&doJOLT));
    MapInsert(&CmdListe,Option(pKICKS[0],pKICKS[1],pKICKS[2],pKICKS[3],NULL      ,&doKICK));
    MapInsert(&CmdListe,Option(pLHAND[0],pLHAND[1],pLHAND[2],pLHAND[3],NULL      ,&doLAYHAND));
    MapInsert(&CmdListe,Option(pLCLAW[0],pLCLAW[1],pLCLAW[2],pLCLAW[3],NULL      ,&doLEOPARDCLAW));
    MapInsert(&CmdListe,Option(pMELEE[0],pMELEE[1],pMELEE[2],pMELEE[3],NULL      ,&doMELEE));
    MapInsert(&CmdListe,Option(pMELEP[0],pMELEP[1],pMELEP[2],pMELEP[3],NULL      ,&elMELEEPRI));
    MapInsert(&CmdListe,Option(pMELES[0],pMELES[1],pMELES[2],pMELES[3],NULL      ,&elMELEESEC));
    MapInsert(&CmdListe,Option(pMENDS[0],pMENDS[1],pMENDS[2],pMENDS[3],NULL      ,&doMEND));
    MapInsert(&CmdListe,Option(pBOWID[0],pBOWID[1],pBOWID[2],pBOWID[3],NULL      ,&elRANGED));
    MapInsert(&CmdListe,Option(pPETAS[0],pPETAS[1],pPETAS[2],pPETAS[3],NULL      ,&doPETASSIST));
    MapInsert(&CmdListe,Option(pPETDE[0],pPETDE[1],pPETDE[2],pPETDE[3],NULL      ,&doPETDELAY));
    MapInsert(&CmdListe,Option(pPETRN[0],pPETRN[1],pPETRN[2],pPETRN[3],NULL      ,&doPETRANGE));
    MapInsert(&CmdListe,Option(pPETMN[0],pPETMN[1],pPETMN[2],pPETMN[3],NULL      ,&doPETMEND));
    MapInsert(&CmdListe,Option(pPICKP[0],pPICKP[1],pPICKP[2],pPICKP[3],NULL      ,&doPICKPOCKET));
    MapInsert(&CmdListe,Option(pPOKER[0],pPOKER[1],pPOKER[2],pPOKER[3],NULL      ,&elPOKER));
    MapInsert(&CmdListe,Option(pHFAST[0],pHFAST[1],pHFAST[2],pHFAST[3],NULL      ,&doPOTHEALFAST));
    MapInsert(&CmdListe,Option(pHOVER[0],pHOVER[1],pHOVER[2],pHOVER[3],NULL      ,&doPOTHEALOVER));
    MapInsert(&CmdListe,Option(pPRVKM[0],pPRVKM[1],pPRVKM[2],pPRVKM[3],AggroReset,&doPROVOKEMAX));
    MapInsert(&CmdListe,Option(pPRVKE[0],pPRVKE[1],pPRVKE[2],pPRVKE[3],NULL      ,&doPROVOKEEND));
    MapInsert(&CmdListe,Option(pPRVKO[0],pPRVKO[1],pPRVKO[2],pPRVKO[3],NULL      ,&doPROVOKEONCE));
    MapInsert(&CmdListe,Option(pPRVK0[0],pPRVK0[1],pPRVK0[2],pPRVK0[3],NULL      ,&idPROVOKE[0]));
    MapInsert(&CmdListe,Option(pPRVK1[0],pPRVK1[1],pPRVK1[2],pPRVK1[3],NULL      ,&idPROVOKE[1]));
    MapInsert(&CmdListe,Option(pRAVOL[0],pRAVOL[1],pRAVOL[2],pRAVOL[3],NULL      ,&doRAGEVOLLEY));
    MapInsert(&CmdListe,Option(pRAKES[0],pRAKES[1],pRAKES[2],pRAKES[3],NULL      ,&doRAKE));
    MapInsert(&CmdListe,Option(pRANGE[0],pRANGE[1],pRANGE[2],pRANGE[3],RangeReset,&doRANGE));
    MapInsert(&CmdListe,Option(pRESUM[0],pRESUM[1],pRESUM[2],pRESUM[3],NULL      ,&doRESUME));
    MapInsert(&CmdListe,Option(pRKICK[0],pRKICK[1],pRKICK[2],pRKICK[3],NULL      ,&doROUNDKICK));
    MapInsert(&CmdListe,Option(pSENSE[0],pSENSE[1],pSENSE[2],pSENSE[3],NULL      ,&doSENSETRAP));
    MapInsert(&CmdListe,Option(pPLUGS[0],pPLUGS[1],pPLUGS[2],pPLUGS[3],NULL      ,&doSKILL));
    MapInsert(&CmdListe,Option(pSLAMS[0],pSLAMS[1],pSLAMS[2],pSLAMS[3],NULL      ,&doSLAM));
    MapInsert(&CmdListe,Option(pSNEAK[0],pSNEAK[1],pSNEAK[2],pSNEAK[3],NULL      ,&doSNEAK));
    MapInsert(&CmdListe,Option(pSTAND[0],pSTAND[1],pSTAND[2],pSTAND[3],NULL      ,&doSTAND));
    MapInsert(&CmdListe,Option(pSTIKR[0],pSTIKR[1],pSTIKR[2],pSTIKR[3],StickReset,&doSTICKRANGE));
    MapInsert(&CmdListe,Option(pSTIKKB[0],pSTIKKB[1],pSTIKKB[2],pSTIKKB[3],StickReset,&doSTICKBREAK));
    MapInsert(&CmdListe,Option(pSTIKNR[0],pSTIKNR[1],pSTIKNR[2],pSTIKNR[3],StickReset,&doSTICKNORANGE));
    MapInsert(&CmdListe,Option(pSTIKD[0],pSTIKD[1],pSTIKD[2],pSTIKD[3],StickReset,&doSTICKDELAY));
    MapInsert(&CmdListe,Option(pSTIKM[0],pSTIKM[1],pSTIKM[2],pSTIKM[3],NULL      ,&doSTICKMODE));
    MapInsert(&CmdListe,Option(pSTRIKM[0],pSTRIKM[1],pSTRIKM[2],pSTRIKM[3],NULL  ,&doSTRIKEMODE));
    MapInsert(&CmdListe,Option(pSTUNS[0],pSTUNS[1],pSTUNS[2],pSTUNS[3],NULL      ,&doSTUNNING));
    MapInsert(&CmdListe,Option(pSTUN0[0],pSTUN0[1],pSTUN0[2],pSTUN0[3],NULL      ,&idSTUN[0]));
    MapInsert(&CmdListe,Option(pSTUN1[0],pSTUN1[1],pSTUN1[2],pSTUN1[3],NULL      ,&idSTUN[1]));
    MapInsert(&CmdListe,Option(pSTRIK[0],pSTRIK[1],pSTRIK[2],pSTRIK[3],NULL      ,&doSTRIKE));
    MapInsert(&CmdListe,Option(pTAUNT[0],pTAUNT[1],pTAUNT[2],pTAUNT[3],NULL      ,&doTAUNT));
    MapInsert(&CmdListe,Option(pTHIEF[0],pTHIEF[1],pTHIEF[2],pTHIEF[3],NULL      ,&doTHIEFEYE));
    MapInsert(&CmdListe,Option(pTHROW[0],pTHROW[1],pTHROW[2],pTHROW[3],NULL      ,&doTHROWSTONE));
    MapInsert(&CmdListe,Option(pTIGER[0],pTIGER[1],pTIGER[2],pTIGER[3],NULL      ,&doTIGERCLAW));
    MapInsert(&CmdListe,Option(pTWIST[0],pTWIST[1],pTWIST[2],pTWIST[3],NULL      ,&doTWISTEDSHANK));
    MapInsert(&CmdListe,Option(pSHIEL[0],pSHIEL[1],pSHIEL[2],pSHIEL[3],NULL      ,&elSHIELD));

    IniListe.clear();
    MapInsert(&IniListe,Option("backstabif"     ,"","","",NULL,&ifBACKSTAB));
    MapInsert(&IniListe,Option("bashif"         ,"","","",NULL,&ifBASH));
    MapInsert(&IniListe,Option("beggingif"      ,"","","",NULL,&ifBEGGING));
    MapInsert(&IniListe,Option("callchallengeif","","","",NULL,&ifCALLCHALLENGE));
    MapInsert(&IniListe,Option("gutpunchif"      ,"","","",NULL,&ifGUTPUNCH));
    MapInsert(&IniListe,Option("opstrikeif"      ,"","","",NULL,&ifOPPORTUNISTICSTRIKE));
    MapInsert(&IniListe,Option("throatjabif"      ,"","","",NULL,&ifTHROATJAB));
    MapInsert(&IniListe,Option("battleleapif"   ,"","","",NULL,&ifBATTLELEAP));
    MapInsert(&IniListe,Option("challengeforif" ,"","","",NULL,&ifCHALLENGEFOR));
    MapInsert(&IniListe,Option("commandingif"   ,"","","",NULL,&ifCOMMANDING));
    MapInsert(&IniListe,Option("cryhavocif"     ,"","","",NULL,&ifCRYHAVOC));
    MapInsert(&IniListe,Option("disarmif"       ,"","","",NULL,&ifDISARM));
    MapInsert(&IniListe,Option("dragonpunchif"  ,"","","",NULL,&ifDRAGONPUNCH));
    MapInsert(&IniListe,Option("eaglestrikeif"  ,"","","",NULL,&ifEAGLESTRIKE));
    MapInsert(&IniListe,Option("evadeif"        ,"","","",NULL,&ifEVADE));
    MapInsert(&IniListe,Option("fallsif"        ,"","","",NULL,&ifFALLS));
    MapInsert(&IniListe,Option("feralswipeif"   ,"","","",NULL,&ifFERALSWIPE));
    MapInsert(&IniListe,Option("fistofwuif"     ,"","","",NULL,&ifFISTSOFWU));
    MapInsert(&IniListe,Option("flyingkickif"   ,"","","",NULL,&ifFLYINGKICK));
    MapInsert(&IniListe,Option("forageif"       ,"","","",NULL,&ifFORAGE));
    MapInsert(&IniListe,Option("frenzyif"       ,"","","",NULL,&ifFRENZY));
    MapInsert(&IniListe,Option("harmtouchif"    ,"","","",NULL,&ifHARMTOUCH));
    MapInsert(&IniListe,Option("pothealfastif"  ,"","","",NULL,&ifPOTHEALFAST));
    MapInsert(&IniListe,Option("pothealoverif"  ,"","","",NULL,&ifPOTHEALOVER));
    MapInsert(&IniListe,Option("hideif"         ,"","","",NULL,&ifHIDE));
    MapInsert(&IniListe,Option("intimidationif" ,"","","",NULL,&ifINTIMIDATION));
    MapInsert(&IniListe,Option("joltif"         ,"","","",NULL,&ifJOLT));
    MapInsert(&IniListe,Option("kickif"         ,"","","",NULL,&ifKICK));
    MapInsert(&IniListe,Option("layhandif"      ,"","","",NULL,&ifLAYHAND));
    MapInsert(&IniListe,Option("leopardclawif"  ,"","","",NULL,&ifLEOPARDCLAW));
    MapInsert(&IniListe,Option("mendif"         ,"","","",NULL,&ifMEND));
    MapInsert(&IniListe,Option("pickpocketif"   ,"","","",NULL,&ifPICKPOCKET));
    MapInsert(&IniListe,Option("provokeif"      ,"","","",NULL,&ifPROVOKE));
    MapInsert(&IniListe,Option("ragevolleyif"   ,"","","",NULL,&ifRAGEVOLLEY));
    MapInsert(&IniListe,Option("rakeif"         ,"","","",NULL,&ifRAKE));
    MapInsert(&IniListe,Option("roundkickif"    ,"","","",NULL,&ifROUNDKICK));
    MapInsert(&IniListe,Option("sensetrapif"    ,"","","",NULL,&ifSENSETRAP));
    MapInsert(&IniListe,Option("slamif"         ,"","","",NULL,&ifSLAM));
    MapInsert(&IniListe,Option("sneakif"        ,"","","",NULL,&ifSNEAK));
    MapInsert(&IniListe,Option("strikeif"       ,"","","",NULL,&ifSTRIKE));
    MapInsert(&IniListe,Option("stunningif"     ,"","","",NULL,&ifSTUNNING));
    MapInsert(&IniListe,Option("tauntif"        ,"","","",NULL,&ifTAUNT));
    MapInsert(&IniListe,Option("thiefeyeif"     ,"","","",NULL,&ifTHIEFEYE));
    MapInsert(&IniListe,Option("throwstoneif"   ,"","","",NULL,&ifTHROWSTONE));
    MapInsert(&IniListe,Option("tigerclawif"    ,"","","",NULL,&ifTIGERCLAW));
    MapInsert(&IniListe,Option("twistedshankif" ,"","","",NULL,&ifTWISTEDSHANK));
    MapInsert(&IniListe,Option("stickcmd"       ,"","","",NULL,&StickCMD));
    MapInsert(&IniListe,Option("strikecmd"      ,"","","",NULL,&StrikeCMD));
    MapInsert(&IniListe,Option("downshit0"      ,"","","",NULL,&DOWNSHIT[0]));
    MapInsert(&IniListe,Option("downshit1"      ,"","","",NULL,&DOWNSHIT[1]));
    MapInsert(&IniListe,Option("downshit2"      ,"","","",NULL,&DOWNSHIT[2]));
    MapInsert(&IniListe,Option("downshit3"      ,"","","",NULL,&DOWNSHIT[3]));
    MapInsert(&IniListe,Option("downshit4"      ,"","","",NULL,&DOWNSHIT[4]));
    MapInsert(&IniListe,Option("downshit5"      ,"","","",NULL,&DOWNSHIT[5]));
    MapInsert(&IniListe,Option("downshit6"      ,"","","",NULL,&DOWNSHIT[6]));
    MapInsert(&IniListe,Option("downshit7"      ,"","","",NULL,&DOWNSHIT[7]));
    MapInsert(&IniListe,Option("downshit8"      ,"","","",NULL,&DOWNSHIT[8]));
    MapInsert(&IniListe,Option("downshit9"      ,"","","",NULL,&DOWNSHIT[9]));
    MapInsert(&IniListe,Option("downshit10"      ,"","","",NULL,&DOWNSHIT[10]));
    MapInsert(&IniListe,Option("downshit11"      ,"","","",NULL,&DOWNSHIT[11]));
    MapInsert(&IniListe,Option("downshit12"      ,"","","",NULL,&DOWNSHIT[12]));
    MapInsert(&IniListe,Option("downshit13"      ,"","","",NULL,&DOWNSHIT[13]));
    MapInsert(&IniListe,Option("downshit14"      ,"","","",NULL,&DOWNSHIT[14]));
    MapInsert(&IniListe,Option("downshit15"      ,"","","",NULL,&DOWNSHIT[15]));
    MapInsert(&IniListe,Option("holyshit0"      ,"","","",NULL,&HOLYSHIT[0]));
    MapInsert(&IniListe,Option("holyshit1"      ,"","","",NULL,&HOLYSHIT[1]));
    MapInsert(&IniListe,Option("holyshit2"      ,"","","",NULL,&HOLYSHIT[2]));
    MapInsert(&IniListe,Option("holyshit3"      ,"","","",NULL,&HOLYSHIT[3]));
    MapInsert(&IniListe,Option("holyshit4"      ,"","","",NULL,&HOLYSHIT[4]));
    MapInsert(&IniListe,Option("holyshit5"      ,"","","",NULL,&HOLYSHIT[5]));
    MapInsert(&IniListe,Option("holyshit6"      ,"","","",NULL,&HOLYSHIT[6]));
    MapInsert(&IniListe,Option("holyshit7"      ,"","","",NULL,&HOLYSHIT[7]));
    MapInsert(&IniListe,Option("holyshit8"      ,"","","",NULL,&HOLYSHIT[8]));
    MapInsert(&IniListe,Option("holyshit9"      ,"","","",NULL,&HOLYSHIT[9]));
    MapInsert(&IniListe,Option("holyshit10"      ,"","","",NULL,&HOLYSHIT[10]));
    MapInsert(&IniListe,Option("holyshit11"      ,"","","",NULL,&HOLYSHIT[11]));
    MapInsert(&IniListe,Option("holyshit12"      ,"","","",NULL,&HOLYSHIT[12]));
    MapInsert(&IniListe,Option("holyshit13"      ,"","","",NULL,&HOLYSHIT[13]));
    MapInsert(&IniListe,Option("holyshit14"      ,"","","",NULL,&HOLYSHIT[14]));
    MapInsert(&IniListe,Option("holyshit15"      ,"","","",NULL,&HOLYSHIT[15]));

    VarListe.clear();
    MapInsert(&VarListe,Option("idleopardclaw"  ,"","","",NULL,&idLEOPARDCLAW));
    MapInsert(&VarListe,Option("idragevolley"   ,"","","",NULL,&idRAGEVOLLEY));
    MapInsert(&VarListe,Option("idbackstab"     ,"","","",NULL,&idBACKSTAB));
    MapInsert(&VarListe,Option("idbash"         ,"","","",NULL,&idBASH));
    MapInsert(&VarListe,Option("idbegging"      ,"","","",NULL,&idBEGGING));
    MapInsert(&VarListe,Option("idcallchallenge","","","",NULL,&idCALLCHALLENGE));
    MapInsert(&VarListe,Option("idgutpunch"      ,"","","",NULL,&idGUTPUNCH));
    MapInsert(&VarListe,Option("idthroatjab"      ,"","","",NULL,&idTHROATJAB));
    MapInsert(&VarListe,Option("idoppstrike"    ,"","","",NULL,&idOPPORTUNISTICSTRIKE));
    MapInsert(&VarListe,Option("idbattleleap"   ,"","","",NULL,&idBATTLELEAP));
    MapInsert(&VarListe,Option("idcommanding"   ,"","","",NULL,&idCOMMANDING));
    MapInsert(&VarListe,Option("idcryhavoc"     ,"","","",NULL,&idCRYHAVOC));
    MapInsert(&VarListe,Option("iddisarm"       ,"","","",NULL,&idDISARM));
    MapInsert(&VarListe,Option("iddragonpunch"  ,"","","",NULL,&idDRAGONPUNCH));
    MapInsert(&VarListe,Option("ideaglestrike"  ,"","","",NULL,&idEAGLESTRIKE));
    MapInsert(&VarListe,Option("idescape"       ,"","","",NULL,&idESCAPE));
    MapInsert(&VarListe,Option("idferalswipe"   ,"","","",NULL,&idFERALSWIPE));
    MapInsert(&VarListe,Option("idfistsofwu"    ,"","","",NULL,&idFISTSOFWU));
    MapInsert(&VarListe,Option("idflyingkick"   ,"","","",NULL,&idFLYINGKICK));
    MapInsert(&VarListe,Option("idforage"       ,"","","",NULL,&idFORAGE));
    MapInsert(&VarListe,Option("idfrenzy"       ,"","","",NULL,&idFRENZY));
    MapInsert(&VarListe,Option("idharmtouch"    ,"","","",NULL,&idHARMTOUCH));
    MapInsert(&VarListe,Option("idhide"         ,"","","",NULL,&idHIDE));
    MapInsert(&VarListe,Option("idintimidation" ,"","","",NULL,&idINTIMIDATION));
    MapInsert(&VarListe,Option("idjolt"         ,"","","",NULL,&idJOLT));
    MapInsert(&VarListe,Option("idkick"         ,"","","",NULL,&idKICK));
    MapInsert(&VarListe,Option("idlayhand"      ,"","","",NULL,&idLAYHAND));
    MapInsert(&VarListe,Option("idmend"         ,"","","",NULL,&idMEND));
    MapInsert(&VarListe,Option("idpickpocket"   ,"","","",NULL,&idPICKPOCKET));
    MapInsert(&VarListe,Option("idrake"         ,"","","",NULL,&idRAKE));
    MapInsert(&VarListe,Option("idroundkick"    ,"","","",NULL,&idROUNDKICK));
    MapInsert(&VarListe,Option("idsensetrap"    ,"","","",NULL,&idSENSETRAP));
    MapInsert(&VarListe,Option("idslam"         ,"","","",NULL,&idSLAM));
    MapInsert(&VarListe,Option("idsneak"        ,"","","",NULL,&idSNEAK));
    MapInsert(&VarListe,Option("idstrike"       ,"","","",NULL,&idSTRIKE));
    MapInsert(&VarListe,Option("idtaunt"        ,"","","",NULL,&idTAUNT));
    MapInsert(&VarListe,Option("idthiefeye"     ,"","","",NULL,&idTHIEFEYE));
    MapInsert(&VarListe,Option("idthrowstone"   ,"","","",NULL,&idTHROWSTONE));
    MapInsert(&VarListe,Option("idtigerclaw"    ,"","","",NULL,&idTIGERCLAW));
    MapInsert(&VarListe,Option("idfeign0"       ,"","","",NULL,&idFEIGN[0]));
    MapInsert(&VarListe,Option("idfeign1"       ,"","","",NULL,&idFEIGN[1]));
    MapInsert(&VarListe,Option("idpetmend"      ,"","","",NULL,&idPETMEND));
    MapInsert(&VarListe,Option("idpothealfast"  ,"","","",NULL,&idPOTHEALFAST));
    MapInsert(&VarListe,Option("idpothealover"  ,"","","",NULL,&idPOTHEALOVER));
    MapInsert(&VarListe,Option("idprovoke0"     ,"","","",NULL,&idPROVOKE[0]));
    MapInsert(&VarListe,Option("idprovoke1"     ,"","","",NULL,&idPROVOKE[1]));
    MapInsert(&VarListe,Option("idstun0"        ,"","","",NULL,&idSTUN[0]));
    MapInsert(&VarListe,Option("idstun1"        ,"","","",NULL,&idSTUN[1]));

    ZeroMemory(ColorArray,sizeof(ColorArray));
    ColorArray[13] =true; // Attack/AutoFire/Enrage/Infuriate
    ColorArray[265]=true; // Hits Target
    ColorArray[267]=true; // Miss Target
    ColorArray[266]=true; // Hits me
    ColorArray[268]=true; // Miss me
    ColorArray[270]=true; // Failed Hide/Sneak
    ColorArray[273]=true; // Failed FD????
    ColorArray[288]=true; // Target begin to cast
    ColorArray[289]=true; // Spells results, broken fd
    ColorArray[306]=true; // NPC Enrage/Infuriate
    ColorArray[328]=true; // Pet Hits Target
    ColorArray[337]=true; // Pet Messages

    ZeroMemory(AttackArray,sizeof(AttackArray));
    AttackArray[0]=true;
    AttackArray[1]=true;
    AttackArray[2]=true;
    AttackArray[3]=true;
    AttackArray[4]=true;
    AttackArray[5]=true;      // hit with main hand
    AttackArray[6]=true;
    AttackArray[7]=true;
    AttackArray[8]=true;      // punch
    AttackArray[9]=true;
    AttackArray[10]=true;
    AttackArray[11]=true;
    AttackArray[12]=true;     // hit with offhand
    AttackArray[42]=true;     // casting type 1
    AttackArray[43]=true;     // casting type 2
    AttackArray[44]=true;     // casting type 3
    AttackArray[80]=true;     // attacking
    AttackArray[129]=true;    // attacking
    AttackArray[144]=true;    // attacking

    ZeroMemory(IdlingArray,sizeof(IdlingArray));
    IdlingArray[26]=true;     // mezzed maybe?
    IdlingArray[32]=true;     // sitting
    IdlingArray[71]=true;     // standing after sitting
    IdlingArray[110]=true;    // standing still

    SaveIndx=0;
    pMeleeEvent=new Blech('#');
    ZeroMemory(SaveList,sizeof(SaveList));
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("Auto fire off#*#"                                                     ,AUTOFIREOFF  ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("Auto fire on#*#"                                                      ,AUTOFIREON   ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#Attacking #*# Master.#*#"                                          ,PETATTK      ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#Sorry#*#calming down.#*#"                                          ,PETBACK      ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#Waiting for your order to attack, Master.#*#"                      ,PETHOLD      ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#Now Holding#*#I will not attack until ordered.#*#"                 ,PETHOLD      ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*# begins casting a spell#*#"                                        ,CASTING      ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*# begins to cast#*#"                                                ,CASTING      ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*# has become ENRAGED#*#"                                            ,ENRAGEON     ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*# is no longer enraged#*#"                                          ,ENRAGEOFF    ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*# is infuriated#*#"                                                 ,INFURIATEON  ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*# no longer infuriated#*#"                                          ,INFURIATEOFF ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*# has fallen to the ground#*#"                                      ,FALLEN       ,(void *)1);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#You are no longer feigning death#*#"                               ,BROKEN       ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#Your body aches from a wave of pain#*#"                            ,BROKEN       ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#The strength of your will allows you to resume feigning death#*#"  ,RESUME       ,(void *)0);

    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#You failed to hide yourself#*#"                                    ,HIDEOFF      ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#You stop hiding#*#"                                                ,HIDEOFF      ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#You have moved and are no longer hidden#*#"                        ,HIDEOFF      ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#You have hidden yourself from view#*#"                             ,HIDEON       ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#You are as quiet as a herd of running elephants#*#"                ,SNEAKOFF     ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#You stop sneaking#*#"                                              ,SNEAKOFF     ,(void *)0);
    SaveList[SaveIndx++]=pMeleeEvent->AddEvent("#*#You are as quiet as a cat stalking its prey#*#"                    ,SNEAKON      ,(void *)0);

    pMeleeTypes= new MQ2MeleeType;
    AddMQ2Data("Melee",DataMelee);
    AddMQ2Data("meleemvb",datameleemvb);
    AddMQ2Data("meleemvi",datameleemvi);
    AddMQ2Data("meleemvs",datameleemvs);
    AddCommand("/EnrageON",EnrageON);
    AddCommand("/EnrageOFF",EnrageOFF);
    AddCommand("/InfuriateON",InfuriateON);
    AddCommand("/InfuriateOFF",InfuriateOFF);
    AddCommand("/KillThis",KillThis);
    AddCommand("/Melee",Melee);
    AddCommand("/ThrowIt",ThrowIT);

    bMULoaded = HandleMoveUtils();
}

PLUGIN_API VOID SetGameState(DWORD GameState)
{
    Bindding(GameState==GAMESTATE_INGAME);
    if(GameState==GAMESTATE_INGAME)
    {
        if(!Loaded)
        {
            Configure();
            DebugSpew("MQ2Melee SetGameState GAMESTATE_INGAME & NOT LOADED, calling Configure()");
        }
        else
        {
            DebugSpew("MQ2Melee SetGameState GAMESTATE_INGAME & LOADED=true, not calling anything");
        }
    }
    else if(GameState!=GAMESTATE_LOGGINGIN)
    {
        if(Loaded)
        {
            DebugSpew("MQ2Melee SetGameState not INGAME or LOGGINGIN & LOADED=true, setting LOADED false");
            Loaded=false;
        }
        else
        {
            DebugSpew("MQ2Melee SetGameState not INGAME and *is* LOGGINGIN, not changing loaded");
        }
    }
    DebugSpew("MQ2Melee SetGameState Loaded == %s", Loaded ? "true" : "false");
}

PLUGIN_API DWORD OnIncomingChat(PCHAR Line, DWORD Color) {
    if(ColorArray[Color & 0x1FF] && doSKILL && gbInZone && pMeleeEvent) switch(Color) {
    case 265: SwingHits++; break;
    case 267: SwingHits++; break;
    case 266: TakenHits++; break;
    case 268: TakenHits++; break;
    default : pMeleeEvent->Feed(Line);
    }
    return 0;
}

PLUGIN_API void OnPulse(void)
{
    if (doSKILL && Loaded && gbInZone && SpawnMe())
    {
        if (PCHARINFO2 Me = GetCharInfo2())
        {
            if (GetCharInfo2()->Shrouded != Shrouded)
            {
                SetGameState(GAMESTATE_UNLOADING);
                SetGameState(GAMESTATE_INGAME);
            }
            if (!HiddenTimer && IsInvisible()) HiddenTimer=(DWORD)clock();
            if (!SilentTimer && IsSneaking()) SilentTimer=(DWORD)clock();
            Travel = SpeedRun(SpawnMe());
            if (Moving=(Travel>0.05 || Travel<-0.05)) TimerMove=(DWORD)clock()+delay*5;
            Immobile = (!(MQ2Globals::gbMoving) && (!TimerMove || (DWORD)clock()>TimerMove));
            if (doPETASSIST)
            {
                if (PSPAWNINFO Pet=SpawnPet())
                {
                    if (AttackArray[Pet->Animation & 0xFF]) PetSEEN();
                    else if (!PetOnHold && (DWORD)clock() > PetOnAttk && IdlingArray[Pet->Animation & 0xFF]) PetBACK();
                }
            }
            if (MeleeTarg && (!pTarget || MeleeType != SpawnMask(GetSpawnID(MeleeTarg)))) Override(NULL, "");
            if ((DWORD)clock() > MeleeTime)
            {
                MeleeTime = (DWORD)clock() + delay;
                MeleeHandle();
            }
        }
    }
    if ((bMULoaded && !bMUPointers) || (bMUPointers && !bMULoaded))
    {
        bMULoaded = HandleMoveUtils();
    }
}

PLUGIN_API VOID ShutdownPlugin()
{
    SetGameState(GAMESTATE_UNLOADING);

    RemoveCommand("/EnrageON");
    RemoveCommand("/EnrageOFF");
    RemoveCommand("/InfuriateON");
    RemoveCommand("/InfuriateOFF");
    RemoveCommand("/KillThis");
    RemoveCommand("/Melee");
    RemoveCommand("/ThrowIt");

    RemoveMQ2Data("Melee");
    RemoveMQ2Data("meleemvs");
    RemoveMQ2Data("meleemvi");
    RemoveMQ2Data("meleemvb");

    pMeleeEvent->Reset();
    delete pMeleeEvent;
    delete pMeleeTypes;

    Bindding(false);
}
