• 🏆 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!

[JASS] JASS Coding trouble

Status
Not open for further replies.
Level 9
Joined
Nov 4, 2007
Messages
931
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?
JASS:
function R2L takes real r returns location
    return r
endfunction
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 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:
Status
Not open for further replies.
Top