The desync happens at the very start when the game starts and it only happens when there's 3 or more people, when 4 it desyncs 1 person when 5 it desyncs 2 etc. I have managed to identify triggers that cause it but I can't seem to be able to find why they do it so any help would be appreciated! I will also post any triggers that happen on map initialization and elapsed game time is 0.00 seconds as well just in case.
It's basically the Codeless Save/Load by TriggerHappy with some modifications made by DarkPacific etc to make it work in later version of reforged.
(As a side note the desyncs were still happening even before I was using the LocalPlayer to disable user control)
EDIT: Additionally I don't know if that matters but I use the Wc3 vex map optimizer to protect the map using the settings as shown in the pictures. I also import the latest common.j and blizzard.j
EDIT2: In a 9-man lobby that I tried earlier today it appears 2 got desynced so...
It's basically the Codeless Save/Load by TriggerHappy with some modifications made by DarkPacific etc to make it work in later version of reforged.
JASS:
library SyncHelper
globals
public constant string SYNC_PREFIX = "S"
endglobals
private keyword INITS
private struct Sync extends array
static trigger Trigger = CreateTrigger()
implement INITS
endstruct
function SyncString takes string s returns boolean
return BlzSendSyncData(SYNC_PREFIX, s)
endfunction
function OnSyncString takes code func returns triggeraction
return TriggerAddAction(Sync.Trigger, func)
endfunction
function RemoveSyncString takes triggeraction t returns nothing
call TriggerRemoveAction(Sync.Trigger, t)
endfunction
private module INITS
private static method onInit takes nothing returns nothing
local integer i = 0
loop
call BlzTriggerRegisterPlayerSyncEvent(.Trigger, Player(i), SYNC_PREFIX, false)
set i = i + 1
exitwhen i == bj_MAX_PLAYER_SLOTS
endloop
endmethod
endmodule
endlibrary
JASS:
library SaveFile requires FileIO
private keyword SaveFileInit
struct SaveFile extends array
static constant string ManualPath = "Manual"
static constant string InvalidPath = "Unknown"
static constant integer MIN = 1
static constant integer MAX = 10
private File file
static method operator Folder takes nothing returns string
return udg_MapName
endmethod
static method getPath takes integer slot returns string
if (slot == 0) then
return .Folder + "\\SaveSlot_" + .InvalidPath + ".pld"
elseif (slot > 0 and (slot < .MIN or slot > .MAX)) then
return .Folder + "\\SaveSlot_" + .InvalidPath + ".pld"
elseif (slot < 0) then
return .Folder + "\\SaveSlot_" + .ManualPath + ".pld"
endif
return .Folder + "\\SaveSlot_" + I2S(slot) + ".pld"
endmethod
static method getBackupPath takes integer slot, integer saveNumber returns string
if (slot == 0) then
return .Folder + "\\Backups\\SaveSlot_" + .InvalidPath + ".pld"
elseif (slot > 0 and (slot < .MIN or slot > .MAX)) then
return .Folder + "\\Backups\\SaveSlot_" + .InvalidPath + ".pld"
elseif (slot < 0) then
return .Folder + "\\Backups\\SaveSlot_" + .ManualPath + ".pld"
endif
return .Folder + "\\Backups\\SaveSlot_" + I2S(slot) + "_" + I2S(saveNumber) + ".pld"
endmethod
static method create takes player p, string title, integer slot, integer saveNumber, string data returns thistype
if (GetLocalPlayer() == p) then
call FileIO_Write(.getPath(slot), title + "\n" + data)
call FileIO_Write(.getBackupPath(slot, saveNumber), title + "\n" + data)
endif
return slot
endmethod
static method clear takes player p, integer slot, integer saveNumber returns thistype
if (GetLocalPlayer() == p) then
call FileIO_Write(.getPath(slot), "")
call FileIO_Write(.getBackupPath(slot, saveNumber), "")
endif
return slot
endmethod
static method exists takes integer slot, integer saveNumber returns boolean // async
if saveNumber == 0 then
return StringLength(FileIO_Read(.getPath(slot))) > 1
else
return StringLength(FileIO_Read(.getBackupPath(slot, saveNumber))) > 1
endif
endmethod
method getLines takes integer line, boolean includePrevious, integer saveNumber returns string // async
local string contents = FileIO_Read(.getPath(this))
local integer len = StringLength(contents)
local string char = null
local string buffer = ""
local integer curLine = 0
local integer i = 0
//call BJDebugMsg("Reading " + .getPath(this) + " with length " + I2S(len))
//call BJDebugMsg("Contents " + contents)
if saveNumber > 0 then
set contents = FileIO_Read(.getBackupPath(this, saveNumber))
set len = StringLength(contents)
//call BJDebugMsg("saveNumber > 0: Reading Backup")
//call BJDebugMsg("Reading " + .getBackupPath(this, saveNumber) + " with length " + I2S(len))
//call BJDebugMsg("Contents " + contents)
endif
loop
exitwhen i > len
set char = SubString(contents, i, i + 1)
if (char == "\n") then
set curLine = curLine + 1
if (curLine > line) then
return buffer
endif
if (not includePrevious) then
set buffer = ""
endif
else
set buffer = buffer + char
endif
set i = i + 1
endloop
if (curLine == line) then
return buffer
endif
return null
endmethod
method getLine takes integer line returns string // async
return .getLines(line, false, 0)
endmethod
method getTitle takes integer saveNumber returns string // async
return .getLines(0, false, saveNumber)
endmethod
method getData takes nothing returns string // async
return .getLines(1, false, 0)
endmethod
method getBackupData takes integer saveNumber returns string // async
return .getLines(1, false, saveNumber)
endmethod
implement SaveFileInit
endstruct
private module SaveFileInit
private static method onInit takes nothing returns nothing
//set thistype.Folder = udg_MapName
endmethod
endmodule
endlibrary
JASS:
library FileIO
/***************************************************************
*
* v1.1.0, by TriggerHappy
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*
* Provides functionality to read and write files.
* _________________________________________________________________________
* 1. Requirements
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* - Patch 1.29 or higher.
* - JassHelper (vJASS)
* _________________________________________________________________________
* 2. Installation
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* Copy the script to your map and save it.
* _________________________________________________________________________
* 3. API
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
* struct File extends array
*
* static constant integer AbilityCount
* static constant integer PreloadLimit
*
* readonly static boolean ReadEnabled
* readonly static integer Counter
* readonly static integer array List
*
* static method open takes string filename returns File
* static method create takes string filename returns File
*
* ---------
*
* method write takes string value returns File
* method read takes nothing returns string
*
* method readEx takes boolean close returns string
* method readAndClose takes nothing returns string
* method readBuffer takes nothing returns string
* method writeBuffer takes string contents returns nothing
* method appendBuffer takes string contents returns nothing
*
* method close takes nothing returns nothing
*
* public function Write takes string filename, string contents returns nothing
* public function Read takes string filename returns string
*
***************************************************************/
globals
// Enable this if you want to allow the system to read files generated in patch 1.30 or below.
// NOTE: For this to work properly you must edit the 'Amls' ability and change the levels to 2
// as well as typing something in "Level 2 - Text - Tooltip - Normal" text field.
//
// Enabling this will also cause the system to treat files written with .write("") as empty files.
//
// This setting is really only intended for those who were already using the system in their map
// prior to patch 1.31 and want to keep old files created with this system to still work.
private constant boolean BACKWARDS_COMPATABILITY = false
endglobals
private keyword FileInit
struct File extends array
static constant integer AbilityCount = 10
static constant integer PreloadLimit = 200
readonly static integer Counter = 0
readonly static integer array List
readonly static integer array AbilityList
readonly static boolean ReadEnabled = false
readonly string filename
private string buffer
static method open takes string filename returns thistype
local thistype this = .List[0]
if (this == 0) then
set this = Counter + 1
set Counter = this
else
set .List[0] = .List[this]
endif
set this.filename = filename
set this.buffer = null
debug if (this >= JASS_MAX_ARRAY_SIZE) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 120, "FileIO(" + filename + ") WARNING: Maximum instance limit " + I2S(JASS_MAX_ARRAY_SIZE) + " reached.")
debug endif
return this
endmethod
// This is used to detect invalid characters which aren't supported in preload files.
static if (DEBUG_MODE) then
private static method validateInput takes string contents returns string
local integer i = 0
local integer l = StringLength(contents)
local string ch = ""
loop
exitwhen i >= l
set ch = SubString(contents, i, i + 1)
if (ch == "\\") then
return ch
elseif (ch == "\"") then
return ch
endif
set i = i + 1
endloop
return null
endmethod
endif
method write takes string contents returns thistype
local integer i = 0
local integer c = 0
local integer len = StringLength(contents)
local integer lev = 0
local string prefix = "-" // this is used to signify an empty string vs a null one
local string chunk
debug if (.validateInput(contents) != null) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 120, "FileIO(" + filename + ") ERROR: Invalid character |cffffcc00" + .validateInput(contents) + "|r")
debug return this
debug endif
set this.buffer = null
// Check if the string is empty. If null, the contents will be cleared.
if (contents == "") then
set len = len + 1
endif
// Begin to generate the file
call PreloadGenClear()
call PreloadGenStart()
loop
exitwhen i >= len
debug if (c >= .AbilityCount) then
debug call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 120, "FileIO(" + filename + ") ERROR: String exceeds max length (" + I2S(.AbilityCount * .PreloadLimit) + ").|r")
debug endif
set lev = 0
static if (BACKWARDS_COMPATABILITY) then
if (c == 0) then
set lev = 1
set prefix = ""
else
set prefix = "-"
endif
endif
set chunk = SubString(contents, i, i + .PreloadLimit)
call Preload("\" )\ncall BlzSetAbilityTooltip(" + I2S(.AbilityList[c]) + ", \"" + prefix + chunk + "\", " + I2S(lev) + ")\n//")
set i = i + .PreloadLimit
set c = c + 1
endloop
call Preload("\" )\nendfunction\nfunction a takes nothing returns nothing\n //")
call PreloadGenEnd(this.filename)
return this
endmethod
method clear takes nothing returns thistype
return this.write(null)
endmethod
private method readPreload takes nothing returns string
local integer i = 0
local integer lev = 0
local string array original
local string chunk = ""
local string output = ""
loop
exitwhen i == .AbilityCount
set original[i] = BlzGetAbilityTooltip(.AbilityList[i], 0)
set i = i + 1
endloop
// Execute the preload file
call Preloader(this.filename)
// Read the output
set i = 0
loop
exitwhen i == .AbilityCount
set lev = 0
// Read from ability index 1 instead of 0 if
// backwards compatability is enabled
static if (BACKWARDS_COMPATABILITY) then
if (i == 0) then
set lev = 1
endif
endif
// Make sure the tooltip has changed
set chunk = BlzGetAbilityTooltip(.AbilityList[i], lev)
if (chunk == original[i]) then
if (i == 0 and output == "") then
return null // empty file
endif
return output
endif
// Check if the file is an empty string or null
static if not (BACKWARDS_COMPATABILITY) then
if (i == 0) then
if (SubString(chunk, 0, 1) != "-") then
return null // empty file
endif
set chunk = SubString(chunk, 1, StringLength(chunk))
endif
endif
// Remove the prefix
if (i > 0) then
set chunk = SubString(chunk, 1, StringLength(chunk))
endif
// Restore the tooltip and append the chunk
call BlzSetAbilityTooltip(.AbilityList[i], original[i], lev)
set output = output + chunk
set i = i + 1
endloop
return output
endmethod
method close takes nothing returns nothing
if (this.buffer != null) then
call .write(.readPreload() + this.buffer)
set this.buffer = null
endif
set .List[this] = .List[0]
set .List[0] = this
endmethod
method readEx takes boolean close returns string
local string output = .readPreload()
local string buf = this.buffer
if (close) then
call this.close()
endif
if (output == null) then
return buf
endif
if (buf != null) then
set output = output + buf
endif
return output
endmethod
method read takes nothing returns string
return .readEx(false)
endmethod
method readAndClose takes nothing returns string
return .readEx(true)
endmethod
method appendBuffer takes string contents returns thistype
set .buffer = .buffer + contents
return this
endmethod
method readBuffer takes nothing returns string
return .buffer
endmethod
method writeBuffer takes string contents returns nothing
set .buffer = contents
endmethod
static method create takes string filename returns thistype
return .open(filename).write("")
endmethod
implement FileInit
endstruct
private module FileInit
private static method onInit takes nothing returns nothing
local string originalTooltip
// We can't use a single ability with multiple levels because
// tooltips return the first level's value if the value hasn't
// been set. This way we don't need to edit any object editor data.
set File.AbilityList[0] = 'Amls'
set File.AbilityList[1] = 'Aroc'
set File.AbilityList[2] = 'Amic'
set File.AbilityList[3] = 'Amil'
set File.AbilityList[4] = 'Aclf'
set File.AbilityList[5] = 'Acmg'
set File.AbilityList[6] = 'Adef'
set File.AbilityList[7] = 'Adis'
set File.AbilityList[8] = 'Afbt'
set File.AbilityList[9] = 'Afbk'
// Backwards compatability check
static if (BACKWARDS_COMPATABILITY) then
static if (DEBUG_MODE) then
set originalTooltip = BlzGetAbilityTooltip(File.AbilityList[0], 1)
call BlzSetAbilityTooltip(File.AbilityList[0], SCOPE_PREFIX, 1)
if (BlzGetAbilityTooltip(File.AbilityList[0], 1) == originalTooltip) then
call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0, 120, "FileIO WARNING: Backwards compatability enabled but \"" + GetObjectName(File.AbilityList[0]) + "\" isn't setup properly.|r")
endif
endif
endif
// Read check
set File.ReadEnabled = File.open("FileTester.pld").write(SCOPE_PREFIX).readAndClose() == SCOPE_PREFIX
endmethod
endmodule
public function Write takes string filename, string contents returns nothing
call File.open(filename).write(contents).close()
endfunction
public function Read takes string filename returns string
return File.open(filename).readEx(true)
endfunction
endlibrary
JASS:
library SaveHelperLib initializer Init requires SyncHelper, PlayerUtils, SaveFile
// Uses GUI variables from the "Save Init" trigger. You can modify these functions to use your own variables.
private keyword SaveHelperInit
struct SaveHelper extends array
static constant hashtable Hashtable = InitHashtable()
static constant integer KEY_ITEMS = 1
static constant integer KEY_UNITS = 2
static constant integer KEY_NAMES = 3
static method MaxCodeSyncLength takes nothing returns integer
return udg_SaveLoadMaxLength
endmethod
static method GetUserHero takes User user returns unit
return udg_SavePlayerHero[user.id]
endmethod
// static method GetSavesPerSlot takes User user, integer slot returns unit
// return udg_NumberOfSaves[user.id*12+slot]
// endmethod
// static method GetSavesPerSlot takes player p, integer slot returns unit
// return udg_NumberOfSaves[GetPlayerId(p)*12+slot]
// endmethod
static method GetSavesPerSlot takes player p, integer slot returns integer
return udg_NumberOfSaves[GetPlayerId(p)*12+slot]
endmethod
static method SetSavesPerSlot takes player p, integer slot, integer saves returns nothing
set udg_NumberOfSaves[GetPlayerId(p)*12+slot] = saves
endmethod
static method RemoveUserHero takes User user returns nothing
call RemoveUnit(udg_SavePlayerHero[user.id])
set udg_SavePlayerHero[user.id] = null
endmethod
static method SetUserHero takes User user, unit u returns nothing
set udg_SavePlayerHero[user.id] = u
endmethod
static method IsUserLoading takes User user returns boolean
return udg_SavePlayerLoading[user.id]
endmethod
static method SetUserLoading takes User user, boolean flag returns nothing
set udg_SavePlayerLoading[user.id] = flag
endmethod
static method SetSaveSlot takes User user, integer slot returns nothing
set udg_SaveCurrentSlot[user.id] = slot
endmethod
static method GetSaveSlot takes User user returns integer
return udg_SaveCurrentSlot[user.id]
endmethod
static method GetUnitJobLevel takes unit u returns integer
if BlzGetUnitIntegerField(u, UNIT_IF_GOLD_BOUNTY_AWARDED_BASE) == 1 then
return 1
elseif BlzGetUnitIntegerField(u, UNIT_IF_GOLD_BOUNTY_AWARDED_BASE) == 2 then
return 2
else
return 3
endif
endmethod
static method ClassColor takes unit u returns string
if GetUnitTypeId(u) == 'H007' or GetUnitTypeId(u) == 'H004' then //Acolyte
return " |cffffffff" + GetObjectName(GetUnitTypeId(u)) + "|r "
else
return GetObjectName(GetUnitTypeId(u))
endif
endmethod
static method GetUnitTitle takes unit u returns string
return ClassColor(u) + "(Lv." + I2S(GetHeroLevel(u)) + ")"
endmethod
static method GetMapName takes nothing returns string
return udg_MapName
endmethod
static method MaxAbilityLevel takes nothing returns integer
return 10
endmethod
static method MaxAbilities takes nothing returns integer
return udg_SaveAbilityTypeMax
endmethod
static method MaxItems takes nothing returns integer
return udg_SaveItemTypeMax
endmethod
static method MaxUnits takes nothing returns integer
return udg_SaveUnitTypeMax
endmethod
static method MaxNames takes nothing returns integer
return udg_SaveNameMax
endmethod
static method MaxHeroStat takes nothing returns integer
return udg_SaveUnitMaxStat
endmethod
static method GetAbility takes integer index returns integer
return udg_SaveAbilityType[index]
endmethod
static method GetItem takes integer index returns integer
return udg_SaveItemType[index]
endmethod
static method GetUnit takes integer index returns integer
return udg_SaveUnitType[index]
endmethod
static method ConvertItemId takes integer itemId returns integer
return LoadInteger(thistype.Hashtable, KEY_ITEMS, itemId)
endmethod
static method ConvertUnitId takes integer unitId returns integer
return LoadInteger(thistype.Hashtable, KEY_UNITS, unitId)
endmethod
static method GetHeroNameFromID takes integer id returns string
return udg_SaveNameList[id]
endmethod
static method GetHeroNameID takes string name returns integer
return LoadInteger(thistype.Hashtable, KEY_NAMES, StringHash(name))
endmethod
static method ConvertHeroName takes string name returns string
return udg_SaveNameList[GetHeroNameID(name)]
endmethod
static method GUILoadNext takes nothing returns nothing
set udg_SaveValue[udg_SaveCount] = Savecode(udg_SaveTempInt).Decode(udg_SaveMaxValue[udg_SaveCount])
//call BJDebugMsg(I2S(udg_SaveCount) + ", " + I2S(udg_SaveValue[udg_SaveCount]))
endmethod
static method GetLevelXP takes integer level returns real
local real xp = udg_HeroXPLevelFactor // level 1
local integer i = 1
loop
exitwhen i > level
set xp = (xp*udg_HeroXPPrevLevelFactor) + (i+1) * udg_HeroXPLevelFactor
set i = i + 1
endloop
return xp-udg_HeroXPLevelFactor
endmethod
static method Init takes nothing returns nothing // called at the end of "Save Init" trigger
local integer i = 0
loop
exitwhen i >= thistype.MaxItems() //or udg_SaveItemType[i] == 0
call SaveInteger(thistype.Hashtable, KEY_ITEMS, udg_SaveItemType[i], i)
set i = i + 1
endloop
set i = 0
loop
exitwhen i >= thistype.MaxUnits() //or udg_SaveUnitType[i] == 0
call SaveInteger(thistype.Hashtable, KEY_UNITS, udg_SaveUnitType[i], i)
set i = i + 1
endloop
set i = 1
loop
exitwhen i >= SaveHelper.MaxNames() or udg_SaveNameList[i] == "" or udg_SaveNameList[i] == null
call SaveInteger(thistype.Hashtable, KEY_NAMES, StringHash(udg_SaveNameList[i]), i)
set i = i + 1
endloop
endmethod
endstruct
function GetHeroSaveCode takes unit u returns string
if (udg_SaveUseGUI) then
call TriggerExecute(gg_trg_Save_GUI)
return udg_SaveTempString
endif
return ""
endfunction
private function LoadSaveSlot_OnLoad takes nothing returns nothing
local player p = GetTriggerPlayer()
local string prefix = BlzGetTriggerSyncPrefix()
local string data = BlzGetTriggerSyncData()
local User user = User[p]
call SaveHelper.SetUserLoading(user, false)
if (udg_SaveUseGUI) then
set udg_SaveLoadEvent_Code = data
set udg_SaveLoadEvent_Player = p
set udg_SaveLoadEvent = 1.
set udg_SaveLoadEvent = -1
endif
set p = null
set prefix = null
set data = null
endfunction
function LoadSaveSlot takes player p, integer slot returns nothing
local SaveFile savefile = SaveFile(slot)
local string s
local User user = User[p]
local integer saveNumber = SaveHelper.GetSavesPerSlot(p, slot)
if (not SaveFile.exists(slot, saveNumber)) then
call DisplayTextToPlayer(p, 0, 0, "Did not find any save data.")
return
elseif (SaveHelper.IsUserLoading(user)) then
call DisplayTextToPlayer(p, 0, 0, "Please wait while your character synchronizes.")
else
if (saveNumber == 0) then
set s = savefile.getData()
else
set s = savefile.getBackupData(saveNumber)
endif
if (GetLocalPlayer() == p) then
call SyncString(s)
endif
call ClearTextMessages()
call DisplayTimedTextToPlayer(p, 0, 0, 15, "Synchronzing with other players...")
call SaveHelper.SetSaveSlot(user, slot)
endif
set s = null
endfunction
function DeleteCharSlot takes player p, integer slot returns nothing
local integer saveNumber = SaveHelper.GetSavesPerSlot(p, slot) + 1
call SaveHelper.SetSavesPerSlot(p, slot, saveNumber)
if (GetLocalPlayer() == p) then
call SaveFile(slot).clear(p, slot, saveNumber)
endif
endfunction
function SaveCharToSlot takes unit u, integer slot, string s returns nothing
local player p = GetOwningPlayer(u)
local integer saveNumber = SaveHelper.GetSavesPerSlot(p, slot) + 1
call SaveHelper.SetSavesPerSlot(p, slot, saveNumber)
if (GetLocalPlayer() == p) then
call SaveFile(slot).create(p, SaveHelper.GetUnitTitle(u), slot, saveNumber, s)
endif
call SaveHelper.SetSaveSlot(User[p], slot)
set p = null
endfunction
private function Init takes nothing returns nothing
call OnSyncString(function LoadSaveSlot_OnLoad)
endfunction
endlibrary
-
Init Load Screen
-
Events
-
Map initialization
-
-
Conditions
-
Actions
-
Set TestVersion = True
-
-------- Save/Load --------
-
Set SaveLoadMaxLength = 64
-
Set SaveUseGUI = True
-
-------- This willl be the directory the save codes will be saved to. --------
-
Set MapName = Twilight's Eve Nightfall
-
Set SaveShowCode = False
-
Set SaveHeroName = False
-
Set SaveNameMax = 999
-
-------- Set these to the values they are in the Advanced -> Gameplay constants --------
-
Set HeroXPConstant = 0
-
Set HeroXPLevelFactor = 100
-
Set HeroXPPrevLevelFactor = 1
-
Set HeroXPRequired = 200
-
-------- Store unit types that can be saved here --------
-
Set SaveUnitType[0] = No unit-type
-
Set SaveUnitType[1] = Personal Stash
-
Set SaveUnitType[2] = Acolyte
-
Set SaveUnitType[3] = Priest
-
Set SaveUnitType[4] = Hierophant
-
Set SaveUnitType[5] = Acolyte (Female)
-
Set SaveUnitType[6] = Matriarch (Female)
-
Set SaveUnitType[7] = Prophetess
-
Set SaveUnitType[8] = Druid
-
Set SaveUnitType[9] = Shapeshifter
-
Set SaveUnitType[10] = Werebear (Shapeshifter)
-
Set SaveUnitType[11] = Werewolf (Shapeshifter)
-
Set SaveUnitType[12] = RuneMaster
-
Set SaveUnitType[13] = Shaman
-
Set SaveUnitType[14] = Summoner
-
Set SaveUnitType[15] = Initiate
-
Set SaveUnitType[16] = Wizard
-
Set SaveUnitType[17] = White Wizard
-
Set SaveUnitType[18] = Mage
-
Set SaveUnitType[19] = ArchSage
-
Set SaveUnitType[20] = Templar
-
Set SaveUnitType[21] = High Templar
-
Set SaveUnitType[22] = Grand Templar
-
Set SaveUnitType[23] = Dark Templar
-
Set SaveUnitType[24] = Dark ArchTemplar
-
Set SaveUnitType[25] = Archer
-
Set SaveUnitType[26] = Marksman
-
Set SaveUnitType[27] = Sniper
-
Set SaveUnitType[28] = Tracker
-
Set SaveUnitType[29] = Monster Hunter
-
Set SaveUnitType[30] = Thief
-
Set SaveUnitType[31] = Stalker
-
Set SaveUnitType[32] = Master Stalker
-
Set SaveUnitType[33] = Assassin
-
Set SaveUnitType[34] = Phantom Assassin
-
Set SaveUnitType[35] = Swordsman
-
Set SaveUnitType[36] = Crusader
-
Set SaveUnitType[37] = Avenger
-
Set SaveUnitType[38] = Imperial Knight
-
Set SaveUnitType[39] = Champion
-
Set SaveUnitType[40] = Witch Hunter
-
Set SaveUnitType[41] = Witcher
-
Set SaveUnitType[42] = Professional Witcher
-
Set SaveUnitType[43] = Inquisitor
-
Set SaveUnitType[44] = Grand Inquisitor
-
Set SaveUnitTypeMax = 99
-
-------- Store item types that can be saved here --------
-
Set SaveItemType[0] = (Item-type of No item)
-
Custom script: set udg_SaveItemType[1] = 'I02F'
-
Custom script: set udg_SaveItemType[2] = 'I029'
-
Custom script: set udg_SaveItemType[3] = 'I00G'
-
Custom script: set udg_SaveItemType[4] = 'I02H'
-
Custom script: set udg_SaveItemType[5] = 'I02C'
-
Custom script: set udg_SaveItemType[6] = 'I02G'
-
Custom script: set udg_SaveItemType[7] = 'I00H'
-
Custom script: set udg_SaveItemType[8] = 'I003'
-
Custom script: set udg_SaveItemType[9] = 'I00J'
-
Custom script: set udg_SaveItemType[10] = 'I00I'
-
Custom script: set udg_SaveItemType[11] = 'I001'
-
Custom script: set udg_SaveItemType[12] = 'I02D'
-
Custom script: set udg_SaveItemType[13] = 'I02A'
-
Custom script: set udg_SaveItemType[14] = 'I002'
-
Custom script: set udg_SaveItemType[15] = 'I02B'
-
Custom script: set udg_SaveItemType[16] = 'I02E'
-
Set SaveItemTypeMax = 999
-
-------- Store ability types that can be saved here --------
-
Custom script: set udg_SaveAbilityType[1] = 'A007'
-
Custom script: set udg_SaveAbilityType[2] = 'A006'
-
Custom script: set udg_SaveAbilityType[3] = 'A008'
-
Custom script: set udg_SaveAbilityType[4] = 'A009'
-
Set SaveAbilityTypeMax = 199
-
-------- --------
-
Custom script: call SaveHelper.Init()
-
Set Skypper = |cffffcc00Basic Questgiver Skypper|r
-
Set Arnold = |cffffcc00Arnold the Treasure Hunter|r
-
Set Squeaky = |cffffcc00Squeaky the Exotic Pandaren|r
-
Set Kiba = |cffffcc00Civil Agent Kiba|r
-
Set Kain = |cffffcc00Kain the Material Collector|r
-
For each (Integer A) from 1 to 10, do (Actions)
-
Loop - Actions
-
Set HeroRevivalPoint[(Integer A)] = (Center of Rez Point Snow <gen>)
-
-
-
Set GeneratorRegion = ItemGenerator <gen>
-
Set PlayerItemSpawn[1] = (Center of Red Item <gen>)
-
Set PlayerItemSpawn[2] = (Center of Blue Item <gen>)
-
Set PlayerItemSpawn[3] = (Center of Teal Item <gen>)
-
Set PlayerItemSpawn[4] = (Center of Purple Item <gen>)
-
Set PlayerItemSpawn[5] = (Center of Yellow Item <gen>)
-
Set PlayerItemSpawn[6] = (Center of Orange Item <gen>)
-
Set PlayerItemSpawn[7] = (Center of Green Item <gen>)
-
Set PlayerItemSpawn[8] = (Center of Pink Item <gen>)
-
Set PlayerItemSpawn[9] = (Center of Gray Item <gen>)
-
Set PlayerItemSpawn[10] = (Center of Light Blue Item <gen>)
-
-------- Locations to -enter --------
-
Set DungeonEnterLoc[1] = IceDungeon <gen>
-
Set DungeonEnterLoc[2] = CryptDungeonEntrance <gen>
-
Set DungeonEnterLoc[3] = GoldMineDungeon <gen>
-
Set DungeonEnterLoc[4] = MountainDungeonEntrance <gen>
-
Set DungeonEnterLoc[5] = PuzzleDungeonEntrance <gen>
-
Set DungeonEnterLoc[6] = NagaEntrance <gen>
-
Set DungeonEnterLoc[8] = HellEntrance <gen>
-
Set DungeonEnterLoc[9] = SewersEntrance <gen>
-
Set DungeonEnterLoc[10] = AbyssalEntrance <gen>
-
Set DungeonEnterLoc[11] = IllusionCityEntrance <gen>
-
Set DungeonEnterLoc[12] = DragonDungeonEntrance <gen>
-
-------- Spawn locations --------
-
Set DungeonSpawnLoc[1] = IceDungeonStart <gen>
-
Set DungeonSpawnLoc[2] = CryptEntranceSpawn <gen>
-
Set DungeonSpawnLoc[3] = GoldMineDungeonSpawn <gen>
-
Set DungeonSpawnLoc[4] = MountainDungeonEntranceSpawn <gen>
-
Set DungeonSpawnLoc[5] = PuzzleDungeonEntranceSpawn <gen>
-
Set DungeonSpawnLoc[6] = NagaEntranceSpawn <gen>
-
Set DungeonSpawnLoc[7] = TristramEntranceSpawn <gen>
-
Set DungeonSpawnLoc[8] = HellEntranceSpawn <gen>
-
Set DungeonSpawnLoc[9] = SewerSpawn <gen>
-
Set DungeonSpawnLoc[11] = IllusionCitySpawn <gen>
-
-------- Dungeon Regions --------
-
Set DungeonRegion[1] = IcyDungeonArea <gen>
-
Set DungeonRegion[2] = CryptDungeonArea <gen>
-
Set DungeonRegion[3] = GoldMineDungeonArea <gen>
-
Set DungeonRegion[4] = CentaurDungeon Area <gen>
-
-------- Dungeon Portals --------
-
Set DungeonPortalUnit[1] = Portal (Dungeon) 1109 <gen>
-
Set DungeonPortalUnit[2] = Portal (Dungeon) 1134 <gen>
-
Set DungeonPortalUnit[3] = Portal (Dungeon) 0390 <gen>
-
-------- Groups --------
-
Custom script: set udg_UnitCheck = CreateGroup()
-
Custom script: set udg_UnitPlayerCheck = CreateGroup()
-
Custom script: set udg_CombatGroup = CreateForce()
-
Custom script: set udg_TauntGroup = CreateGroup()
-
Custom script: set udg_hell1FixateGroup = CreateGroup()
-
-------- Player Colors --------
-
Set PlayerC[1] = |cffff0303
-
Set PlayerC[2] = |cff0042ff
-
Set PlayerC[3] = |cff1be7ba
-
Set PlayerC[4] = |cff550081
-
Set PlayerC[5] = |cfffefc00
-
Set PlayerC[6] = |cfffe890d
-
Set PlayerC[7] = |cff21bf00
-
Set PlayerC[8] = |cffe45caf
-
Set PlayerC[9] = |cff939596
-
Set PlayerC[10] = |cff7ebff1
-
Set PlayerC[11] = |cff106247
-
Set PlayerC[12] = |cff4f2b05
-
Set PlayerC[13] = |cff9c0000
-
Set PlayerC[14] = |cff0000c3
-
Set PlayerC[15] = |cff00ebff
-
Set PlayerC[16] = |cffbd00ff
-
Set PlayerC[17] = |cffecce87
-
Set PlayerC[18] = |cfff7a58b
-
Set PlayerC[19] = |cffbfff81
-
Set PlayerC[20] = |cffdbb8eb
-
Set PlayerC[21] = |cff4f5055
-
Set PlayerC[22] = |cffecf0ff
-
Set PlayerC[23] = |cff00781e
-
Set PlayerC[24] = |cffa56f34
-
Set PlayerC[25] = |cff2e2d2e
-
Set PlayerC[26] = |cff2e2d2e
-
Set PlayerC[27] = |cff2e2d2e
-
Set PlayerC[28] = |cff2e2d2e
-
-------- Player Stash --------
-
Set PlayerStashRegion[1] = PlayerStash1 <gen>
-
Set PlayerStashRegion[2] = PlayerStash2 <gen>
-
Set PlayerStashRegion[3] = PlayerStash3 <gen>
-
Set PlayerStashRegion[4] = PlayerStash4 <gen>
-
Set PlayerStashRegion[5] = PlayerStash5 <gen>
-
Set PlayerStashRegion[6] = PlayerStash6 <gen>
-
Set PlayerStashRegion[7] = PlayerStash7 <gen>
-
Set PlayerStashRegion[8] = PlayerStash8 <gen>
-
Set PlayerStashRegion[9] = PlayerStash9 <gen>
-
Set PlayerStashRegion[10] = PlayerStash10 <gen>
-
-------- Knockup System Hash --------
-
Hashtable - Create a hashtable
-
Set KUS_hash = (Last created hashtable)
-
-------- Knockback System Setup --------
-
Set FK_IntervalPerMove = 0.03
-
Trigger - Add to FK Loop <gen> the event (Time - Every FK_IntervalPerMove seconds of game time)
-
Custom script: call DestroyGroup(udg_InitTempGroup)
-
Custom script: set udg_InitTempGroup = null
-
-------- --------
-
-
(As a side note the desyncs were still happening even before I was using the LocalPlayer to disable user control)
-
Init 0
-
Events
-
Time - Elapsed game time is 0.00 seconds
-
-
Conditions
-
Actions
-
Custom script: local player p = GetLocalPlayer()
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-
If - Conditions
-
TestVersion Equal to True
-
-
Then - Actions
-
Set SaveLoad_MapVersion = 0.00
-
Visibility - Disable black mask
-
Visibility - Disable fog of war
-
Trigger - Turn on Test Leveling <gen>
-
Trigger - Turn on Test Gold <gen>
-
Trigger - Turn on Test Create Class <gen>
-
-
Else - Actions
-
Set SaveLoad_MapVersion = 0.01
-
Visibility - Disable black mask
-
Visibility - Disable fog of war
-
Visibility - Enable black mask
-
Visibility - Enable fog of war
-
-
-
Game - Hide creep camps on the minimap.
-
Custom script: if p != null then
-
Custom script: call EnableUserControl(false)
-
Custom script: endif
-
-
EDIT: Additionally I don't know if that matters but I use the Wc3 vex map optimizer to protect the map using the settings as shown in the pictures. I also import the latest common.j and blizzard.j
EDIT2: In a 9-man lobby that I tried earlier today it appears 2 got desynced so...
Attachments
Last edited: