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

No ideea why stop/ignored the trigger if no any known mistake

Status
Not open for further replies.
Level 17
Joined
Nov 13, 2006
Messages
1,814
Two big problem

map attached

1.
thread isn't break at fixed point, it is depend on how many item equipment do you got, till ~5 equiped item work without problem, at 6th break at X part of trigger, if u equip 7 then before X part, if u have 8 then close after loop etc

indifferent what slot/order :/

you can test when start inventory and use Save Game ability


JASS:
function Create_Save_Load_Code takes nothing returns boolean
    local string CODE // final code will be stored to this variable
    local integer l //get the string length of the alphabet string
    local integer i
    local integer ii
    local integer array Pow2
    local integer array PowL
    local integer MinExp // that exp what was needed for your hero current level
    local integer MaxExp // that exp what needed for your hero for level up
    local integer CurExp // with how much exp hero passed the last level up
    local integer CLASS // the hero unit type index in SL_HERO_TYPE array
    local integer LV // hero level
    local integer EXP // hero exp
    local integer STR // hero strength
    local integer AGI // hero agility
    local integer INT // hero intelligence
    local integer GOLD // player gold
    local integer LUMBER // player lumber
    local integer X // hero x coordinate
    local integer Y // hero y coordinate
    local integer COORD_LEN_X // how much character needed for save hero location
    local integer COORD_LEN_Y // how much character needed for save hero location
    local boolean ERROR = true
    local integer MAX_X //highest X coordinate on map
    local integer MAX_Y //highest Y coordinate on map
    local integer MAX_HERO
    local integer MAX_VAR
    local unit d //dummy unit
    local unit u = GetTriggerUnit()
    local player p
    local location loc //just for location
    local string Key //this is a key for saveing lv, exp, stats into 1 character, we will search thsi string in VAR array for get a index
    local string s
    local string s1
    local string s2
    local string s3
    local integer id
    local integer ITEM_STR
    local integer ITEM_AGI
    local integer ITEM_INT
    local integer START_STR
    local integer START_AGI
    local integer START_INT
    local integer cv
    local integer a1
    local integer a2
    local integer a3
    local integer a4
    local integer b1
    local integer b2
    local integer b3
    local integer b4
    local item itm
    local integer BLACKSMITH
    local integer TAILOR
    local integer JEWELLER
    local integer PHARMACIST
    local integer ITEMS1
    local integer ITEMS2
    local integer DURATIBILITY
    local integer MAX_INVENTORY
    local integer EQ_B_CODE1 //eq boolean code for 1st 5 item, 6th boolean about if have 6, 7, 8, 9, 10 item
    local integer EQ_B_CODE2 //eq boolean code for 2nd 5 item, 6, 7, 8, 9, 10th item
    local integer EQ_Count //count equiped items
    local integer GEM_LEN
    local string array CODE_Row //line with eq codes
    local integer CODE_Row_Count //count how much line needed for write down all equipment
    local integer BONUS //predefined bonus stat index's from items
    local integer BONUS_LEN //predefined bonus stats length from items (1 = 0 - 82, 2 = 0 - 6400)
    local string array EQC //equipment code string
    local integer MAX_CHAR = 60 //maximum character in row
    local string PATH
    local string HERO_NAME
    local string HERO_LV
    local boolean SAVE_COORD = SL_SAVE_COORD()
 
    if GetSpellAbilityId() == 'A018' then
        //call IssueImmediateOrder( u, "stop" )
        set a1 = GetUnitTypeId(u)
        set START_STR = LoadInteger(udg_FSS, 636, a1)
        set START_AGI = LoadInteger(udg_FSS, 637, a1)
        set START_INT = LoadInteger(udg_FSS, 638, a1)
        set ITEM_STR = 0
        set ITEM_AGI = 0
        set ITEM_INT = 0
        set p = GetTriggerPlayer()
        set cv = GetUnitUserData(u)
        set CODE = ""
        set Key = ""
        set l = StringLength(SL_CODE())
        set MAX_X = R2I(GetRectMaxX(bj_mapInitialPlayableArea))
        set MAX_Y = R2I(GetRectMaxY(bj_mapInitialPlayableArea))
        set BLACKSMITH = LoadInteger(udg_Stat_Table, 27000 + cv, 1)
        set TAILOR = LoadInteger(udg_Stat_Table, 27000 + cv, 2)
        set JEWELLER = LoadInteger(udg_Stat_Table, 27000 + cv, 3)
        set PHARMACIST = LoadInteger(udg_Stat_Table, 27000 + cv, 4)
        set MAX_VAR = LoadInteger(udg_SL_HASHTABLE, 1, 0)
        set MAX_HERO = LoadInteger(udg_SL_HASHTABLE, 2, 0)
        set EQ_Count = 0
        set MAX_INVENTORY = 20 //our inventory capacity is 20 item
        set GEM_LEN = SL_GetIntegerSize(LoadInteger(udg_CItem_Table, - 2000, 0))
        set EQ_B_CODE1 = 0
        set EQ_B_CODE2 = 0
        //----------- just preload the string bases with max values like 1char length till length-1 ----
        set i = 1
        loop
            set PowL[i] = R2I(Pow(l, i)) - 1
            set i = i + 1
            exitwhen i == 5
        endloop
        //-------------------------------------------------------------------------------

        //----------- just preload the 2 bases, like 1,2,4,8,16,32 ----------------------
        set i = 0
        loop
            set Pow2[i] = R2I(Pow(2, i))
            set i = i + 1
            exitwhen i > 6
        endloop
        //-------------------------------------------------------------------------------

        //we calculate how much str, agi, int coming from items - directly and from sockets
        //we start in inventory - we check the charms
        set i = 1
        loop
            exitwhen i > MAX_INVENTORY
            if HaveSavedHandle(udg_Stat_Table, cv, i + 99) then
                set itm = LoadItemHandle(udg_Stat_Table, cv, i + 99)
                if GetItemLevel(itm) == 111 then //if item level is 111 then item is charm
                    set id = GetHandleId(itm)
                    set ITEM_STR = ITEM_STR + LoadInteger(udg_CItem_Table, id, 44)
                    set ITEM_AGI = ITEM_AGI + LoadInteger(udg_CItem_Table, id, 45)
                    set ITEM_INT = ITEM_INT + LoadInteger(udg_CItem_Table, id, 46)
                endif
            endif
            set i = i + 1
        endloop
        set itm = null

        //we start build the code for equipments, each equipment individually and at end combine to a large row
        //equipment slots: 1 - 10 
        set i = 1
        loop
            exitwhen i == 11
            set EQC[i] = null
            //if in equipment slot have saved item then
            if HaveSavedHandle(udg_Stat_Table, cv, i) then
                if i < 6 then
                    set EQ_B_CODE1 = EQ_B_CODE1 + Pow2[i - 1]
                else
                    if EQ_B_CODE1 < 32 then
                        set EQ_B_CODE1 = EQ_B_CODE1 + 32
                    endif
                    set EQ_B_CODE2 = EQ_B_CODE2 + Pow2[i - 6]
                endif
                set EQ_Count = EQ_Count + 1
                set id = GetHandleId(LoadItemHandle(udg_Stat_Table, cv, i))
                set ITEM_STR = ITEM_STR + LoadInteger(udg_CItem_Table, id, 44)
                set ITEM_AGI = ITEM_AGI + LoadInteger(udg_CItem_Table, id, 45)
                set ITEM_INT = ITEM_INT + LoadInteger(udg_CItem_Table, id, 46)
                set DURATIBILITY = R2I(LoadReal(udg_CItem_Table, id, 15) - LoadReal(udg_CItem_Table, id, 14)) //maxdur - duratibility

                //we build a number, what store 6 boolean: 
                //unique id, refined, socketed, ethernal, rnd def(armor)/activation(weapon), duratibility length(1 or 2)
                set a1 = 0
                if LoadInteger(udg_CItem_Table, id, 0) > 0 then
                    set a1 = a1 + 1
                endif
                if LoadInteger(udg_CItem_Table, id, 16) > 0 then
                    set a1 = a1 + 2
                endif
                if LoadInteger(udg_CItem_Table, id, 18) > 0 then
                    set a1 = a1 + 4
                endif
                if LoadInteger(udg_CItem_Table, id, 13) > 0 then
                    set a1 = a1 + 8
                endif
                if LoadInteger(udg_CItem_Table, id, 25) > 0 then
                    set a1 = a1 + 16
                endif
                if DURATIBILITY >= l then
                    set a1 = a1 + 32
                endif
                set EQC[i] = SL_IntegerToCode(a1, 1)
           // --- end of boolean and we create from number a character --- 
  
                 // lets if was unique id then add that
                set a1 = LoadInteger(udg_CItem_Table, id, 0)
                if a1 > 0 then
                    set EQC[i] = EQC[i] + SL_IntegerToCode(a1, 1)
                else
                    //lets check base stats: subtype, quality, grade, lv req
                    set EQC[i] = EQC[i] + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 3), 1) + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 4), 1) + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 7), 2) + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 8), 2)
                    //lets add the bonus item stats
                    set ii = 0
                    set a2 = 0
                    loop
                        set BONUS = Inline_Item_Bonus_Stat(ii)
                        set BONUS_LEN = Inline_Item_Bonus_Stat_Length(BONUS)
                        exitwhen BONUS == 0
                        set a1 = LoadInteger(udg_CItem_Table, id, BONUS)
                        if a1 > 0 then
                            set EQC[i] = EQC[i] + SL_IntegerToCode(BONUS, GEM_LEN) + SL_IntegerToCode(a1, BONUS_LEN)
                        endif
                        set ii = ii + 1
                    endloop
                endif

                //check if defence is random on armor or no
                if LoadInteger(udg_CItem_Table, id, 25) > 0 then
                    if (i == 1 or i == 2 or i == 4) and LoadInteger(udg_CItem_Table, id, 25) == 1 then
                        set ii = 0
                        loop
                            exitwhen ii > 4
                            set a1 = LoadInteger(udg_CItem_Table, id, 35 + ii)
                            set EQC[i] = EQC[i] + SL_IntegerToCode(a1, 2)
                            set ii = ii + 1
                        endloop
                    elseif i == 3 then
                        set EQC[i] = EQC[i] + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 25), 1)
                    endif
                endif
                //save duratibility
                set EQC[i] = EQC[i] + SL_IntegerToCode(DURATIBILITY, - 1)
                //check if item is refined
                if LoadInteger(udg_CItem_Table, id, 16) > 0 then
                    set EQC[i] = EQC[i] + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 16), 1)
                endif

                //read out the socket bonus stat and its value too
                set a1 = LoadInteger(udg_CItem_Table, id, 18)
                if a1 > 0 then
                    set ii = 0
                    loop
                        exitwhen ii > a1
                        set a2 = LoadInteger(udg_CItem_Table, id, 1500 + ii)
                        set b3 = LoadInteger(udg_CItem_Table, id, 1000 + ii)
                           //if socket was filled then add socket unique id to code
                        set b4 = 1
                        loop
                            exitwhen b4 > b3
                            set EQC[i] = EQC[i] + SL_IntegerToCode(a2, 1)
                            set b4 = b4 + 1
                        endloop
                       
                        //we check if sockets give bonus stat too
                        if a2 == 0 then
                            set ii = a1 + 1 //break out from loop
                        else
                            set a3 = LoadInteger(udg_CItem_Table, id, 2)
                            set a4 = ItemType2GemType(a3)
                            if a4 != 0 then
                                set b1 = LoadInteger(udg_CItem_Table, - 2000 - a2, 8 + a4)
                                set b2 = LoadInteger(udg_CItem_Table, - 2000 - a2, b1)
                                set b4 = b2 * b3
                                if b1 == 44 then
                                    set ITEM_STR = ITEM_STR + b4
                                elseif b1 == 44 then
                                    set ITEM_AGI = ITEM_AGI + b4
                                elseif b1 == 44 then
                                    set ITEM_INT = ITEM_INT + b4
                                endif
                            endif
                        endif
                        set ii = ii + 1
                    endloop
                endif
            endif
            if EQC[i] != null then
              call BJDebugMsg(EQC[i])
            endif
            set i = i + 1
        endloop

        set STR = GetHeroStr(u, false) - ITEM_STR - START_STR
        set AGI = GetHeroAgi(u, false) - ITEM_AGI - START_AGI
        set INT = GetHeroInt(u, false) - ITEM_INT - START_INT
        call BJDebugMsg("str" + I2S(STR))
        call BJDebugMsg("agi" + I2S(AGI))
        call BJDebugMsg("int" + I2S(INT))
        set s1 = ""
        set s2 = ""
        set s3 = ""

//---------- check if 2 character length would be sufficient for hero coord or no ----

        set COORD_LEN_X = SL_GetIntegerSize(MAX_X * 2)
        set COORD_LEN_Y = SL_GetIntegerSize(MAX_Y * 2)
        call BJDebugMsg("4")
//------------------------------------------------------------------------------------
        // ----- we get the hero index from hashtable, if it will be 0, then not found
        set CLASS = LoadInteger(udg_SL_HASHTABLE, 2, GetUnitTypeId(u))
        // --- if isn't 0 then Hero was stored into array and we continue -----

        if CLASS != 0 then
            // --- we get every data, what we will use that not sure yet ----
            set LV = GetHeroLevel(u)
            set EXP = GetHeroXP(u)
            set STR = GetHeroStr (u, false)
            set AGI = GetHeroAgi (u, false)
            set INT = GetHeroInt (u, false)
            set GOLD = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
            set LUMBER = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
            call BJDebugMsg("5")
            //formating the stuff to max value if maybe it is higher
            set LV = ModuloInteger(LV, PowL[2] + 1)
            set EXP = ModuloInteger(EXP, PowL[4] + 1)
            set STR = ModuloInteger(STR, PowL[2] + 1)
            set AGI = ModuloInteger(AGI, PowL[2] + 1)
            set INT = ModuloInteger(INT, PowL[2] + 1)
            set GOLD = ModuloInteger(GOLD, MAX_GOLD() + 1)
            set LUMBER = ModuloInteger(LUMBER, MAX_GOLD() + 1)
            //if your hero not maxed level then
            if MAX_HERO_LEVEL() != LV then
                // -- we get the MinExp, MaxExp, CurExp with createing a dummy unit at player 1 start location
                set loc = GetStartLocationLoc(GetPlayerStartLocation(Player(0)))
                set d = CreateUnit(Player(0), GetUnitTypeId(u), GetLocationX(loc), GetLocationY(loc), 0)
                call RemoveLocation(loc)
                if LV == 1 then
                    set MinExp = 0
                else
                    call SetHeroLevel(d, LV, false)
                    set MinExp = GetHeroXP(d)
                endif
                call SetHeroLevel(d, LV + 1, false)
                set MaxExp = GetHeroXP(d) - 1
                call RemoveUnit(d)
                set CurExp = EXP - MinExp
            else
                set MinExp = EXP
                set MaxExp = EXP
                set CurExp = 0
            endif
            call BJDebugMsg("5.5")
            //lets start build the H_CODE with class then with level
            //lets check if max class is higher than the Alpahabet string base
            set a1 = 1
            if MAX_HERO > PowL[1] then
                set a1 = 2
            endif
            set CODE = SL_IntegerToCode(CLASS, a1)
            call BJDebugMsg("6")
            //we must figure out what better, if we save LV+CurExp or total EXP
            set s1 = SL_IntegerToCode(LV, - 1) + SL_IntegerToCode(CurExp, - 1)
            set s2 = SL_IntegerToCode(EXP, - 1)
            set a1 = StringLength(s1)
            set a2 = StringLength(s2)
            if a1 > a2 then
                set Key = "0" + I2S(a2)
                set CODE = CODE + s2
            else
                set Key = I2S(StringLength(SL_IntegerToCode(LV, - 1))) + I2S(StringLength(SL_IntegerToCode(CurExp, - 1)))
                set CODE = CODE + s1
            endif

            //next piece what we save is the stats
            if SL_SAVE_STAT() then
                set s1 = SL_IntegerToCode(STR, - 1)
                set s2 = SL_IntegerToCode(AGI, - 1)
                set s3 = SL_IntegerToCode(INT, - 1)
                set a1 = StringLength(s1)
                set a2 = StringLength(s2)
                set a3 = StringLength(s3)
                set CODE = CODE + s1 + s2 + s3
                set Key = Key + I2S(a1) + I2S(a2) + I2S(a3)
            else
                set Key = Key + "111"
            endif
            call BJDebugMsg("7")
            //saveing resource part: gold and lumber    
            if SL_SAVE_GOLD() and SL_SAVE_LUMBER() then
                call BJDebugMsg("7.01")

                if not (GOLD == 0 and LUMBER == 0) then
                    set s1 = SL_IntegerToCode(GOLD, - 1)
                    set s2 = SL_IntegerToCode(LUMBER, - 1)
                    set a1 = StringLength(s1)
                    set a2 = StringLength(s2)
                    set CODE = CODE + SL_IntegerToCode((a1 * 10 + a2), - 1) + s1 + s2
                    set Key = Key + I2S(a1)
                    set Key = Key + I2S(a2)
                    call BJDebugMsg("7.02")
                else
                    call BJDebugMsg("7.03")
                    set Key = Key + "00"
                endif

                call BJDebugMsg("7.1")
            elseif SL_SAVE_GOLD() then
                call BJDebugMsg("7.101")
                if GOLD > 0 then
                    call BJDebugMsg("7.102")
                    set CODE = CODE + SL_IntegerToCode(GOLD, - 1)
                    set Key = Key + I2S(StringLength(SL_IntegerToCode(GOLD, - 1)))
                    call BJDebugMsg("7.103")
                else
                    set Key = Key + "0"
                    call BJDebugMsg("7.104")
                endif
                set Key = Key + "0"
                call BJDebugMsg("7.105")
            elseif SL_SAVE_LUMBER() then
                call BJDebugMsg("7.106")
                set Key = Key + "0"
                if LUMBER > 0 then
                    set CODE = CODE + SL_IntegerToCode(LUMBER, - 1)
                    set Key = Key + I2S(StringLength(SL_IntegerToCode(LUMBER, - 1)))
                    call BJDebugMsg("7.107")
                else
                    set Key = Key + "0"
                endif
            else
                set Key = Key + "00"
            endif

            call BJDebugMsg("7.2")
            //we save hero coordinates (X,Y) with shift
            if SAVE_COORD then
                set a1 = R2I(GetUnitX(u)) + MAX_X //x coordinate with shift for don't be negative number
                set a2 = R2I(GetUnitY(u)) + MAX_Y //y coordinate with shift for don't be negative number
                set CODE = CODE + SL_IntegerToCode(a1, COORD_LEN_X) + SL_IntegerToCode(a2, COORD_LEN_Y)
            endif

            call BJDebugMsg("7.3")
            //we search after Key index in VAR array, when Key == VAR[index] then we save index
            set a1 = SL_GetIntegerSize(MAX_VAR)
            set a2 = - 1
            set i = 0
            call BJDebugMsg("max" + I2S(MAX_VAR))
            call BJDebugMsg("size" + I2S(SL_GetIntegerSize(MAX_VAR)))
            call BJDebugMsg("key" + Key)
            loop
                exitwhen i > MAX_VAR or a2 != - 1

                if LoadStr(udg_SL_HASHTABLE, 1, i) == Key then
                    call BJDebugMsg(LoadStr(udg_SL_HASHTABLE, 1, i))
                    set a2 = i
                endif
                set i = i + 1
            endloop
            call BJDebugMsg("7.4")
            if a2 != - 1 then
                set s1 = SL_IntegerToCode(a2, a1)
                set CODE = s1 + CODE
                set ERROR = false
            endif
        endif
        call BJDebugMsg("8")
        //we save the craft progress and check if unit got equiped stuff, got item in inventory
        set a1 = 0
        if BLACKSMITH >= l then
            set a1 = a1 + 1
        endif
        if TAILOR >= l then
            set a1 = a1 + 2
        endif
        if JEWELLER >= l then
            set a1 = a1 + 4
        endif
        if PHARMACIST >= l then
            set a1 = a1 + 8
        endif
        if EQ_Count > 0 then
            set a1 = a1 + 16
        endif
//        if INV_Count > 0 then
//          set a1 = a1+32
//        endif
        call BJDebugMsg("9")
        set CODE = CODE + SL_IntegerToCode(a1, 1) + SL_IntegerToCode(BLACKSMITH, - 1) + SL_IntegerToCode(TAILOR, - 1) + SL_IntegerToCode(JEWELLER, - 1) + SL_IntegerToCode(PHARMACIST, - 1)
        set HERO_NAME = GetUnitName(u)
        set HERO_LV = I2S(LV)
        call BJDebugMsg("10"+CODE)
        // let prepare the loooong code 
        set CODE_Row_Count = 1
        set CODE_Row[CODE_Row_Count] = CODE
        
        set i = 1
        loop
            exitwhen i > 10
            if EQC[i] != null then
                set a1 = StringLength(EQC[i])
                set a2 = StringLength(CODE_Row[CODE_Row_Count])
                if a1 + a2 > MAX_CHAR then
                    set s1 = SL_CodeCheckSum(CODE_Row[CODE_Row_Count], p)
                    set s2 = SL_CodeCheckSum(CODE_Row[1], p)
                    if CODE_Row_Count != 1 then
                        set CODE_Row[CODE_Row_Count] = s1 + SL_IntegerToCode(CODE_Row_Count, 1) + CODE_Row[CODE_Row_Count] + s2
                    else
                        set s3 = SL_IntegerToCode(EQ_B_CODE1, - 1)
                        if EQ_B_CODE1 > 31 then
                            set s3 = s3 + SL_IntegerToCode(EQ_B_CODE2, - 1)
                        endif
                        set CODE_Row[CODE_Row_Count] = s1 + s3 + CODE_Row[CODE_Row_Count] + s2
                    endif
                    set CODE_Row_Count = CODE_Row_Count + 1
                    set CODE_Row[CODE_Row_Count] = EQC[i]
                else
                    set CODE_Row[CODE_Row_Count] = CODE_Row[CODE_Row_Count] + EQC[i]
                endif
            set EQC[i] = null
            endif
            set i = i + 1
        endloop

        if not ERROR then
            set CODE = CODE + SL_CodeCheckSum(CODE, p)
            set PATH = SL_FOLDER() + "\\" + HERO_NAME + " - " + HERO_LV + " by " + GetPlayerName(p) + ".txt"
            //if StringLength(CODE) < 60 then
            //call DisplayTextToPlayer ( p, 0, 0, "|cffffff00Code:|r -Load " + SL_Colorized_Code(CODE, "00FF00", "FFFF00", "00FFFF", "FF00FF", 0) )
            //    call DisplayTextToPlayer ( p, 0, 0, "|cffffff00Code:|r -Load " + CODE )
           // else
              //  call DisplayTextToPlayer ( p, 0, 0, "|cffffff00Code:|r -Load " + CODE )
            //endif
            call DisplayTextToPlayer ( p, 0, 0, "|cff7777ffNote:|r Code saved into |cffff8888" + PATH + "|r")
            set i = 1
            if GetLocalPlayer() == p then
                call PreloadGenClear()
                call PreloadGenStart()
                call Preload("\r\n\t\t\t\tHero: " + HERO_NAME + "\r\n\t\t\t\t" + "Level: " + HERO_LV + "\t\t\r\n\t\t\t\t" + "Name: " + GetPlayerName(p) + "\t\t\r\n" )
                loop
                    exitwhen i > CODE_Row_Count
                    call Preload("Code " + I2S(i) + ": " + CODE_Row[i] + "\t\t\r\n" )
                    call DisplayTextToPlayer ( p, 0, 0, CODE_Row[i] )
                    set i = i + 1
                endloop
                call PreloadGenEnd(PATH)
                set i = 1
            endif
        else
            call DisplayTextToPlayer ( p, 0, 0, "|cffff7777Warning:|r something went wrong." )
        endif
        set p = null
        set loc = null
        set d = null
        set u = null
    endif
return false
endfunction

//===========================================================================
function InitTrig_Save_Game_ability takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 0
//EVENT_PLAYER_UNIT_SPELL_CAST   -    EVENT_PLAYER_UNIT_SPELL_FINISH
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_CAST, null)
        set i = i + 1
        exitwhen i == 16
    endloop
    call TriggerAddCondition( t, Condition( function Create_Save_Load_Code ) )
    set t = null
endfunction


