| 12-12-2009, 07:05 PM | #1 |
Hi there, Here are my questions. 1. After looking some time in the forums I found out what are desyncs and understood what's wrong with my code :) Now I'm looking for a way to synchronize stuff between players. Strictly saying I'm making a command system - I want it to spawn units in camera target position of player who entered the command. However GetCameraTargetPosition only provides values for local player... I'm looking for a way to pass that value to other players. I couldn't find a nice system that could do that. Btw maybe someone knows a tutorial or other resource covering topic of desyncs and the way net game works. 2. How to use the new natives (hashtables and stuff) in NewGen pack? I found common.j in JassHelper folder, so I thought of swapping it with a new one. The problem is I searched all the WC3 MPQs and i didn't manage to find common.j with the new functions inside. So btw where is common.j in WC3 files? 3. "Enable Colorizer" is placed under Grimoire menu in JNGP. However I can't see it anywhere, no sign of it's existance, no way to use or colorize anything. What's that Colorizer and how to use it? I've got some other questions, mainly on JNGP, but I'll add them later... |
| 12-12-2009, 09:42 PM | #2 |
1. There are a couple of methods to sync values out there, I couldn't really name them off the top of my mind, though. I know one involves using player selections to pass integer values, not sure about how the rest work. Try searching around. 2. You should be able to use the hashtable natives with the latest NewGen version, if not, then try updating JassHelper, that's the only thing that I changed in my copy of NewGen and the enw natives work fine. 3. No idea, you best ask this in the newGen thread. |
| 12-12-2009, 11:49 PM | #3 |
Ty for reply. I'm going to post what I found in case anyone needs that information in future... 1. I've searched forums before and I've came across a post saying that at least 3 synchronizing methods exist, also I found somewhere there a demo map with system using selections to pass 12bit integers. However I didn't like it at all. In the process for a second I had an ugly selection of some flying sheep (so it's no use in fight), also selecting some unit right at the same time caused wrong values to show up. Atm I can't find that thread or any other resource on synchronizing, I'll look for some tomorrow and post. So I am still looking for a system, tutorial or anything else on topic of desyncs and synchronizing. 2. Seems they those functions were finely compiled by JassHelper, TESH just didn't highlight them (forgot that that's what does the thing...). Searched for a while and fixed. Heres link: TESH update. |
| 12-13-2009, 02:36 AM | #4 |
JASS:Jass: library SyncDatas initializer onInit globals private gamecache GC = null // leave it to null, or use your own but i don't recommend it // i only let this possibility because of the limit of 256 game caches endglobals private function interface FunctionInterface takes integer i returns nothing globals private force Players private integer I private string TempVariableName private FunctionInterface TempFunc private integer TempIndex private player SyncedPlayer = null endglobals private function Crash takes nothing returns nothing // just a test function call Crash.execute() endfunction function GetSyncedPlayer takes nothing returns player return SyncedPlayer endfunction //! runtextmacro t_InitSyncDatas("boolean","Boolean","false") //! runtextmacro t_InitSyncDatas("integer","Integer","0") //! runtextmacro t_InitSyncDatas("real","Real","0.") //! runtextmacro t_InitSyncDatas("string","String","null") //! textmacro t_InitSyncDatas takes TYPE , TYPE_NAME , TYPE_NULL globals private $TYPE$ Temp$TYPE_NAME$ = $TYPE_NULL$ endglobals private function DoThe$TYPE_NAME$Sync takes nothing returns nothing local integer i = GetPlayerId(GetEnumPlayer()) local string variableName = TempVariableName local string s = SCOPE_PREFIX + "$TYPE_NAME$" local FunctionInterface f = TempFunc local integer data = TempIndex if GetLocalPlayer() == Player(i) then call Store$TYPE_NAME$(GC,s,variableName+I2S(i),Temp$TYPE_NAME$) endif call TriggerSyncStart() //if GetLocalPlayer() == Player(1) then // just to test the case when a player left during the sync // call Crash() //endif if GetLocalPlayer() == Player(i) then call SyncStored$TYPE_NAME$(GC, s, variableName+I2S(i)) endif call TriggerSyncReady() set SyncedPlayer = Player(i) call f.evaluate(data) set SyncedPlayer = null endfunction private function Callback$TYPE_NAME$ takes nothing returns nothing call DoThe$TYPE_NAME$Sync.execute() endfunction function Get$TYPE_NAME$ForPlayer takes string variableName, player whichPlayer returns $TYPE$ return GetStored$TYPE_NAME$(GC,SCOPE_PREFIX + "$TYPE_NAME$",variableName+I2S(GetPlayerId(whichPlayer))) endfunction function Sync$TYPE_NAME$ takes $TYPE$ which$TYPE_NAME$, string variableName, FunctionInterface whichFunction, integer data returns nothing set TempVariableName = variableName set Temp$TYPE_NAME$ = which$TYPE_NAME$ set TempFunc = whichFunction set TempIndex = data call ForForce(Players,function Callback$TYPE_NAME$) set TempVariableName = "" set Temp$TYPE_NAME$ = $TYPE_NULL$ set TempFunc = 0 set TempIndex = 0 endfunction //! endtextmacro private function HandleLeavers takes nothing returns boolean call ForceRemovePlayer(Players,GetTriggerPlayer()) return false endfunction private function onInit takes nothing returns nothing local trigger trig = CreateTrigger() local integer i = 0 set Players = CreateForce() if GC == null then set GC = InitGameCache(SCOPE_PREFIX) endif loop exitwhen i == 12 if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(Player(i)) == MAP_CONTROL_USER then call ForceAddPlayer(Players,Player(i)) call TriggerRegisterPlayerEvent(trig,Player(i),EVENT_PLAYER_LEAVE) call TriggerAddCondition(trig,function HandleLeavers) endif set i = i+1 endloop endfunction endlibrary It needs more work and more tests but that's basically the only truly silent way. I've test it only with a good host and 2 players, the needed time was about 0.5 s. I don't know what happens with a bad host and more players and also when a player leave during the sync. If it appears this method can take longer than 0.5 s i would use the selection stuff instead. You can select locally a unit with GetLocalPlayer, the selection event will fire for all players, so you can use it to sync datas. It also have delay, but if you select/deselect without any wait the players can't notice it. I didn't test what happens if you need to select more than 12 units though. |
