Добавлен , опубликован

Актуальная версия v1.0.5a

Описание

Теперь можно редактировать стандартный интерфейс Варкрафта без необходимости внедрять сторонние библиотеки.
Требования:

Код

Memory Hack

Typecast
native MergeUnits	takes integer qty, integer a, integer b, integer make returns boolean
native ConvertUnits takes integer qty, integer id returns boolean
native IgnoredUnits takes integer unitid returns integer

library Typecast
//! nocjass
    globals
        code Code //This is not used, it's here just to fool Jasshelper
        code l__Code
        integer Int //This is not used, it's here just to fool Jasshelper
        integer l__Int
        string Str //This is not used, it's here just to fool Jasshelper
        string l__Str
        boolean Bool //This is not used, it's here just to fool Jasshelper
        boolean l__Bool
        trigger Trig //This is not used, it's here just to fool Jasshelper
        trigger l__Trig
        
        integer Array
        integer array l__Array
        integer bytecode
        integer array l__bytecode
        integer array Memory
        integer bytecodedata //used to pass data between regular code and bytecode
    endglobals

    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 Array //typecast Array to integer
    endfunction

    //# +nosemanticerror
    function GetArrayAddress takes nothing returns integer //not really needed
        return l__Array
        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 //Prevents Jasshelper from inlining this function
    endfunction
    
    function setTrig takes trigger t returns nothing
        set l__Trig = t
        return //Prevents Jasshelper from inlining this function
    endfunction

    private function Typecast1 takes nothing returns nothing
        local integer Code //Jasshelper will implicitly rename this to l__Code
        local code Int     //Jasshelper will implicitly rename this to l__Int
    endfunction

    //# +nosemanticerror
    function C2I takes code c returns integer
        call setCode(c)
        return l__Code
    endfunction

    //# +nosemanticerror
    function I2C takes integer i returns code
        call setInt(i)
        return l__Int
    endfunction

    private function Typecast2 takes nothing returns nothing
        local integer Str //Jasshelper will implicitly rename this to l__Str
        local string Int   //Jasshelper will implicitly rename this to l__Int
    endfunction

    //# +nosemanticerror
    function SH2I takes string s returns integer
        call setStr(s)
        return l__Str
    endfunction

    //# +nosemanticerror
    function I2SH takes integer i returns string
        call setInt(i)
        return l__Int
    endfunction

    private function Typecast3 takes nothing returns nothing
        local integer Bool //Jasshelper will implicitly rename this to l__Bool
        local boolean Int  //Jasshelper will implicitly rename this to l__Int
    endfunction

    //# +nosemanticerror
    function B2I takes boolean b returns integer
        call setBool(b)
        return l__Bool
    endfunction

    //# +nosemanticerror
    function I2B takes integer i returns boolean
        call setInt(i)
        return l__Int
    endfunction
    
    private function Typecast4 takes nothing returns nothing
        local integer Trig //Jasshelper will implicitly rename this to l__Trig
        local trigger Int  //Jasshelper will implicitly rename this to l__Int
    endfunction
    
    //# +nosemanticerror
    function T2I takes trigger t returns integer
        call setTrig(t)
        return l__Trig
    endfunction
    
    //# +nosemanticerror
    function I2T takes integer i returns trigger
        call setInt(i)
        return l__Int
    endfunction

    
    //# +nosemanticerror
    function realToIndex takes real r returns integer
        return r
    endfunction

    function cleanInt takes integer i returns integer
        return i
    endfunction

    //# +nosemanticerror
    function indexToReal takes integer i returns real
        return i
    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

    
    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 udg_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 udg_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 bytecode
    endfunction

    //# +nosemanticerror
    function GetBytecodeAddress takes nothing returns integer
        return l__bytecode
        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

    //# +nosemanticerror
    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)))
        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 (crashes while map saving)
    endfunction
    
    function WriteRealMemory takes integer addr, integer val returns nothing
        if (addr/4*4 != addr) then
            call BJDebugMsg("WriteMemory WARNING! : " + I2S(addr))
            //call WriteRealMemory_FIX(addr,val)
        else 
            set Memory[addr/4] = val
        endif
    endfunction

    function ReadRealMemory takes integer addr returns integer
        if (addr/4*4 != addr) then
            call BJDebugMsg("ReadMemory WARNING! : " + I2S(addr))
            //return ReadRealMemory_FIX(addr)
        endif
        return Memory[addr/4]
    endfunction
//! endnocjass
endlibrary
MemoryHack
library Memory initializer Init uses Typecast

    globals
        integer address_GameBase
        integer address_GameState
        
        integer array RJassNativesBuffer
        integer RJassNativesBufferSize = 0
        
        integer address_VirtualAlloc = 0
        integer address_JassEnvironment = 0
        integer address_IgnoredUnits = 0
        integer address_IgnoredUnitsOffset = 0
        integer address_MergeUnits = 0
        integer address_MergeUnitsOffset = 0
    endglobals

    
    function GetJassContext takes integer id returns integer
        return Memory[Memory[Memory[Memory[address_JassEnvironment]/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 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 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 CreateJassNativeHook takes integer oldaddress, integer newaddress returns integer
        local integer FirstAddress = ReadRealPointer2LVL(address_JassEnvironment*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)
                    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)
                
                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

    
    private function Init takes nothing returns nothing
        local integer i = 0
        local integer bytecodeAddress = 0
        call ForForce(bj_FORCE_PLAYER[0], I2C(8 + C2I(function UnlockMemory)))
        set bytecodeAddress = GetBytecodeAddress()
        set i = Memory[bytecodeAddress/4]
        set i = i - Memory[i/4]
        
        if i == 5205600 then // 1.26a
            set address_GameBase = ReadRealMemory(bytecodeAddress) - 0x951060
            set address_GameState = (address_GameBase + 0xAB65F4) / 4
            set address_JassEnvironment = (address_GameBase + 0xADA848) / 4
            set address_VirtualAlloc = (address_GameBase + 0x86D0F4) / 4
            set address_MergeUnits = address_GameBase + 0x2DD320
            set address_IgnoredUnits = address_GameBase + 0x2DCE80
        else
            call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, "Unsupported version!")
        endif
    endfunction

endlibrary
FpCall
library FpCall initializer Init uses Memory

    globals
        //integer pReservedExecutableMemory0 = 0
        integer pReservedExecutableMemory = 0
    endglobals

    
    function fast_call1 takes integer pFuncFastcallAddr, integer arg1 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0xB9F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg1)
        call WriteRealMemory(pReservedExecutableMemory+8, 0xBEF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+16, 0xC35ED6FF)
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call takes integer pFuncFastcallAddr returns integer 
        return fast_call1(pFuncFastcallAddr, 0)
    endfunction

    function fast_call2 takes integer pFuncFastcallAddr, integer arg1, integer arg2 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0xBAF68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg2)
        call WriteRealMemory(pReservedExecutableMemory+8, 0xB9F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg1)
        call WriteRealMemory(pReservedExecutableMemory+16, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+20, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+24, 0xC35ED6FF)
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call3 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg3)
        call WriteRealMemory(pReservedExecutableMemory+8, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg2)
        call WriteRealMemory(pReservedExecutableMemory+16, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+20, arg1)
        call WriteRealMemory(pReservedExecutableMemory+24, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+28, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+32, 0xC35ED6FF)
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call4 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg4)
        call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg3)
        call WriteRealMemory(pReservedExecutableMemory+16, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+20, arg2)
        call WriteRealMemory(pReservedExecutableMemory+24, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+28, arg1)
        call WriteRealMemory(pReservedExecutableMemory+32, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+36, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+40, 0xC35ED6FF)
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call5 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg5)
        call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg4)
        call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+20, arg3)
        call WriteRealMemory(pReservedExecutableMemory+24, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+28, arg2)
        call WriteRealMemory(pReservedExecutableMemory+32, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+36, arg1)
        call WriteRealMemory(pReservedExecutableMemory+40, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+44, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+48, 0xC35ED6FF)
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call6 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg6)
        call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg5)
        call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+20, arg4)
        call WriteRealMemory(pReservedExecutableMemory+24, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+28, arg3)
        call WriteRealMemory(pReservedExecutableMemory+32, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+36, arg2)
        call WriteRealMemory(pReservedExecutableMemory+40, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+44, arg1)
        call WriteRealMemory(pReservedExecutableMemory+48, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+52, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+56, 0xC35ED6FF)
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call7 takes integer pFuncFastcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5, integer arg6, integer arg7 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg7)
        call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg6)
        call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+20, arg5)
        call WriteRealMemory(pReservedExecutableMemory+24, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+28, arg4)
        call WriteRealMemory(pReservedExecutableMemory+32, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+36, arg3)
        call WriteRealMemory(pReservedExecutableMemory+40, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+44, arg2)
        call WriteRealMemory(pReservedExecutableMemory+48, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+52, arg1)
        call WriteRealMemory(pReservedExecutableMemory+56, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+60, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+64, 0xC35ED6FF)
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function fast_call8 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(pReservedExecutableMemory, 0x68F68B56) 
        call WriteRealMemory(pReservedExecutableMemory+4, arg8)
        call WriteRealMemory(pReservedExecutableMemory+8, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+12, arg7)
        call WriteRealMemory(pReservedExecutableMemory+16, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+20, arg6)
        call WriteRealMemory(pReservedExecutableMemory+24, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+28, arg5)
        call WriteRealMemory(pReservedExecutableMemory+32, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+36, arg4)
        call WriteRealMemory(pReservedExecutableMemory+40, 0x68F68B90) 
        call WriteRealMemory(pReservedExecutableMemory+44, arg3)
        call WriteRealMemory(pReservedExecutableMemory+48, 0xBAF68B90) 
        call WriteRealMemory(pReservedExecutableMemory+52, arg2)
        call WriteRealMemory(pReservedExecutableMemory+56, 0xB9F68B90)
        call WriteRealMemory(pReservedExecutableMemory+60, arg1)
        call WriteRealMemory(pReservedExecutableMemory+64, 0xBEF68B90)
        call WriteRealMemory(pReservedExecutableMemory+68, pFuncFastcallAddr)
        call WriteRealMemory(pReservedExecutableMemory+72, 0xC35ED6FF)
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset, pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction

    
    function this_call1 takes integer pFuncThiscallAddr, integer arg1 returns integer 
        return fast_call2(pFuncThiscallAddr, arg1, 0)
    endfunction
    
    function this_call2 takes integer pFuncThiscallAddr, integer arg1, integer arg2 returns integer 
        return fast_call3(pFuncThiscallAddr, arg1, 0, arg2)
    endfunction
    
    function this_call3 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3 returns integer 
        return fast_call4(pFuncThiscallAddr, arg1, 0, arg2, arg3)
    endfunction
    
    function this_call4 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4 returns integer 
        return fast_call5(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4)
    endfunction
    
    function this_call5 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5 returns integer 
        return fast_call6(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4, arg5)
    endfunction
    
    function this_call6 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5, integer arg6 returns integer 
        return fast_call7(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4, arg5, arg6)
    endfunction
    
    function this_call7 takes integer pFuncThiscallAddr, integer arg1, integer arg2, integer arg3, integer arg4, integer arg5, integer arg6, integer arg7 returns integer 
        return fast_call8(pFuncThiscallAddr, arg1, 0, arg2, arg3, arg4, arg5, arg6, arg7)
    endfunction


    function std_call1 takes integer pFuncStdcallAddr, integer arg1 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+8, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+12, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+16, 0xC359D1FF) // call ecx, pop ecx, ret
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function std_call takes integer pFuncStdcallAddr returns integer
        return std_call1(pFuncStdcallAddr, 0)
    endfunction
    
    function std_call2 takes integer pFuncStdcallAddr, integer arg1, integer arg2 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+16, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+20, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+24, 0xC359D1FF) // call ecx, pop ecx, ret
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function std_call3 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+24, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+28, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+32, 0xC359D1FF) // call ecx, pop ecx, ret
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function std_call4 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+32, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+36, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+40, 0xC359D1FF) // call ecx, pop ecx, ret
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function std_call5 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer 
        local integer pOffset1
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg5) // push arg5
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+36, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+40, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+44, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+48, 0xC359D1FF) // call ecx, pop ecx, ret
        
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function std_call6 takes integer pFuncStdcallAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 , integer arg6 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg6) // push arg6
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg5) // push arg5
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+36, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+40, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+44, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+48, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+52, pFuncStdcallAddr) // mov ecx, pFuncStdcallAddr
        call WriteRealMemory(pReservedExecutableMemory+56, 0xC359D1FF) // call ecx, pop ecx, ret
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    
    function c_call1 takes integer pFuncCdeclAddr, integer arg1 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+8, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+12, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+16, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+20, 0xCCC35904) // 4, pop ecx, ret
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function c_call2 takes integer pFuncCdeclAddr, integer arg1, integer arg2 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+16, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+20, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+24, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+28, 0xCCC35908) // 4, pop ecx, ret
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function c_call3 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+24, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+28, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+32, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+36, 0xCCC3590C) // 4, pop ecx, ret
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function c_call4 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+32, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+36, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+40, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+44, 0xCCC35910) // 4, pop ecx, ret
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function c_call5 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg5) // push arg5
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+36, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+40, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+44, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+48, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+52, 0xCCC35914) // 4, pop ecx, ret
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    function c_call6 takes integer pFuncCdeclAddr, integer arg1, integer arg2, integer arg3 , integer arg4, integer arg5 , integer arg6 returns integer 
        local integer pOffset1
        
        call WriteRealMemory(pReservedExecutableMemory, 0x68C98B51) // push ecx. mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+4, arg6) // push arg6
        call WriteRealMemory(pReservedExecutableMemory+8, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+12, arg5) // push arg5
        call WriteRealMemory(pReservedExecutableMemory+16, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+20, arg4) // push arg4
        call WriteRealMemory(pReservedExecutableMemory+24, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+28, arg3) // push arg3
        call WriteRealMemory(pReservedExecutableMemory+32, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+36, arg2) // push arg2
        call WriteRealMemory(pReservedExecutableMemory+40, 0x6890C98B) //  mov ecx,ecx
        call WriteRealMemory(pReservedExecutableMemory+44, arg1) // push arg1
        call WriteRealMemory(pReservedExecutableMemory+48, 0xB990C98B) // mov ecx,ecx , nop
        call WriteRealMemory(pReservedExecutableMemory+52, pFuncCdeclAddr) // mov ecx, pFuncCdeclAddr
        call WriteRealMemory(pReservedExecutableMemory+56, 0xC483D1FF) // call ecx, add esp, 
        call WriteRealMemory(pReservedExecutableMemory+60, 0xCCC35918) // 4, pop ecx, ret
        
        if address_IgnoredUnitsOffset == 0 then 
            set address_IgnoredUnitsOffset = CreateJassNativeHook(address_IgnoredUnits, pReservedExecutableMemory )
        else
            call WriteRealMemory(address_IgnoredUnitsOffset,pReservedExecutableMemory)
        endif
        
        set pOffset1 = IgnoredUnits(0)
        call WriteRealMemory(address_IgnoredUnitsOffset, address_IgnoredUnits)
        return pOffset1
    endfunction
    
    
    function AllocateExecutableMemory takes integer size returns integer
        local integer retval = 0
        if address_VirtualAlloc != 0 then 
            if pReservedExecutableMemory == 0 then 
                if address_MergeUnitsOffset == 0 then
                    set address_MergeUnitsOffset = CreateJassNativeHook(address_MergeUnits, Memory[address_VirtualAlloc] )
                else
                    call WriteRealMemory(address_MergeUnitsOffset, Memory[address_VirtualAlloc])
                endif
                set retval = B2I(MergeUnits(0, size+4, 0x3000, 0x40))
                call WriteRealMemory(address_MergeUnitsOffset, address_MergeUnits)
                return retval
            else 
                set retval = std_call4(Memory[address_VirtualAlloc], 0, size+4, 0x3000, 0x40)
            endif 
            
        endif
        
        if (retval == 0) then 
            return 0
        endif
        
        return (retval + 4) / 4 * 4
    endfunction
    
    
    private function Init takes nothing returns nothing
        //set pReservedExecutableMemory0 = AllocateExecutableMemory(1000)
        set pReservedExecutableMemory = AllocateExecutableMemory(1000)
    endfunction

endlibrary
Utils
library Utils initializer Init uses Memory, FpCall

    globals
        integer address_ConvertString = 0
        integer address_GameClass2 = 0
    endglobals

    
    function Message takes string msg returns nothing
        call DisplayTextToPlayer(GetLocalPlayer(), 0.0, 0.0, msg)
    endfunction
    
    function ConvertNullTerminatedStringToString takes integer pNullTerminatedString returns string
        return I2SH(this_call1(address_ConvertString, pNullTerminatedString))
    endfunction
    
    function GetMouseEnv takes nothing returns integer
        return Memory[Memory[address_GameClass2]/4 + 0x3BC/4] + 0x310
    endfunction

    function GetMouseTerrainX takes nothing returns real
        return GetRealFromMemory(Memory[GetMouseEnv()/4 + 0])
    endfunction

    function GetMouseTerrainY takes nothing returns real
        return GetRealFromMemory(Memory[GetMouseEnv()/4 + 1])
    endfunction

    function GetMouseTerrainZ takes nothing returns real
        return GetRealFromMemory(Memory[GetMouseEnv()/4 + 2])
    endfunction

    
    private function Init takes nothing returns nothing
        set address_ConvertString = address_GameBase + 0x3BAA20
        set address_GameClass2 = (address_GameBase + 0xAB4F80) / 4
    endfunction
    
endlibrary

Systems

Interface
library Interface initializer Init uses FpCall, Utils

    globals
        constant integer ANCHOR_TOPLEFT = 0
        constant integer ANCHOR_TOP = 1
        constant integer ANCHOR_TOPRIGHT = 2
        constant integer ANCHOR_LEFT = 3
        constant integer ANCHOR_CENTER = 4
        constant integer ANCHOR_RIGHT = 5
        constant integer ANCHOR_BOTTOMLEFT = 6
        constant integer ANCHOR_BOTTOM = 7
        constant integer ANCHOR_BOTTOMRIGHT = 8
        
        constant integer FRAME_WorldFrameWar3 = 239
        constant integer FRAME_Minimap = 240
        constant integer FRAME_InfoBar = 241
        constant integer FRAME_CommandBar = 242
        constant integer FRAME_ResourceBarFrame = 243
        constant integer FRAME_UpperButtonBarFrame = 244
        constant integer FRAME_Unknown1 = 245 // ?
        constant integer FRAME_ClickableBlock = 246
        constant integer FRAME_HeroBar = 247
        constant integer FRAME_PeonBar = 248
        constant integer FRAME_Message = 249
        constant integer FRAME_UnitMessage = 250
        constant integer FRAME_ChatMessage = 251
        constant integer FRAME_TopMessage = 252
        constant integer FRAME_Portrait = 253
        constant integer FRAME_TimeOfDayIndicator = 254
        constant integer FRAME_ChatEditBar = 255
        constant integer FRAME_CinematicPanel = 256
        constant integer FRAME_Unknown2 = 257 // ?
        constant integer FRAME_MinimapButton1 = 258
        constant integer FRAME_MinimapButton2 = 259
        constant integer FRAME_MinimapButton3 = 260
        constant integer FRAME_MinimapButton4 = 261
        constant integer FRAME_MinimapButton5 = 262
        constant integer FRAME_FrameB = 263
        constant integer FRAME_MouseBorders = 264
        constant integer FRAME_FrameA = 265
        constant integer FRAME_SimpleConsole = 266
    
        integer address_GetGameUI = 0
        integer address_SetFramePoint = 0
        integer address_SetFramePoint2 = 0
        integer address_SetFrameWidth = 0
        integer address_SetFrameHeight = 0
        integer address_GetFrameTextAddress = 0
        integer address_GetFrameItemAddress = 0
        integer address_GetFrameSkinAddress = 0
        integer address_UpdateFrameText = 0
        
        integer pTooltipFrame = 0
        
        integer pGameUI = 0
    endglobals
    
    // =================================================
    
    function GetGameUI takes integer a1, integer a2 returns integer
        return fast_call2(address_GetGameUI, a1, a2)
    endfunction
    
    function ReadGameUIStruct takes integer element returns integer
        return Memory[pGameUI/4 + element]
    endfunction
    
    function GetRootFrame takes nothing returns integer
        return pGameUI + 180
    endfunction
    
    function SetFramePoint takes integer pFrame, integer point, integer pParentFrame, integer relativePoint, real offsetX, real offsetY returns nothing
        call this_call7(address_SetFramePoint, pFrame, point, pParentFrame, relativePoint, SetRealIntoMemory(offsetX), SetRealIntoMemory(offsetY), 1)
    endfunction
    
    function SetFramePoint2 takes integer pFrame, integer point, real offsetX, real offsetY returns nothing
        call this_call5(address_SetFramePoint2, pFrame, point, SetRealIntoMemory(offsetX), SetRealIntoMemory(offsetY), 1)
    endfunction
    
    function SetFrameWidth takes integer pFrame, real width returns nothing
        call this_call2(address_SetFrameWidth, pFrame, SetRealIntoMemory(width))
    endfunction
    
    function SetFrameHeight takes integer pFrame, real height returns nothing
        call this_call2(address_SetFrameHeight, pFrame, SetRealIntoMemory(height))
    endfunction
    
    function GetFrameWidth takes integer pFrame returns real
        return GetRealFromMemory(Memory[pFrame/4 + 22])
    endfunction
    
    function GetFrameHeight takes integer pFrame returns real
        return GetRealFromMemory(Memory[pFrame/4 + 23])
    endfunction
    
    function GetFramePointParent takes integer pFrame, integer point returns integer
        return Memory[Memory[pFrame/4 + point + 2]/4 + 1]
    endfunction
    
    function GetFramePointRelativePoint takes integer pFrame, integer point returns integer
        return Memory[Memory[pFrame/4 + point + 2]/4 + 2]
    endfunction
    
    function GetFramePointX takes integer pFrame, integer point returns real
        return GetRealFromMemory(Memory[Memory[pFrame/4 + point + 2]/4 + 3])
    endfunction
    
    function GetFramePointY takes integer pFrame, integer point returns real
        return GetRealFromMemory(Memory[Memory[pFrame/4 + point + 2]/4 + 4])
    endfunction
    
    function GetFrameTextAddress takes string name, integer id returns integer
        return fast_call2(address_GetFrameTextAddress, GetStringAddress(name), id)
    endfunction
    
    function GetFrameItemAddress takes string name, integer id returns integer
        return fast_call2(address_GetFrameItemAddress, GetStringAddress(name), id)
    endfunction

    function GetFrameSkinAddress takes string name, integer id returns integer
        return fast_call2(address_GetFrameSkinAddress, GetStringAddress(name), id)
    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 SetFrameTextAddress takes integer addr, string str returns nothing
        call this_call2(address_UpdateFrameText, addr, GetStringAddress(str))
    endfunction

    // =================================================
    
    function GetPanelButton takes integer pFrame, integer row, integer column returns integer
        return Memory[Memory[4 * row + Memory[pFrame/4 + 85]/4 + 2]/4 + column]
    endfunction
    
    function GetMinimapButton takes integer id returns integer // id = [0; 4]
        return ReadGameUIStruct(FRAME_MinimapButton1 + id)
    endfunction

    function GetUpperButtonBarButton takes integer id returns integer // id = [0; 3]
        local integer pUpperButtonBar = ReadGameUIStruct(FRAME_UpperButtonBarFrame)
        if (id == 0) then
            return Memory[pUpperButtonBar/4 + 78]
        elseif (id == 1) then
            return Memory[pUpperButtonBar/4 + 76]
        elseif (id == 2) then
            return Memory[pUpperButtonBar/4 + 77]
        elseif (id == 3) then
            return Memory[pUpperButtonBar/4 + 88]
        endif
        return 0
    endfunction
    
    function GetCommandBarButton takes integer row, integer column returns integer // row = [0; 2]  column = [0; 3]
        local integer pCommandBar = ReadGameUIStruct(FRAME_CommandBar)
        return GetPanelButton(pCommandBar, row, column)
    endfunction

    function GetItemBarButton takes integer id returns integer // id = [0; 5]
        local integer pInfoBar = ReadGameUIStruct(FRAME_InfoBar)
        local integer pItemBar = Memory[pInfoBar/4 + 82]
        return Memory[Memory[pItemBar/4 + 76]/4 + 2 * id + 1]
    endfunction
    
    function GetHeroBarButton takes integer id returns integer // id = [0; 6]
        local integer pHeroBar = ReadGameUIStruct(FRAME_HeroBar)
        return GetPanelButton(pHeroBar, id, 0)
    endfunction
    
    // =================================================
    
    function HideInterface takes nothing returns nothing
        local integer pRootFrame = GetRootFrame()

        call SetFramePoint(ReadGameUIStruct(FRAME_UpperButtonBarFrame), ANCHOR_TOPLEFT, pRootFrame, ANCHOR_TOPLEFT, 0.0, 1.0)
        call SetFramePoint(ReadGameUIStruct(FRAME_ResourceBarFrame), ANCHOR_TOPRIGHT, pRootFrame, ANCHOR_TOPRIGHT, 0.0, 1.0)

        call SetFramePoint(ReadGameUIStruct(FRAME_SimpleConsole), ANCHOR_TOPLEFT, pRootFrame, ANCHOR_TOPLEFT, 10.0, 0.0)
        call SetFramePoint(ReadGameUIStruct(FRAME_SimpleConsole), ANCHOR_TOPRIGHT, pRootFrame, ANCHOR_TOPRIGHT, -10.0, 0.0)

        call SetFramePoint(ReadGameUIStruct(FRAME_Portrait) + 180, ANCHOR_BOTTOMLEFT, pRootFrame, ANCHOR_BOTTOMLEFT, 1.0, 1.0)
        call SetFramePoint(ReadGameUIStruct(FRAME_Minimap) + 180, ANCHOR_BOTTOMLEFT, pRootFrame, ANCHOR_BOTTOMLEFT, 1.0, 1.0)

        call SetFramePoint(ReadGameUIStruct(FRAME_PeonBar), ANCHOR_BOTTOMLEFT, pRootFrame, ANCHOR_BOTTOMLEFT, 1.0, 1.0)
        call SetFramePoint(ReadGameUIStruct(FRAME_HeroBar), ANCHOR_TOPLEFT, pRootFrame, ANCHOR_TOPLEFT, 0.0, 1.0)

        call SetFramePoint(ReadGameUIStruct(FRAME_TimeOfDayIndicator) + 180, ANCHOR_BOTTOMLEFT, pRootFrame, ANCHOR_BOTTOMLEFT, 1.0, 1.0)
        call SetFramePoint(Memory[ReadGameUIStruct(FRAME_TimeOfDayIndicator)/4 + 108] + 180, ANCHOR_TOP, pRootFrame, ANCHOR_TOP, 1.0, 0.0) // TimeOfDayIndicator UBERTIP

        call SetFramePoint(Memory[ReadGameUIStruct(FRAME_InfoBar)/4 + 83], ANCHOR_BOTTOMRIGHT, pRootFrame, ANCHOR_TOPLEFT, 1.0, 0.0) // ConsoleInventoryCoverTexture
    endfunction

    function EditBlackBorders takes real upperHeight, real bottomHeight returns nothing
        local integer pWorldFrameWar3 = ReadGameUIStruct(FRAME_WorldFrameWar3) + 180
        local integer pRootFrame = GetRootFrame()

        call SetFramePoint(pWorldFrameWar3, ANCHOR_TOPRIGHT, pRootFrame, ANCHOR_TOPRIGHT, 0.0, -upperHeight)
        call SetFramePoint(pWorldFrameWar3, ANCHOR_BOTTOMLEFT, pRootFrame, ANCHOR_BOTTOMLEFT, 0.0, bottomHeight)
    endfunction
    
    function EditPortrait takes integer anchor, real offsetX, real offsetY, real width, real height returns nothing
        local integer pPortraitFrame = ReadGameUIStruct(FRAME_Portrait) + 180
        local integer pRootFrame = GetRootFrame()
        
        if (width >= 0) then
            call SetFrameWidth(pPortraitFrame, width)
        endif
        if (height >= 0) then
            call SetFrameHeight(pPortraitFrame, height)
        endif
        call SetFramePoint(pPortraitFrame, ANCHOR_BOTTOMLEFT, pRootFrame, anchor, offsetX, -(offsetY + GetFrameHeight(pPortraitFrame)))
    endfunction
    
    function EditMinimap takes integer anchor, real offsetX, real offsetY, real width, real height returns nothing
        local integer pMinimapFrame = ReadGameUIStruct(FRAME_Minimap) + 180
        local integer pRootFrame = GetRootFrame()

        call SetFramePoint(pMinimapFrame, ANCHOR_BOTTOMLEFT, pRootFrame, anchor, offsetX, -(offsetY + height))
        call SetFramePoint(pMinimapFrame, ANCHOR_TOPRIGHT, pRootFrame, anchor, offsetX + width, -offsetY)
    endfunction
    
    function EditCommandBarButton takes integer row, integer column, integer anchor, real offsetX, real offsetY, real width, real height returns nothing
        local integer pButtonFrame = GetCommandBarButton(row, column)
        local integer pRootFrame = GetRootFrame()
        
        if (width >= 0) then
            call SetFrameWidth(pButtonFrame, width)
            //call SetFrameWidth(Memory[pButtonFrame/4 + 82], width)
        endif
        if (height >= 0) then
            call SetFrameHeight(pButtonFrame, height)
        endif
        call SetFramePoint(pButtonFrame, ANCHOR_TOPLEFT, pRootFrame, anchor, offsetX, -offsetY)
    endfunction
    
    function EditItemBarButton takes integer buttonId, integer anchor, real offsetX, real offsetY, real width, real height returns nothing
        local integer pButtonFrame = GetItemBarButton(buttonId)
        local integer pRootFrame = GetRootFrame()
        
        if (width >= 0) then
            call SetFrameWidth(pButtonFrame, width)
        endif
        if (height >= 0) then
            call SetFrameHeight(pButtonFrame, height)
        endif
        call SetFramePoint(pButtonFrame, ANCHOR_TOPLEFT, pRootFrame, anchor, offsetX, -offsetY)
    endfunction
    
    function EditMinimapButton takes integer buttonId, integer anchor, real offsetX, real offsetY, real width, real height returns nothing
        local integer pButtonFrame = GetMinimapButton(buttonId)
        local integer pRootFrame = GetRootFrame()
        
        if (width >= 0) then
            call SetFrameWidth(pButtonFrame, width)
        endif
        if (height >= 0) then
            call SetFrameHeight(pButtonFrame, height)
        endif
        call SetFramePoint(pButtonFrame, ANCHOR_TOPLEFT, pRootFrame, anchor, offsetX, -offsetY)
    endfunction
    
    function EditUpperButtonBarButton takes integer buttonId, integer anchor, real offsetX, real offsetY, real width, real height returns nothing
        local integer pButtonFrame = GetUpperButtonBarButton(buttonId)
        local integer pRootFrame = GetRootFrame()
        
        if (width >= 0) then
            call SetFrameWidth(pButtonFrame, width)
        endif
        if (height >= 0) then
            call SetFrameHeight(pButtonFrame, height)
        endif
        
        if (buttonId == 0) then
            call SetFramePoint(pButtonFrame, ANCHOR_TOPLEFT, pRootFrame, anchor, offsetX, -offsetY)
        else
            call SetFramePoint(pButtonFrame, ANCHOR_LEFT, pRootFrame, anchor, offsetX, -(offsetY + GetFrameHeight(pButtonFrame)/2))
        endif
    endfunction
    
    function EditHeroBarButton takes integer buttonId, integer anchor, real offsetX, real offsetY, real width, real height returns nothing
        local integer pButtonFrame = GetHeroBarButton(buttonId)
        local integer pRootFrame = GetRootFrame()
        
        if (width >= 0) then
            call SetFrameWidth(pButtonFrame, width)
        endif
        if (height >= 0) then
            call SetFrameHeight(pButtonFrame, height)
        endif
        call SetFramePoint(pButtonFrame, ANCHOR_TOPLEFT, pRootFrame, anchor, offsetX, -offsetY)
    endfunction
    
    function EditHeroBarHealthBar takes integer buttonId, integer anchor, real offsetX, real offsetY, real width, real height returns nothing
        local integer pHealthFrame = Memory[GetHeroBarButton(buttonId)/4 + 115]
        local integer pRootFrame = GetRootFrame()
        
        if (width >= 0) then
            call SetFrameWidth(pHealthFrame, width)
        endif
        if (height >= 0) then
            call SetFrameHeight(pHealthFrame, height)
        endif
        call SetFramePoint(pHealthFrame, ANCHOR_TOP, pRootFrame, anchor, offsetX + GetFrameWidth(pHealthFrame)/2, -offsetY)
    endfunction
    
    function EditHeroBarManaBar takes integer buttonId, integer anchor, real offsetX, real offsetY, real width, real height returns nothing
        local integer pManaFrame = Memory[GetHeroBarButton(buttonId)/4 + 116]
        local integer pRootFrame = GetRootFrame()
        
        if (width >= 0) then
            call SetFrameWidth(pManaFrame, width)
        endif
        if (height >= 0) then
            call SetFrameHeight(pManaFrame, height)
        endif
        call SetFramePoint(pManaFrame, ANCHOR_TOP, pRootFrame, anchor, offsetX + GetFrameWidth(pManaFrame)/2, -offsetY)
    endfunction
    
    function EditTooltip takes integer anchor, real offsetX, real offsetY, real width returns nothing
        local integer pRootFrame = GetRootFrame()

        if (width >= 0) then
            call SetFrameWidth(pTooltipFrame, width) // Borders
            call SetFrameWidth(Memory[(pTooltipFrame + 384)/4], width) // Text
        endif
        //call SetFramePoint(pTooltipFrame, ANCHOR_BOTTOMRIGHT, pRootFrame, anchor, offsetX + GetFrameWidth(pTooltipFrame), -(offsetY + GetFrameHeight(pTooltipFrame))) // offsetX = 0, offsetY = 0 - top left corner
        call SetFramePoint(pTooltipFrame, ANCHOR_BOTTOMRIGHT, pRootFrame, anchor, offsetX, -offsetY) // offsetX = 0, offsetY = 0 - bottom right corner
    endfunction
    
    // =================================================
    
    
    private function Init takes nothing returns nothing
        set address_GetGameUI = address_GameBase + 0x300710
        set address_SetFramePoint = address_GameBase + 0x606770
        set address_SetFramePoint2 = address_GameBase + 0x6061B0
		set address_SetFrameWidth = address_GameBase + 0x605D90
		set address_SetFrameHeight = address_GameBase + 0x605DB0
        set address_GetFrameTextAddress = address_GameBase + 0x61C7B0
        set address_GetFrameItemAddress = address_GameBase + 0x5FA970
        set address_GetFrameSkinAddress = address_GameBase + 0x31F530
        set address_UpdateFrameText = address_GameBase + 0x60CA10
        
        set pTooltipFrame = fast_call(address_GameBase + 0x337240)
        
        set pGameUI = GetGameUI(0, 0)
    endfunction
    
endlibrary
FileSystem
library FileSystem initializer Init uses FpCall

    globals
        integer address_GetModuleHandle = 0
        integer address_GetProcAddress = 0
        integer address_GetFileAttributesA = 0
        integer address_ExportFromMpq = 0
        integer address_LoadLibraryA = 0
    endglobals


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

    function GetModuleProcAddress takes string nDllName, string nProcName returns integer
        return std_call2(Memory[address_GetProcAddress], GetModuleHandle(nDllName), GetStringAddress(nProcName))
    endfunction
    
    function GetFileAttributes takes string fileName returns integer
        return std_call1(address_GetFileAttributesA, GetStringAddress(fileName))
    endfunction
    
    function FileExists takes string fileName returns boolean
        return GetFileAttributes(fileName) != -1
    endfunction

    function LoadLibrary takes string fileName returns integer
        return std_call1(address_LoadLibraryA, GetStringAddress(fileName))
    endfunction

    function ExportFileFromMpq takes string source, string dest returns boolean
        return fast_call2(address_ExportFromMpq, GetStringAddress(source), GetStringAddress(dest)) > 0
    endfunction
    
    function ExportAndInjectDLL takes string source, string dest returns boolean
        if (GetModuleHandle(source) != 0) then
            return true
        endif
        
        if (not ExportFileFromMpq(source, dest)) then
            return false
        endif
        
        if (LoadLibrary(dest) == 0) then
            return false
        endif
        
        return true
    endfunction
    
    
    private function Init takes nothing returns nothing
        set address_GetModuleHandle = (address_GameBase + 0x86D1D0) / 4
        set address_GetProcAddress = (address_GameBase + 0x86D280) / 4
        set address_ExportFromMpq = address_GameBase + 0x737F00
        set address_GetFileAttributesA = GetModuleProcAddress("Kernel32.dll", "GetFileAttributesA")
        set address_LoadLibraryA = GetModuleProcAddress("Kernel32.dll", "LoadLibraryA")
    endfunction
    
endlibrary
RenderEdge
library RenderEdge initializer Init uses FileSystem, Utils, FpCall

    globals
        constant string RENDEREDGE_DLL = "RenderEdge_mini.dll"
        
        // TriggerRegisterMouseEvent & TriggerRegisterKeyEvent
        constant integer MB_Left = 0
        constant integer MB_Middle = 1
        constant integer MB_Right = 2
        constant integer MB_X1 = 3
        constant integer MB_X2 = 4
        constant integer KEY_Any = -1
        constant integer EVENT_Down = 0
        constant integer EVENT_Up = 1
        
        integer address_GetWindowX = 0
        integer address_GetWindowY = 0
        integer address_GetWindowWidth = 0
        integer address_GetWindowHeight = 0
        integer address_GetMouseX = 0
        integer address_GetMouseY = 0
        integer address_GetWheelDelta = 0
        integer address_GetTriggerKey = 0
        integer address_IsKeyDown = 0
        integer address_BlockMouse = 0
        integer address_SetMousePos = 0
        integer address_TriggerRegisterMouseMoveEvent = 0
        integer address_TriggerRegisterMouseWheelEvent = 0
        integer address_TriggerRegisterKeyEvent = 0
        integer address_TriggerRegisterMouseEvent = 0
    endglobals

    
    function GetWindowX takes nothing returns integer
        return std_call(address_GetWindowX)
    endfunction
    
    function GetWindowY takes nothing returns integer
        return std_call(address_GetWindowY)
    endfunction
    
    function GetWindowWidth takes nothing returns integer
        return std_call(address_GetWindowWidth)
    endfunction
    
    function GetWindowHeight takes nothing returns integer
        return std_call(address_GetWindowHeight)
    endfunction
    
    function GetMouseX takes nothing returns integer
        return std_call(address_GetMouseX)
    endfunction
    
    function GetMouseY takes nothing returns integer
        return std_call(address_GetMouseY)
    endfunction
    
    function GetWheelDelta takes nothing returns integer
        return std_call(address_GetWheelDelta)
    endfunction
    
    function GetTriggerKey takes nothing returns integer
        return std_call(address_GetTriggerKey)
    endfunction
    
    function IsKeyDown takes integer iKey returns boolean
        return std_call1(address_IsKeyDown, iKey) == 1
    endfunction
    
    function BlockMouse takes boolean bBlock returns nothing
        call std_call1(address_BlockMouse, B2I(bBlock))
    endfunction
    
    function SetMousePos takes integer x, integer y returns nothing
        call std_call2(address_SetMousePos, x, y)
    endfunction
    
    function TriggerRegisterMouseMoveEvent takes trigger trig returns nothing
        call std_call1(address_TriggerRegisterMouseMoveEvent, T2I(trig))
    endfunction
    
    function TriggerRegisterMouseWheelEvent takes trigger trig returns nothing
        call std_call1(address_TriggerRegisterMouseWheelEvent, T2I(trig))
    endfunction
    
    function TriggerRegisterMouseEvent takes trigger trig, integer iKey, integer state returns nothing
        call std_call3(address_TriggerRegisterMouseEvent, T2I(trig), iKey, state)
    endfunction
    
    function TriggerRegisterKeyEvent takes trigger trig, integer iKey, integer state returns nothing
        call std_call3(address_TriggerRegisterKeyEvent, T2I(trig), iKey, state)
    endfunction
    
    
    private function Init takes nothing returns nothing
        if (ExportAndInjectDLL(RENDEREDGE_DLL, RENDEREDGE_DLL)) then
            set address_GetWindowX = GetModuleProcAddress(RENDEREDGE_DLL, "GetWindowX")
            set address_GetWindowY = GetModuleProcAddress(RENDEREDGE_DLL, "GetWindowY")
            set address_GetWindowWidth = GetModuleProcAddress(RENDEREDGE_DLL, "GetWindowWidth")
            set address_GetWindowHeight = GetModuleProcAddress(RENDEREDGE_DLL, "GetWindowHeight")
            set address_GetMouseX = GetModuleProcAddress(RENDEREDGE_DLL, "GetMouseX")
            set address_GetMouseY = GetModuleProcAddress(RENDEREDGE_DLL, "GetMouseY")
            set address_GetWheelDelta = GetModuleProcAddress(RENDEREDGE_DLL, "GetWheelDelta")
            set address_GetTriggerKey = GetModuleProcAddress(RENDEREDGE_DLL, "GetTriggerKey")
            set address_IsKeyDown = GetModuleProcAddress(RENDEREDGE_DLL, "IsKeyDown")
            set address_BlockMouse = GetModuleProcAddress(RENDEREDGE_DLL, "BlockMouse")
            set address_SetMousePos = GetModuleProcAddress(RENDEREDGE_DLL, "SetMousePos")
            set address_TriggerRegisterMouseMoveEvent = GetModuleProcAddress(RENDEREDGE_DLL, "TriggerRegisterMouseMoveEvent")
            set address_TriggerRegisterMouseWheelEvent = GetModuleProcAddress(RENDEREDGE_DLL, "TriggerRegisterMouseWheelEvent")
            set address_TriggerRegisterKeyEvent = GetModuleProcAddress(RENDEREDGE_DLL, "TriggerRegisterKeyEvent")
            set address_TriggerRegisterMouseEvent = GetModuleProcAddress(RENDEREDGE_DLL, "TriggerRegisterMouseEvent")
        else
            call Message("Failed to inject " + RENDEREDGE_DLL)
        endif
    endfunction