JASS:
function SL_IntegerToCode takes integer i, integer len returns string
    local string s = ""
    local integer m = 0
    local integer c
    local string ss = SL_CODE()
    local integer l = StringLength(ss)
    local boolean e = false
    if l < 36 then
        set c = 7
    elseif l < 74 then
        set c = 6
    else
        set c = 5
    endif

    if i <= Pow(l, c - 1) then
        loop
            set c = c - 1
            if c > 0 then
                if not e and i >= Pow(l, c) then
                    set e = true
                endif
                    
                set m = i / R2I(Pow(l, c))
                set i = i - m * R2I(Pow(l, c))

                if not e and m == 0 then
                else
                    set s = s + SubString(ss, m, m + 1)
                endif

            else
                set m = ModuloInteger(i, l)
                set s = s + SubString(ss, m, m + 1)
                set i = 0
            endif
            exitwhen c == 0
        endloop
    endif
    if len != - 1 then
        loop
            exitwhen StringLength(s) >= len
            set s = SubString(ss, 0, 1) + s
        endloop
    endif
    return s
endfunction

function SL_CodeToInteger takes string c returns integer
    local integer l = StringLength(c)
    local integer m = StringLength(SL_CODE())
    local integer i = 0
    local integer char
    local string s 
    local integer int = 0
    if l > 0 then
        loop
            exitwhen i == l
            set s = SubString(c, i, i + 1)
            if s != StringCase(s, true) then
              set char = LoadInteger(udg_SL_HASHTABLE, StringHash(s), 2)
            else
              set char = LoadInteger(udg_SL_HASHTABLE, StringHash(s), 1) 
            endif
            if char !=0 or i > 0 then
                set int = int + R2I(Pow(m, l - i - 1)) * char
            endif
            set i = i + 1
        endloop
    endif
    set s = null
    return int
endfunction

function SL_GetIntegerSize takes integer a returns integer
local integer base = StringLength(SL_CODE())
local integer max = 4
local integer i = 0
if base < 64 then
   set max = 6
elseif base < 74 then
   set max = 5
endif

loop
set i = i + 1
exitwhen i > max
if a < R2I(Pow(base,i)) then
  return i
endif
endloop
endfunction

function SL_CodeCheckSum takes string c, player p returns string
    local string EC = SL_CODE()
    local integer cl = SL_CRC_LEN()
    local integer MaxV = R2I(Pow(StringLength(EC), cl))
    local integer i
    
    if SL_BIND_TO_PLAYER() then
        set i = StringHash(c + StringCase(GetPlayerName(p), false))
    else
        set i = StringHash(c)
    endif

    if i < 0 then
        set i = i * - 1
    endif

    if i > MaxV then
        set i = ModuloInteger(i, MaxV)
    endif

    return SL_IntegerToCode(i, cl)
endfunction

//we inline the bonus stats for make it easier for other functions, like SaveLoad and Multiboard
function Inline_Item_Bonus_Stat takes integer i returns integer
local integer a = 0
local integer max = 42
local integer array IS
            set IS[0] = 40
            set IS[1] = 47
            set IS[2] = 27
            set IS[3] = 31
            set IS[4] = 28
            set IS[5] = 29
            set IS[6] = 32
            set IS[7] = 33
            set IS[8] = 22
            set IS[9] = 23
            set IS[10] = 24
            set IS[11] = 44
            set IS[12] = 45
            set IS[13] = 46
            set IS[14] = 48
            set IS[15] = 55
            set IS[16] = 49
            //57-81
            set a = 17
            loop
                set IS[a] = a + 40
                set a = a + 1
                exitwhen a > max
            endloop
if i >= 0 and i <= max then
   return IS[i]
else
   return 0
endif
endfunction

//we inline the bonus stats length for make it easier for other functions, like SaveLoad
//this need to type manually, what is the max value for each item stat bonus, if return 1 then
//stat not higher than 82, if return 2 then not higher than 82*82
function Inline_Item_Bonus_Stat_Length takes integer i returns integer
local integer a = 0
local integer max = 99
if i >= 0 and i <= max then
   //bonus: hp, mp, mdef, pdef, damages could be higher than 83
   if (i >= 57 and i < 66) or i == 67 or i == 68 or (i > 72 and i < 81) or i == 82 or i == 40 or i == 47 then
       return 2
   else
       return 1
   endif
else
   return 0
endif
endfunction


2. here dmg trigger totally skipped sometimes when attacking revived hero (randomly start, like killed same enemy hero (example paladin at neutral hostile) 10-20x then suddenly stop running the trigger but if u target another unit then work vs them only vs that pervious hero no, but after a time automatically start work vs 'bugged' hero too)

you can test if u use whosyourdaddy or equip equipment and attack blood mage and orc blademaster for longer time


JASS:
function UnitDamageTargetEx takes unit localSource, unit localTarget, real localAmount, boolean attack, boolean ranged, attacktype localAttackType, damagetype localDamageType, weapontype localWeaponType returns boolean
    // Avoid infinite loop due to recursion
    if udg_PDD_damageType == udg_PDD_CODE then
        return false
    endif
   
    // Avoid allocating attacks on units that are about to be killed
    if ( localTarget == udg_PDD_target and GetUnitLife(localTarget) - udg_PDD_amount < udg_PDD_UNIT_MIN_LIFE ) then
        return false
    endif
   
    // Store all damage parameters determined by the user
    set udg_PDD_allocatedAttacks = udg_PDD_allocatedAttacks + 1
    call SaveUnitHandle(udg_PDD_h, udg_PDD_allocatedAttacks, 0, localSource)
    call SaveUnitHandle(udg_PDD_h, udg_PDD_allocatedAttacks, 1, localTarget)
    call SaveReal(udg_PDD_h, udg_PDD_allocatedAttacks, 2, localAmount)
    call SaveBoolean(udg_PDD_h, udg_PDD_allocatedAttacks, 3, attack)
    call SaveBoolean(udg_PDD_h, udg_PDD_allocatedAttacks, 4, ranged)
    call SaveInteger(udg_PDD_h, udg_PDD_allocatedAttacks, 5, GetHandleId(localAttackType))
    call SaveInteger(udg_PDD_h, udg_PDD_allocatedAttacks, 6, GetHandleId(localDamageType))
    call SaveInteger(udg_PDD_h, udg_PDD_allocatedAttacks, 7, GetHandleId(localWeaponType))

    // Return true if the damage was allocated
    return true
endfunction


function DamageDecrease takes integer cv, integer slot, real amount returns nothing
    local item itm
    local integer id
    local real dur
    local integer pl = GetPlayerId(GetOwningPlayer(udg_UDexUnits[cv])) + 1
    if HaveSavedHandle(udg_Stat_Table, cv, slot ) then
    set itm = LoadItemHandle(udg_Stat_Table, cv, slot )
    if slot < 10 and itm != null and amount > 0 then
        set id = GetHandleId(itm)

        set dur = LoadReal(udg_CItem_Table, id, 14) - amount
        call SaveReal(udg_CItem_Table, id, 14, dur)
        if dur < 11 then
            if not LoadBoolean(udg_Stat_Table, - cv, - 3 ) then
                call SaveBoolean(udg_Stat_Table, - cv, - 3, true )
                call DisplayTextToPlayer (Player(pl - 1), 0, 0, "|cffff0000Warning:|r |cffffff00" + GetItemName(itm) + "|r |cffff0000got low duratibility!!|r")
            endif
            if dur < 1 then
                call ForcedUnequip (cv, slot)
                call DisplayTextToPlayer (Player(pl - 1), 0, 0, "|cffff0000Broken item:|r |cffffff00" + GetItemName(itm) + "|r |cffff0000got no duratibility!!|r")
            endif
        endif
    endif
    set itm = null
    endif
endfunction

function Trig_Set_Damage takes nothing returns boolean
    local unit a = udg_PDD_source
    local unit t = udg_PDD_target
    local integer ap = GetPlayerId(GetOwningPlayer(a)) + 1
    local integer tp = GetPlayerId(GetOwningPlayer(t)) + 1
    local integer acv = GetUnitUserData(a)
    local integer tcv = GetUnitUserData(t)
    local integer rnd //random for hit chance
    local real dmg = udg_PDD_amount
    local real dmgaddon
    local real r
    local real tr
    local real block
    local real eva
    local real alv
    local real dlv
    local real crit
    local real critdmg
    local real pdef
    local real mdef
    local integer hit
    local integer pv
    local real attackerlv
    local real targetlv
    local real PhysicalRed
    local real MagicRed
    local real ref = udg_Global_Reflect[tcv]
    local real ls = udg_Global_LifeSteal[acv]
    local real ms = udg_Global_ManaSteal[acv]
    local real DmgRed
    local integer DDType = udg_PDD_damageType//1=physical, 2=spell, 3=custom dmg
    local integer MDType = udg_PDD_magicType//0=physical, 1=fire, 2=water,3=lightning,4=poison,5=earth
if dmg > 0 then
    if MDType > 99 then
        set MDType = MDType - 100
        set DDType = 3
    endif
    if dmg <= 0 then
        set udg_PDD_amount = 1
        set dmg = udg_PDD_amount
    endif
          //  call DisplayTextToForce( GetPlayersAll(), I2S(dmgtype)+"-"+I2S(DamageTypeDOT)+R2S(udg_Global_MDmg4[acv]) )
    if DDType == 1 and MDType == 0 then
        if udg_Global_MDmg1[acv] > 0.00 then
            set udg_PDD_magicType = 1
            call UnitDamageTargetEx (a, t, udg_Global_MDmg1[acv], true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
        elseif udg_Global_MDmg2[acv] > 0.00 then
            set udg_PDD_magicType = 2
            call UnitDamageTargetEx (a, t, udg_Global_MDmg2[acv], true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
        elseif udg_Global_MDmg3[acv] > 0.00 then
            set udg_PDD_magicType = 3
            call UnitDamageTargetEx (a, t, udg_Global_MDmg3[acv], true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
        elseif udg_Global_MDmg4[acv] > 0.00 then
            set udg_PDD_magicType = 4
            call UnitDamageTargetEx (a, t, udg_Global_MDmg4[acv], true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
        elseif udg_Global_MDmg5[acv] > 0.00 then
            set udg_PDD_magicType = 5
            call UnitDamageTargetEx (a, t, udg_Global_MDmg5[acv], true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
        endif
        //call DestroyEffect(AddSpecialEffectTarget(udg_Effects[1], t, EFFECT_POINT(30)))
        //call FT (Player(ap-1), Player(tp-1),I2S(R2I(dmgaddon)), 0.8, t, 20, 100, 100, 255, 200)
    endif

    if ( IsUnitType(a, UNIT_TYPE_HERO) ) then
        set attackerlv = GetHeroLevel(a)
    else
        set attackerlv = GetUnitLevel(a)
    endif
    if ( IsUnitType(t, UNIT_TYPE_HERO) ) then
        set targetlv = GetHeroLevel(t)
    else
        set targetlv = GetUnitLevel(t)
    endif
            
    //pet power if you got summoner class, i not enabled it
    //if ( udg_Pet[GetUnitUserData(udg_Hero[ap])] == a and udg_Class2[ap]==6 ) then
    //    set dmg = dmg + (udg_Stat_Pet_Power[ap] + GetHeroInt(udg_Hero[ap], true)/100.00) * dmg
    //endif

    set block = udg_Global_Block[tcv]
    set alv = udg_Global_AttLv[acv]
    set dlv = udg_Global_DefLv[tcv]

    if ( GetPlayerController(GetOwningPlayer(a)) != MAP_CONTROL_USER ) then
        set pv = GetUnitPointValue(a)
        if pv >= 50 and pv < 55 then
            set MDType = pv - 49
        endif
        set alv = udg_Global_AttLv[acv]
    endif

// call DisplayTextToPlayer(Player(0),0,0,GetUnitName(a)+" TYPE"+I2S(DDType)+" mtype"+I2S(MDType)+"-->amount"+" dmg"+R2S(dmg))


    if ( GetPlayerController(GetOwningPlayer(t)) != MAP_CONTROL_USER ) and udg_Difficulty != 1 then
        set dlv = udg_Global_DefLv[tcv] + udg_Difficulty * 10
    else
        if GetPlayerController(GetOwningPlayer(t)) == MAP_CONTROL_USER and GetPlayerController(GetOwningPlayer(a)) == MAP_CONTROL_USER then
            set dmg = dmg / 4
        endif
        set dlv = udg_Global_DefLv[tcv]
    endif


    set crit = udg_Global_Crit[acv]
    set critdmg = udg_Global_CritDmg[acv] + DEFAULT_CRITICAL_DAMAGE()
    set eva = ( udg_Global_Eva[tcv] - 1.00 ) / ( ( 2.00 * udg_Global_Acc[acv] ) + ( udg_Global_Eva[tcv] - 1.00 ) )
    set hit = HitChance(acv, tcv)//R2I((1.00 - eva) * 100.00)

    set pdef = udg_Global_Pdef[tcv]

    if MDType == 1 then
        set mdef = udg_Global_Mdef1[tcv]
    elseif MDType == 2 then
        set mdef = udg_Global_Mdef2[tcv]
    elseif MDType == 3 then
        set mdef = udg_Global_Mdef3[tcv]
    elseif MDType == 4 then
        set mdef = udg_Global_Mdef4[tcv]
    elseif MDType == 5 then
        set mdef = udg_Global_Mdef5[tcv]
    else
        set mdef = 0
    endif

    set dmg = dmg + (udg_Global_DmgInc[acv] - udg_Global_DmgRed[tcv]) / 100.00 * dmg

    if mdef < 0 then
        set mdef = 0
    endif

    if pdef < 0 then
        set pdef = 0
    endif
    set rnd = GetRandomInt(0, 99)
    if rnd < hit and MDType == 0 and DDType == 1 then
        set dmg = 0.00
        call FT (Player(ap - 1), Player(tp - 1), "Miss!", 0.9 , t, 7, 51, 51, 255, 200)
        set DmgRed = 0
    else
        set rnd = GetRandomInt(0, 99)
        if rnd < block and DDType < 3 then
            set dmg = 0.00
            call FT (Player(ap - 1), Player(tp - 1), "Blocked!", 0.9, t, 7, 0, 0, 255, 200)
            set DmgRed = 0
        else
            set PhysicalRed = pdef / ( 40.00 * attackerlv + pdef + 25.00 )
            set MagicRed = mdef / ( 40.00 * attackerlv + mdef + 25.00 )
            set rnd = GetRandomInt(0, 99)
            if rnd < udg_Global_ArmorBreak[acv] then
                //it was completly ignore the defence but seems that op without high hp
                //so i changed so i increased the incoming dmg with divide target ressitance% by 2
                //set DmgRed = 1
                set PhysicalRed = PhysicalRed / 2.00
                set MagicRed = MagicRed / 2  
            endif
                if MDType > 1 then
                    set DmgRed = ( 1 - MagicRed )
                else
                    set DmgRed = 1 - PhysicalRed 
                endif

                set dmg = dmg * DmgRed

            if GetPlayerController(GetOwningPlayer(t)) == MAP_CONTROL_USER and DmgRed > 0 then
                call DamageDecrease (tcv, 1, DmgRed / 5)
                call DamageDecrease (tcv, 2, DmgRed / 5)
                call DamageDecrease (tcv, 4, DmgRed / 5)
                call DamageDecrease (tcv, 5, DmgRed / 5)
                call DamageDecrease (tcv, 6, DmgRed / 5)
                call DamageDecrease (tcv, 7, DmgRed / 5)
                call DamageDecrease (tcv, 8, DmgRed / 5)
                call DamageDecrease (tcv, 9, DmgRed / 5)
                if udg_Inv_Sens[tp] and udg_Camera_Lock[tp] > 0 then
                      call WindowTransition (tp, udg_Camera_Lock[tp], 0)
                endif
            endif


            if GetPlayerController(GetOwningPlayer(a)) == MAP_CONTROL_USER then
                if HaveSavedHandle(udg_Stat_Table, acv, 3) then
                   call DamageDecrease (acv, 3, 0.05)
                   set rnd = GetHandleId(LoadItemHandle(udg_Stat_Table, acv, 3 ))
                   set dmg = GetRandomReal(WeaponMinDamageModifier(LoadInteger(udg_CItem_Table, rnd, 3))*dmg, dmg)
                endif
            endif

            if ( alv > dlv ) then
                set dmg = dmg * ( 1 + ( alv - dlv ) / 100.00 )
            else
                set dmg = dmg / ( 1.00 + ( dlv - alv ) / 120.00)
            endif

            if udg_Global_Act_Id[acv] > 0 then
              set rnd = GetRandomInt(0, 99)
              if udg_Global_Act_Id[acv] == 1 then
                 if rnd < 5 then
                    set dmg = dmg * 2
                    call DestroyEffect(AddSpecialEffectTarget(EFFECT(1), t, EFFECT_POINT(30)))
                    if GetUnitMaxLife(a)*0.05 > GetUnitLife(a) then
                       call SetUnitLife(a, 1)         
                    else
                       call SetUnitLife(a, GetUnitLife(a)-(GetUnitMaxLife(a)*0.05)) 
                    endif
                 endif
               elseif udg_Global_Act_Id[acv] == 2 then
                 if rnd < 5 then
                    call AddOT (a, a, -1, R2I(GetUnitMaxLife(a)*0.1), 20)
                 endif
               elseif udg_Global_Act_Id[acv] == 3 then
                 if rnd < 5 then
                    call AddOT (a, t, 0, udg_Stat_Dmg[acv]+50, 20)
                 endif
               elseif udg_Global_Act_Id[acv] == 4 then
                 if rnd < 5 then
                    call AddUnitBuff (a, 6, 25, 5, 0, 0)
                    call AddUnitBuff (a, 7, -25, 5, 0, 0)
                 endif
               elseif udg_Global_Act_Id[acv] == 5 then
                 if rnd < 5 then
                    call AddUnitBuff (a, 9, 13, 6, 0, 0)
                    call AddUnitBuff (a, 10, 13, 6, 0, 0)
                 endif
               elseif udg_Global_Act_Id[acv] == 6 then
                 if rnd < 5 then
                    call AddUnitBuff (t, 7, -15, 5, 0, 0)
                 endif
               elseif udg_Global_Act_Id[acv] == 7 then
                 if rnd < 5 then
                    call AddUnitBuff (a, 11, 100, 4, 0, 0)
                 endif
               elseif udg_Global_Act_Id[acv] == 8 then
                 if rnd < 5 then
                    call AddUnitBuff (a, 15, R2I(udg_Stat_Pdef[acv]*0.6), 20, 0, 0)
                    call AddUnitBuff (a, 16, R2I(udg_Stat_Mdef1[acv]*0.6), 20, 0, 0)
                    call AddUnitBuff (a, 17, R2I(udg_Stat_Mdef2[acv]*0.6), 20, 0, 0)
                    call AddUnitBuff (a, 18, R2I(udg_Stat_Mdef3[acv]*0.6), 20, 0, 0)
                    call AddUnitBuff (a, 19, R2I(udg_Stat_Mdef4[acv]*0.6), 20, 0, 0)
                    call AddUnitBuff (a, 20, R2I(udg_Stat_Mdef5[acv]*0.6), 20, 0, 0)
                 endif
               elseif udg_Global_Act_Id[acv] == 9 then
                 if rnd < 25 then
                    call AddUnitBuff (a, 5, 50, 4, 0, 0)
                 endif
              endif
            endif

            if GetRandomReal(0.00, 100) <= crit and DDType < 3 and dmg > 0 then
                set dmg = dmg * critdmg / 100.00
                call FT (Player(ap - 1), Player(tp - 1), I2S(R2I(dmg)), 1.5, t, 10, 255, 0, 0, 200)
            else
                call FT (Player(ap - 1), Player(tp - 1), I2S(R2I(dmg)), 0.8, t, 15, 179, 255, 51, 200)
            endif

            if DDType < 3 and dmg > 5 then
                if ls > 0 then
                    set r = dmg * ls / 100.00
                    set ls = GetUnitLife(a) + r
                    call SetUnitLife(a, ls )
                    if r > 0.99 then
                        call FT_Ex (Player(ap - 1), Player(tp - 1), "+" + I2S(R2I(r)), 0.8, a, 15, 255, 30, 30, 200, 0)
                    endif
                endif
                if ms > 0 then
                    set r = dmg * ms / 100.00
                    set ms = GetUnitState(a, UNIT_STATE_MANA) + r
                    call SetUnitState(a, UNIT_STATE_MANA, ms )
                    if r > 0.99 then
                        call FT_Ex (Player(ap - 1), Player(tp - 1), "+" + I2S(R2I(r)), 0.8, a, 15, 30, 30, 255, 200, 180)
                    endif
                endif
                if ref > 0 then
                    set dmgaddon = dmg * ref / 100.00
                    call UnitDamageTargetEx (a, t, dmgaddon, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, null)
                    if dmgaddon > 0.99 then
                        set udg_PDD_magicType = MDType
                        call FT_Ex (Player(ap - 1), Player(tp - 1), I2S(R2I(dmgaddon)), 1, t, 13, 70, 255, 30, 200, 270)
                    endif
                endif
            endif
        endif
    endif

    set udg_PDD_amount = dmg
    set udg_PDD_magicType = 0


    if udg_CombatTimer[tcv] < 1 then
        set udg_CombatTimer[tcv] = 10
        set udg_CombatIndex = udg_CombatIndex + 1
        set udg_CombatI2CV[udg_CombatIndex] = tcv
        call StatRefresh (tcv)
        if udg_Camera_Lock[tp] == 1 then
            call ShowStat (tp)
        endif
    else
        set udg_CombatTimer[tcv] = 10
    endif

    if udg_CombatTimer[acv] < 1 then
        set udg_CombatTimer[acv] = 10
        set udg_CombatIndex = udg_CombatIndex + 1
        set udg_CombatI2CV[udg_CombatIndex] = acv
        call StatRefresh (acv)
        if udg_Camera_Lock[ap] == 1 then
           call ShowStat (ap)
        endif
    else
        set udg_CombatTimer[acv] = 10
    endif

    //call DisplayTextToPlayer(Player(0),0,0,"3-->amount"+" dmg"+R2S(dmg))
endif

    set a = null
    set t = null
    return false
endfunction

//===========================================================================
function InitTrig_Set_Damage takes nothing returns nothing
    set gg_trg_Set_Damage = CreateTrigger( )
    call TriggerRegisterVariableEvent( gg_trg_Set_Damage, "udg_PDD_damageEventTrigger", EQUAL, 1.00 )
    call TriggerAddCondition( gg_trg_Set_Damage, Condition( function Trig_Set_Damage ) )
endfunction
 

Attachments

  • 1_Shadowvzs ORPG v0.99z_MUI.w3x
    1 MB · Views: 49

Kazeon

Hosted Project: EC
Level 33
Joined
Oct 12, 2011
Messages
3,449
There must be something to do with the OP limit. To solve it you should run several parts of the code into separated "thread". This is just one example:
JASS:
function display takes nothing returns nothing
    call BJDebugMsg("aaa")
endfunction

// This method will mostly hits the OP limit, the "done" message won't be displayed
function caller1 takes nothing returns nothing
    local integer i = 10000

    loop
        exitwhen i < 0
        // Directly display
        call BJDebugMsg("aaa")
        set i = i - 1
    endloop
    call BJDebugMsg("done")
endfunction

// While this one does not
function caller2 takes nothing returns nothing
    local integer i = 10000

    loop
        exitwhen i < 0
        // Display the message at a separated thread
        call ForForce(bj_FORCE_PLAYER[0], function display)
        set i = i - 1
    endloop
    call BJDebugMsg("done")
endfunction

That's a poor example, bcs I'm too lazy to open WE right now.
 
Level 17
Joined
Nov 13, 2006
Messages
1,814
There must be something to do with the OP limit. To solve it you should run several parts of the code into separated "thread". This is just one example:
JASS:
function display takes nothing returns nothing
    call BJDebugMsg("aaa")
endfunction

// This method will mostly hits the OP limit, the "done" message won't be displayed
function caller1 takes nothing returns nothing
    local integer i = 10000

    loop
        exitwhen i < 0
        // Directly display
        call BJDebugMsg("aaa")
        set i = i - 1
    endloop
    call BJDebugMsg("done")
endfunction

// While this one does not
function caller2 takes nothing returns nothing
    local integer i = 10000

    loop
        exitwhen i < 0
        // Display the message at a separated thread
        call ForForce(bj_FORCE_PLAYER[0], function display)
        set i = i - 1
    endloop
    call BJDebugMsg("done")
endfunction

That's a poor example, bcs I'm too lazy to open WE right now.

op limit related with loop or with character amount in 1 function or what?
i deleted few thing from there but its stoped in same place, also stop allways after loop, so still show after the loop the 2 BJDebugMsg (if less than 6 item then even more)

other side lets say separate a big loop from others but that would help?

[edit]
i separeted it but same thread die


JASS:
function EquipmentsToCode takes unit u returns integer
    local integer ITEM_STR = 0
    local integer ITEM_AGI = 0
    local integer ITEM_INT = 0
    local integer ut = GetUnitTypeId(u)
    local integer START_STR = LoadInteger(udg_FSS, 636, ut)
    local integer START_AGI = LoadInteger(udg_FSS, 637, ut)
    local integer START_INT = LoadInteger(udg_FSS, 638, ut)
    local integer DURATIBILITY
    local integer MAX_INVENTORY = 20 //our inventory capacity is 20 item
    local integer GEM_LEN = SL_GetIntegerSize(LoadInteger(udg_CItem_Table, - 2000, 0))
    local integer cv = GetUnitUserData(u)
    local item itm
    local integer id
    local integer l = StringLength(SL_CODE())
    local integer i
    local integer ii
    local integer EQ_Count = 0
    local integer a1
    local integer a2
    local integer a3
    local integer a4
    local integer b1
    local integer b2
    local integer b3
    local integer b4
    local integer BONUS //predefined bonus stat index's from items
    local integer BONUS_LEN //predefined bonus stats length from items (1 = 0 - 82, 2 = 0 - 6400)

    set udg_SL_EQ_B_CODE1 = 0
    set udg_SL_EQ_B_CODE2 = 0

        //we calculate how much str, agi, int coming from items - directly and from sockets
        //we start in inventory - we check the charms
        set i = 1
        loop
            exitwhen i > MAX_INVENTORY
            if HaveSavedHandle(udg_Stat_Table, cv, i + 99) then
                set itm = LoadItemHandle(udg_Stat_Table, cv, i + 99)
                if GetItemLevel(itm) == 111 then //if item level is 111 then item is charm
                    set id = GetHandleId(itm)
                    set ITEM_STR = ITEM_STR + LoadInteger(udg_CItem_Table, id, 44)
                    set ITEM_AGI = ITEM_AGI + LoadInteger(udg_CItem_Table, id, 45)
                    set ITEM_INT = ITEM_INT + LoadInteger(udg_CItem_Table, id, 46)
                endif
            endif
            set i = i + 1
        endloop
        set itm = null

        //we start build the code for equipments, each equipment individually and at end combine to a large row
        //equipment slots: 1 - 10 

        set i = 1
        loop
            exitwhen i == 11
            set udg_SL_EQC[i] = null
            //if in equipment slot have saved item then
            if HaveSavedHandle(udg_Stat_Table, cv, i) then
                if i < 6 then
                    set udg_SL_EQ_B_CODE1 = udg_SL_EQ_B_CODE1 + udg_Pow2[i - 1]
                else
                    if udg_SL_EQ_B_CODE1 < 32 then
                        set udg_SL_EQ_B_CODE1 = udg_SL_EQ_B_CODE1 + 32
                    endif
                    set udg_SL_EQ_B_CODE2 = udg_SL_EQ_B_CODE2 + udg_Pow2[i - 6]
                endif
                set EQ_Count = EQ_Count + 1
                set id = GetHandleId(LoadItemHandle(udg_Stat_Table, cv, i))
                set ITEM_STR = ITEM_STR + LoadInteger(udg_CItem_Table, id, 44)
                set ITEM_AGI = ITEM_AGI + LoadInteger(udg_CItem_Table, id, 45)
                set ITEM_INT = ITEM_INT + LoadInteger(udg_CItem_Table, id, 46)
                set DURATIBILITY = R2I(LoadReal(udg_CItem_Table, id, 15) - LoadReal(udg_CItem_Table, id, 14)) //maxdur - duratibility

                //we build a number, what store 6 boolean: 
                //unique id, refined, socketed, ethernal, rnd def(armor)/activation(weapon), duratibility length(1 or 2)
                set a1 = 0
                if LoadInteger(udg_CItem_Table, id, 0) > 0 then
                    set a1 = a1 + 1
                endif
                if LoadInteger(udg_CItem_Table, id, 16) > 0 then
                    set a1 = a1 + 2
                endif
                if LoadInteger(udg_CItem_Table, id, 18) > 0 then
                    set a1 = a1 + 4
                endif
                if LoadInteger(udg_CItem_Table, id, 13) > 0 then
                    set a1 = a1 + 8
                endif
                if LoadInteger(udg_CItem_Table, id, 25) > 0 then
                    set a1 = a1 + 16
                endif
                if DURATIBILITY >= l then
                    set a1 = a1 + 32
                endif
                set udg_SL_EQC[i] = SL_IntegerToCode(a1, 1)
           // --- end of boolean and we create from number a character --- 
  
                 // lets if was unique id then add that
                set a1 = LoadInteger(udg_CItem_Table, id, 0)
                if a1 > 0 then
                    set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(a1, 1)
                else
                    //lets check base stats: subtype, quality, grade, lv req
                    set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 3), 1) + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 4), 1) + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 7), 2) + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 8), 2)
                    //lets add the bonus item stats
                    set ii = 0
                    set a2 = 0
                    loop
                        set BONUS = Inline_Item_Bonus_Stat(ii)
                        set BONUS_LEN = Inline_Item_Bonus_Stat_Length(BONUS)
                        exitwhen BONUS == 0
                        set a1 = LoadInteger(udg_CItem_Table, id, BONUS)
                        if a1 > 0 then
                            set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(BONUS, GEM_LEN) + SL_IntegerToCode(a1, BONUS_LEN)
                        endif
                        set ii = ii + 1
                    endloop
                endif

                //check if defence is random on armor or no
                if LoadInteger(udg_CItem_Table, id, 25) > 0 then
                    if (i == 1 or i == 2 or i == 4) and LoadInteger(udg_CItem_Table, id, 25) == 1 then
                        set ii = 0
                        loop
                            exitwhen ii > 4
                            set a1 = LoadInteger(udg_CItem_Table, id, 35 + ii)
                            set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(a1, 2)
                            set ii = ii + 1
                        endloop
                    elseif i == 3 then
                        set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 25), 1)
                    endif
                endif
                //save duratibility
                set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(DURATIBILITY, - 1)
                //check if item is refined
                if LoadInteger(udg_CItem_Table, id, 16) > 0 then
                    set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 16), 1)
                endif

                //read out the socket bonus stat and its value too
                set a1 = LoadInteger(udg_CItem_Table, id, 18)
                if a1 > 0 then
                    set ii = 0
                    loop
                        exitwhen ii > a1
                        set a2 = LoadInteger(udg_CItem_Table, id, 1500 + ii)
                        set b3 = LoadInteger(udg_CItem_Table, id, 1000 + ii)
                           //if socket was filled then add socket unique id to code
                        set b4 = 1
                        loop
                            exitwhen b4 > b3
                            set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(a2, 1)
                            set b4 = b4 + 1
                        endloop
                       
                        //we check if sockets give bonus stat too
                        if a2 == 0 then
                            set ii = a1 + 1 //break out from loop
                        else
                            set a3 = LoadInteger(udg_CItem_Table, id, 2)
                            set a4 = ItemType2GemType(a3)
                            if a4 != 0 then
                                set b1 = LoadInteger(udg_CItem_Table, - 2000 - a2, 8 + a4)
                                set b2 = LoadInteger(udg_CItem_Table, - 2000 - a2, b1)
                                set b4 = b2 * b3
                                if b1 == 44 then
                                    set ITEM_STR = ITEM_STR + b4
                                elseif b1 == 44 then
                                    set ITEM_AGI = ITEM_AGI + b4
                                elseif b1 == 44 then
                                    set ITEM_INT = ITEM_INT + b4
                                endif
                            endif
                        endif
                        set ii = ii + 1
                    endloop
                endif
            endif
            set i = i + 1
        endloop
 call BJDebugMsg("1")
        set udg_SL_STR = GetHeroStr(u, false) - ITEM_STR - START_STR
        set udg_SL_AGI = GetHeroAgi(u, false) - ITEM_AGI - START_AGI
        set udg_SL_INT = GetHeroInt(u, false) - ITEM_INT - START_INT
return EQ_Count
endfunction

function Create_Save_Load_Code takes nothing returns boolean
    local string CODE // final code will be stored to this variable
    local integer l //get the string length of the alphabet string
    local integer i
    local integer ii
    local integer array Pow2
    local integer array PowL
    local integer MinExp // that exp what was needed for your hero current level
    local integer MaxExp // that exp what needed for your hero for level up
    local integer CurExp // with how much exp hero passed the last level up
    local integer CLASS // the hero unit type index in SL_HERO_TYPE array
    local integer LV // hero level
    local integer EXP // hero exp
    local integer STR // hero strength
    local integer AGI // hero agility
    local integer INT // hero intelligence
    local integer GOLD // player gold
    local integer LUMBER // player lumber
    local integer X // hero x coordinate
    local integer Y // hero y coordinate
    local integer COORD_LEN_X // how much character needed for save hero location
    local integer COORD_LEN_Y // how much character needed for save hero location
    local boolean ERROR = true
    local integer MAX_X //highest X coordinate on map
    local integer MAX_Y //highest Y coordinate on map
    local integer MAX_HERO
    local integer MAX_VAR
    local unit d //dummy unit
    local unit u = GetTriggerUnit()
    local player p
    local location loc //just for location
    local string Key //this is a key for saveing lv, exp, stats into 1 character, we will search thsi string in VAR array for get a index
    local string s
    local string s1
    local string s2
    local string s3
    local integer id
    local integer cv
    local integer a1
    local integer a2
    local integer a3
    local integer a4
    local item itm
    local integer BLACKSMITH
    local integer TAILOR
    local integer JEWELLER
    local integer PHARMACIST
    local integer ITEMS1
    local integer ITEMS2
    local integer EQ_Count //count equiped items
    local string array CODE_Row //line with eq codes
    local integer CODE_Row_Count //count how much line needed for write down all equipment
    local string array EQC //equipment code string
    local integer MAX_CHAR = 60 //maximum character in row
    local string PATH
    local string HERO_NAME
    local string HERO_LV
    local boolean SAVE_COORD = SL_SAVE_COORD()
    local force ff = CreateForce()
    if GetSpellAbilityId() == 'A018' then
        set EQ_Count = EquipmentsToCode(u)
        set p = GetTriggerPlayer()
        set cv = GetUnitUserData(u)
        set CODE = ""
        set Key = ""
        set l = StringLength(SL_CODE())
        set MAX_X = R2I(GetRectMaxX(bj_mapInitialPlayableArea))
        set MAX_Y = R2I(GetRectMaxY(bj_mapInitialPlayableArea))
        set BLACKSMITH = LoadInteger(udg_Stat_Table, 27000 + cv, 1)
        set TAILOR = LoadInteger(udg_Stat_Table, 27000 + cv, 2)
        set JEWELLER = LoadInteger(udg_Stat_Table, 27000 + cv, 3)
        set PHARMACIST = LoadInteger(udg_Stat_Table, 27000 + cv, 4)
        set MAX_VAR = LoadInteger(udg_SL_HASHTABLE, 1, 0)
        set MAX_HERO = LoadInteger(udg_SL_HASHTABLE, 2, 0)
        //----------- just preload the string bases with max values like 1char length till length-1 ----
        set i = 1
        loop
            set PowL[i] = R2I(Pow(l, i)) - 1
            set i = i + 1
            exitwhen i == 5
        endloop
        //-------------------------------------------------------------------------------

        //set s3 = ""

