- 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
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
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