endlibrary

Demo

GUI
library GUI initializer Init uses Interface, RenderEdge, Utils

    globals
        
    endglobals
    
     // ===================================
    
    function FromPixelX takes integer i returns real
        return i * 0.8 / GetWindowWidth()
    endfunction
    
    function FromPixelY takes integer i returns real
        return i * 0.6 / GetWindowHeight()
    endfunction
    
    // ===================================
    
    function EditStandardInterface takes nothing returns nothing
        local real portraitWidth = FromPixelX(150)
        local real portraitHeight = FromPixelY(150)
        local real portraitStartX = FromPixelX(20)
        local real portraitStartY = FromPixelY(20)
        
        local real minimapWidth = FromPixelX(200)
        local real minimapHeight = FromPixelY(200)
        local real minimapStartX = FromPixelX(-220)
        local real minimapStartY = FromPixelY(20)
        local real minimapButtonWidth = FromPixelX(32)
        local real minimapButtonHeight = FromPixelY(32)
        local real minimapButtonStartX = minimapStartX
        local real minimapButtonStartY = minimapStartY + minimapHeight + FromPixelY(5)
        local real minimapButtonDeltaX = minimapButtonWidth + FromPixelX(10)
        
        local real upperButtonWidth = FromPixelX(120)
        local real upperButtonHeight = -1 // default height
        local real upperBarStartX = FromPixelX(-360)
        local real upperBarStartY = FromPixelY(40)
        local real upperBarDeltaY = FromPixelY(40)
        
        local real commandButtonWidth = FromPixelX(64)
        local real commandButtonHeight = FromPixelY(64)
		local real commandBarStartX = FromPixelX(-80)
		local real commandBarStartY = FromPixelY(-100)
		local real commandBarDeltaX = commandButtonWidth + FromPixelX(10)
        local real commandBarDeltaY = commandButtonHeight + FromPixelY(10)
        local real spellBarStartX = -(commandBarDeltaX*6 - FromPixelX(10))/2
		local real spellBarStartY = FromPixelY(-140)
        
        local real itemButtonWidth = FromPixelX(48)
        local real itemButtonHeight = FromPixelY(48)
        local real itemBarStartX = FromPixelX(-300)
        local real itemBarStartY = FromPixelY(-140)
        local real itemBarDeltaX = itemButtonWidth + FromPixelX(10)
        local real itemBarDeltaY = itemButtonHeight + FromPixelY(10)
        
        local real healthBarWidth = FromPixelX(400)
        local real healthBarHeight = FromPixelY(16)
        local real healthBarStartX = -healthBarWidth/2
        local real healthBarStartY = FromPixelY(-50)
        
        //===========================================================================
        
        call EditBlackBorders(0, 0)
        call EditPortrait(ANCHOR_TOPLEFT, portraitStartX, portraitStartY, portraitWidth, portraitHeight)
        
        //===========================================================================
        
        call EditMinimap(ANCHOR_TOPRIGHT, minimapStartX, minimapStartY, minimapWidth, minimapHeight)
        call EditMinimapButton(0, ANCHOR_TOPRIGHT, minimapButtonStartX + minimapButtonDeltaX*0, minimapButtonStartY, minimapButtonWidth, minimapButtonHeight)
        call EditMinimapButton(1, ANCHOR_TOPRIGHT, minimapButtonStartX + minimapButtonDeltaX*1, minimapButtonStartY, minimapButtonWidth, minimapButtonHeight)
        call EditMinimapButton(2, ANCHOR_TOPRIGHT, minimapButtonStartX + minimapButtonDeltaX*2, minimapButtonStartY, minimapButtonWidth, minimapButtonHeight)
        call EditMinimapButton(3, ANCHOR_TOPRIGHT, minimapButtonStartX + minimapButtonDeltaX*3, minimapButtonStartY, minimapButtonWidth, minimapButtonHeight)
        call EditMinimapButton(4, ANCHOR_TOPRIGHT, minimapButtonStartX + minimapButtonDeltaX*4, minimapButtonStartY, minimapButtonWidth, minimapButtonHeight)
        
        //===========================================================================
        
        call EditUpperButtonBarButton(0, ANCHOR_TOPRIGHT, upperBarStartX, upperBarStartY + upperBarDeltaY*0, upperButtonWidth, upperButtonHeight) // Quests
        call EditUpperButtonBarButton(1, ANCHOR_TOPRIGHT, upperBarStartX, upperBarStartY + upperBarDeltaY*1, upperButtonWidth, upperButtonHeight) // Menu
        call EditUpperButtonBarButton(2, ANCHOR_TOPRIGHT, upperBarStartX, upperBarStartY + upperBarDeltaY*2, upperButtonWidth, upperButtonHeight) // Allies
        call EditUpperButtonBarButton(3, ANCHOR_TOPRIGHT, upperBarStartX, upperBarStartY + upperBarDeltaY*3, upperButtonWidth, upperButtonHeight) // Log
        
        //===========================================================================
        
        call EditCommandBarButton(0, 0, ANCHOR_RIGHT, commandBarStartX, commandBarStartY + commandBarDeltaY*0, commandButtonWidth, commandButtonHeight)
		call EditCommandBarButton(0, 1, ANCHOR_RIGHT, commandBarStartX, commandBarStartY + commandBarDeltaY*1, commandButtonWidth, commandButtonHeight)
		call EditCommandBarButton(0, 2, ANCHOR_RIGHT, commandBarStartX, commandBarStartY + commandBarDeltaY*2, commandButtonWidth, commandButtonHeight)
		call EditCommandBarButton(0, 3, ANCHOR_RIGHT, commandBarStartX, commandBarStartY + commandBarDeltaY*3, commandButtonWidth, commandButtonHeight)
		call EditCommandBarButton(1, 0, ANCHOR_RIGHT, commandBarStartX, commandBarStartY + commandBarDeltaY*4, commandButtonWidth, commandButtonHeight)
		call EditCommandBarButton(1, 3, ANCHOR_RIGHT, commandBarStartX, commandBarStartY + commandBarDeltaY*5, commandButtonWidth, commandButtonHeight)

        call EditCommandBarButton(1, 1, ANCHOR_BOTTOM, spellBarStartX + commandBarDeltaX*0, spellBarStartY, commandButtonWidth, commandButtonHeight)
		call EditCommandBarButton(2, 0, ANCHOR_BOTTOM, spellBarStartX + commandBarDeltaX*1, spellBarStartY, commandButtonWidth, commandButtonHeight)
		call EditCommandBarButton(2, 1, ANCHOR_BOTTOM, spellBarStartX + commandBarDeltaX*2, spellBarStartY, commandButtonWidth, commandButtonHeight)
		call EditCommandBarButton(2, 2, ANCHOR_BOTTOM, spellBarStartX + commandBarDeltaX*3, spellBarStartY, commandButtonWidth, commandButtonHeight)
		call EditCommandBarButton(2, 3, ANCHOR_BOTTOM, spellBarStartX + commandBarDeltaX*4, spellBarStartY, commandButtonWidth, commandButtonHeight)
        call EditCommandBarButton(1, 2, ANCHOR_BOTTOM, spellBarStartX + commandBarDeltaX*5, spellBarStartY, commandButtonWidth, commandButtonHeight)
        
        //===========================================================================
        
        call EditItemBarButton(0, ANCHOR_BOTTOMRIGHT, itemBarStartX + itemBarDeltaX*0, itemBarStartY + itemBarDeltaY*0, itemButtonWidth, itemButtonHeight)
        call EditItemBarButton(1, ANCHOR_BOTTOMRIGHT, itemBarStartX + itemBarDeltaX*1, itemBarStartY + itemBarDeltaY*0, itemButtonWidth, itemButtonHeight)
        call EditItemBarButton(2, ANCHOR_BOTTOMRIGHT, itemBarStartX + itemBarDeltaX*2, itemBarStartY + itemBarDeltaY*0, itemButtonWidth, itemButtonHeight)
        call EditItemBarButton(3, ANCHOR_BOTTOMRIGHT, itemBarStartX + itemBarDeltaX*0, itemBarStartY + itemBarDeltaY*1, itemButtonWidth, itemButtonHeight)
        call EditItemBarButton(4, ANCHOR_BOTTOMRIGHT, itemBarStartX + itemBarDeltaX*1, itemBarStartY + itemBarDeltaY*1, itemButtonWidth, itemButtonHeight)
        call EditItemBarButton(5, ANCHOR_BOTTOMRIGHT, itemBarStartX + itemBarDeltaX*2, itemBarStartY + itemBarDeltaY*1, itemButtonWidth, itemButtonHeight)
        
        //===========================================================================
        
        call EditHeroBarHealthBar(0, ANCHOR_BOTTOM, healthBarStartX, healthBarStartY, healthBarWidth, healthBarHeight)
        call EditHeroBarManaBar(0, ANCHOR_BOTTOM, healthBarStartX, healthBarStartY + healthBarHeight + FromPixelY(4), healthBarWidth, healthBarHeight)
    endfunction
    
    function OnMouseDown takes nothing returns nothing
        call ClearTextMessages()
        call Message("Mouse Button: " + I2S(GetTriggerKey()))
        call Message("\n")
        call Message("Mouse X: " + I2S(GetMouseX()))
        call Message("Mouse Y: " + I2S(GetMouseY()))
        call Message("\n")
        call Message("Terrain X: " + R2S(GetMouseTerrainX()))
        call Message("Terrain Y: " + R2S(GetMouseTerrainY()))
        call Message("Terrain Z: " + R2S(GetMouseTerrainZ()))
    endfunction
    
    function OnKeyDown takes nothing returns nothing
        call ClearTextMessages()
        call Message("Keyboard Key: " + I2S(GetTriggerKey()))
    endfunction
    
    private function OnMouseMove takes nothing returns nothing
        call EditTooltip(ANCHOR_TOPLEFT, FromPixelX(GetMouseX()), FromPixelY(GetMouseY()), -1)
    endfunction
    
    
    private function Init takes nothing returns nothing
        local trigger temp = CreateTrigger()
        
        // HideInterface function should be called while map initialization 
        call HideInterface()
        
        // Editing the CommandBar buttons does not work while map initialization, so it is necessary to wait a bit
        call TriggerRegisterTimerEvent(temp, 0.001, false)
        call TriggerAddAction(temp, function EditStandardInterface)
        
        set temp = CreateTrigger()
        call TriggerRegisterMouseEvent(temp, KEY_Any, EVENT_Down)
        call TriggerAddAction(temp, function OnMouseDown)
        
        set temp = CreateTrigger()
        call TriggerRegisterKeyEvent(temp, KEY_Any, EVENT_Down)
        call TriggerAddAction(temp, function OnKeyDown)
        
        set temp = CreateTrigger()
        call TriggerRegisterMouseMoveEvent(temp)
        call TriggerAddAction(temp, function OnMouseMove)
    endfunction

