• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Desync when calling Preloader() locally

Level 2
Joined
Apr 19, 2022
Messages
7
I have been sitting in the editor of version 1.26 for a very long time, but now I decided to switch to the functionality of Reforge, but to my surprise, when saving a map in Reforge, a desynchronization occurs in this place, what has changed in the new versions of Warcraft, because when saving a map in 1.26 everything works? Help fix the desynchronization

Code causing desynchronization

JASS:
  if GetLocalPlayer()==p then
          call Preloader("save2\\Multiplayer\\DungeonRunners\\"+udg_Name[GetPlayerId(p)+1]+".pld")
        endif


JASS:
function Trig_InitialPlayersLoad_Actions takes nothing returns nothing
    local integer i=0
    local player p
    loop
      exitwhen i>15
      set udg_Player[i]=Player(i)
      set i=i+1
    endloop
    set udg_ColoredName[1] = ( ( "|c00FF0000" + GetPlayerName(Player(0)) ) + "|r" )
    set udg_ColoredName[2] = ( ( "|c000000FF" + GetPlayerName(Player(1)) ) + "|r" )
    set udg_ColoredName[3] = ( ( "|c0000FFC2" + GetPlayerName(Player(2)) ) + "|r" )
    set udg_ColoredName[4] = ( ( "|c004B005D" + GetPlayerName(Player(3)) ) + "|r" )
    set udg_ColoredName[5] = ( ( "|c00FFFF00" + GetPlayerName(Player(4)) ) + "|r" )
    set udg_ColoredName[6] = ( ( "|c00FF8B00" + GetPlayerName(Player(5)) ) + "|r" )
    set udg_ColoredName[7] = ( ( "|c0000C800" + GetPlayerName(Player(6)) ) + "|r" )
    set udg_ColoredName[8] = ( ( "|c00FF52AE" + GetPlayerName(Player(7)) ) + "|r" )
    set udg_ColoredName[9] = ( ( "|c00888888" + GetPlayerName(Player(8)) ) + "|r" )
    set udg_ColoredName[10] = ( ( "|c009FC4FF" + GetPlayerName(Player(9)) ) + "|r" )
    set udg_ColoredName[11] = ( ( "|c00004400" + GetPlayerName(Player(10)) ) + "|r" )
    set udg_ColoredName[12] = ( ( "|c00543200" + GetPlayerName(Player(11)) ) + "|r" )
    set i=1
    loop
        exitwhen i>12
        set udg_Name[i] = GetPlayerName(udg_Player[i-1])
        set i=i+1
    endloop
    set i=0
    loop
      exitwhen i>11
      set p=udg_Player[i]
     // call NameLoad(p)
      if GetPlayerController(p)==MAP_CONTROL_USER and GetPlayerSlotState(p)==PLAYER_SLOT_STATE_PLAYING then
        if GetLocalPlayer()==p then
          call Preloader("save2\\Multiplayer\\DungeonRunners\\"+udg_Name[GetPlayerId(p)+1]+".pld")
        endif
      endif
      set i=i+1
    endloop
endfunction

//===========================================================================
function InitTrig_InitialPlayersLoad takes nothing returns nothing
    set gg_trg_InitialPlayersLoad = CreateTrigger()
    call TriggerAddAction( gg_trg_InitialPlayersLoad, function Trig_InitialPlayersLoad_Actions )
endfunction
 
Two things to watch out for:
  1. This thread (Known causes of desync) seems to suggest that certain player controller/player slot-state checks can cause desyncs (I haven't personally verified this, but it may be worth testing to see if that is related since you have GetPlayerController() and GetPlayerSlotState()).
  2. Could you give an example of the file you're preloading? jassdoc says that Preloader returns asynchronous values, so depending on what it contains and how you use those results, you can end up disconnecting players:
Code:
@note If you use `Preloader` to load some values into your map, these values
are very likely to be different for each player (since the player might not 
even have local files enabled), so treat them as async values.

I assume you're using a save/load system, so if you're loading a string that you'll then decode into data, you'll want to make sure you synchronize that whole string across all players before handling it.
 
Level 2
Joined
Apr 19, 2022
Messages
7
Yes, you are right! I use the save loading system, finally found someone who understands this topic. I think the problem is in data synchronization, but I can't figure out what to do?

I tried to remove GetLocalPlayer, desynchronization did not happen, but the hero will only load as the last player, I may be wrong that the problem is in GetLocalPlayer, but I would really like to fix it

Here is my file: How to synchronize data?

JASS:
function PreloadFiles takes nothing returns nothing

    call PreloadStart()
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),1,7)
call SetPlayerTechMaxAllowed(Player(14),1,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),2,536877998)
call SetPlayerTechMaxAllowed(Player(14),2,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),3,536870992)
call SetPlayerTechMaxAllowed(Player(14),3,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),4,536870922)
call SetPlayerTechMaxAllowed(Player(14),4,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),5,536870922)
call SetPlayerTechMaxAllowed(Player(14),5,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),6,1630548276)
call SetPlayerTechMaxAllowed(Player(14),6,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),7,1630549057)
call SetPlayerTechMaxAllowed(Player(14),7,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),8,1630548293)
call SetPlayerTechMaxAllowed(Player(14),8,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),9,536870912)
call SetPlayerTechMaxAllowed(Player(14),9,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),10,536870928)
call SetPlayerTechMaxAllowed(Player(14),10,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),11,536870924)
call SetPlayerTechMaxAllowed(Player(14),11,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),12,536870927)
call SetPlayerTechMaxAllowed(Player(14),12,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),13,536870912)
call SetPlayerTechMaxAllowed(Player(14),13,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),14,1747988549)
call SetPlayerTechMaxAllowed(Player(14),14,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),15,1764766298)
call SetPlayerTechMaxAllowed(Player(14),15,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),16,1821875853)
call SetPlayerTechMaxAllowed(Player(14),16,2)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),17,1837996702)
call SetPlayerTechMaxAllowed(Player(14),17,2)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),18,1764766537)
call SetPlayerTechMaxAllowed(Player(14),18,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),19,1805426317)
call SetPlayerTechMaxAllowed(Player(14),19,2)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),20,1764766531)
call SetPlayerTechMaxAllowed(Player(14),20,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),21,536870921)
call SetPlayerTechMaxAllowed(Player(14),21,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),22,536870912)
call SetPlayerTechMaxAllowed(Player(14),22,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),23,536870912)
call SetPlayerTechMaxAllowed(Player(14),23,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),24,536870917)
call SetPlayerTechMaxAllowed(Player(14),24,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),25,536870913)
call SetPlayerTechMaxAllowed(Player(14),25,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),26,536870912)
call SetPlayerTechMaxAllowed(Player(14),26,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),27,536870912)
call SetPlayerTechMaxAllowed(Player(14),27,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),28,536870912)
call SetPlayerTechMaxAllowed(Player(14),28,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),29,536870912)
call SetPlayerTechMaxAllowed(Player(14),29,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),30,536870912)
call SetPlayerTechMaxAllowed(Player(14),30,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),31,536870912)
call SetPlayerTechMaxAllowed(Player(14),31,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),32,536870912)
call SetPlayerTechMaxAllowed(Player(14),32,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),33,536870912)
call SetPlayerTechMaxAllowed(Player(14),33,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),34,536870912)
call SetPlayerTechMaxAllowed(Player(14),34,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),35,536870912)
call SetPlayerTechMaxAllowed(Player(14),35,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),36,536870912)
call SetPlayerTechMaxAllowed(Player(14),36,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),37,536870912)
call SetPlayerTechMaxAllowed(Player(14),37,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),38,536870912)
call SetPlayerTechMaxAllowed(Player(14),38,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),39,536870912)
call SetPlayerTechMaxAllowed(Player(14),39,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),40,536870912)
call SetPlayerTechMaxAllowed(Player(14),40,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),41,536870912)
call SetPlayerTechMaxAllowed(Player(14),41,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),42,536870912)
call SetPlayerTechMaxAllowed(Player(14),42,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),43,536870912)
call SetPlayerTechMaxAllowed(Player(14),43,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),44,536870912)
call SetPlayerTechMaxAllowed(Player(14),44,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),45,536870912)
call SetPlayerTechMaxAllowed(Player(14),45,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),46,536870912)
call SetPlayerTechMaxAllowed(Player(14),46,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),47,536870912)
call SetPlayerTechMaxAllowed(Player(14),47,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),48,536870912)
call SetPlayerTechMaxAllowed(Player(14),48,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),49,536870912)
call SetPlayerTechMaxAllowed(Player(14),49,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),50,536870912)
call SetPlayerTechMaxAllowed(Player(14),50,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),51,536870912)
call SetPlayerTechMaxAllowed(Player(14),51,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),52,536870913)
call SetPlayerTechMaxAllowed(Player(14),52,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),53,1082523648)
call SetPlayerTechMaxAllowed(Player(14),53,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),54,172935768)
call SetPlayerTechMaxAllowed(Player(14),54,2)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),55,1226180937)
call SetPlayerTechMaxAllowed(Player(14),55,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),56,536870917)
call SetPlayerTechMaxAllowed(Player(14),56,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),57,441079156)
call SetPlayerTechMaxAllowed(Player(14),57,2)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),58,536870995)
call SetPlayerTechMaxAllowed(Player(14),58,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),59,536871167)
call SetPlayerTechMaxAllowed(Player(14),59,1)
  //" )
    call Preload( "" )
