• 🏆 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!
  • ✅ Time to vote for the top 3 models! The POLL for Hive's 6th HD Modeling Contest: Mechanical is now open! 📅 Poll close on July 16, 2024! 🔗 Cast your vote now!

[System] Simple Low Level Save/Load Framework

Level 31
Joined
Jul 10, 2007
Messages
6,306
For very simple save/load codes that don't need backwards compatibility or any of the advanced features of Encoder and only need to perhaps save a few values.


This includes all of the latest encryption as well as easy to edit configs. It is set up to be GUI friendly (if you want a vjass person to quickly set up a save/load code for you, they can easily read/write to your GUI variables).


This requires knowledge of BigInt as well as general saving and loading. I use this template for making simple save/load codes for people =P.


The only system that this does not include in it is UnitStatePercent as that requires some Lua, but it is simple enough to add to the bottom and make SL use at the top, so that can be added when needed.


In this template you will see 3 variables that it saves/loads-
test1
test2
test3

Those are just there so that one can quickly see how to use this. They can all be deleted.


Security Features-
player+salt+BASE based bases
player+salt+CHECKSUM bases checksums
player+salt based shuffling


Compression Features-
Plain old BigInt. No tree based structure like the one Encoder has. This is again for simple save/load codes.


Backwards Compatibility-
None, but it can be built in if needed.


This framework is very low level


If you have any of these resources in your map, delete them out of the script via CTRL+F library ResourceName
  • Table
  • BigInt
  • KnuthChecksum
  • Scrambler
  • Ascii
  • Base


The reason these systems are in this is for easy cnp. I expect many users using this to be using this for making simple save/load systems for GUI friends that probably aren't using any of the above systems anyways.


JASS:
library SL uses BigInt, KnuthChecksum, Scrambler
/*************************************************************************************
*
*                                       SETTINGS
*
*************************************************************************************/
globals
    //character set
    private constant string BASE="abcdefghijklmnopqrstuvwxyzABCDEFGHKLMNOPQRSTUVWXYZ0123456789@#$%&?"
    private constant boolean LOAD_ONCE=false                //if true, players can only successfully load once
    private constant boolean ONLINE_ONLY=false              //if true, game has to be on b.net or LAN to save/load
    private constant integer MIN_SAVE_PLAYER=1              //minimum amount of players required in game to save
    private constant integer MIN_LOAD_PLAYER=1              //minimum amount of players required in game to load
    //max checksum: 214748364
    private constant integer MAX_CHECKSUM =214748364        //maximum checksum
    private constant integer SHUFFLES =3                    //how many shuffles to perform
    private constant real VARIANCE =.85                     //checksum variance (shouldn't change)
    private constant string NUM_COLOR ="|cff40e0d0"         //what to color numbers
    private constant string LOWER_COLOR ="|cffff69b4"       //what to color lowercase characters
    private constant string UPPER_COLOR ="|cff00AA00"       //what to color uppercase characters
    private constant string SPEC_COLOR ="|cffffff00"        //what to color special characters
    private constant string DELIMITER_COLOR ="|cffffffff"   //what to color DELIMITER characters
    private constant string DELIMITER ="-"                  //DELIMITER to make code easier to read
    private constant integer DELIMITER_COUNT =4             //how many characters per DELIMITER
    //makes it impossible to get checksum with JASS w/o this code
    private constant string CHECKSUM_SALT ="123456"
    private constant string START_MESSAGE=""                //message displayed before code
    private constant string END_MESSAGE=""                  //message displayed after code
    private constant integer MAX_LOAD_ATTEMPT=-1            //<0 means infinite load attempts
    private constant real LOAD_TIME=180                     //how long the players can load for at the start of game
    private constant string LOAD_STOP_IN="|cffff0000Loading will be disabled in "
    //displayed when a player attempts to load and code was invalid
    private constant string INVALID_CODE="|cffff0000Invalid Code"
    //displayed after INVALID_CODE if MAX_LOAD_ATTEMPT is greater than 0
    private constant string LOAD_ATTEMPT=" Load attempt(s) Left"
    //displayed when a player successfully loads
    private constant string VALID_CODE="|cff008B00Decoding Successful"
    private constant integer MIN_CODE_LENGTH=10         //minimum length of code
    private constant integer MAX_CODE_LENGTH=30         //maximum length of code
    
    private constant string LOAD_DISABLED="|cffff0000Loading Disabled"  //message displayed when loading is disabled
    private constant string SAVE_DISABLED="|cffff0000Saving Disabled"   //message displayed when saving is disabled
endglobals
//! textmacro SCRAMBLER_SETTINGS
    globals
    /*************************************************************************************
    *
    *                                       SALT
    *
    *   Refers to what to append to the player's name when generating scrambler keys
    *   for each player. This is essentially like a password. It's impossible for another
    *   map to descramble a number without this password.
    *
    *   This password can be any string, such as "7/ah+53~r\\ZZ"
    *
    *************************************************************************************/
        private constant string SALT="123456"
    endglobals
    
    /*************************************************************************************
    *
    *                                   SetShuffleOrder
    *
    *   Creates the shuffling algorithm using 5 different prime bases.
    *
    *   Shuffling mixes a number up using a variety of bases to produce results rivaling
    *   top random number generators.
    *
    *   Different bases ensure better mixes.
    *
    *   Enabled Bases: 
    *
    *       2
    *           Will shuffle number in groups of 1 bit
    *       3
    *           Will shuffle number in groups of 1.58 bits
    *       5
    *           Will shuffle number in groups of 2.32 bits
    *       7
    *           Will shuffle in groups of 2.81 bits
    *       11
    *           Will shuffle in groups of 3.46 bits
    *
    *   Strategies:
    *
    *       1.
    *           shuffle by large1, shuffle by small1, shuffle by large2, etc
    *       2.
    *           shuffle by small1, shuffle by large1, shuffle by small2, etc
    *       3.
    *           shuffle by small1, shuffle by small2, shuffle by large1, shuffle by small3, etc
    *
    *       Keep in mind that as fractional bits are shuffled, bits split/merge, meaning that the number
    *       can drastically change by becoming much smaller or much larger.
    *
    *
    *   Shuffle Array: so
    *
    *   Ex:
    *
    *       set so[0]=3         //first mix by 1.58 bits
    *       set so[1]=2         //second mix by 1 bit
    *       set so[2]=7         //third mix by 2.81 bits
    *       set so[3]=2         //fourth mix by 1 bit
    *
    *       return 4            //return number of mixes
    *
    *************************************************************************************/
    private keyword so
    private function SetShuffleOrder takes nothing returns integer
        /*************************************************************************************
        *
        *                                       MIXES
        *
        *   array: so
        *   bases: 2,3,5,7,11
        *
        *************************************************************************************/
        set so[0]=2
        
        /*************************************************************************************
        *
        *                                       MIX COUNT
        *
        *************************************************************************************/
        return 1
    endfunction
//! endtextmacro
/*************************************************************************************
*
*                               SAVE/LOAD SETTINGS
*
*************************************************************************************/
globals
    //the biggest value you can save of all of the values
    private constant integer BIGGEST=1000000
    
    //variables for copying GUI vars over
    private integer array test
endglobals
//saves data from copied variables above
private function SaveData takes BigInt i, integer id returns nothing
    if (test[0]>1000000-1) then
        set test[0]=1000000-1
    endif
    if (test[1]>100000-1) then
        set test[1]=100000-1
    endif
    if (test[2]>10000-1) then
        set test[2]=10000-1
    endif
    call i.multiply(1000000)
    call i.add(test[0],0)
    call i.multiply(100000)
    call i.add(test[1],0)
    call i.multiply(10000)
    call i.add(test[2],0)
endfunction
//copies GUI variable data into array vars
private function CopyData takes integer id returns nothing
    set test[0]=udg_test[id]
    set test[1]=udg_test2[id]
    set test[2]=udg_test3[id]
endfunction
//loads values from code into arry vars
private function LoadData takes BigInt i, integer id returns nothing
    set test[2]=i.divide(10000)
    set test[1]=i.divide(100000)
    set test[0]=i.divide(1000000)
endfunction
//erases GUI vars
private function UnloadData takes integer id returns nothing
    set udg_test[id]=0
    set udg_test2[id]=0
    set udg_test3[id]=0
endfunction 
//writes to GUI vars (creates units, does w/e)
private function FinalizeData takes integer id returns nothing
    set udg_test[id]=test[0]
    set udg_test2[id]=test[1]
    set udg_test3[id]=test[2]
    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(test[0]))
    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(test[1]))
    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,I2S(test[2]))
endfunction
/*************************************************************************************
*
*                                       CODE
*
*************************************************************************************/
globals
    private integer array ph
    private Base array pb
    private Base b10
    private boolean array bl
    private integer array pl
    private integer c=0
    private trigger t=null
    private trigger t2=null
endglobals
function Save takes nothing returns boolean
    local integer id=GetPlayerId(GetTriggerPlayer())
    local BigInt i=BigInt.create(b10)
    local string s=""
    local integer h
    local string c
    local boolean l
    local integer bs
    local integer ch
    call CopyData(id+1)
    call SaveData(i,id+1)
    set ch=GetKnuthChecksum(i,ph[id])
    if (ph[id]>BIGGEST) then
        call i.destroy()
        set i=BigInt.create(b10)
        call i.add(ch,0)
        call SaveData(i,id+1)
    else
        call i.multiply(ph[id])
        call i.add(ch,0)
    endif
    call Shuffle(i,id,SHUFFLES)
    set i.base=pb[id]
    set h=DELIMITER_COUNT
    loop
        set i=i.previous
        exitwhen i.end
        set c=pb[id].char(i.digit)
        if (0==h) then
            set h=DELIMITER_COUNT
            set s=s+DELIMITER_COLOR+DELIMITER
        endif
        set l=StringCase(c,false)==c
        if (c==StringCase(c,true) and l) then
            if ("0"==c or 0!=S2I(c)) then
                set s=s+NUM_COLOR+c
            else
                set s=s+SPEC_COLOR+c
            endif
        elseif (l) then
            set s=s+LOWER_COLOR+c
        else
            set s=s+UPPER_COLOR+c
        endif
        set h=h-1
    endloop
    call i.destroy()
    if (GetLocalPlayer()==GetTriggerPlayer()) then
        call ClearTextMessages()
    endif
    call DisplayTimedTextToPlayer(GetTriggerPlayer(),.5,.5,60,START_MESSAGE+s+END_MESSAGE)
    return false
endfunction
function Load takes nothing returns boolean
    local integer id=GetPlayerId(GetTriggerPlayer())
    local BigInt i
    local string s2
    local integer m
    local string c
    local string s=""
    local integer bs
    local integer ch
    local boolean f
    if ((not bl[id] or not LOAD_ONCE) and 0<pl[id]) then
        set s2=GetEventPlayerChatString()
        set s2=SubString(s2,6,StringLength(s2))
        set m=StringLength(s2)
        loop
            exitwhen 0==m
            set m=m-1
            set c=SubString(s2,m,m+1)
            if (c!=DELIMITER) then
                set s=c+s
            endif
        endloop
        if (0<MAX_LOAD_ATTEMPT) then
            set pl[id]=pl[id]-1
        endif
        if (GetLocalPlayer()==GetTriggerPlayer()) then
            call ClearTextMessages()
        endif
        set m=StringLength(s)
        if (m<MIN_CODE_LENGTH or m>MAX_CODE_LENGTH) then
            if (0<MAX_LOAD_ATTEMPT) then
                call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,INVALID_CODE+", "+I2S(pl[id])+LOAD_ATTEMPT)
            else
                call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,INVALID_CODE)
            endif
        else
            set i=BigInt.convertString(s,pb[id])
            if (0==i) then
                if (0<MAX_LOAD_ATTEMPT) then
                    call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,INVALID_CODE+", "+I2S(pl[id])+LOAD_ATTEMPT)
                else
                    call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,INVALID_CODE)
                endif
            endif
            set i.base=b10
            call Unshuffle(i,id,SHUFFLES)
            set f=ph[id]>BIGGEST
            if (not f and i.divide(ph[id])!=GetKnuthChecksum(i,ph[id])) then
                call i.destroy()
                if (0<MAX_LOAD_ATTEMPT) then
                    call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,INVALID_CODE+", "+I2S(pl[id])+LOAD_ATTEMPT)
                else
                    call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,INVALID_CODE)
                endif
                return false
            else
                call LoadData(i,id+1)
                if (f) then
                    set ch=i.toInt()
                    call i.destroy()
                    set i=BigInt.create(b10)
                    call SaveData(i,id+1)
                    if (ch!=GetKnuthChecksum(i,ph[id])) then
                        call i.destroy()
                        if (MAX_LOAD_ATTEMPT>0) then
                            call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,INVALID_CODE+", "+I2S(pl[id])+LOAD_ATTEMPT)
                        else
                            call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,INVALID_CODE)
                        endif
                        return false
                    endif
                endif
                call i.destroy()
                set bl[id]=true
                call UnloadData(id+1)
                call FinalizeData(id+1)
                call DisplayTimedTextToPlayer(GetTriggerPlayer(),0,0,60,VALID_CODE)
            endif
        endif
    endif
    return false
endfunction
//this is run when a player leaves
private function Leave takes nothing returns boolean
    set c=c-1                       //decrease player count by 1
    
    //if player count is under minimum count needed for saving
    //and save trigger is enabled
    //disable save trigger
    if (c<MIN_SAVE_PLAYER and null!=t) then
        call DestroyTrigger(t)      //disable save trigger
        set t=null
        
        //display saving disabled message to all players
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,SAVE_DISABLED)
    endif
    
    //if player count is under minimum count for loading
    //and load trigger is enabled
    //disable load trigger
    if (c<MIN_LOAD_PLAYER and null!=t2) then
        call DestroyTrigger(t2)     //disable load trigger
        set t2=null
        
        //display loading disabled message to all players
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,LOAD_DISABLED)
    endif
    
    return false
endfunction
//stops load
private function SO takes nothing returns nothing
    //if loading is enabled
    if (null!=t2) then
        call DestroyTrigger(t2)
        set t2=null
    
        //display loading disabled message to all players
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,LOAD_DISABLED)
    endif
    
    call DestroyTimer(GetExpiredTimer())
endfunction
private module N
    private static method onInit takes nothing returns nothing
        local integer i=11                  //players 0-11
        local player p
        local integer ch                    //player hash
        local integer m                     //minimum checksum
        local integer ma                    //checksums active
        local trigger t3                    //leave trigger
        local Base y                        //BASE
        local BigInt q                      //base as BigInt
        local BigInt q2                     //player unique base as BigInt
        local integer ml=MAX_LOAD_ATTEMPT   //max load attempts formatted
        //is game not online?
        local boolean f=(not ReloadGameCachesFromDisk() or not ONLINE_ONLY)
        local real r=LOAD_TIME
        
        //if MAX_LOAD_ATTEMPT is under 0, then set formatted max load to 1
        //so that all players have infinite load attempts
        if (ml<0) then
            set ml=1
        endif
        
        //count how many players are in the map
        loop
            set p=Player(i)
            if (GetPlayerSlotState(p)==PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p)==MAP_CONTROL_USER) then
                set c=c+1
            endif
            exitwhen i==0
            set i=i-1
        endloop
        
        //if not online or player count too small, display saving is disabled to all players
        if (not f or c<MIN_SAVE_PLAYER) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,SAVE_DISABLED)
        endif
        //if not online or player count to small, display loading is disabled to all players
        if (not f or c<MIN_LOAD_PLAYER) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,LOAD_DISABLED)
        //disable load in a certain amount of time
        elseif (r>0) then
            call TimerStart(CreateTimer(),LOAD_TIME,false,function SO)
            if (r<86400) then
                if (r<3600) then
                    if (r<60) then
                        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,LOAD_STOP_IN+R2S(r)+" seconds")
                    else
                        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,LOAD_STOP_IN+R2S(r/60)+" minutes")
                    endif
                else
                    call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,LOAD_STOP_IN+R2S(r/360)+" hours")
                endif
            else
                call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,LOAD_STOP_IN+R2S(r/3600)+" days")
            endif
        endif
        
        //if online and either there are enough players to save or enough to load, then
        //set up the save/load
        if (f and (c>=MIN_SAVE_PLAYER or c>=MIN_LOAD_PLAYER)) then
            set t3=CreateTrigger()                                  //leave trigger
            call TriggerAddCondition(t3,Condition(function Leave))  //add Leave function to leave trigger
            
            //go back to player 11
            set i=11
            
            if (c>=MIN_SAVE_PLAYER) then
                set t=CreateTrigger()                   //save trigger
                call TriggerAddCondition(t,Condition(function Save))
            endif
            if (c>=MIN_LOAD_PLAYER) then
                set t2=CreateTrigger()                  //load trigger
                call TriggerAddCondition(t2,Condition(function Load))
            endif
            
            set m=R2I(MAX_CHECKSUM*VARIANCE)        //minimum possible checksum
            set ma=MAX_CHECKSUM-m                   //checksums active
            
            //convert BASE string into a Base with 0 swapped with 1 so that 0 isn't lost
            set y=Base[SubString(BASE,1,2)+SubString(BASE,0,1)+SubString(BASE,2,StringLength(BASE))]
            
            //convert the BASE string into a big integer
            set q=BigInt.convertString(BASE,y)
            
            //create base 10
            set b10=Base["0123456789"]
            
            //set up save/load for each player
            loop
                set p=Player(i)     //convert integer to player
                //if the player is not a computer and is playing
                if (GetPlayerSlotState(p)==PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p)==MAP_CONTROL_USER) then
                    set q2=q.copy()                     //copy original base
                    call Scramble(q2,i,3,y,true)        //scramble it
                    set pb[i]=Base[q2.toString()]       //give to player
                    call q2.destroy()                   //clean
                    
                    //get player hash (for player unique checksum)
                    set ch=IAbsBJ(StringHash(GetPlayerName(p)+CHECKSUM_SALT))
                    
                    //generate player unique checksum
                    set ph[i]=ch-ch/ma*ma+m
                    
                    //if enough players for saving, then register player to save trigger
                    if (c>=MIN_SAVE_PLAYER) then
                        call TriggerRegisterPlayerChatEvent(t,p,"-save",true)
                    endif
                    
                    //if enough players for loading, then register player to load trigger
                    if (c>=MIN_LOAD_PLAYER) then
                        call TriggerRegisterPlayerChatEvent(t2,p,"-load ",false)
                    endif
                    
                    //register player to player leave trigger
                    call TriggerRegisterPlayerEvent(t3,p,EVENT_PLAYER_LEAVE)
                    
                    //give player formatted max load attempts remaining
                    set pl[i]=ml
                endif
                exitwhen i==0
                set i=i-1
            endloop
            
            //clean handles
            set t=null
            set t2=null
            set t3=null
        endif
        
        set p=null
    endmethod
endmodule
private struct I extends array
    implement N
endstruct
endlibrary
library BigInt uses Base
globals
private integer i=0
private integer array n
private integer array p
private integer array v
private Base array b
private boolean array e
private trigger j=CreateTrigger()
private trigger x=CreateTrigger()
private trigger x4=CreateTrigger()
private trigger x5=CreateTrigger()
private trigger y0=CreateTrigger()
private trigger y6=CreateTrigger()
private trigger y7=CreateTrigger()
private trigger y8=CreateTrigger()
private trigger y9=CreateTrigger()
private trigger x1=CreateTrigger()
private trigger x2=CreateTrigger()
private integer td=0
private integer my=0
private integer my3=0
private integer td2=0
private string yy=""
private integer dz
endglobals
private module IntMod
private static method onInit takes nothing returns nothing
call TriggerAddCondition(j,Condition(function thistype.ch))
call TriggerAddCondition(x,Condition(function thistype.ml))
call TriggerAddCondition(x4,Condition(function thistype.div))
call TriggerAddCondition(x5,Condition(function thistype.s2))
call TriggerAddCondition(y0,Condition(function thistype.a0))
call TriggerAddCondition(y7,Condition(function thistype.m0))
call TriggerAddCondition(y6,Condition(function thistype.tos))
call TriggerAddCondition(y8,Condition(function thistype.c0))
call TriggerAddCondition(y9,Condition(function thistype.a1))
call TriggerAddCondition(x1,Condition(function thistype.m1))
call TriggerAddCondition(x2,Condition(function thistype.m2))
endmethod
endmodule
struct BigInt extends array
method operator previous takes nothing returns thistype
return p[this]
endmethod
method operator next takes nothing returns thistype
return n[this]
endmethod
method operator digit takes nothing returns integer
return v[this]
endmethod
method operator digit= takes integer y returns nothing
set v[this] = y
endmethod
method operator end takes nothing returns boolean
return e[this]
endmethod
private static method c0 takes nothing returns boolean
local integer y
local integer z
local integer q
local integer k=td
if (0==n[0]) then
set i=i+1
set z=i
else
set z=n[0]
set n[0]=n[z]
endif
set e[z]=true
set b[z]=b[k]
set v[z]=0
set q=z
loop
set k=n[k]
exitwhen e[k]
if (0==n[0]) then
set i=i+1
set y=i
else
set y=n[0]
set n[0]=n[y]
endif
set n[q]=y
set p[y]=q
set v[y]=v[k]
set q=y
endloop
set p[z]=q
set n[q]=z
set dz=z
return true
endmethod
method copy takes nothing returns thistype
set td=this
call TriggerEvaluate(y8)
return dz
endmethod
private static method a1 takes nothing returns boolean
local integer y=td
local integer a
local integer z=b[y].size
local integer q=0
local integer m
local integer g=dz
local integer k=my
loop
if (e[n[y]]) then
if (0==n[0]) then
set i=i+1
set a=i
else
set a=n[0]
set n[0]=n[a]
endif
set p[a]=y
set n[a]=td
set n[y]=a
set p[td]=a
set v[a]=0
endif
set y=n[y]
exitwhen 0==g
set g=g-1
endloop
loop
set k=n[k]
set v[y]=v[y]+v[k]
set m=y
loop
exitwhen z>v[m]
set q=v[m]/z
set v[m]=v[m]-v[m]/z*z
if (e[n[m]]) then
if (0==n[0]) then
set i=i+1
set a=i
else
set a=n[0]
set n[0]=n[a]
endif
set p[a]=m
set n[a]=td
set n[m]=a
set p[td]=a
set v[a]=0
endif
set m=n[m]
set v[m]=v[m]+q
endloop
exitwhen e[n[k]]
if (e[n[y]]) then
if (0==n[0]) then
set i=i+1
set a=i
else
set a=n[0]
set n[0]=n[a]
endif
set p[a]=y
set n[a]=td
set n[y]=a
set p[td]=a
set v[a]=0
endif
set y=n[y]
endloop
return true
endmethod
method addBig takes BigInt k,integer g returns nothing
if (0<v[p[k]]) then
set td=this
set my=k
set dz=g
call TriggerEvaluate(y9)
endif
endmethod
private static integer array zs
private static method m2 takes nothing returns boolean
local integer q=td2
local integer m=dz
local integer a
local integer k=my3
loop
set q=q-1
if (e[n[m]]) then
if (0==n[0]) then
set i=i+1
set a=i
else
set a=n[0]
set n[0]=n[a]
endif
set p[a]=m
set n[a]=td
set n[m]=a
set p[td]=a
set v[a]=0
endif
set m=n[m]
set v[m]=v[m]+zs[q]*v[k]
exitwhen 0==q
endloop
return true
endmethod
private static method m1 takes nothing returns boolean
local integer y=0
local integer q=0
local integer a=td
local integer m=a
local integer w=a
local integer k=my
loop
set a=p[a]
exitwhen e[a]
set zs[y]=v[a]
set y=y+1
endloop
set n[p[a]]=n[0]
set n[0]=n[a]
set n[a]=a
set p[a]=a
loop
set k=n[k]
exitwhen e[k]
set td2=y
set w=n[w]
set dz=w
set my3=k
call TriggerEvaluate(x2)
endloop
set y=0
set a=td
set w=a
set q=a
set k=b[a].size
set m=a
loop
if (e[n[a]]) then
if (0==n[0]) then
set i=i+1
set m=i
else
set m=n[0]
set n[0]=n[m]
endif
set p[m]=a
set n[m]=w
set n[a]=m
set p[w]=m
set v[m]=0
endif
set a=n[a]
set y=y+v[a]
set v[a]=y-y/k*k
set y=y/k
exitwhen e[n[a]] and 0==y
endloop
return true
endmethod
method multiplyBig takes BigInt k returns nothing
if (0<v[p[k]]) then
set td=this
set my=k
call TriggerEvaluate(x1)
elseif (0==v[p[k]] and not e[p[this]]) then
set n[p[this]]=0
set n[0]=n[this]
set n[this]=this
set p[this]=this
endif
endmethod
static method create takes Base k returns thistype
local integer y
local integer z
if (0==n[0]) then
set i=i+1
set z=i
else
set z=n[0]
set n[0]=n[z]
endif
set e[z]=true
set b[z]=k
set n[z]=z
set p[z]=z
set v[z]=0
return z
endmethod
private static method a0 takes nothing returns boolean
local integer y=td
local integer a
local integer z=my3
local integer k=td2
loop
if (e[n[y]]) then
if (0==n[0]) then
set i=i+1
set a=i
else
set a=n[0]
set n[0]=n[a]
endif
set p[a]=y
set n[a]=td
set n[y]=a
set p[td]=a
set v[a]=0
endif
set y=n[y]
exitwhen 0==z
set z=z-1
endloop
set z=b[td].size
loop
set v[y]=v[y]+k
exitwhen z>v[y]
set k=v[y]/z
set v[y]=v[y]-k*z
if (e[n[y]]) then
if (0==n[0]) then
set i=i+1
set a=i
else
set a=n[0]
set n[0]=n[a]
endif
set p[a]=y
set n[a]=td
set n[y]=a
set p[td]=a
set v[a]=0
endif
set y=n[y]
endloop
return true
endmethod
method add takes integer k,integer g returns nothing
if (0<k) then
set td=this
set my3=g
set td2=k
call TriggerEvaluate(y0)
endif
endmethod
private static method ml takes nothing returns boolean
local integer y=td
local integer z=b[td].size
local integer a=0
local integer k=my
local integer q
loop
set y=n[y]
exitwhen e[y]
set v[y]=v[y]*k
endloop
set y=td
loop
set y=n[y]
exitwhen e[y]
set q=y
loop
exitwhen z>v[q]
if (e[n[q]]) then
if (0==n[0]) then
set i=i+1
set a=i
else
set a=n[0]
set n[0]=n[a]
endif
set p[a]=q
set n[a]=td
set n[q]=a
set p[td]=a
set v[a]=0
endif
set v[n[q]]=v[n[q]]+v[q]/z
set v[q]=v[q]-v[q]/z*z
endloop
endloop
return true
endmethod
method multiply takes integer k returns nothing
if (0<k) then
if (0<v[p[this]]) then
set td=this
set my=k
call TriggerEvaluate(x)
endif
elseif (0==k and not e[p[this]]) then
set n[p[this]]=n[0]
set n[0]=n[this]
set n[this]=this
set p[this]=this
endif
endmethod
method enq takes integer k returns nothing
local integer y=p[this]
local integer z
local integer a=b[this].size
loop
if (0==n[0]) then
set i=i+1
set z=i
else
set z=n[0]
set n[0]=n[z]
endif
set p[z]=y
set n[z]=n[y]
set n[y]=z
set p[n[z]]=z
set v[z]=k
set y=z
exitwhen a>v[y]
set k=v[y]/a
set v[y]=v[y]-k*a
endloop
endmethod
method deq takes nothing returns integer
local thistype z=p[this]
if (not e[z]) then
set p[this]=p[z]
set n[p[z]]=this
set n[z]=n[0]
set n[0]=z
endif
return v[z]
endmethod
method push takes integer k returns nothing
local integer y=this
local integer z
local integer a=b[this].size
loop
if (0==n[0]) then
set i=i+1
set z=i
else
set z=n[0]
set n[0]=n[z]
endif
set p[z]=y
set n[z]=n[y]
set n[y]=z
set p[n[z]]=z
set v[z]=k
set y=z
exitwhen a>v[y]
set k=v[y]/a
set v[y]=v[y]-k*a
endloop
endmethod
method pop takes nothing returns integer
local thistype z=n[this]
if (not e[z]) then
set n[this]=n[z]
set p[n[z]]=this
set n[z]=n[0]
set n[0]=z
endif
return v[z]
endmethod
method rr takes nothing returns nothing
local integer z
set z=p[this]
set n[z]=n[this]
set p[n[z]]=z
set p[this]=p[z]
set n[p[z]]=this
set p[z]=this
set n[this]=z
endmethod
method rl takes nothing returns nothing
local integer z
set z=n[this]
set p[z]=p[this]
set n[p[z]]=z
set n[this]=n[z]
set p[n[z]]=this
set n[z]=this
set p[this]=z
endmethod
private static method m0 takes nothing returns boolean
local integer z=0
local integer q=td
local integer u=b[q].size
local integer k=my
loop
set q=p[q]
exitwhen e[q]
set z=(z*u+v[q])
set z=z-z/k*k
endloop
set dz=z
return true
endmethod
method mod takes integer k returns integer
set td=this
set my=k
call TriggerEvaluate(y7)
return dz
endmethod
method destroy takes nothing returns nothing
set n[p[this]]=n[0]
set n[0]=this
set e[this]=false
endmethod
private static method tos takes nothing returns boolean
local string q=""
local integer y=td
local Base z=b[y]
loop
set y=n[y]
exitwhen e[y]
set q=z.char(v[y])+q
endloop
if (q=="") then
set yy=z.char(0)
else
set yy=q
endif
return true
endmethod
method toString takes nothing returns string
set td=this
call TriggerEvaluate(y6)
return yy
endmethod
method operator base= takes Base k returns nothing
if (b[this].size!=k.size and not e[n[this]]) then
set td=this
set td2=k
call TriggerEvaluate(j)
endif
set b[this]=k
endmethod
private static method ch takes nothing returns boolean
local integer q=td
local integer u
local integer k
if (0==n[0]) then
set i=i+1
set k=i
else
set k=n[0]
set n[0]=n[k]
endif
set e[k]=true
set u=p[q]
set p[q]=p[u]
set p[k]=u
set n[k]=u
set p[u]=k
set n[u]=k
set b[k]=td2
set v[k]=0
set my=Base(b[td]).size
set my3=0
set td=k
set td2=v[u]
set v[u]=0
loop
call TriggerEvaluate(y0)
exitwhen e[p[q]]
call TriggerEvaluate(x)
set u=p[q]
set p[q]=p[u]
set td2=v[u]
set n[u]=n[0]
set n[0]=u
endloop
set n[q]=n[k]
set p[q]=p[k]
set p[n[k]]=q
set n[p[k]]=q
set n[k]=n[0]
set n[0]=k
set e[k]=false
return true
endmethod
method toInt takes nothing returns integer
local integer k=0
local integer z=b[this].size
loop
set this=p[this]
exitwhen e[this]
set k=k*z
set k=k+v[this]
endloop
return k
endmethod
private static method div takes nothing returns boolean
local integer z=0
local integer a=td
local integer y=a
local integer h=b[a].size
local integer k=my
set y=p[y]
loop
set z=z*h+v[y]
exitwhen e[p[y]] or z>=k
set n[y]=n[0]
set n[0]=y
set y=p[y]
endloop
set p[a]=y
set n[y]=a
loop
set v[y]=z/k
set z=z-v[y]*k
set y=p[y]
exitwhen e[y]
set z=z*h+v[y]
endloop
set y=a
loop
set y=p[y]
exitwhen 0!=v[y] or e[y]
set n[y]=n[0]
set n[0]=y
endloop
set p[a]=y
set n[y]=a
set my=z
return true
endmethod
method divide takes integer k returns integer
if (0<k and 0<v[p[this]]) then
set td=this
set my=k
call TriggerEvaluate(x4)
else
return 0
endif
return my
endmethod
private static method s2 takes nothing returns boolean
local Base d=td
local string k=yy
local integer y
local integer z
local integer h=StringLength(k)
if (not d.isValid(k)) then
set td=0
return true
endif
if (0==n[0]) then
set i=i+1
set z=i
else
set z=n[0]
set n[0]=n[z]
endif
set e[z]=true
set b[z]=d
set n[z]=z
set p[z]=z
set v[z]=0
loop
set h=h-1
if (0==n[0]) then
set i=i+1
set y=i
else
set y=n[0]
set n[0]=n[y]
endif
set v[y]=d.ord(SubString(k,h,h+1))
set p[y]=p[z]
set n[y]=z
set n[p[z]]=y
set p[z]=y
exitwhen 0==h
endloop
set td=z
return true
endmethod
static method convertString takes string k,Base y returns thistype
set yy=k
set td=y
call TriggerEvaluate(x5)
return td
endmethod
method operator base takes nothing returns Base
return b[this]
endmethod
implement IntMod
endstruct
endlibrary
library Base uses Ascii,Table
globals
private Table gt=0
private integer array n
private string array b
private Table array t
private integer c=0
private integer array s
endglobals
private module Init
private static method onInit takes nothing returns nothing
set gt=Table.create()
endmethod
endmodule
struct Base extends array
static method operator [] takes string base returns thistype
local integer value
local string char
local integer i=0
local integer v
local integer dv
set value = StringHash(base)
set i = gt[value]
set v = i
if (0!=i) then
loop
exitwhen 0==i or base==b[i]
set i=n[i]
endloop
endif
if (0==i) then
set c=c+1
set i=c
set dv=v
set t[i]=Table.create()
set b[i]=base
set value=StringLength(base)
set s[i]=value
loop
set value=value-1
set char=SubString(base,value,value+1)
set v=Char2Ascii(char)
set t[i][v]=value
set t[i].string[-value]=char
exitwhen 0==value
endloop
if (0==dv) then
set gt[value]=i
else
set n[i]=n[dv]
set n[dv]=i
endif
endif
return i
endmethod
method convertToString takes integer i returns string
local integer k=s[this]
local string n=""
loop
exitwhen i<k
set n=t[this].string[-(i-i/k*k)]+n
set i=i/k
endloop
return t[this].string[-i]+n
endmethod
method convertToInteger takes string i returns integer
local integer n=0
local integer p=StringLength(i)
local integer l=0
local integer k=s[this]
local string char
loop
exitwhen 0==p
set p=p-1
set l=l+1
set char=SubString(i,l-1,l)
set n=n+t[this][Char2Ascii(char)]*R2I(Pow(k,p))
endloop
return n
endmethod
method ord takes string c returns integer
return t[this][Char2Ascii(c)]
endmethod
method char takes integer i returns string
return t[this].string[-i]
endmethod
method isValid takes string s returns boolean
local integer i=StringLength(s)
local string c
if (0<i) then
loop
set c=SubString(s,i-1,i)
if (not t[this].has(Char2Ascii(c))) then
return false
endif
set i=i-1
exitwhen 0==i
endloop
else
return false
endif
return true
endmethod
method operator size takes nothing returns integer
return s[this]
endmethod
implement Init
endstruct
endlibrary
library Scrambler uses BigInt
//! runtextmacro SCRAMBLER_SETTINGS()
globals
private integer array ss
private boolean array se
private BigInt array d
private integer i
private integer dc
private integer k
private integer s1
private integer s2
private integer s3
private integer pid
private trigger mt=CreateTrigger()
private trigger dt=CreateTrigger()
private trigger st=CreateTrigger()
private trigger ut=CreateTrigger()
private BigInt bi
private Base array bs
private integer array so
private integer sc=0
endglobals
private function LNF takes BigInt int,boolean i0 returns nothing
set dc=0
if (i0) then
loop
set int=int.next
exitwhen int.end
set d[dc]=int
set dc=dc+1
endloop
else
loop
set int=int.next
exitwhen int.next.end
set d[dc]=int
set dc=dc + 1
endloop
set int=int.next
endif
endfunction
private function LNB takes BigInt int,boolean i0 returns nothing
set dc=0
if (not i0) then
set int=int.previous
endif
loop
set int=int.previous
exitwhen int.end
set d[dc]=int
set dc=dc+1
endloop
endfunction
private function FLP takes integer id,integer i2 returns nothing
loop
exitwhen 0==i2
set s1=dc
loop
exitwhen 0==s1
set s1=s1-1
if (se[k]) then
set k=ss[id]
else
set k=k+1
endif
endloop
set i2=i2-1
endloop
endfunction
function Scramble takes BigInt int,integer id,integer shuffles,Base bb,boolean i0 returns nothing
local Base b=int.base
set pid=id
set k=ss[id]
set i=shuffles
if (b!=bb) then
set int.base=bb
endif
call LNF(int,i0)
call TriggerEvaluate(st)
if (b!=bb) then
set int.base=b
endif
endfunction
function Unscramble takes BigInt int,integer id,integer shuffles,integer bb,boolean i0 returns nothing
local Base b=int.base
set i=shuffles
set pid=id
set k=ss[id]
if (b!=bb) then
set int.base=bb
endif
call LNB(int,i0)
call FLP(id,shuffles)
call TriggerEvaluate(ut)
if (b!=bb) then
set int.base=b
endif
endfunction
private function St takes nothing returns boolean
loop
exitwhen 0==i
set s1=dc
loop
exitwhen 0==s1
set s1=s1-1
set s2=s1-ss[k]
loop
exitwhen 0<=s2
set s2=dc+s2
endloop
set s3=d[s2].digit
set d[s2].digit=d[s1].digit
set d[s1].digit=s3
if (se[k]) then
set k=ss[pid]
else
set k=k+1
endif
endloop
set i=i-1
endloop
return false
endfunction
private function Ut takes nothing returns boolean
loop
exitwhen 0==i
set s1 = dc
loop
exitwhen 0==s1
set s1=s1-1
set k=k-1
if (0==ss[k]) then
set k=ss[pid+12]
endif
set s2=s1+ss[k]
loop
exitwhen s2<dc
set s2=s2-dc
endloop
set s3=d[s2].digit
set d[s2].digit=d[s1].digit
set d[s1].digit=s3
endloop
set i=i-1
endloop
return false
endfunction
private function Mt takes nothing returns boolean
local integer sh=0
set k=ss[pid]
loop
exitwhen sh==sc
set i=1
set bi.base=bs[so[sh]]
call LNF(bi,false)
call St()
set sh=sh+1
set k=ss[pid]
endloop
return false
endfunction
private function Dt takes nothing returns boolean
local integer sh=sc
set k=ss[pid]
loop
exitwhen 0==sh
set sh=sh-1
set i=1
set bi.base=bs[so[sh]]
call LNB(bi,false)
call FLP(pid,1)
call Ut()
set k=ss[pid]
endloop
return false
endfunction

function Shuffle takes BigInt int, integer id, integer h returns nothing
local Base b=int.base
set bi=int
set pid=id
loop
exitwhen 0==h
call TriggerEvaluate(mt)
set h=h-1
endloop
set int.base=b
endfunction
function Unshuffle takes BigInt int, integer id, integer h returns nothing
local Base b=int.base
set bi=int
set pid=id
loop
exitwhen 0==h
call TriggerEvaluate(dt)
set h=h-1
endloop
set int.base=b
endfunction
private module Init
private static method onInit takes nothing returns nothing
local integer is=11
local integer hh
local integer ks=25
local Base b8=Base["012345678"]
local BigInt bg
call TriggerAddCondition(mt,Condition(function Mt))
call TriggerAddCondition(dt,Condition(function Dt))
call TriggerAddCondition(st,Condition(function St))
call TriggerAddCondition(ut,Condition(function Ut))
set bs[2]=Base["01"]
set bs[3]=Base["012"]
set bs[5]=Base["01234"]
set bs[7]=Base["0123456"]
set bs[11]=Base["0123456789A"]
set sc=SetShuffleOrder()
loop
if (GetPlayerSlotState(Player(is))==PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(is))==MAP_CONTROL_USER) then
set ss[is]=ks
set hh=StringHash(StringCase(GetPlayerName(Player(is))+SALT,false))
if (0>hh) then
set hh=-hh
endif
set bg=BigInt.create(b8)
call bg.add(hh,0)
set bg=bg.previous
loop
set ss[ks]=bg.digit+1
set bg=bg.previous
exitwhen bg.end
set ks=ks+1
endloop
set se[ks]=true
set ss[is+12]=ks
call bg.destroy()
set ks=ks+2
endif
exitwhen 0==is
set is=is-1
endloop
endmethod
endmodule
private struct Inits extends array
implement Init
endstruct
endlibrary
library Ascii
globals
private integer array i
private string array c
endglobals
function Char2Ascii takes string s returns integer
local integer a
if ("\\"==s) then
return 92
endif
set a=i[StringHash(s)/0x1F0748+0x3EA]
if (s!=c[a]) then
return a+32
endif
return a
endfunction
function Ascii2Char takes integer a returns string
return c[a]
endfunction
function A2S takes integer a returns string
local string s=""
loop
set s=c[a-a/256*256]+s
set a=a/256
exitwhen 0==a
endloop
return s
endfunction
function S2A takes string s returns integer
local integer a=0
local integer l=StringLength(s)
local integer j=0
local string m
local integer h
loop
exitwhen j==l
set m=SubString(s,j,j+1)
if ("\\"==m) then
set a=a*256+92
else
set h=i[StringHash(m)/0x1F0748+0x3EA]
if (m!=c[h]) then
set a=a*256+h+32
else
set a=a*256+h
endif
endif
set j=j+1
endloop
return a
endfunction
private module Init
private static method onInit takes nothing returns nothing
set i[931]=8
set i[1075]=9
set i[1586]=10
set i[1340]=12
set i[412]=13
set i[198]=32
set i[1979]=33
set i[1313]=34
set i[1003]=35
set i[1264]=36
set i[983]=37
set i[1277]=38
set i[306]=39
set i[904]=40
set i[934]=41
set i[917]=42
set i[1972]=43
set i[1380]=44
set i[1985]=45
set i[869]=46
set i[1906]=47
set i[883]=48
set i[1558]=49
set i[684]=50
set i[582]=51
set i[668]=52
set i[538]=53
set i[672]=54
set i[1173]=55
set i[71]=56
set i[277]=57
set i[89]=58
set i[1141]=59
set i[39]=60
set i[1171]=61
set i[51]=62
set i[305]=63
set i[0]=64
set i[222]=65
set i[178]=66
set i[236] =67
set i[184]=68
set i[1295]=69
set i[1390]=70
set i[1276]=71
set i[203]=72
set i[1314]=73
set i[209]=74
set i[1315]=75
set i[170]=76
set i[1357]=77
set i[1343]=78
set i[1397]=79
set i[1420]=80
set i[1419]=81
set i[1396]=82
set i[1374]=83
set i[1407]=84
set i[499]=85
set i[1465]=86
set i[736]=87
set i[289]=88
set i[986]=89
set i[38]=90
set i[1230]=91
set i[1636]=93
set i[1416]=94
set i[1917]=95
set i[217]=96
set i[833]=123
set i[1219]=124
set i[553]=125
set i[58]=126
set c[8]="\b"
set c[9]="\t"
set c[10]="\n"
set c[12]="\f"
set c[13]="\r"
set c[32]=" "
set c[33]="!"
set c[34]="\""
set c[35]="#"
set c[36]="$"
set c[37]="%"
set c[38]="&"
set c[39]="'"
set c[40]="("
set c[41]=")"
set c[42]="*"
set c[43]="+"
set c[44]=","
set c[45]="-"
set c[46]="."
set c[47]="/"
set c[48]="0"
set c[49]="1"
set c[50]="2"
set c[51]="3"
set c[52]="4"
set c[53]="5"
set c[54]="6"
set c[55]="7"
set c[56]="8"
set c[57]="9"
set c[58]=":"
set c[59]=";"
set c[60]="<"
set c[61]="="
set c[62]=">"
set c[63]="?"
set c[64]="@"
set c[65]="A"
set c[66]="B"
set c[67]="C"
set c[68]="D"
set c[69]="E"
set c[70]="F"
set c[71]="G"
set c[72]="H"
set c[73]="I"
set c[74]="J"
set c[75]="K"
set c[76]="L"
set c[77]="M"
set c[78]="N"
set c[79]="O"
set c[80]="P"
set c[81]="Q"
set c[82]="R"
set c[83]="S"
set c[84]="T"
set c[85]="U"
set c[86]="V"
set c[87]="W"
set c[88]="X"
set c[89]="Y"
set c[90]="Z"
set c[92]="\\"
set c[97]="a"
set c[98]="b"
set c[99]="c"
set c[100]="d"
set c[101]="e"
set c[102]="f"
set c[103]="g"
set c[104]="h"
set c[105]="i"
set c[106]="j"
set c[107]="k"
set c[108]="l"
set c[109]="m"
set c[110]="n"
set c[111]="o"
set c[112]="p"
set c[113]="q"
set c[114]="r"
set c[115]="s"
set c[116]="t"
set c[117]="u"
set c[118]="v"
set c[119]="w"
set c[120]="x"
set c[121]="y"
set c[122]="z"
set c[91]="["
set c[93]="]"
set c[94]="^"
set c[95]="_"
set c[96]="`"
set c[123]="{"
set c[124]="|"
set c[125]="}"
set c[126]="~"
endmethod
endmodule
private struct Inits extends array
implement Init
endstruct
endlibrary
library KnuthChecksum uses BigInt
function GetKnuthChecksum takes BigInt k, integer m returns integer
local BigInt c = k.copy()
local BigInt c2 = k.copy()
call c.add(3,0)
call c2.multiplyBig(c)
call c.destroy()
set c = c2.mod(m)
call c2.destroy()
return c
endfunction
endlibrary
library Table
globals
private hashtable ht=InitHashtable()
private integer q=2
private integer w=0
endglobals
private struct dex extends array
static method operator size takes nothing returns Table
return 1
endmethod
static method operator list takes nothing returns Table
return 2
endmethod
endstruct
private struct strings extends array
method operator [] takes integer key returns string
return LoadStr(ht,this,key)
endmethod
method operator []= takes integer key,string value returns nothing
call SaveStr(ht,this,key,value)
endmethod
method has takes integer key returns boolean
return HaveSavedString(ht,this,key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedString(ht,this,key)
endmethod
endstruct
private module stringm
method operator string takes nothing returns strings
return this
endmethod
endmodule
struct Table extends array
implement stringm
method operator [] takes integer key returns Table
return LoadInteger(ht,this,key)
endmethod
method operator []= takes integer key,Table a returns nothing
call SaveInteger(ht,this,key,a)
endmethod
method has takes integer key returns boolean
return HaveSavedInteger(ht,this,key)
endmethod
method remove takes integer key returns nothing
call RemoveSavedInteger(ht,this,key)
endmethod
method flush takes nothing returns nothing
call FlushChildHashtable(ht,this)
endmethod
static method create takes nothing returns Table
local Table this=dex.list[0]
if 0==this then
set q=q+1
set this=q
else
set dex.list[0]=dex.list[this]
call dex.list.remove(this)
endif
return this
endmethod
method destroy takes nothing returns nothing
call this.flush()
set dex.list[this]=dex.list[0]
set dex.list[0]=this
endmethod
endstruct
endlibrary
 

Attachments

  • Template.w3x
    60.9 KB · Views: 89
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
Also, you're going to have to change the globals to User Declared Globals (udg)


You didn't read all of it =P


JASS:
//writes to GUI vars (creates units, does w/e)
private function FinalizeData takes integer id returns nothing
    set udg_test[id]=test[id]
    set udg_test2[id]=test2[id]
    set udg_test3[id]=test3[id]
endfunction


The reason for this is because sometimes there may be units involved. I don't do a write until I'm sure of the data =). The globals are just there for storage ;p.