//---------- check if 2 character length would be sufficient for hero coord or no ----

        set COORD_LEN_X = SL_GetIntegerSize(MAX_X * 2)
        set COORD_LEN_Y = SL_GetIntegerSize(MAX_Y * 2)
        call BJDebugMsg("4")

        // ----- we get the hero index from hashtable, if it will be 0, then not found
        set CLASS = LoadInteger(udg_SL_HASHTABLE, 2, GetUnitTypeId(u))
        // --- if isn't 0 then Hero was stored into array and we continue -----

        if CLASS != 0 then
            // --- we get every data, what we will use that not sure yet ----
            set LV = GetHeroLevel(u)
            set EXP = GetHeroXP(u)
            set STR = GetHeroStr (u, false)
            set AGI = GetHeroAgi (u, false)
            set INT = GetHeroInt (u, false)
            set GOLD = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
            set LUMBER = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
            //call BJDebugMsg("5")
            //formating the stuff to max value if maybe it is higher
            set LV = ModuloInteger(LV, PowL[2] + 1)
            set EXP = ModuloInteger(EXP, PowL[4] + 1)
            set STR = ModuloInteger(STR, PowL[2] + 1)
            set AGI = ModuloInteger(AGI, PowL[2] + 1)
            set INT = ModuloInteger(INT, PowL[2] + 1)
            set GOLD = ModuloInteger(GOLD, MAX_GOLD() + 1)
            set LUMBER = ModuloInteger(LUMBER, MAX_GOLD() + 1)
            //if your hero not maxed level then
            if MAX_HERO_LEVEL() != LV then
                // -- we get the MinExp, MaxExp, CurExp with createing a dummy unit at player 1 start location
                set loc = GetStartLocationLoc(GetPlayerStartLocation(Player(0)))
                set d = CreateUnit(Player(0), GetUnitTypeId(u), GetLocationX(loc), GetLocationY(loc), 0)
                call RemoveLocation(loc)
                if LV == 1 then
                    set MinExp = 0
                else
                    call SetHeroLevel(d, LV, false)
                    set MinExp = GetHeroXP(d)
                endif
                call SetHeroLevel(d, LV + 1, false)
                set MaxExp = GetHeroXP(d) - 1
                call RemoveUnit(d)
                set CurExp = EXP - MinExp
            else
                set MinExp = EXP
                set MaxExp = EXP
                set CurExp = 0
            endif
            //call BJDebugMsg("5.5")
            //lets start build the H_CODE with class then with level
            //lets check if max class is higher than the Alpahabet string base
            set a1 = 1
            if MAX_HERO > PowL[1] then
                set a1 = 2
            endif
            set CODE = SL_IntegerToCode(CLASS, a1)
            //call BJDebugMsg("6")
            //we must figure out what better, if we save LV+CurExp or total EXP
            set s1 = SL_IntegerToCode(LV, - 1) + SL_IntegerToCode(CurExp, - 1)
            set s2 = SL_IntegerToCode(EXP, - 1)
            set a1 = StringLength(s1)
            set a2 = StringLength(s2)
            if a1 > a2 then
                set Key = "0" + I2S(a2)
                set CODE = CODE + s2
            else
                set Key = I2S(StringLength(SL_IntegerToCode(LV, - 1))) + I2S(StringLength(SL_IntegerToCode(CurExp, - 1)))
                set CODE = CODE + s1
            endif

            //next piece what we save is the stats
            if SL_SAVE_STAT() then
                set s1 = SL_IntegerToCode(STR, - 1)
                set s2 = SL_IntegerToCode(AGI, - 1)
                set s3 = SL_IntegerToCode(INT, - 1)
                set a1 = StringLength(s1)
                set a2 = StringLength(s2)
                set a3 = StringLength(s3)
                set CODE = CODE + s1 + s2 + s3
                set Key = Key + I2S(a1) + I2S(a2) + I2S(a3)
            else
                set Key = Key + "111"
            endif
            //call BJDebugMsg("7")
            //saveing resource part: gold and lumber    
            if SL_SAVE_GOLD() and SL_SAVE_LUMBER() then
                //call BJDebugMsg("7.01")

                if not (GOLD == 0 and LUMBER == 0) then
                    set s1 = SL_IntegerToCode(GOLD, - 1)
                    set s2 = SL_IntegerToCode(LUMBER, - 1)
                    set a1 = StringLength(s1)
                    set a2 = StringLength(s2)
                    set CODE = CODE + SL_IntegerToCode((a1 * 10 + a2), - 1) + s1 + s2
                    set Key = Key + I2S(a1)
                    set Key = Key + I2S(a2)
                    call BJDebugMsg("7.02")
                else
                    call BJDebugMsg("7.03")
                    set Key = Key + "00"
                endif

                //call BJDebugMsg("7.1")
            elseif SL_SAVE_GOLD() then
                //call BJDebugMsg("7.101")
                if GOLD > 0 then
                    call BJDebugMsg("7.102")
                    set CODE = CODE + SL_IntegerToCode(GOLD, - 1)
                    set Key = Key + I2S(StringLength(SL_IntegerToCode(GOLD, - 1)))
                    call BJDebugMsg("7.103")
                else
                    set Key = Key + "0"
                    call BJDebugMsg("7.104")
                endif
                set Key = Key + "0"
                //call BJDebugMsg("7.105")
            elseif SL_SAVE_LUMBER() then
                //call BJDebugMsg("7.106")
                set Key = Key + "0"
                if LUMBER > 0 then
                    set CODE = CODE + SL_IntegerToCode(LUMBER, - 1)
                    set Key = Key + I2S(StringLength(SL_IntegerToCode(LUMBER, - 1)))
                    call BJDebugMsg("7.107")
                else
                    set Key = Key + "0"
                endif
            else
                set Key = Key + "00"
            endif

            //call BJDebugMsg("7.2")
            //we save hero coordinates (X,Y) with shift
            if SAVE_COORD then
                set a1 = R2I(GetUnitX(u)) + MAX_X //x coordinate with shift for don't be negative number
                set a2 = R2I(GetUnitY(u)) + MAX_Y //y coordinate with shift for don't be negative number
                set CODE = CODE + SL_IntegerToCode(a1, COORD_LEN_X) + SL_IntegerToCode(a2, COORD_LEN_Y)
            endif

            //call BJDebugMsg("7.3")
            //we search after Key index in VAR array, when Key == VAR[index] then we save index
            set a1 = SL_GetIntegerSize(MAX_VAR)
            set a2 = - 1
            set i = 0
            //call BJDebugMsg("max" + I2S(MAX_VAR))
            //call BJDebugMsg("size" + I2S(SL_GetIntegerSize(MAX_VAR)))
            //call BJDebugMsg("key" + Key)
            loop
                exitwhen i > MAX_VAR or a2 != - 1

                if LoadStr(udg_SL_HASHTABLE, 1, i) == Key then
                    call BJDebugMsg(LoadStr(udg_SL_HASHTABLE, 1, i))
                    set a2 = i
                endif
                set i = i + 1
            endloop
            //call BJDebugMsg("7.4")
            if a2 != - 1 then
                set s1 = SL_IntegerToCode(a2, a1)
                set CODE = s1 + CODE
                set ERROR = false
            endif
        endif
        //call BJDebugMsg("8")
        //we save the craft progress and check if unit got equiped stuff, got item in inventory
        set a1 = 0
        if BLACKSMITH >= l then
            set a1 = a1 + 1
        endif
        if TAILOR >= l then
            set a1 = a1 + 2
        endif
        if JEWELLER >= l then
            set a1 = a1 + 4
        endif
        if PHARMACIST >= l then
            set a1 = a1 + 8
        endif
        if EQ_Count > 0 then
            set a1 = a1 + 16
        endif
//        if INV_Count > 0 then
//          set a1 = a1+32
//        endif
        //call BJDebugMsg("9")
        set CODE = CODE + SL_IntegerToCode(a1, 1) + SL_IntegerToCode(BLACKSMITH, - 1) + SL_IntegerToCode(TAILOR, - 1) + SL_IntegerToCode(JEWELLER, - 1) + SL_IntegerToCode(PHARMACIST, - 1)
        set HERO_NAME = GetUnitName(u)
        set HERO_LV = I2S(LV)
        call BJDebugMsg("10"+CODE)
        // let prepare the loooong code 
        set CODE_Row_Count = 1
        set CODE_Row[CODE_Row_Count] = CODE
        
        set i = 1
        loop
            exitwhen i > 10
            if udg_SL_EQC[i] != null then
                set a1 = StringLength(udg_SL_EQC[i])
                set a2 = StringLength(CODE_Row[CODE_Row_Count])
                if a1 + a2 > MAX_CHAR then
                    set s1 = SL_CodeCheckSum(CODE_Row[CODE_Row_Count], p)
                    set s2 = SL_CodeCheckSum(CODE_Row[1], p)
                    if CODE_Row_Count != 1 then
                        set CODE_Row[CODE_Row_Count] = s1 + SL_IntegerToCode(CODE_Row_Count, 1) + CODE_Row[CODE_Row_Count] + s2
                    else
                        set s3 = SL_IntegerToCode(udg_SL_EQ_B_CODE1, - 1)
                        if udg_SL_EQ_B_CODE1 > 31 then
                            set s3 = s3 + SL_IntegerToCode(udg_SL_EQ_B_CODE2, - 1)
                        endif
                        set CODE_Row[CODE_Row_Count] = s1 + s3 + CODE_Row[CODE_Row_Count] + s2
                    endif
                    set CODE_Row_Count = CODE_Row_Count + 1
                    set CODE_Row[CODE_Row_Count] = EQC[i]
                else
                    set CODE_Row[CODE_Row_Count] = CODE_Row[CODE_Row_Count] + EQC[i]
                endif
             endif
            set i = i + 1
        endloop

        if not ERROR then
            set CODE = CODE + SL_CodeCheckSum(CODE, p)
            set PATH = SL_FOLDER() + "\\" + HERO_NAME + " - " + HERO_LV + " by " + GetPlayerName(p) + ".txt"
            //if StringLength(CODE) < 60 then
            //call DisplayTextToPlayer ( p, 0, 0, "|cffffff00Code:|r -Load " + SL_Colorized_Code(CODE, "00FF00", "FFFF00", "00FFFF", "FF00FF", 0) )
            //    call DisplayTextToPlayer ( p, 0, 0, "|cffffff00Code:|r -Load " + CODE )
           // else
              //  call DisplayTextToPlayer ( p, 0, 0, "|cffffff00Code:|r -Load " + CODE )
            //endif
            call DisplayTextToPlayer ( p, 0, 0, "|cff7777ffNote:|r Code saved into |cffff8888" + PATH + "|r")
            set i = 1
            if GetLocalPlayer() == p then
                call PreloadGenClear()
                call PreloadGenStart()
                call Preload("\r\n\t\t\t\tHero: " + HERO_NAME + "\r\n\t\t\t\t" + "Level: " + HERO_LV + "\t\t\r\n\t\t\t\t" + "Name: " + GetPlayerName(p) + "\t\t\r\n" )
                loop
                    exitwhen i > CODE_Row_Count
                    call Preload("Code " + I2S(i) + ": " + CODE_Row[i] + "\t\t\r\n" )
                    call DisplayTextToPlayer ( p, 0, 0, CODE_Row[i] )
                    set i = i + 1
                endloop
                call PreloadGenEnd(PATH)
                set i = 1
            endif
        else
            call DisplayTextToPlayer ( p, 0, 0, "|cffff7777Warning:|r something went wrong." )
        endif
        set p = null
        set loc = null
        set d = null
        set u = null
    endif
return false
endfunction

//===========================================================================
function InitTrig_Save_Game_ability takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 0
//EVENT_PLAYER_UNIT_SPELL_CAST   -    EVENT_PLAYER_UNIT_SPELL_FINISH
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_CAST, null)
        set i = i + 1
        exitwhen i == 16
    endloop
    call TriggerAddCondition( t, Condition( function Create_Save_Load_Code ) )
    set t = null
endfunction
 
Last edited:
Level 17
Joined
Nov 13, 2006
Messages
1,814
placed it to multiple divided timer function and atm look like that work but 2nd problem look like same bug with revived heroes no dmg modofication so ignore the whole trigger

JASS:
function BuildFinalCode takes nothing returns nothing
    local integer i = 1
    local integer MAX_CHAR = 100 //maximum character in row
    local integer a1
    local integer a2
    local string s1
    local string s2
    local string s3
    local timer t = GetExpiredTimer()
    local integer tid = GetHandleId(t)
    local unit u = LoadUnitHandle(udg_SL_HASHTABLE, 9, tid)
    local string CODE = LoadStr(udg_SL_HASHTABLE, 8, tid)
    local player p = LoadPlayerHandle(udg_SL_HASHTABLE, 10, tid)
    local string HERO_NAME = GetHeroProperName(u)
    local string HERO_LV = I2S(GetHeroLevel(u))
    local string PATH = SL_FOLDER() + "\\" + HERO_NAME + " - " + HERO_LV + " by " + GetPlayerName(p) + ".txt"
    local string array CODE_Row //line with eq codes
    local integer CODE_Row_Count = 1 //count how much line needed for write down all equipment
    call RemoveSavedHandle(udg_SL_HASHTABLE, 9, tid)
    call RemoveSavedHandle(udg_SL_HASHTABLE, 10, tid)

    set CODE_Row[CODE_Row_Count] = CODE
    loop
        exitwhen i > 10
        if udg_SL_EQC[i] != null then
            set udg_SL_EQC[i] = udg_SL_EQC[i]
            set a1 = StringLength(udg_SL_EQC[i])
            set a2 = StringLength(CODE_Row[CODE_Row_Count])
            if a1 + a2 > MAX_CHAR then
                if CODE_Row_Count != 1 then
                    set CODE_Row[CODE_Row_Count] = SL_IntegerToCode(CODE_Row_Count, 1) + CODE_Row[CODE_Row_Count]
                    set s2 = SL_CodeCheckSum(CODE_Row[CODE_Row_Count], p)
                    set CODE_Row[CODE_Row_Count] = s1 + SL_IntegerToCode(CODE_Row_Count, 1) + CODE_Row[CODE_Row_Count] + s2
                else
                    set s3 = SL_IntegerToCode(udg_SL_EQ_B_CODE1, - 1)
                    if udg_SL_EQ_B_CODE1 > 31 then
                        set s3 = s3 + SL_IntegerToCode(udg_SL_EQ_B_CODE2, - 1)
                    endif
                    set CODE_Row[CODE_Row_Count] = s3 + CODE_Row[CODE_Row_Count]
                    set s1 = SL_CodeCheckSum(CODE_Row[1], p)
                    set CODE_Row[CODE_Row_Count] = s1 + CODE_Row[CODE_Row_Count] + s1

                endif
                set CODE_Row_Count = CODE_Row_Count + 1
                set CODE_Row[CODE_Row_Count] = udg_SL_EQC[i]
            else
                if i == 10 then
                    if CODE_Row_Count > 1 then
                        set CODE_Row[CODE_Row_Count] = SL_IntegerToCode(0, 1) + CODE_Row[CODE_Row_Count] + udg_SL_EQC[i]
                        set s2 = SL_CodeCheckSum(CODE_Row[CODE_Row_Count], p)
                        if s1 == null then
                            set s1 = s2
                        endif
                        set CODE_Row[CODE_Row_Count] = s1 + CODE_Row[CODE_Row_Count] + s2
                    else
                        if udg_SL_EQ_B_CODE1 < 32 then
                           set udg_SL_EQ_B_CODE1 = udg_SL_EQ_B_CODE1 + 32
                        endif
                        set s3 = SL_IntegerToCode(udg_SL_EQ_B_CODE1, - 1) + SL_IntegerToCode(udg_SL_EQ_B_CODE2 + 32, - 1)
                        set CODE_Row[CODE_Row_Count] = s3 + CODE_Row[CODE_Row_Count] + udg_SL_EQC[i]
                        set s1 = SL_CodeCheckSum(CODE_Row[1], p)
                        set CODE_Row[CODE_Row_Count] = s1 + CODE_Row[CODE_Row_Count] + s1
                    endif
                else
                    set CODE_Row[CODE_Row_Count] = CODE_Row[CODE_Row_Count] + udg_SL_EQC[i]
                endif
            endif
        endif
        set i = i + 1
    endloop

    call DisplayTextToPlayer ( p, 0, 0, "|cff7777ffNote:|r Code saved into |cffff8888" + PATH + "|r")
    set i = 1
    if GetLocalPlayer() == p then
        call PreloadGenClear()
        call PreloadGenStart()
        call Preload("\r\n\t\t\t\tHero: " + HERO_NAME + "\r\n\t\t\t\t" + "Level: " + HERO_LV + "\t\t\r\n\t\t\t\t" + "Name: " + GetPlayerName(p) + "\t\t\r\n" )
        loop
            exitwhen i > CODE_Row_Count
            call Preload("Code " + I2S(i) + ": -load " + CODE_Row[i] )
            
            call DisplayTextToPlayer ( p, 0, 0, "Code " + I2S(i) + ": " + CODE_Row[i] + " =" + I2S(StringLength(CODE_Row[i])))
            set i = i + 1
        endloop
        call PreloadGenEnd(PATH)
        set i = 1
    endif
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
    set u = null
endfunction

function ReadOutTheSockets takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer tid = GetHandleId(t)
    local integer id = LoadInteger(udg_SL_HASHTABLE, 5, tid)
    local integer i = LoadInteger(udg_SL_HASHTABLE, 6, tid)
    local integer a1 = LoadInteger(udg_SL_HASHTABLE, 7, tid)
    local integer a2
    local integer a3
    local integer a4
    local integer b1
    local integer b2
    local integer b3
    local integer b4
    local integer ii
    //read out the socket bonus stat and its value too
    set ii = 0
    loop
        exitwhen ii > a1
        set a2 = LoadInteger(udg_CItem_Table, id, 1500 + ii)
        set b3 = LoadInteger(udg_CItem_Table, id, 1000 + ii)
        //if socket was filled then add socket unique id to code
        set b4 = 1
        loop
            exitwhen b4 > b3
            set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(a2, 1)
            set b4 = b4 + 1
        endloop
                       
        //we check if sockets give bonus stat too
        if a2 == 0 then
            set ii = a1 + 1 //break out from loop
        else
            set a3 = LoadInteger(udg_CItem_Table, id, 2)
            set a4 = ItemType2GemType(a3)
            if a4 != 0 then
                set b1 = LoadInteger(udg_CItem_Table, - 2000 - a2, 8 + a4)
                set b2 = LoadInteger(udg_CItem_Table, - 2000 - a2, b1)
                set b4 = b2 * b3
                if b1 == 44 then
                    set udg_SL_STR = udg_SL_STR - b4
                elseif b1 == 45 then
                    set udg_SL_AGI = udg_SL_AGI - b4
                elseif b1 == 46 then
                    set udg_SL_INT = udg_SL_INT - b4
                endif
            endif
        endif
        set ii = ii + 1
    endloop
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
endfunction

function EquipmentsToCode takes nothing returns nothing
    local integer ITEM_STR = 0
    local integer ITEM_AGI = 0
    local integer ITEM_INT = 0
    local timer t1 = GetExpiredTimer()
    local integer tid1 = GetHandleId(t1)
    local timer t2
    local integer tid2
    local unit u = LoadUnitHandle(udg_SL_HASHTABLE, 4, tid1)
    local integer ut = GetUnitTypeId(u)
    local integer START_STR = LoadInteger(udg_FSS, 636, ut)
    local integer START_AGI = LoadInteger(udg_FSS, 637, ut)
    local integer START_INT = LoadInteger(udg_FSS, 638, ut)
    local integer DURATIBILITY
    local integer MAX_INVENTORY = 20 //our inventory capacity is 20 item
    local integer GEM_LEN = SL_GetIntegerSize(LoadInteger(udg_CItem_Table, - 2000, 0))
    local integer cv = GetUnitUserData(u)
    local item itm
    local integer id
    local integer l = StringLength(SL_CODE())
    local integer i
    local integer ii
    local integer a1
    local integer a2
    local integer a3
    local integer a4
    local integer b1
    local integer b2
    local integer b3
    local integer b4
    local integer BONUS //predefined bonus stat index's from items
    local integer BONUS_LEN //predefined bonus stats length from items (1 = 0 - 82, 2 = 0 - 6400)
    call RemoveSavedHandle(udg_SL_HASHTABLE, 0, tid1)

    set udg_SL_EQ_B_CODE1 = 0
    set udg_SL_EQ_B_CODE2 = 0

        //we calculate how much str, agi, int coming from items - directly and from sockets
        //we start in inventory - we check the charms
    set i = 1
    loop
        exitwhen i > MAX_INVENTORY
        if HaveSavedHandle(udg_Stat_Table, cv, i + 99) then
            set itm = LoadItemHandle(udg_Stat_Table, cv, i + 99)
            if GetItemLevel(itm) == 111 then //if item level is 111 then item is charm
                set id = GetHandleId(itm)
                set ITEM_STR = ITEM_STR + LoadInteger(udg_CItem_Table, id, 44)
                set ITEM_AGI = ITEM_AGI + LoadInteger(udg_CItem_Table, id, 45)
                set ITEM_INT = ITEM_INT + LoadInteger(udg_CItem_Table, id, 46)
            endif
        endif
        set i = i + 1
    endloop
    set itm = null

    //we start build the code for equipments, each equipment individually and at end combine to a large row
    //equipment slots: 1 - 10 
    set udg_SL_EQ_Count = 0
    set i = 1
    loop
        exitwhen i == 11
        set udg_SL_EQC[i] = ""
        //if in equipment slot have saved item then
        if HaveSavedHandle(udg_Stat_Table, cv, i) then
            if i < 6 then
                set udg_SL_EQ_B_CODE1 = udg_SL_EQ_B_CODE1 + udg_Pow2[i - 1]
            else
                if udg_SL_EQ_B_CODE1 < 32 then
                    set udg_SL_EQ_B_CODE1 = udg_SL_EQ_B_CODE1 + 32
                endif
                set udg_SL_EQ_B_CODE2 = udg_SL_EQ_B_CODE2 + udg_Pow2[i - 6]
            endif
            set udg_SL_EQ_Count = udg_SL_EQ_Count + 1
            set id = GetHandleId(LoadItemHandle(udg_Stat_Table, cv, i))
            set ITEM_STR = ITEM_STR + LoadInteger(udg_CItem_Table, id, 44)
            set ITEM_AGI = ITEM_AGI + LoadInteger(udg_CItem_Table, id, 45)
            set ITEM_INT = ITEM_INT + LoadInteger(udg_CItem_Table, id, 46)
            set DURATIBILITY = R2I(LoadReal(udg_CItem_Table, id, 15) - LoadReal(udg_CItem_Table, id, 14)) //maxdur - duratibility

            //we build a number, what store 6 boolean: 
            //unique id, refined, socketed, ethernal, rnd def(armor)/activation(weapon), duratibility length(1 or 2)
            set a1 = 0
            if LoadInteger(udg_CItem_Table, id, 0) > 0 then
                set a1 = a1 + 1
            endif
            if LoadInteger(udg_CItem_Table, id, 16) > 0 then
                set a1 = a1 + 2
            endif
            if LoadInteger(udg_CItem_Table, id, 18) > 0 then
                set a1 = a1 + 4
            endif
            if LoadInteger(udg_CItem_Table, id, 13) > 0 then
                set a1 = a1 + 8
            endif
            if LoadInteger(udg_CItem_Table, id, 25) > 0 then
                set a1 = a1 + 16
            endif
            if DURATIBILITY >= l then
                set a1 = a1 + 32
            endif
            set udg_SL_EQC[i] = SL_IntegerToCode(a1, 1)
           // --- end of boolean and we create from number a character --- 
  
            // lets if was unique id then add that
            set a1 = LoadInteger(udg_CItem_Table, id, 0)
            if a1 > 0 then
                set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(a1, 1)
            else
                //lets check base stats: subtype, quality, grade, lv req
                set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 3), 1) + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 4), 1) + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 7), 2) + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 8), 2)
                //lets add the bonus item stats
                set ii = 0
                set a2 = 0
                loop
                    set BONUS = Inline_Item_Bonus_Stat(ii)
                    set BONUS_LEN = Inline_Item_Bonus_Stat_Length(BONUS)
                    exitwhen BONUS == 0
                    set a1 = LoadInteger(udg_CItem_Table, id, BONUS)
                    if a1 > 0 then
                        set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(BONUS, GEM_LEN) + SL_IntegerToCode(a1, BONUS_LEN)
                    endif
                    set ii = ii + 1
                endloop
            endif
            if i < 10 then
            //check if defence is random on armor or no
                if LoadInteger(udg_CItem_Table, id, 25) > 0 then
                    if (i == 1 or i == 2 or i == 4) and LoadInteger(udg_CItem_Table, id, 25) == 1 then
                        set ii = 0
                        loop
                            exitwhen ii > 4
                            set a1 = LoadInteger(udg_CItem_Table, id, 35 + ii)
                            set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(a1, 2)
                            set ii = ii + 1
                        endloop
                    elseif i == 3 then
                        set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 25), 1)
                    endif
                endif

            //save duratibility
                set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(DURATIBILITY, - 1)
            //check if item is refined
                if LoadInteger(udg_CItem_Table, id, 16) > 0 then
                    set udg_SL_EQC[i] = udg_SL_EQC[i] + SL_IntegerToCode(LoadInteger(udg_CItem_Table, id, 16), 1)
                endif

                set a1 = LoadInteger(udg_CItem_Table, id, 18)
                if a1 > 0 then
                    set t2 = CreateTimer()
                    set tid2 = GetHandleId(t2)
                    call SaveInteger(udg_SL_HASHTABLE, 5, tid2, id)
                    call SaveInteger(udg_SL_HASHTABLE, 6, tid2, i)
                    call SaveInteger(udg_SL_HASHTABLE, 7, tid2, a1)
                    call TimerStart(t2, 0.00, false, function ReadOutTheSockets)
                    set t2 = null
                endif
            endif
        endif
        set i = i + 1
    endloop
    set udg_SL_STR = GetHeroStr(u, false) - ITEM_STR - START_STR
    set udg_SL_AGI = GetHeroAgi(u, false) - ITEM_AGI - START_AGI
    set udg_SL_INT = GetHeroInt(u, false) - ITEM_INT - START_INT
    call PauseTimer(t1)
    call DestroyTimer(t1)
    set u = null
    set t1 = null