call SetPlayerTechMaxAllowed(Player(15),602,1636804050)
call SetPlayerTechMaxAllowed(Player(14),602,1)
  //" )
    call Preload( "" )
endfunction
function recyclebin takes nothing returns nothing
//" )
    call PreloadEnd( 0.0 )

endfunction
 
Do you have a link to the save/load system you're using? Or are you able to share the code that "loads" the data? Chances are that that is where the desync occurs, since that is where the asynchronous data actually gets "used" to do something meaningful (e.g. creating a hero, granting them stats/items, etc.).

If you want to do a bit of reading, I strongly recommend reading up on these two tutorials:
These will give you an overview of why save/load systems are set up the way they are. At a high level, the saving process goes as follows:
  1. You gather all the data you want to save
  2. Encode it into a string (or a set of integers in your case)
  3. Save that data into a .pld file
However, the way it is stored in the .pld file is important. Preloader(...) allows us to run that local file as a script, but in order to get "data" from it, we need to run functions that store that data somewhere. That's why most preload files will look something like this:
JASS:
function PreloadFiles takes nothing returns nothing

    call PreloadStart()
    call Preload( "" )
call BlzSetAbilityTooltip(1097690227, "Blood Mage (Hale Magefire)
B:2|RtHe@`QWE(>e(s4&XYPy", 1)
//" )
    call Preload( "" )
endfunction
function a takes nothing returns nothing
 //" )
    call PreloadEnd( 0.0 )

endfunction

As mentioned in the File I/O tutorial linked above, there are a bunch of different natives you can use to store the saved data so you can read it back. In your case, it seems like the author was using SetPlayerTechMaxAllowed to store integers.

So once you have it saved, at a high-level, the loading process goes as follows:
  1. You run the preload file via Preloader(...), which will then populate the data somewhere you can read back
  2. You can then read the data back into some variable locally (e.g. BlzGetAbilityTooltip for strings, or GetPlayerTechMaxAllowed in your case for integers)
  3. Once you have that data locally, you'll need to sync the data to all other players before using it for logic
This strategy largely hasn't changed at a high-level. The main differences with reforged is that we can now use BlzSetAbilityTooltip to store the data from the .pld file and then BlzGetAbilityTooltip to read it back in our map's code. And then as for syncing, the main difference in reforged is that we have fancy new sync natives to use:

So typically, you'll use BlzSendSyncData("SOME_PREFIX", myStringData) to sync some data, and then BlzTriggerRegisterPlayerSyncEvent to "use" it once that data has become synchronized across all players.

I'm guessing the system you're using already syncs the data back in some way (likely using one of the methods mentioned in Lizreu's tutorial), so if you share that logic I can give some recommendations.
 
Level 2
Joined
Apr 19, 2022
Messages
7
It is surprising that when saving in 1.26, there were no such problems, but in Reforge there is already an additional "mandatory" synchronization.

In the attachment DATA MANAGER, but it is only the basis from which the auto SaveLoad system was written. (It is unlikely that this is relevant to watch)

So typically, you'll use BlzSendSyncData("SOME_PREFIX", myStringData) to sync some data, and then BlzTriggerRegisterPlayerSyncEvent to "use" it once that data has become synchronized across all players.

Based on the material I read, I don't have synchronization via BlzSendSyncData and BlzTriggerRegisterPlayerSyncEvent, which means that desynchronization occurs.
Tell me, based on the provided code, where should I insert the new Blz functions for synchronization?

Here is my download code:
JASS:
function LoadPlayerTalentTable takes player p returns nothing
    local unit u=PlayerCharacter(p)
    local integer i=TALANTS
    loop
      exitwhen i==0
      if udg_SaveInt[21+i]<0 or udg_SaveInt[21+i]>10  then
        set udg_SaveInt[21+i]=0
      endif
      call SetUnitTalentLevel(u,i,udg_SaveInt[21+i])
      //call BJDebugMsg (I2S(21+i)+"="+I2S(udg_SaveInt[21+i]))
      set i=i-1
    endloop
    set u=null
    
endfunction

function CheckNumbers takes nothing returns boolean
    local integer lvl=udg_SaveInt[2]/200+1
    local integer i=0
    local integer i2
    local integer i3
    if udg_SaveInt[2]>200*udg_Const_CurMaxLevel then
      return false
    endif
    if udg_SaveInt[3]+udg_SaveInt[4]+udg_SaveInt[5]>28+lvl*2 then
      return false
    endif
    if udg_SaveInt[10]>GetHeroMSL(lvl) or udg_SaveInt[11]>GetHeroMSL(lvl) or udg_SaveInt[12]>GetHeroMSL(lvl) or udg_SaveInt[13]>GetHeroMSL(lvl) then
      return false
    endif
    if udg_SaveInt[10]+udg_SaveInt[11]+udg_SaveInt[12]+udg_SaveInt[13]-lvl/5>lvl then
      return false
    endif
    loop
      exitwhen i>4
      set i2=i+1
      loop
        exitwhen i2>5
        if udg_SaveInt[15+i]!=0 and udg_SaveInt[15+i]==udg_SaveInt[15+i2] then
          return false
        endif
        set i2=i2+1
      endloop
      set i=i+1
    endloop
    set i=22
    set i2=0
    loop
      exitwhen i>51
      set i2=i2+udg_SaveInt[i]
      set i=i+1
    endloop
    if i2>lvl/5 then
      return false
    endif
    set i=udg_SaveInt[22]+udg_SaveInt[23]+udg_SaveInt[24]
    set i2=udg_SaveInt[25]+udg_SaveInt[26]+udg_SaveInt[27]
    set i3=udg_SaveInt[28]+udg_SaveInt[29]+udg_SaveInt[30]
    if (i<5 and i2+i3>0) or (i2<5 and i3>0) then
      return false
    endif
    set i=udg_SaveInt[32]+udg_SaveInt[33]+udg_SaveInt[34]
    set i2=udg_SaveInt[35]+udg_SaveInt[36]+udg_SaveInt[37]
    set i3=udg_SaveInt[38]+udg_SaveInt[39]+udg_SaveInt[40]
    if (i<5 and i2+i3>0) or (i2<5 and i3>0) then
      return false
    endif
    set i=udg_SaveInt[42]+udg_SaveInt[43]+udg_SaveInt[44]
    set i2=udg_SaveInt[45]+udg_SaveInt[46]+udg_SaveInt[47]
    set i3=udg_SaveInt[48]+udg_SaveInt[49]+udg_SaveInt[50]
    if (i<5 and i2+i3>0) or (i2<5 and i3>0) then
      return false
    endif
    if udg_SaveInt[6]=='AIsr' or udg_SaveInt[7]=='AIsr' or udg_SaveInt[8]=='AIsr' or udg_SaveInt[9]=='AIsr' then
      return false
    endif
    return true
endfunction

function DestroyThem takes nothing returns nothing
  local integer i=1
  call FlushGameCache(udg_cache)
  loop
    exitwhen i>udg_SaveSize
    if i==60 then
        set i=602
    endif
    call SetPlayerTechMaxAllowed(Player(15),i,0)
    call SetPlayerTechMaxAllowed(Player(14),i,0)
    if i==602 then
        set i=udg_SaveSize
    endif
    set i=i+1
  endloop
endfunction

function ReadInteger takes integer Offset,player p returns nothing
  set udg_SyncInteger=Offset
  set udg_SyncPlayer=p
  call ExecuteFunc("ReadInteger_f")
endfunction

function ReadInteger_f3 takes nothing returns nothing
  local trigger t=GetTriggeringTrigger()
  local integer id=GetHandleId(t)
  local player p=LoadPlayerHandle(udg_h,id,1)
  local integer offset=LoadInteger(udg_h,id,2)
  call SaveInteger(udg_h,100+GetPlayerId(p),offset,GetStoredInteger(udg_cache,I2S(offset),I2S(GetPlayerId(p))))
  call FlushChildHashtable(udg_h,id)
  call DestroyTrigger(t)
  set t=null
endfunction


function ReadInteger_f2 takes nothing returns nothing
  local trigger t=GetTriggeringTrigger()
  local integer id=GetHandleId(t)
  local player p=LoadPlayerHandle(udg_h,id,1)
  local integer offset=LoadInteger(udg_h,id,2)
  local integer a
  call TriggerSyncStart()
  if GetLocalPlayer()==p then
      call SyncStoredInteger(udg_cache,I2S(offset),I2S(GetPlayerId(p)))
  endif
  call TriggerSyncReady()
  set a=GetStoredInteger(udg_cache,I2S(offset),I2S(GetPlayerId(p)))
  call TriggerClearActions(t)
  call TriggerAddAction(t,function ReadInteger_f3)
  call TriggerRegisterTimerEvent(t,1.,false)
  set t=null
endfunction

function ReadInteger_f takes nothing returns nothing
  local player p=udg_SyncPlayer
  local integer a=udg_SyncInteger
  local integer offset=udg_SyncInteger
  local string sid=I2S(GetPlayerId(p))
  local string soffset=I2S(offset)
  local trigger t=CreateTrigger()
  local integer id=GetHandleId(t)
  if GetLocalPlayer()==p then
    if GetPlayerTechMaxAllowed(udg_Player[14] , offset) == 2 then
      set a = - GetPlayerTechMaxAllowed(udg_Player[15] , offset)
    elseif GetPlayerTechMaxAllowed(udg_Player[14] , offset) == 1 then
      set a = GetPlayerTechMaxAllowed(udg_Player[15] , offset)
    elseif GetPlayerTechMaxAllowed(udg_Player[14] , offset) == 4 then
      set a = -2147483648
    else
      set a = 0
    endif
    call StoreInteger(udg_cache , soffset ,sid, a)
  endif
  call TriggerSyncStart()
  if GetLocalPlayer() == p then
      call SyncStoredInteger(udg_cache,soffset,sid)
  endif
  call TriggerSyncReady()
  set a=GetStoredInteger(udg_cache,soffset,sid)
  call SavePlayerHandle(udg_h,id,1,p)
  call SaveInteger(udg_h,id,2,offset)
  call TriggerAddAction(t,function ReadInteger_f2)
  call TriggerRegisterTimerEvent(t,1.,false)
  set t=null
endfunction

function CheckCode takes player p returns boolean
if udg_SaveInt[602]==-536870912 then
   // call BJDebugMsg("602=52"+I2S(udg_SaveInt[602])+"="+I2S(CheckSum1()))
        set udg_SaveInt[602]=udg_SaveInt[52]
    endif
    
    if udg_SaveInt[602]!=CheckSum1() then
      call BJDebugMsg("602="+I2S(udg_SaveInt[602])+"="+I2S(CheckSum1()))
      return false
    endif
    if udg_SaveInt[53]!=CheckSum2() then
    call BJDebugMsg("53="+I2S(udg_SaveInt[53])+"="+I2S(CheckSum2()))
      return false
    endif
    if udg_SaveInt[54]!=CheckSum3() then
    call BJDebugMsg("54="+I2S(udg_SaveInt[54])+"="+I2S(CheckSum3()))
      return false
    endif
    if udg_SaveInt[55]!=CheckSum4(p) then
    call BJDebugMsg("55="+I2S(udg_SaveInt[55])+"="+I2S(CheckSum4(p)))
      return false
    endif
    if udg_SaveInt[56]!=CheckSum5(p) then
    call BJDebugMsg("56="+I2S(udg_SaveInt[56])+"="+I2S(CheckSum5(p)))
      return false
    endif
    if udg_SaveInt[57]!=CheckSum6(p) then
    call BJDebugMsg("57="+I2S(udg_SaveInt[57])+"="+I2S(CheckSum6(p)))
      return false
    endif
    return true
endfunction

function LoadCharacter takes nothing returns nothing
    local player p=udg_SaveP
    local integer id=AdvancedModel(udg_SaveInt[14])
    local unit u
    local integer pid=1+GetPlayerId(p)
    local integer i=1
    if udg_SaveInt[1]==1 then
      set udg_SaveInt[58]=0
    endif
    if not CheckNumbers() then
      return
    endif
    set u=CreateUnit(p,id,GetPlayerStartLocationX(p),GetPlayerStartLocationY(p),0.)
    if GetUnitAbilityLevel(u,'AIsr')!=1 then
      call KillUnit(u)
      call RemoveUnit(u)
      set i=0
      if GetLocalPlayer()==p then
        set i=pid
      endif
      call Player(i)
      return
    endif
    call SaveInteger(udg_h,100+GetPlayerId(p),-1,udg_SaveInt[14])
    set udg_Character[pid]=u
    call SetHeroXP(u,udg_SaveInt[2],false)
    call SaveInteger(udg_h,GetHandleId(u),99,udg_SaveInt[3]+udg_SaveInt[4]+udg_SaveInt[5])
    call SetHeroStat(u,0,udg_SaveInt[3])
    call SetHeroStat(u,1,udg_SaveInt[4])
    call SetHeroStat(u,2,udg_SaveInt[5])
    if udg_SaveInt[6]==0 then
        if udg_SaveInt[7]!=0 then
          set udg_SaveInt[6]=udg_SaveInt[7]
          set udg_SaveInt[10]=udg_SaveInt[11]
          set udg_SaveInt[7]=0
          set udg_SaveInt[11]=0
        else
            if udg_SaveInt[8]!=0 then
              set udg_SaveInt[6]=udg_SaveInt[8]
              set udg_SaveInt[10]=udg_SaveInt[12]
              set udg_SaveInt[8]=0
              set udg_SaveInt[12]=0
            else
                if udg_SaveInt[9]!=0 then
                  set udg_SaveInt[6] = udg_SaveInt[9]
                  set udg_SaveInt[10] = udg_SaveInt[13]
                  set udg_SaveInt[9] = 0
                  set udg_SaveInt[13] = 0
                endif
            endif
        endif
    endif
    if udg_SaveInt[7]==0 then
        if udg_SaveInt[8]!=0 then
          set udg_SaveInt[7]=udg_SaveInt[8]
          set udg_SaveInt[11]=udg_SaveInt[12]
          set udg_SaveInt[8]=0
          set udg_SaveInt[12]=0
        else
            if udg_SaveInt[9]!=0 then
              set udg_SaveInt[7]=udg_SaveInt[9]
              set udg_SaveInt[11]=udg_SaveInt[13]
              set udg_SaveInt[9]=0
              set udg_SaveInt[13]=0
            endif
        endif
    endif
    if udg_SaveInt[8]==0 and udg_SaveInt[9]!=0 then
      set udg_SaveInt[8]=udg_SaveInt[9]
      set udg_SaveInt[12]=udg_SaveInt[13]
      set udg_SaveInt[9]=0
      set udg_SaveInt[13]=0
    endif
    set udg_Spell1[pid]=udg_SaveInt[6]
    set udg_Spell2[pid]=udg_SaveInt[7]
    set udg_Spell3[pid]=udg_SaveInt[8]
    set udg_Spell4[pid]=udg_SaveInt[9]
    set udg_Spell1LVL[pid]=udg_SaveInt[10]
    set udg_Spell2LVL[pid]=udg_SaveInt[11]
    set udg_Spell3LVL[pid]=udg_SaveInt[12]
    set udg_Spell4LVL[pid]=udg_SaveInt[13]
    set udg_QuestLevel[pid]=udg_SaveInt[21]
    set udg_RunnerSymbol[pid]=udg_SaveInt[59]
    call UnitAddItemToSlotById(u,udg_SaveInt[15],0)
    call UnitAddItemToSlotById(u,udg_SaveInt[16],1)
    call UnitAddItemToSlotById(u,udg_SaveInt[17],2)
    call UnitAddItemToSlotById(u,udg_SaveInt[18],3)
    call UnitAddItemToSlotById(u,udg_SaveInt[19],4)
    call UnitAddItemToSlotById(u,udg_SaveInt[20],5)
    call GroupAddUnit(udg_Characters,u)
                                //call BJDebugMsg("Download Hero="+GetUnitName(FirstOfGroup(udg_Characters)))
    call LoadPlayerTalentTable(p)
    call SaveInteger(udg_h,GetHandleId(u),19,GetHeroLevel(u))
    call SaveInteger(udg_h,GetHandleId(u),20,GetHeroXP(u))
    //loop
    //    exitwhen i>udg_SaveSize
    //    set udg_SaveInt[i]=0
    //    set i=i+1
    //endloop
    call UnitAddAbility(u,UnbindSpell(udg_Spell1[pid],1))
    call SetUnitAbilityLevel(u,UnbindSpell(udg_Spell1[pid],1),udg_Spell1LVL[pid])
    call UnitAddAbility(u,UnbindSpell(udg_Spell2[pid],2))
    call SetUnitAbilityLevel(u,UnbindSpell(udg_Spell2[pid],2),udg_Spell2LVL[pid])
    call UnitAddAbility(u,UnbindSpell(udg_Spell3[pid],3))
    call SetUnitAbilityLevel(u,UnbindSpell(udg_Spell3[pid],3),udg_Spell3LVL[pid])
    call UnitAddAbility(u,UnbindSpell(udg_Spell4[pid],4))
    call SetUnitAbilityLevel(u,UnbindSpell(udg_Spell4[pid],4),udg_Spell4LVL[pid])
    call SaveInteger(udg_h,100+GetPlayerId(p),58,udg_SaveInt[58]+1)
    call SetPlayerMaxHeroesAllowed(0,p)
    call SuspendHeroXP(u,true)
    call TriggerSleepAction(0.)
    //set udg_SaveP=GetOwningPlayer(u)
    if GetLocalPlayer()==p then
      call SelectUnitSingle(u)
      call PanCameraTo(GetUnitX(u),GetUnitY(u))
    endif
    set udg_Character[pid]=u
    set u=null
    //set udg_CharLoaded=true
endfunction

function ReadThem takes nothing returns nothing
  local timer t=GetExpiredTimer()
  local integer id=GetHandleId(t)
  local player p=LoadPlayerHandle(udg_h,id,1)
  local integer i=LoadInteger(udg_h,id,2)
  local integer n=LoadInteger(udg_h,id,3)
  call ReadInteger(i,p)
  if i==602 then
            set i=n
  endif
  if i==60 then
            set i=601
  endif
  if i>=n then
    call FlushChildHashtable(udg_h,id)
    call DestroyTimer(t)
  else
    call SaveInteger(udg_h,id,2,i+1)
  endif
  set t=null
endfunction

function LoadAllPlayers_f takes nothing returns nothing
  local player p=udg_SaveP
  local timer t=CreateTimer()
  local integer id=GetHandleId(t)
  call SavePlayerHandle(udg_h,id,1,p)
  call SaveInteger(udg_h,id,2,1)
  call SaveInteger(udg_h,id,3,udg_SaveSize)
  call TimerStart(t,0.03,true,function ReadThem)
  call ReadInteger(3333,p)
  set t=null
endfunction

function LoadAllPlayers takes nothing returns nothing
    local integer q
    local integer n
    local integer i2=0
    loop
      exitwhen i2>11
      set udg_SaveP=udg_Player[i2]
      if GetPlayerController(udg_SaveP)==MAP_CONTROL_USER and GetPlayerSlotState(udg_SaveP)==PLAYER_SLOT_STATE_PLAYING then
        call LoadAllPlayers_f()
      endif
      set i2=i2+1
    endloop
endfunction

function GetPlayerSaveInt takes player p returns nothing
  local integer i=1
  local integer id=100+GetPlayerId(p)
  loop  
    exitwhen i>udg_SaveSize
    if i==60 then
            set i=602
          endif
    if i<60 or i==602 then//
        set udg_SaveInt[i]=LoadInteger(udg_h,id,i)-536870912
    endif//
    if i==602 then
            set i=udg_SaveSize
          endif
    set i=i+1
  endloop
  set udg_SaveInt[1]=udg_SaveInt[1]+536870912
endfunction

function LoadPlayerHero takes player p returns nothing
    local integer i=1
    local integer q
    local integer n
    call GetPlayerSaveInt(p)
    set q=udg_SaveInt[1]
    if q<1 or q>udg_SaveVersion then
      if q>udg_SaveVersion then
        call ErrorMsg(p,"Your character is from a newer version.")
        set udg_SaveInt[1]=-1
      endif
      return
    endif
    if not CheckCode(p) then
      call ErrorMsg(p,"Your save is corrupted.")
      set i=1
      loop
          exitwhen i>udg_SaveSize
          if i==60 then
            set i=602
          endif
          if i<60 or i==602 then//
            set udg_SaveInt[i]=0
            endif//
          set i=i+1
      endloop
      return
    endif
endfunction



function LoadThem_f takes nothing returns nothing
  local trigger t=GetTriggeringTrigger()
  local integer id=GetHandleId(t)
  local integer i=LoadInteger(udg_h,id,1)
  local player p
  local boolean b=false
  if i>11 then
    call DisableTrigger(t)
    set t=null
    call DestroyThem()
    return
  endif
  call SaveInteger(udg_h,id,1,i+1)
  set p=udg_Player[i]
  set udg_SaveP=udg_Player[i]
  if GetPlayerController(p)==MAP_CONTROL_USER and GetPlayerSlotState(p)==PLAYER_SLOT_STATE_PLAYING then
    set udg_CharLoaded=false
    call LoadPlayerHero(p)
    if (udg_SaveInt[1]==0) then
       set udg_Character[i]=CreateUnit(p,'ewsp',GetRectCenterX(gg_rct_SelectBody),GetRectCenterY(gg_rct_SelectBody),0.)
       set TextTag[1]=CreateTextTagLocBJ( "|c00FFFF00Hero talents, chosen every 5 levels\n(Available from hero level 5)|r", GetRectCenter(gg_rct_Hint1), 0, 10, 100, 100, 0.00, 0 )
       set TextTag[2]=CreateTextTagLocBJ("|c00FFFF00Ability Books|r", GetRectCenter(gg_rct_Hint4), 0, 10, 100, 100, 100, 0 )
       set TextTag[3]=CreateTextTagLocBJ("|c00FFFF00For passing the level, experience is given, and after passing the level, items are played.\n\nIf you did not have time to choose your abilities, do not worry, you can choose them after passing the level.|r", GetRectCenter(gg_rct_Hint5), 0, 10, 100, 100, 100, 0 )
       set TextTag[4]=CreateTextTagLocBJ("|c00FFFF00You will receive experience and items after completing the level.|r", GetRectCenter(gg_rct_Hint6), 0, 10, 100, 100, 100, 0 )
       if GetLocalPlayer()==p then
         call PanCameraTo(GetRectCenterX(gg_rct_SelectBody),GetRectCenterY(gg_rct_SelectBody))
         call SelectUnitSingle(gg_unit_ntav_0000)
         call DisplayTimedTextToPlayer(p,0,0,30,"|c00FFFF00Choose a hero model in the tavern.\nIt is important that all heroes are the same, they are just models.\nDuring the process, you will be able to customize the hero for yourself.|r")
       endif
       set udg_CharLoaded=true
    else
      if udg_SaveInt[1]!=-1 then
        call ExecuteFunc("LoadCharacter")
      endif
    endif
  endif
  set t=null
endfunction

function LoadThem takes nothing returns nothing
    local integer i=1
    local trigger t=CreateTrigger()
    local player p
    local integer temp
    loop
      exitwhen i>12
      set p=Player(i-1)
      set temp=LoadInteger(udg_h,100+GetPlayerId(p),3333)
      if temp==udg_FMVersion then
        set udg_Advanced[1+GetPlayerId(p)]=true
        call DisplayTextToPlayer(p,0,0,"|c00ff0000ВНИМАНИЕ:|r The file module has been successfully connected.")
      elseif temp!=0 and temp<udg_FMVersion then
        call DisplayTextToPlayer(p,0,0,"|c00ff0000ВНИМАНИЕ:|r The file module is outdated and not connected. Download a new one from anufis.ucoz.ru")
      elseif temp!=0 and temp>udg_FMVersion then
        call DisplayTextToPlayer(p,0,0,"|c00ff0000ВНИМАНИЕ:|r The file module for the card is of a newer version and is not connected.")
      endif
      set i=i+1
    endloop
    call SaveInteger(udg_h,GetHandleId(t),1,0)
    call TriggerAddAction(t,function LoadThem_f)
    call TriggerRegisterTimerEvent(t,4.,true)
    set t=null
endfunction

function Trig_LoadEverybody_Actions takes nothing returns nothing
    local trigger t=CreateTrigger()
    call LoadAllPlayers()
    call TriggerAddAction(t,function LoadThem)
    call TriggerRegisterTimerEvent(t,1.+0.03*59,false)
    set t=null
endfunction

//===========================================================================
function InitTrig_LoadEverybody takes nothing returns nothing
    set gg_trg_LoadEverybody = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_LoadEverybody, 1.00 )
    call TriggerAddAction( gg_trg_LoadEverybody, function Trig_LoadEverybody_Actions )
endfunction
 

Attachments

  • data manager v1.7 (2).w3x
    22.6 KB · Views: 2
Top