Also, the compile to JASS is pointless because of the globals ;P


Also, if you look at the characters, I left l, I,and J out. I'm also going to be taking out ^+=<>! since those are also annoying to read =P. I'll be adding in ?

That's the easiest character set to read ;D. I don't have to squint my eyes to see if the letter is an I or a J and I don't have to freak over the +-=>-<-

=P

a-a-a-a-a is much easier to read than +-=->-<

^ seems fine too, but it's a bit small in wc3. l is probably fine as well.

So looking at this for new standard character set I use (65 chars)
abcdefghijklmnopqrstuvwxyzABCDEFGHKLMNOPQRSTUVWXYZ0123456789@#$%&?
 
Level 10
Joined
Jul 12, 2009
Messages
318
I have trouble telling O and 0 apart in WC3-font; you may want to omit one of those characters.

FYI, I've been using `123456789-=abcdefghijkmnopqrstuvwxyz[];~!@#$%^&*()_+ABCDEFGHJKLMNPQRSTUVWXYZ{}:<>? as a base, although it's a pain to type non-alphabetic characters.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Updated
-Fixed online checking boolean
-Added new config options as well as new features
-Rather than disabling the save/load triggers, they are now destroyed
-save/load trigs are only created if they should be created now
-Systems update: BigInt, Ascii, Scrambler, Base


If anyone else wants any other configuration options, please let me know =).
 
Top