endfunction

function Create_Save_Load_Code takes nothing returns boolean
    local string CODE // final code will be stored to this variable
    local integer l //get the string length of the alphabet string
    local integer i
    local integer ii
    local integer array Pow2
    local integer array PowL
    local integer MinExp // that exp what was needed for your hero current level
    local integer MaxExp // that exp what needed for your hero for level up
    local integer CurExp // with how much exp hero passed the last level up
    local integer CLASS // the hero unit type index in SL_HERO_TYPE array
    local integer LV // hero level
    local integer EXP // hero exp
    local integer STR // hero strength
    local integer AGI // hero agility
    local integer INT // hero intelligence
    local integer GOLD // player gold
    local integer LUMBER // player lumber
    local integer X // hero x coordinate
    local integer Y // hero y coordinate
    local integer COORD_LEN_X // how much character needed for save hero location
    local integer COORD_LEN_Y // how much character needed for save hero location
    local boolean ERROR = true
    local integer MAX_X //highest X coordinate on map
    local integer MAX_Y //highest Y coordinate on map
    local integer MAX_HERO
    local integer MAX_VAR
    local unit d //dummy unit
    local unit u = GetTriggerUnit()
    local player p
    local location loc //just for location
    local string Key //this is a key for saveing lv, exp, stats into 1 character, we will search thsi string in VAR array for get a index
    local string s
    local string s1
    local string s2
    local string s3
    local integer id
    local integer cv
    local integer a1
    local integer a2
    local integer a3
    local integer a4
    local integer BLACKSMITH
    local integer TAILOR
    local integer JEWELLER
    local integer PHARMACIST
    local integer ITEMS1
    local integer ITEMS2
    local boolean SAVE_COORD = SL_SAVE_COORD()
    local timer t

    if GetSpellAbilityId() == 'A018' then
        set t = CreateTimer()
        call SaveUnitHandle(udg_SL_HASHTABLE, 4, GetHandleId(t), u)
        call TimerStart(t, 0.00, false, function EquipmentsToCode)
        set t = null
        set p = GetTriggerPlayer()
        set cv = GetUnitUserData(u)
        set CODE = ""
        set Key = ""
        set l = StringLength(SL_CODE())
        set MAX_X = R2I(GetRectMaxX(bj_mapInitialPlayableArea))
        set MAX_Y = R2I(GetRectMaxY(bj_mapInitialPlayableArea))
        set BLACKSMITH = LoadInteger(udg_Stat_Table, 27000 + cv, 1)
        set TAILOR = LoadInteger(udg_Stat_Table, 27000 + cv, 2)
        set JEWELLER = LoadInteger(udg_Stat_Table, 27000 + cv, 3)
        set PHARMACIST = LoadInteger(udg_Stat_Table, 27000 + cv, 4)
        set MAX_VAR = LoadInteger(udg_SL_HASHTABLE, 1, 0)
        set MAX_HERO = LoadInteger(udg_SL_HASHTABLE, 2, 0)
        //----------- just preload the string bases with max values like 1char length till length-1 ----
        set i = 1
        loop
            set PowL[i] = R2I(Pow(l, i)) - 1
            set i = i + 1
            exitwhen i == 5
        endloop
        //-------------------------------------------------------------------------------

        //set s3 = ""

//---------- check if 2 character length would be sufficient for hero coord or no ----

        set COORD_LEN_X = SL_GetIntegerSize(MAX_X * 2)
        set COORD_LEN_Y = SL_GetIntegerSize(MAX_Y * 2)

        // ----- we get the hero index from hashtable, if it will be 0, then not found
        set CLASS = LoadInteger(udg_SL_HASHTABLE, 2, GetUnitTypeId(u))
        // --- if isn't 0 then Hero was stored into array and we continue -----

        if CLASS != 0 then
            // --- we get every data, what we will use that not sure yet ----
            set LV = GetHeroLevel(u)
            set EXP = GetHeroXP(u)
            set STR = GetHeroStr (u, false)
            set AGI = GetHeroAgi (u, false)
            set INT = GetHeroInt (u, false)
            set GOLD = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
            set LUMBER = GetPlayerState(p, PLAYER_STATE_RESOURCE_LUMBER)
            //call BJDebugMsg("5")
            //formating the stuff to max value if maybe it is higher
            set LV = ModuloInteger(LV, PowL[2] + 1)
            set EXP = ModuloInteger(EXP, PowL[4] + 1)
            set STR = ModuloInteger(STR, PowL[2] + 1)
            set AGI = ModuloInteger(AGI, PowL[2] + 1)
            set INT = ModuloInteger(INT, PowL[2] + 1)
            set GOLD = ModuloInteger(GOLD, MAX_GOLD() + 1)
            set LUMBER = ModuloInteger(LUMBER, MAX_GOLD() + 1)
            //if your hero not maxed level then
            if MAX_HERO_LEVEL() != LV then
                // -- we get the MinExp, MaxExp, CurExp with createing a dummy unit at player 1 start location
                set loc = GetStartLocationLoc(GetPlayerStartLocation(Player(0)))
                set d = CreateUnit(Player(0), GetUnitTypeId(u), GetLocationX(loc), GetLocationY(loc), 0)
                call RemoveLocation(loc)
                if LV == 1 then
                    set MinExp = 0
                else
                    call SetHeroLevel(d, LV, false)
                    set MinExp = GetHeroXP(d)
                endif
                call SetHeroLevel(d, LV + 1, false)
                set MaxExp = GetHeroXP(d) - 1
                call RemoveUnit(d)
                set CurExp = EXP - MinExp
            else
                set MinExp = EXP
                set MaxExp = EXP
                set CurExp = 0
            endif
            //lets start build the H_CODE with class then with level
            //lets check if max class is higher than the Alpahabet string base
            set a1 = 1
            if MAX_HERO > PowL[1] then
                set a1 = 2
            endif
            set CODE = SL_IntegerToCode(CLASS, a1)
            //we must figure out what better, if we save LV+CurExp or total EXP
            set s1 = SL_IntegerToCode(LV, - 1) + SL_IntegerToCode(CurExp, - 1)
            set s2 = SL_IntegerToCode(EXP, - 1)
            set a1 = StringLength(s1)
            set a2 = StringLength(s2)
            if a1 > a2 then
                set Key = "0" + I2S(a2)
                set CODE = CODE + s2
            else
                set Key = I2S(StringLength(SL_IntegerToCode(LV, - 1))) + I2S(StringLength(SL_IntegerToCode(CurExp, - 1)))
                set CODE = CODE + s1
            endif

            //next piece what we save is the stats
            if SL_SAVE_STAT() then
                set s1 = SL_IntegerToCode(STR, - 1)
                set s2 = SL_IntegerToCode(AGI, - 1)
                set s3 = SL_IntegerToCode(INT, - 1)
                set a1 = StringLength(s1)
                set a2 = StringLength(s2)
                set a3 = StringLength(s3)
                set CODE = CODE + s1 + s2 + s3
                set Key = Key + I2S(a1) + I2S(a2) + I2S(a3)
            else
                set Key = Key + "111"
            endif
            //saveing resource part: gold and lumber    
            if SL_SAVE_GOLD() and SL_SAVE_LUMBER() then
                if not (GOLD == 0 and LUMBER == 0) then
                    set s1 = SL_IntegerToCode(GOLD, - 1)
                    set s2 = SL_IntegerToCode(LUMBER, - 1)
                    set a1 = StringLength(s1)
                    set a2 = StringLength(s2)
                    set CODE = CODE + SL_IntegerToCode((a1 * 10 + a2), - 1) + s1 + s2
                    set Key = Key + I2S(a1)
                    set Key = Key + I2S(a2)
                else
                    set Key = Key + "00"
                endif

            elseif SL_SAVE_GOLD() then
                if GOLD > 0 then
                    set CODE = CODE + SL_IntegerToCode(GOLD, - 1)
                    set Key = Key + I2S(StringLength(SL_IntegerToCode(GOLD, - 1)))
                else
                    set Key = Key + "0"
                endif
                set Key = Key + "0"
            elseif SL_SAVE_LUMBER() then
                set Key = Key + "0"
                if LUMBER > 0 then
                    set CODE = CODE + SL_IntegerToCode(LUMBER, - 1)
                    set Key = Key + I2S(StringLength(SL_IntegerToCode(LUMBER, - 1)))
                else
                    set Key = Key + "0"
                endif
            else
                set Key = Key + "00"
            endif

            //we save hero coordinates (X,Y) with shift
            if SAVE_COORD then
                set a1 = R2I(GetUnitX(u)) + MAX_X //x coordinate with shift for don't be negative number
                set a2 = R2I(GetUnitY(u)) + MAX_Y //y coordinate with shift for don't be negative number
                set CODE = CODE + SL_IntegerToCode(a1, COORD_LEN_X) + SL_IntegerToCode(a2, COORD_LEN_Y)
            endif

            //we search after Key index in VAR array, when Key == VAR[index] then we save index
            set a1 = SL_GetIntegerSize(MAX_VAR)
            set a2 = - 1
            set i = 0

            loop
                exitwhen i > MAX_VAR or a2 != - 1
                if LoadStr(udg_SL_HASHTABLE, 1, i) == Key then
                    set a2 = i
                endif
                set i = i + 1
            endloop
            if a2 != - 1 then
                set s1 = SL_IntegerToCode(a2, a1)
                set CODE = s1 + CODE
                set ERROR = false
            endif
        endif
        //we save the craft progress and check if unit got equiped stuff, got item in inventory
        set a1 = 0
        if BLACKSMITH >= l then
            set a1 = a1 + 1
        endif
        if TAILOR >= l then
            set a1 = a1 + 2
        endif
        if JEWELLER >= l then
            set a1 = a1 + 4
        endif
        if PHARMACIST >= l then
            set a1 = a1 + 8
        endif
        if udg_SL_EQ_Count > 0 then
            set a1 = a1 + 16
        endif
//        if INV_Count > 0 then
//          set a1 = a1+32
//        endif
        set CODE = CODE + SL_IntegerToCode(a1, 1) + SL_IntegerToCode(BLACKSMITH, - 1) + SL_IntegerToCode(TAILOR, - 1) + SL_IntegerToCode(JEWELLER, - 1) + SL_IntegerToCode(PHARMACIST, - 1)


        if not ERROR then
            set t = CreateTimer()
            set a1 = GetHandleId(t)
            call SaveStr(udg_SL_HASHTABLE, 8, a1, CODE)
            call SaveUnitHandle(udg_SL_HASHTABLE, 9, a1, u)
            call SavePlayerHandle(udg_SL_HASHTABLE, 10, a1, p)
            call TimerStart(t, 0.01, false, function BuildFinalCode)
            set t = null
        else
            call DisplayTextToPlayer ( p, 0, 0, "|cffff7777Warning:|r something went wrong." )
        endif
        set p = null
        set loc = null
        set d = null
        set u = null
    endif
    return false
endfunction

//===========================================================================
function InitTrig_Save_Game_ability takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 0
    //EVENT_PLAYER_UNIT_SPELL_CAST   -    EVENT_PLAYER_UNIT_SPELL_FINISH
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_CAST, null)
        set i = i + 1
        exitwhen i == 16
    endloop
    call TriggerAddCondition( t, Condition( function Create_Save_Load_Code ) )
    set t = null
endfunction
 
Status
Not open for further replies.
Top