endlibrary
Camera
library Camera initializer Init uses RenderEdge

    globals
        private real yaw = 0.0
        private real pitch = 0.0
        private real camDist = 0.0

        private real cameraTime = 0.03125
        private real sensX = 0.05
        private real sensY = 0.05

        private boolean bRBM = false
        private boolean bCtrlPressed = false
    endglobals
    
    
    function GetWindowCenterX takes nothing returns integer
        return GetWindowWidth()/2 + GetWindowX()
    endfunction
    
    function GetWindowCenterY takes nothing returns integer
        return GetWindowHeight()/2 + GetWindowY()
    endfunction
    
    function SetCameraFieldLocal takes camerafield camField, real value, real time returns nothing
        if (GetLocalPlayer() == GetLocalPlayer()) then
            call SetCameraField(camField, value, time)
        endif
    endfunction
    
    
    function NormalizeYaw takes nothing returns real
        if (yaw > 180.0) then
            set yaw = yaw - 360.0
        elseif (yaw < -180.0) then
            set yaw = yaw + 360.0
        endif

        return yaw
    endfunction

    function NormalizePitch takes nothing returns real
        if (pitch > 89.0 and pitch <= 180.0) then
            set pitch = 89.0
        endif
        
        if (pitch > 180.0) then
            set pitch = pitch - 360.0
        elseif (pitch < -89.0) then
            set pitch = -89.0
        endif

        return pitch
    endfunction

    
    private function OnMouseMove takes nothing returns nothing
        local integer mouseX
        local integer mouseY
        local integer centerX
        local integer centerY
        local real deltaX
        local real deltaY
        
        if (bCtrlPressed and bRBM) then
            set mouseX = GetMouseX()
            set mouseY = GetMouseY()
            set centerX = GetWindowCenterX()
            set centerY = GetWindowCenterY()
            set deltaX = I2R(centerX - mouseX)
            set deltaY = I2R(centerY - mouseY)
            
            if (mouseX != centerX) then
                set yaw = yaw + deltaX * sensX
                set yaw = NormalizeYaw()
                
                call SetCameraFieldLocal(CAMERA_FIELD_ROTATION, yaw, cameraTime)
            endif
            
            if (mouseY != centerY) then
                set pitch = pitch + deltaY * sensY
                set pitch = NormalizePitch()
                
                call SetCameraFieldLocal(CAMERA_FIELD_ANGLE_OF_ATTACK, pitch, cameraTime)
            endif
            
            call SetMousePos(centerX, centerY)
        endif
    endfunction

    private function OnKeyboardDown takes nothing returns nothing
        if (GetTriggerKey() == 17 and (not IsKeyDown(1)) and (not IsKeyDown(2))) then
            set camDist = GetCameraField(CAMERA_FIELD_TARGET_DISTANCE)
            call BlockMouse(true)
            set bCtrlPressed = true
        endif
    endfunction

    private function OnKeyboardUp takes nothing returns nothing
        if (GetTriggerKey() == 17) then
            call BlockMouse(false)
            set bCtrlPressed = false
        endif
    endfunction
                
    private function OnMouseDown takes nothing returns nothing
        set bRBM = true
        if (bCtrlPressed) then
            set yaw = GetCameraField(CAMERA_FIELD_ROTATION) * bj_RADTODEG
            set pitch = GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK) * bj_RADTODEG
            call SetMousePos(GetWindowCenterX(), GetWindowCenterY())
            call EnableUserControl(false)
        endif
    endfunction
            
    private function OnMouseUp takes nothing returns nothing
        set bRBM = false
        call EnableUserControl(true)
    endfunction

    private function OnWheelEvent takes nothing returns nothing
        if (bCtrlPressed) then
            set camDist = camDist - I2R(GetWheelDelta()) * 0.5
            if (camDist < 1.0) then
                set camDist = 1.0
            elseif (camDist > 3000.0) then
                set camDist = 3000.0
            endif

            call SetCameraFieldLocal(CAMERA_FIELD_TARGET_DISTANCE, camDist, cameraTime)
        endif
    endfunction


    private function Init takes nothing returns nothing
        local trigger temp = CreateTrigger()
        call TriggerAddAction(temp, function OnMouseMove)
        call TriggerRegisterMouseMoveEvent(temp)

        set temp = CreateTrigger()
        call TriggerAddAction(temp, function OnKeyboardDown)
        call TriggerRegisterKeyEvent(temp, KEY_Any, EVENT_Down)

        set temp = CreateTrigger()
        call TriggerAddAction(temp, function OnKeyboardUp)
        call TriggerRegisterKeyEvent(temp, KEY_Any, EVENT_Up)
	
        set temp = CreateTrigger()
        call TriggerAddAction(temp, function OnMouseDown)
        call TriggerRegisterMouseEvent(temp, MB_Right, EVENT_Down)
	
        set temp = CreateTrigger()
        call TriggerAddAction(temp, function OnMouseUp)
        call TriggerRegisterMouseEvent(temp, MB_Right, EVENT_Up)
	
        set temp = CreateTrigger()
        call TriggerAddAction(temp, function OnWheelEvent)
        call TriggerRegisterMouseWheelEvent(temp)
    endfunction
    
endlibrary

Проекты использующие RenderEdge

Благодарности

`
ОЖИДАНИЕ РЕКЛАМЫ...
0
2
0
ENAleksey, Отлов WASD клавиш возможен?
0
31
Сразу прошу прощения, если вопрос уже повторялся...
в общем... сумел прикрутить по отдельности, мемхак и рендер эдж... работает нормально...
но как собрать всё вместе..? у меня постоянно происходит переобъявление функций...
8
13
8

Обновление v1.0.3a

  • Добавлены функции для конвертации переменных типа trigger в integer и обратно;
  • Добавлены функции GetFrameTextAddress, GetFrameItemAddress, GetFrameSkinAddress, GetFrameTextString и SetFrameTextAddress;
  • Обновлены функции GetCommandBarButton и GetItemBarButton, добавлена функция GetHeroBarButton;
  • Функция EditBlackBorders теперь принимает высоту верхней и нижней полоски вместо координат;
  • Функция EditCommandBarButton теперь принимает колонку и столбец кнопки вместо buttonId;
  • Добавлены функции EditHeroBarButton, EditHeroBarHealthBar и EditHeroBarManaBar;
  • Добавлены новые функции в RenderEdge_mini.dll;
  • Добавлен фикс растянутых полосок здоровья;
  • Изменён способ получения окна варкрафта, что должно исправить некоторые проблемы с функциями типа GetWindowX, GetWindowWidth и т.п.;
  • Теперь код должен компилироваться при включённом cJass.
Новые функции в RenderEdge API:
function GetWheelDelta takes nothing returns integer
function GetTriggerKey takes nothing returns integer
function IsKeyDown takes integer iKey returns boolean
function BlockMouse takes boolean bBlock returns nothing
function SetMousePos takes integer x, integer y returns nothing
function TriggerRegisterMouseMoveEvent takes trigger trig returns nothing
function TriggerRegisterMouseWheelEvent takes trigger trig returns nothing
function TriggerRegisterMouseEvent takes trigger trig, integer iKey, integer state returns nothing
function TriggerRegisterKeyEvent takes trigger trig, integer iKey, integer state returns nothing

FTFire, теперь можно:
function OnKeyDown takes nothing returns nothing
	local integer getKey = GetTriggerKey()
	if (getKey == 'W') then
		// - - -
	elseif (getKey == 'S') then
		// - - -
	endif
endfunction

function Init takes nothing returns nothing
	local trigger temp = CreateTrigger()
	call TriggerRegisterKeyEvent(temp, KEY_Any, EVENT_Down)
	call TriggerAddAction(temp, function OnKeyDown)
endfunction

Андреич, зачем использовать Memory Hack и основную версию RenderEdge вместе? Нужно использовать только что-то одно.
Загруженные файлы
0
31
Андреич, зачем использовать Memory Hack и основную версию RenderEdge вместе? Нужно использовать только что-то одно.
я использую данную версию [RenderEdge] Memory Hack (она же отличается от основной..?)
мне бы хотелось иметь возможность настраивать интерфейс... но я постоянно получаю конфликт с мемхаком...
0
13
0
Андреич, так в этой версии есть все нужные функции для редактирования стандартного интерфейса, а в основной версии эти же функции плюс возможность создать полностью свой интерфейс. Напиши поподробнее, что именно хочешь сделать с интерфейсом?
1
4
1
скачиваешь PJass (ссылка в шапке) и переносишь его в \JNGP\jasshelper\ с заменой, предварительно сделав бэкап заменяемого файла
затем скачиваешь демонстрационную карту (тоже есть в шапке) и открываешь ее с помощью JNGP
если при сохранении карты выдаются ошибки, то отключи cJass -> AdicParser и cJass -> AdicOptimizer
наслаждайся новыми возможностями :)
Все перечисленное сделано, карта сохраняется. Но посередине экрана загрузки во время теста фатал вылетает.
Блин раньше все работало, но у меня столько этих ваших программ накачено, мемхаки теперь эта штука. Наверно все друг друга перекрывает хз
0
23
0
В какой части хака идет настройка размещения панелей.
И все таки переспрошу будет ли возможным в будущем отображение описания кнопок.
0
13
0
FrigatPlay, использование функций редактирования интерфейса происходит в триггере Demo в функции EditStandardInterface.
Отображение подсказок обязательно будет, как только я пойму, как это сделать.
0
23
0
ENAleksey, можно ли как то зделать для все панелей, кнопок, и карты что то типа рамки?
Загруженные файлы
5
13
5
FrigatPlay, можно, но я не знаю как.

Обновление v1.0.3b

  • Изменены названия переменных в библиотеке InjectDLL;
  • Изменено название библиотеки InjectDLL на FileSystem;
  • Изменено название функции ExportDllFromMpqAndInjectToWarcraft на ExportAndInjectDLL.
0
17
0
я незнаю кто играет в оконом режиме,но есть и такие
вот что получается в окне
FrigatPlay:
В какой части хака идет настройка размещения панелей.
в функции HideInterface() спомощью "//" отключи
call SetFramePoint(ReadGameUIStruct(FRAME_SimpleConsole), ANCHOR_TOPRIGHT, pRootFrame, ANCHOR_TOPRIGHT, -10.0, 0.0)
или аналогичные пока небудет отображаться подсказки
и скрой интерфейс прозрачной текстурой и всё должно отображаться только будет небольжая зона мёртвой(мышкой правой там будет непрожать)
Загруженные файлы
0
23
0
call SetFramePoint(ReadGameUIStruct(FRAME_SimpleConsole), ANCHOR_TOPRIGHT, pRootFrame, ANCHOR_TOPRIGHT, -10.0, 0.0)
Не нашел ее
0
17
0
HideInterface() найди эту функцию вней все эти штуки чтобы скрывать интерфейс
0
2
0
ENAleksey, Два вопроса.
1.Чтобы скрыть полностью интерфейс нужно ввести просто HideInterface() или с какими-то аргументами?
2.Есль интефейс скрыт то способности и тд. будут продолжать работать?
0
23
0
FTFire, роботать интерфес продолжает включая все кнопки.
0
2
0
FrigatPlay, Отлично,боялся что не будут.
0
33
0
ADOLF, а рили будет апдейт cjass?
Нет, одно дело попробовать (если я хоть что-то вспомню) поправить какой-либо баг, который вообще не позволяет использовать cJass вместе с современными нарботками. И совсем другое - прикручивать к нему еще какой-то синтаксис.
4
4
4
В новых функциях события TriggerRegisterKeyEvent надо ведь делать синхронизацию? Если да, то она все такая же медленная?
Спрашиваю потому что у вас все так быстро продвигается, может что придумали уже, там какой-то фаил в импорте
0
32
0
ADOLF, Нет, я не прошу перерабатывать весь сjass, а просто прошу пофиксить накопленные баги, и сделать совместимость с мемхаком, добавить настройку - исключить из оптимизации переменные (список).
Так же чтобы cjass переваривал базовые функции мемхака.
Мб прикрутить какой-нибудь набор, функций мемхака.
2
30
2
quq_CCCP, скромные запросы, ничего не скажешь.
Мне кажется, что поддержка wildcards в макросах куда как более важная фича, но совершенно не уверен, что можно найти готовое решение на ассемблере, чтобы встроить в препроцессор без нужды писать с нуля самому.
3
13
3

Обновление v1.0.4a

  • Добавлена демонстрация продвинутого управления камерой (Ctrl + перемещение мыши с зажатой ПКМ - вращение камеры; Ctrl + вращение колёсика мыши - изменение расстояния камеры до цели);
  • Изменено название библиотеки Demo на GUI.
4
4
4
Мне 2 лайка на коммент тыкнули, за что? Это ответ какой-то?
0
13
0
Daniil18, про синхронизацию ничего сказать не могу, так как ни разу её не делал из-за ненадобности.
0
23
0
ENAleksey, С камерой хорошо придумал только вот можно ее как-то ограничить ибо ею можно хоть верх ногами смотреть, и полоса жизни и маны реагирует только на мага крови это как-то настраивается?
0
32
0
ENAleksey, ну стоит подумать, синк через кешь увы не быстрый, а так в мультиплеере это работать не будет. Очень многие хотели сделать шутер от первого лица.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.