|
|
|
|
Десинк с GetLocalPlayer()
|
|
oleg_best_oleg | Дата: Среда, 11 Января 2012, 17:53:15 | Сообщение # 1 |
Группа: Заблокированные
Сообщений: 1726
Награды: 0
Репутация: 654
Блокировки:
| Примерно около двадцатой или тридцатой секунды игры появляется десинк.
Десинк был с из-за кода: Code 125 if GetLocalPlayer() == GetOwningPlayer(dat.hero) then 126 call PanCameraToTimed(dat.x, dat.y, PANCAM) 127 call ClearSelection() 128 call SelectUnit(dat.hero, true) 129 endif Убрав эту часть из кода, десинка не было. Далее вопрос: Можно ли заменить эти действия нелокальными или без BJ ?
Сообщение отредактировал oleg_best_oleg - Среда, 11 Января 2012, 17:53:41 |
|
|
|
lawson | Дата: Среда, 11 Января 2012, 18:05:09 | Сообщение # 2 |
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
| Quote (oleg_best_oleg) GetLocalPlayer() == GetOwningPlayer(dat.hero) А поменять местами не пробовал?
Nic nie wiem bo mam chuj. редактирую посты! ВСЕ!
|
|
|
|
oleg_best_oleg | Дата: Среда, 11 Января 2012, 18:06:53 | Сообщение # 3 |
Группа: Заблокированные
Сообщений: 1726
Награды: 0
Репутация: 654
Блокировки:
| lawson, не пробовал. Я думал что должно начинаться с "GetLocalPlayer()"...Попробую.
|
|
|
|
lawson | Дата: Среда, 11 Января 2012, 18:08:06 | Сообщение # 4 |
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
| Quote (oleg_best_oleg) не пробовал Ты писал структуры?
Nic nie wiem bo mam chuj. редактирую посты! ВСЕ!
Сообщение отредактировал lawson - Среда, 11 Января 2012, 18:11:03 |
|
|
|
oleg_best_oleg | Дата: Среда, 11 Января 2012, 18:10:03 | Сообщение # 5 |
Группа: Заблокированные
Сообщений: 1726
Награды: 0
Репутация: 654
Блокировки:
| Quote (lawson) Ты структуры? Вот код: Code library HeroRevival requires TimerUtils globals private constant real PANCAM = 0.6 endglobals private function GetAdjustedTime takes real time, unit hero returns real return time + 0. * GetHeroLevel(hero) //if you want something extra or you can set the time to 0 //and use this for a formula instead //I call this function for the formula func in the documentation endfunction private function FilterHero takes unit u returns boolean return IsUnitType(u, UNIT_TYPE_HERO) and IsUnitType(u, UNIT_TYPE_DEAD) //just check if the unit is a hero //and to check if the unit is already dead (thanks to axarion for this one) //you can edit the filter if you want endfunction // END SETUP //****************************************************************************************************************************** //
globals // // To make sure that the users wont run several instances with the same unit // private group NOSTACK = CreateGroup() endglobals
private struct data extends array static integer i = 0 static integer array r unit hero real x real y boolean eff endstruct private function finish takes nothing returns nothing local timer t = GetExpiredTimer() local data dat = GetTimerData(t) call ReleaseTimer(t) //recycle timer set t = null call ReviveHero(dat.hero, dat.x, dat.y, dat.eff) //revive hero call GroupRemoveUnit(NOSTACK, dat.hero) if GetOwningPlayer(dat.hero) == GetLocalPlayer() then call PanCameraToTimed(dat.x, dat.y, PANCAM) call ClearSelection() call SelectUnit(dat.hero, true) endif set data.r[0] = data.r[data.r[0]] set data.r[data.r[0]] = dat endfunction function HeroRevive takes unit hero, real time, real x, real y, boolean eff returns nothing local data dat local timer t if FilterHero(hero) and not IsUnitInGroup(hero, NOSTACK) then if 0 == data.r[0] then set data.i = data.i + 1 set dat = data.i else set dat = data.r[0] set data.r[0] = data.r[data.r[0]] endif
set t = NewTimer() set dat.hero = hero set dat.x = x set dat.y = y set dat.eff = eff call GroupAddUnit(NOSTACK, hero) call SetTimerData(t, dat) call TimerStart(t, GetAdjustedTime(time, hero), false, function finish) set t = null debug else debug call BJDebugMsg("HeroRevival Error: The unit is either alive or isn't a hero unit or is already in the system, please check your trigger calls.") endif endfunction function HeroReviveLoc takes unit hero, real time, location loc, boolean eff returns nothing call HeroRevive(hero, time, GetLocationX(loc), GetLocationY(loc), eff) endfunction endlibrary
|
|
|
|
lawson | Дата: Среда, 11 Января 2012, 18:11:20 | Сообщение # 6 |
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
| oleg_best_oleg, Всмысле ты их писал?
Nic nie wiem bo mam chuj. редактирую посты! ВСЕ!
|
|
|
|
oleg_best_oleg | Дата: Среда, 11 Января 2012, 18:12:14 | Сообщение # 7 |
Группа: Заблокированные
Сообщений: 1726
Награды: 0
Репутация: 654
Блокировки:
| lawson, нет.
|
|
|
|
SirNikolas | Дата: Среда, 11 Января 2012, 19:28:25 | Сообщение # 8 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Quote (lawson) А поменять местами не пробовал? От перемены мест слагаемых... Кхм, операндов сравнения, реультат не меняется.Quote (oleg_best_oleg) return IsUnitType(u, UNIT_TYPE_HERO) and IsUnitType(u, UNIT_TYPE_DEAD) return IsUnitType(u, UNIT_TYPE_HERO) == true and IsUnitType(u, UNIT_TYPE_DEAD) == true Так надежнее в данном случае.
Посмотрел, код отличный, десинхронизаций он вызывать не должен.Quote (oleg_best_oleg) Примерно около двадцатой или тридцатой секунды игры Т. е. зависит от времени, а не от воскрешения героя?
|
|
|
|
Ty3uK | Дата: Среда, 11 Января 2012, 19:41:12 | Сообщение # 9 |
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
| Зачем лишние сравнения, Ник? Без тру всегда работало
|
|
|
|
Dreii | Дата: Среда, 11 Января 2012, 19:43:45 | Сообщение # 10 |
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
| Ty3uK, У меня были случаии. Проверял кто был убитым и проверка не срабатывал доставил "== true" все ок сталою
|
|
|
|
Ty3uK | Дата: Среда, 11 Января 2012, 19:45:11 | Сообщение # 11 |
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
| Хм... Ну я не сталкивался, поэтому и говорю. Но на заметку возьму, спасибо
|
|
|
|
[stebashka] | Дата: Среда, 11 Января 2012, 19:46:04 | Сообщение # 12 |
пути и нити разными бывают
Группа: Библиотекари
Сообщений: 4719
Награды: 5
Блокировки:
| Quote (Dreii) "А в колодец не плюй - ведь напиться придётся" - [DUOS] Это ДУОС сказал? О, Господи, да ты сумасшедший.
|
|
|
|
Dreii | Дата: Среда, 11 Января 2012, 19:47:57 | Сообщение # 13 |
10 уровень
Группа: Проверенные
Сообщений: 4991
Награды: 0
Репутация: 603
Блокировки:
| [stebashka], Есть немного,незнаю кто гвоорил))Только видел пост дуоса)
|
|
|
|
oleg_best_oleg | Дата: Среда, 11 Января 2012, 20:03:50 | Сообщение # 14 |
Группа: Заблокированные
Сообщений: 1726
Награды: 0
Репутация: 654
Блокировки:
| Quote (SirNikolas) Т. е. зависит от времени, а не от воскрешения героя? Нет, после 20-30 секунд игры. Не смотря на таймер.
|
|
|
|
SirNikolas | Дата: Четверг, 12 Января 2012, 12:02:42 | Сообщение # 15 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Quote (Ty3uK) Зачем лишние сравнения, Ник? Без тру всегда работало Quote (:avtoradolf:) Также обратите внимание на b == true. Это неправильно. Для надежности надо писать (b == true and b != false), этому нас еще в свое время MPI3 учил. На самом деле надо писать просто b, например: if b then... Исключение - IsUnitType. До патча 1.24 она бажила, если не сравнивать результат с true. Многие по привычке пишут так и сейчас, так же как удаляют boolexpr'ы.Quote (oleg_best_oleg) Нет, после 20-30 секунд игры. Несмотря на таймер. Тогда выложи библиотеку TimerUtils. Я примерно представляю, что там, но вдруг ошибка именно из-за нее.
|
|
|
|
oleg_best_oleg | Дата: Четверг, 12 Января 2012, 13:35:04 | Сообщение # 16 |
Группа: Заблокированные
Сообщений: 1726
Награды: 0
Репутация: 654
Блокировки:
| TimerUtils: Code library TimerUtils initializer init //********************************************************************* //* TimerUtils (red+blue+orange flavors for 1.24b+) //* ---------- //* //* To implement it , create a custom text trigger called TimerUtils //* and paste the contents of this script there. //* //* To copy from a map to another, copy the trigger holding this //* library to your map. //* //* (requires vJass) More scripts: htt://www.wc3c.net //* //* For your timer needs: //* * Attaching //* * Recycling (with double-free protection) //* //* set t=NewTimer() : Get a timer (alternative to CreateTimer) //* ReleaseTimer(t) : Relese a timer (alt to DestroyTimer) //* SetTimerData(t,2) : Attach value 2 to timer //* GetTimerData(t) : Get the timer's value. //* You can assume a timer's value is 0 //* after NewTimer. //* //* Multi-flavor: //* Set USE_HASH_TABLE to true if you don't want to complicate your life. //* //* If you like speed and giberish try learning about the other flavors. //* //********************************************************************
//================================================================ globals //How to tweak timer utils: // USE_HASH_TABLE = true (new blue) // * SAFEST // * SLOWEST (though hash tables are kind of fast) // // USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = true (orange) // * kinda safe (except there is a limit in the number of timers) // * ALMOST FAST // // USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = false (red) // * THE FASTEST (though is only faster than the previous method // after using the optimizer on the map) // * THE LEAST SAFE ( you may have to tweak OFSSET manually for it to // work) // private constant boolean USE_HASH_TABLE = true private constant boolean USE_FLEXIBLE_OFFSET = false
private constant integer OFFSET = 0x100000 private integer VOFFSET = OFFSET //Timers to preload at map init: private constant integer QUANTITY = 256 //Changing this to something big will allow you to keep recycling // timers even when there are already AN INCREDIBLE AMOUNT of timers in // the stack. But it will make things far slower so that's probably a bad idea... private constant integer ARRAY_SIZE = 8190
endglobals
//================================================================================================== globals private integer array data[ARRAY_SIZE] private hashtable ht endglobals
//It is dependent on jasshelper's recent inlining optimization in order to perform correctly. function SetTimerData takes timer t, integer value returns nothing static if(USE_HASH_TABLE) then // new blue call SaveInteger(ht,0,GetHandleId(t), value) elseif (USE_FLEXIBLE_OFFSET) then // orange static if (DEBUG_MODE) then if(GetHandleId(t)-VOFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif set data[GetHandleId(t)-VOFFSET]=value else // new red static if (DEBUG_MODE) then if(GetHandleId(t)-OFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif set data[GetHandleId(t)-OFFSET]=value endif endfunction
function GetTimerData takes timer t returns integer static if(USE_HASH_TABLE) then // new blue return LoadInteger(ht,0,GetHandleId(t) ) elseif (USE_FLEXIBLE_OFFSET) then // orange static if (DEBUG_MODE) then if(GetHandleId(t)-VOFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif return data[GetHandleId(t)-VOFFSET] else // new red static if (DEBUG_MODE) then if(GetHandleId(t)-OFFSET<0) then call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer") endif endif return data[GetHandleId(t)-OFFSET] endif endfunction
//========================================================================================== globals private timer array tT[ARRAY_SIZE] private integer tN = 0 private constant integer HELD=0x28829022 //use a totally random number here, the more improbable someone uses it, the better. endglobals
//========================================================================================== function NewTimer takes nothing returns timer if (tN==0) then //If this happens then the QUANTITY rule has already been broken, try to fix the // issue, else fail. debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly") static if( not USE_HASH_TABLE) then debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true") set tT[0]=CreateTimer() static if( USE_FLEXIBLE_OFFSET) then if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then //all right, couldn't fix it call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.") return null endif else if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then //all right, couldn't fix it call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.") return null endif endif endif else set tN=tN-1 endif call SetTimerData(tT[tN],0) return tT[tN] endfunction
//========================================================================================== function ReleaseTimer takes timer t returns nothing if(t==null) then debug call BJDebugMsg("Warning: attempt to release a null timer") return endif if (tN==ARRAY_SIZE) then debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
//stack is full, the map already has much more troubles than the chance of bug call DestroyTimer(t) else call PauseTimer(t) if(GetTimerData(t)==HELD) then debug call BJDebugMsg("Warning: ReleaseTimer: Double free!") return endif call SetTimerData(t,HELD) set tT[tN]=t set tN=tN+1 endif endfunction
private function init takes nothing returns nothing local integer i=0 local integer o=-1 local boolean oops = false static if( USE_HASH_TABLE ) then set ht = InitHashtable() loop exitwhen(i==QUANTITY) set tT[i]=CreateTimer() call SetTimerData(tT[i], HELD) set i=i+1 endloop set tN = QUANTITY else loop set i=0 loop exitwhen (i==QUANTITY) set tT[i] = CreateTimer() if(i==0) then set VOFFSET = GetHandleId(tT[i]) static if(USE_FLEXIBLE_OFFSET) then set o=VOFFSET else set o=OFFSET endif endif if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then exitwhen true endif if (GetHandleId(tT[i])-o>=0) then set i=i+1 endif endloop set tN = i exitwhen(tN == QUANTITY) set oops = true exitwhen not USE_FLEXIBLE_OFFSET debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again") endloop if(oops) then static if ( USE_FLEXIBLE_OFFSET) then debug call BJDebugMsg("The problem has been fixed.") //If this message doesn't appear then there is so much //handle id fragmentation that it was impossible to preload //so many timers and the thread crashed! Therefore this //debug message is useful. elseif(DEBUG_MODE) then call BJDebugMsg("There were problems and the new timer limit is "+I2S(i)) call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:") call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)") call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) ) endif endif endif
endfunction
endlibrary
Вызов функции: Скриншот.
|
|
|
|
|
|
|
|
|
|
|