- Joined
- Nov 4, 2007
- Messages
- 933
With the new patch out, a lot of functions that used the return bug have had to be redone using the new natives, but can someone help me figure out how to redo this function since it no longer works in the new patch?
P.S. this function is used as part of a save/load system, so its crucial I get it back to normal if at all possible, thx for help.
EDIT: Included the entire system
JASS:
function R2L takes real r returns location
return r
endfunction
EDIT: Included the entire system
JASS:
function HtoR takes handle h returns real
return I2R(GetHandleId(h))
endfunction
function RtoL takes real r returns location
return Location(0,r)
endfunction
function RtoI takes real r returns integer
return R2I(r)
endfunction
function ItoR takes integer i returns real
return I2R(i)
endfunction
function HtoI takes handle h returns integer
return GetHandleId(h)
endfunction
function log takes real y, real base returns real
local real x
local real factor = 1.0
local real logy = 0.0
local real sign = 1.0
if(y < 0.) then
return 0.0
endif
if(y < 1.) then
set y = 1.0/y
set sign = -1.0
endif
//Chop out powers of the base
loop
exitwhen y < 1.0001 //decrease this ( bounded below by 1) to improve precision
if(y > base) then
set y = y / base
set logy = logy + factor
else
set base = SquareRoot(base)
set factor = factor / 2.
endif
endloop
return sign*logy
endfunction
function Savecode_player_charset takes nothing returns string
return "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
endfunction
function Savecode_player_charsetlen takes nothing returns integer
return StringLength(Savecode_player_charset())
endfunction
function Savecode_player_chartoi takes string c returns integer
local integer i = 0
local string charset = Savecode_player_charset()
local integer len = Savecode_player_charsetlen()
loop
exitwhen i>=len or c == SubString(charset,i,i+1)
set i = i + 1
endloop
return i
endfunction
function Savecode_charset takes nothing returns string
return "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
endfunction
function Savecode_charsetlen takes nothing returns integer
return StringLength(Savecode_charset())
endfunction
function BASE takes nothing returns integer
return Savecode_charsetlen()
endfunction
function HASHN takes nothing returns integer
return 5000 //1./HASHN() is the probability of a random code being valid
endfunction
function MAXINT takes nothing returns integer
return 2147483647
endfunction
function BigNum_new takes nothing returns location
return Location(0.,0.)
endfunction
function BigNum_destroy takes location bignum returns nothing
local location next
loop
exitwhen bignum == null
set next = RtoL(GetLocationY(bignum))
call RemoveLocation(bignum)
set bignum = next
endloop
endfunction
function BigNum_iszero takes location bignum returns boolean
loop
exitwhen bignum == null
if GetLocationX(bignum) != 0. then
return false
endif
set bignum = RtoL(GetLocationY(bignum))
endloop
return true
endfunction
function BigNum_dump takes location savecode returns nothing
local string s = ""
local integer x
loop
exitwhen savecode == null
set x = RtoI(GetLocationX(savecode))
set s = I2S(x)+" "+s
set savecode = RtoL(GetLocationY(savecode))
endloop
call BJDebugMsg(s)
endfunction
function BigNum_clean takes location bignum returns boolean
local location next = RtoL(GetLocationY(bignum))
local integer this = RtoI(GetLocationX(bignum))
if (next == null) and (this == 0) then
return true
elseif BigNum_clean(next) then
call RemoveLocation(next)
set next = null
//Potentially an optimization to not move if bignum == 0
call MoveLocation(bignum,GetLocationX(bignum),0.)
return this == 0
else
set next = null
return false
endif
endfunction
//fails if bignum is null
//BASE() + carry must be less than MAXINT()
function BigNum_addsmall takes location bignum, integer carry returns nothing
local location next
local integer sum
local integer y
loop
exitwhen carry == 0
set y = RtoI(GetLocationX(bignum))
set sum = y + carry
set carry = sum / BASE()
set sum = sum - carry*BASE()
call MoveLocation(bignum,ItoR(sum),GetLocationY(bignum))
set next = RtoL(GetLocationY(bignum))
if next == null then
set next = Location(0.,0.)
call MoveLocation(bignum,GetLocationX(bignum),HtoR(next))
endif
set bignum = next
endloop
set bignum = null
set next = null
endfunction
//x*BASE() must be less than MAXINT()
function BigNum_mulsmall takes location bignum, integer x returns nothing
local location next = null
local integer product
local integer y
local integer remainder
local integer carry = 0
loop
exitwhen bignum == null and carry == 0
set y = RtoI(GetLocationX(bignum))
set product = x * y + carry
set carry = (product/BASE())
set remainder = (product - carry*BASE())
call MoveLocation(bignum,ItoR(remainder),GetLocationY(bignum))
set next = RtoL(GetLocationY(bignum))
if next == null and carry != 0 then
set next = Location(0.,0.)
call MoveLocation(bignum,GetLocationX(bignum),HtoR(next))
endif
set bignum = next
endloop
set next = null
endfunction
//Returns remainder
function BigNum_divsmall takes location bignum, integer denom returns integer
local location next = RtoL(GetLocationY(bignum))
local integer quotient
local integer remainder = 0
local integer num
if(next != null) then
set remainder = BigNum_divsmall(next,denom)
set next = null
endif
set num = RtoI(GetLocationX(bignum))
set num = num + remainder*BASE()
set quotient = num/denom
set remainder = num - quotient*denom
call MoveLocation(bignum,ItoR(quotient),GetLocationY(bignum))
return remainder
endfunction
function BigNum_lastdigit takes location bignum returns integer
local location next
local integer lastdigit
loop
set next = RtoL(GetLocationY(bignum))
exitwhen next == null
set bignum = next
endloop
set lastdigit = RtoI(GetLocationX(bignum))
set bignum = null
return lastdigit
endfunction
function Savecode_new takes nothing returns location
return Location(0.,HtoR(BigNum_new()))
endfunction
function Savecode_destroy takes location savecode returns nothing
call BigNum_destroy(savecode)
endfunction
function Savecode_encode takes location savecode, integer val, integer max returns nothing
call MoveLocation(savecode,log(max+1,BASE())+GetLocationX(savecode),GetLocationY(savecode))
// call MoveLocation(savecode,(max+1)*GetLocationX(savecode)+max,GetLocationY(savecode))
call BigNum_mulsmall(RtoL(GetLocationY(savecode)),max+1)
call BigNum_addsmall(RtoL(GetLocationY(savecode)),val)
endfunction
function Savecode_decode takes location savecode, integer max returns integer
// call MoveLocation(savecode,GetLocationX(savecode)/max,GetLocationY(savecode))
return BigNum_divsmall(RtoL(GetLocationY(savecode)),max+1)
endfunction
function Savecode_chartoi takes string c returns integer
local integer i = 0
local string charset = Savecode_charset()
local integer len = Savecode_charsetlen()
loop
exitwhen i>=len or c == SubString(charset,i,i+1)
set i = i + 1
endloop
return i
endfunction
function Savecode_itochar takes integer i returns string
return SubString(Savecode_charset(),i,i+1)
endfunction
function Savecode_isempty takes location savecode returns boolean
return BigNum_iszero(savecode)
endfunction
function Savecode_length takes location savecode, integer base returns real
// return log(GetLocationX(savecode),BASE())
return GetLocationX(savecode)
endfunction
function Savecode_clean takes location savecode returns nothing
set savecode = RtoL(GetLocationY(savecode))
call BigNum_clean(savecode)
endfunction
function Savecode_pad takes location savecode returns nothing
local location prev
local integer maxlen = R2I(1.+Savecode_length(savecode,BASE()))
set savecode = RtoL(GetLocationY(savecode))
loop
exitwhen savecode == null
set prev = savecode
set savecode = RtoL(GetLocationY(savecode))
set maxlen = maxlen - 1
endloop
loop
exitwhen maxlen <= 0
call MoveLocation(prev,GetLocationX(prev),HtoR(Location(0.,0.)))
set prev = RtoL(GetLocationY(prev))
set maxlen = maxlen - 1
endloop
set prev = null
endfunction
function Savecode_tos takes location savecode returns string
local string s = ""
loop
set savecode = RtoL(GetLocationY(savecode))
exitwhen savecode == null
set s = Savecode_itochar(RtoI(GetLocationX(savecode))) + s
endloop
return s
endfunction
function Savecode_froms takes location savecode, string s returns nothing
local integer i = StringLength(s)-1
local location node
loop
exitwhen i < 0
set node = Location(ItoR(Savecode_chartoi(SubString(s,i,i+1))),0.)
call MoveLocation(savecode,GetLocationX(savecode),HtoR(node))
set savecode = node
set i = i - 1
endloop
endfunction
function Savecode_hash takes location savecode returns integer
local integer hash = 0
local integer x
set savecode = RtoL(GetLocationY(savecode))
loop
exitwhen savecode == null
set x = RtoI(GetLocationX(savecode))
set hash = ModuloInteger(hash + 37*hash/(x+1) + 357*x/(1+hash-(hash/BASE())*BASE()) + 1337,HASHN())
set savecode = RtoL(GetLocationY(savecode))
endloop
return hash
endfunction
function Savecode_scommhash takes string s returns integer
local integer array count
local integer i = 0
local integer len = StringLength(s)
local integer x
set s = StringCase(s,true)
loop
exitwhen i >= len
set x = Savecode_player_chartoi(SubString(s,i,i+1))
set count[x] = count[x] + 1
set i = i + 1
endloop
set i = 0
set len = Savecode_player_charsetlen()
set x = 0
loop
exitwhen i>= len
set x = count[i]*count[i]*i+count[i]*x+x+173
set i = i + 1
endloop
if x < 0 then
set x = -x
endif
return x
endfunction
function modb takes integer x returns integer
if x >= BASE() then
return x - BASE()
elseif x < 0 then
return x + BASE()
else
return x
endif
endfunction
//sign = 1 is forward
//sign = -1 is backward
function Savecode_obfuscate takes location savecode, integer key,integer sign returns nothing
local location head
local integer seed = GetRandomInt(0,MAXINT())
local integer x
local integer advance
set savecode = RtoL(GetLocationY(savecode))
set head = savecode
if sign == -1 then
call SetRandomSeed(BigNum_lastdigit(head))
set x = RtoI(GetLocationX(head))
set x = modb(x + sign*GetRandomInt(0,BASE()-1))
call MoveLocation(head,ItoR(x),GetLocationY(head))
endif
call SetRandomSeed(key)
loop
exitwhen savecode == null
set x = RtoI(GetLocationX(savecode))
if sign == -1 then
set advance = x
endif
set x = modb(x + sign*GetRandomInt(0,BASE()-1))
if sign == 1 then
set advance = x
endif
set advance = advance + GetRandomInt(0,BASE()-1)
call SetRandomSeed(advance)
// call SetRandomSeed(GetRandomInt(0,BASE()-1))
call MoveLocation(savecode,ItoR(x),GetLocationY(savecode))
set savecode = RtoL(GetLocationY(savecode))
endloop
if sign == 1 then
call SetRandomSeed(x)
set x = RtoI(GetLocationX(head))
set x = modb(x + sign*GetRandomInt(0,BASE()-1))
call MoveLocation(head,ItoR(x),GetLocationY(head))
endif
set head = null
call SetRandomSeed(seed)
endfunction
function Savecode_dump takes location savecode returns nothing
local string s = ""
local integer x
set s = "max: "+R2S(GetLocationX(savecode))
set savecode = RtoL(GetLocationY(savecode))
loop
exitwhen savecode == null
set x = RtoI(GetLocationX(savecode))
set s = I2S(x)+" "+s
set savecode = RtoL(GetLocationY(savecode))
endloop
call BJDebugMsg(s)
endfunction
//finalize a save
function Savecode_save takes location savecode, player p,integer loadtype returns string
local integer key = Savecode_scommhash(GetS("PNames",GetConvertedPlayerId(p)))+loadtype*73
local string s
local integer hash
call Savecode_clean(savecode)
// call Savecode_dump(savecode)
// call Savecode_pad(savecode)
set hash = Savecode_hash(savecode)
call Savecode_encode(savecode,hash,HASHN())
call Savecode_clean(savecode)
// call Savecode_dump(savecode)
// call BJDebugMsg("Expected length: " +I2S(R2I(1.+Savecode_length(savecode,BASE()))))
// call BJDebugMsg("Room left in last char: "+R2S(1.-ModuloReal((Savecode_length(savecode,BASE())),1)))
call Savecode_pad(savecode)
call Savecode_obfuscate(savecode,key,1)
return Savecode_tos(savecode)
endfunction
//start a load
function Savecode_load takes location savecode, player p, string s,integer loadtype returns boolean
local integer ikey = Savecode_scommhash(GetS("PNames",GetConvertedPlayerId(p)))+loadtype*73
local integer inputhash
call Savecode_froms(savecode,s)
call Savecode_obfuscate(savecode,ikey,-1)
set inputhash = Savecode_decode(savecode,HASHN())
// call Savecode_dump(savecode)
call Savecode_clean(savecode)
return inputhash == Savecode_hash(savecode)
endfunction
Last edited: