• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Memory hack

Level 19
Joined
Dec 12, 2010
Messages
2,069
Memory hack, basement and basic functions by @leandrotp
Extended API by DracoL1ch
Memory hooks, DLL, direct function calls by Karaul0v


What is it?
An innate WC3 tool which allows to access any data within user's PC. You can read and write any memory you want, except when it comes to inner Windows protection systems (ProcessLock, UDP, low level of access etc). Basically you can act like WC3 itself, reading and writing data as normal game does.

Why is it needed?
You can extend your map far beyond WC3 possibilities. Use any low-level function of game which is unaccessible from JASS without having to waste your time imitating it. You're working with a low-level memory language, so it's still diffucult but worthy.

What about security?
Sure you can write viruses basing on this. Heck, you were able to do so long ago, like Preload never been fixed since 2008 or w/e it comes. Thing is, atomic energy are also destructive, yet humanity somehow managed to make it most healthy way to get energy, so you can actually access this page right now via your PC, which is also mostly based on military researches. Everything has 2 sides.

From your side you can notify users about this hack, remind them about possible danger of playing unknown, non-official maps, or maps downloaded from different sources. That's best you can do. Rest is up to players.

What about cons?
This thing isn't OS-based, yet due to different approaches it may, and mostly, won't run on non-Windows systems. We had no Linux/Mac writes anyway, and there's literally less than 10 players from those systems. Yet you risk to lose those guys. All of these been tested on Windows 7 x64 & x86, windows 10 runs it as well, rest are unknown.

Declared code isn't supposed to work from within WC3 Map Editor. We did write it on plain txt files and put inside the maps with MPQEditor to check things out. Editor uses optimizations which may hurt it. If you really wanna to use it look for proper PJass and add proper syntax markers to get over any errors info.

You need at least good JASS skills in order to understand what happens and how to work with memory. You can't do it with GUI or so. That's really advanced level which is totally unfriendly for now.

This bug will be fixed with next official patch. Thing is - do you really care about updating? If yes, then you can close this tab right now. We don't need to hear another wave of messages "this is dangerous and should be fixed, you shouldn't spread it". Nobody else but fans made WC3 live long life till today, so we will carry this tradition. Blizzard did nothing to boost mapmaking back those years, so I can see no signs they will do that next years. Audience is dropping fast enough, game isn't money-making, so it's dead end. If your map really worth it people will stay with 1.26 or 1.27 versions (only 2 are supported for now, you can add support for other versions as well if you wanna to).

So, if you wanna carry this on, lets start

Init()
Whole project can be found at GitHub. You can improve or add commentary or make editor-friendly branch if you want to. Feel free to update outdated parts if you need or add new functions to get another data we didn't need to use (there's a lot of fields, duh).

GitHub contains ChekSynt.bat which runs PJass to check script. Note that default (correct) result of this check is:
guide10.png


It contains 11 errors, which is normal. Any others is your fault.

We also use some AI functions as a door to WC3 bytecode compilator, note that.

Whole script (as for 1st of November 2016):
JASS:
// reserved native for call 4 integer function and return BOOLEAN value
native MergeUnits          takes integer qty, integer a, integer b, integer make returns boolean
// reserved native for call 2 integer function and return BOOLEAN value (can be converted to int!)
native ConvertUnits         takes integer qty, integer id               returns boolean
// reserved native for call 1 integer function and return integer value
native IgnoredUnits        takes integer unitid                        returns integer

// https://github.com/Karaulov/WarcraftIII_DLL_126-xxx (EXTRADLLNAME)
// DLL is helpful ally which makes game easire
// Basically there's no jass-way to detect whenever player leaves to rollback changes
// so DLL does it for you with "AddNewOffsetToRestore" function
// if DLL is missing global changes you did will affect whole game until it's restarted
// You can detect function which uses DLL by "GetModuleProcAddress(EXTRADLLNAME" part inside of them\

globals
    integer TempInteger=0
    integer Temp_GetSomeAdd1=0
    integer Temp_GetSomeAdd2=0
    integer DamageIncrementer=0
    real array DamageValues
    integer array DamageAttackTypes
    integer array DamageDamageTypes
    player LocalPlayer=null
    hashtable TempHash=InitHashtable()
    hashtable RectData = InitHashtable()
    hashtable HY=InitHashtable()
    boolean IsL1ch=true//used in "echo" function to display debug messages
 
    boolean array WidescreenState
    real GJ_LastDmg=0//outdated yet could be useful
    integer GJ_LastDamageType=0
    integer GJ_LastAttackType=0
 
    hashtable ObjectDataPointersTable=InitHashtable()
 
    timer SuperTextPrinter_Timer=null
    hashtable AbilitiesHashtable=InitHashtable()
 
    integer testFunctionCount = 0
    integer latestAddress1 = 0
    integer latestAddress2 = 0

    integer array Ascii__Ints
    string array Ascii__Chars
 
    code l__Code
    integer l__Int
    string l__Str
    boolean l__Bool
 
    constant string dotaconfigfle="config.dota"
 
    integer array l__Array
 
    string array HexNumber__Chars
 
    integer bytecode
    integer array l__bytecode
    integer array Memory
    integer bytecodedata //used to pass data between regular code and bytecode
    integer GameState
    integer pointers
    integer pUnitData
    integer pAbilityData
 
    constant gametype GAME_TYPE_ALL= ConvertGameType(0xFFFFFFFF)
 
    integer array H
    trigger l__library_init
 
 
    // For SetUnitFlags_2 (unit+0x20)
    constant integer UNIT_VISIBLED_TO_ALL         = 0x10
    constant integer UNIT_INVULNERABLE             = 0x8
    constant integer UNIT_SELECTABLE             = 0x2
    constant integer UNIT_HIDDEN                 = 0x1
    constant integer UNIT_AUTOATTACK_DISABLED=0x10000000
    constant integer UNIT_ILLUSION=0x40000000
 
    // For SetUnitFlags (unit+0xD4)
    //flag 0x4 causes fatal if any damage received
    //flag 0x40 stands for red flash, but doesn't directly calls it
    constant integer UNIT_DEAD = 0x100
    //like dead hero, provides no vision, cant be selected, enemies doesn't flee when attacked by unit with this flag
    constant integer UNIT_MINMAP_ICON_HIDE        = 0x80000
    constant integer UNIT_MINMAP_ICON_TAVERN    = 0x40000
    constant integer UNIT_MINMAP_ICON_GOLD        = 0x20000
    constant integer UNIT_MINMAP_SHAREVISIBLE    = 0x10000
    constant integer UNIT_STUNNED= 0x100000
    constant integer UNIT_INVISIBLED             = 0x1000000
    constant integer UNIT_HAS_FLYING_VISION= 0x20000000
 
    integer pCameraDefaultHeight
    real array DefaultCameraHeight
 
    // 126a 0xAB65F4
    // 127a 0xBE4238
    integer pGlobalPlayerClass
 
    // 127a 0xBEC464
    // 126a 0xAB4450
    integer pUnitMaxSpeedConstant
    integer pUnitMaxSpeedConstantD

    real     UnitMaxSpeedConstant
    // 127a 0xBEC460
    // 126a 0xAB444C
    integer pUnitMinSpeedConstant
    integer pUnitMinSpeedConstantD

    real     UnitMinSpeedConstant
    // 127a 0xBEC46C
    // 126a 0xAB4458
    integer pBuildingMaxSpeedConstant
    integer pBuildingMaxSpeedConstantD

    real    BuildingMaxSpeedConstant
    // 127a 0xBEC468
    // 126a 0xAB4454
    integer pBuildingMinSpeedConstant
    integer pBuildingMinSpeedConstantD

    real     BuildingMinSpeedConstant
    integer pUnitUIDefAddr
    integer pUnitDataDefAddr
    integer pAbilityUIDefAddr
    integer pAbilityDataDefAddr
 
    integer pAttackSpeedLimit
    real    AttackSpeedLimit
 
    integer pAttackTimeLimit
    real    AttackTimeLimit
 
    integer pWar3MapJLocation=0

 
    integer pGameClass1=0
    integer pGameClass2=0
    integer pGameClass3=0
    integer pTimerAddr=0
    integer pCGameState=0
 
    integer pJassEnvAddress=0
 
    integer pLightEnv=0
 
    integer pGetModuleHandle=0
    integer pGetProcAddress=0
 
    integer GameDLL=0
    integer GameVersion=0
 
    integer pMergeUnits=0
    integer pMergeUnitsOffset=0
    integer pIgnoredUnits=0
    integer pIgnoredUnitsOffset=0
    integer pConvertUnits=0
    integer pConvertUnitsOffset=0
    integer pLeaderboardSetItemLabelColor=0
 
    integer pSetHPBarColorForPlayer=0
    integer pSetHPBarXScaleForPlayer=0
    integer pSetHPBarYScaleForPlayer=0
 
    integer pSetHPCustomHPBarUnit=0
 
 
    integer pSetMPBarXScaleForPlayer=0
    integer pSetMPBarYScaleForPlayer=0
    integer pSetMPBarYOffsetForPlayer=0
 
 
    integer pExportFromMpq=0
    integer pGetFrameItemAddress=0
    integer pGetFrameSkinAddress=0
    integer pGetFrameTextAddress=0
    integer pUpdateFrameText=0
 
    integer pFrameDefClass=0
    integer pConvertString=0
    integer pPacketClass=0
    integer pPacketSend=0
 
 
    integer pPingMinimapOffset=0
    integer pPingMinimapExOffset=0
 
    integer PingMinimapUnlocker = 0
    integer PingMinimapExUnlocker = 0
    boolean NotLockedPingMinimap = true
    boolean NotLockedPingMinimapEx = true
 
    integer pFindWindowA=0
    integer pMessageBoxA=0
    integer pGetAsyncKeyState=0
    integer pWritePrivateProfileStringA=0
    integer pGetPrivateProfileStringA=0
    integer pLoadLibraryA=0
    integer pGetFileAttributesA=0
    integer pVirtualAlloc=0
    integer pVirtualProtect=0
 
    integer array RJassNativesBuffer
    integer RJassNativesBufferSize = 0
 
 
    integer pReservedExecutableMemory=0
    integer pReservedExecutableMemory2=0
    integer pBitwiseOR_ExecutableMemory
    boolean NeedInitBitwiseOr = true
    integer pBitwiseXOR_ExecutableMemory
    boolean NeedInitBitwiseXor = true
    integer pBitwiseAND_ExecutableMemory
    boolean NeedInitBitwiseAnd = true
 
    integer pReservedWritableMemory
    integer pReservedWritableMemory2
 
    constant integer szReservedWritableMemory = 3000
 
    integer pStorm279
    integer pPrintText1
    integer pPrintText2
    integer pPrintText3
    integer pGetUnitAbility
    integer pGetUnitAddress
    integer p_sprintf
    integer pChangeFont
 
    integer pUpdateRestoreTimer=0
    integer pAddNewOffsetToRestore=0
    constant string EXTRADLLNAME="DotAAllstarsHelper688.dll"

    integer pReserverdIntArg1
    integer pReserverdIntArg2
    integer pReserverdIntArg3
    integer pReserverdIntArg4
    hashtable Addresses=InitHashtable()
    constant integer DEF_ADR_ABILITY_DATA=0
    constant integer DEF_ADR_ABILITY_UI=1
    constant integer DEF_ADR_UNIT_DATA=2
    constant integer DEF_ADR_UNIT_UI=3
    constant integer DEF_ADR_ITEM_DATA=4
    constant integer ILLUSTION_BONUS_DAMAGE_RECEIVES=0
    constant integer ILLUSTION_BONUS_DAMAGE_DEALS=1
 
    integer pOrder1_offset
    integer pOrder2_offset
    integer pOrder3_offset
    integer pOrder4_offset
    integer pOrder5_offset
    integer pOrder6_offset
    integer pOrder7_offset
    integer pOrder8_offset
    integer Order1_unlockedvalue = 0
    integer Order2_unlockedvalue = 0
    integer Order3_unlockedvalue = 0
    integer Order4_unlockedvalue = 0
    integer Order5_unlockedvalue = 0
    integer Order6_unlockedvalue = 0
    integer Order7_unlockedvalue = 0
    integer Order8_unlockedvalue = 0
    integer Order1_lockedvalue
    integer Order2_lockedvalue
    integer Order3_lockedvalue
    integer Order4_lockedvalue
    integer Order5_lockedvalue
    integer Order6_lockedvalue
    integer Order7_lockedvalue
    integer Order8_lockedvalue
    boolean IsOrder1Locked = false
    boolean IsOrder2Locked = false
    boolean IsOrder3Locked = false
    boolean IsOrder4Locked = false
    boolean IsOrder5Locked = false
    boolean IsOrder6Locked = false
    boolean IsOrder7Locked = false
    boolean IsOrder8Locked = false
 
    boolean FogUpdateBlocked = false
    integer pUpdateFogManual=0
    integer pFogUpdateBlockAddr=0
    integer pFogUpdateBlockAddrOld1=0
    integer pFogUpdateBlockAddrOld2=0
    integer pFogUpdateBlockAddrNew1=0
    integer pFogUpdateBlockAddrNew2=0
 
    integer pGetLatestDownloadedString = 0
    integer pGetDownloadStatus = 0
    integer pSaveNewMapFromUrl = 0
    integer pGetDownloadProgress = 0
    integer pGetCurrentMapDir = 0
 
    integer pStartAbilityCD=0
 
    integer pSendCommandWithoutTarget
    integer pMissile
    integer pWindowIsActive
    integer pSendHttpGetRequest = 0
    integer pAllianceOutput
    integer AllianceLocker = 0
    boolean NotLockedAllianceOutput = true
 
    integer pMutePlayer=0
    integer pUnMutePlayer=0
 
    integer pSetWidescreenFixState=0
    integer pSetCustomFovFix=0
 
    boolean EXTRADLLLOADED = false
 
    integer RegionEditMode = 0
    real LatestMouseX = 0.
    real LatestMouseY = 0.
    integer LatestSelectRect = 0
    integer LatestOverRect = 0
 
 
    integer gl_hRectID = 0
 
    integer OPLimitAddress1=0
    integer OPLimitAddress2=0
    integer pCycloneFixCondition=0
    constant integer CycloneFixCondition026a=0x808B08EB
    integer CycloneFixBaseValue=0
    constant integer CycloneFixCondition027a=0x458B16EB
    integer pCaptionsOverTheCreeps=0
    integer pPhaseShiftInvisibilityFlagByte=0
    constant integer PhaseShiftInvisibilityFlagByteFixed0x26=0x00000060
    constant integer PhaseShiftInvisibilityFlagByteFixed0x27=0x00000060
 
    integer pMemcpy
    integer pSearchStringValue
    integer pSearchStringAddr1
    integer pSearchStringAddr2
 
    integer pReservedMemoryForUpdateFrameText
 
    integer pSimulateAttackInstance
    integer pGameTime
 
    integer pToggleForcedSubSelection=0
    integer pToggleBlockKeyAndMouseEmulation=0
    integer pToggleClickHelper=0
 
    integer pSetStunToUnitTRUE
    integer    pSetStunToUnitFALSE
 
    integer pReservedMemoryForSystemTime
    integer pGetLocalTime=0
 
    integer pCommonSilence
    integer pAddSilenceOnAbility
    integer pRemoveSilenceFromAbility
    integer pPauseUnitDisabler
 
    integer pUpdateUnitsSpeedCurrent
 
    integer pSendMessageToChat=0
 
    integer pCastSilenceToTarget
    integer pCastAbility=0
 
    integer pDamageBlockIllusionCheck=0
 
    integer pItemDropOrderTriggerFix=0
 
    integer pFixModelCollisionSphere=0
 
    integer pGetOrLoadFile
    integer pApplyTerrainFilterDirectly=0
    integer pSetMainFuncWork=0
    integer pFixModelTexturePath=0
 
    integer StoreIntegerOffset = 0
    integer StoreIntegerUnlocker = 0
    boolean StoreIntegerLocked = false
 
    integer pPatchModel = 0
    integer pChangeAnimationSpeed = 0
    integer pSetSequenceValue = 0
    integer pRedirectFile = 0
    integer pReservedMemoryForMissileHandler=0
    integer pReservedMemoryForDamageHandler=0
    integer pUnitVtable = 0
    integer pRealUnitDamageHandler = 0
    integer pTriggerExecute = 0
    integer pDamageTarget = 0
    integer pMissileEspData = 0
    integer pDamageEspData = 0
    integer pMissileFuncStart = 0
    integer pMissileJumpBack = 0
    integer pItemDataNode=0
    integer pJassLog = 0
endglobals

function Char2Ascii takes string s returns integer
    local integer i= Ascii__Ints[StringHash(s) / 0x1F0748 + 0x3EA]
    if i == 47 and s == "\\" then
        set i=92
    elseif i >= 65 and i <= 90 and s != Ascii__Chars[i] then
        set i=i + 32
    endif
    return i
endfunction

function Char2Hex takes string s returns integer
    local integer i= Ascii__Ints[StringHash(s) / 0x1F0748 + 0x3EA]
    if i >= 48 and i <= 57 then
        return i - 48
    elseif i >= 65 and i <= 70 then
        return i - 55
    endif
    return - 1
endfunction

function Ascii2Char takes integer i returns string
    return Ascii__Chars[i]
endfunction

function Ascii__onInit takes nothing returns nothing
    set Ascii__Ints[931]=8
    set Ascii__Ints[1075]=9
    set Ascii__Ints[1586]=10
    set Ascii__Ints[1340]=12
    set Ascii__Ints[412]=13
    set Ascii__Ints[198]=32
    set Ascii__Ints[1979]=33
    set Ascii__Ints[1313]=34
    set Ascii__Ints[1003]=35
    set Ascii__Ints[1264]=36
    set Ascii__Ints[983]=37
    set Ascii__Ints[1277]=38
    set Ascii__Ints[306]=39
    set Ascii__Ints[904]=40
    set Ascii__Ints[934]=41
    set Ascii__Ints[917]=42
    set Ascii__Ints[1972]=43
    set Ascii__Ints[1380]=44
    set Ascii__Ints[1985]=45
    set Ascii__Ints[869]=46
    set Ascii__Ints[1906]=47
    set Ascii__Ints[883]=48
    set Ascii__Ints[1558]=49
    set Ascii__Ints[684]=50
    set Ascii__Ints[582]=51
    set Ascii__Ints[668]=52
    set Ascii__Ints[538]=53
    set Ascii__Ints[672]=54
    set Ascii__Ints[1173]=55
    set Ascii__Ints[71]=56
    set Ascii__Ints[277]=57
    set Ascii__Ints[89]=58
    set Ascii__Ints[1141]=59
    set Ascii__Ints[39]=60
    set Ascii__Ints[1171]=61
    set Ascii__Ints[51]=62
    set Ascii__Ints[305]=0 //fixme 63
    set Ascii__Ints[0]=64
    set Ascii__Ints[222]=65
    set Ascii__Ints[178]=66
    set Ascii__Ints[236]=67
    set Ascii__Ints[184]=68
    set Ascii__Ints[1295]=69
    set Ascii__Ints[1390]=70
    set Ascii__Ints[1276]=71
    set Ascii__Ints[203]=72
    set Ascii__Ints[1314]=73
    set Ascii__Ints[209]=74
    set Ascii__Ints[1315]=75
    set Ascii__Ints[170]=76
    set Ascii__Ints[1357]=77
    set Ascii__Ints[1343]=78
    set Ascii__Ints[1397]=79
    set Ascii__Ints[1420]=80
    set Ascii__Ints[1419]=81
    set Ascii__Ints[1396]=82
    set Ascii__Ints[1374]=83
    set Ascii__Ints[1407]=84
    set Ascii__Ints[499]=85
    set Ascii__Ints[1465]=86
    set Ascii__Ints[736]=87
    set Ascii__Ints[289]=88
    set Ascii__Ints[986]=89
    set Ascii__Ints[38]=90
    set Ascii__Ints[1230]=91
    set Ascii__Ints[1636]=93
    set Ascii__Ints[1416]=94
    set Ascii__Ints[1917]=95
    set Ascii__Ints[217]=96
    set Ascii__Ints[833]=123
    set Ascii__Ints[1219]=124
    set Ascii__Ints[553]=125
    set Ascii__Ints[58]=126
 
    set Ascii__Chars[0]="?"
    set Ascii__Chars[8]="\b"
    set Ascii__Chars[9]="\t"
    set Ascii__Chars[10]="\n"
    set Ascii__Chars[12]="\f"
    set Ascii__Chars[13]="\r"
    set Ascii__Chars[32]=" "
    set Ascii__Chars[33]="!"
    set Ascii__Chars[34]="\""
    set Ascii__Chars[35]="#"
    set Ascii__Chars[36]="$"
    set Ascii__Chars[37]="%"
    set Ascii__Chars[38]="&"
    set Ascii__Chars[39]="'"//'
    set Ascii__Chars[40]="("
    set Ascii__Chars[41]=")"
    set Ascii__Chars[42]="*"
    set Ascii__Chars[43]="+"
    set Ascii__Chars[44]=","
    set Ascii__Chars[45]="-"
    set Ascii__Chars[46]="."
    set Ascii__Chars[47]="/"
    set Ascii__Chars[48]="0"
    set Ascii__Chars[49]="1"
    set Ascii__Chars[50]="2"
    set Ascii__Chars[51]="3"
    set Ascii__Chars[52]="4"
    set Ascii__Chars[53]="5"
    set Ascii__Chars[54]="6"
    set Ascii__Chars[55]="7"
    set Ascii__Chars[56]="8"
    set Ascii__Chars[57]="9"
    set Ascii__Chars[58]=":"
    set Ascii__Chars[59]=";"
    set Ascii__Chars[60]="<"
    set Ascii__Chars[61]="="
    set Ascii__Chars[62]=">"
    set Ascii__Chars[63]="?"
    set Ascii__Chars[64]="@"
    set Ascii__Chars[65]="A"
    set Ascii__Chars[66]="B"
    set Ascii__Chars[67]="C"
    set Ascii__Chars[68]="D"
    set Ascii__Chars[69]="E"
    set Ascii__Chars[70]="F"
    set Ascii__Chars[71]="G"
    set Ascii__Chars[72]="H"
    set Ascii__Chars[73]="I"
    set Ascii__Chars[74]="J"
    set Ascii__Chars[75]="K"
    set Ascii__Chars[76]="L"
    set Ascii__Chars[77]="M"
    set Ascii__Chars[78]="N"
    set Ascii__Chars[79]="O"
    set Ascii__Chars[80]="P"
    set Ascii__Chars[81]="Q"
    set Ascii__Chars[82]="R"
    set Ascii__Chars[83]="S"
    set Ascii__Chars[84]="T"
    set Ascii__Chars[85]="U"
    set Ascii__Chars[86]="V"
    set Ascii__Chars[87]="W"
    set Ascii__Chars[88]="X"
    set Ascii__Chars[89]="Y"
    set Ascii__Chars[90]="Z"
    set Ascii__Chars[91]="["
    set Ascii__Chars[92]="\\"
    set Ascii__Chars[93]="]"
    set Ascii__Chars[94]="^"
    set Ascii__Chars[95]="_"
    set Ascii__Chars[96]="`"
    set Ascii__Chars[97]="a"
    set Ascii__Chars[98]="b"
    set Ascii__Chars[99]="c"
    set Ascii__Chars[100]="d"
    set Ascii__Chars[101]="e"
    set Ascii__Chars[102]="f"
    set Ascii__Chars[103]="g"
    set Ascii__Chars[104]="h"
    set Ascii__Chars[105]="i"
    set Ascii__Chars[106]="j"
    set Ascii__Chars[107]="k"
    set Ascii__Chars[108]="l"
    set Ascii__Chars[109]="m"
    set Ascii__Chars[110]="n"
    set Ascii__Chars[111]="o"
    set Ascii__Chars[112]="p"
    set Ascii__Chars[113]="q"
    set Ascii__Chars[114]="r"
    set Ascii__Chars[115]="s"
    set Ascii__Chars[116]="t"
    set Ascii__Chars[117]="u"
    set Ascii__Chars[118]="v"
    set Ascii__Chars[119]="w"
    set Ascii__Chars[120]="x"
    set Ascii__Chars[121]="y"
    set Ascii__Chars[122]="z"
    set Ascii__Chars[123]="{"
    set Ascii__Chars[124]="|"
    set Ascii__Chars[125]="}"
    set Ascii__Chars[126]="~"
endfunction


//library Ascii ends
//library Typecast:


function InitArray takes integer vtable returns nothing
    set l__Array[4] = 0
    set l__Array[1] = vtable
    set l__Array[2] = -1
    set l__Array[3] = -1
endfunction

function TypecastArray takes nothing returns nothing
    local integer l__Array //typecast Array to integer
endfunction

function GetArrayAddress takes nothing returns integer //not really needed
    loop
        return l__Array
    endloop
    return 0
endfunction

function setCode takes code c returns nothing
    set l__Code=c
    return //Prevents Jasshelper from inlining this function
endfunction

function setInt takes integer i returns nothing
    set l__Int=i
    return //Prevents JassHelper from inlining this function
endfunction

function setStr takes string s returns nothing
    set l__Str = s
    return //Prevents JassHelper from inlining this function
endfunction

function setBool takes boolean b returns nothing
    set l__Bool = b
    return
endfunction

function Typecast1 takes nothing returns nothing
    local integer l__Code
    local code l__Int
endfunction

function C2I takes code c returns integer
    call setCode(c)
    loop //Loop is not required, I'm using it just to fool Pjass
        return l__Code
    endloop
    return 0
endfunction

function I2C takes integer i returns code
    call setInt(i)
    loop //Loop is not required, I'm using it just to fool Pjass
        return l__Int
    endloop
    return null
endfunction

function Typecast2 takes nothing returns nothing
    local integer l__Str
    local string l__Int
endfunction

function SH2I takes string s returns integer
    call setStr(s)
    loop //Loop is not required, I'm using it just to fool Pjass
              return l__Str
    endloop
    return 0
endfunction

function I2SH takes integer i returns string
    call setInt(i)
    loop //Loop is not required, I'm using it just to fool Pjass
              return l__Int
    endloop
    return null
endfunction

function Typecast3 takes nothing returns nothing
    local integer l__Bool
    local boolean l__Int
endfunction

function B2I takes boolean b returns integer
    call setBool(b)
    loop //Loop is not required, I'm using it just to fool Pjass
          return l__Bool
    endloop
    return 0
endfunction

function I2B takes integer i returns boolean
    call setInt(i)
    loop //Loop is not required, I'm using it just to fool Pjass
            return l__Int
    endloop
    return false
endfunction

    function realToIndex takes real r returns integer
        loop
            return r
        endloop
        return 0
    endfunction

    function cleanInt takes integer i returns integer
        return i
    endfunction

    function indexToReal takes integer i returns real
        loop
            return i
        endloop
        return 0.0
    endfunction

    function cleanReal takes real r returns real
        return r
    endfunction

function GetRealFromMemory takes integer i returns real
    return cleanReal(indexToReal(i))
endfunction

function SetRealIntoMemory takes real r returns integer
    return cleanInt(realToIndex(r))
endfunction

//library Typecast ends
//library HexNumber:

function BitwiseNot takes integer i returns integer
    return 0xFFFFFFFF - i
endfunction

function PowI takes integer x, integer power returns integer
    local integer res=1
    local integer y=x
    if power==0 then
        return 1
    endif
    set power=power-1
    loop
        set x=x*y
        set power=power-1
        exitwhen power==0
    endloop
    return x
endfunction


function ShiftLeftForBits takes integer i, integer shiftval returns integer
    return i * (PowI(2,shiftval))
endfunction

function ShiftRightForBits takes integer i, integer shiftval returns integer
    return i / (PowI(2,shiftval))
endfunction

function ShiftLeftForBytes takes integer i, integer shiftval returns integer
    return ShiftLeftForBits(i,shiftval * 8)
endfunction

function ShiftRightForBytes takes integer i, integer shiftval returns integer
    return ShiftRightForBits(i,shiftval * 8)
endfunction



function GetByteFromInteger takes integer i, integer byteid returns integer
    local integer tmpval = i
    local integer retval = 0
    local integer byte1 = 0
    local integer byte2 = 0
    local integer byte3 = 0
    local integer byte4 = 0
    if (tmpval < 0) then
        set tmpval = BitwiseNot(tmpval)
        set byte4 = 255 - ModuloInteger(tmpval,256)
        set tmpval = tmpval / 256
        set byte3 = 255 - ModuloInteger(tmpval,256)
        set tmpval = tmpval / 256
        set byte2 = 255 - ModuloInteger(tmpval,256)
        set tmpval = tmpval / 256
        set byte1 = 255 - tmpval
    else
        set byte4 =  ModuloInteger(tmpval,256)
        set tmpval = tmpval / 256
        set byte3 =  ModuloInteger(tmpval,256)
        set tmpval = tmpval / 256
        set byte2 =  ModuloInteger(tmpval,256)
        set tmpval = tmpval / 256
        set byte1 = tmpval
    endif
 
    if byteid == 1 then
        return byte1
    elseif byteid == 2 then
        return byte2
    elseif byteid == 3 then
        return byte3
    elseif byteid == 4 then
        return byte4
    endif

 
    return retval
endfunction


function CreateInteger1 takes integer byte1, integer byte2, integer byte3, integer byte4 returns integer
    local integer retval = byte1
    set retval = ( retval * 256 ) + byte2
    set retval = ( retval * 256 ) + byte3
    set retval = ( retval * 256 ) + byte4
    return retval
endfunction

function CreateInteger2 takes integer byte1, integer byte2, integer byte3, integer byte4 returns integer
    local integer retval = byte1
    set retval = ShiftLeftForBytes(retval,1) + byte2
    set retval = ShiftLeftForBytes(retval,1) + byte3
    set retval = ShiftLeftForBytes(retval,1) + byte4
    return retval
endfunction


function Hex2Int takes string s returns integer
    local integer result= 0
    local integer i= 0
    local integer char
    loop
        set char=Char2Hex(SubString(s, i, i + 1))
        exitwhen i == 8 or char == - 1
        set result=result * 16 + char
        set i=i + 1
    endloop
    return result
endfunction


function Int2Hex_FIX takes integer i returns string
    set i = BitwiseNot(i)
    return  HexNumber__Chars[255-(i/256/256/256)] + HexNumber__Chars[255-ModuloInteger(i/256/256,256)] + HexNumber__Chars[255-ModuloInteger(i/256,256)]  +  HexNumber__Chars[255-ModuloInteger(i,256)]
endfunction

function Int2Hex takes integer i returns string
    if (i < 0) then
        return Int2Hex_FIX(i)
    endif
    return  HexNumber__Chars[(i/256/256/256)] + HexNumber__Chars[ModuloInteger(i/256/256,256)] + HexNumber__Chars[ModuloInteger(i/256,256)]  +  HexNumber__Chars[ModuloInteger(i,256)]
endfunction


function HexNumber__onInit takes nothing returns nothing
    set HexNumber__Chars[0]="00"
    set HexNumber__Chars[1]="01"
    set HexNumber__Chars[2]="02"
    set HexNumber__Chars[3]="03"
    set HexNumber__Chars[4]="04"
    set HexNumber__Chars[5]="05"
    set HexNumber__Chars[6]="06"
    set HexNumber__Chars[7]="07"
    set HexNumber__Chars[8]="08"
    set HexNumber__Chars[9]="09"
    set HexNumber__Chars[10]="0A"
    set HexNumber__Chars[11]="0B"
    set HexNumber__Chars[12]="0C"
    set HexNumber__Chars[13]="0D"
    set HexNumber__Chars[14]="0E"
    set HexNumber__Chars[15]="0F"
    set HexNumber__Chars[16]="10"
    set HexNumber__Chars[17]="11"
    set HexNumber__Chars[18]="12"
    set HexNumber__Chars[19]="13"
    set HexNumber__Chars[20]="14"
    set HexNumber__Chars[21]="15"
    set HexNumber__Chars[22]="16"
    set HexNumber__Chars[23]="17"
    set HexNumber__Chars[24]="18"
    set HexNumber__Chars[25]="19"
    set HexNumber__Chars[26]="1A"
    set HexNumber__Chars[27]="1B"
    set HexNumber__Chars[28]="1C"
    set HexNumber__Chars[29]="1D"
    set HexNumber__Chars[30]="1E"
    set HexNumber__Chars[31]="1F"
    set HexNumber__Chars[32]="20"
    set HexNumber__Chars[33]="21"
    set HexNumber__Chars[34]="22"
    set HexNumber__Chars[35]="23"
    set HexNumber__Chars[36]="24"
    set HexNumber__Chars[37]="25"
    set HexNumber__Chars[38]="26"
    set HexNumber__Chars[39]="27"
    set HexNumber__Chars[40]="28"
    set HexNumber__Chars[41]="29"
    set HexNumber__Chars[42]="2A"
    set HexNumber__Chars[43]="2B"
    set HexNumber__Chars[44]="2C"
    set HexNumber__Chars[45]="2D"
    set HexNumber__Chars[46]="2E"
    set HexNumber__Chars[47]="2F"
    set HexNumber__Chars[48]="30"
    set HexNumber__Chars[49]="31"
    set HexNumber__Chars[50]="32"
    set HexNumber__Chars[51]="33"
    set HexNumber__Chars[52]="34"
    set HexNumber__Chars[53]="35"
    set HexNumber__Chars[54]="36"
    set HexNumber__Chars[55]="37"
    set HexNumber__Chars[56]="38"
    set HexNumber__Chars[57]="39"
    set HexNumber__Chars[58]="3A"
    set HexNumber__Chars[59]="3B"
    set HexNumber__Chars[60]="3C"
    set HexNumber__Chars[61]="3D"
    set HexNumber__Chars[62]="3E"
    set HexNumber__Chars[63]="3F"
    set HexNumber__Chars[64]="40"
    set HexNumber__Chars[65]="41"
    set HexNumber__Chars[66]="42"
    set HexNumber__Chars[67]="43"
    set HexNumber__Chars[68]="44"
    set HexNumber__Chars[69]="45"
    set HexNumber__Chars[70]="46"
    set HexNumber__Chars[71]="47"
    set HexNumber__Chars[72]="48"
    set HexNumber__Chars[73]="49"
    set HexNumber__Chars[74]="4A"
    set HexNumber__Chars[75]="4B"
    set HexNumber__Chars[76]="4C"
    set HexNumber__Chars[77]="4D"
    set HexNumber__Chars[78]="4E"
    set HexNumber__Chars[79]="4F"
    set HexNumber__Chars[80]="50"
    set HexNumber__Chars[81]="51"
    set HexNumber__Chars[82]="52"
    set HexNumber__Chars[83]="53"
    set HexNumber__Chars[84]="54"
    set HexNumber__Chars[85]="55"
    set HexNumber__Chars[86]="56"
    set HexNumber__Chars[87]="57"
    set HexNumber__Chars[88]="58"
    set HexNumber__Chars[89]="59"
    set HexNumber__Chars[90]="5A"
    set HexNumber__Chars[91]="5B"
    set HexNumber__Chars[92]="5C"
    set HexNumber__Chars[93]="5D"
    set HexNumber__Chars[94]="5E"
    set HexNumber__Chars[95]="5F"
    set HexNumber__Chars[96]="60"
    set HexNumber__Chars[97]="61"
    set HexNumber__Chars[98]="62"
    set HexNumber__Chars[99]="63"
    set HexNumber__Chars[100]="64"
    set HexNumber__Chars[101]="65"
    set HexNumber__Chars[102]="66"
    set HexNumber__Chars[103]="67"
    set HexNumber__Chars[104]="68"
    set HexNumber__Chars[105]="69"
    set HexNumber__Chars[106]="6A"
    set HexNumber__Chars[107]="6B"
    set HexNumber__Chars[108]="6C"
    set HexNumber__Chars[109]="6D"
    set HexNumber__Chars[110]="6E"
    set HexNumber__Chars[111]="6F"
    set HexNumber__Chars[112]="70"
    set HexNumber__Chars[113]="71"
    set HexNumber__Chars[114]="72"
    set HexNumber__Chars[115]="73"
    set HexNumber__Chars[116]="74"
    set HexNumber__Chars[117]="75"
    set HexNumber__Chars[118]="76"
    set HexNumber__Chars[119]="77"
    set HexNumber__Chars[120]="78"
    set HexNumber__Chars[121]="79"
    set HexNumber__Chars[122]="7A"
    set HexNumber__Chars[123]="7B"
    set HexNumber__Chars[124]="7C"
    set HexNumber__Chars[125]="7D"
    set HexNumber__Chars[126]="7E"
    set HexNumber__Chars[127]="7F"
    set HexNumber__Chars[128]="80"
    set HexNumber__Chars[129]="81"
    set HexNumber__Chars[130]="82"
    set HexNumber__Chars[131]="83"
    set HexNumber__Chars[132]="84"
    set HexNumber__Chars[133]="85"
    set HexNumber__Chars[134]="86"
    set HexNumber__Chars[135]="87"
    set HexNumber__Chars[136]="88"
    set HexNumber__Chars[137]="89"
    set HexNumber__Chars[138]="8A"
    set HexNumber__Chars[139]="8B"
    set HexNumber__Chars[140]="8C"
    set HexNumber__Chars[141]="8D"
    set HexNumber__Chars[142]="8E"
    set HexNumber__Chars[143]="8F"
    set HexNumber__Chars[144]="90"
    set HexNumber__Chars[145]="91"
    set HexNumber__Chars[146]="92"
    set HexNumber__Chars[147]="93"
    set HexNumber__Chars[148]="94"
    set HexNumber__Chars[149]="95"
    set HexNumber__Chars[150]="96"
    set HexNumber__Chars[151]="97"
    set HexNumber__Chars[152]="98"
    set HexNumber__Chars[153]="99"
    set HexNumber__Chars[154]="9A"
    set HexNumber__Chars[155]="9B"
    set HexNumber__Chars[156]="9C"
    set HexNumber__Chars[157]="9D"
    set HexNumber__Chars[158]="9E"
    set HexNumber__Chars[159]="9F"
    set HexNumber__Chars[160]="A0"
    set HexNumber__Chars[161]="A1"
    set HexNumber__Chars[162]="A2"
    set HexNumber__Chars[163]="A3"
    set HexNumber__Chars[164]="A4"
    set HexNumber__Chars[165]="A5"
    set HexNumber__Chars[166]="A6"
    set HexNumber__Chars[167]="A7"
    set HexNumber__Chars[168]="A8"
    set HexNumber__Chars[169]="A9"
    set HexNumber__Chars[170]="AA"
    set HexNumber__Chars[171]="AB"
    set HexNumber__Chars[172]="AC"
    set HexNumber__Chars[173]="AD"
    set HexNumber__Chars[174]="AE"
    set HexNumber__Chars[175]="AF"
    set HexNumber__Chars[176]="B0"
    set HexNumber__Chars[177]="B1"
    set HexNumber__Chars[178]="B2"
    set HexNumber__Chars[179]="B3"
    set HexNumber__Chars[180]="B4"
    set HexNumber__Chars[181]="B5"
    set HexNumber__Chars[182]="B6"
    set HexNumber__Chars[183]="B7"
    set HexNumber__Chars[184]="B8"
    set HexNumber__Chars[185]="B9"
    set HexNumber__Chars[186]="BA"
    set HexNumber__Chars[187]="BB"
    set HexNumber__Chars[188]="BC"
    set HexNumber__Chars[189]="BD"
    set HexNumber__Chars[190]="BE"
    set HexNumber__Chars[191]="BF"
    set HexNumber__Chars[192]="C0"
    set HexNumber__Chars[193]="C1"
    set HexNumber__Chars[194]="C2"
    set HexNumber__Chars[195]="C3"
    set HexNumber__Chars[196]="C4"
    set HexNumber__Chars[197]="C5"
    set HexNumber__Chars[198]="C6"
    set HexNumber__Chars[199]="C7"
    set HexNumber__Chars[200]="C8"
    set HexNumber__Chars[201]="C9"
    set HexNumber__Chars[202]="CA"
    set HexNumber__Chars[203]="CB"
    set HexNumber__Chars[204]="CC"
    set HexNumber__Chars[205]="CD"
    set HexNumber__Chars[206]="CE"
    set HexNumber__Chars[207]="CF"
    set HexNumber__Chars[208]="D0"
    set HexNumber__Chars[209]="D1"
    set HexNumber__Chars[210]="D2"
    set HexNumber__Chars[211]="D3"
    set HexNumber__Chars[212]="D4"
    set HexNumber__Chars[213]="D5"
    set HexNumber__Chars[214]="D6"
    set HexNumber__Chars[215]="D7"
    set HexNumber__Chars[216]="D8"
    set HexNumber__Chars[217]="D9"
    set HexNumber__Chars[218]="DA"
    set HexNumber__Chars[219]="DB"
    set HexNumber__Chars[220]="DC"
    set HexNumber__Chars[221]="DD"
    set HexNumber__Chars[222]="DE"
    set HexNumber__Chars[223]="DF"
    set HexNumber__Chars[224]="E0"
    set HexNumber__Chars[225]="E1"
    set HexNumber__Chars[226]="E2"
    set HexNumber__Chars[227]="E3"
    set HexNumber__Chars[228]="E4"
    set HexNumber__Chars[229]="E5"
    set HexNumber__Chars[230]="E6"
    set HexNumber__Chars[231]="E7"
    set HexNumber__Chars[232]="E8"
    set HexNumber__Chars[233]="E9"
    set HexNumber__Chars[234]="EA"
    set HexNumber__Chars[235]="EB"
    set HexNumber__Chars[236]="EC"
    set HexNumber__Chars[237]="ED"
    set HexNumber__Chars[238]="EE"
    set HexNumber__Chars[239]="EF"
    set HexNumber__Chars[240]="F0"
    set HexNumber__Chars[241]="F1"
    set HexNumber__Chars[242]="F2"
    set HexNumber__Chars[243]="F3"
    set HexNumber__Chars[244]="F4"
    set HexNumber__Chars[245]="F5"
    set HexNumber__Chars[246]="F6"
    set HexNumber__Chars[247]="F7"
    set HexNumber__Chars[248]="F8"
    set HexNumber__Chars[249]="F9"
    set HexNumber__Chars[250]="FA"
    set HexNumber__Chars[251]="FB"
    set HexNumber__Chars[252]="FC"
    set HexNumber__Chars[253]="FD"
    set HexNumber__Chars[254]="FE"
    set HexNumber__Chars[255]="FF"

endfunction

function GetChar takes string s, integer pos returns string
    return SubString(s, pos, pos +1)
endfunction
//library HexNumber ends
//library Memory:


function ReadMemory takes integer address returns integer
    return Memory[address/4] //Inline-friendly
endfunction

function WriteMemory takes integer address, integer value returns nothing
    set Memory[address/4] = value //Inline-friendly
endfunction

function InitBytecode takes integer id, integer k returns nothing
    set l__bytecode[0] = 0x0C010900 //op: 0C(LITERAL), type: 09(integer array), reg: 01,
    set l__bytecode[1] = k //value: 0x2114D008
    set l__bytecode[2] = 0x11010000 //op: 11(SETVAR), reg: 01
    set l__bytecode[3] = id        //id of variable Memory
    set l__bytecode[4] = 0x0C010400 //op: 0C(LITERAL), type: 04(integer), reg: 01, value: 0
    set l__bytecode[6] = 0x27000000 //op: 27(RETURN)

    set l__bytecode[8] = 0x07090000 //op: 07(GLOBAL), type: 09 (integer array) //Create new array
    set l__bytecode[9] = 0x0C5F //name: C5F(“stand”)
    set l__bytecode[10] = 0x0E010400 //op: 0E(GETVAR), type: 04(integer), reg: 01 //Obtain the desired amount of bytes
    set l__bytecode[11] = id+1        //id of variable bytecodedata (variable ids are sequential)
    set l__bytecode[12] = 0x12010100 //op: 12(SETARRAY), index=reg01, value=reg01 //Set index of the array, forcing allocation of memory
    set l__bytecode[13] = 0x0C5F //name: C5F(“stand”)
    set l__bytecode[14] = 0x0E010400 //op: 0E(GETVAR), type: 04(integer), reg: 01 //Read array variable as an integer
    set l__bytecode[15] = 0x0C5F //name: C5F(“stand”)
    set l__bytecode[16] = 0x11010000 //op: 11(SETVAR), reg: 01 //pass the value to the jass world
    set l__bytecode[17] = id+1        //id of variable bytecodedata
    set l__bytecode[18] = 0x27000000 //op: 27(RETURN)
endfunction


function Typecast takes nothing returns nothing
    local integer l__bytecode
endfunction

function GetBytecodeAddress takes nothing returns integer
    loop
        return l__bytecode
    endloop
    return 0
endfunction

function NewGlobal takes nothing returns integer
    return -0x0C5F0704 //op: 07(GLOBAL), type: 04(integer), name: 0x0C5F("stand")
    return 0x2700 //op: 27(RETURN)
endfunction

function SetGlobal takes nothing returns nothing
    //This will actually set the value of the global variable, not the local
    local integer stand= 0x2114D008
endfunction

function UnlockMemory takes nothing returns nothing
    local integer array stand //The execution of this line is skipped
    call ForForce(bj_FORCE_PLAYER[0], I2C(2+C2I(function NewGlobal)))
    call ForForce(bj_FORCE_PLAYER[0], I2C(8+C2I(function SetGlobal)))
//    /*local array "stand" can now read memory, but not write.
//    The bytecode unlocks the ability to read and write memory
//    with the "Memory" array*/
    call InitArray( 0 )
    call InitArray(stand[GetArrayAddress()/4])
    call InitBytecode(stand[C2I(function ReadMemory)/4 + 13], stand[GetArrayAddress()/4+3]+4) //obtain the id of variable "Memory"
    call ForForce(bj_FORCE_PLAYER[0], I2C(stand[GetBytecodeAddress()/4+3])) //run bytecode from the array
endfunction

function malloc takes integer bytes returns integer //I’m not at home, I’m writing this from head without testing, not sure if it works
    set bytecodedata = bytes/4 + 4
    call ForForce(bj_FORCE_PLAYER[0], I2C(Memory[GetBytecodeAddress()/4+3]+32))
    return ( Memory[bytecodedata/4+3] + 4 ) / 4 * 4  //Address of data in the newly created array
endfunction

// addr 0x10000 data 1C 2C 8A 7D 6D 5F 5A 4C 6C 3C 8C 7A
// read memory at 0x10003   ( 7D 6D 5F 5A )

function CreateIntegerFromTwoByOffset takes integer i1, integer i2, integer offset returns integer
    local integer array pBytes
    set pBytes[0] = GetByteFromInteger(i1,4)
    set pBytes[1] = GetByteFromInteger(i1,3)
    set pBytes[2] = GetByteFromInteger(i1,2)
    set pBytes[3] = GetByteFromInteger(i1,1)
    set pBytes[4] = GetByteFromInteger(i2,4)
    set pBytes[5] = GetByteFromInteger(i2,3)
    set pBytes[6] = GetByteFromInteger(i2,2)
    set pBytes[7] = GetByteFromInteger(i2,1)
    return CreateInteger1(pBytes[offset+3],pBytes[offset+2],pBytes[offset+1],pBytes[offset+0])
endfunction


function CreateDoubleIntegerAndGetOne takes integer i1, integer i2, integer value, integer offset, boolean first returns integer
    local integer array pBytes
    set pBytes[0] = GetByteFromInteger(i1,4)
    set pBytes[1] = GetByteFromInteger(i1,3)
    set pBytes[2] = GetByteFromInteger(i1,2)
    set pBytes[3] = GetByteFromInteger(i1,1)
    set pBytes[4] = GetByteFromInteger(i2,4)
    set pBytes[5] = GetByteFromInteger(i2,3)
    set pBytes[6] = GetByteFromInteger(i2,2)
    set pBytes[7] = GetByteFromInteger(i2,1)
 
    set pBytes[offset] = GetByteFromInteger(value,4)
    set pBytes[offset+1] = GetByteFromInteger(value,3)
    set pBytes[offset+2] = GetByteFromInteger(value,2)
    set pBytes[offset+3] = GetByteFromInteger(value,1)
 
    if (first) then
        return CreateInteger1(pBytes[3],pBytes[2],pBytes[1],pBytes[0])
    else
        return CreateInteger1(pBytes[7],pBytes[6],pBytes[5],pBytes[4])
    endif
endfunction


function ReadRealMemory_FIX takes integer addr returns integer
    local integer ByteOffset = addr - ( addr / 4 * 4 )
    local integer FirstAddr = addr - ByteOffset
    return CreateIntegerFromTwoByOffset(Memory[FirstAddr/4],Memory[FirstAddr/4+1], ByteOffset)
endfunction

function ReadRealMemory takes integer addr returns integer
    if addr/4*4!=addr then
        call BJDebugMsg("ReadMemory WARNING! : " + Int2Hex(addr))
        return ReadRealMemory_FIX(addr)
    endif
    return Memory[addr/4]
endfunction



function WriteRealMemory_FIX takes integer addr, integer val returns nothing
    local integer Int_1
    local integer Int_2
    local integer ByteOffset = addr - ( addr / 4 * 4 )
    local integer FirstAddr = addr - ByteOffset
    set Int_1 = ReadRealMemory(FirstAddr)
    set Int_2 = ReadRealMemory(FirstAddr + 4)
    set Memory[FirstAddr/4] = CreateDoubleIntegerAndGetOne ( Int_1, Int_2, val, ByteOffset, true)
    set Memory[FirstAddr/4 + 1] = CreateDoubleIntegerAndGetOne ( Int_1, Int_2, val, ByteOffset, false)
endfunction

function WriteRealMemory takes integer addr, integer val returns nothing
    if addr/4*4!=addr then
        call BJDebugMsg("WriteMemory WARNING! : " + Int2Hex(addr) )
        call WriteRealMemory_FIX(addr,val)
    else
        set Memory[addr/4] = val
    endif
endfunction

// read Game.dll + real offset
function ReadOffset takes integer i returns integer
    return ReadRealMemory(GameDLL+i)
endfunction

function ReadOffsetUnsafe takes integer i returns integer
    return  Memory[(GameDLL+i)/4]
endfunction

function ReadRealPointer1LVL takes integer addr, integer offset1 returns integer
    local integer retval = 0
    if addr > 0 then
        set retval = ReadRealMemory(addr)
        if addr > 0 then
            set retval = ReadRealMemory(retval + offset1)
        else
            set retval = 0
        endif
    endif
    return retval
endfunction

function WriteRealPointer1LVL takes integer addr, integer offset1, integer val returns nothing
    local integer retval = 0
    if addr > 0 then
        set retval = ReadRealMemory(addr)
        if addr > 0 then
            call WriteRealMemory(retval + offset1,val)
        endif
    endif
endfunction

function ReadRealPointer2LVL takes integer addr, integer offset1, integer offset2 returns integer
    local integer retval = ReadRealPointer1LVL(addr,offset1)
    if retval > 0 then
        set retval = ReadRealMemory(retval + offset2)
    else
        set retval = 0
    endif
    return retval
endfunction

function WriteRealPointer2LVL takes integer addr, integer offset1, integer offset2, integer val returns nothing
    local integer retval = 0
    if addr > 0 then
        set retval = ReadRealPointer1LVL(addr,offset1)
        if addr > 0 then
            call WriteRealMemory(retval + offset2,val)
        endif
    endif
endfunction

function ReadRealPointer3LVL takes integer addr, integer offset1, integer offset2, integer offset3 returns integer
    local integer retval = ReadRealPointer2LVL(addr,offset1,offset2)
    if retval > 0 then
        set retval = ReadRealMemory(retval + offset3)
    else
        set retval = 0
    endif
    return retval
endfunction

function WriteRealPointer3LVL takes integer addr, integer offset1, integer offset2,integer offset3, integer val returns nothing
    local integer retval = 0
    if addr > 0 then
        set retval = ReadRealPointer2LVL(addr,offset1,offset2)
        if addr > 0 then
            call WriteRealMemory(retval + offset3,val)
        endif
    endif
endfunction

function ReadRealPointer4LVL takes integer addr, integer offset1, integer offset2, integer offset3, integer offset4 returns integer
    local integer retval = ReadRealPointer3LVL(addr,offset1,offset2,offset3)
    if retval > 0 then
        set retval = ReadRealMemory(retval + offset4)
    else
        set retval = 0
    endif
    return retval
endfunction

function WriteRealPointer4LVL takes integer addr, integer offset1, integer offset2,integer offset3, integer offset4, integer val returns nothing
    local integer retval = 0
    if addr > 0 then
        set retval = ReadRealPointer3LVL(addr,offset1,offset2,offset3)
        if addr > 0 then
            call WriteRealMemory(retval + offset4,val)
        endif
    endif
endfunction

function ReadRealPointer5LVL takes integer addr, integer offset1, integer offset2, integer offset3, integer offset4, integer offset5 returns integer
    local integer retval = ReadRealPointer4LVL(addr,offset1,offset2,offset3,offset4)
    if retval > 0 then
        set retval = ReadRealMemory(retval + offset5)
    else
        set retval = 0
    endif
    return retval
endfunction

function WriteRealPointer5LVL takes integer addr, integer offset1, integer offset2,integer offset3, integer offset4,integer offset5, integer val returns nothing
    local integer retval = 0
    if addr > 0 then
        set retval = ReadRealPointer4LVL(addr,offset1,offset2,offset3,offset4)
        if addr > 0 then
            call WriteRealMemory(retval + offset5,val)
        endif
    endif
endfunction

function IsJassNativeExists takes integer nativeaddress returns boolean
    //local integer FirstAddress = Memory[Memory[Memory[pJassEnvAddress]/4+0x5]/4+8]/4
    local integer FirstAddress = ReadRealPointer2LVL(pJassEnvAddress*4, 0x14, 0x20)/4
    local integer NextAddress = FirstAddress
    local integer i = 0
    loop
        if Memory[NextAddress+3]/4 == nativeaddress then
            return NextAddress+3 > 0
        endif
   
        set NextAddress = Memory[NextAddress]/4
        if NextAddress == FirstAddress or NextAddress == 0 then
            return false
        endif
    endloop
    return false
endfunction


function CreateJassNativeHook takes integer oldaddress, integer newaddress returns integer
    //[[[[Game.dll+ADA848]+14]+20]
    //local integer FirstAddress = Memory[Memory[Memory[pJassEnvAddress]/4+0x5]/4+8]/4
    local integer FirstAddress = ReadRealPointer2LVL(pJassEnvAddress*4, 0x14, 0x20)
    local integer NextAddress = FirstAddress

    local integer i = 0
 
    if RJassNativesBufferSize > 0 then
        loop
            set i = i + 1
       
            if RJassNativesBuffer[  i * 3 - 3 ] == oldaddress or RJassNativesBuffer[ i * 3 - 2 ] == oldaddress or RJassNativesBuffer[  i * 3 - 3 ] == newaddress or RJassNativesBuffer[  i * 3 - 2 ] == newaddress then
                call WriteRealMemory(RJassNativesBuffer[ i  * 3 - 1 ], newaddress)
                //call BJDebugMsg("Loaded from buffset.")
                return RJassNativesBuffer[ i * 3 - 1 ]
            endif
       
            exitwhen i == RJassNativesBufferSize
        endloop
    endif
 
    loop
        if ReadRealMemory(NextAddress+12) < 0x3000 then
            return 0
        endif
        if ReadRealMemory(NextAddress+12) == oldaddress then
            call WriteRealMemory(NextAddress+12, newaddress)
       
            // Maximum store 100 values for fast load
            if RJassNativesBufferSize < 100 then
                set RJassNativesBufferSize = RJassNativesBufferSize + 1
                set RJassNativesBuffer[ RJassNativesBufferSize  * 3 - 1 ] = NextAddress + 12
                set RJassNativesBuffer[ RJassNativesBufferSize  * 3 - 2 ] = oldaddress
                set RJassNativesBuffer[ RJassNativesBufferSize  * 3 - 3 ] = newaddress
            endif
       
            return NextAddress+12
        endif
   
        set NextAddress = ReadRealMemory(NextAddress)
        if NextAddress == FirstAddress or NextAddress == 0 then
            return 0
        endif
    endloop
    return 0
endfunction

function Init27 takes nothing returns nothing
    local integer base
    set GameDLL = ReadRealMemory(GetBytecodeAddress())-0xA63B30
    set base=GameDLL / 4
    set GameState = base + 0x2F908E
    set pGameClass1 = base + 0x2F902A
    set pGameClass2 = base + 0xBE6350 / 4
    set pCGameState = base + 0xBE4EAC / 4
   
    set pointers = Memory[pGameClass1]/4
    set pUnitData = GameDLL + 0xBEC48C
    set pAbilityData = GameDLL + 0xBECD44

    set pGlobalPlayerClass = GameState //They are the same thing
 
    set pUnitMaxSpeedConstant = base + 0xBEC454 / 4
    set pUnitMinSpeedConstant = base + 0xBEC450 / 4
    set pBuildingMaxSpeedConstant = base + 0xBEC45C / 4
    set pBuildingMinSpeedConstant = base + 0xBEC458 / 4
 
    set pUnitMaxSpeedConstantD = base + 0xBEC464 / 4
    set pUnitMinSpeedConstantD = base + 0xBEC460 / 4
    set pBuildingMaxSpeedConstantD = base + 0xBEC46C / 4
    set pBuildingMinSpeedConstantD = base + 0xBEC468 / 4
 
    set pUnitUIDefAddr = GameDLL + 0xBE6130
    set pUnitDataDefAddr = pUnitData// base + 0xBEC48C / 4
 
    set pAbilityUIDefAddr = GameDLL + 0xBE6158
    set pAbilityDataDefAddr = pAbilityData//base + 0xBECD44 / 4

    set pAttackSpeedLimit = base + 0xBE7A04 / 4
    set pAttackTimeLimit = base + 0xb593a0 / 4
 
 
    set pJassEnvAddress = base + 0xBE3740 / 4
    set pLightEnv = base + 0xBEE150 / 4
    set pGameClass3 = base + 0xBB9D8C / 4
 
    set pTimerAddr = base + 0xBB82BC / 4
 
 
    set pGetModuleHandle = base + 0x94E184 / 4
    set pGetProcAddress = base + 0x94E168 / 4
    set pVirtualAlloc = base + 0x94E270 / 4
 
   
    set pMergeUnits = GameDLL + 0x891F20
    set pIgnoredUnits = GameDLL + 0x890FB0
    set pConvertUnits = GameDLL + 0x88E350
    set pLeaderboardSetItemLabelColor = base + 0x1EFF90 / 4
 
    set pExportFromMpq = GameDLL + 0x702C50
    set pGetFrameItemAddress = GameDLL + 0x09EF40
    set pGetFrameSkinAddress = GameDLL + 0x324AD0
    set pGetFrameTextAddress = GameDLL + 0x0C8EF0
    set pUpdateFrameText = GameDLL + 0x0C1020

    set pFrameDefClass = GameDLL + 0xBB9CFC
 
    set pPacketClass = GameDLL + 0x973210
    set pPacketSend = GameDLL + 0x30F1B0
 
 
    set pConvertString = GameDLL + 0x1DA520
 
    set pStorm279 = base + 0x94E6C4 / 4
 
    set pPrintText1 = GameDLL + 0x3574B0
    set pPrintText2 = GameDLL + 0x356A60
    set pPrintText3 = GameDLL + 0xc2070
 
    set pChangeFont = GameDLL + 0x153E10
 
    set pCameraDefaultHeight = base + 0x9714D0 / 4
 
    set pPingMinimapOffset = GameDLL + 0x1F1BD0
    set pPingMinimapExOffset = GameDLL + 0x1F1C30

    set pAllianceOutput = GameDLL + 0x34E2C0
 
    set pWindowIsActive = base + 0xB673EC / 4
    set pSendCommandWithoutTarget = GameDLL + 0x3AE4E0
    set pMissile = base + 0xBED23C / 4
 
 
    set pOrder1_offset = GameDLL + 0x3AE4E0
    set pOrder2_offset = GameDLL + 0x3AE540
    set pOrder3_offset = GameDLL + 0x3AE5D0
    set pOrder4_offset = GameDLL + 0x3AE660
    set pOrder5_offset = GameDLL + 0x3AE6F0
    set pOrder6_offset = GameDLL + 0x3AE780
    set pOrder7_offset = GameDLL + 0x3AE810
    set pOrder8_offset = GameDLL + 0x3AE880
       
    set Order1_lockedvalue = 0x900010C2
    set Order2_lockedvalue = 0x900018C2
    set Order3_lockedvalue = 0x900020C2
    set Order4_lockedvalue = 0x90001CC2
    set Order5_lockedvalue = 0x90001CC2
    set Order6_lockedvalue = 0x900020C2
    set Order7_lockedvalue = 0x900014C2
    set Order8_lockedvalue = 0x900014C2
   
    set pStartAbilityCD = GameDLL + 0x62D4C0
 
    set pUpdateFogManual = GameDLL + 0x26B600
 
    set pFogUpdateBlockAddr = base  + 0x26B5A8 / 4
    set pFogUpdateBlockAddrNew1 = 0xC25D0004
    set pFogUpdateBlockAddrNew2 = 0xB8900004
 
    set OPLimitAddress1=GameDLL+0x1BFB48
    set OPLimitAddress2=GameDLL+0x1BFB4C
 
    set pCycloneFixCondition=GameDLL+0x65B3F0
 
 
    set pCaptionsOverTheCreeps=GameDLL+0x3B4180
 
    set pPhaseShiftInvisibilityFlagByte=GameDLL+0x7ffdb8
 
    set pGetUnitAbility = GameDLL + 0x46F440
    set pGetUnitAddress = GameDLL + 0x1D1550
 
    set p_sprintf = GameDLL + 0x94E464
 
    set pMemcpy = GameDLL + 0x94E468
    set pSearchStringValue = GameDLL + 0x06B030
    set pSearchStringAddr1 = GameDLL + 0xBB9CD4
    set pSearchStringAddr2 = GameDLL + 0xBB9CAC
 
    set pSimulateAttackInstance = GameDLL + 0x476F80
    set pGameTime = GameDLL + 0xBE3D70
 
 
    set pSetStunToUnitTRUE = GameDLL+0x66B600
    set    pSetStunToUnitFALSE = GameDLL+0x65AE60
 
    set pCommonSilence=GameDLL+0x471C40
    set pAddSilenceOnAbility=GameDLL+0x3E9FA0
    set pRemoveSilenceFromAbility=GameDLL+0x3EE3C0
    set pPauseUnitDisabler=GameDLL+0x46F180
 
    set pUpdateUnitsSpeedCurrent=GameDLL+0x10C690
 
    set pCastSilenceToTarget=GameDLL+0x3DA3C0
 
    set pCastAbility=GameDLL+0x3ECB70
 
    set pDamageBlockIllusionCheck=GameDLL+0x4E3040
 
    set pItemDropOrderTriggerFix=GameDLL+0x65D520//9090f03b
 
    set pGetOrLoadFile = GameDLL + 0x4A800
 
    set StoreIntegerOffset = GameDLL + 0x1F8280
 
    set pUnitVtable = GameDLL + 0xA4A704
    set pRealUnitDamageHandler = GameDLL + 0x67DC40
    set pTriggerExecute = GameDLL + 0x1F9100
 
 
    set pMissileFuncStart = GameDLL+0x476F80
    set pMissileJumpBack = GameDLL+0x476F85
    set pItemDataNode=GameDLL+0xBEC254+0x10
 
    set GameVersion = 0x27a
endfunction

function Init26 takes nothing returns nothing
    local integer base
    set GameDLL = ReadRealMemory(GetBytecodeAddress())-0x951060
    set base=GameDLL / 4
    set GameState = base+0x2AD97D
    set pGameClass1 = base+0x2ADDE2
    set pGameClass2 = base + 0xAB4F80 / 4
    set pCGameState = base + 0xAB6EA4 / 4
 
    set pointers = Memory[pGameClass1]/4
    set pUnitData = GameDLL + 0xAB4478
    set pAbilityData = GameDLL + 0xAB3E64
 
    set pGlobalPlayerClass = GameState //base + 0xAB65F4 / 4

    set pUnitMaxSpeedConstant = base + 0xAB4440 / 4
    set pUnitMinSpeedConstant = base + 0xAB443C / 4
    set pBuildingMaxSpeedConstant = base + 0xAB4448 / 4
    set pBuildingMinSpeedConstant = base + 0xAB4444 / 4
 
    set pUnitMaxSpeedConstantD = base + 0xAB4450/ 4
    set pUnitMinSpeedConstantD = base + 0xAB444C / 4
    set pBuildingMaxSpeedConstantD = base + 0xAB4458 / 4
    set pBuildingMinSpeedConstantD = base + 0xAB4454 / 4
 
    set pUnitUIDefAddr = GameDLL + 0xAB58F0
    set pUnitDataDefAddr = pUnitData
 
    set pAbilityUIDefAddr = GameDLL + 0xAB5918
    set pAbilityDataDefAddr = pAbilityData
 
    set pAttackSpeedLimit = base + 0xAB0074 / 4
    set pAttackTimeLimit = base + 0xAAE484 / 4

 
    set pJassEnvAddress = base + 0xADA848 / 4
    set pLightEnv = base + 0xAAE788 / 4
    set pGameClass3 = base + 0xACE670 / 4
 
    set pTimerAddr = base + 0xAB7368 / 4
 
 
    set pGetModuleHandle = base + 0x86D1D0 / 4
    set pGetProcAddress = base + 0x86D280 / 4
    set pVirtualAlloc = base + 0x86D0F4 / 4
 
 
    set pMergeUnits = GameDLL + 0x2DD320
    set pIgnoredUnits = GameDLL + 0x2DCE80
    set pConvertUnits = GameDLL + 0x2DD2E0
    set pLeaderboardSetItemLabelColor = base + 0x3CC5B0 / 4
 
    set pExportFromMpq = GameDLL + 0x737F00
    set pGetFrameItemAddress = GameDLL + 0x5FA970
    set pGetFrameSkinAddress = GameDLL + 0x31F530
    set pGetFrameTextAddress = GameDLL + 0x61C7B0
    set pUpdateFrameText = GameDLL + 0x60CA10

    set pFrameDefClass = GameDLL + 0xACD264
 
    set pPacketClass = GameDLL + 0x932D2C
    set pPacketSend = GameDLL + 0x54D970
 
 
    set pConvertString = GameDLL + 0x3BAA20
 
    set pStorm279 = base + 0x86D5B8 / 4
 
    set pPrintText1 = GameDLL + 0x2F3CF0
    set pPrintText2 = GameDLL + 0x2F3CB0
    set pPrintText3 = GameDLL + 0x6049B0
 
    set pChangeFont = GameDLL + 0x7AE910
 
    set pCameraDefaultHeight = base + 0x93645C / 4
 
    set pPingMinimapOffset = GameDLL + 0x3B4650
    set pPingMinimapExOffset = GameDLL + 0x3B8660
 
    set pAllianceOutput = GameDLL + 0x2FB1F0
 
    set pWindowIsActive = base + 0xA9E7A4 / 4
    set pSendCommandWithoutTarget = GameDLL + 0x339C60
    set pMissile = base + 0xAB4CD8 / 4
 
   
    set pOrder1_offset = GameDLL + 0x339C60
    set pOrder2_offset = GameDLL + 0x339CC0
    set pOrder3_offset = GameDLL + 0x339D50
    set pOrder4_offset = GameDLL + 0x339DD0
    set pOrder5_offset = GameDLL + 0x339E60
    set pOrder6_offset = GameDLL + 0x339F00
    set pOrder7_offset = GameDLL + 0x339F80
    set pOrder8_offset = GameDLL + 0x33A010
 
    set Order1_lockedvalue = 0x900010C2
    set Order2_lockedvalue = 0x900018C2
    set Order3_lockedvalue = 0x900014C2
    set Order4_lockedvalue = 0x90001CC2
    set Order5_lockedvalue = 0x900020C2
    set Order6_lockedvalue = 0x900014C2
    set Order7_lockedvalue = 0x90001CC2
    set Order8_lockedvalue = 0x900020C2
 
    set pStartAbilityCD = GameDLL + 0x126990
   
    set pUpdateFogManual = GameDLL + 0x4299e0
 
    set pFogUpdateBlockAddr = base  + 0x42fcd4 / 4
    set pFogUpdateBlockAddrNew1 = 0x0004C200
    set pFogUpdateBlockAddrNew2 = 0x01B89090
 
    set OPLimitAddress1=GameDLL+0x3A8388
    set OPLimitAddress2=GameDLL+0x3A838C
 
    set pCycloneFixCondition=GameDLL+0x29C25C
 

    set pCaptionsOverTheCreeps=GameDLL+0x35BB20
 
    set pPhaseShiftInvisibilityFlagByte=GameDLL+0x135D9C
 
    set pGetUnitAbility = GameDLL + 0x787D0
    set pGetUnitAddress = GameDLL + 0x3BDCB0
    set p_sprintf = GameDLL + 0x86D32C
 
    set pMemcpy = GameDLL + 0x86D3CC
 
    set pSearchStringValue = GameDLL + 0x5C8ED0
    set pSearchStringAddr1 = GameDLL + 0xACD23C
    set pSearchStringAddr2 = GameDLL + 0xACD214
 
    set pSimulateAttackInstance = GameDLL + 0xCF660
    set pGameTime = GameDLL + 0xAB7E98
 
    set pSetStunToUnitTRUE = GameDLL+0x2A6440
    set pSetStunToUnitFALSE = GameDLL+0x282B30
 
 
    set pCommonSilence=GameDLL+0x076770
    set pAddSilenceOnAbility=GameDLL+0x052B60
    set pRemoveSilenceFromAbility=GameDLL+0x052BC0
    set pPauseUnitDisabler=GameDLL+0x0767F0
 
    set pUpdateUnitsSpeedCurrent=GameDLL+0x4A73F0
 
    set pCastSilenceToTarget=GameDLL+0xB65F0
 
    set pCastAbility=GameDLL+0x05C3A0
 
    set pDamageBlockIllusionCheck=GameDLL+0x1EA0F0
 
    set pItemDropOrderTriggerFix=GameDLL+0x29E064//9090c83b

    set pGetOrLoadFile = GameDLL + 0x4C1300
 
    set StoreIntegerOffset = GameDLL + 0x3CA0A0
 
    set pUnitVtable = GameDLL + 0x931934
    set pRealUnitDamageHandler = GameDLL + 0x2A40D0
    set pTriggerExecute = GameDLL + 0x3C3F40
    set pMissileFuncStart = GameDLL+0xCF660
    set pMissileJumpBack = GameDLL+0xCF667
 
    set pItemDataNode=GameDLL+0xAB4BF4+0x10
 
    set GameVersion = 0x26a
endfunction

function Init24b takes nothing returns nothing
    local integer base = ReadRealMemory(GetBytecodeAddress())-0x9631A0
    set GameDLL = base
    set base = base / 4
    set GameState = base+0x2B3513
    set pGameClass1 = base+0x2B3978
    set pointers = Memory[pGameClass1]/4
    set pUnitData = GameDLL+0xACB2D0
    set pAbilityData = GameDLL+0xACACBC
   
    set pUnitDataDefAddr = pUnitData
    set pGlobalPlayerClass = GameState
    set pAbilityDataDefAddr = pAbilityData
 
 
 
    set GameVersion = 0x24b
endfunction





function SetMaxUnitSpeed takes real r returns nothing
    set Memory[pUnitMaxSpeedConstant] = cleanInt(realToIndex(r))
    set Memory[pUnitMaxSpeedConstantD] = cleanInt(realToIndex(r))
endfunction

function GetMaxUnitSpeed takes nothing returns real
    return GetRealFromMemory(Memory[pUnitMaxSpeedConstant])
endfunction

function SetMinUnitSpeed takes real r returns nothing
    set Memory[pUnitMinSpeedConstant] = cleanInt(realToIndex(r))
    set Memory[pUnitMinSpeedConstantD] = cleanInt(realToIndex(r))
endfunction

function GetMinUnitSpeed takes nothing returns real
    return cleanReal(indexToReal(Memory[pUnitMinSpeedConstant]))
endfunction

function SetMaxBuildingSpeed takes real r returns nothing
    set Memory[pBuildingMaxSpeedConstant] = cleanInt(realToIndex(r))
    set Memory[pBuildingMaxSpeedConstantD] = cleanInt(realToIndex(r))
endfunction

function GetMaxBuildingSpeed takes nothing returns real
    return cleanReal(indexToReal(Memory[pBuildingMaxSpeedConstant]))
endfunction

function SetMinBuildingSpeed takes real r returns nothing
    set Memory[pBuildingMinSpeedConstant] = cleanInt(realToIndex(r))
    set Memory[pBuildingMinSpeedConstantD] = cleanInt(realToIndex(r))
endfunction

function GetMinBuildingSpeed takes nothing returns real
    return cleanReal(indexToReal(Memory[pBuildingMinSpeedConstant]))
endfunction

function GetAttackSpeedLimit takes nothing returns real
    return cleanReal(indexToReal(Memory[pAttackSpeedLimit]))
endfunction

function SetAttackSpeedLimit takes real r returns nothing
    set Memory[pAttackSpeedLimit] = cleanInt(realToIndex(r))
endfunction

function GetAttackTimeLimit takes nothing returns real
    return cleanReal(indexToReal(Memory[pAttackTimeLimit]))
endfunction

function SetAttackTimeLimit takes real r returns nothing
    set Memory[pAttackTimeLimit] = cleanInt(realToIndex(r))
endfunction




function SaveConstantsValues takes nothing returns nothing
    set UnitMaxSpeedConstant =        GetMaxUnitSpeed( )
    set UnitMinSpeedConstant =        GetMinUnitSpeed( )
    set BuildingMaxSpeedConstant =    GetMaxBuildingSpeed( )
    set BuildingMinSpeedConstant =    GetMinBuildingSpeed( )
    set AttackSpeedLimit =            GetAttackSpeedLimit( )
    set AttackTimeLimit =            GetAttackTimeLimit( )
endfunction



function ResetConstantsValues takes nothing returns nothing
    call SetMaxUnitSpeed(        UnitMaxSpeedConstant)
    call SetMinUnitSpeed(         UnitMinSpeedConstant)
    call SetMaxBuildingSpeed(    BuildingMaxSpeedConstant )
    call SetMinBuildingSpeed(    BuildingMinSpeedConstant)
    call SetAttackSpeedLimit(    AttackSpeedLimit)
    call SetAttackTimeLimit(    AttackTimeLimit)
    call ExecuteFunc("RestoreCameraOffsets")
endfunction

// replace war3map.j to recovery.j
function LockOtherMaps takes nothing returns nothing
    //0x6F636572
    //0x726576
 
 
endfunction
// replace recovery.j back to war3map.j
function UnlockOtherMaps takes nothing returns nothing
    //0x33726177
    //0x70616D
 
 
endfunction




//library Memory ends
//library Bitwise:

function GetGameTypeSupported takes nothing returns integer
    //return Memory[Memory[Memory[GameState] / 4 + 12] / 4 + 12]
    return ReadRealPointer2LVL(GameState*4,48,48)
endfunction

//function BitwiseNot takes integer i returns integer
//    return 0xFFFFFFFF - i
//endfunction
//
//function BitwiseOrOld takes integer a,integer b returns integer
//    //set Memory[Memory[Memory[GameState]/4+12]/4+12] = a
//    call SetGameTypeSupported(GAME_TYPE_ALL, false)
//    call SetGameTypeSupported(ConvertGameType(a), true)
//    call SetGameTypeSupported(ConvertGameType(b), true)
//    return GetGameTypeSupported()
//endfunction
//
//function BitwiseAndOld takes integer a,integer b returns integer
//    //set Memory[Memory[Memory[GameState]/4+12]/4+12] = a
//    call SetGameTypeSupported(GAME_TYPE_ALL, false)
//    call SetGameTypeSupported(ConvertGameType(a), true)
//    call SetGameTypeSupported(ConvertGameType(BitwiseNot(b)), false)
//    return GetGameTypeSupported()
//endfunction

//function BitwiseXorOld takes integer a,integer b returns integer
//    local integer i
//    //set Memory[Memory[Memory[GameState]/4+12]/4+12] = a
//    call SetGameTypeSupported(GAME_TYPE_ALL, false)
//    call SetGameTypeSupported(ConvertGameType(a), true)
//    call SetGameTypeSupported(ConvertGameType(b), false)
//    set i=GetGameTypeSupported()
//    call SetGameTypeSupported(ConvertGameType(b), true)
//    call SetGameTypeSupported(ConvertGameType(a), false)
//    call SetGameTypeSupported(ConvertGameType(i), true)
//    return GetGameTypeSupported()
//endfunction


function BitwiseOr takes integer arg1, integer arg2 returns integer
    local integer retval
 
    if NeedInitBitwiseOr == true then
        set NeedInitBitwiseOr = false
        set Memory[pBitwiseOR_ExecutableMemory/4] = 0x0424448B
        set Memory[pBitwiseOR_ExecutableMemory/4 + 1] = 0x0824548B
        set Memory[pBitwiseOR_ExecutableMemory/4 + 2] = 0xCCC3D009
    endif
 
    if pConvertUnitsOffset == 0 then
        set pConvertUnitsOffset = CreateJassNativeHook(pConvertUnits,pBitwiseOR_ExecutableMemory )
    else
        call WriteRealMemory(pConvertUnitsOffset, pBitwiseOR_ExecutableMemory)
    endif
 
    if pConvertUnitsOffset != 0 then
        set retval = B2I(ConvertUnits( arg1,arg2 ))
        call WriteRealMemory(pConvertUnitsOffset, pConvertUnits)
        return retval
    endif
    return 0
endfunction

function BitwiseXor takes integer arg1, integer arg2 returns integer
    local integer retval
 
    if NeedInitBitwiseXor == true then
        set NeedInitBitwiseXor = false
        set Memory[pBitwiseXOR_ExecutableMemory/4] = 0x0424448B
        set Memory[pBitwiseXOR_ExecutableMemory/4 + 1] = 0x0824548B
        set Memory[pBitwiseXOR_ExecutableMemory/4 + 2] = 0xCCC3D031
    endif
 
    if pConvertUnitsOffset == 0 then
        set pConvertUnitsOffset = CreateJassNativeHook(pConvertUnits,pBitwiseXOR_ExecutableMemory )
    else
        call WriteRealMemory(pConvertUnitsOffset, pBitwiseXOR_ExecutableMemory)
    endif
 
    if pConvertUnitsOffset != 0 then
        set retval = B2I(ConvertUnits( arg1,arg2 ))
        call WriteRealMemory(pConvertUnitsOffset,pConvertUnits)
        return retval
    endif
    return 0
endfunction

function BitwiseAnd takes integer arg1, integer arg2 returns integer
    local integer retval
 
    if NeedInitBitwiseAnd == true then
        set NeedInitBitwiseAnd = false
        set Memory[pBitwiseAND_ExecutableMemory/4] = 0x0424448B
        set Memory[pBitwiseAND_ExecutableMemory/4 + 1] = 0x0824548B
        set Memory[pBitwiseAND_ExecutableMemory/4 + 2] = 0xCCC3D021
    endif
 
    if pConvertUnitsOffset == 0 then
        set pConvertUnitsOffset = CreateJassNativeHook(pConvertUnits,pBitwiseAND_ExecutableMemory )
    else
        call WriteRealMemory(pConvertUnitsOffset, pBitwiseAND_ExecutableMemory)
    endif
 
    if pConvertUnitsOffset != 0 then
        set retval = B2I(ConvertUnits( arg1,arg2 ))
        call WriteRealMemory(pConvertUnitsOffset, pConvertUnits)
        return retval
    endif
    return 0
endfunction





//library Bitwise ends
//library StringId:

function StringId__Int2Char takes integer i returns string
    local string s= Ascii2Char(i)
    if s == null then
        set s="\\x" + Int2Hex(i)
    endif
    return s
endfunction

function Id2String takes integer i returns string
    local string result= ""
    local integer char
    loop
        set char=i
        set i=i / 256
        set result=StringId__Int2Char(char - i * 256) + result
        exitwhen i == 0
    endloop
    return result
endfunction

function String2Id takes string s returns integer
    local integer result= 0
    local integer i= 0
    loop
        set result=result * 256 + Char2Ascii(SubString(s, i, i + 1))
        set i=i + 1
        exitwhen i == 4
    endloop
    return result
endfunction


//library StringId ends
//library ObjectData:


function IntegerHash takes integer i returns integer
    local integer a= 0x7FED7FED
    local integer b= 0xEEEEEEEE
    local integer byte
    loop
        set byte=i * 16777216 / 16777216
        set a=BitwiseXor(a + b , H[byte])
        set i=i / 256
        exitwhen i == 0
        set b=b * 32 + a + b + byte + 3
    endloop
    return a
endfunction

function GetObjectData takes integer pData,integer rawcode returns integer
    local integer hash    = IntegerHash(rawcode)
    local integer list    = ReadRealMemory(pData) / 4 + ModuloInteger(hash, ReadRealMemory(pData + 8) + 1) * 3
    local integer i    = Memory[list + 2] / 4
    loop
        exitwhen i <= 0
        if Memory[i] == hash and Memory[i + 5] == rawcode then
            return i
        endif
        set i    =    Memory[Memory[list] / 4 + i + 1] / 4
    endloop
    return 0
endfunction

function GetObjectDataCaching takes integer pData, integer rawcode returns integer
    local integer k
    if HaveSavedInteger(ObjectDataPointersTable,pData,rawcode) then
        return LoadInteger(ObjectDataPointersTable,pData,rawcode)
    endif
    set k=GetObjectData(pData,rawcode)
    call SaveInteger(ObjectDataPointersTable,pData,rawcode,k)
    return k
endfunction

function ObjectData__Init takes nothing returns nothing
    set H[1]=0xA22E726E
    set H[2]=0xD43D94C0
    set H[3]=0x6DE064C7
    set H[4]=0xFE8D4B2F
    set H[5]=0x345A287E
    set H[6]=0x13941BCF
    set H[7]=0xD822114D
    set H[8]=0xA79E1270
    set H[9]=0xFB2D4CF9
    set H[10]=0xCB25DDAE
    set H[11]=0x7B5E64D5
    set H[12]=0x88544672
    set H[13]=0xF201BF3F
    set H[14]=0x677CAF6E
    set H[15]=0x34502020
    set H[16]=0x5DD18D92
    set H[18]=0x320F2252
    set H[19]=0xCBB1F259
    set H[20]=0x5C5ED8C1
    set H[21]=0x922BB610
    set H[22]=0x7165A961
    set H[23]=0x35F39EDF
    set H[24]=0x056FA002
    set H[25]=0x58FEDA8B
    set H[26]=0x28F76B40
    set H[27]=0xD92FF267
    set H[28]=0xE625D404
    set H[29]=0x4FD34CD1
    set H[30]=0xC54E3D00
    set H[31]=0x9221ADB2
    set H[32]=0x2BC26B40
    set H[33]=0xCDF0DDAE
    set H[35]=0x99A2D007
    set H[36]=0x2A4FB66F
    set H[37]=0x601C93BE
    set H[38]=0x3F56870F
    set H[39]=0x03E47C8D
    set H[40]=0xD3607DB0
    set H[41]=0x26EFB839
    set H[42]=0xF6E848EE
    set H[43]=0xA720D015
    set H[44]=0xB416B1B2
    set H[45]=0x1DC42A7F
    set H[46]=0x933F1AAE
    set H[47]=0x60128B60
    set H[48]=0x921F9B39
    set H[49]=0x344E0DA7
    set H[50]=0x665D2FF9
    set H[52]=0x90ACE668
    set H[53]=0xC679C3B7
    set H[54]=0xA5B3B708
    set H[55]=0x6A41AC86
    set H[56]=0x39BDADA9
    set H[57]=0x8D4CE832
    set H[58]=0x5D4578E7
    set H[59]=0x0D7E000E
    set H[60]=0x1A73E1AB
    set H[61]=0x84215A78
    set H[62]=0xF99C4AA7
    set H[63]=0xC66FBB59
    set H[64]=0x0172B4D1
    set H[65]=0xA3A1273F
    set H[66]=0xD5B04991
    set H[67]=0x6F531998
    set H[69]=0x35CCDD4F
    set H[70]=0x1506D0A0
    set H[71]=0xD994C61E
    set H[72]=0xA910C741
    set H[73]=0xFCA001CA
    set H[74]=0xCC98927F
    set H[75]=0x7CD119A6
    set H[76]=0x89C6FB43
    set H[77]=0xF3747410
    set H[78]=0x68EF643F
    set H[79]=0x35C2D4F1
    set H[80]=0xCBA5D782
    set H[81]=0x6DD449F0
    set H[82]=0x9FE36C42
    set H[83]=0x39863C49
    set H[84]=0xCA3322B1
    set H[86]=0xDF39F351
    set H[87]=0xA3C7E8CF
    set H[88]=0x7343E9F2
    set H[89]=0xC6D3247B
    set H[90]=0x96CBB530
    set H[91]=0x47043C57
    set H[92]=0x53FA1DF4
    set H[93]=0xBDA796C1
    set H[94]=0x332286F0
    set H[95]=0xFFF5F7A2
    set H[96]=0xEC6BE431
    set H[97]=0x8E9A569F
    set H[98]=0xC0A978F1
    set H[99]=0x5A4C48F8
    set H[100]=0xEAF92F60
    set H[101]=0x20C60CAF
    set H[103]=0xC48DF57E
    set H[104]=0x9409F6A1
    set H[105]=0xE799312A
    set H[106]=0xB791C1DF
    set H[107]=0x67CA4906
    set H[108]=0x74C02AA3
    set H[109]=0xDE6DA370
    set H[110]=0x53E8939F
    set H[111]=0x20BC0451
    set H[112]=0x27DDEEB3
    set H[113]=0xCA0C6121
    set H[114]=0xFC1B8373
    set H[115]=0x95BE537A
    set H[116]=0x266B39E2
    set H[117]=0x5C381731
    set H[118]=0x3B720A82
    set H[120]=0xCF7C0123
    set H[121]=0x230B3BAC
    set H[122]=0xF303CC61
    set H[123]=0xA33C5388
    set H[124]=0xB0323525
    set H[125]=0x19DFADF2
    set H[126]=0x8F5A9E21
    set H[127]=0x5C2E0ED3
    set H[128]=0x5861ED90
    set H[129]=0xFA905FFE
    set H[130]=0x2C9F8250
    set H[131]=0xC6425257
    set H[132]=0x56EF38BF
    set H[133]=0x8CBC160E
    set H[134]=0x6BF6095F
    set H[135]=0x3083FEDD
    set H[137]=0x538F3A89
    set H[138]=0x2387CB3E
    set H[139]=0xD3C05265
    set H[140]=0xE0B63402
    set H[141]=0x4A63ACCF
    set H[142]=0xBFDE9CFE
    set H[143]=0x8CB20DB0
    set H[144]=0x04D2B307
    set H[145]=0xA7012575
    set H[146]=0xD91047C7
    set H[147]=0x72B317CE
    set H[148]=0x035FFE36
    set H[149]=0x392CDB85
    set H[150]=0x1866CED6
    set H[151]=0xDCF4C454
    set H[152]=0xAC70C577
    set H[154]=0xCFF890B5
    set H[155]=0x803117DC
    set H[156]=0x8D26F979
    set H[157]=0xF6D47246
    set H[158]=0x6C4F6275
    set H[159]=0x3922D327
    set H[160]=0x34DA2252
    set H[161]=0xD70894C0
    set H[162]=0x0917B712
    set H[163]=0xA2BA8719
    set H[164]=0x33676D81
    set H[165]=0x69344AD0
    set H[166]=0x486E3E21
    set H[167]=0x0CFC339F
    set H[168]=0xDC7834C2
    set H[169]=0x30076F4B
    set H[171]=0xB0388727
    set H[172]=0xBD2E68C4
    set H[173]=0x26DBE191
    set H[174]=0x9C56D1C0
    set H[175]=0x692A4272
    set H[176]=0x84A19B2B
    set H[177]=0x26D00D99
    set H[178]=0x58DF2FEB
    set H[179]=0xF281FFF2
    set H[180]=0x832EE65A
    set H[181]=0xB8FBC3A9
    set H[182]=0x9835B6FA
    set H[183]=0x5CC3AC78
    set H[184]=0x2C3FAD9B
    set H[185]=0x7FCEE824
    set H[186]=0x4FC778D9
    set H[188]=0x0CF5E19D
    set H[189]=0x76A35A6A
    set H[190]=0xEC1E4A99
    set H[191]=0xB8F1BB4B
    set H[192]=0x77ABB98E
    set H[193]=0x19DA2BFC
    set H[194]=0x4BE94E4E
    set H[195]=0xE58C1E55
    set H[196]=0x763904BD
    set H[197]=0xAC05E20C
    set H[198]=0x8B3FD55D
    set H[199]=0x4FCDCADB
    set H[200]=0x1F49CBFE
    set H[201]=0x72D90687
    set H[202]=0x42D1973C
    set H[203]=0xF30A1E63
    set H[205]=0x69AD78CD
    set H[206]=0xDF2868FC
    set H[207]=0xABFBD9AE
    set H[208]=0x0DFE40C1
    set H[209]=0xB02CB32F
    set H[210]=0xE23BD581
    set H[211]=0x7BDEA588
    set H[212]=0x0C8B8BF0
    set H[213]=0x4258693F
    set H[214]=0x21925C90
    set H[215]=0xE620520E
    set H[216]=0xB59C5331
    set H[217]=0x092B8DBA
    set H[218]=0xD9241E6F
    set H[219]=0x895CA596
    set H[220]=0x96528733
    set H[222]=0x757AF02F
    set H[223]=0x424E60E1
    set H[224]=0x98835092
    set H[225]=0x3AB1C300
    set H[226]=0x6CC0E552
    set H[227]=0x0663B559
    set H[228]=0x97109BC1
    set H[229]=0xCCDD7910
    set H[230]=0xAC176C61
    set H[231]=0x70A561DF
    set H[232]=0x40216302
    set H[233]=0x93B09D8B
    set H[234]=0x63A92E40
    set H[235]=0x13E1B567
    set H[236]=0x20D79704
    set H[237]=0x8A850FD1
    set H[239]=0xCCD370B2
    set H[240]=0xCBAFDFE0
    set H[241]=0x6DDE524E
    set H[242]=0x9FED74A0
    set H[243]=0x399044A7
    set H[244]=0xCA3D2B0F
    set H[245]=0x000A085E
    set H[246]=0xDF43FBAF
    set H[247]=0xA3D1F12D
    set H[248]=0x734DF250
    set H[249]=0xC6DD2CD9
    set H[250]=0x96D5BD8E
    set H[251]=0x470E44B5
    set H[252]=0x54042652
    set H[253]=0xBDB19F1F
    set H[254]=0x332C8F4E
endfunction


//library ObjectData ends
//library Utils:

function ConvertHandle takes handle h returns integer
    if GetHandleId(h)>0 then
        return Memory[Memory[Memory[Memory[GameState] / 4 + 7] / 4 + 103] / 4 + GetHandleId(h) * 3 - 0x2FFFFF]
    endif
    return 0
endfunction

function ConvertPointer takes integer ptr returns integer
    local integer i= Memory[ptr / 4]
    if i < 0 then
        return Memory[Memory[pointers + 11] / 4 - i * 2 + 1]
    endif
    return Memory[Memory[pointers + 3] / 4 + i * 2 + 1]
endfunction

function GetUnitFlags takes unit u returns integer
    return Memory[ConvertHandle(u) / 4 + 23]
endfunction

function SetUnitFlags takes unit u,integer i returns nothing
    set Memory[ConvertHandle(u) / 4 + 23]=i
endfunction

function IsFlagBitSet takes integer flags, integer bit returns boolean
    return flags/bit*2147483648 != 0
endfunction

//armor types:
// 0 - Light; 1 - Medium; 2 - Heavy; 3 - Fortified; 4 - Normal; 5 - Hero; 6 - Divine; 7 - unarmored;
//rest seems to have Light properties
function GetUnitArmorType takes unit u returns integer
    return Memory[(ConvertHandle(u) + 0xE4)/4]
endfunction

function SetUnitArmorType takes unit u, integer id returns nothing
    set Memory[(ConvertHandle(u) + 0xE4)/4]=id
endfunction

function GetUnitArmor takes unit u returns real
    return indexToReal(Memory[ConvertHandle(u) / 4 + 56])
endfunction

function SetUnitArmor takes unit u,real r returns nothing
    set Memory[ConvertHandle(u) / 4 + 56]=cleanInt(realToIndex(r))
endfunction

function SetUnitTypeId takes unit u,integer i returns nothing
    set Memory[ConvertHandle(u) / 4 + 12]=i
endfunction

function GetUnitTypeIdReal takes integer i returns integer
    return Memory[i / 4 + 12]
endfunction

function SetUnitPhased takes unit u returns nothing
    local integer data= GetObjectDataCaching(pUnitData , GetUnitTypeId(u)) + 107
    local integer p1= Memory[data]
    local integer p2= Memory[data + 1]
//    call BJDebugMsg(Int2Hex((data-107)*4))
    set Memory[data]=8
    set Memory[data + 1]=16
    call SetUnitPathing(u, true)
    set Memory[data]=p1
    set Memory[data + 1]=p2
endfunction

function GetAbilityX takes ability a, integer x returns real
    if x==20 then
        return Memory[Memory[Memory[ConvertHandle(a)/4+21]/4+21]/4-(41-x)+1*26]*1.0
    else
        return indexToReal(Memory[Memory[Memory[ConvertHandle(a)/4+21]/4+21]/4-(41-x)+1*26])
    endif
endfunction

function SetAbilityX takes ability a, integer x, real d returns nothing
    if x==20 then
        set Memory[Memory[Memory[ConvertHandle(a)/4+21]/4+21]/4+1*26-(2+x)]=R2I(d)
    else
        set Memory[Memory[Memory[ConvertHandle(a)/4+21]/4+21]/4+1*26-(2+x)]=cleanInt(realToIndex(d))
    endif
endfunction


function GetUnitFlags_2 takes unit u returns integer
    return Memory[ConvertHandle(u) / 4 + 8]
endfunction

function SetUnitFlags_2 takes unit u,integer i returns nothing
    set Memory[ConvertHandle(u) / 4 + 8]=i
endfunction

// Real - addres in memory

function GetRealPlayerById takes integer i returns integer
    local integer pladdr =  Memory[pGlobalPlayerClass] + ( i * 4 ) + 0x58
    return Memory[pladdr/4]
endfunction

function GetLocalPlayerIdReal takes nothing returns integer
    return Memory[Memory[pGlobalPlayerClass]/4+0xA]
endfunction

function GetLocalPlayerReal takes nothing returns integer
    return GetRealPlayerById(GetLocalPlayerIdReal( ) )
endfunction


// Get Selected Unit
function GetPlayerSelectedUnitReal takes integer realplayer returns integer
    local integer pladdr = realplayer/4 + 0xD
    set pladdr = Memory[pladdr]
    set pladdr = pladdr + 0x1E0
    return Memory[pladdr/4]
endfunction


function SetPlayerSelectedUnitReal takes integer realplayer, integer pConvertedHandle returns nothing
    local integer pladdr = realplayer/4 + 0xD
    set pladdr = Memory[pladdr]
    set pladdr = pladdr + 0x1E0
    set Memory[pladdr/4] = pConvertedHandle
endfunction

function GetUnitVertexColorB takes unit u returns integer
    return GetByteFromInteger(Memory[(Memory[ConvertHandle(u) / 4 + 0xA]+328)/4],4)
endfunction

function GetUnitVertexColorG takes unit u returns integer
    return GetByteFromInteger(Memory[(Memory[ConvertHandle(u) / 4 + 0xA]+328)/4],3)
endfunction

function GetUnitVertexColorR takes unit u returns integer
    return GetByteFromInteger(Memory[(Memory[ConvertHandle(u) / 4 + 0xA]+328)/4],2)
endfunction

function GetUnitVertexColorA takes unit u returns integer
    return GetByteFromInteger(Memory[(Memory[ConvertHandle(u) / 4 + 0xA]+328)/4],1)
endfunction


function GetUnitVertexColorB_2 takes unit u returns integer
    return GetByteFromInteger(Memory[ConvertHandle(u) / 4 + 181],4)
endfunction

function GetUnitVertexColorG_2 takes unit u returns integer
    return GetByteFromInteger(Memory[ConvertHandle(u) / 4 + 181],3)
endfunction

function GetUnitVertexColorR_2 takes unit u returns integer
    return GetByteFromInteger(Memory[ConvertHandle(u) / 4 + 181],2)
endfunction

function GetUnitVertexColorA_2 takes unit u returns integer
    return GetByteFromInteger(Memory[ConvertHandle(u) / 4 + 181],1)
endfunction


function SetUnitColorDirectlyForAddresss takes integer pConvertedHandle, integer red, integer green, integer blue, integer alpha returns nothing
    //, real fadetime returns nothing
    local integer resultcolor = CreateInteger1(alpha,red,green,blue)
    local integer colorflag = 0
    set Memory[(Memory[pConvertedHandle / 4 + 0xA]+328)/4] = resultcolor
 
    //set Memory[(Memory[pConvertedHandle / 4 + 0xA]+324)/4] = cleanInt(realToIndex(fadetime))
    set Memory[(Memory[pConvertedHandle / 4 + 0xA]+320)/4] = 0
    set Memory[(Memory[pConvertedHandle / 4 + 0xA]+316)/4] = 0
 
    set colorflag = Memory[(Memory[pConvertedHandle / 4 + 0xA]+312)/4]
    if BitwiseAnd( colorflag, 0x800) == 0 then
        set Memory[(Memory[pConvertedHandle / 4 + 0xA]+312)/4] = BitwiseXor(colorflag, 0x800)
    endif
 
 
endfunction

function echo takes string s returns nothing
    if IsL1ch then
        call DisplayTimedTextToPlayer(LocalPlayer,0,0,30,s)
    endif
endfunction


function SetUnitColorDirectly takes unit u, integer red, integer green, integer blue, integer alpha returns nothing
//    call echo(Int2Hex(ConvertHandle(u)))
    call SetUnitColorDirectlyForAddresss(ConvertHandle(u),red,green,blue,alpha)
endfunction


function GetJassContext takes integer id returns integer
    return Memory[Memory[Memory[Memory[pJassEnvAddress]/4+5]/4+36]/4+id]
endfunction

function GetStringAddress takes string s returns integer
    return Memory[Memory[Memory[Memory[GetJassContext(1)/4+2589]/4+2]/4+SH2I(s)*4+2]/4+7]
endfunction

function WriteNullTerminatedString takes string s, integer i_address returns nothing
    set Memory[i_address/4] = GetStringAddress(s)
endfunction

function GetDefAddr takes integer id, integer class, integer first, integer currentOffset returns integer
    local integer FirstDataDefEntry = ReadRealMemory(first)
    local integer CurrentDefAddr = Memory[FirstDataDefEntry/4 + 2] + currentOffset
    local integer FirstDefAddr = CurrentDefAddr
    local integer CurrentDefId = 0
    local integer CurrentDefId2 = 0
    if FirstDataDefEntry == 0 then
        return 0
    endif
//    if HaveSavedInteger(Addresses,id,class)then
//        return LoadInteger(Addresses,id,class) - 0xC
//    endif
 
//    if HaveSavedInteger(Addresses,class,0)then
//        set CurrentDefAddr=LoadInteger(Addresses,class,0)
//        set FirstDefAddr=LoadInteger(Addresses,class,1)
//        call echo("address preloaded")
//    elseif HaveSavedInteger(Addresses,class,1)==false then
//        call echo("first address saved")
//        call SaveInteger(Addresses,class,1,FirstDefAddr)
//    endif
 
    loop
        set CurrentDefId = Memory[CurrentDefAddr/4+2]
   
//        call SaveInteger(Addresses,CurrentDefId,class,CurrentDefAddr)
//        call SaveInteger(Addresses,class,0,CurrentDefAddr)
//        call echo(Id2String(CurrentDefId))
        if HaveSavedInteger(ObjectDataPointersTable,class,CurrentDefId)==false then
//            call echo("Cached "+Id2String(CurrentDefId))
            call SaveInteger(ObjectDataPointersTable,class,CurrentDefId,CurrentDefAddr - 0xC)
        endif
        exitwhen CurrentDefId == id
   
        set CurrentDefAddr = Memory[CurrentDefAddr/4]
        if CurrentDefAddr == 0 or CurrentDefAddr == FirstDefAddr then
//            if CurrentDefAddr == 0 then
//                call echo("drop for null")
//            else
//                call echo("drop for start")
//            endif
            return 0
        endif
    endloop
 
    if CurrentDefAddr == 0 then
//        call echo("drop for zero")
        return 0
    endif
    return CurrentDefAddr - 0xC// as GetObjectData*4 but search only by id..
endfunction

function GetDefAddrCaching takes integer id, integer class, integer first, integer currentOffset returns integer
    if HaveSavedInteger(ObjectDataPointersTable,class,id) then
//        call echo("loaded")
        return LoadInteger(ObjectDataPointersTable,class,id)
    endif
    return GetDefAddr(id,class,first,currentOffset)
endfunction

function GetUnitDataDefAddr takes integer id returns integer
    return GetDefAddrCaching(id,DEF_ADR_UNIT_DATA,pUnitDataDefAddr,0xC)
endfunction

function GetUnitUIDefAddr takes integer id returns integer
    return GetDefAddrCaching(id,DEF_ADR_UNIT_UI,pUnitUIDefAddr,0x10)
endfunction

function GetAbilityDataDefAddr takes integer id returns integer
    return GetDefAddrCaching(id,DEF_ADR_ABILITY_DATA,pAbilityDataDefAddr,0xC)
endfunction

function GetAbilityUIDefAddr takes integer id returns integer
    return GetDefAddrCaching(id,DEF_ADR_ABILITY_UI,pAbilityUIDefAddr,0x10)
endfunction

//1 = str, 2 = int, 3 = agi
function GetHeroPrimaryAttribute takes unit u returns integer
    local integer a=ConvertHandle(u)
    if a>0 then
        set a=ReadRealMemory(a + 0x1F0)
        if a>0 then
            return ReadRealMemory(a+0xCC)
        endif
    endif
    return 0
endfunction

function GetHeroPrimaryAttributeById takes integer id returns integer
    local integer a=GetUnitDataDefAddr(id)
    if a>0 then
        return ReadRealMemory(a + 0x17C)
    endif
    return 0
endfunction

function SetHeroPrimaryAttribute takes unit u,integer i returns nothing
    if IsUnitIdType(GetUnitTypeId(u),UNIT_TYPE_HERO) then
        set Memory[Memory[ConvertHandle(u) / 4 + 124] / 4 + 51]=i
    endif
endfunction

function PrintJassNatives takes nothing returns nothing
    //[[[[Game.dll+ADA848]+14]+20]
    local integer FirstAddress = Memory[Memory[Memory[pJassEnvAddress]/4+0x5]/4+8]/4
    local integer NextAddress = FirstAddress
    call PreloadEndEx()
    call PreloadGenClear()
    call PreloadGenStart()
 
    loop
        set NextAddress = Memory[NextAddress]/4
        set testFunctionCount = testFunctionCount + 1
        call Preload("native add "+Int2Hex(Memory[NextAddress+0xC/4]))
        if NextAddress == FirstAddress or NextAddress == 0 then
            call PreloadGenEnd("natives"+R2S(GetRandomReal(0,500))+".txt")
            call PreloadGenClear()
            return
        endif
    endloop
endfunction





function SetAbilityManaCost takes integer abil, integer level, integer cost returns nothing
    local integer a=GetObjectDataCaching(pAbilityData, abil)
    if a>0 then
        set a=Memory[a+21]
        if a>0 then
            set Memory[a/4-22+level*26]=cost
        endif
    endif
endfunction

function GetAbilityManaCost takes integer abil, integer level returns integer
    local integer a=GetObjectDataCaching(pAbilityData, abil)
    if a>0 then
        set a=Memory[a+21]
        if a>0 then
            return Memory[a/4-22+level*26]
        endif
    endif
    return 0
endfunction

function GetAbilityManaCostAddr takes integer add, integer level returns integer
    if Memory[add/4+0x54/4]>0 then
        return Memory[Memory[add/4+0x54/4]/4+level*0x68/4]
    endif
    return 0
endfunction

function SetAbilityManaCostAddr takes integer add, integer level, integer mc returns nothing
    if Memory[add/4+0x54/4]>0 then
        set Memory[Memory[add/4+0x54/4]/4+level*0x68/4]=mc
    endif
endfunction

function SetAbilityCD takes integer abil, integer level, real cool returns nothing
    set Memory[Memory[GetObjectDataCaching(pAbilityData, abil)+21]/4-21+level*26]= cleanInt(realToIndex(cool))
endfunction

function GetAbilityCD takes integer abil, integer level returns real
    local integer a=GetObjectDataCaching(pAbilityData, abil)
    if a>0 then
        if Memory[a+21]>0 then
            return cleanReal(indexToReal(Memory[Memory[a+21]/4-21+level*26])) // need clean/indextoreal ?
        endif
    endif
    return 0.
endfunction

function GetAbilCastTime takes ability abil returns real
 return cleanReal(indexToReal(Memory[ConvertHandle(abil)/4 + 0x84/4] ))
endfunction

function SetAbilCastTime takes ability abil ,real r returns nothing
 set Memory[ConvertHandle(abil)/4 + 0x84/4] = cleanInt(realToIndex(r ))
endfunction

function GetAbilityMaxLevel takes integer abil returns integer
    local integer a
    if abil==0 then
        return 0
    endif
    set a=GetObjectDataCaching(pAbilityData, abil)
    if a>0 then
        return Memory[a+20]
    endif
    return 0
endfunction

function AddAbilityCooldown takes ability a, real seconds returns nothing
    local integer pData = Memory[ConvertHandle(a)/4+55]/4
    if pData != 0 then
        set Memory[pData+1] = cleanInt(realToIndex(seconds+cleanReal(indexToReal(Memory[pData+1]))))
        //set Memory[ConvertHandle(a)/4+45] = cleanInt(realToIndex(seconds+cleanReal(indexToReal(Memory[ConvertHandle(a)/4+45])))) This should not be modified together
    endif
endfunction

function AddAbilityCooldownConverted takes integer a, real seconds returns nothing
    local integer pData = Memory[a+55]/4
    if pData != 0 then
        set Memory[pData+1] = cleanInt(realToIndex(seconds+cleanReal(indexToReal(Memory[pData+1]))))
    endif
endfunction

function AddAbilityBaseCooldown takes ability a, real seconds returns nothing
    local integer pData = Memory[ConvertHandle(a)/4+45]
    if pData != 0 then
        set Memory[pData] = cleanInt(realToIndex(seconds))
    endif
endfunction

//This value holds the base cooldown of the ability at the last time it was casted. It’s used to calculate the % of elapsed cooldown.
//This is completely irrelevant for the gameplay, it’s used only to determine which frame of the cooldown model will be displayed.

function GetAbilityCurrentCooldown takes ability a returns real
    local integer pData = Memory[ConvertHandle(a)/4+55]/4
    if pData != 0 then
        return cleanReal(indexToReal(Memory[pData+1])) - cleanReal(indexToReal(Memory[Memory[pData+3]/4+16]))
    endif
    return .0
endfunction

function CopyCooldownStr takes integer from, integer to returns nothing
    local integer pData = Memory[from+55]
    if pData != 0 then
        //if Memory[to+55]==0 then
            set Memory[to+55]=pData
            //set Memory[to+52]=Memory[from+52]
            //set Memory[to+54]=to*4
            set Memory[to+45]=Memory[from+45]
            if IsFlagBitSet(Memory[to+8],512)==false then
                set Memory[to+8]=Memory[to+8]+512
//                call BJDebugMsg("add cd")
            else
//                call BJDebugMsg("already cd")
            endif
        //endif
    endif
endfunction

function GetAbilityCurrentCooldownConverted takes integer a returns real
    local integer pData = Memory[a+55]/4
    if pData != 0 then
        return cleanReal(indexToReal(Memory[pData+1])) - cleanReal(indexToReal(Memory[Memory[pData+3]/4+16]))
    endif
    return .0
endfunction

//This actually returns the timestamp, not the cooldown. To get the real cooldown you need to subtract this from the current game time.

function GetAbilityCooldownReal takes ability a returns real
    local integer pData = Memory[ConvertHandle(a)/4+55]/4
    if pData != 0 then
        return cleanReal(indexToReal(Memory[pData+1]))
    endif
    return 0.
endfunction

function IsAbilityOnCooldown takes integer z returns boolean
    return IsFlagBitSet(Memory[(z+0x20)/4],512)
endfunction

function SetAbilityDisabled takes integer pAbility, integer count returns nothing
    set Memory[pAbility/4+15] = count //not safe unless used with PauseUnit. Button will be blacked, but current casts of that ability won’t be interrupted.
endfunction

function GetAbilityDisabledCount takes integer pAbility returns integer
    return Memory[pAbility/4+15]
endfunction

function SetAbilityHidden takes integer pAbility, integer count returns nothing
    set Memory[pAbility/4+16] = count //This one is 100% safe. This hides the ability button, and order can’t be issued.
endfunction

function SetAbilityDisabled2 takes integer pAbility, integer count returns nothing
    set Memory[pAbility/4+17] = count //This one is used by Orb of Slow. Button is blacked, but cooldown is stil displayed.
endfunction

function GetAbilityDisabled2 takes integer pAbility returns integer
    return Memory[pAbility/4+17]//This one is used by Orb of Slow. Button is blacked, but cooldown is stil displayed.
endfunction

function DisableUnitsMovement takes unit u, boolean disable returns nothing
    local integer i=2
    if disable==false then
        set i=1
    endif
    call PauseUnit(u,true)
    call SetAbilityDisabled(Memory[ConvertHandle( u )/4+123], i)
    call PauseUnit(u,false)
endfunction
//pointer to 'Amov' is located at offset 123 of unit object, Aatk is at offset 122, and AInv is offset 124

//Hides all command buttons and sets the Ward flag. Unit will keep its current order, and player can’t give new orders
//Notice the the unit can’t be ordered with triggers as well. To issue an order you need to temporarily reenable control
function DisableUnitControl takes unit u returns nothing
    local integer pUnit = ConvertHandle(u)/4
    local integer flags = Memory[pUnit+146]
    local integer Amov = Memory[pUnit+123]/4+16
    local integer Aatk = Memory[pUnit+122]/4+16
//    call echo("disabled on "+GetUnitName(u))
    if not IsFlagBitSet(flags,512) then
        set Memory[pUnit+146] = flags + 512
    endif
    if Amov != 16 then
        set Memory[Amov] = Memory[Amov] + 1
    endif
    if Aatk != 16 then
        set Memory[Aatk] = Memory[Aatk] + 1
    endif
endfunction

//Removes the Ward flag and reenables Amov and Aatk
function EnableUnitControl takes unit u returns nothing
    local integer pUnit = ConvertHandle(u)/4
    local integer flags = Memory[pUnit+146]
    local integer Amov = Memory[pUnit+123]/4+16
    local integer Aatk = Memory[pUnit+122]/4+16
//    call echo("enabled on "+GetUnitName(u))
    if IsFlagBitSet(flags,512) then
        set Memory[pUnit+146] = flags - 512
    endif
    if Amov != 16 and Memory[Amov]>0 then
        set Memory[Amov] = Memory[Amov] - 1
    endif
    if Aatk != 16 and Memory[Aatk]>0 then
        set Memory[Aatk] = Memory[Aatk] - 1
    endif
endfunction


function SetUnitModel takes integer uiobjectaddr, string s returns nothing
    call WriteNullTerminatedString(s, uiobjectaddr+0x30 )
endfunction

function SetUnitModelUF takes unit u, string s returns nothing//user-friendly
    call SetUnitModel(GetUnitUIDefAddr(GetUnitTypeId(u)),s)
endfunction

function SetUnitModelUFAddress takes integer address, string s returns nothing
    call SetUnitModel(address,s)
endfunction

function GetUnitAttackAbilityForAddress takes integer pConvertedHandle returns integer
    return Memory[pConvertedHandle/4+0x1e8/4]
endfunction

function GetUnitAttackAbility takes unit u returns integer
    return GetUnitAttackAbilityForAddress(ConvertHandle(u))
endfunction

function GetUnitMoveAbilityForAddress takes integer pConvertedHandle returns integer
    return Memory[pConvertedHandle/4+0x1eC/4]
endfunction

function GetUnitMoveAbility takes unit u returns integer
    return GetUnitMoveAbilityForAddress(ConvertHandle(u))
endfunction

function GetUnitHeroAbilityForAddress takes integer pConvertedHandle returns integer
    return Memory[pConvertedHandle/4+0x1F0/4]
endfunction

function GetUnitHeroAbility takes unit u returns integer
    return GetUnitHeroAbilityForAddress(ConvertHandle(u))
endfunction

function GetUnitBuildAbilityForAddress takes integer pConvertedHandle returns integer
    return Memory[pConvertedHandle/4+0x1F4/4]
endfunction

function GetUnitBuildAbility takes unit u returns integer
    return GetUnitBuildAbilityForAddress(ConvertHandle(u))
endfunction

function GetUnitInventoryAbilityForAddress takes integer pConvertedHandle returns integer
    return Memory[pConvertedHandle/4+0x1F8/4]
endfunction

function GetUnitInventoryAbility takes unit u returns integer
    return GetUnitInventoryAbilityForAddress(ConvertHandle(u))
endfunction



// Alternative for sub_6F4786B0 (126a)
function GetSomeAddress takes integer pAddr1 ,integer pAddr2 returns integer //I just split your function into 2, it should be working as before
    local integer pOff1 = 44
 
    if BitwiseAnd(pAddr1,pAddr2) == -1 then
      return 0
    endif
 
    if pAddr1 >= 0 then
      set pOff1 = 12
    endif
 
    set pOff1 = Memory[pGameClass1]/4 + pOff1/4
    set pOff1 = Memory[pOff1]
 
    if pOff1 == 0 then
      return 0
    endif
 
    set pOff1 = pOff1 + 8 * pAddr1 + 4
 
    set pOff1 = Memory[pOff1/4]
 
    if pOff1 == 0 or Memory[pOff1/4 + 0x18/4] != pAddr2 then
      return 0
    endif
 
    return pOff1
 
endfunction

function GetSomeAddressForAbility takes integer pAddr1 ,integer pAddr2 returns integer //Second part of GetSomeAddressForAbility
    local integer pOff1 = GetSomeAddress(pAddr1,pAddr2)
    if pOff1==0 or Memory[pOff1/4 + 0x20/4] != 0 then
      return 0
    endif
    return Memory[pOff1/4+0x54/4]
endfunction

function GetSomeAddressForLocustFlags takes integer pAddr1 ,integer pAddr2 returns integer
    local integer i = GetSomeAddress(pAddr1,pAddr2)
    return Memory[i/4+37]
endfunction

function SetLocustFlags takes unit u, integer i returns nothing //These flags can make unit immune to truesight
    local integer pOff1 = ConvertHandle(u)/4+91
    set pOff1 = GetSomeAddressForLocustFlags(Memory[pOff1], Memory[pOff1+1])
    set Memory[pOff1/4+13] = i
endfunction

function EnableTruesightImmunity takes unit u returns nothing
//I don’t really know what other side effects may be caused by this, at least GroupEnum is not affected
    call SetLocustFlags(u, 0x08000000)
endfunction

function DisableTruesightImmunity takes unit u returns nothing
    call SetLocustFlags(u, 0)
endfunction

function UnStunUnit takes unit u returns nothing
    set Memory[ConvertHandle(u)/4+102] = 0
endfunction

function IsUnitStunned2 takes unit u returns boolean
    return Memory[ConvertHandle(u)/4+102] > 0
endfunction

function IsUnitInvulnerable takes unit u returns boolean
    local integer k
//    call BJDebugMsg(GetUnitName(u))
    if u==null then
        return false
    endif
    set k=ConvertHandle(u)
    if k==0 then
        return false
    endif
    return Memory[k/4+8]/8*0x80000000 != 0
endfunction

function GetUnitInvulnerableCounter takes unit u returns integer
    local integer k
    if u==null then
        return 0
    endif
    set k=ConvertHandle(u)
    if k==0 then
        return 0
    endif
    return Memory[k/4+0xE8/4]
endfunction

function SetUnitInvulnerableCounter takes unit u, integer i returns nothing
    local integer k
    if u==null then
        return
    endif
    set k=ConvertHandle(u)
    if k==0 then
        return
    endif
    set Memory[k/4+0xE8/4]=i
endfunction

function GetUnitAbilityForAddresss takes integer pConvertedHandle, integer abilid returns integer
    local integer pAddr1 = pConvertedHandle + 476
    local integer pAddr2 = pConvertedHandle + 480
    local integer pOff1 = 0
    set pAddr1 = Memory[pAddr1/4]
    set pAddr2 = Memory[pAddr2/4]
    if pAddr1 == 0 or pAddr2 == 0 or BitwiseAnd(pAddr1,pAddr2) == -1 then
        return 0
    endif
    set pOff1 = GetSomeAddressForAbility(pAddr1,pAddr2)
    if pOff1 == 0 then
        return 0
    endif
    loop
        exitwhen pOff1 == 0
        if Memory[pOff1/4+52/4] == abilid then
        return pOff1
        endif
        set pOff1 = GetSomeAddressForAbility( Memory[pOff1/4+36/4], Memory[pOff1/4+40/4])
    endloop
    return pOff1
endfunction

function GetAbilityOrderID takes integer pAbility returns integer
    local integer pOffset2
    local integer pOffset1
    if pAbility<1 then
        return 0
    endif
//    call BJDebugMsg(Int2Hex(pAbility)+" sent")
//    call PolledWait(1.)

    //  mov ecx,[esp+04]
    //  mov edx,[ecx+6C]
    //  cmp edx,D0142 { 852290 }
    //  je 0493413A
    //  mov eax,00000000 { 0 }
    //  ret
    //  mov ecx,[ecx]
    //  mov ecx,[ecx+00000308]
    //  call ecx
    //  ret

 
    set Memory[pReservedExecutableMemory/4] = 0x04244C8B
    set Memory[pReservedExecutableMemory/4 + 1] = 0x816C518B
    set Memory[pReservedExecutableMemory/4 + 2] = 0x0D0142FA
    set Memory[pReservedExecutableMemory/4 + 3] = 0xB8067400
    set Memory[pReservedExecutableMemory/4 + 4] = 0x00000000
    set Memory[pReservedExecutableMemory/4 + 5] = 0x8B098BC3
    set Memory[pReservedExecutableMemory/4 + 6] = 0x00030889
    set Memory[pReservedExecutableMemory/4 + 7] = 0x90E1FF00
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 

    if pIgnoredUnitsOffset != 0 then
        set pOffset2 = IgnoredUnits(pAbility)
        call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
        return pOffset2
    endif
 
    return 0
endfunction

function PrintAllUnitAbilities takes integer pConvertedHandle returns nothing
    local integer pAddr1 = pConvertedHandle + 476
    local integer pAddr2 = pConvertedHandle + 480

    local integer pOff1 = 0

    set pAddr1 = Memory[pAddr1/4]
    set pAddr2 = Memory[pAddr2/4]
    if pAddr1 == 0 or pAddr2 == 0 or BitwiseAnd(pAddr1,pAddr2) == -1 then
        return
    endif

    set pOff1 = GetSomeAddressForAbility(pAddr1,pAddr2)
 
    if pOff1 == 0 then
        return
    endif
 
    loop
        exitwhen pOff1 == 0

        call DisplayTextToPlayer(GetLocalPlayer(),0.0,0.0,"Address:"+Int2Hex(pOff1)+". ID:"+Id2String(Memory[pOff1/4+52/4])+" name: "+GetObjectName(Memory[pOff1/4+52/4]))
   
        set pOff1 = GetSomeAddressForAbility( Memory[pOff1/4+36/4], Memory[pOff1/4+40/4])
    endloop
 
endfunction

//function PrintAllUnitAbilitiesOld takes integer pConvertedHandle returns nothing
//    local integer pAddr1 = pConvertedHandle + 476
//    local integer pAddr2 = pConvertedHandle + 480
//
//    local integer pOff1 = 0
//
//    set pAddr1 = Memory[pAddr1/4]
//    set pAddr2 = Memory[pAddr2/4]
//    if pAddr1 == 0 or pAddr2 == 0 or BitwiseAndOld(pAddr1,pAddr2) == -1 then
//        return
//    endif
//
//    set pOff1 = GetSomeAddressForAbility(pAddr1,pAddr2)
//
//    if pOff1 == 0 then
//        return
//    endif
//
//    loop
//        exitwhen pOff1 == 0
//
//        call DisplayTextToPlayer(GetLocalPlayer(),0.0,0.0,"Address:"+Int2Hex(pOff1)+". ID:"+Id2String(Memory[pOff1/4+52/4])+" name: "+GetObjectName(Memory[pOff1/4+52/4]))
//   
//        set pOff1 = GetSomeAddressForAbility( Memory[pOff1/4+36/4], Memory[pOff1/4+40/4])
//    endloop
//
//endfunction

function GetAllUnitAbilities takes unit u returns nothing
    local integer pConvertedHandle=ConvertHandle(u)
    local integer pAddr1 = pConvertedHandle + 476
    local integer pAddr2 = pConvertedHandle + 480
    local integer i=0
    local integer h=GetHandleId(u)
    local integer pOff1 = 0
    call FlushChildHashtable(TempHash,h)
 
    set pAddr1 = Memory[pAddr1/4]
    set pAddr2 = Memory[pAddr2/4]
    if pAddr1 == 0 or pAddr2 == 0 or BitwiseAnd(pAddr1,pAddr2) == -1 then
        return
    endif

    set pOff1 = GetSomeAddressForAbility(pAddr1,pAddr2)
 
    if pOff1 == 0 then
        return
    endif
 
    loop
        exitwhen pOff1 == 0

//        call DisplayTextToPlayer(GetLocalPlayer(),0.0,0.0,"Address:"+Int2Hex(pOff1)+". ID:"+Id2String(Memory[pOff1/4+52/4])+" name: "+GetObjectName(Memory[pOff1/4+52/4]))
        if Memory[pOff1/4+0x34/4]!='Amov' and Memory[pOff1/4+0x34/4]!='AHer' and Memory[pOff1/4+0x34/4]!='Aatk' and Memory[pOff1/4+0x34/4]!='AInv' then
            call SaveInteger(TempHash,h,i,pOff1)//address
            call SaveInteger(TempHash,h+1,i,Memory[pOff1/4+0x34/4])//ability id
            set i=i+1
        endif
        set pOff1 = GetSomeAddressForAbility( Memory[pOff1/4+36/4], Memory[pOff1/4+40/4])
        //facepalm
    endloop
 
    call SaveInteger(TempHash,'abil',0,i)
endfunction



function CallFastCallWith1Args takes integer pFuncFastcallAddr, integer arg1 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0xB9F68B56)
    call WriteRealMemory(pReservedExecutableMemory2+4, arg1)
    call WriteRealMemory(pReservedExecutableMemory2+8, 0xBEF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+12, pFuncFastcallAddr)
    call WriteRealMemory(pReservedExecutableMemory2+16, 0xC35ED6FF)
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction


function CallFastCallWith2Args takes integer pFuncFastcallAddr, integer arg1, integer arg2 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0xBAF68B56)
    call WriteRealMemory(pReservedExecutableMemory2+4, arg2)
    call WriteRealMemory(pReservedExecutableMemory2+8, 0xB9F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+12, arg1)
    call WriteRealMemory(pReservedExecutableMemory2+16, 0xBEF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+20, pFuncFastcallAddr)
    call WriteRealMemory(pReservedExecutableMemory2+24, 0xC35ED6FF)
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction


function CallFastCallWith3Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
    call WriteRealMemory(pReservedExecutableMemory2+4, arg3)
    call WriteRealMemory(pReservedExecutableMemory2+8, 0xBAF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+12, arg2)
    call WriteRealMemory(pReservedExecutableMemory2+16, 0xB9F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+20, arg1)
    call WriteRealMemory(pReservedExecutableMemory2+24, 0xBEF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+28, pFuncFastcallAddr)
    call WriteRealMemory(pReservedExecutableMemory2+32, 0xC35ED6FF)
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction


function FUCKINGCallWith4Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
    call WriteRealMemory(pReservedExecutableMemory2+4, arg4)
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+12, arg3)
    call WriteRealMemory(pReservedExecutableMemory2+16, 0xB8F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+20, arg2)
    call WriteRealMemory(pReservedExecutableMemory2+24, 0xBFF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+28, arg1)
    call WriteRealMemory(pReservedExecutableMemory2+32, 0xBEF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+36, pFuncFastcallAddr)
    call WriteRealMemory(pReservedExecutableMemory2+40, 0xC35ED6FF)

    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction

function CallFastCallWith4Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
    call WriteRealMemory(pReservedExecutableMemory2+4, arg4)
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+12, arg3)
    call WriteRealMemory(pReservedExecutableMemory2+16, 0xBAF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+20, arg2)
    call WriteRealMemory(pReservedExecutableMemory2+24, 0xB9F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+28, arg1)
    call WriteRealMemory(pReservedExecutableMemory2+32, 0xBEF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+36, pFuncFastcallAddr)
    call WriteRealMemory(pReservedExecutableMemory2+40, 0xC35ED6FF)
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction


function CallFastCallWith5Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
    call WriteRealMemory(pReservedExecutableMemory2+4, arg5)
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+12, arg4)
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+20, arg3)
    call WriteRealMemory(pReservedExecutableMemory2+24, 0xBAF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+28, arg2)
    call WriteRealMemory(pReservedExecutableMemory2+32, 0xB9F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+36, arg1)
    call WriteRealMemory(pReservedExecutableMemory2+40, 0xBEF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+44, pFuncFastcallAddr)
    call WriteRealMemory(pReservedExecutableMemory2+48, 0xC35ED6FF)
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction




function CallFastCallWith6Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
    call WriteRealMemory(pReservedExecutableMemory2+4, arg6)
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+12, arg5)
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+20, arg4)
    call WriteRealMemory(pReservedExecutableMemory2+24, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+28, arg3)
    call WriteRealMemory(pReservedExecutableMemory2+32, 0xBAF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+36, arg2)
    call WriteRealMemory(pReservedExecutableMemory2+40, 0xB9F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+44, arg1)
    call WriteRealMemory(pReservedExecutableMemory2+48, 0xBEF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+52, pFuncFastcallAddr)
    call WriteRealMemory(pReservedExecutableMemory2+56, 0xC35ED6FF)
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction



function CallFastCallWith7Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6, integer arg7 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
    call WriteRealMemory(pReservedExecutableMemory2+4, arg7)
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+12, arg6)
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+20, arg5)
    call WriteRealMemory(pReservedExecutableMemory2+24, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+28, arg4)
    call WriteRealMemory(pReservedExecutableMemory2+32, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+36, arg3)
    call WriteRealMemory(pReservedExecutableMemory2+40, 0xBAF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+44, arg2)
    call WriteRealMemory(pReservedExecutableMemory2+48, 0xB9F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+52, arg1)
    call WriteRealMemory(pReservedExecutableMemory2+56, 0xBEF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+60, pFuncFastcallAddr)
    call WriteRealMemory(pReservedExecutableMemory2+64, 0xC35ED6FF)
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction


function CallFastCallWith8Args takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6, integer arg7, integer arg8 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68F68B56)
    call WriteRealMemory(pReservedExecutableMemory2+4, arg8)
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+12, arg7)
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+20, arg6)
    call WriteRealMemory(pReservedExecutableMemory2+24, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+28, arg5)
    call WriteRealMemory(pReservedExecutableMemory2+32, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+36, arg4)
    call WriteRealMemory(pReservedExecutableMemory2+40, 0x68F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+44, arg3)
    call WriteRealMemory(pReservedExecutableMemory2+48, 0xBAF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+52, arg2)
    call WriteRealMemory(pReservedExecutableMemory2+56, 0xB9F68B90)
    call WriteRealMemory(pReservedExecutableMemory2+60, arg1)
    call WriteRealMemory(pReservedExecutableMemory2+64, 0xBEF68B90)
    call WriteRealMemory(pReservedExecutableMemory2+68, pFuncFastcallAddr)
    call WriteRealMemory(pReservedExecutableMemory2+72, 0xC35ED6FF)
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction




function CallThisCallWith1Args takes integer pFuncThiscallAddr, integer arg1 returns integer
    return CallFastCallWith2Args(pFuncThiscallAddr,arg1,0)
endfunction

function CallThisCallWith2Args takes integer pFuncThiscallAddr, integer arg1, integer arg2 returns integer
    return CallFastCallWith3Args(pFuncThiscallAddr,arg1,0,arg2)
endfunction

function CallThisCallWith3Args takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3 returns integer
    return CallFastCallWith4Args(pFuncThiscallAddr,arg1,0,arg2,arg3)
endfunction

function CallThisCallWith4Args takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4 returns integer
    return CallFastCallWith5Args(pFuncThiscallAddr,arg1,0,arg2,arg3,arg4)
endfunction

function CallThisCallWith5Args takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5 returns integer
    return CallFastCallWith6Args(pFuncThiscallAddr,arg1,0,arg2,arg3,arg4,arg5)
endfunction

function CallThisCallWith6Args takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5, integer arg6 returns integer
    return CallFastCallWith7Args(pFuncThiscallAddr,arg1,0,arg2,arg3,arg4,arg5,arg6)
endfunction

function CallThisCallWith7Args takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5, integer arg6, integer arg7 returns integer
    return CallFastCallWith8Args(pFuncThiscallAddr,arg1,0,arg2,arg3,arg4,arg5,arg6,arg7)
endfunction

function GetUnitAbilityReal takes integer UnitAddress, integer AbilCode, integer unk1, integer unk2, integer unk3, integer unk4 returns integer
    return CallThisCallWith6Args(pGetUnitAbility,UnitAddress,AbilCode,unk1,unk2, unk3, unk4)
endfunction

function GetUnitAddress takes unit u returns integer
    return CallThisCallWith1Args(pGetUnitAddress, GetHandleId(u))
endfunction


function GetUnitAbility takes unit u, integer abilid returns integer
    if u==null then
        return 0
    endif
    return CallThisCallWith6Args(pGetUnitAbility,GetUnitAddress(u),abilid,0, 1, 1, 1)
endfunction

//function GetUnitAbility takes unit u, integer abilid returns integer
//
//
//    if abilid == 'Aatk' then
//        return GetUnitAttackAbility(u)
//    endif
//    if abilid == 'Amov' then
//        return GetUnitMoveAbility(u)
//    endif
//    if abilid == 'AHer' then
//        return GetUnitHeroAbility(u)
//    endif
//    if abilid == 'AObu' or abilid == 'AUbu' or abilid == 'ANbu' or abilid == 'AHbu' or abilid == 'AEbu' or abilid == 'AGbu' then
//        return GetUnitBuildAbility(u)
//    endif
//    if abilid == 'AInv' then
//        return GetUnitInventoryAbility(u)
//    endif
//
//    return GetUnitAbilityForAddresss(ConvertHandle(u),abilid)
//endfunction

function GetAbilityOrderIDbyID takes integer id returns integer
    local integer a
    if HaveSavedInteger(AbilitiesHashtable,id,'ordr') then
        return LoadInteger(AbilitiesHashtable,id,'ordr')
    endif
    if id=='AHer' or id=='ANeg' or id=='Aatk' or id=='AInv' then
        call SaveInteger(AbilitiesHashtable,id,'ordr',0)
        return 0
    endif
//    call BJDebugMsg("Requested "+Int2Hex(id))
    set bj_lastCreatedUnit=CreateUnit(Player(0),'e00E',0,0,0)
    call UnitAddAbility(bj_lastCreatedUnit,id)
    set a=GetUnitAbility(bj_lastCreatedUnit,id)
    set a=GetAbilityOrderID(a)
    call SaveInteger(AbilitiesHashtable,id,'ordr',a)
    return a
endfunction

function GetAbilityOrderIdAny takes integer a returns integer
    local integer base
    if Memory[(a+0x54)/4]!=0 and Memory[(a+0x6C)/4]!=0 then
        set base=Memory[(Memory[(a+0x54)/4]+0x30)/4]
//        call echo(Id2String(base))
        if base>0 and base!='ANcl' then
            return GetAbilityOrderIDbyID(base)
//            return 0
        elseif base=='ANcl' then
            return Memory[(a+0x124)/4]
        endif
    endif
    return 0
endfunction

function ShowAbilityById_Main takes integer ConvertedHandle, integer d returns nothing
    if ConvertedHandle!=0 then
        if Memory[ConvertedHandle/4]!=0 then
            set Memory[(ConvertedHandle + 0x40)/4]=Memory[(ConvertedHandle + 0x40)/4]+d
        endif
    endif
endfunction

function HideAbilityButton takes unit u, integer id, boolean hide returns nothing
    local integer offset
    if u!=null and id!=0 then
        set offset=GetUnitAbility(u,id)
        if offset!=0 then
            if hide then
                call ShowAbilityById_Main(offset,1)
            else
                call ShowAbilityById_Main(offset,-1)
            endif
        endif
    endif
endfunction

function GetSpellCastpoint takes ability a returns real
    return cleanReal(indexToReal(Memory[(ConvertHandle(a)+0x8C)/4]))
endfunction

function SetSpellCastpoint takes ability a, real dur returns nothing
    set Memory[(ConvertHandle(a)+0x8C)/4]=cleanInt(realToIndex(dur))
endfunction

function GetSpellBackswing takes ability a returns real
    return cleanReal(indexToReal(Memory[(ConvertHandle(a)+0x94)/4]))
endfunction

function SetSpellBackswing takes ability a, real dur returns nothing
    set Memory[(ConvertHandle(a)+0x94)/4]=cleanInt(realToIndex(dur))
endfunction

function ToggleAbilityAutocast takes integer address, boolean on returns nothing
    local integer flags
    local integer flag128=0//0 if enabled
    local integer flag524288=0
    if address>0 then
        set flags=Memory[(address+0x20)/4]
        if BitwiseAnd(flags,0x80)==0 then
            set flag128=0x80//not enabled
//            call echo("not enabled")
//        else
//            call echo("enabled")
        endif
        if BitwiseAnd(flags,0x80000)==0 then
            set flag524288=0x80000//not enabled
        endif
        if on and flag128>0 then
            set flags=flags+flag128
        elseif on==false and flag128==0 then
            set flags=flags-0x80
        endif
        if on and flag524288>0 then
            set flags=flags+flag524288
        elseif on==false and flag524288==0 then
            set flags=flags-0x80000
        endif
        set Memory[(address+0x20)/4]=flags
    endif
endfunction

function SetUnitAbiltyAutocast takes unit u, integer id, boolean on returns nothing
    call ToggleAbilityAutocast(GetUnitAbility(u,id),on)
endfunction

function SetUnitAttackType takes unit u, integer i, integer attacknum returns nothing
    if attacknum==1 then
        set Memory[(GetUnitAttackAbility(u) + 0xF4)/4]=i
    elseif attacknum==2 then
        set Memory[(GetUnitAttackAbility(u) + 0xF8)/4]=i
    endif
endfunction

function SetUnitAttackType1 takes unit u, integer i returns nothing
    call SetUnitAttackType(u,i,1)
endfunction

function SetUnitAttackType2 takes unit u, integer i returns nothing
    call SetUnitAttackType(u,i,2)
endfunction

//6 = hero, 5 = chaos, 4 = magic, 3 = siege, 2 = piercing, 1 = normal, 0 = spell?
//values over 6 takes incorrect multipliers from nearby memory, do not use them
function GetUnitAttackType1 takes unit u returns integer
    return Memory[GetUnitAttackAbility(u)/4 + 0xF4/4]
endfunction

function GetUnitAttackType2 takes unit u returns integer
    return Memory[GetUnitAttackAbility(u)/4 + 0xF8/4]
endfunction

//unit's weapon type is melee, ranged, splash, artillery, etc
//values 1-8
// 2 = ranger, 1 = instante, 0 = melee, 5 = splash, 6 = mbounce,
function SetUnitWeaponType takes unit u, integer i returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0xDC/4]=i
endfunction

function GetUnitWeaponType takes unit u returns integer
    return Memory[GetUnitAttackAbility(u)/4 + 0xDC/4]
endfunction

//setting green bonus automatically adjusts base damage to fit
function SetUnitGreenBonusDamage takes unit u, integer i returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0xAC/4]=i
endfunction

function GetUnitGreenBonusDamage takes unit u returns integer
    return Memory[GetUnitAttackAbility(u)/4 + 0xAC/4]
endfunction

function AddUnitGreenBonusDamage takes unit u, integer i returns nothing
    call SetUnitGreenBonusDamage(u,GetUnitGreenBonusDamage(u)+i)
endfunction

function SetUnitBaseDamage takes unit u, integer i returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0xA0/4]=i
endfunction

function GetUnitBaseDamage takes unit u returns integer
    return Memory[GetUnitAttackAbility(u)/4 + 0xA0/4]
endfunction

function AddUnitBaseDamage takes unit u, integer bonus returns nothing
    call SetUnitBaseDamage(u,GetUnitBaseDamage(u)+bonus)
endfunction

function SetUnitBaseAttributeDamage takes unit u, integer i returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0xA4/4]=i
endfunction

function GetUnitBaseAttributeDamage takes unit u returns integer
    return Memory[GetUnitAttackAbility(u)/4 + 0xA4/4]
endfunction

function SetUnitDamageDicesSideCount takes unit u, integer i returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0x94/4]=i
endfunction

function GetUnitDamageDicesSideCount takes unit u returns integer
    return Memory[GetUnitAttackAbility(u)/4 + 0x94/4]
endfunction

function SetUnitDamageDicesCount takes unit u, integer i returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0x88/4]=i
endfunction

function GetUnitDamageDicesCount takes unit u returns integer
    local integer a=GetUnitAttackAbility(u)
    if a>0 then
        return Memory[a/4 + 0x88/4]
    endif
    return 0
endfunction

function SetUnitAttackRange1 takes unit u, real r returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0x258/4]=cleanInt(realToIndex(r))
endfunction

function GetUnitAttackRange1 takes unit u returns real
    return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x258/4]))
endfunction

function SetUnitAttackRange2 takes unit u, real r returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0x27C/4]=cleanInt(realToIndex(r))
endfunction

function GetUnitAttackRange2 takes unit u returns real
    return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x27C/4]))
endfunction

function SetUnitBAT1 takes unit u, real r returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0x158/4]=cleanInt(realToIndex(r))
endfunction

function GetUnitBAT1 takes unit u returns real
    return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x158/4]))
endfunction

function SetUnitBAT2 takes unit u, real r returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0x160/4]=cleanInt(realToIndex(r))
endfunction

function GetUnitBAT2 takes unit u returns real
    return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x160/4]))
endfunction

function SetUnitAttackPoint1 takes unit u, real r returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0x16C/4]=cleanInt(realToIndex(r))
endfunction

function SetUnitAttackPoint2 takes unit u, real r returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0x17C/4]=cleanInt(realToIndex(r))
endfunction

function GetUnitAttackPoint1 takes unit u returns real
    return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x16C/4]))
endfunction

function GetUnitAttackPoint2 takes unit u returns real
    return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x17C/4]))
endfunction

function GetUnitAttackEnabledIndex takes unit u returns integer
    return Memory[GetUnitAttackAbility(u)/4 + 0x104/4]
endfunction

function SetUnitAttackBackswing takes unit u, real r returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0x190/4]=cleanInt(realToIndex(r))
endfunction

function GetUnitAttackBackswing takes unit u returns real
    return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x190/4]))
endfunction

function SetUnitAttackSpeed takes unit u, real r returns nothing
    set Memory[GetUnitAttackAbility(u)/4 + 0x1B0/4]=cleanInt(realToIndex(r))
endfunction

function GetUnitAttackSpeed takes unit u returns real
    return cleanReal(indexToReal(Memory[GetUnitAttackAbility(u)/4 + 0x1B0/4]))
endfunction

function AddUnitAttackSpeed takes unit u, real r returns nothing
    call SetUnitAttackSpeed(u,GetUnitAttackSpeed(u)+r)
endfunction

function GetUnitAddressFloatsRelated takes integer pConvertedHandle, integer step returns integer
    local integer pOffset1 = pConvertedHandle + step
    local integer pOffset2 = Memory[pGameClass1]
    set pOffset1 = Memory[pOffset1/4]
    set pOffset2 = Memory[(pOffset2+0xC)/4]
    set pOffset2 = Memory[(( pOffset1 * 8 ) + pOffset2 + 4)/4]
    return pOffset2
endfunction

function SetUnitFacingInstant takes unit u, real a returns nothing
    local integer pOffset2 = GetUnitAddressFloatsRelated(ConvertHandle(u),0xA0)
    set Memory[Memory[(pOffset2+0x28)/4]/4 +0xA4/4]=cleanInt(realToIndex(bj_DEGTORAD*a))
endfunction

function SetUnitMaxHP4Address takes integer pConvertedHandle, real newhp returns nothing
    local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xA0)
    set Memory[(pOffset2+0x84)/4]=cleanInt(realToIndex(newhp))
endfunction

function SetUnitMaxMP4Address takes integer pConvertedHandle, real newmp returns nothing
    local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xC0)
    set Memory[(pOffset2+0x84)/4]=cleanInt(realToIndex(newmp))
endfunction

function SetUnitMaxHP takes unit u, real newhp returns nothing
    call SetUnitMaxHP4Address(ConvertHandle(u),newhp)
endfunction

function SetUnitMaxMP takes unit u, real newmp returns nothing
    call SetUnitMaxMP4Address(ConvertHandle(u),newmp)
endfunction

function GetUnitHPRegenForAddress takes integer pConvertedHandle returns real
    local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xA0)
    return cleanReal(indexToReal(Memory[(pOffset2+0x7C)/4]))
endfunction

function SetUnitXSoft takes integer pConvertedHandle, real x returns nothing
    local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xA0)
    set Memory[Memory[(pOffset2+0x28)/4]/4+0x54/4]=SetRealIntoMemory(x)
endfunction

function SetUnitHPRegenForAddress takes integer pConvertedHandle, real r returns nothing
    local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xA0)
    set Memory[(pOffset2+0x7C)/4]=cleanInt(realToIndex(r))
endfunction

function GetUnitMPRegenForAddress takes integer pConvertedHandle returns real
    local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xC0)
//    call echo(Int2Hex(pOffset2))
    return cleanReal(indexToReal(Memory[(pOffset2+0x7C)/4]))
endfunction

function SetUnitMPRegenForAddress takes integer pConvertedHandle, real r returns nothing
    local integer pOffset2 = GetUnitAddressFloatsRelated(pConvertedHandle,0xC0)
    set Memory[(pOffset2+0x7C)/4]=cleanInt(realToIndex(r))
endfunction

function GetUnitHPRegen takes unit u returns real
    return GetUnitHPRegenForAddress(ConvertHandle(u))
endfunction

function GetWidgetHPRegen takes widget u returns real
    return GetUnitHPRegenForAddress(ConvertHandle(u))
endfunction

function GetUnitMPRegen takes unit u returns real
    return GetUnitMPRegenForAddress(ConvertHandle(u))
endfunction

function SetUnitHPRegen takes unit u, real r returns nothing
    local real curhp=GetWidgetLife(u)
    if curhp>0 then
        call SetUnitHPRegenForAddress(ConvertHandle(u),r)
        call SetWidgetLife(u,curhp)
    endif
endfunction

function AddUnitHPRegen takes unit u, real r returns nothing
    local real curhp=GetWidgetLife(u)
    local integer h
    if curhp>0 then
        set h=ConvertHandle(u)
        call SetUnitHPRegenForAddress(h,r+GetUnitHPRegenForAddress(h))
        call SetWidgetLife(u,curhp)
    endif
endfunction

function SetUnitMPRegen takes unit u, real r returns nothing
    local real curhp=GetUnitState(u,UNIT_STATE_MANA)
    if GetUnitState(u,UNIT_STATE_MAX_MANA)>0 then
        call SetUnitMPRegenForAddress(ConvertHandle(u),r)
        call SetUnitState(u,UNIT_STATE_MANA,curhp)
    endif
endfunction

function AddUnitMPRegen takes unit u, real r returns nothing
    local real curhp=GetUnitState(u,UNIT_STATE_MANA)
    local integer h
    if GetUnitState(u,UNIT_STATE_MAX_MANA)>0 then
        set h=ConvertHandle(u)
        call SetUnitMPRegenForAddress(h,r+GetUnitMPRegenForAddress(h))
        call SetUnitState(u,UNIT_STATE_MANA,curhp)
    endif
endfunction



function SetEffectX_ForAddress takes integer pConvertedHandle, real r returns nothing
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC0/4] = cleanInt(realToIndex(r))
endfunction
function SetEffectX takes effect e, real r returns nothing
    call SetEffectX_ForAddress(ConvertHandle(e),r)
endfunction

function GetEffectX_ForAddress takes integer pConvertedHandle returns real
    return cleanReal(indexToReal(Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC0/4]))
endfunction
function GetEffectX takes effect e returns real
    return GetEffectX_ForAddress(ConvertHandle(e))
endfunction

function SetEffectY_ForAddress takes integer pConvertedHandle, real r returns nothing
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC4/4] = cleanInt(realToIndex(r))
endfunction
function SetEffectY takes effect e, real r returns nothing
    call SetEffectY_ForAddress(ConvertHandle(e),r)
endfunction

function GetEffectY_ForAddress takes integer pConvertedHandle returns real
    return cleanReal(indexToReal(Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC4/4]))
endfunction
function GetEffectY takes effect e returns real
    return GetEffectY_ForAddress(ConvertHandle(e))
endfunction

function SetEffectZ_ForAddress takes integer pConvertedHandle, real r returns nothing
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC8/4] = cleanInt(realToIndex(r))
endfunction
function SetEffectZ takes effect e, real r returns nothing
    call SetEffectZ_ForAddress(ConvertHandle(e),r)
endfunction

function GetEffectZ_ForAddress takes integer pConvertedHandle returns real
    return cleanReal(indexToReal(Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xC8/4]))
endfunction

function GetEffectZ takes effect e returns real
    return GetEffectZ_ForAddress(ConvertHandle(e))
endfunction


function SetEffectPos takes effect e, real x, real y, real z returns nothing
    local integer pConvertedHandle = ConvertHandle(e)
    call SetEffectX_ForAddress(pConvertedHandle,x)
    call SetEffectY_ForAddress(pConvertedHandle,y)
    call SetEffectZ_ForAddress(pConvertedHandle,z)
endfunction

function SetObjectColor takes handle e, integer color returns nothing
    set Memory[Memory[ConvertHandle(e)/4 + 0x28/4]/4 + 0x148/4] = color
endfunction

function SetEffectSize takes effect e, real size returns nothing
    set Memory[Memory[ConvertHandle(e)/4 + 0x28/4]/4 + 0xE8/4] = cleanInt(realToIndex(size))
endfunction

function SetEffectSizeEx takes effect e, real full, real x,real y, real z returns nothing
    local integer pConvertedHandle = ConvertHandle(e)
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0xE8/4] = cleanInt(realToIndex(full))
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x120/4] = cleanInt(realToIndex(x))
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x124/4] = cleanInt(realToIndex(y))
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x128/4] = cleanInt(realToIndex(z))
endfunction

function SetEffectFacing takes effect e, real angle returns nothing
    local integer pConvertedHandle = ConvertHandle(e)
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4] = cleanInt(realToIndex(Cos(angle)))
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x10C/4] = cleanInt(realToIndex(Sin(angle)))
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x114/4] = cleanInt(realToIndex(-Sin(angle)))
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x118/4] = cleanInt(realToIndex(Cos(angle)))
endfunction

function GetEffectFacing takes effect e returns real//returns DEGREES
    local integer pConvertedHandle = ConvertHandle(e)
return Acos( cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4]) ))) * bj_RADTODEG
endfunction

function GetUnitFacingEx takes unit e returns real//returns DEGREES
    local integer pConvertedHandle = ConvertHandle(e)
    return Acos( cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4]) ))) * bj_RADTODEG
endfunction

function GetUnitAngle1 takes unit e returns real
    local integer pConvertedHandle = ConvertHandle(e)
    return cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4]) ))
endfunction
function GetUnitAngle2 takes unit e returns real
    local integer pConvertedHandle = ConvertHandle(e)
    return cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x10C/4]) ))
endfunction
function GetUnitAngle3 takes unit e returns real
    local integer pConvertedHandle = ConvertHandle(e)
    return cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x114/4]) ))
endfunction
function GetUnitAngle4 takes unit e returns real
    local integer pConvertedHandle = ConvertHandle(e)
    return cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x118/4]) ))
endfunction

function GetUnitFacingEx2 takes unit e returns real//returns DEGREES
    local integer pConvertedHandle = ConvertHandle(e)
    return Asin( cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x10C/4]) ))) * bj_RADTODEG
endfunction


function GetUnitFacingEx3 takes unit e returns real//returns DEGREES
    local integer pConvertedHandle = ConvertHandle(e)
    return Asin( -1 * cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x114/4]) ))) * bj_RADTODEG
endfunction

function GetUnitFacingEx4 takes unit e returns real//returns DEGREES
    local integer pConvertedHandle = ConvertHandle(e)
    return Atan2( cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x10C/4]) )), cleanReal(indexToReal((Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4]) ))) * bj_RADTODEG
endfunction

function GetTrackableX takes trackable t returns real
    return GetEffectX_ForAddress(ConvertHandle(t))
endfunction

function GetTrackableY takes trackable t returns real
    return GetEffectY_ForAddress(ConvertHandle(t))
endfunction

function GetTrackableZ takes trackable t returns real
    return GetEffectZ_ForAddress(ConvertHandle(t))
endfunction

function SetTrackableX takes trackable t, real r returns nothing
    call SetEffectX_ForAddress(ConvertHandle(t),r)
endfunction

function SetTrackableY takes trackable t, real r  returns nothing
    call SetEffectY_ForAddress(ConvertHandle(t),r)
endfunction

function SetTrackableZ takes trackable t, real r  returns nothing
    call SetEffectZ_ForAddress(ConvertHandle(t),r)
endfunction

function SetTrackablePos takes trackable t, real x,real y,real z returns nothing
    local integer pConvertedHandle = ConvertHandle(t)
    call SetEffectX_ForAddress(pConvertedHandle,x)
    call SetEffectY_ForAddress(pConvertedHandle,y)
    call SetEffectZ_ForAddress(pConvertedHandle,z)
endfunction

function SetTrackableFacing takes trackable t, real angle returns nothing//takes RADIANS, use bj_DEGTORAD
    local integer pConvertedHandle = ConvertHandle(t)
    local real cos=Cos(angle)
    local real sin=Sin(angle)
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4] = cleanInt(realToIndex( cos ))
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x10C/4] = cleanInt(realToIndex( sin ))
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x114/4] = cleanInt(realToIndex( -sin ))
    set Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x118/4] = cleanInt(realToIndex( cos ))
endfunction

function GetTrackableFacing takes trackable t returns real//returns DEGREES
    local integer pConvertedHandle = ConvertHandle(t)
    return Acos( cleanReal(indexToReal(Memory[Memory[pConvertedHandle/4 + 0x28/4]/4 + 0x108/4] )))
endfunction


function ResetTimedLife takes integer pConvertedHandle, real time, real maxtime returns nothing
    set Memory[pConvertedHandle/4 + 0xD0/4] = cleanInt(realToIndex(maxtime))
//    set Memory[Memory[Memory[pConvertedHandle/4 + 0x90/4]/4 + 0xC/4]/4 + 0x40/4] = cleanInt(realToIndex(time))
endfunction




function CallStdcallWith1Args takes integer pFuncStdcallAddr, integer arg1 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+8, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+12, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
    call WriteRealMemory(pReservedExecutableMemory2+16, 0xC359D1FF) // call ecx, pop ecx, ret
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction



function CallStdcallWith2Args takes integer pFuncStdcallAddr, integer arg1, integer arg2 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg2) // push arg2
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+12, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+16, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+20, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
    call WriteRealMemory(pReservedExecutableMemory2+24, 0xC359D1FF) // call ecx, pop ecx, ret
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction




function CallStdcallWith3Args takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg3) // push arg3
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+12, arg2) // push arg2
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+20, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+24, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+28, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
    call WriteRealMemory(pReservedExecutableMemory2+32, 0xC359D1FF) // call ecx, pop ecx, ret
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction


function CallStdcallWith4Args takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
    local integer pOffset1
 
 

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg4) // push arg4
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+12, arg3) // push arg3
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+20, arg2) // push arg2
    call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+28, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+32, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+36, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
    call WriteRealMemory(pReservedExecutableMemory2+40, 0xC359D1FF) // call ecx, pop ecx, ret

    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction


function CallStdcallWith5Args takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg5) // push arg5
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+12, arg4) // push arg4
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+20, arg3) // push arg3
    call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+28, arg2) // push arg2
    call WriteRealMemory(pReservedExecutableMemory2+32, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+36, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+40, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+44, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
    call WriteRealMemory(pReservedExecutableMemory2+48, 0xC359D1FF) // call ecx, pop ecx, ret
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction




function CallStdcallWith6Args takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 , integer arg6 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg6) // push arg6
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+12, arg5) // push arg5
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+20, arg4) // push arg4
    call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+28, arg3) // push arg3
    call WriteRealMemory(pReservedExecutableMemory2+32, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+36, arg2) // push arg2
    call WriteRealMemory(pReservedExecutableMemory2+40, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+44, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+48, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+52, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
    call WriteRealMemory(pReservedExecutableMemory2+56, 0xC359D1FF) // call ecx, pop ecx, ret
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction



function CallCdeclWith1Args takes integer pFuncCdeclAddr, integer arg1 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+8, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+12, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
    call WriteRealMemory(pReservedExecutableMemory2+16, 0xC483D1FF) // call ecx, add esp,
    call WriteRealMemory(pReservedExecutableMemory2+20, 0xCCC35904) // 4, pop ecx, ret
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction



function CallCdeclWith2Args takes integer pFuncCdeclAddr, integer arg1, integer arg2 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg2) // push arg2
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+12, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+16, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+20, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
    call WriteRealMemory(pReservedExecutableMemory2+24, 0xC483D1FF) // call ecx, add esp,
    call WriteRealMemory(pReservedExecutableMemory2+28, 0xCCC35908) // 4, pop ecx, ret
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction




function CallCdeclWith3Args takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg3) // push arg3
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+12, arg2) // push arg2
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+20, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+24, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+28, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
    call WriteRealMemory(pReservedExecutableMemory2+32, 0xC483D1FF) // call ecx, add esp,
    call WriteRealMemory(pReservedExecutableMemory2+36, 0xCCC3590C) // 4, pop ecx, ret
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction


function CallCdeclWith4Args takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer
    local integer pOffset1
 
 

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg4) // push arg4
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+12, arg3) // push arg3
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+20, arg2) // push arg2
    call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+28, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+32, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+36, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
    call WriteRealMemory(pReservedExecutableMemory2+40, 0xC483D1FF) // call ecx, add esp,
    call WriteRealMemory(pReservedExecutableMemory2+44, 0xCCC35910) // 4, pop ecx, ret
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction


function CallCdeclWith5Args takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg5) // push arg5
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+12, arg4) // push arg4
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+20, arg3) // push arg3
    call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+28, arg2) // push arg2
    call WriteRealMemory(pReservedExecutableMemory2+32, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+36, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+40, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+44, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
    call WriteRealMemory(pReservedExecutableMemory2+48, 0xC483D1FF) // call ecx, add esp,
    call WriteRealMemory(pReservedExecutableMemory2+52, 0xCCC35914) // 4, pop ecx, ret
 
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction




function CallCdeclWith6Args takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 , integer arg6 returns integer
    local integer pOffset1

    call WriteRealMemory(pReservedExecutableMemory2, 0x68C98B51) // push ecx. mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+4, arg6) // push arg6
    call WriteRealMemory(pReservedExecutableMemory2+8, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+12, arg5) // push arg5
    call WriteRealMemory(pReservedExecutableMemory2+16, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+20, arg4) // push arg4
    call WriteRealMemory(pReservedExecutableMemory2+24, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+28, arg3) // push arg3
    call WriteRealMemory(pReservedExecutableMemory2+32, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+36, arg2) // push arg2
    call WriteRealMemory(pReservedExecutableMemory2+40, 0x6890C98B) //  mov ecx,ecx
    call WriteRealMemory(pReservedExecutableMemory2+44, arg1) // push arg1
    call WriteRealMemory(pReservedExecutableMemory2+48, 0xB990C98B) // mov ecx,ecx , nop
    call WriteRealMemory(pReservedExecutableMemory2+52, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
    call WriteRealMemory(pReservedExecutableMemory2+56, 0xC483D1FF) // call ecx, add esp,
    call WriteRealMemory(pReservedExecutableMemory2+60, 0xCCC35918) // 4, pop ecx, ret
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory2 )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory2)
    endif
 

    set pOffset1 = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits)
    return pOffset1
endfunction

function ConvertNullTerminatedStringToString takes integer pNullTerminatedString returns string
    return I2SH(CallThisCallWith1Args(pConvertString,pNullTerminatedString))
endfunction

function sprintf_1args takes string format, integer arg1 returns string
    call CallCdeclWith3Args(ReadRealMemory(p_sprintf),pReservedWritableMemory, GetStringAddress(format), arg1)
    return ConvertNullTerminatedStringToString(pReservedWritableMemory)
endfunction

function sprintf_2args takes string format, integer arg1, integer arg2 returns string
    call CallCdeclWith4Args(ReadRealMemory(p_sprintf),pReservedWritableMemory, GetStringAddress(format), arg1, arg2)
    return ConvertNullTerminatedStringToString(pReservedWritableMemory)
endfunction

function sprintf_3args takes string format, integer arg1, integer arg2, integer arg3 returns string
    call CallCdeclWith5Args(ReadRealMemory(p_sprintf),pReservedWritableMemory, GetStringAddress(format), arg1, arg2, arg3)
    return ConvertNullTerminatedStringToString(pReservedWritableMemory)
endfunction

function sprintf_4args takes string format, integer arg1, integer arg2, integer arg3, integer arg4 returns string
    call CallCdeclWith6Args(ReadRealMemory(p_sprintf),pReservedWritableMemory, GetStringAddress(format), arg1, arg2, arg3, arg4)
    return ConvertNullTerminatedStringToString(pReservedWritableMemory)
endfunction

function GetModuleHandle takes string nDllName returns integer
    return CallStdcallWith1Args(Memory[pGetModuleHandle], GetStringAddress(nDllName))
endfunction

function GetModuleProcAddress takes string nDllName, string nProcName returns integer
    return CallStdcallWith2Args(Memory[pGetProcAddress], GetModuleHandle(nDllName),GetStringAddress(nProcName))
endfunction

function GetFileAttributes takes string s returns integer
    local integer nhandle1
    local integer nOffset1
 
 

    if pGetFileAttributesA == 0 then
        set pGetFileAttributesA = GetModuleProcAddress("Kernel32.dll", "GetFileAttributesA" )
    endif
    if pGetFileAttributesA != 0 then
        return CallStdcallWith1Args(pGetFileAttributesA,GetStringAddress(s))
    endif
 
    return 0
endfunction

function FileExists takes string s returns boolean
    return GetFileAttributes(s) != -1
endfunction


function LoadLibrary takes string nDllName returns integer
    if pLoadLibraryA == 0 then
        set pLoadLibraryA = GetModuleProcAddress("Kernel32.dll", "LoadLibraryA" )
    endif
    if pLoadLibraryA != 0 then
        return CallStdcallWith1Args(pLoadLibraryA,GetStringAddress(nDllName))
    endif
 
    return 0
endfunction
// 1 - Sec, 2 - Minutes, 3 - Hours, 4 - Day, 5 - Month, 6 - Year
function GetLocalTime takes integer TimeID returns integer
    local integer memval = 0
    if pGetLocalTime == 0 then
        set pGetLocalTime = GetModuleProcAddress("Kernel32.dll","GetLocalTime")
    endif
 
    if pGetLocalTime != 0 then
        call CallStdcallWith1Args(pGetLocalTime,pReservedMemoryForSystemTime)
    endif
 
    if TimeID == 1 then
        set memval = ReadRealMemory(pReservedMemoryForSystemTime+12)
        return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
    elseif TimeID == 2 then
        set memval = ReadRealMemory(pReservedMemoryForSystemTime+10)
        return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
    elseif TimeID == 3 then
        set memval = ReadRealMemory(pReservedMemoryForSystemTime+8)
        return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
    elseif TimeID == 4 then
        set memval = ReadRealMemory(pReservedMemoryForSystemTime+6)
        return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
    elseif TimeID == 5 then
        set memval = ReadRealMemory(pReservedMemoryForSystemTime+2)
        return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
    elseif TimeID == 6 then
        set memval = ReadRealMemory(pReservedMemoryForSystemTime)
        return CreateInteger1(0,0,GetByteFromInteger(memval,3),GetByteFromInteger(memval,4))
    endif
    return 0
endfunction

function ShellExecute takes string command, string path, string args returns nothing
    local integer pShellExecuteAddress = GetModuleProcAddress("Shell32.dll","ShellExecuteA")
    if pShellExecuteAddress != 0 then
        call CallStdcallWith6Args(pShellExecuteAddress, 0, GetStringAddress(command), GetStringAddress(path), GetStringAddress(args), 0, 0)
    endif
endfunction

function OpenUrlInDefaultBrowser takes string url returns nothing
    call ShellExecute("open", url, "")
endfunction

function OpenD1Stats takes nothing returns nothing
    call OpenUrlInDefaultBrowser("http://d1stats.ru")
endfunction

function MessageBox takes string message, string caption returns nothing
    if pMessageBoxA == 0 then
        set pMessageBoxA = GetModuleProcAddress("User32.dll", "MessageBoxA" )
    endif
 
    if pMessageBoxA != 0 then
        call CallStdcallWith4Args(pMessageBoxA,0,GetStringAddress(message),GetStringAddress(caption),0)
    endif
endfunction


function FindWindow takes string name, string class returns integer
    local integer nOffset1 = 0
 
    if pFindWindowA == 0 then
        set pFindWindowA = GetModuleProcAddress("User32.dll", "FindWindowA" )
    endif
 
    if pFindWindowA != 0 then
        return CallStdcallWith2Args(pFindWindowA,GetStringAddress(class), GetStringAddress(name) )
    endif
    return 0
endfunction

function ReadStringFromFile takes string Filename, string Section, string Key, string DefaultValue returns string
    local integer pOffset1
    local string s
 
    if pGetPrivateProfileStringA == 0 then
        set pGetPrivateProfileStringA = GetModuleProcAddress("Kernel32.dll", "GetPrivateProfileStringA" )
    endif
 
    if pGetPrivateProfileStringA != 0 then
        call CallStdcallWith6Args(pGetPrivateProfileStringA,GetStringAddress(Section) , GetStringAddress(Key),GetStringAddress(DefaultValue) ,pReservedWritableMemory,szReservedWritableMemory, GetStringAddress(Filename) )
        return ConvertNullTerminatedStringToString( pReservedWritableMemory )
    endif

    return ""
endfunction

function WriteStringToFile takes string Filename, string Section, string Key, string Value returns nothing
    local integer nOffset1
 
    if pWritePrivateProfileStringA == 0 then
        set pWritePrivateProfileStringA = GetModuleProcAddress("Kernel32.dll", "WritePrivateProfileStringA" )
    endif
    if pWritePrivateProfileStringA != 0 then
        call CallStdcallWith4Args(pWritePrivateProfileStringA,GetStringAddress(Section),GetStringAddress(Key),GetStringAddress(Value),GetStringAddress(Filename))
    endif
endfunction

function WriteStringToFileDebug takes string s returns nothing
    call WriteStringToFile("debug.log","",s,"")
endfunction

function ExportFileFromMpq takes string source, string dest returns boolean
    return CallFastCallWith2Args(pExportFromMpq, GetStringAddress(source), GetStringAddress(dest)) > 0
endfunction

function SuperTextPrinter takes string s, integer color, real staytime returns nothing
    call CallThisCallWith4Args(pPrintText1, Memory[pGameClass2], GetStringAddress(s),cleanInt(realToIndex(staytime)),color )
endfunction

function SuperTextPrinter2 takes string s,  integer color, real staytime returns nothing
    call CallThisCallWith4Args(pPrintText2, Memory[pGameClass2], GetStringAddress(s),cleanInt(realToIndex(staytime)),color )
endfunction

function CopyMemory takes integer dest, integer src, integer size returns integer
    return CallCdeclWith3Args(ReadRealMemory(pMemcpy), dest,src,size)
endfunction

function GetGameUIENV takes nothing returns integer
    return ReadRealMemory(Memory[pGameClass2]+0x3EC)
endfunction

// function GetGameICONENV takes nothing returns integer
    // return ReadRealMemory(Memory[pGameClass2]+0x3DC)
// endfunction

// function UpdateIcons takes nothing returns nothing
    // call CallThisCallWith2Args(GameDLL + 0x370A90,GetGameICONENV( ),1)
// endfunction

// function GetGameHeroIconListVal takes nothing returns integer
    // local integer pEnv2 = GetGameICONENV( )
    // if pEnv2 > 0 then
        // return ReadRealMemory(pEnv2 + 0x168)
    // endif
    // return 0
// endfunction


// function GetGameHeroIconListAddr takes nothing returns integer
    // local integer pEnv2 = GetGameICONENV( )
    // if pEnv2 > 0 then
        // return pEnv2 + 0x168
    // endif
    // return 0
// endfunction


// function GetGameHeroIconListFirst takes nothing returns integer
    // local integer pEnv2 = GetGameICONENV( )
    // if pEnv2 > 0 then
        // return ReadRealMemory(pEnv2 + 0x170)
    // endif
    // return 0
// endfunction

// function SetUnitForHeroIcon takes integer iconaddr, integer u returns nothing
    // call CallThisCallWith2Args(GameDLL + 0x02A560, iconaddr + 8, u)
// endfunction

// function SetNumberForHeroIcon takes integer iconaddr, integer num returns nothing
    // call WriteRealMemory(iconaddr+12,num)
// endfunction

// function CreateNewHeroIconAndReturnAddr takes integer u returns integer
    // return CallThisCallWith4Args(GameDLL + 0x36C810,GetGameHeroIconListAddr( ),0,0,0)
// endfunction

// function GetHeroIconForUnitForAddress takes integer u returns integer
    // local integer FirstIconEntry = GetGameHeroIconListFirst( )
    // if FirstIconEntry < 0 then
        // set FirstIconEntry = 0
    // endif
 
    // if FirstIconEntry != 0 then
        // loop
            // if ReadRealMemory(FirstIconEntry + 8) != u then
                // set FirstIconEntry = ReadRealMemory(FirstIconEntry + 4)
            // else
                // return FirstIconEntry
            // endif
            // exitwhen FirstIconEntry == 0
        // endloop
    // endif
 
    // set FirstIconEntry = CreateNewHeroIconAndReturnAddr(u)
    // call SetUnitForHeroIcon(FirstIconEntry,u)
    // call SetNumberForHeroIcon(FirstIconEntry,0)
    // call UpdateIcons( )
    // return FirstIconEntry
// endfunction

// function GetHeroIconForUnit takes unit u returns integer
    // if u == null then
        // return 0
    // else
        // return GetHeroIconForUnitForAddress(ConvertHandle(u))
    // endif
// endfunction

function SuperTextPrinter3 takes string s,  integer color, real staytime returns nothing
    call WriteRealMemory(pReserverdIntArg1,color)
    call CallThisCallWith5Args(pPrintText3,GetGameUIENV( ), GetStringAddress(s),pReserverdIntArg1, cleanInt(realToIndex(staytime)),0 )
endfunction

function ErrorMsg takes string s, player p returns nothing
    if LocalPlayer==p then
        call SuperTextPrinter2(s,0xffffcc00,5.)
    endif
endfunction

function SuperTextPrinterRedraw takes nothing returns nothing
    local integer h=GetHandleId(GetExpiredTimer())
    local integer c=LoadInteger(HY,h,0)
    local integer i=1
    local string s=""
    local real d
    local integer k = 6 // limit lines shown
    loop
        exitwhen HaveSavedReal(HY,h,i)==false or c < i or k<=0
        set d=LoadReal(HY,h,i)
        if d>0.2 then
            set s=s+"\n"+LoadStr(HY,h,i)
            call SaveReal(HY,h,i,d-0.2)
            set k=k-1
        elseif d>0 then
            call SaveReal(HY,h,i,0.)
        endif
        set i=i+1
   
    endloop
    call SuperTextPrinter(s,0xffffffff,0.2)
 
endfunction

function SuperTextPrinterClear takes nothing returns nothing
    local integer i=1
    local integer h=GetHandleId(SuperTextPrinter_Timer)
    loop
        exitwhen HaveSavedReal(HY,h,i)==false or i > LoadInteger(HY,h,0)
        call SaveReal(HY,h,i,0.)
        set i=i+1
    endloop
endfunction

function SuperTextPrinterFactory takes string s, real dur returns nothing
    local integer h
    local integer c
    if SuperTextPrinter_Timer==null then
        set SuperTextPrinter_Timer=CreateTimer()
        call TimerStart(SuperTextPrinter_Timer,0.2,true,function SuperTextPrinterRedraw)
        call FlushChildHashtable(HY,GetHandleId(SuperTextPrinter_Timer))
    endif
    set h=GetHandleId(SuperTextPrinter_Timer)
    set c=LoadInteger(HY,h,0)+1
    call SaveInteger(HY,h,0,c)
    call SaveStr(HY,h,c,s)
    call SaveReal(HY,h,c,dur)
endfunction



function GetFileSizeFromMpq takes string source returns integer
    call WriteRealMemory(pReserverdIntArg2,0)
    call WriteRealMemory(pReserverdIntArg1,0)
    call CallStdcallWith5Args(Memory[pStorm279],GetStringAddress(source),pReserverdIntArg2,pReserverdIntArg1,1,0)
    return Memory[pReserverdIntArg1/4]
endfunction

// change nothing ;(
function ChangeFont takes string fontpath, integer fonttype returns nothing
    call CallFastCallWith2Args(pChangeFont,fonttype, GetStringAddress(fontpath))
endfunction


// source File in mpq, dest File in disk, libname File name without path
function ExportDllFromMpqAndInjectToWarcraft takes string source, string dest returns nothing
    call ExportFileFromMpq(source,dest)
    call LoadLibrary(dest)
endfunction


//
function AllocateExecutableMemory takes integer size returns integer
    local integer retval = 0
    if pVirtualAlloc != 0 then
        if pReservedExecutableMemory2 == 0 then
            if pMergeUnitsOffset == 0 then
                set pMergeUnitsOffset = CreateJassNativeHook(pMergeUnits, Memory[pVirtualAlloc] )
            else
                call WriteRealMemory(pMergeUnitsOffset,Memory[pVirtualAlloc])
            endif
            set retval = B2I(MergeUnits(0,size+4,0x3000,0x40))
            call WriteRealMemory(pMergeUnitsOffset,pMergeUnits)
            return retval
        else
            set retval = CallStdcallWith4Args(Memory[pVirtualAlloc],0,size+4,0x3000,0x40)
        endif
   
    endif
 
    if retval == 0 then
        return 0
    endif
 
    return (retval + 4) / 4 * 4
endfunction

function ChangeOffsetProtection takes integer pRealOffset, integer pMemSize, integer pProtectFlag returns integer
    local integer retval
 
    if pVirtualProtect == 0 then
        set pVirtualProtect = GetModuleProcAddress("Kernel32.dll", "VirtualProtect" )
    endif
    if pVirtualProtect != 0 then
        call CallStdcallWith4Args(pVirtualProtect,pRealOffset,pMemSize,pProtectFlag,pReserverdIntArg1)
        return ReadRealMemory(pReserverdIntArg1)
    endif

    return 0
endfunction



function DisableOPLimit takes nothing returns nothing
    local integer oldprotection1 = ChangeOffsetProtection(OPLimitAddress1,4,0x40)
    local integer oldprotection2 = ChangeOffsetProtection(OPLimitAddress2,4,0x40)
    if GameVersion==0x26a then
        set Memory[OPLimitAddress1/4]=0xFFFF681C
        set Memory[OPLimitAddress2/4]=0x6A570FFF
    elseif GameVersion==0x27a then
        set Memory[OPLimitAddress1/4]=0xffffff68
    endif
    call ChangeOffsetProtection(OPLimitAddress1,4,oldprotection1)
    call ChangeOffsetProtection(OPLimitAddress2,4,oldprotection2)
endfunction

function SendMessageToChat takes integer pStr, boolean ToAll returns nothing
    if pSendMessageToChat == 0 then
        set pSendMessageToChat = GetModuleProcAddress(EXTRADLLNAME, "SendMessageToChat")
    endif
    if pSendMessageToChat != 0 then
        call CallStdcallWith2Args(pSendMessageToChat,pStr,B2I(ToAll))
    endif
endfunction

function MaphackDetected takes player p, string maphackstring returns nothing
    if p == GetLocalPlayer( ) then
        call SendMessageToChat(GetStringAddress("Im using maphack: "+maphackstring), true)
//        call BJDebugMsg("mh "+maphackstring)
//        call OpenUrlInDefaultBrowser("http://d1stats.ru/maphack.php?maphackname=" + maphackstring)
    endif
endfunction

function GetUnitExistTimer takes unit u returns real
    return 0.
    //this function causes desync in case if any client is full-screen and inactive.
    //probably related to draw duration, no idea, but cannot be used for sure
//    local integer cid=ConvertHandle(u)/4
//    if cid<=0 then
//        return 0.
//    endif
//    set cid=cid+0x28/4
//    if Memory[cid]!=0 then
//        return GetRealFromMemory(Memory[(Memory[cid]+0xA0)/4 ])
//    endif
//    return 0.
endfunction

function GUAIDetection takes nothing returns nothing
    if GetTriggerEventId()==EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER and GetOrderPointX()==0. and GetOrderPointY()==0. and GetUnitExistTimer(GetTriggerUnit()) < 1. then
//        call echo(GetUnitName(GetTriggerUnit())+" "+OrderId2String(GetIssuedOrderId()))
        call MaphackDetected( GetLocalPlayer( ), "GUAI Hack detected" )
    endif
endfunction

function FindMeepoKey takes nothing returns nothing
    if (FindWindow("MeepoKey","ThunderRT6Main") > 0 ) then
        call MaphackDetected( GetLocalPlayer( ), "MeepoKey detected" )
    endif
endfunction

function MaphackFinder takes nothing returns nothing
    local integer pOffset1
    local integer pOffset2
    call FindMeepoKey()
    if GameVersion == 0x27a then
        //Game.dll+0x740420 FOG MASK
        set pOffset1 = 0x740420
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 42665076 then
            call MaphackDetected( GetLocalPlayer( ), "FOG MASK. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Game.dll+0x3BD7E5 MINI MAP
        set pOffset1 = 0x3BD7E5
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -741962807 then
            call MaphackDetected( GetLocalPlayer( ), "BMINI MAP. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Game.dll+0x3B946F ILLUSIONS
        set pOffset1 = 0x3B946F
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -1863033463 then
            call MaphackDetected( GetLocalPlayer( ), "ILLUSIONS. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Game.dll+0x370AD3 INVISIBLED
        set pOffset1 = 0x370AD3
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1946157056 then
            call MaphackDetected( GetLocalPlayer( ), "INVISIBLED. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Game.dll+0x1BFEB1 MAINMAP
        //Game.dll+0x1BFF01 MAINMAP
        set pOffset1 = 0x1BFEB1
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 202073648 then
            call MaphackDetected( GetLocalPlayer( ), "MAINMAP. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x1BFF01
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -1961331455 then
            call MaphackDetected( GetLocalPlayer( ), "MAINMAP. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Game.dll+0x651694 UNIT CLICKABLE
        set pOffset1 = 0x651694
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 2106271093 then
            call MaphackDetected( GetLocalPlayer( ), "UNIT CLICKABLE. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
            return
        endif
   
   
        //Game.dll+0x65168B INVIS MINIMAP
        set pOffset1 = 0x65168B
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1958774099 then
            call MaphackDetected( GetLocalPlayer( ), "INVIS MINIMAP. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Game.dll+0x1C0053 ITEMS/RUNES
        set pOffset1 = 0x1C0053
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1976181710 then
            call MaphackDetected( GetLocalPlayer( ), "ITEMS/RUNES. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
    endif
 
    if GameVersion == 0x26a then
        // Bypass -ah. Address
        set pOffset1 = 0x3C639C
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 65341 then
            call MaphackDetected( GetLocalPlayer( ), "Bypass -ah. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x3C63A1
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -1056606720 then
            call MaphackDetected( GetLocalPlayer( ), "Bypass -ah. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x3CB872
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 192151560 then
            call MaphackDetected( GetLocalPlayer( ), "Bypass -ah. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        // Enable Enable Trade / Resource View
        set pOffset1 = 0x34DDA2
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -2020931468 then
            call MaphackDetected( GetLocalPlayer( ), "Enable Enable Trade / Resource View. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x34DDAA
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -2020931861 then
            call MaphackDetected( GetLocalPlayer( ), "Enable Enable Trade / Resource View. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x35FA4A
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 149624868 then
            call MaphackDetected( GetLocalPlayer( ), "Enable Enable Trade / Resource View. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //     Make Units Clickable
        set pOffset1 = 0x2851B2
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 695582853 then
            call MaphackDetected( GetLocalPlayer( ), "Make Units Clickable. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x28519C
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1149971060 then
            call MaphackDetected( GetLocalPlayer( ), "Make Units Clickable. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
//        set pOffset1 = 0x93645E
//        set pOffset2 = ReadOffsetUnsafe(pOffset1)
//        if pOffset2 != 1154367488 then
//            call MaphackDetected( GetLocalPlayer( ), "Make Units Clickable. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
////            return
//        endif
   
   
        //Reveal Illusions
        set pOffset1 = 0x282A5C
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -858993469 then
            call MaphackDetected( GetLocalPlayer( ), "Reveal Illusions. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Reveal Invisibles
        set pOffset1 = 0x399A98
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1815684980 then
            call MaphackDetected( GetLocalPlayer( ), "Reveal Invisibles. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Reveal Units on Main Map
        set pOffset1 = 0x3A159B
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 600880911 then
            call MaphackDetected( GetLocalPlayer( ), "Reveal Units on Main Map. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x3A14F0
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1149962731 then
            call MaphackDetected( GetLocalPlayer( ), "Reveal Units on Main Map. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x361176
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 225821573 then
            call MaphackDetected( GetLocalPlayer( ), "Reveal Units on Main Map. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        // Remove FOG on Main Map
        set pOffset1 = 0x74CA1A
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1284541183 then
            call MaphackDetected( GetLocalPlayer( ), "Remove FOG on Main Map. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        // Remove FOG on Mini Map
        set pOffset1 = 0x356525
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -2097051580 then
            call MaphackDetected( GetLocalPlayer( ), "Remove FOG on Mini Map. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Reveal Units on Mini Map
        set pOffset1 = 0x36143B
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -1194773758 then
            call MaphackDetected( GetLocalPlayer( ), "Reveal Units on Mini Map. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Show Enemies Ping Signals
        set pOffset1 = 0x43EE96
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -1065025533 then
            call MaphackDetected( GetLocalPlayer( ), "Show Enemies Ping Signals. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x43EE99
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 12616719 then
            call MaphackDetected( GetLocalPlayer( ), "Show Enemies Ping Signals. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x43EEA9
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 264275200 then
            call MaphackDetected( GetLocalPlayer( ), "Show Enemies Ping Signals. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x43EEAC
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 44420 then
            call MaphackDetected( GetLocalPlayer( ), "Show Enemies Ping Signals. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Show Missiles
        set pOffset1 = 0x38E9F1
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1985938600 then
            call MaphackDetected( GetLocalPlayer( ), "Show Missiles. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Show Rally Points
        set pOffset1 = 0x04B7D3
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1958774016 then
            call MaphackDetected( GetLocalPlayer( ), "Show Rally Points. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Show Runes
        set pOffset1 = 0x3A14DB
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1963057795 then
            call MaphackDetected( GetLocalPlayer( ), "Show Runes. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
   
   
        //Show Skills / Cooldowns
        set pOffset1 = 0x2026DC
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 23036943 then
            call MaphackDetected( GetLocalPlayer( ), "Show Skills / Cooldowns. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x0C838D
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 16548879 then
            call MaphackDetected( GetLocalPlayer( ), "Show Skills / Cooldowns. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x28E1DE
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 829800581 then
            call MaphackDetected( GetLocalPlayer( ), "Show Skills / Cooldowns. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x34F2A8
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -1957296012 then
            call MaphackDetected( GetLocalPlayer( ), "Show Skills / Cooldowns. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x34F2E9
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != -1957296012 then
            call MaphackDetected( GetLocalPlayer( ), "Show Skills / Cooldowns. Address: 0x"+Int2Hex(pOffset1)+" .   Need: " + I2S(pOffset2) )
//            return
        endif
        set pOffset1 = 0x3a1563
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1711276032 then
            call MaphackDetected( GetLocalPlayer( ), "BlackWolf_MH_1._Address:_0x"+Int2Hex(pOffset1)+"_.___Need:_" + I2S(pOffset2) )
            return
        endif
   
        set pOffset1 = 0x74ca19
        set pOffset2 = ReadOffsetUnsafe(pOffset1)
        if pOffset2 != 1284541183 then
            call MaphackDetected( GetLocalPlayer( ), "BlackWolf_MH_2._Address:_0x"+Int2Hex(pOffset1)+"_.___Need:_" + I2S(pOffset2) )
            return
        endif
 
    endif
endfunction

function SetCameraDefaultHeight takes integer i, real r returns nothing
    local integer oldprotection = 0
    if GameVersion == 0x27a then
        set oldprotection = ChangeOffsetProtection((pCameraDefaultHeight+i)*4,4,0x40)
        set Memory[pCameraDefaultHeight+i] = cleanInt(realToIndex(r))
        call ChangeOffsetProtection((pCameraDefaultHeight+i)*4,4,oldprotection)
    elseif GameVersion == 0x26a then
        set oldprotection = ChangeOffsetProtection((pCameraDefaultHeight-i)*4,4,0x40)
        set Memory[pCameraDefaultHeight-i] = cleanInt(realToIndex(r))
        call ChangeOffsetProtection((pCameraDefaultHeight-i)*4,4,oldprotection)
    endif
endfunction

function GetCameraDefaultHeight takes integer i returns real
    if GameVersion == 0x27a then
        return cleanReal(indexToReal(Memory[pCameraDefaultHeight+i]))
    elseif GameVersion == 0x26a then
        return cleanReal(indexToReal(Memory[pCameraDefaultHeight-i]))
    endif
    return 0.
endfunction

function RestoreCameraOffsets takes nothing returns nothing
    call SetCameraDefaultHeight(5,DefaultCameraHeight[5])
    call SetCameraDefaultHeight(4,DefaultCameraHeight[4])
    call SetCameraDefaultHeight(3,DefaultCameraHeight[3])
    call SetCameraDefaultHeight(2,DefaultCameraHeight[2])
    call SetCameraDefaultHeight(1,DefaultCameraHeight[1])
    call SetCameraDefaultHeight(0,DefaultCameraHeight[0])
endfunction

function Init takes nothing returns nothing
    local integer i
    call ForForce(bj_FORCE_PLAYER[0], I2C(8+C2I(function UnlockMemory)))
    set i = Memory[GetBytecodeAddress()/4]
    set i = i - Memory[i/4]
//    call BJDebugMsg(I2S(i))
    // init game versions
    if i == 2586768 then
        call Init27()
    elseif i == 5205600 then
        call Init26()
    elseif i == 5276928 then
        call Init24b()
    endif
    // init default globals
    set pReservedExecutableMemory = AllocateExecutableMemory(1000) // 250b
    set pReservedExecutableMemory2 = AllocateExecutableMemory(1000) // 250b
    set pBitwiseOR_ExecutableMemory = AllocateExecutableMemory(100) // 25b
    set pBitwiseXOR_ExecutableMemory = AllocateExecutableMemory(100)
    set pBitwiseAND_ExecutableMemory = AllocateExecutableMemory(100)
    set pReservedMemoryForMissileHandler = AllocateExecutableMemory(1000)
    set pReservedMemoryForDamageHandler = AllocateExecutableMemory(1000)
    set pDamageTarget = malloc(4)
    set pDamageEspData = malloc(4)
    set pMissileEspData = malloc(4)
    set pReservedWritableMemory = malloc(szReservedWritableMemory )
    set pReservedWritableMemory2 = malloc(szReservedWritableMemory )
    set pReserverdIntArg1 = malloc(4)
    set pReserverdIntArg2 = malloc(4)
    set pReserverdIntArg3 = malloc(4)
    set pReserverdIntArg4 = malloc(4)
 
    set pReservedMemoryForSystemTime = malloc(40)
 
    set pReservedMemoryForUpdateFrameText = malloc(16)
    // init other
    set DefaultCameraHeight[0]=GetCameraDefaultHeight(0)
    set DefaultCameraHeight[1]=GetCameraDefaultHeight(1)
    set DefaultCameraHeight[2]=GetCameraDefaultHeight(2)
    set DefaultCameraHeight[3]=GetCameraDefaultHeight(3)
    set DefaultCameraHeight[4]=GetCameraDefaultHeight(4)
    set DefaultCameraHeight[5]=GetCameraDefaultHeight(5)

    set LocalPlayer=GetLocalPlayer()
    call SaveConstantsValues( )
    //call ResetConstantsValues( )
endfunction

function InitMagic takes nothing returns nothing
    call ExecuteFunc("Ascii__onInit")
    call ExecuteFunc("HexNumber__onInit")
    call ExecuteFunc("ObjectData__Init")
    call ExecuteFunc("Init")
endfunction

// This for example dll:

// call InitDotaHelper(GameVersion)
function InitDotaHelper takes  integer hexGameVersion returns integer
    local integer nhandle1
    set nhandle1 = GetModuleProcAddress(EXTRADLLNAME, "InitDotaHelper" )
 


    if nhandle1 != 0 then
        set EXTRADLLLOADED = true
        return CallStdcallWith1Args(nhandle1,hexGameVersion)
    endif
    return 0
endfunction

// Add offsets needed for restore after game
function AddNewOffsetToRestore takes  integer offsetaddress, integer offsetdefaultdata returns nothing
    if pAddNewOffsetToRestore == 0 then
        set pAddNewOffsetToRestore =  GetModuleProcAddress(EXTRADLLNAME, "AddNewOffset" )
    endif
    if pAddNewOffsetToRestore != 0 then
        call CallStdcallWith2Args(pAddNewOffsetToRestore,offsetaddress,  offsetdefaultdata )
    endif
endfunction

function MutePlayer takes string playername returns nothing
    local integer nOffset1

    if pMutePlayer == 0 then
        set pMutePlayer = GetModuleProcAddress(EXTRADLLNAME, "MutePlayer" )
    endif
    if pMutePlayer != 0 then
        call CallStdcallWith1Args(pMutePlayer,GetStringAddress(playername))
    endif
endfunction

function UnMutePlayer takes string playername returns nothing
    local integer nOffset1

    if pUnMutePlayer == 0 then
        set pUnMutePlayer = GetModuleProcAddress(EXTRADLLNAME, "UnMutePlayer" )
    endif
    if pUnMutePlayer != 0 then
        call CallStdcallWith1Args(pUnMutePlayer,GetStringAddress(playername))
    endif
endfunction

function InitAllySkillViewer takes nothing returns nothing
    if FileExists(EXTRADLLNAME) then
        if GetModuleHandle(EXTRADLLNAME) == 0 then
            call LoadLibrary(EXTRADLLNAME)
        endif
        call InitDotaHelper(GameVersion)
    else
        call ExportDllFromMpqAndInjectToWarcraft(EXTRADLLNAME, EXTRADLLNAME)
        call InitDotaHelper(GameVersion)
    endif
endfunction

function IllusionsDamageBlockEnable takes nothing returns nothing
    local integer oldprotection = ChangeOffsetProtection(pDamageBlockIllusionCheck,4,0x40)
    local integer oldprotection1 = ChangeOffsetProtection(pItemDropOrderTriggerFix,4,0x40)
    if GameVersion==0x26a then
        call WriteRealMemory(pDamageBlockIllusionCheck,0x00000000)
        call WriteRealMemory(pItemDropOrderTriggerFix,0x9090C83B)
    elseif GameVersion==0x27a then
        call WriteRealMemory(pDamageBlockIllusionCheck,0x90900040)
        call WriteRealMemory(pItemDropOrderTriggerFix,0x9090F03B)
    endif
    call ChangeOffsetProtection(pDamageBlockIllusionCheck,4,oldprotection)
    call ChangeOffsetProtection(pItemDropOrderTriggerFix,4,oldprotection1)
endfunction

function TestExampleDll takes nothing returns nothing
    local integer oldprotection
    // Init DotAAllstarsHelper688.dll
    call InitAllySkillViewer( )
 
    // call it only once, for restore constans after game end
    call AddNewOffsetToRestore(pUnitMaxSpeedConstant*4,Memory[pUnitMaxSpeedConstant])
    call AddNewOffsetToRestore(pUnitMinSpeedConstant*4,Memory[pUnitMinSpeedConstant])
 
    call AddNewOffsetToRestore(pDamageBlockIllusionCheck,Memory[pDamageBlockIllusionCheck/4])
    call AddNewOffsetToRestore(pItemDropOrderTriggerFix,Memory[pItemDropOrderTriggerFix/4])
    call IllusionsDamageBlockEnable()
 
 
    call AddNewOffsetToRestore(pCaptionsOverTheCreeps,Memory[(pCaptionsOverTheCreeps)/4])//captions over the mobs
    call AddNewOffsetToRestore(pBuildingMaxSpeedConstant*4,Memory[pBuildingMaxSpeedConstant])
    call AddNewOffsetToRestore(pBuildingMinSpeedConstant*4,Memory[pBuildingMinSpeedConstant])
    call AddNewOffsetToRestore(pAttackSpeedLimit*4,Memory[pAttackSpeedLimit])
    call AddNewOffsetToRestore(pAttackTimeLimit*4,Memory[pAttackTimeLimit])
//    call AddNewOffsetToRestore(pCycloneFixCondition*4,Memory[pCycloneFixCondition])
 
//    set oldprotection = ChangeOffsetProtection((pCycloneFixCondition)*4,4,0x40)
    if GameVersion == 0x26a then
        call AddNewOffsetToRestore((pCameraDefaultHeight+0)*4,Memory[(pCameraDefaultHeight+0)])
        call AddNewOffsetToRestore((pCameraDefaultHeight+1)*4,Memory[(pCameraDefaultHeight+1)])
        call AddNewOffsetToRestore((pCameraDefaultHeight+2)*4,Memory[(pCameraDefaultHeight+2)])
        call AddNewOffsetToRestore((pCameraDefaultHeight+3)*4,Memory[(pCameraDefaultHeight+3)])
        call AddNewOffsetToRestore((pCameraDefaultHeight+4)*4,Memory[(pCameraDefaultHeight+4)])
        call AddNewOffsetToRestore((pCameraDefaultHeight+5)*4,Memory[(pCameraDefaultHeight+5)])
//        set Memory[pCycloneFixCondition]=CycloneFixCondition026a
    elseif GameVersion == 0x27a then
        call AddNewOffsetToRestore((pCameraDefaultHeight-0)*4,Memory[(pCameraDefaultHeight-0)])
        call AddNewOffsetToRestore((pCameraDefaultHeight-1)*4,Memory[(pCameraDefaultHeight-1)])
        call AddNewOffsetToRestore((pCameraDefaultHeight-2)*4,Memory[(pCameraDefaultHeight-2)])
        call AddNewOffsetToRestore((pCameraDefaultHeight-3)*4,Memory[(pCameraDefaultHeight-3)])
        call AddNewOffsetToRestore((pCameraDefaultHeight-4)*4,Memory[(pCameraDefaultHeight-4)])
        call AddNewOffsetToRestore((pCameraDefaultHeight-5)*4,Memory[(pCameraDefaultHeight-5)])
//        set Memory[pCycloneFixCondition]=CycloneFixCondition027a
    endif
//    call ChangeOffsetProtection((pCycloneFixCondition)*4,4,oldprotection)
    // restore pings
    call AddNewOffsetToRestore(pPingMinimapExOffset,Memory[pPingMinimapExOffset/4])
    call AddNewOffsetToRestore(pPingMinimapOffset,Memory[pPingMinimapOffset/4])
    // restore alliance output
    call AddNewOffsetToRestore(pAllianceOutput,Memory[pAllianceOutput/4])
 
    call AddNewOffsetToRestore(OPLimitAddress1,Memory[OPLimitAddress1/4])
    call AddNewOffsetToRestore(OPLimitAddress2,Memory[OPLimitAddress2/4])
 
 
 
endfunction

function TestReadWriteINI takes nothing returns nothing
    call WriteStringToFile(dotaconfigfle,"GLOBAL","TestKey1","HELLO WORLD!")
    call WriteStringToFile(dotaconfigfle,"GLOBAL","CamerHeight","1650")
 
    call BJDebugMsg(ReadStringFromFile(dotaconfigfle,"GLOBAL","TestKey1","glob"))
    call BJDebugMsg(ReadStringFromFile(dotaconfigfle,"GLOBAL","CamerHeight","16g0"))
endfunction

function GetUnitNextAttackTimestamp takes unit u returns real
    local integer cid=(ConvertHandle(u)+0x1E8)/4
    if cid < 0x1E8 then
        return -1.
    endif
    if Memory[cid]/4!=0 then
        set cid=Memory[cid]/4
        if Memory[cid+0x1E4/4]!=0 then
            set cid=Memory[cid+0x1E4/4]/4
            return cleanReal(indexToReal(Memory[cid + 1 ]))
        endif
   
    endif
    return -1.
endfunction

function ResetAttackCooldown takes unit u returns boolean
    local integer cid=(ConvertHandle(u)+0x1E8)/4
    local real r1
    local real r2
    if cid < 0x1E8 then
        return false
    endif
    if Memory[cid]/4!=0 then
        set cid=Memory[cid]/4
        if Memory[cid+0x1E4/4]!=0 then
            set Memory[cid+0x1E4/4]=0
            return true
        endif
    endif
    return false
endfunction

function ChangeItemId takes item it, integer targetID returns nothing
    local integer cid=ConvertHandle(it)/4
    local integer curID
    if cid == 0 then
        return
    endif
    set curID=Memory[cid+0x30/4]
    set Memory[cid+0x30/4]=targetID
endfunction

function GetUnitMSBonus takes unit u returns real
    local integer cid=ConvertHandle(u)/4
    if cid <= 0 then
        return -1000.
    endif
    if Memory[cid+0x1EC/4]!=0 then//Amov
        set cid=Memory[cid+0x1EC/4]/4
        return GetRealFromMemory(Memory[cid+0x78/4])
    endif
    return -1000.
endfunction

function GetUnitCurrentBaseMS takes unit u returns real
    local integer cid=ConvertHandle(u)/4
    if cid <= 0 then
        return 0.
    endif
    if Memory[cid+0x1EC/4]!=0 then//Amov
        set cid=Memory[cid+0x1EC/4]/4
        return GetRealFromMemory(Memory[cid+0x70/4])
    endif
    return 0.
endfunction

//to set base MS use SetUnitMovespeed

function SetUnitMSBonus takes unit u, real r returns boolean
    local integer cid=ConvertHandle(u)/4
    if cid <= 0 then
        return false
    endif
    if Memory[cid+0x1EC/4]!=0 then//Amov
        set cid=Memory[cid+0x1EC/4]/4
        set Memory[cid+0x78/4]=SetRealIntoMemory(r)
        call SetUnitMoveSpeed(u,GetRealFromMemory(Memory[cid+0x70/4]))//required to update ms instantly
        return true
    endif
    return false
endfunction

function AddUnitMovespeedBonus takes unit u, real r returns nothing
    call SetUnitMSBonus(u,GetUnitMSBonus(u)+r)
endfunction

function RemoveAllUnitMovementDisables takes unit u returns nothing
    local integer a=GetHandleId(u)
    if a> 0 then
        set a=ConvertHandle(u)
        if a>0 then
            if Memory[a/4+0x1EC/4]>0 then
                set Memory[Memory[a/4+0x1EC/4]/4 + 0x7C/4]=0
            endif
        endif
    endif
endfunction

function IsUnitMovementDisabled takes unit u returns boolean
    local integer a=GetHandleId(u)
    if a> 0 then
        set a=ConvertHandle(u)
        if a>0 then
            if Memory[a/4+0x1EC/4]>0 then
                return Memory[Memory[a/4+0x1EC/4]/4 + 0x7C/4]<=0
            endif
        endif
    endif
    return false
endfunction

function ToggleUnitMovement takes integer a, integer d returns nothing
    if a>0 then
        if Memory[a/4+0x1EC/4]>0 then
            set Memory[Memory[a/4+0x1EC/4]/4 + 0x7C/4]=Memory[Memory[a/4+0x1EC/4]/4 + 0x7C/4]+d
        endif
    endif
endfunction

function DisableUnitMovement takes unit u returns nothing
    if u==null then
        return
    endif
    call ToggleUnitMovement(ConvertHandle(u),1)
endfunction

function EnableUnitMovement takes unit u returns nothing
    if u==null then
        return
    endif
    call ToggleUnitMovement(ConvertHandle(u),-1)
endfunction

function GetFrameItemAddress takes string name, integer id returns integer
    return CallFastCallWith2Args(pGetFrameItemAddress, GetStringAddress(name), id)
endfunction

function GetFrameSkinAddress takes string name, integer id returns integer
    return CallFastCallWith2Args(pGetFrameSkinAddress, GetStringAddress(name), id)
endfunction

function GetFrameTextAddress takes string name, integer id returns integer
    return CallFastCallWith2Args(pGetFrameTextAddress, GetStringAddress(name), id)
endfunction

function GetFrameTextAddressTEXT takes string name, integer id returns integer
    local integer FrameAddr = GetFrameTextAddress(name,id)
    if FrameAddr == 0 then
        return 0
    endif
    return ReadRealMemory(FrameAddr+0x9C)
endfunction

function GetFrameTextString takes string name, integer id returns string
    local integer FrameAddr = GetFrameTextAddress(name,id)
    if FrameAddr == 0 then
        return ""
    endif
    return ConvertNullTerminatedStringToString(ReadRealMemory(FrameAddr+0x9C))
endfunction

//function UpdateFrameText takes integer

// function UpdateFrameText takes integer addr returns nothing
    // local real x1 = cleanReal(indexToReal(ReadRealMemory(addr+0x44)))
    // local real y1 = cleanReal(indexToReal(ReadRealMemory(addr+0x48)))
    // local real x2 = cleanReal(indexToReal(ReadRealMemory(addr+0x4C)))
    // local real y2 = cleanReal(indexToReal(ReadRealMemory(addr+0x50)))
    // call WriteRealMemory(pReservedMemoryForUpdateFrameText,cleanInt(realToIndex(x1)))
    // call WriteRealMemory(pReservedMemoryForUpdateFrameText+4,cleanInt(realToIndex(y1)))
    // call WriteRealMemory(pReservedMemoryForUpdateFrameText+8,cleanInt(realToIndex(x2)))
    // call WriteRealMemory(pReservedMemoryForUpdateFrameText+12,cleanInt(realToIndex(y2)))
    // call CallThisCallWith2Args(ReadRealPointer1LVL(addr,0), addr,pReservedMemoryForUpdateFrameText)
// endfunction

function SetFrameTextAddress takes integer addr, string str returns nothing
    // call UpdateFrameText(addr)
    // call WriteRealMemory(addr+0x9C,GetStringAddress(str))
    // call UpdateFrameText(addr)
    call CallThisCallWith2Args(pUpdateFrameText,addr,GetStringAddress(str))
endfunction

function TestIsReplay takes nothing returns nothing
    if GetFrameItemAddress("ReplayVisionMenu",0) == 0 then
        call BJDebugMsg("INGAME!")
    else
        call BJDebugMsg("INREPLAY!")
    endif
endfunction

function DisableSaveGameSaveButton takes nothing returns nothing
    local integer pSaveGameSaveButton = GetFrameItemAddress("SaveGameFileEditBox",0)
    if pSaveGameSaveButton > 0 then
        set Memory[pSaveGameSaveButton/4 + 0x1D4/4] = 0
        set Memory[pSaveGameSaveButton/4 + 0x108/4] = 0
        set Memory[pSaveGameSaveButton/4 + 0x1E8/4] = 0
    endif
    set pSaveGameSaveButton = GetFrameItemAddress("FileListFrame",0)
    if pSaveGameSaveButton > 0 then
        set Memory[pSaveGameSaveButton/4 + 0x10C/4] = 0x3B03123E
    endif
endfunction

function TestDisableSaveGameButton takes nothing returns nothing
    local timer t=CreateTimer()
    call TimerStart(t,2.0,false,function DisableSaveGameSaveButton)
endfunction

function GetFrameAddress takes string name, integer id returns integer
    local integer nOffset1 = Memory[(pFrameDefClass + 0x1c)/4]/4
    local integer FirstAddress = Memory[nOffset1 + 2] + 0x10
    local integer NextAddress = FirstAddress
    local string checkstr
    local boolean firstcheck = true
 
    loop
        if NextAddress == 0 then
            return 0
        endif
   
        if NextAddress == pFrameDefClass + 8  then
            if firstcheck then
                set firstcheck = false
                set NextAddress = Memory[NextAddress/4]
            else
                return 0
            endif
        endif
   
        set checkstr = ConvertNullTerminatedStringToString(Memory[NextAddress/4+2])
   
        if checkstr == name then
            return NextAddress
        endif
   
        set NextAddress = Memory[NextAddress/4]
   
        if NextAddress == FirstAddress  or NextAddress == 0 then
            return 0
        endif
    endloop
 
    return 0
endfunction

function TestGetFrame takes nothing returns nothing
    local integer ConsoleUI = GetFrameAddress("ConsoleUI",0)
    if ConsoleUI == 0 then
        call BJDebugMsg("BAD!")
    else
        call BJDebugMsg(Int2Hex(ConsoleUI))
    endif
endfunction

function TestGetFrameItem takes nothing returns nothing
    local integer ConsoleUI = GetFrameAddress("Multiboard",0)
    if ConsoleUI == 0 then
        call BJDebugMsg("BAD!")
    else
        call BJDebugMsg(Int2Hex(ConsoleUI))
    endif
endfunction

// Don't use pReservedWritableMemory2 for pOffset
function GenerateNewPacket takes integer pOffset, integer pSize returns integer
    set Memory[pReservedWritableMemory2/4] = pPacketClass
    set Memory[pReservedWritableMemory2/4 + 1] = pOffset
    set Memory[pReservedWritableMemory2/4 + 2] = 0
    set Memory[pReservedWritableMemory2/4 + 3] = 0
    set Memory[pReservedWritableMemory2/4 + 4] = pSize
    set Memory[pReservedWritableMemory2/4 + 5] = 0xFFFFFFFF
    return pReservedWritableMemory2
endfunction

function SendGamePacket takes integer pOffset, integer pSize returns nothing
    //1st byte stands for ID, 2nd is pSize, rest is the body, w/e you want
    call CallFastCallWith2Args(pPacketSend, GenerateNewPacket(pOffset,pSize),0 )
endfunction


// Packet id : 0x01(Pause game) . Size : 1 byte
function Packet_Pause takes player p returns nothing
    if GetLocalPlayer() == p then
        set Memory[pReservedWritableMemory/4] = 0x00000001
        call SendGamePacket(pReservedWritableMemory,1)
    endif
endfunction


// Packet id : 0x02(Resume game) . Size : 1 byte
// Can't use from jass if not after Pause
function Packet_Resume takes player p returns nothing
    if GetLocalPlayer() == p then
        set Memory[pReservedWritableMemory/4] = 0x00000002
        call SendGamePacket(pReservedWritableMemory,1)
    endif
endfunction



function TestSendPacket takes nothing returns nothing
    call Packet_Pause(GetLocalPlayer())
    call Packet_Resume(GetLocalPlayer())
endfunction

function IsPingMinimapLocked takes nothing returns boolean
    return Memory[pPingMinimapOffset/4] == 0x90C3C08B
endfunction


function LockPingMinimap takes nothing returns nothing
    local integer oldprotection = ChangeOffsetProtection( pPingMinimapOffset,4,0x40)
 
    if NotLockedPingMinimap and IsPingMinimapLocked( ) then
        call MaphackDetected( GetLocalPlayer( ), "Ping hack detected!" )
    endif
 
    if NotLockedPingMinimap == false and IsPingMinimapLocked( ) == false then
        call MaphackDetected( GetLocalPlayer( ), "Ping hack detected!#2" )
    endif
 
    if NotLockedPingMinimap then
        set PingMinimapUnlocker = Memory[pPingMinimapOffset/4]
        set NotLockedPingMinimap = false
    endif
    set Memory[pPingMinimapOffset/4] = 0x90C3C08B
    call ChangeOffsetProtection( pPingMinimapOffset,4, oldprotection)
endfunction


function UnlockPingMinimap takes nothing returns nothing
    local integer oldprotection = ChangeOffsetProtection( pPingMinimapOffset,4,0x40)
 
    if NotLockedPingMinimap and IsPingMinimapLocked( ) then
        call MaphackDetected( GetLocalPlayer( ), "Ping hack detected!#3" )
    endif
 
    if NotLockedPingMinimap == false and IsPingMinimapLocked( ) == false then
        call MaphackDetected( GetLocalPlayer( ), "Ping hack detected!#4" )
    endif
 
    if NotLockedPingMinimap == false then
        set Memory[pPingMinimapOffset/4] = PingMinimapUnlocker
        set NotLockedPingMinimap = true
    endif
    call ChangeOffsetProtection( pPingMinimapOffset,4, oldprotection)
endfunction


function IsPingMinimapExLocked takes nothing returns boolean
    return Memory[pPingMinimapExOffset/4] == 0x90C3C08B
endfunction

function LockPingMinimapEx takes nothing returns nothing
    local integer oldprotection = ChangeOffsetProtection( pPingMinimapExOffset,4,0x40)
 
    if NotLockedPingMinimapEx and IsPingMinimapExLocked( ) then
        call MaphackDetected( GetLocalPlayer( ), "PingEx hack detected!" )
    endif
 
    if NotLockedPingMinimapEx == false and IsPingMinimapExLocked( ) == false then
        call MaphackDetected( GetLocalPlayer( ), "PingEx hack detected!#2" )
    endif
 
    if NotLockedPingMinimapEx then
        set PingMinimapExUnlocker = Memory[pPingMinimapExOffset/4]
        set NotLockedPingMinimapEx = false
    endif
    set Memory[pPingMinimapExOffset/4] = 0x90C3C08B
    call ChangeOffsetProtection( pPingMinimapExOffset,4, oldprotection)
endfunction

function UnlockPingMinimapEx takes nothing returns nothing
    local integer oldprotection = ChangeOffsetProtection( pPingMinimapExOffset,4,0x40)
 
    if NotLockedPingMinimapEx and IsPingMinimapExLocked( ) then
        call MaphackDetected( GetLocalPlayer( ), "PingEx hack detected!#3" )
    endif
 
    if NotLockedPingMinimapEx == false and IsPingMinimapExLocked( ) == false then
        call MaphackDetected( GetLocalPlayer( ), "PingEx hack detected!#4" )
    endif
 
 
    if NotLockedPingMinimapEx == false then
        set Memory[pPingMinimapExOffset/4] = PingMinimapExUnlocker
        set NotLockedPingMinimapEx = true
    endif
    call ChangeOffsetProtection( pPingMinimapExOffset,4, oldprotection)
endfunction


function nPngMinimap takes real x, real y, real d returns nothing
    call UnlockPingMinimap( )
    call PingMinimap(x,y,d)
    call LockPingMinimap( )
endfunction


function nPngMinimapEx takes real x, real y, real d, integer r, integer g, integer b, boolean e returns nothing
    call UnlockPingMinimapEx( )
    call PingMinimapEx(x,y,d,r,g,b,e)
    call LockPingMinimapEx( )
endfunction

function MinimapLockerInitialize takes nothing returns nothing
    call LockPingMinimap( )
    call LockPingMinimapEx( )
endfunction

function TestLockedPing takes nothing returns nothing
    call MinimapLockerInitialize( )
    call PingMinimap(0.,0.,3.)
endfunction

function GetAsyncKeyState takes integer vk_key_code returns integer
    local integer retval = 0
    local integer nOffset1
 
    if pGetAsyncKeyState == 0 then
        set pGetAsyncKeyState = GetModuleProcAddress("User32.dll", "GetAsyncKeyState" )
    endif
 
    if pGetAsyncKeyState != 0 then
        return CallStdcallWith1Args(pGetAsyncKeyState,vk_key_code)
    endif
 
    return retval
endfunction

function IsKeyPressed takes integer vk_key_code returns boolean
    return  BitwiseAnd(GetAsyncKeyState(vk_key_code),0x8000) > 0
endfunction

function TestKeyPressed takes nothing returns nothing
    //https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
    local integer VK_LMENU = 0xA4
    if IsKeyPressed(VK_LMENU) then
        call BJDebugMsg("LEFT ALT IS PRESSED")
    else
        call BJDebugMsg("PLEASE PRESS AND HOLD ALT KEY")
    endif
endfunction

function LockAllianceOutput takes boolean block returns nothing
    local integer oldprotection = ChangeOffsetProtection( pAllianceOutput,4,0x40)
    if NotLockedAllianceOutput then
        set AllianceLocker = Memory[pAllianceOutput/4]
        set NotLockedAllianceOutput = false
    endif
    if block then
        set Memory[pAllianceOutput/4] = 0xCC0008C2
    else
        set Memory[pAllianceOutput/4] = AllianceLocker
    endif
    call ChangeOffsetProtection( pAllianceOutput,4, oldprotection)
endfunction



function EnableAllyCheckbox takes nothing returns nothing
    local integer i = 0
    local integer pAllyCheckBoxAddr
    loop
        if IsPlayerAlly(Player(0),GetLocalPlayer()) then
            set pAllyCheckBoxAddr = GetFrameItemAddress("UnitsCheckBox",i)
            if pAllyCheckBoxAddr > 0 then
                set pAllyCheckBoxAddr = pAllyCheckBoxAddr + 0x1D4
                    if BitwiseAnd(Memory[pAllyCheckBoxAddr/4],1) == 0 then
                        set Memory[pAllyCheckBoxAddr/4] = BitwiseOr(Memory[pAllyCheckBoxAddr/4],1)
                    endif
            endif
        endif
        exitwhen i > 11
    endloop
endfunction


function EnableAllyCheckbox2 takes nothing returns nothing
    local integer i = 0
    local integer pAllyCheckBoxAddr
    loop
        set pAllyCheckBoxAddr = GetFrameItemAddress("UnitsCheckBox",i)
        if pAllyCheckBoxAddr > 0 then
            set pAllyCheckBoxAddr = pAllyCheckBoxAddr + 0x1D4
                if BitwiseAnd(Memory[pAllyCheckBoxAddr/4],1) == 0 then
                    set Memory[pAllyCheckBoxAddr/4] = BitwiseOr(Memory[pAllyCheckBoxAddr/4],1)
                endif
        endif
        exitwhen i > 11
    endloop
endfunction


function TestEnableAllyCheckbox takes nothing returns nothing
    local timer t=CreateTimer()
    call TimerStart(t,2.0,false,function EnableAllyCheckbox)
endfunction

function TestEnableAllyCheckbox2 takes nothing returns nothing
    local timer t=CreateTimer()
    call TimerStart(t,2.0,false,function EnableAllyCheckbox2)
endfunction

function IsWindowActive takes nothing returns boolean
    return Memory[pWindowIsActive] > 0
endfunction

//SendActionWithoutTarget(0xd0004) - stop
function SendActionWithoutTarget takes integer orderid returns nothing
    call CallStdcallWith4Args(pSendCommandWithoutTarget,orderid,0,1,4)
endfunction

// 0 - default, 1 - path, 2 - splash, 3 - bounce, 4 - line
function GetMissilesCount takes integer missiletype returns integer
    return Memory[pMissile+3+(missiletype*6)]
endfunction

function GetFirstMissile takes integer missiletype returns integer
    return Memory[pMissile+4+(missiletype*6)]
endfunction

function GetLatestMissile takes integer missiletype returns integer
    return Memory[pMissile+5+(missiletype*6)]
endfunction

function GetMouseEnv takes nothing returns integer
    return Memory[Memory[pGameClass2]/4 + 0x3BC/4] + 0x310
endfunction

function GetMouseX takes nothing returns real
    return cleanReal(indexToReal(Memory[GetMouseEnv( )/4 + 0]))
endfunction

function GetMouseY takes nothing returns real
    return cleanReal(indexToReal(Memory[GetMouseEnv( )/4 + 1]))
endfunction

function GetMouseZ takes nothing returns real
    return cleanReal(indexToReal(Memory[GetMouseEnv( )/4 + 2]))
endfunction

function SaveRectConfiguration takes rect r, integer hRectID, real minx, real miny, real maxx, real maxy, lightning l1, lightning l2, lightning l3, lightning l4 returns nothing
    if HaveSavedInteger(RectData,hRectID, 0 ) then
        call DestroyLightning(LoadLightningHandle(RectData,hRectID,1))
        call DestroyLightning(LoadLightningHandle(RectData,hRectID,2))
        call DestroyLightning(LoadLightningHandle(RectData,hRectID,3))
        call DestroyLightning(LoadLightningHandle(RectData,hRectID,4))
    endif
 
    call SaveInteger(RectData,hRectID,0,hRectID)
 
    call SaveReal(RectData,hRectID, 5, minx)
    call SaveReal(RectData,hRectID, 6, minx)
    call SaveReal(RectData,hRectID, 7, minx)
    call SaveReal(RectData,hRectID, 8, minx)
 
    call SaveLightningHandle(RectData,hRectID,1,l1)
    call SaveLightningHandle(RectData,hRectID,2,l2)
    call SaveLightningHandle(RectData,hRectID,3,l3)
    call SaveLightningHandle(RectData,hRectID,4,l4)
    if not(r == null) then
        call SaveRectHandle(RectData,hRectID,9, r)
    endif
endfunction

function GetRectIdFromMousePosition takes real x, real y returns integer
    local integer hRectID = 1
    local rect r = null
    loop
        if not(HaveSavedInteger(RectData,hRectID,0)) then
            return -1
        endif

        set r = LoadRectHandle(RectData,hRectID,9)

        if RectContainsCoords(r,x,y) then
            return hRectID
        endif
        set hRectID = hRectID + 1
    endloop
    return -1
endfunction

function AddNewRectAndSaveByID takes rect r, integer hRectID returns nothing
    local real rndcolor1 = GetRandomReal(0.,1.)
    local real rndcolor2 = GetRandomReal(0.,1.)
    local real rndcolor3 = GetRandomReal(0.,1.)
    local real minx = GetRectMinX(r)
    local real miny = GetRectMinY(r)
    local real maxx = GetRectMaxX(r)
    local real maxy = GetRectMaxY(r)
    // Left
    local lightning hLighting1 = AddLightning("DRAM", false, minx, miny, minx, maxy)
    // TOP
    local lightning hLighting2 = AddLightning("DRAM", false, minx, miny, maxx, miny)
    // RIGHT
    local lightning hLighting3 = AddLightning("DRAM", false, maxx, miny, maxx, maxy)
    // DOWN
    local lightning hLighting4 = AddLightning("DRAM", false, minx, maxy, maxx, maxy)
 

    call SetLightningColor(hLighting1,rndcolor1,rndcolor2,rndcolor3,1.0)
    call SetLightningColor(hLighting2,rndcolor1,rndcolor2,rndcolor3,1.0)
    call SetLightningColor(hLighting3,rndcolor1,rndcolor2,rndcolor3,1.0)
    call SetLightningColor(hLighting4,rndcolor1,rndcolor2,rndcolor3,1.0)

    call SaveRectConfiguration(r, hRectID ,minx,miny,maxx,maxy,hLighting1,hLighting2,hLighting3,hLighting4)
endfunction

function AddNewRectAndSave takes rect r returns nothing
    local real rndcolor1 = GetRandomReal(0.,1.)
    local real rndcolor2 = GetRandomReal(0.,1.)
    local real rndcolor3 = GetRandomReal(0.,1.)
    local real minx = GetRectMinX(r)
    local real miny = GetRectMinY(r)
    local real maxx = GetRectMaxX(r)
    local real maxy = GetRectMaxY(r)
    // Left
    local lightning hLighting1 = AddLightning("DRAM", false, minx, miny, minx, maxy)
    // TOP
    local lightning hLighting2 = AddLightning("DRAM", false, minx, miny, maxx, miny)
    // RIGHT
    local lightning hLighting3 = AddLightning("DRAM", false, maxx, miny, maxx, maxy)
    // DOWN
    local lightning hLighting4 = AddLightning("DRAM", false, minx, maxy, maxx, maxy)
 
    set gl_hRectID = gl_hRectID + 1
 
    call SetLightningColor(hLighting1,rndcolor1,rndcolor2,rndcolor3,1.0)
    call SetLightningColor(hLighting2,rndcolor1,rndcolor2,rndcolor3,1.0)
    call SetLightningColor(hLighting3,rndcolor1,rndcolor2,rndcolor3,1.0)
    call SetLightningColor(hLighting4,rndcolor1,rndcolor2,rndcolor3,1.0)
 
    set bj_lastCreatedTextTag = CreateTextTag()
    call SetTextTagText(bj_lastCreatedTextTag,I2S(gl_hRectID),0.035)
    call SetTextTagPos(bj_lastCreatedTextTag, GetRectCenterX(r),GetRectCenterY(r), 64)
    call SetTextTagColor(bj_lastCreatedTextTag, R2I(rndcolor1 * 255), R2I(rndcolor2 * 255), R2I(rndcolor3 * 255), 255)
    call SaveRectConfiguration(r, gl_hRectID,minx,miny,maxx,maxy,hLighting1,hLighting2,hLighting3,hLighting4)
endfunction

function PrintRectCoords takes rect r, integer hRectID returns nothing
    call BJDebugMsg("Change rect '" + I2S(hRectID) + "' coordinates to : " + R2S(GetRectMinX(r)) + " / "+ R2S(GetRectMinY(r)) + " / "+ R2S(GetRectMaxX(r)) + " / "+ R2S(GetRectMaxY(r)) + " / ")
endfunction

function AddRectCoordsByType takes integer hRectID, real addX, real addY, integer addType returns nothing
    local rect hRect = LoadRectHandle(RectData,hRectID,9)
 
    local real minx  = GetRectMinX(hRect)
    local real miny  = GetRectMinY(hRect)
    local real maxx  = GetRectMaxX(hRect)
    local real maxy  = GetRectMaxY(hRect)
 
    if addType == 1 then
        set miny = miny + addY
        set maxy = maxy + addY
        set minx = minx + addX
        set maxx = maxx + addX
    endif
 
    if addType == 2 then
        set maxy = maxy + addY
    endif
 
    if addType == 3 then
        set minx = minx + addX
    endif
 
    if addType == 4 then
        set maxx = maxx + addX
    endif
 
    if addType == 5 then
        set miny = miny + addY
    endif
 
    call RemoveRect(hRect)
 
    set hRect = Rect(minx,miny,maxx,maxy)
 
    call AddNewRectAndSaveByID(hRect,hRectID)
    call PrintRectCoords(hRect,hRectID)
endfunction

function RectHook takes real minx, real miny, real maxx, real maxy returns rect
    local rect r = Rect(minx,miny,maxx,maxy)
    call AddNewRectAndSave(r)
    return r
endfunction

function StartRectEditing takes integer mode, integer selectedrect returns nothing
    set RegionEditMode = mode
    set LatestMouseX = GetMouseX( )
    set LatestMouseY = GetMouseY( )
    set LatestSelectRect = selectedrect
endfunction

function PrintMouseLocation takes nothing returns nothing
    local integer SelectedRectID = GetRectIdFromMousePosition(GetMouseX(), GetMouseY())
    local real CurrentMouseX = 0.
    local real CurrentMouseY = 0.
    local real AddX            =  0.
    local real AddY            =  0.
 
    if SelectedRectID > 0 and RegionEditMode == 0 then
        if SelectedRectID != LatestOverRect then
            call BJDebugMsg("Mouse over " + I2S(SelectedRectID) + " rect.")
        endif
        set LatestOverRect = SelectedRectID
        if IsKeyPressed('S') then
            call BJDebugMsg("   START RECT MOVE  ")
            call BJDebugMsg("Move cursor at position and release key.")
            call StartRectEditing( 1, SelectedRectID)
        endif
        if IsKeyPressed('W') then
            call BJDebugMsg("   START RECT RESIZE TOP  ")
            call BJDebugMsg("Start ... Move cursor at position and release key.")
            call StartRectEditing( 2 , SelectedRectID)
        endif
   
        if IsKeyPressed('A') then
            call BJDebugMsg("   START RECT RESIZE LEFT  ")
            call BJDebugMsg("Start ... Move cursor at position and release key.")
            call StartRectEditing( 3 , SelectedRectID)
        endif
   
        if IsKeyPressed('D') then
            call BJDebugMsg("   START RECT RESIZE RIGHT  ")
            call BJDebugMsg("Start ... Move cursor at position and release key.")
            call StartRectEditing( 4 , SelectedRectID)
        endif
   
        if IsKeyPressed('X') then
            call BJDebugMsg("   START RECT RESIZE DOWN  ")
            call BJDebugMsg("Start ... Move cursor at position and release key.")
            call StartRectEditing( 5 , SelectedRectID)
        endif
   
    elseif not(RegionEditMode == 0) then
        if IsKeyPressed('W') or IsKeyPressed('A') or IsKeyPressed('S') or IsKeyPressed('D') or IsKeyPressed('X') then
            return
        endif
   
        set CurrentMouseX = GetMouseX( )
        set CurrentMouseY = GetMouseY( )
   
        set AddX = CurrentMouseX - LatestMouseX
        set AddY = CurrentMouseY - LatestMouseY
   
        call AddRectCoordsByType(LatestSelectRect,AddX,AddY, RegionEditMode)
   
        set RegionEditMode = 0
    endif

endfunction

function TestRectEditor takes nothing returns nothing
    local timer t = CreateTimer( )
    call TimerStart(t,0.2,true,function PrintMouseLocation)
    call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
    call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
    call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
    call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
    call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
    call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
    call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
    call RectHook(GetRandomReal(-500,500),GetRandomReal(-500,500),GetRandomReal(-1000,1000),GetRandomReal(-1000,1000))
 
endfunction


function TestPlayerMute takes boolean pMute, player p, string playername returns nothing
    if pMute then
        call MutePlayer( playername )
    else
        call UnMutePlayer( playername )
    endif
endfunction

function ReadEAX takes nothing returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C08B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits)
    return retval
endfunction

function ReadEBX takes nothing returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C38B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return retval
endfunction

function ReadECX takes nothing returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C18B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return retval
endfunction

function ReadEDX takes nothing returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C28B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return retval
endfunction

function ReadESI takes nothing returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C68B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return retval
endfunction

function ReadEDI takes nothing returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C78B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return retval
endfunction

function ReadEBP takes nothing returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C58B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return retval
endfunction

function ReadESP takes nothing returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C48B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,  pIgnoredUnits)
    return retval
endfunction


function ReadEAX_offset takes integer offset returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C08B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return Memory[(retval+offset)/4]
endfunction

function ReadEBX_offset takes integer offset returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C38B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return Memory[(retval+offset)/4]
endfunction

function ReadECX_offset takes integer offset returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C18B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return Memory[(retval+offset)/4]
endfunction

function ReadEDX_offset takes integer offset returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C28B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return Memory[(retval+offset)/4]
endfunction

function ReadESI_offset takes integer offset returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C68B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits )
    return Memory[(retval+offset)/4]
endfunction

function ReadEDI_offset takes integer offset returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C78B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset, pIgnoredUnits )
    return Memory[(retval+offset)/4]
endfunction

function ReadEBP_offset takes integer offset returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C58B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset,pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return Memory[(retval+offset)/4]
endfunction

function ReadESP_offset takes integer offset returns integer
    local integer retval = 0
    set Memory[pReservedExecutableMemory/4] = 0xCCC3C48B
 
    if pIgnoredUnitsOffset == 0 then
        set pIgnoredUnitsOffset = CreateJassNativeHook(pIgnoredUnits, pReservedExecutableMemory )
    else
        call WriteRealMemory(pIgnoredUnitsOffset, pReservedExecutableMemory)
    endif
 
    set retval = IgnoredUnits(0)
    call WriteRealMemory(pIgnoredUnitsOffset,pIgnoredUnits )
    return Memory[(retval+offset)/4]
endfunction


// WARNING!! IT CAN BE USED ONLY IN FIRST CONDITION AT FIRST POSITION
function GJ_GetRealDmg126a takes nothing returns real
    return cleanReal(indexToReal(ReadEBP_offset(0x380)))
endfunction

// WARNING!! IT CAN BE USED ONLY IN FIRST CONDITION AT FIRST POSITION
function GJ_GetRealDmg127a takes nothing returns real
    return cleanReal(indexToReal(ReadEBP_offset(0x400)))
endfunction

function GJ_SaveLastDmg126a takes nothing returns boolean
    if GetTriggerEventId()!=EVENT_UNIT_DAMAGED then
        return true
    endif
 
    set GJ_LastDmg = GJ_GetRealDmg126a( )
 
    set GJ_LastAttackType=ReadEBP_offset(0x37C)
    if ReadEBP_offset(0x368)!=0 or ReadEBP_offset(0x378)==0x3F800000 then
        set GJ_LastDamageType=0
    else
        set GJ_LastDamageType=ReadEBP_offset(0x378)
    endif
//    call BJDebugMsg("rewrote with "+R2S(GJ_LastDmg))
    return true
endfunction

function GJ_SaveLastDmg127a takes nothing returns boolean
    if GetTriggerEventId()!=EVENT_UNIT_DAMAGED then
        return true
    endif
    set GJ_LastDmg = GJ_GetRealDmg127a( )
    set GJ_LastAttackType=ReadEBP_offset(0x3B0)
    if ReadEBP_offset(0x3CC)!=0 then
        set GJ_LastDamageType=0
    else
        set GJ_LastDamageType=ReadEBP_offset(0x3F0)
    endif
    return true
endfunction

    //integer pGetLatestDownloadedString = 0
    // integer pGetDownloadStatus = 0
    // integer pSaveNewMapFromUrl = 0
function GetLatestDownloadedString takes nothing returns string
    local integer retval = 0

    if pGetLatestDownloadedString == 0 then
        set pGetLatestDownloadedString = GetModuleProcAddress(EXTRADLLNAME, "GetLatestDownloadedString")
    endif
    if pGetLatestDownloadedString != 0 then
        return ConvertNullTerminatedStringToString(CallStdcallWith1Args(pGetLatestDownloadedString,0))
    endif
    return ""
endfunction

    // integer pSaveNewMapFromUrl = 0
function GetCurrentMapDir takes nothing returns string
    local integer retval = 0

    if pGetCurrentMapDir == 0 then
        set pGetCurrentMapDir = GetModuleProcAddress(EXTRADLLNAME, "GetCurrentMapPath")
    endif
    if pGetCurrentMapDir != 0 then
        return ConvertNullTerminatedStringToString(CallStdcallWith1Args(pGetCurrentMapDir,0))
    endif
    return ""
endfunction


function GetDownloadProgress takes nothing returns integer
    local integer retval = 0

    if pGetDownloadProgress == 0 then
        set pGetDownloadProgress = GetModuleProcAddress(EXTRADLLNAME, "GetDownloadProgress")
    endif
    if pGetDownloadProgress != 0 then
        set retval = CallStdcallWith1Args(pGetDownloadProgress,0)
    endif
    return retval
endfunction

function GetDownloadStatus takes nothing returns integer
    local integer retval = 0
    // -1 - error
    // 0 - nothing been dl'd
    // 1 - dl finished
    // 2 - file exists or broken path
 
    if pGetDownloadStatus == 0 then
        set pGetDownloadStatus = GetModuleProcAddress(EXTRADLLNAME, "GetDownloadStatus")
    endif
    if pGetDownloadStatus != 0 then
        set retval = CallStdcallWith1Args(pGetDownloadStatus,0)
    endif
    return retval
endfunction

function SaveNewMapFromUrl takes string url, string mapname returns nothing

    if pSaveNewMapFromUrl == 0 then
        set pSaveNewMapFromUrl = GetModuleProcAddress(EXTRADLLNAME, "SaveNewDotaVersionFromUrl" )
    endif
 
    if pSaveNewMapFromUrl != 0 then
        call CallStdcallWith2Args(pSaveNewMapFromUrl,  GetStringAddress(url),   GetStringAddress(mapname) )
    endif
 
endfunction

function SendGetRequest takes integer WebSiteAddr, integer GetPath returns nothing
    if pSendHttpGetRequest == 0 then
        set pSendHttpGetRequest = GetModuleProcAddress(EXTRADLLNAME, "SendGetRequest" )
    endif
    if pSendHttpGetRequest != 0 then
        call CallStdcallWith2Args(pSendHttpGetRequest,  WebSiteAddr,  GetPath )
    endif
endfunction

function SendHttpGetRequest takes string WebSiteAddr, string GetPath returns nothing
    call SendGetRequest( GetStringAddress(WebSiteAddr), GetStringAddress(GetPath))
endfunction

function TestSendHttpGetRequest takes nothing returns nothing
    call SendHttpGetRequest("d1stats.ru","/test.php?q1=1234&q2=21234&q3=31234&q4=41234&q5=51234&q6=61234&q7=71234&q8=81234&q9=91234&q10=101234")
endfunction

function StartDownloadNewDotaVersion takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local integer i = GetDownloadStatus( )
    if i != 0 then
        if i == 1 then
            call BJDebugMsg( " ALL OKAY , DOTA DOWNLOADED " )
        else
            call BJDebugMsg( " ALL BAD , DOTA NE DOWNLOADED ")
        endif
        call DestroyTimer(t)
        set t = null
    else
        call DisplayTimedTextToForce(bj_FORCE_ALL_PLAYERS,1.0, "DownloadProgress:" + I2S( GetDownloadProgress( ) ) + "%..")
    endif
endfunction

function WaitForGetDotaVersion takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local integer i = GetDownloadStatus( )
    local string s = ""
    if i != 0 then
        if i == 1 then
            set s = GetLatestDownloadedString( )
            call BJDebugMsg("Status: ok,map name:" + s)
            call SaveNewMapFromUrl("http://d1stats.ru/files/Allstars/" + s + ".w3x",GetCurrentMapDir( ) + s + ".w3x")
            call BJDebugMsg("url: http://d1stats.ru/files/Allstars/" + s + ".w3x, filename:" + s + ".w3x")
            call TimerStart(CreateTimer( ),1.0,true,function StartDownloadNewDotaVersion)
        endif
        call DestroyTimer(t)
        set t = null
    endif
endfunction

function WaitForDownloadServerStatus takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local integer i = GetDownloadStatus( )
    if i != 0 then
        if i == 1 then
            call BJDebugMsg("Status: ok, now get map name...")
            call SendHttpGetRequest("d1stats.ru","/last.php")
            call TimerStart(CreateTimer( ),0.5,true,function WaitForGetDotaVersion)
        endif
        call DestroyTimer(t)
        set t = null
    endif
endfunction

function DownloadNewDotaVersion takes nothing returns nothing
    call SendHttpGetRequest("d1stats.ru","/last.php")
    call TimerStart(CreateTimer( ),0.2,true,function WaitForDownloadServerStatus)
endfunction



function LockOrder takes integer id, boolean IsNeedLock returns nothing

    local integer oldprotection = 0

    if id == 1 then
        if IsNeedLock then
            if IsOrder1Locked == false then
                if Order1_unlockedvalue == 0 then
                    set Order1_unlockedvalue = Memory[pOrder1_offset/4]
                endif
                set oldprotection = ChangeOffsetProtection(pOrder1_offset,4,0x40)
                set Memory[pOrder1_offset/4] = Order1_lockedvalue
                call ChangeOffsetProtection(pOrder1_offset,4,oldprotection)
                set IsOrder1Locked = true
            endif
        else
            if IsOrder1Locked == true then
                set oldprotection = ChangeOffsetProtection(pOrder1_offset,4,0x40)
                set Memory[pOrder1_offset/4] = Order1_unlockedvalue
                call ChangeOffsetProtection(pOrder1_offset,4,oldprotection)
                set IsOrder1Locked = false
            endif
        endif
    elseif id == 2 then
        if IsNeedLock then
            if IsOrder2Locked == false then
                if Order2_unlockedvalue == 0 then
                    set Order2_unlockedvalue = Memory[pOrder2_offset/4]
                endif
                set oldprotection = ChangeOffsetProtection(pOrder2_offset,4,0x40)
                set Memory[pOrder2_offset/4] = Order2_lockedvalue
                call ChangeOffsetProtection(pOrder2_offset,4,oldprotection)
                set IsOrder2Locked = true
            endif
        else
            if IsOrder2Locked == true then
                set oldprotection = ChangeOffsetProtection(pOrder2_offset,4,0x40)
                set Memory[pOrder2_offset/4] = Order2_unlockedvalue
                call ChangeOffsetProtection(pOrder2_offset,4,oldprotection)
                set IsOrder2Locked = false
            endif
        endif
    elseif id == 3 then
        if IsNeedLock then
            if IsOrder3Locked == false then
                if Order3_unlockedvalue == 0 then
                    set Order3_unlockedvalue = Memory[pOrder3_offset/4]
                endif
                set oldprotection = ChangeOffsetProtection(pOrder3_offset,4,0x40)
                set Memory[pOrder3_offset/4] = Order3_lockedvalue
                call ChangeOffsetProtection(pOrder3_offset,4,oldprotection)
                set IsOrder3Locked = true
            endif
        else
            if IsOrder3Locked == true then
                set oldprotection = ChangeOffsetProtection(pOrder3_offset,4,0x40)
                set Memory[pOrder3_offset/4] = Order3_unlockedvalue
                call ChangeOffsetProtection(pOrder3_offset,4,oldprotection)
                set IsOrder3Locked = false
            endif
        endif
    elseif id == 4 then
        if IsNeedLock then
            if IsOrder4Locked == false then
                if Order4_unlockedvalue == 0 then
                    set Order4_unlockedvalue = Memory[pOrder4_offset/4]
                endif
                set oldprotection = ChangeOffsetProtection(pOrder4_offset,4,0x40)
                set Memory[pOrder4_offset/4] = Order4_lockedvalue
                call ChangeOffsetProtection(pOrder4_offset,4,oldprotection)
                set IsOrder4Locked = true
            endif
        else
            if IsOrder4Locked == true then
                set oldprotection = ChangeOffsetProtection(pOrder4_offset,4,0x40)
                set Memory[pOrder4_offset/4] = Order4_unlockedvalue
                call ChangeOffsetProtection(pOrder4_offset,4,oldprotection)
                set IsOrder4Locked = false
            endif
        endif
    elseif id == 5 then
        if IsNeedLock then
            if IsOrder5Locked == false then
                if Order5_unlockedvalue == 0 then
                    set Order5_unlockedvalue = Memory[pOrder5_offset/4]
                endif
                set oldprotection = ChangeOffsetProtection(pOrder5_offset,4,0x40)
                set Memory[pOrder5_offset/4] = Order5_lockedvalue
                call ChangeOffsetProtection(pOrder5_offset,4,oldprotection)
                set IsOrder5Locked = true
            endif
        else
            if IsOrder5Locked == true then
                set oldprotection = ChangeOffsetProtection(pOrder5_offset,4,0x40)
                set Memory[pOrder5_offset/4] = Order5_unlockedvalue
                call ChangeOffsetProtection(pOrder5_offset,4,oldprotection)
                set IsOrder5Locked = false
            endif
        endif
    elseif id == 6 then
        if IsNeedLock then
            if IsOrder6Locked == false then
                if Order6_unlockedvalue == 0 then
                    set Order6_unlockedvalue = Memory[pOrder6_offset/4]
                endif
                set oldprotection = ChangeOffsetProtection(pOrder6_offset,4,0x40)
                set Memory[pOrder6_offset/4] = Order6_lockedvalue
                call ChangeOffsetProtection(pOrder6_offset,4,oldprotection)
                set IsOrder6Locked = true
            endif
        else
            if IsOrder6Locked == true then
                set oldprotection = ChangeOffsetProtection(pOrder6_offset,4,0x40)
                set Memory[pOrder6_offset/4] = Order6_unlockedvalue
                call ChangeOffsetProtection(pOrder6_offset,4,oldprotection)
                set IsOrder6Locked = false
            endif
        endif
    elseif id == 7 then
        if IsNeedLock then
            if IsOrder7Locked == false then
                if Order7_unlockedvalue == 0 then
                    set Order7_unlockedvalue = Memory[pOrder7_offset/4]
                endif
                set oldprotection = ChangeOffsetProtection(pOrder7_offset,4,0x40)
                set Memory[pOrder7_offset/4] = Order7_lockedvalue
                call ChangeOffsetProtection(pOrder7_offset,4,oldprotection)
                set IsOrder7Locked = true
            endif
        else
            if IsOrder7Locked == true then
                set oldprotection = ChangeOffsetProtection(pOrder7_offset,4,0x40)
                set Memory[pOrder7_offset/4] = Order7_unlockedvalue
                call ChangeOffsetProtection(pOrder7_offset,4,oldprotection)
                set IsOrder7Locked = false
            endif
        endif
    elseif id == 8 then
        if IsNeedLock then
            if IsOrder8Locked == false then
                if Order8_unlockedvalue == 0 then
                    set Order8_unlockedvalue = Memory[pOrder8_offset/4]
                endif
                set oldprotection = ChangeOffsetProtection(pOrder8_offset,4,0x40)
                set Memory[pOrder8_offset/4] = Order8_lockedvalue
                call ChangeOffsetProtection(pOrder8_offset,4,oldprotection)
                set IsOrder8Locked = true
            endif
        else
            if IsOrder8Locked == true then
                set oldprotection = ChangeOffsetProtection(pOrder8_offset,4,0x40)
                set Memory[pOrder8_offset/4] = Order8_unlockedvalue
                call ChangeOffsetProtection(pOrder8_offset,4,oldprotection)
                set IsOrder8Locked = false
            endif
        endif
    endif
endfunction


function LockOrder1 takes nothing returns nothing
    call LockOrder(1,true)
endfunction
function LockOrder2 takes nothing returns nothing
    call LockOrder(2,true)
endfunction
function LockOrder3 takes nothing returns nothing
    call LockOrder(3,true)
endfunction
function LockOrder4 takes nothing returns nothing
    call LockOrder(4,true)
endfunction
function LockOrder5 takes nothing returns nothing
    call LockOrder(5,true)
endfunction
function LockOrder6 takes nothing returns nothing
    call LockOrder(6,true)
endfunction
function LockOrder7 takes nothing returns nothing
    call LockOrder(7,true)
endfunction
function LockOrder8 takes nothing returns nothing
    call LockOrder(8,true)
endfunction

function UnLockOrder1 takes nothing returns nothing
    call LockOrder(1,false)
endfunction
function UnLockOrder2 takes nothing returns nothing
    call LockOrder(2,false)
endfunction
function UnLockOrder3 takes nothing returns nothing
    call LockOrder(3,false)
endfunction
function UnLockOrder4 takes nothing returns nothing
    call LockOrder(4,false)
endfunction
function UnLockOrder5 takes nothing returns nothing
    call LockOrder(5,false)
endfunction
function UnLockOrder6 takes nothing returns nothing
    call LockOrder(6,false)
endfunction
function UnLockOrder7 takes nothing returns nothing
    call LockOrder(7,false)
endfunction
function UnLockOrder8 takes nothing returns nothing
    call LockOrder(8,false)
endfunction



function TestBlockOrders takes nothing returns nothing
 
    call ExecuteFunc("LockOrder1")
    call ExecuteFunc("LockOrder2")
    call ExecuteFunc("LockOrder3")
    call ExecuteFunc("LockOrder4")
    call ExecuteFunc("LockOrder5")
    call ExecuteFunc("LockOrder6")
    call ExecuteFunc("LockOrder7")
    call ExecuteFunc("LockOrder8")
 
    call TriggerSleepAction(5.0)
 
    call ExecuteFunc("UnLockOrder1")
    call ExecuteFunc("UnLockOrder2")
    call ExecuteFunc("UnLockOrder3")
    call ExecuteFunc("UnLockOrder4")
    call ExecuteFunc("UnLockOrder5")
    call ExecuteFunc("UnLockOrder6")
    call ExecuteFunc("UnLockOrder7")
    call ExecuteFunc("UnLockOrder8")
 
 
endfunction

function StartAbilityCD takes integer pAbility, real cd returns nothing
    set Memory[pReserverdIntArg1/4] = cleanInt(realToIndex(cd))
    call CallThisCallWith2Args(pStartAbilityCD,pAbility, pReserverdIntArg1)
endfunction


function SetHPCustomHPBarUnit takes integer PlayerID, integer UnitID, integer Color, real ScaleX, real ScaleY returns nothing
    if pSetHPCustomHPBarUnit == 0 then
        set pSetHPCustomHPBarUnit = GetModuleProcAddress(EXTRADLLNAME, "SetHPCustomHPBarUnit" )
    endif
 
    if pSetHPCustomHPBarUnit != 0 then
        call CallStdcallWith5Args(pSetHPCustomHPBarUnit,PlayerID , UnitID, Color, realToIndex(cleanReal(ScaleX)), realToIndex(cleanReal(ScaleY)))
    endif

endfunction

function SetHPBarColorForPlayer takes   integer PlayerID, integer HeroColor, integer UnitColor, integer TowerColor returns nothing
 
    if pSetHPBarColorForPlayer == 0 then
        set pSetHPBarColorForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetHPBarColorForPlayer" )
    endif
    if pSetHPBarColorForPlayer != 0 then
        call CallStdcallWith4Args(pSetHPBarColorForPlayer, PlayerID,HeroColor,UnitColor,TowerColor)
    endif
endfunction

 
function SetMPBarXScaleForPlayer takes   integer PlayerID, real HeroXscale, real UnitXscale, real TowerXscale returns nothing
 
    if pSetMPBarXScaleForPlayer == 0 then
        set pSetMPBarXScaleForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetMPBarXScaleForPlayer" )
    endif
    if pSetMPBarXScaleForPlayer != 0 then
        call CallStdcallWith4Args(pSetMPBarXScaleForPlayer, PlayerID, realToIndex(cleanReal(HeroXscale)),realToIndex(cleanReal(UnitXscale)),realToIndex(cleanReal(TowerXscale)))
    endif
endfunction


function SetMPBarYScaleForPlayer takes  integer PlayerID, real HeroYscale, real UnitYscale, real TowerYscale returns nothing
 
    if pSetMPBarYScaleForPlayer == 0 then
        set pSetMPBarYScaleForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetMPBarYScaleForPlayer" )
    endif
    if pSetMPBarYScaleForPlayer != 0 then
        call CallStdcallWith4Args(pSetMPBarYScaleForPlayer, PlayerID, realToIndex(cleanReal(HeroYscale)),realToIndex(cleanReal(UnitYscale)),realToIndex(cleanReal(TowerYscale)))
    endif
endfunction

function SetMPBarYOffsetForPlayer takes  integer PlayerID, real HeroYscale, real UnitYscale, real TowerYscale returns nothing
 
    if pSetMPBarYOffsetForPlayer == 0 then
        set pSetMPBarYOffsetForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetMPBarYOffsetForPlayer" )
    endif
    if pSetMPBarYOffsetForPlayer != 0 then
        call CallStdcallWith4Args(pSetMPBarYOffsetForPlayer, PlayerID, realToIndex(cleanReal(HeroYscale)),realToIndex(cleanReal(UnitYscale)),realToIndex(cleanReal(TowerYscale)))
    endif
endfunction


function SetHPBarXScaleForPlayer takes   integer PlayerID, real HeroXscale, real UnitXscale, real TowerXscale returns nothing
 
    if pSetHPBarXScaleForPlayer == 0 then
        set pSetHPBarXScaleForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetHPBarXScaleForPlayer" )
    endif
    if pSetHPBarXScaleForPlayer != 0 then
        call CallStdcallWith4Args(pSetHPBarXScaleForPlayer, PlayerID, realToIndex(cleanReal(HeroXscale)),realToIndex(cleanReal(UnitXscale)),realToIndex(cleanReal(TowerXscale)))
    endif
endfunction


function SetHPBarYScaleForPlayer takes  integer PlayerID, real HeroYscale, real UnitYscale, real TowerYscale returns nothing
 
    if pSetHPBarYScaleForPlayer == 0 then
        set pSetHPBarYScaleForPlayer = GetModuleProcAddress(EXTRADLLNAME, "SetHPBarYScaleForPlayer" )
    endif
    if pSetHPBarYScaleForPlayer != 0 then
        call CallStdcallWith4Args(pSetHPBarYScaleForPlayer, PlayerID, realToIndex(cleanReal(HeroYscale)),realToIndex(cleanReal(UnitYscale)),realToIndex(cleanReal(TowerYscale)))
    endif
endfunction




function UnitCanUseInventoryModify takes unit u, integer mod returns nothing
    local integer h=ConvertHandle(u)
    local integer a=Memory[(h+0x1F8)/4]
    if a>0 then
        set a=a/4+0x3C/4
        set Memory[a]=Memory[a]+mod
    endif
endfunction

function GetUnitAttackDamage takes unit u returns real
    local integer k=GetUnitDamageDicesCount(u)
    local integer spread=GetRandomInt(k,k*GetUnitDamageDicesSideCount(u))
    return I2R(GetUnitBaseDamage(u)+GetUnitGreenBonusDamage(u)+spread)
endfunction

function SetUnitCurrentMSper32 takes integer convertedHandle, real r returns nothing
    local integer a=GetUnitAddressFloatsRelated(convertedHandle,0xA0)
    local integer b=Memory[a/4+0x28/4]
    if b>0 then
        set Memory[b/4+0x64/4]=SetRealIntoMemory(GetRealFromMemory(Memory[b/4+0x64/4])+r)
    endif
endfunction

function SetUnitCurrentMSper32Address takes integer convertedHandle, integer address, real r returns nothing
    set Memory[address/4]=SetRealIntoMemory(GetRealFromMemory(Memory[address/4])+r)
endfunction

function GetUnitCurrentMSper32Address takes integer convertedHandle returns integer
    local integer a=GetUnitAddressFloatsRelated(convertedHandle,0xA0)
    local integer b=Memory[a/4+0x28/4]
    if b>0 then
        return b+0x64
    endif
    return 0
endfunction

function GetUnitCurrentMSper32 takes integer convertedHandle returns real
    local integer a=GetUnitAddressFloatsRelated(convertedHandle,0xA0)
    local integer b=Memory[a/4+0x28/4]
//    call echo(Int2Hex(a))
    if b>0 then
        return GetRealFromMemory(Memory[b/4+0x64/4])
    endif
    return 0.
endfunction

//only used for Dagger, shouldn't be used for anything else without testing
function GetSpellTargetYReal takes nothing returns real
    if GameVersion==0x26a then
        return cleanReal(indexToReal(ReadEBP_offset(0x76c)))
    elseif GameVersion==0x27a then
        return cleanReal(indexToReal(ReadEBP_offset(0x800)))
    endif
    return 0.
endfunction

function GetSpellTargetXReal takes nothing returns real
    if GameVersion==0x26a then
        return cleanReal(indexToReal(ReadEBP_offset(0x770)))
    elseif GameVersion==0x27a then
        return cleanReal(indexToReal(ReadEBP_offset(0x7FC)))
    endif
    return 0.
endfunction


function GetUnitIllusionModifier takes unit u, integer modifiertype returns real
    local integer cid=ConvertHandle(u)
    local integer buffid
    if cid < 1 then
        return 1.
    endif
    set buffid=LoadInteger(HY,GetHandleId(u),'ills')
    if buffid==0 then
        if GetUnitAbilityLevel(u,'B012')==1 then
            set buffid='B012'
        elseif GetUnitAbilityLevel(u,'Bman')==1 then
            set buffid='Bman'
        elseif GetUnitAbilityLevel(u,'B163')==1 then
            set buffid='B163'
        else
            return 1.
        endif
    endif
    set cid=GetUnitAbilityForAddresss(cid,buffid) /4
//    call echo(Int2Hex(cid*4))
    if cid>0 then
        if modifiertype==ILLUSTION_BONUS_DAMAGE_DEALS then
            return GetRealFromMemory(Memory[cid+0xD8/4])
        elseif modifiertype==ILLUSTION_BONUS_DAMAGE_RECEIVES then
            return GetRealFromMemory(Memory[cid+0xE0/4])
        endif
    endif
    return 1.
endfunction

function ModifyUnitsPassiveDisabledCounter takes unit u, integer mod returns nothing
    local integer cid=ConvertHandle(u)
    if cid<=0 then
        return
    endif
    set cid=(cid+0x1B8)/4
    if mod>0 or Memory[cid] <= mod then
        set Memory[cid]=Memory[cid]+mod
//        call echo(I2S(Memory[cid]))
    endif
endfunction






function NullifyCurrentAttack takes unit u returns string
    local integer cid=(ConvertHandle(u)+0x1E8)/4
    if cid < 0x1E8 then
        return "cannot attack"
    endif
    if Memory[cid]/4!=0 then
        set cid=Memory[cid]/4
        if Memory[cid+0x1F4/4]!=0 then
            set Memory[cid+0x1F4/4]=0
            return "nulled"
        else
            return "already empty"
        endif
    endif
    return "no attack has been found"
endfunction

function AddExtraAttack takes unit u returns boolean
    local integer cid=(ConvertHandle(u)+0x1E8)/4
    local real attackdelay
    if cid < 0x1E8 then
        return false
    endif
    if Memory[cid]/4!=0 then
        set cid=Memory[cid]/4
        if Memory[cid+0x1E4/4]!=0 then
            set cid=Memory[cid+0x1E4/4]/4
            set attackdelay=cleanReal(indexToReal(Memory[cid + 2]))
            if attackdelay > 0 then
                set Memory[cid + 1] = cleanInt(realToIndex(GetUnitNextAttackTimestamp(u)-attackdelay))
                return true
            endif
        endif
    endif
    return false
endfunction




function SetAbilityHotkeyParam takes integer id, integer off, integer newVal returns boolean
    local integer k=(GetAbilityUIDefAddr(id)+off)/4
    if k < off then
        return false
    endif
    if Memory[k]>0 then
        set Memory[Memory[k]/4]=newVal
        return true
    endif
    return false
endfunction

function GetAbilityHotkeyParam takes integer id, integer off returns integer
    local integer k=(GetAbilityUIDefAddr(id)+off)/4
    if k < off then
        return 0
    endif
    if Memory[k]>0 then
        return Memory[Memory[k]/4]
    endif
    return 0
endfunction

function SetAbilityIntegerParam takes integer id, integer off, integer newVal returns boolean
    local integer k=(GetAbilityUIDefAddr(id)+off)/4
    if k < off then
        return false
    endif
    set Memory[k]=newVal
    return true
endfunction

function GetAbilityIntegerParam takes integer id, integer off returns integer
    local integer k=(GetAbilityUIDefAddr(id)+off)/4
 
    if k > off then
        return Memory[k]
    endif
    return 0
endfunction

function SetAbilityRealParam takes integer id, integer off, real newVal returns boolean
    local integer k=(GetAbilityUIDefAddr(id)+off)/4
    if k < off then
        return false
    endif
    set Memory[k]=cleanInt(realToIndex(newVal))
    return true
endfunction

function GetAbilityRealParam takes integer id, integer off returns real
    local integer k=(GetAbilityUIDefAddr(id)+off)/4
    if k > off then
        return cleanReal(indexToReal(Memory[k]))
    endif
    return 0.
endfunction

function SetAbilityBoolParam takes integer id, integer off, boolean newVal returns boolean
    local integer k=(GetAbilityUIDefAddr(id)+off)/4
    if k < off then
        return false
    endif
    if newVal then
        set Memory[k]=1
    else
        set Memory[k]=0
    endif
    return true
endfunction

function GetAbilityBoolParam takes integer id, integer off returns boolean
    local integer k=(GetAbilityUIDefAddr(id)+off)/4
    if k > off then
        return Memory[k] > 0
    endif
    return false
endfunction



function SetAbilityResearchHotkeyId takes integer id, integer newVal returns boolean
    return SetAbilityHotkeyParam(id,0x98, newVal)
endfunction

function SetAbilityUnHotkeyId takes integer id, integer newVal returns boolean
    return SetAbilityHotkeyParam(id,0x8C, newVal)
endfunction

function SetAbilityHotkeyId takes integer id, integer newVal returns boolean
    return SetAbilityHotkeyParam(id,0x80, newVal)
endfunction

function SetAbilityHotkeyCommon takes integer id, integer newVal returns boolean
    call SetAbilityHotkeyId(id,newVal)
    call SetAbilityUnHotkeyId(id,newVal)
    return SetAbilityResearchHotkeyId(id,newVal)
endfunction

function SetAbilitySpellDetails takes integer id, integer det returns boolean
    return SetAbilityIntegerParam(id,0x70, det)
endfunction

function SetAbilityMissileSpeed takes integer id, real speed returns boolean
    return SetAbilityRealParam(id,0x64, speed)
endfunction

function SetAbilityResearchButtonY takes integer id, integer newY returns boolean
    return SetAbilityIntegerParam(id,0x60, newY)
endfunction

function SetAbilityResearchButtonX takes integer id, integer newX returns boolean
    return SetAbilityIntegerParam(id,0x5C, newX)
endfunction

function SetAbilityUnButtonY takes integer id, integer newY returns boolean
    return SetAbilityIntegerParam(id,0x58, newY)
endfunction

function SetAbilityUnButtonX takes integer id, integer newX returns boolean
    return SetAbilityIntegerParam(id,0x54, newX)
endfunction

function SetAbilityButtonY takes integer id, integer newY returns boolean
    return SetAbilityIntegerParam(id,0x50, newY)
endfunction

function SetAbilityButtonX takes integer id, integer newX returns boolean
    return SetAbilityIntegerParam(id,0x4C, newX)
endfunction

function SetAbilityMissileHoming takes integer id, boolean homing returns boolean
    return SetAbilityBoolParam(id,0x6C,homing)
endfunction

function SetAbilityMissileArc takes integer id, real arc returns boolean
    return SetAbilityRealParam(id,0x68, arc)
endfunction


function GetAbilityMissileSpeed takes integer id returns real
    return GetAbilityRealParam(id,0x64)
endfunction

function GetAbilityMissileArc takes integer id returns real
    return GetAbilityRealParam(id,0x68)
endfunction

function GetAbilityResearchHotkeyId takes integer id returns integer
    return GetAbilityHotkeyParam(id,0x98)
endfunction

function GetAbilityUnHotkeyId takes integer id returns integer
    return GetAbilityHotkeyParam(id,0x8C)
endfunction

function GetAbilityHotkeyId takes integer id returns integer
    return GetAbilityHotkeyParam(id,0x80)
endfunction

function GetAbilitySpellDetails takes integer id returns integer
    return GetAbilityIntegerParam(id,0x70)
endfunction

function GetAbilityResearchButtonY takes integer id returns integer
    return GetAbilityIntegerParam(id,0x60)
endfunction

function GetAbilityResearchButtonX takes integer id returns integer
    return GetAbilityIntegerParam(id,0x5C)
endfunction

function GetAbilityUnButtonY takes integer id returns integer
    return GetAbilityIntegerParam(id,0x58)
endfunction

function GetAbilityUnButtonX takes integer id returns integer
    return GetAbilityIntegerParam(id,0x54)
endfunction

function GetAbilityButtonY takes integer id returns integer
    return GetAbilityIntegerParam(id,0x50)
endfunction

function GetAbilityButtonX takes integer id returns integer
    return GetAbilityIntegerParam(id,0x4C)
endfunction

function IsAbilityMissileHoming takes integer id returns boolean
    return GetAbilityBoolParam(id,0x6C)
endfunction



function GetAbilityStringParam takes integer id, integer off returns string
    local integer k=GetAbilityUIDefAddr(id)
    if k < 1 then
        return ""
    endif
//    call echo(Int2Hex(k))
    set k=(k+off)/4
    if Memory[k]>0 then
        return ConvertNullTerminatedStringToString(Memory[k])
    endif
    return ""
endfunction

function SetAbilityStringParam takes integer id, integer off, string newVal returns boolean
    local integer k=GetAbilityUIDefAddr(id)
    if k < 1 then
        return false
    endif
//    call echo(Int2Hex(k))
    set k=(k+off)
//    if Memory[k]>0 then
        //if Memory[Memory[k]]>0 then
            call WriteNullTerminatedString(newVal,k)
            return true
        //endif
//    endif
    return false
endfunction

function GetAbilityStringParam2 takes integer id, integer off, integer lvl returns string
    local integer k=GetAbilityUIDefAddr(id)
    if k < 1 then
        return null
    endif
//    call echo(Int2Hex(k))
    set k=(k+off)/4
    if Memory[k]+lvl-1>0 then
        //if Memory[Memory[k]/4]>0 then
//            call echo(Int2Hex(Memory[k]+(lvl-1)*4))
            return ConvertNullTerminatedStringToString(Memory[(Memory[k]+(lvl-1)*4)/4])
        //endif
    endif
    return null
endfunction

function SetAbilityStringParam2 takes integer id, integer off, string newVal, integer lvl returns boolean
    local integer k=GetAbilityUIDefAddr(id)
    if k < 1 then
        return false
    endif
//    call echo(Int2Hex(k))
    set k=(k+off)/4
    if Memory[k]>0 then
        //if Memory[Memory[k]/4]>0 then
            call WriteNullTerminatedString(newVal,Memory[k+lvl-1])
            return true
        //endif
    endif
    return false
endfunction

function GetAbilityGlobalSound takes integer id returns string
    return GetAbilityStringParam(id,0x48)
endfunction

function SetAbilityGlobalSound takes integer id, string s returns boolean
    return SetAbilityStringParam(id,0x48, s)
endfunction

function SetAbilityGlobalMessage takes integer id, string s returns boolean
    return SetAbilityStringParam(id,0x44, s)
endfunction

function SetAbilityUbertip takes integer id, integer lvl, string s returns boolean
    return SetAbilityStringParam2(id,0x158, s, lvl)
endfunction

function GetAbilityUbertip takes integer id, integer lvl returns string
    return GetAbilityStringParam2(id,0x158, lvl)
endfunction

function GetUnitMissileSpeed takes integer id, integer index returns real
    local integer k=GetUnitUIDefAddr(id)/4
    if k==0 then
        return 0.
    endif
    set k=Memory[k+0x60/4]
    if k==0 then
        return 99999.
    endif
    return GetRealFromMemory(Memory[k/4+index])
endfunction

function SetUnitMissileArt takes unit u, string path returns nothing
    local integer a=GetUnitUIDefAddr(GetUnitTypeId(u))/4
    if a>0 then
        set a=Memory[a+0x40/4]
        set Memory[a/4]=GetStringAddress(path)
    endif
endfunction

function GetPingAddress takes nothing returns integer
    return Memory[(Memory[pGameClass2] + 0x254)/4]
endfunction


function GetPingX takes integer id returns real
    return cleanReal(indexToReal(  Memory[ (Memory[(GetPingAddress( ) + 0xb0)/4] + 12*id)/4]))
endfunction


function GetPingY takes integer id returns real
    return cleanReal( indexToReal(  Memory[ (Memory[(GetPingAddress( ) + 0xb0)/4] + 12*id + 4)/4] ))
endfunction

function GetPingZ takes integer id returns real
    return cleanReal( indexToReal(  Memory[ (Memory[(GetPingAddress( ) + 0xb0)/4] + 12*id + 8)/4] ))
endfunction


function SetPingX takes integer id, real x returns nothing
    set Memory[ (Memory[(GetPingAddress( ) + 0xb0)/4] + 12*id)/4] = cleanInt( realToIndex(x) )
endfunction


function SetPingY takes integer id, real y returns nothing
    set Memory[ ( Memory[ (GetPingAddress( ) + 0xb0 )/4 ] + 12*id + 4 )/4 ] = cleanInt( realToIndex(y) )
endfunction


function SetPingZ takes integer id, real z returns nothing
    set Memory[ ( Memory[ (GetPingAddress( ) + 0xb0 )/4 ] + 12*id + 8 )/4 ] = cleanInt( realToIndex(z) )
endfunction

function GetPingCount takes nothing returns integer
    return Memory[(GetPingAddress( ) + 0xa4)/4]
endfunction

function SetPingCount takes integer i returns nothing
    set Memory[(GetPingAddress( ) + 0xa4)/4] = i
endfunction

function GetNextPingFillID takes nothing returns integer
    return Memory[(GetPingAddress( ) + 0xa0)/4]
endfunction

function SetNextPingFillID takes integer i returns nothing
    set Memory[(GetPingAddress( ) + 0xa0)/4] = i
endfunction

function GetNextPingID takes nothing returns integer
    return Memory[(GetPingAddress( ) + 0x98)/4]
endfunction

function SetNextPingID takes integer i returns nothing
    set Memory[(GetPingAddress( ) + 0x98)/4] = i
endfunction


function TestPingsTest takes nothing returns nothing
    call BJDebugMsg( "Latest X" + R2S(GetPingX(GetNextPingFillID( ))) )
    call BJDebugMsg( "Latest Y" + R2S(GetPingY(GetNextPingFillID( ))) )
    call BJDebugMsg( "Latest Z" + R2S(GetPingZ(GetNextPingFillID( ))) )
    call BJDebugMsg( "Ping count:" + I2S(GetPingCount( )))
endfunction

function GetLightningAddressByID takes integer id returns integer
    if Memory[pLightEnv+0x34/4] != 0 then
        return Memory[(Memory[pLightEnv+0x34/4] + 8)/4] +  (id - 1) * 4
    endif
    return 0
endfunction


function GetGameAreaSizeLimit takes nothing returns real
    return cleanReal(indexToReal(Memory[(Memory[pGameClass3] + 0xF8)/4]))
endfunction

function SetGameAreaSizeLimit takes real r returns nothing
    set Memory[(Memory[pGameClass3] + 0xF8)/4] = cleanInt(realToIndex(r))
endfunction

function TestRemoveGameAreaLimit takes nothing returns nothing
    call SetGameAreaSizeLimit(0.0)
endfunction

function SetWidescreenFixState takes boolean WidescreenState returns nothing
    local integer nOffset1

    if pSetWidescreenFixState == 0 then
        set pSetWidescreenFixState = GetModuleProcAddress(EXTRADLLNAME, "SetWidescreenFixState" )
    endif
    if pSetWidescreenFixState != 0 then
        call CallStdcallWith1Args(pSetWidescreenFixState,B2I(WidescreenState))
    endif
endfunction

function SetCustomFovFix takes real CustomFOV_X returns nothing
    local integer nOffset1

    if pSetCustomFovFix == 0 then
        set pSetCustomFovFix = GetModuleProcAddress(EXTRADLLNAME, "SetCustomFovFix" )
    endif
    if pSetCustomFovFix != 0 then
        call CallStdcallWith1Args(pSetCustomFovFix,cleanInt(realToIndex(CustomFOV_X)))
    endif
endfunction

function TestWideScreen takes nothing returns nothing
    call SetWidescreenFixState(not WidescreenState[GetPlayerId(GetTriggerPlayer())])
    set WidescreenState[GetPlayerId(GetTriggerPlayer())]=not WidescreenState[GetPlayerId(GetTriggerPlayer())]
endfunction

function GetAgileTimersData takes nothing returns integer
    local integer pOffset = Memory[pTimerAddr]
    if pOffset > 0 then
        set pOffset = Memory[(pOffset+0x40)/4]
        if pOffset > 0 then
            return pOffset
        endif
    endif
    return 0
endfunction

function GetTimerList takes nothing returns integer
    local integer pOffset = GetAgileTimersData( )
    if pOffset > 0 then
        set pOffset = ReadRealMemory(pOffset + 0x8)
        if pOffset > 0 then
            return pOffset + 4
        endif
    endif
    return 0
endfunction

function GetTimerCount takes nothing returns integer
    local integer pOffset = GetAgileTimersData( )
    if pOffset > 0 then
        set pOffset = ReadRealMemory(pOffset + 0x20)
        if pOffset > 0 then
            return pOffset - 1
        endif
    endif
    return 0
endfunction


function TestPrintAllTimers takes nothing returns nothing
    local integer TimerList = GetTimerList( )
    local integer TimersCount = GetTimerCount( )
    local integer CurrentTimerID = 0
    local integer CurrentTimer = 0
 
    call BJDebugMsg("First timer addr:" + Int2Hex(ReadRealMemory(TimerList)))
    call BJDebugMsg("Agile addr: " + Int2Hex(GetAgileTimersData( )))
    call BJDebugMsg("Timers count:" + I2S(GetTimerCount()))
    loop
        set TimersCount = GetTimerCount( )
        call BJDebugMsg("Timer id:" + I2S(CurrentTimerID) )
        set CurrentTimer = ReadRealMemory(TimerList + CurrentTimerID * 4)
        call BJDebugMsg("Timer addr: " + Int2Hex(CurrentTimer))
        call BJDebugMsg("Timer 1/2 values: " + R2S(cleanReal(indexToReal(ReadRealMemory(CurrentTimer + 0x4)))) + " / " +  R2S(cleanReal(indexToReal(ReadRealMemory(CurrentTimer + 0x8)))))
        if (cleanReal(indexToReal(ReadRealMemory(CurrentTimer + 0x8))) == 0.4 or cleanReal(indexToReal(ReadRealMemory(CurrentTimer + 0x8))) == 0.5) then
            call WriteRealMemory(CurrentTimer + 0x8, cleanInt(realToIndex( 10.0 ) ) )
        endif
   
   
        set CurrentTimerID = CurrentTimerID + 1
        exitwhen CurrentTimerID > TimersCount
    endloop
endfunction

function GetFogStateAddr takes nothing returns integer
    return Memory[pCGameState + 3]
endfunction



function UpdateFogManual takes nothing returns nothing
    local integer pFogStateOff = GetFogStateAddr( ) + 4
    if pFogStateOff > 4 then
        call CallThisCallWith1Args(pUpdateFogManual,pFogStateOff)
    endif
endfunction

function BlockRealFogUpdate takes boolean block returns nothing
    local integer oldprotection1
    if FogUpdateBlocked then
        set oldprotection1 = ChangeOffsetProtection(pFogUpdateBlockAddr*4,8,0x40)
        if block then
            call AddNewOffsetToRestore(pFogUpdateBlockAddr*4,ReadRealMemory(pFogUpdateBlockAddr*4))
            call AddNewOffsetToRestore((pFogUpdateBlockAddr+1)*4,ReadRealMemory((pFogUpdateBlockAddr+1)*4))
            set Memory[pFogUpdateBlockAddr] = pFogUpdateBlockAddrNew1
            set Memory[pFogUpdateBlockAddr + 1] = pFogUpdateBlockAddrNew2
        else
            set Memory[pFogUpdateBlockAddr] = pFogUpdateBlockAddrOld1
            set Memory[pFogUpdateBlockAddr + 1] = pFogUpdateBlockAddrOld2
        endif
        call ChangeOffsetProtection(pFogUpdateBlockAddr*4,8,oldprotection1)
    else
        set pFogUpdateBlockAddrOld1 = Memory[pFogUpdateBlockAddr]
        set pFogUpdateBlockAddrOld2 = Memory[pFogUpdateBlockAddr + 1]
        set FogUpdateBlocked = true
        call BlockRealFogUpdate( block )
    endif
endfunction

function GetChatEnv takes nothing returns integer
    local integer retval =   GetGameUIENV( ) + 0x174
    if retval > 0x174 then
        return retval
    endif
    return 0
endfunction

function GetChatMessagesList takes nothing returns integer
    return ReadRealMemory(GetChatEnv( )  + 0x18)
endfunction

function SetChatEmptyMessage takes nothing returns nothing
    if GetChatEnv( ) > 0 then
        call WriteRealMemory( GetChatEnv( ) + 4, 1 )
    endif
endfunction

function SetChatMessageXbyID takes integer MsgID, real x returns nothing
    local integer pChatMessageOffset = GetChatMessagesList( ) + MsgID * 12
    call WriteRealMemory(pChatMessageOffset + 0, cleanInt(realToIndex(x)))
endfunction

function SetChatMessageYbyID takes integer MsgID, real x returns nothing
    local integer pChatMessageOffset = GetChatMessagesList( ) + MsgID * 12
    call WriteRealMemory(pChatMessageOffset + 4, cleanInt(realToIndex(x)))
endfunction

function GetChatMessageAddressByID takes integer MsgID returns integer
    local integer pChatMessageOffset = GetChatMessagesList( ) + MsgID * 12
    return ReadRealMemory(pChatMessageOffset + 8)
endfunction

function SearchStringValueAddress takes string str returns integer
    local integer retaddr = CallThisCallWith2Args(pSearchStringValue,pSearchStringAddr1,GetStringAddress(str))
    if retaddr == 0 or ReadRealMemory( retaddr + 0x1C ) == 0 then
        set retaddr = CallThisCallWith2Args(pSearchStringValue,pSearchStringAddr2,GetStringAddress(str))
    endif
    if retaddr == 0 or ReadRealMemory( retaddr + 0x1C ) == 0 then
        return 0
    endif
    return ReadRealMemory( retaddr + 0x1C )
endfunction

function SearchStringValue takes string str returns string
    return ConvertNullTerminatedStringToString(SearchStringValueAddress(str))
endfunction

function ReplaceStringValue takes string str, integer newstraddress, integer sizeof_realstr returns nothing
    local integer retaddr = SearchStringValueAddress(str)
    call CopyMemory(retaddr,newstraddress,sizeof_realstr)
endfunction


function ReplaceStringValueUNSAFE takes string str, integer newstraddress returns nothing
    local integer retaddr = CallThisCallWith2Args(pSearchStringValue,pSearchStringAddr1,GetStringAddress(str))
    if retaddr == 0 or ReadRealMemory( retaddr + 0x1C ) == 0 then
        set retaddr = CallThisCallWith2Args(pSearchStringValue,pSearchStringAddr2,GetStringAddress(str))
    endif
    if retaddr == 0 or ReadRealMemory( retaddr + 0x1C ) == 0 then
        return
    endif
    call AddNewOffsetToRestore(retaddr + 0x1C,ReadRealMemory(retaddr + 0x1C))
    call WriteRealMemory(retaddr + 0x1C, newstraddress)
endfunction

function SimulateAttackInstance takes unit u, unit target returns nothing
    local integer a=GetUnitAbility(u,'Aatk')
    local integer b
    local integer c
    if a>0 then
        set b=ConvertHandle(target)
        //call BJDebugMsg("attack starting")
        call CallThisCallWith7Args(pSimulateAttackInstance,a,b,0,0,1,1,1)
        //attack ability
        //target
        //unknown, must be zero in order to attack to happen
        //1 if should use orb-modifier (any)
        //unused
        //unknown
        //unknown
        //0 1 0 0 0 - autocast hotkey
        //0 0 1 1 1 - default attack
        //0 0 1 0 0 - attack with orb-effect (2nd index?)
   
    endif
endfunction

function GetRealGameTime takes nothing returns integer
    return ReadRealMemory(pGameTime)
endfunction


function GetOrderPlayerId takes unit u returns integer
    local integer pUhandle=0
    if u == null then
        return 0xF
    endif
    set pUhandle = ConvertHandle(u)
    if pUhandle == 0 then
        return 0xF
    endif
    if (ReadRealMemory(pUhandle + 0x1a8) <= 0 or ReadRealMemory(pUhandle + 0x1aC) <= 0) then
        return 0xF
    endif
    return ReadRealMemory(GetSomeAddressForAbility(ReadRealMemory(pUhandle + 0x1a8),ReadRealMemory(pUhandle + 0x1aC))+0x28)
endfunction

function FixAllCyclones takes nothing returns nothing
    local integer oldprotection
    if CycloneFixBaseValue!=0 then
        return
    endif
    set oldprotection = ChangeOffsetProtection((pCycloneFixCondition),4,0x40)
    set CycloneFixBaseValue=ReadRealMemory(pCycloneFixCondition)
    if GameVersion == 0x26a then
        call WriteRealMemory(pCycloneFixCondition,CycloneFixCondition026a)
    elseif GameVersion == 0x27a then
        call WriteRealMemory(pCycloneFixCondition,CycloneFixCondition027a)
    endif
    call ChangeOffsetProtection((pCycloneFixCondition),4,oldprotection)
endfunction

function DeFixAllCyclones takes nothing returns nothing
    local integer oldprotection
    if CycloneFixBaseValue==0 then
        return
    endif
    set oldprotection = ChangeOffsetProtection((pCycloneFixCondition),4,0x40)
    call WriteRealMemory(pCycloneFixCondition,CycloneFixBaseValue)
    set CycloneFixBaseValue=0
    call ChangeOffsetProtection((pCycloneFixCondition),4,oldprotection)
endfunction

function ToggleForcedSubSelection takes boolean b returns nothing
    if pToggleForcedSubSelection == 0 then
        set pToggleForcedSubSelection = GetModuleProcAddress(EXTRADLLNAME, "ToggleForcedSubSelection")
    endif
    if pToggleForcedSubSelection != 0 then
        call CallStdcallWith1Args(pToggleForcedSubSelection,B2I(b))
    endif
endfunction


function ToggleBlockKeyAndMouseEmulation takes boolean b returns nothing
    if pToggleBlockKeyAndMouseEmulation == 0 then
        set pToggleBlockKeyAndMouseEmulation = GetModuleProcAddress(EXTRADLLNAME, "ToggleBlockKeyAndMouseEmulation")
    endif
    if pToggleBlockKeyAndMouseEmulation != 0 then
        call CallStdcallWith1Args(pToggleBlockKeyAndMouseEmulation,B2I(b))
    endif
endfunction

function ToggleClickHelper takes boolean b returns nothing
    if pToggleClickHelper == 0 then
        set pToggleClickHelper = GetModuleProcAddress(EXTRADLLNAME, "ToggleClickHelper")
    endif
    if pToggleClickHelper != 0 then
        call CallStdcallWith1Args(pToggleClickHelper,B2I(b))
    endif
endfunction

function UpdateUnitMoveSpeedTo takes unit u, real ms returns nothing
    local integer a=GetHandleId(u)
    if a>0 then
        set a=ConvertHandle(u)
        if a>0 then
            set a=GetUnitAddressFloatsRelated(a,0xA0)
            if a>0 then
                set a=ReadRealMemory(a+0x28)
                set a=a-0x24
                if a>0 then
                    set ms=ms/32
                    set Memory[pReserverdIntArg1/4] = cleanInt(realToIndex(ms))
                    call CallThisCallWith2Args(pUpdateUnitsSpeedCurrent,a, pReserverdIntArg1)
                endif
            endif
        endif
    endif
endfunction

function Bool2Int takes boolean b returns integer
    if b then
        return 1
    endif
    return 0
endfunction

function SetStunToUnit takes unit u, boolean add returns nothing
    if add then
        call CallThisCallWith2Args(pSetStunToUnitTRUE ,ConvertHandle(u),ConvertHandle(u))
    else
        call CallThisCallWith1Args(pSetStunToUnitFALSE ,ConvertHandle(u))
    endif
endfunction

function CommonSilenceApply takes unit u, boolean app returns nothing
    local integer a=GetHandleId(u)
    if a>0 then
        set a=ConvertHandle(u)
        call CallThisCallWith2Args(pCommonSilence,a,Bool2Int(app))
    endif
endfunction

function DisableAllUnitsAbilities takes unit u, boolean disable returns nothing
    //visually equal to pause: all skills are hidden and silenced
    local integer a=GetHandleId(u)
    if a>0 then
        set a=ConvertHandle(u)
        call CallThisCallWith5Args(pPauseUnitDisabler,a,1,Bool2Int(disable),0,0)
    endif
endfunction

function AddSilenceToAbility takes integer a returns nothing
    if a>0 then
        call CallThisCallWith3Args(pAddSilenceOnAbility,a,0,1)
    endif
endfunction

function RemoveSilenceFromAbility takes integer a returns nothing
    if a>0 then
        call CallThisCallWith3Args(pRemoveSilenceFromAbility,a,0,1)
    endif
endfunction

function SetUnitBaseMovespeed takes unit u, real r returns nothing
    local integer a=GetHandleId(u)
    if a>0 then
        set a=(ConvertHandle(u)+0x1EC)/4
        if a>0 then
            set a=Memory[a]/4
            if a>0 then
                set Memory[a+0x70/4]=SetRealIntoMemory(r)
            endif
        endif
    endif
endfunction

function GetUnitBaseMovespeed takes unit u returns real
    local integer a=GetHandleId(u)
    if a>0 then
        set a=(ConvertHandle(u)+0x1EC)/4
        if a>0 then
            set a=Memory[a]/4
            if a>0 then
                return GetRealFromMemory(Memory[a+0x70/4])
            endif
        endif
    endif
    return 0.
endfunction

function ThrowTargetSpellTargetUnit takes unit who, integer id, widget target returns nothing
    local integer a=ConvertHandle(target)
    local integer x
    local integer y
    if a>0 and GetHandleId(who)>0 then
        set x=ReadRealMemory(a+0xC)
        set y=ReadRealMemory(a+0x10)
        if x>0 and y>0 then
            set a=ConvertHandle(who)
            if a<1 then
                return
            endif
            set a=GetUnitAbility(who,id)
            if a>0 then
                call WriteRealMemory(a+0xE4,x)//for any target (widget)
                call WriteRealMemory(a+0xE8,y)
                if not IsFlagBitSet(ReadRealMemory(a+0x20),0x10000) then
                    //0x19804 stands for "target", 0x1F020 stands for "target item",0x9800 stands for point target
                    call WriteRealMemory(a+0x20,ReadRealMemory(a+0x20)+0x10000)
                    if not IsFlagBitSet(ReadRealMemory(a+0x20),0x1) then
                        call WriteRealMemory(a+0x20,ReadRealMemory(a+0x20)+0x1)
                    endif
                endif
                set a=CallThisCallWith1Args(pCastAbility,a)
            endif
        endif
    endif
endfunction

function ThrowSpellXY takes unit who, integer id, real x, real y returns nothing
//fits for no-target spells as Was Stomp as well
    local integer a=ConvertHandle(who)
    if a>0 then
        set a=GetUnitAbility(who,id)
        if a>0 then
            call WriteRealMemory(a+0xF8,SetRealIntoMemory(x))
            call WriteRealMemory(a+0x100,SetRealIntoMemory(y))
            call WriteRealMemory(a+0x20,0x9800)
            set a=CallThisCallWith1Args(pCastAbility,a)
        endif
    endif
endfunction

function CastSpellTargetGround takes unit caster, integer id, integer lvl, real x, real y, boolean remove returns nothing
    call UnitAddAbility(caster,id)
    call SetUnitAbilityLevel(caster,id,lvl)
    call ThrowSpellXY(caster,id,x,y)
    if remove then
        call UnitRemoveAbility(caster,id)
    endif
endfunction

function ThrowTargetSpellTargetUnitSingle takes unit who, integer id, integer lvl, widget target, boolean remove returns nothing
// due to memory issues requires STDCAlls and ThisCAlls to use different memory allocation
// else spells which deals dmage immediately on cast will interference with damage-related functions and fuck whole thing up
// Chain lightnings stops as soon as ability removed so you may want it to stay
    call UnitAddAbility(who,id)
    if lvl>1 then
        call SetUnitAbilityLevel(who,id,lvl)
    endif
    call ThrowTargetSpellTargetUnit(who,id,target)
    if remove then
        call UnitRemoveAbility(who,id)
    endif
endfunction

function SelfCastSpell takes unit who, integer id, integer lvl returns nothing
// workaround when caster doesnt matter
    call UnitAddAbility(who,id)
    if lvl>1 then
        call SetUnitAbilityLevel(who,id,lvl)
    endif
    call ThrowTargetSpellTargetUnit(who,id,who)
    call UnitRemoveAbility(who,id)
endfunction

function IsAttackDisabled takes unit u returns boolean
    local integer a=GetHandleId(u)
    if a>0 then
        set a=ConvertHandle(u)
        if a>0 then
            set a=ReadRealMemory(a+0x1E8)
            if a>0 then
                return ReadRealMemory(a+0x40)>0
            endif
        endif
    endif
    return false
endfunction

// REMINDER: All this/fast/cdecl calls uses the same pReservedExecutableMemory2
// in case if one thread being interrupted by another
// (midwhile calling some func you deal damage to the unit, and you have ON_DAMAGE
// trigger which runs some function as well, trashing this memory) it will end up with fatal for sure.



function UnstuckWindwalkAbilities takes unit u, integer id returns nothing
    local integer a=GetUnitAbilityLevel(u,id)
    if a>0 then
        set a=GetUnitAbility(u,id)
        if a>0 then
            call WriteRealMemory(a+0x44,-100)
        endif
    endif
endfunction


function ApplyTerrainFilterDirectly takes string Path, integer addr_of_mem, integer addr_of_size, boolean IsTarga returns nothing
    if pApplyTerrainFilterDirectly == 0 then
        set pApplyTerrainFilterDirectly = GetModuleProcAddress(EXTRADLLNAME, "ApplyTerrainFilterDirectly")
    endif
    if pApplyTerrainFilterDirectly != 0 then
        call CallStdcallWith4Args(pApplyTerrainFilterDirectly,GetStringAddress(Path),addr_of_mem,addr_of_size,B2I(IsTarga))
    endif
endfunction


function LoadFileMemAddr takes string FileName returns integer
    if GameVersion == 0x27a then
        return CallFastCallWith4Args(pGetOrLoadFile,GetStringAddress(FileName),0,0,0)
    else
        return FUCKINGCallWith4Args(pGetOrLoadFile,GetStringAddress(FileName),0,0,0)
    endif
endfunction

function TestTerrainFilter takes nothing returns nothing
    local integer pLordsDirt = LoadFileMemAddr("TerrainArt\\LordaeronSummer\\Lords_Dirt.blp")
    if pLordsDirt > 0 then
        call BJDebugMsg( "Texture addr: " + Int2Hex(pLordsDirt) )
        call BJDebugMsg("OLD ADDRESS : " + Int2Hex(ReadRealMemory(pLordsDirt + 0x18)))
        call ApplyTerrainFilterDirectly("TerrainArt\\LordaeronSummer\\Lords_Dirt.blp",pLordsDirt + 0x18, pLordsDirt + 0x1C, false)
        call BJDebugMsg("NEW ADDRESS : " + Int2Hex(ReadRealMemory(pLordsDirt + 0x18)))
    endif
endfunction

function SetMainFuncWork takes boolean b returns nothing
    if pSetMainFuncWork == 0 then
        set pSetMainFuncWork = GetModuleProcAddress(EXTRADLLNAME, "SetMainFuncWork")
    endif
    if pSetMainFuncWork != 0 then
        call CallStdcallWith1Args(pSetMainFuncWork,B2I(b))
    endif
endfunction


function FixModelCollisionSphere takes string Path, real X, real Y, real Z, real Radius returns nothing
    if pFixModelCollisionSphere == 0 then
        set pFixModelCollisionSphere = GetModuleProcAddress(EXTRADLLNAME, "FixModelCollisionSphere")
    endif
    if pFixModelCollisionSphere != 0 then
        call CallStdcallWith5Args(pFixModelCollisionSphere,GetStringAddress(Path),cleanInt(realToIndex(X)),cleanInt(realToIndex(Y)),cleanInt(realToIndex(Z)),cleanInt(realToIndex(Radius)))
    endif
endfunction

function FixModelTexturePath takes string ModelPath, integer TextureID, string NewTexturePath returns nothing
    if pFixModelTexturePath == 0 then
        set pFixModelTexturePath = GetModuleProcAddress(EXTRADLLNAME, "FixModelTexturePath")
    endif
    if pFixModelTexturePath != 0 then
        call CallStdcallWith3Args(pFixModelTexturePath,GetStringAddress(ModelPath),TextureID,GetStringAddress(NewTexturePath))
    endif
endfunction


function PatchModel takes string ModelPath, string patchPath returns nothing
    if pPatchModel == 0 then
        set pPatchModel = GetModuleProcAddress(EXTRADLLNAME, "PatchModel")
    endif
    if pPatchModel != 0 then
        call CallStdcallWith2Args(pPatchModel,GetStringAddress(ModelPath),GetStringAddress(patchPath))
    endif
endfunction


function ChangeAnimationSpeed takes string ModelPath, string AnimationName, real SpeedUP returns nothing
    if pChangeAnimationSpeed == 0 then
        set pChangeAnimationSpeed = GetModuleProcAddress(EXTRADLLNAME, "ChangeAnimationSpeed")
    endif
    if pChangeAnimationSpeed != 0 then
        call CallStdcallWith3Args(pChangeAnimationSpeed,GetStringAddress(ModelPath),GetStringAddress(AnimationName), cleanInt(realToIndex(SpeedUP)))
    endif
endfunction

function SetSequenceValue takes string ModelPath, string AnimationName, integer Indx, real Value returns nothing
    if pSetSequenceValue == 0 then
        set pSetSequenceValue = GetModuleProcAddress(EXTRADLLNAME, "SetSequenceValue")
    endif
    if pSetSequenceValue != 0 then
        call CallStdcallWith4Args(pSetSequenceValue,GetStringAddress(ModelPath),GetStringAddress(AnimationName),Indx, cleanInt(realToIndex(Value)))
    endif
endfunction

function RedirectFile takes string OriginalFileName, string RedirectFileName returns nothing
    if pRedirectFile == 0 then
        set pRedirectFile = GetModuleProcAddress(EXTRADLLNAME, "RedirectFile")
    endif
    if pRedirectFile != 0 then
        call CallStdcallWith2Args(pRedirectFile,GetStringAddress(OriginalFileName),GetStringAddress(RedirectFileName))
    endif
endfunction

function IsStoreIntegerLocked takes nothing returns boolean
    return ReadRealMemory(StoreIntegerOffset) == 0x90C3C08B
endfunction


function LockStoreInteger takes nothing returns nothing
    local integer oldprotection = ChangeOffsetProtection( StoreIntegerOffset,4,0x40)
 
    if StoreIntegerLocked != IsStoreIntegerLocked( ) then
        call MaphackDetected( GetLocalPlayer( ), "StoreInteger hack detected!" )
    endif
 
    if StoreIntegerLocked == false then
        set StoreIntegerUnlocker = ReadRealMemory(StoreIntegerOffset)
        set StoreIntegerLocked = true
    endif
 
    call WriteRealMemory(StoreIntegerOffset, 0x90C3C08B)
    call ChangeOffsetProtection( StoreIntegerOffset,4, oldprotection)
endfunction

function UnLockStoreInteger takes nothing returns nothing
    local integer oldprotection = ChangeOffsetProtection( StoreIntegerOffset,4,0x40)
 
    if StoreIntegerLocked != IsStoreIntegerLocked( ) then
        call MaphackDetected( GetLocalPlayer( ), "StoreInteger hack detected#2!" )
    endif
 
    if StoreIntegerLocked then
        call WriteRealMemory(StoreIntegerOffset,StoreIntegerUnlocker)
        set StoreIntegerLocked = false
    endif
 
    call ChangeOffsetProtection( StoreIntegerOffset,4, oldprotection)
endfunction

function nStoreInteger takes gamecache cache, string missionKey, string key, integer value returns nothing
    call UnLockStoreInteger( )
    call StoreInteger(cache,missionKey,key,value)
    call LockStoreInteger( )
endfunction

function GetUnitVisibilityClass takes unit u returns integer
    local integer a=ConvertHandle(u)
    local integer res=0
    if a>0 then
        set res=ReadRealMemory(a+0x130)
        if res>0 then
            set res=GetSomeAddressForAbility(res,ReadRealMemory(a+0x134))
        endif
    endif
    return res
endfunction

function GetUnitDetectedClass takes unit u returns integer
    local integer a=ConvertHandle(u)
    local integer res=0
    if a>0 then
        set res=ReadRealMemory(a+0x13C)
        if res>0 then
            set res=GetSomeAddressForAbility(res,ReadRealMemory(a+0x140))
        endif
    endif
    return res
endfunction

function Player2Flag takes player p returns integer
    return R2I(Pow(2,GetPlayerId(p)))
endfunction

function IsUnitVisibleToPlayer takes unit u, player p returns boolean
    //true-sight like effect, unit can't get invisible
    local integer a=GetUnitVisibilityClass(u)
    if a>0 then
        return IsFlagBitSet(ReadRealMemory(a+0x24),Player2Flag(p))
    endif
    return false
endfunction

function IsUnitDetectedByPlayer takes unit u, player p returns boolean
    //shared vision-like effect, used for Faerie fire / Wand of evil eye
    //have no reveal effect by itself, used only as detector?
    local integer a=GetUnitDetectedClass(u)
    if a>0 then
        return IsFlagBitSet(ReadRealMemory(a+0x24),Player2Flag(p))
    endif
    return false
endfunction

function SetUnitVisibleByPlayer takes unit u, player p, integer c returns nothing
    local integer a=GetUnitVisibilityClass(u)
    if a>0 then
        call WriteRealMemory(a+0x2C+4*GetPlayerId(p),c)
        if c>0 and IsFlagBitSet(ReadRealMemory(a+0x24),Player2Flag(p))==false then
            call WriteRealMemory(a+0x24,ReadRealMemory(a+0x24)+Player2Flag(p))
        elseif c==0 and IsFlagBitSet(ReadRealMemory(a+0x24),Player2Flag(p)) then
            call WriteRealMemory(a+0x24,ReadRealMemory(a+0x24)-Player2Flag(p))
        endif
    endif
endfunction

function GetUnitVisibleByPlayerCount takes unit u, player p returns integer
    local integer a=GetUnitVisibilityClass(u)
    if a>0 then
        return ReadRealMemory(a+0x2C+4*GetPlayerId(p))
    endif
    return 0
endfunction

function RecountAnyDetectionForUnit takes unit u returns nothing
    local integer a=ConvertHandle(u)
    local integer sum=0
    local integer i=0
    if a>0 then
        set a=GetUnitDetectedClass(u)
        if a>0 then
            loop
                if ReadRealMemory(a+0x2C+4*i)>0 then
                    set sum=sum+R2I(Pow(2,i))
                endif
                set i=i+1
                exitwhen i>15
            endloop
            call WriteRealMemory(a+0x14C,sum)
            call WriteRealMemory(a+0x148,sum)
            set sum=0
            set i=0
        endif
        set a=GetUnitVisibilityClass(u)
        if a>0 then
            loop
                if ReadRealMemory(a+0x2C+4*i)>0 then
                    set sum=sum+R2I(Pow(2,i))
                endif
                set i=i+1
                exitwhen i>15
            endloop
            call WriteRealMemory(a+0x24,sum)
        endif
    endif
endfunction

function RemoveAnyDetectionFromUnit takes unit u returns nothing
    local integer a=ConvertHandle(u)
    if a>0 then
        call WriteRealMemory(a+0x148,0)
        call WriteRealMemory(a+0x14C,0)
        set a=GetUnitVisibilityClass(u)
        if a>0 then
            call WriteRealMemory(a+0x24,0)
        endif
    endif
endfunction

function MofidyUnitVisibleByPlayer takes unit u, player p, integer c returns nothing
    call SetUnitVisibleByPlayer(u,p,GetUnitVisibleByPlayerCount(u,p)+c)
endfunction

function SetUnitDetectedByPlayer takes unit u, player p, integer c returns nothing
    local integer a=GetUnitDetectedClass(u)
    if a>0 then
        call WriteRealMemory(a+0x2C+4*GetPlayerId(p),c)
        if c>0 and IsFlagBitSet(ReadRealMemory(a+0x24),Player2Flag(p))==false then
            call WriteRealMemory(a+0x24,ReadRealMemory(a+0x24)+Player2Flag(p))
        endif
    endif
endfunction

function GetUnitDetectedByPlayerCount takes unit u, player p returns integer
    local integer a=GetUnitDetectedClass(u)
    if a>0 then
        return ReadRealMemory(a+0x2C+4*GetPlayerId(p))
    endif
    return 0
endfunction

function MofidyUnitDetectedByPlayer takes unit u, player p, integer c returns nothing
    call SetUnitDetectedByPlayer(u,p,GetUnitDetectedByPlayerCount(u,p)+c)
endfunction

function SetUnitVisiblePartiallyByPlayer takes unit u, player p, boolean visible returns nothing
    //works a-la shared vision: unit remain "visible" but model won't be shown if unit is invisbile
    //unit can be autoattacked and visible on the minimap
    local integer a=ConvertHandle(u)
    if a>0 then
        if IsFlagBitSet(ReadRealMemory(a+0x148),Player2Flag(p))==false then
            if visible then
                call WriteRealMemory(a+0x148,ReadRealMemory(a+0x148)+Player2Flag(p))
            endif
        else
            if not visible then
                call WriteRealMemory(a+0x148,ReadRealMemory(a+0x148)-Player2Flag(p))
            endif
        endif
    endif
endfunction

function IsUnitVisiblePartiallyByPlayer takes unit u, player p returns boolean
    local integer a=ConvertHandle(u)
    if a>0 then
        return IsFlagBitSet(ReadRealMemory(a+0x148),Player2Flag(p))
    endif
    return false
endfunction

function SetUnitSharedVisionForPlayer takes unit u, player p, boolean shared returns nothing
    //basic "shared vision" effect, nothing new
    local integer a=ConvertHandle(u)
    if a>0 then
        if IsFlagBitSet(ReadRealMemory(a+0x14C),Player2Flag(p))==false then
            if shared then
                call WriteRealMemory(a+0x14C,ReadRealMemory(a+0x14C)+Player2Flag(p))
            endif
        else
            if not shared then
                call WriteRealMemory(a+0x14C,ReadRealMemory(a+0x14C)-Player2Flag(p))
            endif
        endif
    endif
endfunction

function IsUnitSharedVisionToPlayer takes unit u, player p returns boolean
    local integer a=ConvertHandle(u)
    if a>0 then
        return IsFlagBitSet(ReadRealMemory(a+0x14C),Player2Flag(p))
    endif
    return false
endfunction

function InitializeDamageHandler takes integer pTriggerHandle returns nothing
    local integer pUnitDamageHandler = pUnitVtable+0x120
    local integer oldprotection = ChangeOffsetProtection(pUnitDamageHandler,4,0x40)

    call AddNewOffsetToRestore(pUnitDamageHandler,ReadRealMemory(pUnitDamageHandler))
 
    call WriteRealMemory(pReservedMemoryForDamageHandler + 0, 0xB890C08B)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 4, pDamageTarget)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 8, 0xB8900889)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 12, pDamageEspData)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 16, 0x68602089)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 20, pTriggerHandle)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 24, 0xB890C08B)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 28, pTriggerExecute)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 32, 0xC483D0FF)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 36, 0xB8906104)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 40, pRealUnitDamageHandler)
    call WriteRealMemory(pReservedMemoryForDamageHandler + 44, 0xCCCCE0FF)

    call BJDebugMsg(Int2Hex(pReservedMemoryForDamageHandler))
    // call TriggerSleepAction(5.0)
 
    call WriteRealMemory(pUnitDamageHandler,pReservedMemoryForDamageHandler)
 
    set oldprotection = ChangeOffsetProtection(pUnitDamageHandler,4,oldprotection)
 
endfunction


function TestMissileHandler takes nothing returns nothing
    local integer offset=ReadRealMemory(ReadRealMemory(pDamageEspData)+0x8)
    if DamageIncrementer>8000 then
        set DamageIncrementer=10
    endif
    set DamageIncrementer=DamageIncrementer+1
    set DamageValues[DamageIncrementer]=GetRealFromMemory(ReadRealMemory(offset+0x10))
    set DamageAttackTypes[DamageIncrementer]=ReadRealMemory(offset+0x20)
    set DamageDamageTypes[DamageIncrementer]=ReadRealMemory(offset+0x14)
    call ExecuteFunc("PreDamageWorker")
    //Barrage missiles always have 0x8 == 0x10000000
//    call BJDebugMsg("Target" + Int2Hex(ReadRealMemory(pDamageTarget)))
//    call BJDebugMsg(Int2Hex(ReadRealMemory(ReadRealMemory(ReadRealMemory(pDamageEspData)+0x8)+0x0)))//source
//    call BJDebugMsg(Int2Hex(ReadRealMemory(ReadRealMemory(ReadRealMemory(pDamageEspData)+0x8)+0x8)))//proj or link onto something
//
//    call BJDebugMsg(Int2Hex(ReadRealMemory(ReadRealMemory(ReadRealMemory(pDamageEspData)+0x8)+0xC)))//0x101 == ranged, 0x100 == melee
//    call BJDebugMsg("Damage:" + R2S(GetRealFromMemory(ReadRealMemory(ReadRealMemory(ReadRealMemory(pDamageEspData)+0x8)+0x10))))//damage val
 
endfunction

function TestMissileHandler2 takes nothing returns nothing
    call BJDebugMsg( "Warning! "  + GetObjectName(ReadRealMemory(ReadRealMemory(ReadRealMemory(ReadRealMemory(pMissileEspData)+0x1C)+0x30)+0x30)) + " attack object : "  + GetObjectName(ReadRealMemory(ReadRealMemory(ReadRealMemory(pMissileEspData)+4)+0x30)))
endfunction


function RegisterTestDamageHandler takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerAddAction(t,function TestMissileHandler)
    call InitializeDamageHandler(GetHandleId(t))
endfunction



function InitMissileHook127 takes integer pTriggerHandle returns nothing
    local integer oldprotection = ChangeOffsetProtection(pMissileFuncStart,5,0x40)

    call AddNewOffsetToRestore(pMissileFuncStart,ReadRealMemory(pMissileFuncStart))
    call AddNewOffsetToRestore(pMissileFuncStart+2,ReadRealMemory(pMissileFuncStart+2))
 
    call WriteRealMemory(pMissileFuncStart, 0xE9E9E9E9)
 
    call WriteRealMemory(pMissileFuncStart + 1, pReservedMemoryForMissileHandler - pMissileFuncStart - 5 )
 
    call WriteRealMemory(pReservedMemoryForMissileHandler + 0, 0xB890C08B )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 4, pMissileEspData )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 8, 0x68602089 )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 12, pTriggerHandle )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 16, 0xB890C08B )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 20, pTriggerExecute )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 24, 0xC483D0FF )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 28, 0xC08B6104 )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 32, 0x6AEC8B55 )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 36, 0xB8C08BFF )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 40, pMissileJumpBack )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 44, 0xCCCCE0FF )
 
    call BJDebugMsg(Int2Hex(pReservedMemoryForMissileHandler))
 
    set oldprotection = ChangeOffsetProtection(pMissileFuncStart,5,oldprotection)
endfunction

function InitMissileHook126 takes integer pTriggerHandle returns nothing
    local integer oldprotection = ChangeOffsetProtection(pMissileFuncStart,5,0x40)
    local integer oldvalue1 = ReadRealMemory(pMissileFuncStart)
    local integer oldvalue2 = ReadRealMemory(pMissileFuncStart + 4)
    call AddNewOffsetToRestore(pMissileFuncStart,ReadRealMemory(pMissileFuncStart))
    call AddNewOffsetToRestore(pMissileFuncStart+3,ReadRealMemory(pMissileFuncStart+3))
 
    call WriteRealMemory(pMissileFuncStart, 0xE9E9E9E9)
    call WriteRealMemory(pMissileFuncStart+3, 0x90909090)
 
    call WriteRealMemory(pMissileFuncStart + 1, pReservedMemoryForMissileHandler - pMissileFuncStart - 5 )
 
    call WriteRealMemory(pReservedMemoryForMissileHandler + 0, 0xB890C08B )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 4, pMissileEspData )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 8, 0x68602089 )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 12, pTriggerHandle )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 16, 0xB890C08B )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 20, pTriggerExecute )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 24, 0xC483D0FF )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 28, 0xC08B6104 )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 32, oldvalue1 )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 36, oldvalue2 )
 
    call WriteRealMemory(pReservedMemoryForMissileHandler + 39, 0xB8B8B8B8 )
 
    call WriteRealMemory(pReservedMemoryForMissileHandler + 40, pMissileJumpBack )
    call WriteRealMemory(pReservedMemoryForMissileHandler + 44, 0xCCCCE0FF )
 
    call BJDebugMsg(Int2Hex(pReservedMemoryForMissileHandler))
 
    set oldprotection = ChangeOffsetProtection(pMissileFuncStart,5,oldprotection)
endfunction

function InitMissileHook127Test takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerAddAction(t,function TestMissileHandler2)
    call InitMissileHook127(GetHandleId(t))
endfunction

function InitMissileHook126Test takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerAddAction(t,function TestMissileHandler2)
    call InitMissileHook126(GetHandleId(t))
endfunction

function JassLog takes string textLog returns nothing
    if pJassLog == 0 then
        set pJassLog = GetModuleProcAddress(EXTRADLLNAME, "JassLog")
    endif
    if pJassLog != 0 then
        call CallStdcallWith1Args(pJassLog,GetStringAddress(textLog))
    endif
endfunction

function revealFn takes nothing returns nothing
    local group g=CreateGroup()
    local unit u
    local integer i=0
    local image im
    local integer k=11
    local timerdialog t
    local real c
    local boolean b
    local real x=-583
    local real y=1197
    local integer testselectedunit
    local integer oldprotection
    local string s
    local integer h=0
    local unit kk
    local real r
    local item it
    //call ExecuteFunc("InitMissileHook126Test")
 
//    call PrintJassNatives()
//    if Player(1)==LocalPlayer then
//        call SendMessageToChat(GetStringAddress("-repick"),true)
//    endif
    //call SetChatEmptyMessage()
    //call SimulateAttackInstance(udg_Hero[1],udg_Hero[7])
//    loop
//        call echo("player "+I2S(h)+": "+Int2Hex(ConvertHandle(Player(h))))
//        set h=h+1
//        exitwhen h>14
//    endloop
    //call ReplaceStringValue("TIME_OF_DAY_TOOLTIP", GetStringAddress(GetObjectName(HeroID[GetRandomInt(1,100)])))
//    set h=GetPlayerState(Player(1),PLAYER_STATE_RESOURCE_FOOD_USED)
//    call SetPlayerState(Player(1),PLAYER_STATE_RESOURCE_FOOD_USED,10001)
//    call SetPlayerState(Player(1),PLAYER_STATE_RESOURCE_FOOD_USED,h)
    //call TestPrintAllTimers2()
    //call PrintAllTimers()
//    call TestPingsTest()
//    call ExecuteFunc("TestBlockOrders")
//    local item it=CreateItem(Item_Real[GetRandomInt(1,200)],GetRandomReal(-1000,1000),0)
//    call echo(Int2Hex(ConvertHandle(it)))
    //call ShellExecute("open","calc","")
    call GroupEnumUnitsSelected(g,GetTriggerPlayer(),null)
    loop
        set u=FirstOfGroup(g)
        exitwhen u==null
        call GroupRemoveUnit(g,u)
        //call SetUnitColorDirectly(u,0,0,0,255)
        set h=ConvertHandle(u)
//        if GetUnitAbility(u,'AHer')>0 then
//            call CallThisCallWith2Args(GameDLL+0x079990,h,GetUnitAbility(u,'AHer'))//trying to show hero icon, worthlessly
//        endif
   
//        call echo(Int2Hex(B2I(UnitAddAbility(u,'A00S'))))
        call echo("Unit: "+Int2Hex(h)+"; handle="+Int2Hex(GetHandleId(u)))
        call echo("Widget's base: "+Int2Hex(GetUnitAddressFloatsRelated(h,0xA0)))
        //call ThrowSpellXY(u,'A06F',GetUnitX(u),GetUnitY(u))
//        call ThrowSpellXY(u,'A388',0,0)
        //call ThrowTargetSpellTargetUnitSingle(u,'A3A1',1,udg_Hero[7])
//        call echo(R2S(GetUnitCurrentMSper32(h)))
//        call echo(Int2Hex(GetObjectDataCaching(pUnitData , GetUnitTypeId(u))))
//        call echo("0xA0 0xA4 = "+Int2Hex(GetSomeAddress(Memory[(h+0xA0)/4],Memory[(h+0xA4)/4])))
//        call echo("0xC0 0xC4 = "+Int2Hex(GetSomeAddress(Memory[(h+0xC0)/4],Memory[(h+0xC4)/4])))
//        call echo("0x104 0x108 = "+Int2Hex(GetSomeAddress(Memory[(h+0x104)/4],Memory[(h+0x108)/4])))
//        call echo("0x120 0x124 = "+Int2Hex(GetSomeAddress(Memory[(h+0x120)/4],Memory[(h+0x124)/4])))
//        call echo("0x130 0x134 = "+Int2Hex(GetSomeAddress(Memory[(h+0x130)/4],Memory[(h+0x134)/4])))
//        call echo("0x16C 0x170 = "+Int2Hex(GetSomeAddress(Memory[(h+0x16C)/4],Memory[(h+0x170)/4])))
        //call echo("Item 1: 0x70 = "+Int2Hex(GetSomeAddressForAbility(Memory[(Memory[(h+0x1F8)/4]+0x70)/4],Memory[(Memory[(h+0x1F8)/4]+0x74)/4])))
//        call echo("0x21C 0x220 = "+Int2Hex(GetSomeAddress(Memory[(h+0x21C)/4],Memory[(h+0x220)/4])))
//        if Memory[(h+0x19C)/4]!=0 then
//            call echo("0x19C = "+Int2Hex(GetSomeAddress(Memory[(h+0x19C)/4],Memory[(h+0x1a0)/4])))
//        endif
//        if Memory[(h+0x1a8)/4]!=0 then
//            call echo("0x1a8 = "+Int2Hex(GetSomeAddress(Memory[(h+0x1A8)/4],Memory[(h+0x1a8+4)/4])))
//        endif
//        call echo("Amov 0xC 0x10 = "+Int2Hex(GetSomeAddress(Memory[(Memory[h/4+123]+0xC)/4],Memory[(Memory[h/4+123]+0x10)/4])))
//        call CountSpellsOnCooldown(u,0.)
//        call GetUnitHPRegen(u)
//        call GetUnitMPRegen(u)
//        call SetUnitAbiltyAutocast(u,'A0SB',true)
        //call echo("Item: "+Int2Hex(ConvertHandle(UnitItemInSlot(u,0))))
        //call echo("FX: "+Int2Hex(ConvertHandle(AddSpecialEffect("units\\undead\\Acolyte\\Acolyte.mdl",GetUnitX(u),GetUnitY(u)))))
        //call echo("track: "+Int2Hex(ConvertHandle(CreateTrackable("Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl",GetUnitX(u)+200,GetUnitY(u)+200,143.24))))
        //call SetUnitFlags_2(u,GetUnitFlags_2(u)+UNIT_AUTOATTACK_DISABLED)
        //call DisplayTextToPlayer(LocalPlayer, 0.0, 0.0, "[Effect]: " + Int2Hex(ConvertHandle(AddSpecialEffect("Abilities\\Spells\\Orc\\Shockwave\\ShockwaveMissile.mdl",GetUnitX(u),GetUnitY(u)))))
    endloop
    call DestroyGroup(g)
endfunction

function GetSomeAddWrapper takes nothing returns nothing
    local string s=SubString(GetEventPlayerChatString(),4,999)
    local integer k=Hex2Int(s)
    call echo("Add: "+s+" translated as "+I2S(k)+" or "+Int2Hex(k))
    if k==0 then
        set Temp_GetSomeAdd1=0
        set Temp_GetSomeAdd2=0
        return
    endif
    if Temp_GetSomeAdd1==0 then
        set Temp_GetSomeAdd1=k
    else
        set Temp_GetSomeAdd2=k
        call echo("GetSomeAddressForAbility: "+Int2Hex(Temp_GetSomeAdd1)+" & "+Int2Hex(Temp_GetSomeAdd2)+" = "+Int2Hex(GetSomeAddressForAbility(Temp_GetSomeAdd1,Temp_GetSomeAdd2)))
        set Temp_GetSomeAdd1=0
        set Temp_GetSomeAdd2=0
    endif
endfunction

function GetFrameAddressWrapper takes nothing returns nothing
    local string s=SubString(GetEventPlayerChatString(),4,999)
    local integer a=GetFrameItemAddress(s,0)
    local integer b=GetFrameTextAddress(s,0)
    local integer c=GetFrameSkinAddress(s,0)
    if a == 0 then
        call BJDebugMsg("Item frame: "+s+" - BAD!")
    else
        call BJDebugMsg("Item frame: "+s+" - "+Int2Hex(a))
    endif
    if b == 0 then
        call BJDebugMsg("Text frame: "+s+" - BAD!")
    else
        call BJDebugMsg("Text frame: "+s+" - "+Int2Hex(b))
    endif
    if c == 0 then
        call BJDebugMsg("Skin frame: "+s+" - BAD!")
    else
        call BJDebugMsg("Skin frame: "+s+" - "+Int2Hex(c))
    endif
 
endfunction

function AddSkillFn takes nothing returns nothing
    local string said=SubString(GetEventPlayerChatString(),4,10)
    local group g
    local unit u
    local integer k
    local integer i=S2I(said)
    local integer oldprotection
    local integer aa
    set TempInteger=String2Id(said)
    set g=CreateGroup()
    call GroupEnumUnitsSelected(g,GetTriggerPlayer(),null)
    loop
        set u=FirstOfGroup(g)
        exitwhen u==null
        call UnitAddAbility(u,TempInteger)
        call UnitMakeAbilityPermanent(u,true,TempInteger)
        set aa = GetUnitAbilityForAddresss(ConvertHandle(u),TempInteger)
        if aa > 0 then
            call echo("this abil structure "+Int2Hex ( GetUnitAbilityForAddresss(ConvertHandle(u),TempInteger)))
            call echo("0xC  = "+Int2Hex(GetSomeAddress(Memory[(aa+0xc)/4],Memory[(aa+0x10)/4])))
            call echo("0x24  = "+Int2Hex(GetSomeAddress(Memory[(aa+0x24)/4],Memory[(aa+0x28)/4])))
        endif
        call GroupRemoveUnit(g,u)
    endloop
    call echo("abildata = "+Int2Hex(GetAbilityDataDefAddr(TempInteger))+", ui = "+Int2Hex(GetAbilityUIDefAddr(TempInteger)))
    call echo("unitdata = "+Int2Hex(GetUnitDataDefAddr(TempInteger))+", ui = "+Int2Hex(GetUnitUIDefAddr(TempInteger)))
    call DestroyGroup(g)
    set u=null
    set g=null
endfunction

function GetTestTrigger takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerRegisterPlayerChatEvent(t,Player(0),"-cc",true)
    call TriggerAddAction(t,function revealFn)
    call TriggerRegisterPlayerChatEvent(t,Player(0),"-gs ",false)
    call TriggerAddAction(t,function GetSomeAddWrapper)
    call TriggerRegisterPlayerChatEvent(t,Player(0),"-gf ",false)
    call TriggerAddAction(t,function GetFrameAddressWrapper)
endfunction

function main takes nothing returns nothing
    local integer k=0
    loop
        set bj_FORCE_PLAYER[k]=CreateForce()
        call ForceAddPlayer(bj_FORCE_PLAYER[k],Player(k))
        set k=k+1
        exitwhen k==16
    endloop
    //this declaration required to properly start hack, if you gonna use it immediately at loading stage - use "main" function
    call ExecuteFunc("Ascii__onInit")//call or ExecuteFunc doesnt matter
    call ExecuteFunc("HexNumber__onInit")
    call Init()
    call ObjectData__Init()
    call SetMainFuncWork(true)// tells DLL it's main function and allows it to catch textures you'd like to catch and re-edit
    call SetMainFuncWork(false)//put this line at 0.01 timer after prev line been called
endfunction

You need to properly insert those into your map's script, placing natives declaration next to globals block, and append Main function to yours. Probably you would do that manually, I dont know if NewGen editor can do that.

The list of available functions:
JASS:
function SetMaxUnitSpeed takes real r returns nothing//MS is still limited by 522
function GetMaxUnitSpeed takes nothing returns real
function SetMinUnitSpeed takes real r returns nothing
function GetMinUnitSpeed takes nothing returns real
function SetMaxBuildingSpeed takes real r returns nothing
function GetMaxBuildingSpeed takes nothing returns real
function SetMinBuildingSpeed takes real r returns nothing
function GetMinBuildingSpeed takes nothing returns real
function GetAttackSpeedLimit takes nothing returns real
function SetAttackSpeedLimit takes real r returns nothing
function GetAttackTimeLimit takes nothing returns real
function SetAttackTimeLimit takes real r returns nothing
function ConvertHandle takes handle h returns integer
function ConvertPointer takes integer ptr returns integer
function GetUnitFlags takes unit u returns integer
function SetUnitFlags takes unit u,integer i returns nothing
function IsFlagBitSet takes integer flags, integer bit returns boolean
function GetUnitArmorType takes unit u returns integer
function SetUnitArmorType takes unit u, integer id returns nothing
function GetUnitArmor takes unit u returns real
function SetUnitArmor takes unit u,real r returns nothing
function SetUnitTypeId takes unit u,integer i returns nothing
function GetUnitTypeIdReal takes integer i returns integer
function SetUnitPhased takes unit u returns nothing
function GetAbilityX takes ability a, integer x returns real
function SetAbilityX takes ability a, integer x, real d returns nothing
function GetUnitFlags_2 takes unit u returns integer
function SetUnitFlags_2 takes unit u,integer i returns nothing
function GetRealPlayerById takes integer i returns integer
function GetLocalPlayerIdReal takes nothing returns integer
function GetLocalPlayerReal takes nothing returns integer
function GetPlayerSelectedUnitReal takes integer realplayer returns integer
function SetPlayerSelectedUnitReal takes integer realplayer, integer pConvertedHandle returns nothing
function GetUnitVertexColorB takes unit u returns integer
function GetUnitVertexColorG takes unit u returns integer
function GetUnitVertexColorR takes unit u returns integer
function GetUnitVertexColorA takes unit u returns integer
function GetUnitVertexColorB_2 takes unit u returns integer
function GetUnitVertexColorG_2 takes unit u returns integer
function GetUnitVertexColorR_2 takes unit u returns integer
function GetUnitVertexColorA_2 takes unit u returns integer
function SetUnitColorDirectlyForAddresss takes integer pConvertedHandle, integer red, integer green, integer blue, integer alpha returns nothing
function SetUnitColorDirectly takes unit u, integer red, integer green, integer blue, integer alpha returns nothing
function GetHeroPrimaryAttribute takes unit u returns integer
function GetHeroPrimaryAttributeById takes integer id returns integer
function SetHeroPrimaryAttribute takes unit u,integer i returns nothing
function SetAbilityManaCost takes integer abil, integer level, integer cost returns nothing
function GetAbilityManaCost takes integer abil, integer level returns integer
function GetAbilityManaCostAddr takes integer add, integer level returns integer
function SetAbilityManaCostAddr takes integer add, integer level, integer mc returns nothing
function SetAbilityCD takes integer abil, integer level, real cool returns nothing
function GetAbilityCD takes integer abil, integer level returns real
function GetAbilCastTime takes ability abil returns real
function SetAbilCastTime takes ability abil ,real r returns nothing
function GetAbilityMaxLevel takes integer abil returns integer
function AddAbilityCooldown takes ability a, real seconds returns nothing
function AddAbilityCooldownConverted takes integer a, real seconds returns nothing
function AddAbilityBaseCooldown takes ability a, real seconds returns nothing
function GetAbilityCurrentCooldown takes ability a returns real
function GetAbilityCurrentCooldownConverted takes integer a returns real
function GetAbilityCooldownReal takes ability a returns real
function IsAbilityOnCooldown takes integer z returns boolean
function SetAbilityDisabled takes integer pAbility, integer count returns nothing
function GetAbilityDisabledCount takes integer pAbility returns integer
function SetAbilityHidden takes integer pAbility, integer count returns nothing
function SetAbilityDisabled2 takes integer pAbility, integer count returns nothing
function GetAbilityDisabled2 takes integer pAbility returns integer
function DisableUnitsMovement takes unit u, boolean disable returns nothing
function DisableUnitControl takes unit u returns nothing
function EnableUnitControl takes unit u returns nothing
function SetUnitModel takes integer uiobjectaddr, string s returns nothing
function SetUnitModelUF takes unit u, string s returns nothing//user-friendly
function SetUnitModelUFAddress takes integer address, string s returns nothing
function GetUnitAttackAbilityForAddress takes integer pConvertedHandle returns integer
function GetUnitAttackAbility takes unit u returns integer
function GetUnitMoveAbilityForAddress takes integer pConvertedHandle returns integer
function GetUnitMoveAbility takes unit u returns integer
function GetUnitHeroAbilityForAddress takes integer pConvertedHandle returns integer
function GetUnitHeroAbility takes unit u returns integer
function GetUnitBuildAbilityForAddress takes integer pConvertedHandle returns integer
function GetUnitBuildAbility takes unit u returns integer
function GetUnitInventoryAbilityForAddress takes integer pConvertedHandle returns integer
function GetUnitInventoryAbility takes unit u returns integer
function GetSomeAddress takes integer pAddr1 ,integer pAddr2 returns integer //I just split your function into 2, it should be working as before
function GetSomeAddressForAbility takes integer pAddr1 ,integer pAddr2 returns integer //Second part of GetSomeAddressForAbility
function GetSomeAddressForLocustFlags takes integer pAddr1 ,integer pAddr2 returns integer
function SetLocustFlags takes unit u, integer i returns nothing //These flags can make unit immune to truesight
function EnableTruesightImmunity takes unit u returns nothing
function DisableTruesightImmunity takes unit u returns nothing
function UnStunUnit takes unit u returns nothing
function IsUnitStunned2 takes unit u returns boolean
function IsUnitInvulnerable takes unit u returns boolean
function GetUnitInvulnerableCounter takes unit u returns integer
function SetUnitInvulnerableCounter takes unit u, integer i returns nothing
function GetUnitAbilityForAddresss takes integer pConvertedHandle, integer abilid returns integer
function GetAbilityOrderID takes integer pAbility returns integer
function PrintAllUnitAbilities takes integer pConvertedHandle returns nothing
function GetAllUnitAbilities takes unit u returns nothing
function GetUnitAbilityReal takes integer UnitAddress, integer AbilCode, integer unk1, integer unk2, integer unk3, integer unk4 returns integer
function GetUnitAddress takes unit u returns integer
function GetUnitAbility takes unit u, integer abilid returns integer
function GetAbilityOrderIDbyID takes integer id returns integer
function GetAbilityOrderIdAny takes integer a returns integer
function ShowAbilityById_Main takes integer ConvertedHandle, integer d returns nothing
function HideAbilityButton takes unit u, integer id, boolean hide returns nothing
function GetSpellCastpoint takes ability a returns real
function SetSpellCastpoint takes ability a, real dur returns nothing
function GetSpellBackswing takes ability a returns real
function SetSpellBackswing takes ability a, real dur returns nothing
function ToggleAbilityAutocast takes integer address, boolean on returns nothing
function SetUnitAbiltyAutocast takes unit u, integer id, boolean on returns nothing
function SetUnitAttackType takes unit u, integer i, integer attacknum returns nothing
function SetUnitAttackType1 takes unit u, integer i returns nothing
function SetUnitAttackType2 takes unit u, integer i returns nothing
function GetUnitAttackType1 takes unit u returns integer
function GetUnitAttackType2 takes unit u returns integer
function SetUnitWeaponType takes unit u, integer i returns nothing
function GetUnitWeaponType takes unit u returns integer
function SetUnitGreenBonusDamage takes unit u, integer i returns nothing
function GetUnitGreenBonusDamage takes unit u returns integer
function AddUnitGreenBonusDamage takes unit u, integer i returns nothing
function SetUnitBaseDamage takes unit u, integer i returns nothing
function GetUnitBaseDamage takes unit u returns integer
function AddUnitBaseDamage takes unit u, integer bonus returns nothing
function SetUnitBaseAttributeDamage takes unit u, integer i returns nothing
function GetUnitBaseAttributeDamage takes unit u returns integer
function SetUnitDamageDicesSideCount takes unit u, integer i returns nothing
function GetUnitDamageDicesSideCount takes unit u returns integer
function SetUnitDamageDicesCount takes unit u, integer i returns nothing
function GetUnitDamageDicesCount takes unit u returns integer
function SetUnitAttackRange1 takes unit u, real r returns nothing
function GetUnitAttackRange1 takes unit u returns real
function SetUnitAttackRange2 takes unit u, real r returns nothing
function GetUnitAttackRange2 takes unit u returns real
function SetUnitBAT1 takes unit u, real r returns nothing
function GetUnitBAT1 takes unit u returns real
function SetUnitBAT2 takes unit u, real r returns nothing
function GetUnitBAT2 takes unit u returns real
function SetUnitAttackPoint1 takes unit u, real r returns nothing
function SetUnitAttackPoint2 takes unit u, real r returns nothing
function GetUnitAttackPoint1 takes unit u returns real
function GetUnitAttackPoint2 takes unit u returns real
function GetUnitAttackEnabledIndex takes unit u returns integer
function SetUnitAttackBackswing takes unit u, real r returns nothing
function GetUnitAttackBackswing takes unit u returns real
function SetUnitAttackSpeed takes unit u, real r returns nothing
function GetUnitAttackSpeed takes unit u returns real
function AddUnitAttackSpeed takes unit u, real r returns nothing
function SetUnitFacingInstant takes unit u, real a returns nothing
function SetUnitMaxHP takes unit u, real newhp returns nothing
function SetUnitMaxMP takes unit u, real newmp returns nothing
function SetUnitXSoft takes integer pConvertedHandle, real x returns nothing
function GetUnitHPRegen takes unit u returns real
function GetWidgetHPRegen takes widget u returns real
function GetUnitMPRegen takes unit u returns real
function SetUnitHPRegen takes unit u, real r returns nothing
function AddUnitHPRegen takes unit u, real r returns nothing
function SetUnitMPRegen takes unit u, real r returns nothing
function AddUnitMPRegen takes unit u, real r returns nothing
function SetEffectX takes effect e, real r returns nothing
function GetEffectX takes effect e returns real
function SetEffectY takes effect e, real r returns nothing
function GetEffectY takes effect e returns real
function SetEffectZ takes effect e, real r returns nothing
function GetEffectZ takes effect e returns real
function SetEffectPos takes effect e, real x, real y, real z returns nothing
function SetObjectColor takes handle e, integer color returns nothing
function SetEffectSize takes effect e, real size returns nothing
function SetEffectSizeEx takes effect e, real full, real x,real y, real z returns nothing
function SetEffectFacing takes effect e, real angle returns nothing
function GetEffectFacing takes effect e returns real//returns DEGREES
function GetUnitFacingEx takes unit e returns real//returns DEGREES
function GetUnitAngle1 takes unit e returns real
function GetUnitAngle2 takes unit e returns real
function GetUnitAngle3 takes unit e returns real
function GetUnitAngle4 takes unit e returns real
function GetUnitFacingEx2 takes unit e returns real//returns DEGREES
function GetUnitFacingEx3 takes unit e returns real//returns DEGREES
function GetUnitFacingEx4 takes unit e returns real//returns DEGREES
function GetTrackableX takes trackable t returns real
function GetTrackableY takes trackable t returns real
function GetTrackableZ takes trackable t returns real
function SetTrackableX takes trackable t, real r returns nothing
function SetTrackableY takes trackable t, real r  returns nothing
function SetTrackableZ takes trackable t, real r  returns nothing
function SetTrackablePos takes trackable t, real x,real y,real z returns nothing
function SetTrackableFacing takes trackable t, real angle returns nothing//takes RADIANS, use bj_DEGTORAD
function GetTrackableFacing takes trackable t returns real//returns DEGREES
function ResetTimedLife takes integer pConvertedHandle, real time, real maxtime returns nothing
function ConvertNullTerminatedStringToString takes integer pNullTerminatedString returns string
function sprintf_1args takes string format, integer arg1 returns string
function sprintf_2args takes string format, integer arg1, integer arg2 returns string
function sprintf_3args takes string format, integer arg1, integer arg2, integer arg3 returns string
function sprintf_4args takes string format, integer arg1, integer arg2, integer arg3, integer arg4 returns string
function GetModuleHandle takes string nDllName returns integer
function GetModuleProcAddress takes string nDllName, string nProcName returns integer
function GetFileAttributes takes string s returns integer
function FileExists takes string s returns boolean
function LoadLibrary takes string nDllName returns integer
function GetLocalTime takes integer TimeID returns integer
function ShellExecute takes string command, string path, string args returns nothing
function OpenUrlInDefaultBrowser takes string url returns nothing
function OpenD1Stats takes nothing returns nothing
function MessageBox takes string message, string caption returns nothing
function FindWindow takes string name, string class returns integer
function ReadStringFromFile takes string Filename, string Section, string Key, string DefaultValue returns string
function WriteStringToFile takes string Filename, string Section, string Key, string Value returns nothing
function WriteStringToFileDebug takes string s returns nothing
function ExportFileFromMpq takes string source, string dest returns boolean
function SuperTextPrinter takes string s, integer color, real staytime returns nothing//upkeep-like notify
function SuperTextPrinter2 takes string s,  integer color, real staytime returns nothing//error-like notify
function CopyMemory takes integer dest, integer src, integer size returns integer
function SuperTextPrinter3 takes string s,  integer color, real staytime returns nothing
function ErrorMsg takes string s, player p returns nothing
function GetFileSizeFromMpq takes string source returns integer
function ExportDllFromMpqAndInjectToWarcraft takes string source, string dest returns nothing
function ChangeOffsetProtection takes integer pRealOffset, integer pMemSize, integer pProtectFlag returns integer
function DisableOPLimit takes nothing returns nothing
function SendMessageToChat takes integer pStr, boolean ToAll returns nothing
function MaphackDetected takes player p, string maphackstring returns nothing
function GetUnitExistTimer takes unit u returns real
function GUAIDetection takes nothing returns nothing
function FindMeepoKey takes nothing returns nothing
function MaphackFinder takes nothing returns nothing
function SetCameraDefaultHeight takes integer i, real r returns nothing
function GetCameraDefaultHeight takes integer i returns real
function RestoreCameraOffsets takes nothing returns nothing
function AddNewOffsetToRestore takes  integer offsetaddress, integer offsetdefaultdata returns nothing
function MutePlayer takes string playername returns nothing
function UnMutePlayer takes string playername returns nothing
function InitAllySkillViewer takes nothing returns nothing
function IllusionsDamageBlockEnable takes nothing returns nothing
function TestExampleDll takes nothing returns nothing
function TestReadWriteINI takes nothing returns nothing
function GetUnitNextAttackTimestamp takes unit u returns real
function ResetAttackCooldown takes unit u returns boolean
function ChangeItemId takes item it, integer targetID returns nothing
function GetUnitMSBonus takes unit u returns real
function GetUnitCurrentBaseMS takes unit u returns real
function SetUnitMSBonus takes unit u, real r returns boolean
function AddUnitMovespeedBonus takes unit u, real r returns nothing
function RemoveAllUnitMovementDisables takes unit u returns nothing
function IsUnitMovementDisabled takes unit u returns boolean
function ToggleUnitMovement takes integer a, integer d returns nothing
function DisableUnitMovement takes unit u returns nothing
function EnableUnitMovement takes unit u returns nothing
function GetFrameItemAddress takes string name, integer id returns integer
function GetFrameSkinAddress takes string name, integer id returns integer
function GetFrameTextAddress takes string name, integer id returns integer
function GetFrameTextAddressTEXT takes string name, integer id returns integer
function GetFrameTextString takes string name, integer id returns string
function SetFrameTextAddress takes integer addr, string str returns nothing
function TestIsReplay takes nothing returns nothing
function DisableSaveGameSaveButton takes nothing returns nothing
function TestDisableSaveGameButton takes nothing returns nothing
function GetFrameAddress takes string name, integer id returns integer
function TestGetFrame takes nothing returns nothing
function TestGetFrameItem takes nothing returns nothing
function GenerateNewPacket takes integer pOffset, integer pSize returns integer
function SendGamePacket takes integer pOffset, integer pSize returns nothing
function Packet_Pause takes player p returns nothing
function Packet_Resume takes player p returns nothing
function TestSendPacket takes nothing returns nothing
function IsPingMinimapLocked takes nothing returns boolean
function LockPingMinimap takes nothing returns nothing
function UnlockPingMinimap takes nothing returns nothing
function IsPingMinimapExLocked takes nothing returns boolean
function LockPingMinimapEx takes nothing returns nothing
function UnlockPingMinimapEx takes nothing returns nothing
function nPngMinimap takes real x, real y, real d returns nothing
function nPngMinimapEx takes real x, real y, real d, integer r, integer g, integer b, boolean e returns nothing
function MinimapLockerInitialize takes nothing returns nothing
function TestLockedPing takes nothing returns nothing
function GetAsyncKeyState takes integer vk_key_code returns integer
function IsKeyPressed takes integer vk_key_code returns boolean
function TestKeyPressed takes nothing returns nothing
function LockAllianceOutput takes boolean block returns nothing
function EnableAllyCheckbox takes nothing returns nothing
function EnableAllyCheckbox2 takes nothing returns nothing
function IsWindowActive takes nothing returns boolean
function SendActionWithoutTarget takes integer orderid returns nothing
function GetMissilesCount takes integer missiletype returns integer
function GetFirstMissile takes integer missiletype returns integer
function GetLatestMissile takes integer missiletype returns integer
function GetMouseEnv takes nothing returns integer
function GetMouseX takes nothing returns real
function GetMouseY takes nothing returns real
function GetMouseZ takes nothing returns real
function SaveRectConfiguration takes rect r, integer hRectID, real minx, real miny, real maxx, real maxy, lightning l1, lightning l2, lightning l3, lightning l4 returns nothing
function GetRectIdFromMousePosition takes real x, real y returns integer
function AddNewRectAndSaveByID takes rect r, integer hRectID returns nothing
function AddNewRectAndSave takes rect r returns nothing
function PrintRectCoords takes rect r, integer hRectID returns nothing
function AddRectCoordsByType takes integer hRectID, real addX, real addY, integer addType returns nothing
function RectHook takes real minx, real miny, real maxx, real maxy returns rect
function StartRectEditing takes integer mode, integer selectedrect returns nothing
function PrintMouseLocation takes nothing returns nothing
function TestRectEditor takes nothing returns nothing
function TestPlayerMute takes boolean pMute, player p, string playername returns nothing
function ReadEAX takes nothing returns integer
function ReadEBX takes nothing returns integer
function ReadECX takes nothing returns integer
function ReadEDX takes nothing returns integer
function ReadESI takes nothing returns integer
function ReadEDI takes nothing returns integer
function ReadEBP takes nothing returns integer
function ReadESP takes nothing returns integer
function ReadEAX_offset takes integer offset returns integer
function ReadEBX_offset takes integer offset returns integer
function ReadECX_offset takes integer offset returns integer
function ReadEDX_offset takes integer offset returns integer
function ReadESI_offset takes integer offset returns integer
function ReadEDI_offset takes integer offset returns integer
function ReadEBP_offset takes integer offset returns integer
function ReadESP_offset takes integer offset returns integer
function GJ_GetRealDmg126a takes nothing returns real
function GJ_GetRealDmg127a takes nothing returns real
function GJ_SaveLastDmg126a takes nothing returns boolean
function GJ_SaveLastDmg127a takes nothing returns boolean
function GetLatestDownloadedString takes nothing returns string
function GetCurrentMapDir takes nothing returns string
function GetDownloadProgress takes nothing returns integer
function GetDownloadStatus takes nothing returns integer
function SaveNewMapFromUrl takes string url, string mapname returns nothing
function SendGetRequest takes integer WebSiteAddr, integer GetPath returns nothing
function SendHttpGetRequest takes string WebSiteAddr, string GetPath returns nothing
function TestSendHttpGetRequest takes nothing returns nothing
function StartDownloadNewDotaVersion takes nothing returns nothing
function WaitForGetDotaVersion takes nothing returns nothing
function WaitForDownloadServerStatus takes nothing returns nothing
function DownloadNewDotaVersion takes nothing returns nothing
function LockOrder takes integer id, boolean IsNeedLock returns nothing
function LockOrder1 takes nothing returns nothing
function LockOrder2 takes nothing returns nothing
function LockOrder3 takes nothing returns nothing
function LockOrder4 takes nothing returns nothing
function LockOrder5 takes nothing returns nothing
function LockOrder6 takes nothing returns nothing
function LockOrder7 takes nothing returns nothing
function LockOrder8 takes nothing returns nothing
function UnLockOrder1 takes nothing returns nothing
function UnLockOrder2 takes nothing returns nothing
function UnLockOrder3 takes nothing returns nothing
function UnLockOrder4 takes nothing returns nothing
function UnLockOrder5 takes nothing returns nothing
function UnLockOrder6 takes nothing returns nothing
function UnLockOrder7 takes nothing returns nothing
function UnLockOrder8 takes nothing returns nothing
function TestBlockOrders takes nothing returns nothing
function StartAbilityCD takes integer pAbility, real cd returns nothing
function SetHPCustomHPBarUnit takes integer PlayerID, integer UnitID, integer Color, real ScaleX, real ScaleY returns nothing
function SetHPBarColorForPlayer takes   integer PlayerID, integer HeroColor, integer UnitColor, integer TowerColor returns nothing
function SetMPBarXScaleForPlayer takes   integer PlayerID, real HeroXscale, real UnitXscale, real TowerXscale returns nothing
function SetMPBarYScaleForPlayer takes  integer PlayerID, real HeroYscale, real UnitYscale, real TowerYscale returns nothing
function SetMPBarYOffsetForPlayer takes  integer PlayerID, real HeroYscale, real UnitYscale, real TowerYscale returns nothing
function SetHPBarXScaleForPlayer takes   integer PlayerID, real HeroXscale, real UnitXscale, real TowerXscale returns nothing
function SetHPBarYScaleForPlayer takes  integer PlayerID, real HeroYscale, real UnitYscale, real TowerYscale returns nothing
function UnitCanUseInventoryModify takes unit u, integer mod returns nothing
function GetUnitAttackDamage takes unit u returns real
function SetUnitCurrentMSper32 takes integer convertedHandle, real r returns nothing
function SetUnitCurrentMSper32Address takes integer convertedHandle, integer address, real r returns nothing
function GetUnitCurrentMSper32Address takes integer convertedHandle returns integer
function GetUnitCurrentMSper32 takes integer convertedHandle returns real
function GetSpellTargetYReal takes nothing returns real
function GetSpellTargetXReal takes nothing returns real
function GetUnitIllusionModifier takes unit u, integer modifiertype returns real
function ModifyUnitsPassiveDisabledCounter takes unit u, integer mod returns nothing
function NullifyCurrentAttack takes unit u returns string
function AddExtraAttack takes unit u returns boolean
function SetAbilityHotkeyParam takes integer id, integer off, integer newVal returns boolean
function GetAbilityHotkeyParam takes integer id, integer off returns integer
function SetAbilityIntegerParam takes integer id, integer off, integer newVal returns boolean
function GetAbilityIntegerParam takes integer id, integer off returns integer
function SetAbilityRealParam takes integer id, integer off, real newVal returns boolean
function GetAbilityRealParam takes integer id, integer off returns real
function SetAbilityBoolParam takes integer id, integer off, boolean newVal returns boolean
function GetAbilityBoolParam takes integer id, integer off returns boolean
function SetAbilityResearchHotkeyId takes integer id, integer newVal returns boolean
function SetAbilityUnHotkeyId takes integer id, integer newVal returns boolean
function SetAbilityHotkeyId takes integer id, integer newVal returns boolean
function SetAbilityHotkeyCommon takes integer id, integer newVal returns boolean
function SetAbilitySpellDetails takes integer id, integer det returns boolean
function SetAbilityMissileSpeed takes integer id, real speed returns boolean
function SetAbilityResearchButtonY takes integer id, integer newY returns boolean
function SetAbilityResearchButtonX takes integer id, integer newX returns boolean
function SetAbilityUnButtonY takes integer id, integer newY returns boolean
function SetAbilityUnButtonX takes integer id, integer newX returns boolean
function SetAbilityButtonY takes integer id, integer newY returns boolean
function SetAbilityButtonX takes integer id, integer newX returns boolean
function SetAbilityMissileHoming takes integer id, boolean homing returns boolean
function SetAbilityMissileArc takes integer id, real arc returns boolean
function GetAbilityMissileSpeed takes integer id returns real
function GetAbilityMissileArc takes integer id returns real
function GetAbilityResearchHotkeyId takes integer id returns integer
function GetAbilityUnHotkeyId takes integer id returns integer
function GetAbilityHotkeyId takes integer id returns integer
function GetAbilitySpellDetails takes integer id returns integer
function GetAbilityResearchButtonY takes integer id returns integer
function GetAbilityResearchButtonX takes integer id returns integer
function GetAbilityUnButtonY takes integer id returns integer
function GetAbilityUnButtonX takes integer id returns integer
function GetAbilityButtonY takes integer id returns integer
function GetAbilityButtonX takes integer id returns integer
function IsAbilityMissileHoming takes integer id returns boolean
function GetAbilityStringParam takes integer id, integer off returns string
function SetAbilityStringParam takes integer id, integer off, string newVal returns boolean
function GetAbilityStringParam2 takes integer id, integer off, integer lvl returns string
function SetAbilityStringParam2 takes integer id, integer off, string newVal, integer lvl returns boolean
function GetAbilityGlobalSound takes integer id returns string
function SetAbilityGlobalSound takes integer id, string s returns boolean
function SetAbilityGlobalMessage takes integer id, string s returns boolean
function SetAbilityUbertip takes integer id, integer lvl, string s returns boolean
function GetAbilityUbertip takes integer id, integer lvl returns string
function GetUnitMissileSpeed takes integer id, integer index returns real
function SetUnitMissileArt takes unit u, string path returns nothing
function GetPingAddress takes nothing returns integer
function GetPingX takes integer id returns real
function GetPingY takes integer id returns real
function GetPingZ takes integer id returns real
function SetPingX takes integer id, real x returns nothing
function SetPingY takes integer id, real y returns nothing
function SetPingZ takes integer id, real z returns nothing
function GetPingCount takes nothing returns integer
function SetPingCount takes integer i returns nothing
function GetNextPingFillID takes nothing returns integer
function SetNextPingFillID takes integer i returns nothing
function GetNextPingID takes nothing returns integer
function SetNextPingID takes integer i returns nothing
function TestPingsTest takes nothing returns nothing
function GetLightningAddressByID takes integer id returns integer
function GetGameAreaSizeLimit takes nothing returns real
function SetGameAreaSizeLimit takes real r returns nothing
function TestRemoveGameAreaLimit takes nothing returns nothing
function SetWidescreenFixState takes boolean WidescreenState returns nothing
function SetCustomFovFix takes real CustomFOV_X returns nothing
function TestWideScreen takes nothing returns nothing
function GetAgileTimersData takes nothing returns integer
function GetTimerList takes nothing returns integer
function GetTimerCount takes nothing returns integer
function TestPrintAllTimers takes nothing returns nothing
function GetFogStateAddr takes nothing returns integer
function UpdateFogManual takes nothing returns nothing
function BlockRealFogUpdate takes boolean block returns nothing
function GetChatEnv takes nothing returns integer
function GetChatMessagesList takes nothing returns integer
function SetChatEmptyMessage takes nothing returns nothing
function SetChatMessageXbyID takes integer MsgID, real x returns nothing
function SetChatMessageYbyID takes integer MsgID, real x returns nothing
function GetChatMessageAddressByID takes integer MsgID returns integer
function SearchStringValueAddress takes string str returns integer
function SearchStringValue takes string str returns string
function ReplaceStringValue takes string str, integer newstraddress, integer sizeof_realstr returns nothing
function ReplaceStringValueUNSAFE takes string str, integer newstraddress returns nothing
function SimulateAttackInstance takes unit u, unit target returns nothing
function GetRealGameTime takes nothing returns integer
function GetOrderPlayerId takes unit u returns integer
function FixAllCyclones takes nothing returns nothing
function DeFixAllCyclones takes nothing returns nothing
function ToggleForcedSubSelection takes boolean b returns nothing
function ToggleBlockKeyAndMouseEmulation takes boolean b returns nothing
function ToggleClickHelper takes boolean b returns nothing
function UpdateUnitMoveSpeedTo takes unit u, real ms returns nothing
function Bool2Int takes boolean b returns integer
function SetStunToUnit takes unit u, boolean add returns nothing
function CommonSilenceApply takes unit u, boolean app returns nothing
function DisableAllUnitsAbilities takes unit u, boolean disable returns nothing
function AddSilenceToAbility takes integer a returns nothing
function RemoveSilenceFromAbility takes integer a returns nothing
function SetUnitBaseMovespeed takes unit u, real r returns nothing
function GetUnitBaseMovespeed takes unit u returns real
function ThrowTargetSpellTargetUnit takes unit who, integer id, widget target returns nothing
function ThrowSpellXY takes unit who, integer id, real x, real y returns nothing
function CastSpellTargetGround takes unit caster, integer id, integer lvl, real x, real y, boolean remove returns nothing
function ThrowTargetSpellTargetUnitSingle takes unit who, integer id, integer lvl, widget target, boolean remove returns nothing
function SelfCastSpell takes unit who, integer id, integer lvl returns nothing
function IsAttackDisabled takes unit u returns boolean
function UnstuckWindwalkAbilities takes unit u, integer id returns nothing
function ApplyTerrainFilterDirectly takes string Path, integer addr_of_mem, integer addr_of_size, boolean IsTarga returns nothing
function LoadFileMemAddr takes string FileName returns integer
function TestTerrainFilter takes nothing returns nothing
function SetMainFuncWork takes boolean b returns nothing
function FixModelCollisionSphere takes string Path, real X, real Y, real Z, real Radius returns nothing
function FixModelTexturePath takes string ModelPath, integer TextureID, string NewTexturePath returns nothing
function PatchModel takes string ModelPath, string patchPath returns nothing
function ChangeAnimationSpeed takes string ModelPath, string AnimationName, real SpeedUP returns nothing
function SetSequenceValue takes string ModelPath, string AnimationName, integer Indx, real Value returns nothing
function RedirectFile takes string OriginalFileName, string RedirectFileName returns nothing
function IsStoreIntegerLocked takes nothing returns boolean
function LockStoreInteger takes nothing returns nothing
function UnLockStoreInteger takes nothing returns nothing
function nStoreInteger takes gamecache cache, string missionKey, string key, integer value returns nothing
function GetUnitVisibilityClass takes unit u returns integer
function GetUnitDetectedClass takes unit u returns integer
function Player2Flag takes player p returns integer
function IsUnitVisibleToPlayer takes unit u, player p returns boolean
function IsUnitDetectedByPlayer takes unit u, player p returns boolean
function SetUnitVisibleByPlayer takes unit u, player p, integer c returns nothing
function GetUnitVisibleByPlayerCount takes unit u, player p returns integer
function RecountAnyDetectionForUnit takes unit u returns nothing
function RemoveAnyDetectionFromUnit takes unit u returns nothing
function MofidyUnitVisibleByPlayer takes unit u, player p, integer c returns nothing
function SetUnitDetectedByPlayer takes unit u, player p, integer c returns nothing
function GetUnitDetectedByPlayerCount takes unit u, player p returns integer
function MofidyUnitDetectedByPlayer takes unit u, player p, integer c returns nothing
function SetUnitVisiblePartiallyByPlayer takes unit u, player p, boolean visible returns nothing
function IsUnitVisiblePartiallyByPlayer takes unit u, player p returns boolean
function SetUnitSharedVisionForPlayer takes unit u, player p, boolean shared returns nothing
function IsUnitSharedVisionToPlayer takes unit u, player p returns boolean


How to get inside the memory?
Get memory editing program!
For a new like me Cheat Engine (CE) is good enough. If you're pro you can go with OllyDBG or IDAPro, w/e you prefer. Here and go I will stick with CE.

Here and follow I'll use my own code from DotA, since im used to it and it's easier to show.

This script contains basic trigger function with "-cc" chat event. Once typed, it displays selected unit's real address. It's done via
JASS:
    call echo(Int2Hex(ConvertHandle(u)))
line. What is it?
guide3.png


ConvertHandle - main thing, which turns any given handle into real address. Using this address you can locate all object-related data and much more.

Open CE, select in process list War3 and press Enter. Then add any address manually (im adding "0xff" right here):
guide1.png
guide2.png


Now select this new added line, press Ctrl+B to go into Memory editor, and then Ctrl+D to go into Dissect structure list. Then enter converted handle address:

Here's my own noted list of params, as you can see. Tons of data - links, flags, raw values etc
guide4.png


Also meet 0xC & 0x10 fields. It's not just random values but inner code of widget. It's used in replays as well, every action has it's own targets and users. Imagine it as X and Y of the object itself inside the game memory. You can craft proper address from it using -gs CODE1 and then -gs CODE2.

guide4.5.png


guide5.png


Now I will add ability A00S (channel, used for Hoof stomp) to unit, using my custom function:
guide6.png


This ability stands directly for this ability on this unit. It's independant from main class of ability, which is stored at AbilityData and AbilityUI addresses. Here you can as well see "unitData" and "unitUI" addresses - this function works with any proper ID. Note that unit's core data is always preloaded, while abilities are being loaded only when given to any unit. Until then those AbilityData and AbilityUI would return 0.

guide7.png


Here's link at main data of ability itself

guide8.png


Here you can see all it's parameters like in editor, thats, for instance, CD & MC

guide9.png


You can find much more objects inside the memory and more data as well. Some of it may be changed on runtime, some can't.

GitHub contains decoded Game.dll for v1.26 where you can find some offsets, as well as Cheat Tables which can be used to work with CE right now.

I'll write more articles about memory editing next days. Stay intouch and ask questions if you have one. You can speed it up for a bit using donations.
 
Last edited:

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
537
Very nice. Some real nuggets in there. But it desperately needs a cleanup
 
Level 5
Joined
Sep 6, 2010
Messages
91
Very good contribution Draco, I think you can really now have two versions of Dota in the War, one for 1.27 and the other for the upcoming patch by Blizzard. Hopefully the community will not be divided into two sectors, as I would much rather that this utility is used in later versions, so the maps that require large mechanisms, now these will be completed. Everything will be a boom if it could work by 70% in the next patch.
Draco good job.. :cool:
Greetings...
 
narrow minds cant stop the progress, especially with such vague arguments

For one this is too complicated, secondly it is dangerous because memory editing is often used to create cheats, viruses and hacks. Thirdly it goes against end user license agreement.

I never said it's bad, I just said that it needs to be neutralized. I appreciate the possibilities we could have with this. Don't take my words out of context.
 
Level 19
Joined
Dec 12, 2010
Messages
2,069
For one this is too complicated, secondly it is dangerous because memory editing is often used to create cheats, viruses and hacks. Thirdly it goes against end user license agreement.

I never said it's bad, I just said that it needs to be neutralized. I appreciate the possibilities we could have with this. Don't take my words out of context.
cjass complicated as well for those who never used C. Oh, how many viruses been created via Delphi, MS Builder and so on.. Goddamit how those things aren't banned yet? and yep, nobody cares about EULA, especially simple users.
 
cjass complicated as well for those who never used C. Oh, how many viruses been created via Delphi, MS Builder and so on.. Goddamit how those things aren't banned yet? and yep, nobody cares about EULA, especially simple users.

If I did learn C then I would probably be long gone from Warcraft 3 modding. The simplicity of features and world editor is what sustains the modding community. You have a lot to learn if you think that banning exists in Internet, there's no such thing as a ban in web. What you download is entirely up to you whether or not it's dangerous. Yeah, nobody cares about EULA as long as the authorities are not involved. Hive is not a hacking website, especially now since staff have direct communications with Blizzard Classic Games team who are in charge of supporting Warcraft 3. This issue will be resolved in future patches. Enjoy it while you can.
 

Deleted member 219079

D

Deleted member 219079

who ever needs future patches when they have omnipotent possibilities?
I already said that you need to offer an alternative map hosting platform to help MP map creators.
 

Deleted member 219079

D

Deleted member 219079

I'm not going to brainstorm it with you ... I don't want to support this first-hand.

ENT and MMH transfer to next patch for sure. Their bots are connected to official servers and ENT's to some unofficial too, ensuring some visibility for modders. They're free to use and very simple. That kind of service has required a lot of work.
 
Level 2
Joined
Jan 30, 2014
Messages
14
For one, secondly. Thirdly.
Bla, bla, bla. You're forgot that blizzard not making any good changes to real improve WC3 (since ...???...). People trying to extend wc3 mechanics to create more comfortable (for 2016...) play. For game which was totally released into free swimming by developer without any support. (note that: game have top rated positions (for all time) of blizzard games, they heave overboard their top game, #29 metacritic, #32 gamespot, game born in 2002, now is 2016)
For example: New interfaces/DX9 Support/additional or custom shaders, host bots, chat bots, delay reduction, 8MB mapsize bypass, tools for clipping mouse in window - all of them is third party tweaks/tools came to extend/improve user experience, but also conflicts with terms. And it is normal.
half-life-3-confirmed-btw_o_2694487.jpg
 
Last edited:
Level 5
Joined
Sep 6, 2010
Messages
91
Bla, bla, bla. You're forgot that blizzard not making any good changes to real improve WC3 (since ...???...). People trying to extend wc3 mechanics to create more comfortable (for 2016...) play. For game which was totally released into free swimming by developer without any support. (note that: game have top rated positions (for all time) of blizzard games, they heave overboard their top game, #29 metacritic, #32 gamespot, game born in 2002, now is 2016)
For example: New interfaces/DX9 Support/additional or custom shaders, host bots, chat bots, tools for clipping mouse in window is third party tools came to extend user experience, but also conflicts with terms. And it is normal.
half-life-3-confirmed-btw_o_2694487.jpg
Exactly, this game only needs a little push to improve its gameplay. And I do not say it for the fact of using hacks, but of the new functions that can be obtained using only the memory. But in my case it would only be using only the get but not use the sets, as it could be somewhat counterproductive to the community if it is exploited incorrectly. (Only as a suggestion, JassNewGen 2 might have a new tool to handle the new functions given by Draco in memory)
Greetings...
 
Level 19
Joined
Dec 12, 2010
Messages
2,069
This is some legit reverse engineering :)
The sad thing is that it would take a single programmer that still knows how Warcraft's source code looks about 10 minutes to add all of these setters/getters.
why is this sad part? there's 1000s of unexplored possibilities which weren't needed for dota yet might be useful for any other mapmaker. memory is completely freeway, meanwhile any kind of patch is strict short sideroad
 
Level 19
Joined
Dec 12, 2010
Messages
2,069
future patches can add new posibilities not available via memory hacks, memory hacks can only add getters and setters, you cant add new features to the game via it
lel what. only if you mean some kind of platform (blizz sucks at it tho), and yet we have custom game platforms. not to speak mem access is equal to full access which means you can extend it any direction, like with custom dll etcetc
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
yes and you have to rewrite the whole thing every time something changes, like they add new variable into the middle of the class.

You cant really add new code to the engine(you could execute a bit of assembly from the looks of it, but thats about it), so adding new features with this is very infeasible, hence impossible.
Blizz has all the source so they can add any new feature at any future patch as they please
 
Level 2
Joined
Jan 30, 2014
Messages
14
so adding new features with this is very infeasible
Not so hard.

they can add any new feature at any future patch
:D

Anyone except Draco is using any of things posted in 1st message? I mean any tryes to implement/made something work. To load custom dll, etc.

One of goals which can be obtained with this is ingame reloading terrain types. (without any modifications wc3 can only load 16 types and cannot reload them in one game). I mean now you can do some stuff to reload types ingame, which can be used for ingame commands like -winter/-summer/-jungle, making full restyle (including terrain types) of map (for example dota).
 
Last edited:
Level 19
Joined
Dec 12, 2010
Messages
2,069
Anyone except Draco is using any of things posted in 1st message? I mean any tryes to implement/made something work. To load custom dll, etc.

One of goals which can be obtained with this is ingame reloading terrain types. (without any modifications wc3 can only load 16 types and cannot reload them in one game). I mean now you can do some stuff to reload types ingame, which can be used for ingame commands like -winter/-summer/-jungle, making full restyle (including terrain types) of map (for example dota).
well you can't reload existing textures. game using cache for them heavily, its hard to find how and where its stored. we successfully injected our own textures over any thing which get loaded after script comes into play, but not before it
 
Level 29
Joined
Jul 29, 2007
Messages
5,174
The instructions are there if you want to add stuff (or eventually fix it if a patch comes out which would change the offsets).

I did not mean that having access is sad, I am actually quite the supporter of "give full access and let the user shoot his foot".
It's just that most of your functions are the simplest setters and getters that should have existed for years, and making them exist given the source code is probably a matter of 10 minutes :p
 
Level 19
Joined
Dec 12, 2010
Messages
2,069
The instructions are there if you want to add stuff (or eventually fix it if a patch comes out which would change the offsets).

I did not mean that having access is sad, I am actually quite the supporter of "give full access and let the user shoot his foot".
It's just that most of your functions are the simplest setters and getters that should have existed for years, and making them exist given the source code is probably a matter of 10 minutes :p
so I said back to 2008, yet nobody did that
 
Level 25
Joined
Feb 2, 2006
Messages
1,669
So all functions work in multiplayer? This is amazing but I have to agree with GhostWolf that it would have been better Blizzard simply added the natives or the possibility to add custom native with a given C++ API for certain mods.

Shouldn't this be possible with SharpCraft as well without using a JASS script, simply by adding natives in C# and wouldn't it work after the patch with SharpCraft as well except maybe some memory addresses may change? If you need some injection program

I would love to use your custom API for my mod but when the next patch fixes this I guess I can't :D

Damn Blizzard should simply release the source code!
 
+1 for Wc3 source release! :)

Need tell Blizzard, "Please upload WC3 source to Github" :D :D :D

Not gonna happen, Blizzard never released any of it's games source codes.. ever. That's a good thing because a lot of noobs won't have a chance make hundreds of crappy mods. If they ever release the source code it should be safely given to those who have superior knowledge and genuine vision.
 
Level 19
Joined
Dec 12, 2010
Messages
2,069
Not gonna happen, Blizzard never released any of it's games source codes.. ever. That's a good thing because a lot of noobs won't have a chance make hundreds of crappy mods. If they ever release the source code it should be safely given to those who have superior knowledge and genuine vision.
oh my god. wonder why there's so many narrow minded people at the most CREATIVE-based forum ever. map editor? nah, newbies will make shitty maps, over and over again. why does this forum exists then?
goddamn. im losing faith in wc3 modding community.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
its most likely actually impossible for them to release the source code, because they could be using some third party code which is licenced in such a way that it cannot be made open source(someone, I think DSG actually knows exactly what, I think it was the MPQ stuff)
 
  • Like
Reactions: pyf

Rui

Rui

Level 41
Joined
Jan 7, 2005
Messages
7,550
Damn Blizzard should simply release the source code!
+1 for Wc3 source release! :)
I wouldn't go as far as saying source code must be released (because they are obliged not to, see @edo494's post above), but they could certainly conscript volunteers from the community to help release an unofficial 2.0 major patch. We have people who are very capable. It is sad for us to have to suffer with bucolic problems because they won't make something as easy for them to do as the getters and setters in the API under proposal. The fact those modifications are possible is just proof that some things in the game were hardcoded as inaccessible for modders with no apparent reason. If they don't want to waste resources, just let volunteers pick this up.

Also, I sincerely hope that, if they fix this, they'll give us the ability to read and write to all or at least part of the game's memory, even if they block potentially dangerous I/O.
 

pyf

pyf

Level 32
Joined
Mar 21, 2016
Messages
2,985
Not gonna happen, Blizzard never released any of it's games source codes.. ever. That's a good thing because a lot of noobs won't have a chance make hundreds of crappy mods. [...]
You probably mean new game engines / ports / forks?

its most likely actually impossible for them to release the source code, because they could be using some third party code which is licenced in such a way that it cannot be made open source(someone, I think DSG actually knows exactly what, I think it was the MPQ stuff)
Reminds me of Jedi Outcast's source code withdrawal, only a few days after release:
Star Wars Jedi Knight II: Jedi Outcast - Wikipedia

I point out, Warcraft 3 can use the Miles Sound System, which is developed by RAD Game Tools too. Even with the latest patch, the Miles version used by WC3 was not updated (code is still from 2002!). It may or may not explain the MIDI issue with ambient sound, which is mentioned in the patch release notes.
 

pyf

pyf

Level 32
Joined
Mar 21, 2016
Messages
2,985
For Jedi Outcast and Jedi Academy, there is indeed OpenJK, which is a fork of Raven Software's original source code release.

For Jedi Knight / Mysteries of the Sith, there are unofficial fan-made patches (=hacked exe and dll files). They notably remove some of the game's original limits, and also add new possibilities to the engine for modders / programers:
JK Hub - [Project: Jedi Knight 2013 Patch (JK13)]
JK Hub - [Project: Unofficial Patches]

It is rumored LucasArts lost the Jedi Knight source code! Therefore it makes sense here, the JK community took things into their own hands; because this code can not be made available anymore.


A famous example of third-party copyrighted code in a video game, hindering (somewhat) an open-source release, is the DMX sound library used in the Dos version of Doom. Because of it, only the source code to the Linux port was released in 1997.

I believe id Software decided to develop everything in-house, precisely because of various outstanding problems (*cough cough*) involving DMX.

This is the reason I also believe, Blizzard will never conscript volunteers from the community to help release an unofficial 2.0 major patch. Sorry @Rui, but from a corporate perspective, third-parties can really be trouble sometimes.
 
Last edited:

pyf

pyf

Level 32
Joined
Mar 21, 2016
Messages
2,985
I was unaware of this. Thanks for pointing out.
Amazing move by JoWooD, btw.

Quoting Wikipedia (with bold added for readability):
"After a release with many problems and bugs, a dispute between the publisher and developer [of Gothic 3] lead to the separation of them in 2007. The game remained with the last released patch 1.12 in a buggy and unfinished state, and an announced further patch and editor were not finished. [...] Therefore, the copyright holding publisher JoWooD granted access to the source code to developers from the game community to allow the fans at least take care of the significant problems and bugs themselves. In years of voluntary and unpaid work the fan community produced several community patches, with an actual iteration version 1.75 released on April 2012. With this 1.5 GB sized patch significant enhancements and fixes were introduced, so that finally a playable state of the game was achieved. Also, a "Community Story Project" still works on fixing inconsistencies in former Gothic games and on filling story gaps. In 2014 an additional patch and a data optimizer for the 1.75.14 version became available fixing some of the remaining issues.

[...] On November 21, 2008 JoWooD Entertainment released a standalone expansion entitled Gothic 3: Forsaken Gods, developed by Trine Games. Gothic 3: Forsaken Gods was similar buggy as the original game and was later fixed in an Enhanced Edition by Mad Vulture Games, a company which was created by developers from the game community."
 
Last edited:
Top