Продолжение xgm.guru/p/100/208276
Экспериментальным путём удалось выяснить, что фатал из-за переполнения памяти после выхода из игры вызывает заклинание Priest of Titania.
В крайнем случае заменю его на другое, но, может, всё-таки кто отыщет возможную причину?
function PriestOfTitaniaCrystals takes nothing returns nothing
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t2, u5, u6, u7, p, p2, elfs, crystals, heroes
local timer t2 = GetExpiredTimer()
local unit u5 = LoadUnitHandle(udg_Hash,GetHandleId(t2),2)
local unit u6
local unit u7
local location p
local location p2
local group elfs = GetUnitsInRectAll(GetPlayableMapRect())
local group crystals = GetUnitsInRectAll(GetPlayableMapRect())
local group heroes = GetUnitsInRectAll(GetPlayableMapRect())
local integer i = LoadInteger(udg_Hash, GetHandleId(t2),3)
local integer count = 0
local integer count2 = 0
local real elf_creaturetype = 0
local real crystal_might = 0
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
set i = i+1
call SaveInteger(udg_Hash,GetHandleId(t2),3,i)
if IsDead(u5) == true or u5 == null then
call PauseTimer(t2)
call DestroyTimer(t2)
call FlushChildHashtable(udg_Hash, GetHandleId(t2))
else
ГЕРОИ БЕРУТ КРИСТАЛЛЫ...
loop
set u6=FirstOfGroup(heroes)
exitwhen u6==null
call GroupRemoveUnit(heroes,u6)
if ( IsUnitType((u6), UNIT_TYPE_HERO) == true ) and IsDead (u6) == false then
set p = GetUnitLoc(u6)
set count2 = CountUnitsInGroup(crystals)
set count = 0
ТУТ ПОД ПЕРВЫМ УСЛОВИЕМ УЖЕ ЦИКЛ ДЛЯ КРИСТАЛЛОВ, СВЕРХУ НАМ НУЖНО ТОЛЬКО U6 И P...
loop
set u7=FirstOfGroup(crystals)
exitwhen u7==null
call GroupRemoveUnit(crystals,u7)
if ( GetUnitTypeId(u7) == 'n416' ) and IsDead(u7) == false then
set p2 = GetUnitLoc(u7)
if DistanceBetweenPoints (p, p2) < 120 then
set crystal_might = LoadReal(udg_Hash,GetHandleId(u7),StringHash("crystal_might"))
loop
exitwhen crystal_might == 0
set crystal_might = crystal_might - 1
ЭФФЕКТ И ДОБАВКА МАКС. МАНЫ ТРИЖДЫ - ЗАКРЫТО.
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\Polymorph\\PolyMorphTarget.mdl.&#8203;mdx", u6, "chest"))
call UnitAddAbilityBJ('A25P', u6)
call SetUnitAbilityLevelSwapped('A25P', u6, 2)
call UnitRemoveAbilityBJ('A25P', u6)
call UnitAddAbilityBJ('A25P', u6)
call SetUnitAbilityLevelSwapped('A25P', u6, 2)
call UnitRemoveAbilityBJ('A25P', u6)
call UnitAddAbilityBJ('A25P', u6)
call SetUnitAbilityLevelSwapped('A25P', u6, 2)
call UnitRemoveAbilityBJ('A25P', u6)
ЭФФЕКТ И ДОБАВКА МАКС. МАНЫ ТРИЖДЫ - ЗАКРЫТО.
endloop
call RemoveUnit(u7)
call RemoveLocation(p2)
endif
else
endif
endloop
ТУТ ПJД ПЕРВЫМ УСЛОВИЕМ УЖЕ ЦИКЛ ДЛЯ КРИСТАЛЛОВ - ЗАКРЫТО.
ГРУППА КРИСТАЛЛОВ ПОЛНОСТЬЮ ОЧИЩЕНА, НУЖНО ДОБАВИТЬ В НЕЕ ВСЕХ
call GroupAddGroup( elfs, crystals )
ГРУППА КРИСТАЛЛОВ ПОЛНОСТЬЮ ОЧИЩЕНА, НУЖНО ДОБАВИТЬ В НЕЕ ВСЕХ
call RemoveLocation(p)
else
endif
endloop
ГЕРОИ БЕРУТ КРИСТАЛЛЫ - ЗАКРЫТО.
ЖРЕЦ СПАВНИТ КРИСТАЛЛ МОЩЬЮ ПО КОЛ-ВУ ЭЛЬФОВ - ПРОВЕРКА ПО ХЭШУ С ЗАПИСЬЮ В ПЕРЕМЕННУЮ! - СО ВРЕМЕНЕМ ЖИЗНИ 4 СЕК КАЖДЫЙ (РАЗ В 5 СЕКУНД)
if i >=5 then
set i = 0
call SaveInteger(udg_Hash,GetHandleId(t2),3,i)
loop 
set u6=FirstOfGroup(elfs)
exitwhen u6==null
set elf_creaturetype = LoadReal(udg_Hash,GetHandleId(u6),StringHash("elf_creaturetype"))
call GroupRemoveUnit(elfs,u6)
if elf_creaturetype == 1 and IsDead (u6) == false then
set count = count + 1
else
endif
endloop
call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\Polymorph\\PolyMorphTarget.mdl.&#8203;mdx",u5,"chest"))
set u6=CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), 'n416', GetUnitX(u5), GetUnitY(u5), bj_RADTODEG * Atan2(GetUnitY(u5) - GetUnitY(u5), GetUnitX(u5) - GetUnitX(u5)))
call UnitApplyTimedLifeBJ( 4.00, 'BTLF', u6 )
set crystal_might = 0
loop
exitwhen count==0
set crystal_might = crystal_might + 1
set count = count-1
endloop
call SaveReal(udg_Hash,GetHandleId(u6),StringHash("crystal_might"),crystal_might)
endif
ЖРЕЦ СПАВНИТ КРИСТАЛЛ МОЩЬЮ ПО КОЛ-ВУ ЭЛЬФОВ СО ВРЕМЕНЕМ ЖИЗНИ 4 СЕК КАЖДЫЙ - ЗАКРЫТО.
endif
call DestroyGroup (elfs)
call DestroyGroup (crystals)
call DestroyGroup (heroes)
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t2, u5, u6, u7, p, p2, elfs, crystals, heroes
set t2 = null
set u5 = null
set u6 = null
set u7 = null
set p = null
set p2 = null
set elfs = null
set crystals = null
set heroes = null
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
function PriestOfTitania2 takes nothing returns nothing
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
local timer t = GetExpiredTimer()
local unit u5 = LoadUnitHandle(udg_Hash,GetHandleId(t),2)
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
ТУТ СТОП, Т. К. ЭТО ПОСЛЕ АВТОКАСТА НА ОСНОВЕ ХИЛКИ СТАТУИ, НО И ТАЙМЕР ЧУТЬ ПОДОЛЬШЕ
call IssueImmediateOrderBJ( u5, "stop" )
ТУТ СТОП, Т. К. ЭТО ПОСЛЕ АВТОКАСТА НА ОСНОВЕ ХИЛКИ СТАТУИ - ЗАКРЫТО.
call SaveReal(udg_Hash,GetHandleId(u5),StringHash("priestoftitania"),0)
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash,GetHandleId(t))
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
set t = null
set u5 = null
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
function PriestOfTitania takes nothing returns nothing
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, t2, u5, u6
local timer t = CreateTimer()
local timer t2 = CreateTimer()
local unit u5=GetTriggerUnit()
local unit u6
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
local integer i = 0
local real priestoftitania = 0
set priestoftitania = LoadReal(udg_Hash,GetHandleId(u5),StringHash("priestoftitania"))
if ( GetSpellAbilityId() == 'A33A' ) and priestoftitania == 0 then
call SaveReal(udg_Hash,GetHandleId(u5),StringHash("priestoftitania"),1)
call PlaySoundOnUnitBJ( gg_snd_MaroSorcererPriestOfTitania, 100, u5 )
set u6=CreateUnit(GetOwningPlayer(u5), 'n413', GetUnitX(u5), GetUnitY(u5), bj_RADTODEG * Atan2(GetUnitY(u5) - GetUnitY(u5), GetUnitX(u5) - GetUnitX(u5)))
call UnitApplyTimedLifeBJ( 120.00, 'BTLF', u6 )
ХЭШ ЭЛЬФА
call SaveReal(udg_Hash,GetHandleId(u6),StringHash("elf_creaturetype"),1)
ХЭШ ЭЛЬФА - ЗАКРЫТО.
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer2.mdx",u6,"origin"))
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer2.mdx",u6,"chest"))
ХП РЕГ ВНОВЬ СОЗДАННОМУ ПО ЛВЛУ СКАСТОВАННОЙ АБИЛЫ
call AddUnitHPRegen (u6,10.00*GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit()))
ХП РЕГ ВНОВЬ СОЗДАННОМУ ПО ЛВЛУ СКАСТОВАННОЙ АБИЛЫ - ЗАКРЫТО.
call SaveUnitHandle(udg_Hash, GetHandleId(t),2,u5)
call TimerStart(t,0.19,false,function PriestOfTitania2)
call SaveUnitHandle(udg_Hash, GetHandleId(t2),2,u6)
call SaveInteger(udg_Hash, GetHandleId(t2),3,i)
call TimerStart(t2,1,true,function PriestOfTitaniaCrystals)
else
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, GetHandleId(t))
call PauseTimer(t2)
call DestroyTimer(t2)
call FlushChildHashtable(udg_Hash, GetHandleId(t2))
endif
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, t2, u5, u6
set t = null
set t2 = null
set u5 = null
set u6 = null
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction

Все.
Проблема была НЕ в коде.
Код абилы вообще выключен, но после игры с ней фаталит. Просто за активацию дефолтной абилы.
Проблема в РО. ФАТАЛ ПОСЛЕ ИГРЫ ВЫЗЫВАЕТ НАСТРОЙКА АБИЛЫ В РО.
Для меня это звучит как "девочка с бородой" - в принципе возможно, но довольно удивительно, поэтому сразу в голову и не пришло.
Че-то нашаманено, ща перераспакую архив с "чистыми" картами и буду разбираться, что. Но т. к. эта абила пастилась на основе другой, сделанной на основе replenishlife, а там фатала не наблюдалось - разберусь.
///////////////////
Ну или другой вариант еще остался - РО в принципе настолько раздут до опупения, что любая дефолтная абила, созданная после момента X, начинает фаталить, если часто юзать ее в игре.
Но это крайне сомнительно, ибо:
  1. Довольно бредово;
  2. Первая из двух фаталящих абил на основе replenishlife была создана ДО трех последующих за ней абил у своего героя.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
28
относительно глобального периодического таймера - нет, конечно, одно дело что-то каждую секунду вертится и проверяет кучу условий вне зависимости от того, есть там юниты вообще удовлетворяющие этим условиям или нет; другое дело - что-то только при конкретных действиях создается и проверяется.
Кажется, Вы плохо понимаете, как работает периодический триггер.
Периодически триггер вызывает условие, если оно есть, (TriggerEvaluate), а после действие (TriggerExecute). Потому если есть N периодических триггеров с разными условиями, то будет вызываться N условий каждый тик, то есть N новых потоков (если не 2N, я вот не знаю, наследуют ли действия поток условий или создают новый).
А если заменить это всё 1 таймеров с if - elseif, то условия будут вычисляться только до того момента, пока одно из них не даст TRUE. В худшем случае, будет посчитано N условий. Но даже в этом случае это будет лучше триггеров, так как те каждый тик создают как минимум N новых потоков, а 1 таймер каждый тик создают только 1 новый поток.
Другое дело, разница между одним период. триггером и 1 период таймером. Таймер регулировать проще, чем триггер, а в случае ненадобности, таймер можно просто удалить.
что не так?
Глобальные таймеры - это ни хорошо, ни плохо. Глобальный таймер можно создать 1 раз и его использовать.
globals
   constant timer TIMER = CreateTimer()
endglobals
Этот таймер нельзя перезаписать, но можно удалить.
А можно создавать и удалять, если это нужно. Я так делаю, чтобы быть убеждённым, что отсроченные действия не будут выполнены после удаления структуры и уже созданный таймер не будет потерян в памяти из-за его пересоздания при инициализации структуры.
struct CustomTimer
   timer t
   // some parameters

   static method create takes nothing returns thistype
      local thistype this = allocate()
      set t = CreateTimer()
      return this
   endmethod

   method onDestroy takes nothing returns nothing
      call DestroyTimer(t)
   endmethod
endstruct
В целом можно таймер просто паузить при удалении структуры, а при создании написать условие для проверки наличия таймера, но тогда это будет 4 строки, вместо 2-х, а таймеры будут всегда висеть в памяти.
21
PT153, триггеры могут просто вообще даже не созданы быть
а таймер глобальный если не удален то всегда крутится и проверяет
ну если ты удаляешь то ок
все я говорю тема не об этом уже
28
а таймер глобальный если не удален то всегда крутится и проверяет
Есть такая функция, называется PauseTimer().
К тому же, таймер можно и не стартовать (Timer Start()), тогда и крутиться нечему.
триггеры могут просто вообще даже не созданы быть
Может быть, выключены, а не созданы?
все я говорю тема не об этом уже
Да я понял, просто совет даю.
Можете не отвечать.
16
Не надо насиловать стюардессу.
jASS медленнее любой нативной реализации (внутренних систем). 10 таймеров тиком по 0.02 будут эффективнее, чем один с тем же тиком и 10 if-else ветками, просто потому что таймер вызывается на пару микросекунд, а каждая строка жасса превращается в пару десятков микросекунд, в зависимости от сложности условий. Очень узкий спектр задач можно реализовать универсальным таймером так, чтобы оно работало быстрее, и пока у вас менее сотни подобных таймеров - всё норм.
Триггер тяжелее таймера по существу и по свойствам, где можно - пихай таймеры, просто без фанатизма, нужен именно триггер - ничего страшного, юзай триггер. Экономия в 0.0005 секунды может легко превратиться в часы дебага, которые нахер никому не сдались.
Из того, что там есть, битая модель больше прочих подходит
21
////////
Вообще чер-те что
Заклинание выше удалено вообще, поставлена совершенно НОВАЯ Qшка. Очень простая.
После первой же игры после выхода из игры фатал.
Единственное, что у них общее - передрочка максимальной маны вот так вот (через предметную способность):
call UnitAddAbilityBJ('A25P', u6)
call SetUnitAbilityLevelSwapped('A25P', u6, 2)
call UnitRemoveAbilityBJ('A25P', u6)
И в той и в той Q это по многу раз делается.
Неужели это может быть причиной невозможности очистить память?
Переприкреплено.
/////////////////////////
Ну бред же сивой кобылы! Ща игра без новой Qшки изучения и юза - намеренно - опять нет фатала.
Что у нового героя, проклятие на любую Qшку, что ли?
Ведь там у него другие способности юзают мемхак и хоть бы хны! Да ладно мемхак - они еще и здоровье так же предметно перепродрачивают. С какого ктулху перепродрачивать здоровье (при этом больше и чаще) можно, а ману нельзя?! Или это только у этого героя нельзя?
Последняя игра еще и дольше была, то есть что-то если бы "накапливалось" - однозначно должно было бы.
Ну вот же код новой Qшки, просто всё, как арбуз.
code
function UntamedWilds2 takes nothing returns nothing
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
local timer t = GetExpiredTimer()
local unit u5 = LoadUnitHandle(udg_Hash,GetHandleId(t),2)
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
ТУТ СТОП, Т. К. ЭТО ПОСЛЕ АВТОКАСТА НА ОСНОВЕ ХИЛКИ СТАТУИ, НО И ТАЙМЕР ЧУТЬ ПОДОЛЬШЕ
call IssueImmediateOrderBJ( u5, "stop" )
ТУТ СТОП, Т. К. ЭТО ПОСЛЕ АВТОКАСТА НА ОСНОВЕ ХИЛКИ СТАТУИ - ЗАКРЫТО.
call SaveReal(udg_Hash,GetHandleId(u5),StringHash("untamedwilds"),0)
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash,GetHandleId(t))
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
set t = null
set u5 = null
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
function UntamedWilds takes nothing returns nothing
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5, u6, elves
local timer t = CreateTimer()
local unit u5=GetTriggerUnit()
local unit u6
local group elves = GetUnitsInRectAll(GetPlayableMapRect())
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
local integer i = 0
local integer count = 0
local real elf_creaturetype = 0
local real untamedwilds = 0
set untamedwilds = LoadReal(udg_Hash,GetHandleId(u5),StringHash("untamedwilds"))
if ( GetSpellAbilityId() == 'A33M' ) and untamedwilds == 0 then
call SaveReal(udg_Hash,GetHandleId(u5),StringHash("untamedwilds"),1)
call PlaySoundOnUnitBJ( gg_snd_MaroSorcererUntamedWilds, 100, u5 )
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx",u5,"origin"))
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx",u5,"chest"))
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx",u5,"hand left"))
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx",u5,"hand right"))
СЧИТАЕМ ЭЛЬФОВ
loop
set u6=FirstOfGroup(elves)
exitwhen u6==null
set elf_creaturetype = LoadReal(udg_Hash,GetHandleId(u6),StringHash("elf_creaturetype"))
call GroupRemoveUnit(elves,u6)
if elf_creaturetype == 1 and IsDead (u6) == false then
set count = count + 1
else
endif
endloop
СЧИТАЕМ ЭЛЬФОВ - ЗАКРЫТО.
set count = count + GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit())
set count = count * 3
ДОБАВЛЯЕМ МАНУ
call SetUnitState(u5, UNIT_STATE_MANA, GetUnitState(u5, UNIT_STATE_MANA) + count)
loop
exitwhen count == 0
set count = count - 1
ЭФФЕКТ И ДОБАВКА МАКС. МАНЫ
call UnitAddAbilityBJ('A25P', u5)
call SetUnitAbilityLevelSwapped('A25P', u5, 2)
call UnitRemoveAbilityBJ('A25P', u5)
ЭФФЕКТ И ДОБАВКА МАКС. МАНЫ - ЗАКРЫТО.
endloop
ДОБАВЛЯЕМ МАНУ - ЗАКРЫТО.
call SaveUnitHandle(udg_Hash, GetHandleId(t),2,u5)
call TimerStart(t,0.19,false,function UntamedWilds2)
else
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, GetHandleId(t))
endif
call DestroyGroup (elves)
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5, u6, elves
set t = null
set u5 = null
set u6 = null
set elves = null
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
/
Вообще вот еще важно:
loop
set u6=FirstOfGroup(elves)
exitwhen u6==null
set elf_creaturetype = LoadReal(udg_Hash,GetHandleId(u6),StringHash("elf_creaturetype"))
call GroupRemoveUnit(elves,u6)
if elf_creaturetype == 1 and IsDead (u6) == false then
set count = count + 1
else
endif
endloop
оно пытается подгрузить LoadReal(udg_Hash,GetHandleId(u6),StringHash("elf_creaturetype")) даже с тех u6, на кого никогда никакой строки не сохранялось
причем вообще со всех юнитов на карте
но это страшно?! ведь там явно возвращается осмысленный 0, или нет?!
Загруженные файлы
20
Почему бы просто не реализовать все адекватно, а не через индусские костыли? Авось и проблема исчезнет.
Элсо - ордерить "stop" через 0.19 сек — это подло. А вдруг играть будут микроменеджмент крабы, которые сами прожимают стоп?
Элсо,
        call PauseTimer(t)
		call DestroyTimer(t)
		call FlushChildHashtable(udg_Hash,GetHandleId(t))//ссылка на таймер еще не обнулена, так что, возможно, GetHandleId(t) возвращает не 0, но я не уверен. Если нуль - хештейбл разрастается со временем.
16
вылет на функции, которая чистит данные о скиллах из таблиц
21
Diaboliko, стоп ордерится через 0,19, потому что это спелл на основе автокаста репленишлайфа статуи
если так не делать, то герой после применения спелла встанет и будет ждать его перезарядки
а если делать раньше, то спелл на кд пойти не успеет
по тому, что ты процитировал - это может быть хорошо или плохо
но это во ВСЕХ триггерах моей системы так
а в настоящее время фатал создается из-за ОДНОГО конкретного заклинания
пока что получается так:
UntamedWilds2 - это вообще подфункция, ее можно не смотреть - опять же во всех функциях системы со спеллами на основе репленишлайфа все точно так же, и они не фаталят
смотрим UntamedWilds
что делается в функции?
спецэффекты и звуки - проигрываются корректно, и 100500 раз такое юзалось
чуть подозрительной выглядит добавка маны, но подобным способом через предмет макс мана увеличивается еще много где, это известный способ и о фаталах после него не известно, + есть герой, у которого крип-доспех так же надрачивает себе макс. жизнь (и даже еще много больше передрачивает), и у него фаталы от этого после игры не появлялись
//////////
Итак, ЧТО ОСТАЁТСЯ?
А остаётся вот что:
set elf_creaturetype = LoadReal(udg_Hash,GetHandleId(u6),StringHash("elf_creaturetype"))
Дело в том, что эта функция пытается прочитать реалку и из тех юнитов, на которых она вообще НЕ сохранялась.
При этом она смотрит ВСЕХ ЮНИТОВ В ИГРЕ ВООБЩЕ
Ясно, что это много
И вот подобного раньше в моей системе не было, все стрингхэши пока сохранялись на уникальные объекты типа кругов и героев, а тут пытается прочитаться хэш со всех юнитов, причем и с тех, на которых ранее он НЕ записывался
Вот что-то тут не так
///////////////////
DracoL1ch, ок
/////
короче, поскольку на данный момент система "эльфов" еще не создана и первичная задача - устранение фатала, пока сделаю так:
set elf_creaturetype = LoadReal(udg_Hash,GetHandleId(u6),StringHash("elf_creaturetype"))
вот эту строчку заменю на
if ... проверка по 2 типам существ
set elf_creaturetype = 1
endif
потому что на данный момент:
  • только эти 2 типа существ являются эльфами;
  • никак перестать эльфами быть эти 2 типа существ не могут;
  • никакие другие существа никак не могут стать эльфами.
90% уверенности, что фатал пропадет. Пока все сходится на этом.
Правда, на будущее систему типов существ придется как-то менять, но пока будет устранена проблема.
/
или еще есть идея
попробовать записать после else
ll SaveReal(udg_Hash,GetHandleId(u6),StringHash("elfcreaturetype"),2)
Потому что, может быть, там как-то странно JASS понимает и при попытке перевести "несуществующий хэш" в реалку исправно возвращает 0, а при попытке его очистить видит, что он типа как есть и типа как нет и не знает, что делать.
(Кэп намекает - существо будет эльфом, если elf_creaturetype = 1, любое другое значение при проверке возвращает, что оно не эльф)
короче надо вот через mpq war3map.j помучить и проверить оба варианта
утвержденный - уже открывать в WE и вписывать
///////
ТАК
call FlushChildHashtable(udg_Hash,GetHandleId(u6)) НЕЛЬЗЯ!!!
потому что на многих u6 есть и будут важные хэши
//////
СЕБЕ ЗАМЕТКА: 1 часть - менять war3map.j и делать реоптимайз главными пока ок не будет...
2 часть - потереть всю папку, делать рераспак архива и открывать карты и норм переписывать код в WE на утвержденный вариант...
3 часть релиз...
/
/////
в общем прямо тут будет отчет
и по фигу
ща проверим с записью двойки
50 на 50 будет фатал или нет
если нет то это мега зшбс потому что система эльфов будет пахать
но это самый сомнительный вариант
если он не то мб соображу как же еще отлавливать всех с хэшем эльфкричатип один не прибегая к общей группе
ну можно офк их в глобалку писать но я не хочу глобалку добавлять их и так много путаница и считаю глобалки не тру, да и потом если глобалка - так и хэш на хрен не нужон
/////////
увы, ФАТАЛ С ЗАПИСЬЮ 2 сохранился =/
/
ладно попробуем пока чтобы эльфы через бд
n417 и n418
тогда получается такой блок Считаем эльфов, заменить тот
СЧИТАЕМ ЭЛЬФОВ
loop
set u6=FirstOfGroup(elves)
exitwhen u6 == null
call GroupRemoveUnit(elves, u6)
if IsDead(u6) == false then
БД ЭЛЬФОВ. МОЖЕТ ДОПОЛНЯТЬСЯ МАРКЕРАМИ.
if ( GetUnitTypeId(u6) == 'n417' ) or ( GetUnitTypeId(u6) == 'n418' ) then
БД ЭЛЬФОВ. МОЖЕТ ДОПОЛНЯТЬСЯ МАРКЕРАМИ. ХЭШ НА ЭТО НЕ ИДЁТ - ЗАКРЫТО.
set count=count + 1
endif
else
endif
endloop
СЧИТАЕМ ЭЛЬФОВ - ЗАКРЫТО.
///////////////
если это прокатит, то мб просто вынесу вверх в функцию IsUnitElf но позже
чтобы при новых баффах везде бд не заполнять
БРЕД!!! Все равно фатал...
Так, ну есть еще одно предположение...
function UntamedWilds takes nothing returns nothing
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5, u6, elves
local timer t= CreateTimer()
local unit u5=GetTriggerUnit()
local unit u6
local group elves= CreateGroup()
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
local integer i= 0
local integer count= 0
local real elf_creaturetype= 0
local real untamedwilds= 0
set untamedwilds=LoadReal(udg_Hash, GetHandleId(u5), StringHash("untamedwilds"))

if ( GetSpellAbilityId() == 'A33M' ) and untamedwilds == 0 then
call SaveReal(udg_Hash, GetHandleId(u5), StringHash("untamedwilds"), 1)

set elves=GetUnitsInRectAll(GetPlayableMapRect())

call PlaySoundOnUnitBJ(gg_snd_MaroSorcererUntamedWilds, 100, u5)

call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx", u5, "origin"))
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx", u5, "chest"))
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx", u5, "hand left"))
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx", u5, "hand right"))

//СЧИТАЕМ ЭЛЬФОВ
loop
set u6=FirstOfGroup(elves)
exitwhen u6 == null
call GroupRemoveUnit(elves, u6)
//БД ЭЛЬФОВ. МОЖЕТ ДОПОЛНЯТЬСЯ МАРКЕРАМИ.
if ( GetUnitTypeId(u6) == 'n417' ) or ( GetUnitTypeId(u6) == 'n418' ) then
//БД ЭЛЬФОВ. МОЖЕТ ДОПОЛНЯТЬСЯ МАРКЕРАМИ. ХЭШ НА ЭТО НЕ ИДЁТ - ЗАКРЫТО.
set count=count + 1
else
endif
endloop
//СЧИТАЕМ ЭЛЬФОВ - ЗАКРЫТО.

set count=count + GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit())
set count=count * 3

//ДОБАВЛЯЕМ МАНУ
call SetUnitState(u5, UNIT_STATE_MANA, GetUnitState(u5, UNIT_STATE_MANA) + count)
loop
exitwhen count == 0
set count=count - 1
//ЭФФЕКТ И ДОБАВКА МАКС. МАНЫ
call UnitAddAbilityBJ('A25P', u5)
call SetUnitAbilityLevelSwapped('A25P', u5, 2)
call UnitRemoveAbilityBJ('A25P', u5)
//ЭФФЕКТ И ДОБАВКА МАКС. МАНЫ - ЗАКРЫТО.
endloop
//ДОБАВЛЯЕМ МАНУ - ЗАКРЫТО.

call SaveUnitHandle(udg_Hash, GetHandleId(t), 2, u5)
call TimerStart(t, 0.19, false, function UntamedWilds2)
else
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, GetHandleId(t))
endif

call DestroyGroup(elves)

//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5, u6, elves
set t=null
set u5=null
set u6=null
set elves=null
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
ТУТ ***** нечему в принципе фаталить!!!
Вначале задаются переменные. Ну ок, одна считывается из стрингхэша, но так же сделаны все новые заклинания в системе и они не вызывают фатала!!!
далее элементарный ифзенэлс.
звук.
эффекты.
Счет эльфов. Уже БЕЗ ХЭША!!!
И цикл, который заканчивается, иначе фаталило бы НАМНОГО раньше!!!
Ну вот и всё. ШОЗАБРЕД???? С КАКОГО ***************************************************** фатал????
/
так. а попробую ща вообще все убрать в функции UntamedWilds, но сам ее запуск оставить, если ща в последней попытке фатал будет. Мб я не туда пляшу...
((упрощенный код
function UntamedWilds takes nothing returns nothing
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
local timer t= CreateTimer()
local unit u5=GetTriggerUnit()
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
local real untamedwilds= 0
set untamedwilds=LoadReal(udg_Hash, GetHandleId(u5), StringHash("untamedwilds"))
if ( GetSpellAbilityId() == 'A33M' ) and untamedwilds == 0 then
call SaveReal(udg_Hash, GetHandleId(u5), StringHash("untamedwilds"), 1)
call PlaySoundOnUnitBJ(gg_snd_MaroSorcererUntamedWilds, 100, u5)
call SaveUnitHandle(udg_Hash, GetHandleId(t), 2, u5)
call TimerStart(t, 0.19, false, function UntamedWilds2)
else
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, GetHandleId(t))
endif
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
set t=null
set u5=null
ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
))
///////
upd: при выучивании триг регается нормально... только на него...
и только при лвл 1...
ДАШОЗАБРЕД ЯИГРАТЬУЖЕХОЧУ
////////
лять да с кодом выше предпоследним тоже фатал...
так ну попробуем практически пустую функцию (последний код)
если ок - будем постепенно вставлять "куски"
//////////
Так, 21-11 - тест пустой функции (ну практически пустой)
потом в любом случае отвлекаемся на важное от всего этого, потом решаем, что делать дальше
но вроде должна уж пустая-то без фаталов пройти
если не пройдет - там че-то от переполнения РО что ли в принципе и/или тригов и проверки данных по всем активированным спеллам, что ли, но нет, бред, там прист в списке спеллов-то первым был изначально еще до нового спелла, ну и с хрен ли присту бажить тогда, а последующим нет?
все-таки пока про код думаем
/////////////
имхо уж пустая-то функция не зафаталит
тогда будем кусками вставлять:
  • сперва аккуратно просчет числа эльфов БЕЗ добаффффффффффффффффффффффки маны
  • потом, если ок, вставим добаффффффффффффффффффффффффффку
  • потом, если ок, вернем и эффекты визуальные на место
ну а если фатал бу и при практически пустой функции - ето уже ппц порнуха, знач трабла не в скилле а там в каком-то в принципе переполнении или хз, что этот скилл уже переполняет че-то сверх меры...
upd: мб в плане эффектов обойдемся ток добавкой на чест, я уже ничему не верю тут в этом спелле упоротом
////////
ТААААК! ТАААК! ТААК!!! Игорь сделал мощное встречное движение... о чем это я... а неважно... оное уже не гуглится дажы ыыыыыыыы
Ну крч так ну ето ето ето ето ето ПУСТОЙ ВСЕ-ТАКИ НЕ ФАТАЛИТ.
Уже значит не совсем все того этого куку шо.
Опять коды енти пхать
function UntamedWilds takes nothing returns nothing
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5, u6
local timer t= CreateTimer()
local unit u5=GetTriggerUnit()
local unit u6
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
local integer count= 0
local real untamedwilds= 0

set untamedwilds=LoadReal(udg_Hash, GetHandleId(u5), StringHash("untamedwilds"))

if ( GetSpellAbilityId() == 'A33M' ) and untamedwilds == 0 then

call SaveReal(udg_Hash, GetHandleId(u5), StringHash("untamedwilds"), 1)
call PlaySoundOnUnitBJ(gg_snd_MaroSorcererUntamedWilds, 100, u5)

set udg_g=GetUnitsInRectAll(GetPlayableMapRect())

//ДЕЙСТВИЯ С ГЛОБАЛ ГРУППОЙ НЕ ДОЛЖНЫ МОЧЬ ПЕРЕЗАПИСАТЬСЯ В ПРОЦЕССЕ
//СЧИТАЕМ ЭЛЬФОВ
loop
set u6=FirstOfGroup(udg_g)
exitwhen u6 == null
call GroupRemoveUnit(udg_g,u6)
//БД ЭЛЬФОВ. МОЖЕТ ДОПОЛНЯТЬСЯ МАРКЕРАМИ.
if ( GetUnitTypeId(u6) == 'n417' ) or ( GetUnitTypeId(u6) == 'n418' ) then
//БД ЭЛЬФОВ. МОЖЕТ ДОПОЛНЯТЬСЯ МАРКЕРАМИ. ХЭШ НА ЭТО НЕ ИДЁТ - ЗАКРЫТО.
set count=count + 1
else
endif
endloop
//СЧИТАЕМ ЭЛЬФОВ - ЗАКРЫТО.
//ДЕЙСТВИЯ С ГЛОБАЛ ГРУППОЙ НЕ ДОЛЖНЫ МОЧЬ ПЕРЕЗАПИСАТЬСЯ В ПРОЦЕССЕ - ЗАКРЫТО.

call SaveUnitHandle(udg_Hash, GetHandleId(t), 2, u5)
call TimerStart(t, 0.19, false, function UntamedWilds2)

call DestroyGroup (udg_g)

else

call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, GetHandleId(t))
endif

//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5, u6
set t=null
set u5=null
set u6=null
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
Так. Все, это компилится 22-16.
Теперь эльфы считаются, но не добавляют ману. Попробуем глобальную группу еще вместо локальной, т. к. она тогда будет не всегда создаваться.
Если ок, тогда проверим уже и добавку маны.
Фак просто нервы никуда уже СВОЛОЧИ!!! Ну Мултанюшка, ну действуй!!!
ТАК в 22-34 переоптимайз из-за опечатки...
/
Так. вот оно.
////////////////////
ФАТАЛИТ СЧЁТ ЭЛЬФОВ.
ФАТАЛИТ СЧЁТ ЭЛЬФОВ.
ФАТАЛИТ СЧЁТ ЭЛЬФОВ.
(После игры)
set udg_g=GetUnitsInRectAll(GetPlayableMapRect())
ДЕЙСТВИЯ С ГЛОБАЛ ГРУППОЙ НЕ ДОЛЖНЫ МОЧЬ ПЕРЕЗАПИСАТЬСЯ В ПРОЦЕССЕ
СЧИТАЕМ ЭЛЬФОВ
loop
set u6=FirstOfGroup(udg_g)
exitwhen u6 == null
call GroupRemoveUnit(udg_g,u6)
БД ЭЛЬФОВ. МОЖЕТ ДОПОЛНЯТЬСЯ МАРКЕРАМИ.
if ( GetUnitTypeId(u6) == 'n417' ) or ( GetUnitTypeId(u6) == 'n418' ) then
БД ЭЛЬФОВ. МОЖЕТ ДОПОЛНЯТЬСЯ МАРКЕРАМИ. ХЭШ НА ЭТО НЕ ИДЁТ - ЗАКРЫТО.
set count=count + 1
else
endif
endloop
СЧИТАЕМ ЭЛЬФОВ - ЗАКРЫТО.
ДЕЙСТВИЯ С ГЛОБАЛ ГРУППОЙ НЕ ДОЛЖНЫ МОЧЬ ПЕРЕЗАПИСАТЬСЯ В ПРОЦЕССЕ - ЗАКРЫТО.
Вот это фаталит. Хоть с локалкой, хоть с глобалкой группой.
Хоть с хэшстрингом, хоть без.
Втф?
Вкрайний можно везде закл UntamedWilds переписать тупо на увеличение макс. и текущей маны, но не оч хочется...
Итак, вот пока НЕ фаталящий вариант. Пляшем от него.
function UntamedWilds takes nothing returns nothing
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
local timer t= CreateTimer()
local unit u5=GetTriggerUnit()
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
local real untamedwilds= 0
set untamedwilds=LoadReal(udg_Hash, GetHandleId(u5), StringHash("untamedwilds"))
if ( GetSpellAbilityId() == 'A33M' ) and untamedwilds == 0 then
call SaveReal(udg_Hash, GetHandleId(u5), StringHash("untamedwilds"), 1)
call PlaySoundOnUnitBJ(gg_snd_MaroSorcererUntamedWilds, 100, u5)
call SaveUnitHandle(udg_Hash, GetHandleId(t), 2, u5)
call TimerStart(t, 0.19, false, function UntamedWilds2)
else
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, GetHandleId(t))
endif
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
set t=null
set u5=null
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
Но в этом варианте и нет ничего.
А ну-ка попробуем вот так:
function UntamedWilds takes nothing returns nothing
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
local timer t= CreateTimer()
local unit u5=GetTriggerUnit()
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
local real untamedwilds= 0
local integer count= 0
set untamedwilds=LoadReal(udg_Hash, GetHandleId(u5), StringHash("untamedwilds"))
if ( GetSpellAbilityId() == 'A33M' ) and untamedwilds == 0 then

call SaveReal(udg_Hash, GetHandleId(u5), StringHash("untamedwilds"), 1)
call PlaySoundOnUnitBJ(gg_snd_MaroSorcererUntamedWilds, 100, u5)


call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx", u5, "origin"))
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx", u5, "chest"))
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx", u5, "hand left"))
call DestroyEffect(AddSpecialEffectTarget("MaroSorcerer1New.mdx", u5, "hand right"))

set count=count + GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit())
set count=count * 3

//ДОБАВЛЯЕМ МАНУ
call SetUnitState(u5, UNIT_STATE_MANA, GetUnitState(u5, UNIT_STATE_MANA) + count)
loop
exitwhen count == 0
set count=count - 1
//ЭФФЕКТ И ДОБАВКА МАКС. МАНЫ
call UnitAddAbilityBJ('A25P', u5)
call SetUnitAbilityLevelSwapped('A25P', u5, 2)
call UnitRemoveAbilityBJ('A25P', u5)
//ЭФФЕКТ И ДОБАВКА МАКС. МАНЫ - ЗАКРЫТО.
endloop
//ДОБАВЛЯЕМ МАНУ - ЗАКРЫТО.

call SaveUnitHandle(udg_Hash, GetHandleId(t), 2, u5)
call TimerStart(t, 0.19, false, function UntamedWilds2)
else
call PauseTimer(t)
call DestroyTimer(t)
call FlushChildHashtable(udg_Hash, GetHandleId(t))
endif
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ: t, u5
set t=null
set u5=null
//ВНИМАНИЕ!!! ОБНУЛЯЕМЫЕ ПЕРЕМЕННЫЕ ЗДЕСЬ СПИСКОМ - НОВЫЙ ШАБЛОН СОВЕРШЕНСТВА, ВСЕ ТЕСТКАРТЫ БЕЗ ОНОГО БУДУТ УДАЛЕНЫ - ЗАКРЫТО
endfunction
Если так будет действовать, остаётся лишь решить, как нам эльфов присчитать...
тут все наоборот - все есть, кроме подсчета эльфов в группе

Выполнена перезапись в 23-43 на вариант выше
ща будем после компиляции тестить
если все ок - ток родить присчет эльфов или отказаться от него (но последнее хреново)
если нет... пока нет сил уже решать и желания, просто посмотрим
Выполнено перезапись в 23-50 из-за опечатки, ппц нервы гомонят
Я С***О ИГРААААТЬ ХАААААААААААААААААЧУ
24
ClotPh, попробуй считать эльфов не перебором, а в момент их рождения и смерти, со счетчиком в глобалке/массиве - должно быть эффективнее если юнитов много на карте. Заодно получаеш бесплатный инструмент для отладки, позволяющий подставлять туда любое число независимо от реального кол-ва эльфов (офк, при условии отключения реального подсчета).
21
prog, я не хочу исп. глобалки без крайней необходимости
и ща мой мозг не выдержит такого, он уже хочет отдыхать, а релизить хочется
так, О_О, фатал
тут реально проклятие Qшки какое-то, пока она сверх простая, ничего не происходит
при попытках че-то в нее добавить - фатал
может, какое-то "переполнение кастом кода", что ли? Тоже бредовато...
Вообще ничего не понятно
Вот ща эльфы НЕ считались и все равно фатал
Просто фатал при попытках в Qшку добавить действия
////
Ну будем курить дальше, что делать.
0-53. Из последнего варианта кода убрано все после последнего дестройэффекта и начиная с сохранения хэндла.
Т. е. спелл ща все равно "пустышка", но хоть кроме звука еще эффекты спавнит. И переменная count таки невинно просто ОБЪЯВЛЯЕТСЯ.
Сыграю так. Хоть компиляция долгая, а катки быстрые...
////////////////
Еще раз, пока получается так: фатала после игры нет, пока Q - "спелл-пустышка". Т. е. просто издает звук и запускает таймер UntamedWilds2, где невинно перезаписывает блокирующий себя при касте хэш (как делают все спеллы новые в системе).
Как только пытаюсь приписать или добавку маны без подсчёта эльфов, или подсчёт эльфов без добавки маны - фатал.
//////
В общем, сейчас добавляю к "пустышке" объявление переменной count целочисленной без использования и спецэффекты.
Если фатала не будет - уже что-то довольно интересное.
Если будет - значит, дело не в конкретной части кода, а что-то в системе опять поперек себя шире или хрен поймешь. Надо будет тогда все-таки весь код PriestOfTitania неактивный стереть, что ли, но это все равно получится лишь временная панацея...
/////////////////
Может, "нестандартный код до глобальных триггеров" стал слишком большим? Но тоже бредовато. Во-первых, раньше он был еще больше до некоторой последней реструктуризации. Во-вторых, игра по идее все равно видит весь код нестандартным. Чушь крч...
/////////////
"вылет на функции, которая чистит данные о скиллах из таблиц"
"вылет на функции, которая чистит данные о скиллах из таблиц"
"вылет на функции, которая чистит данные о скиллах из таблиц"
"вылет на функции, которая чистит данные о скиллах из таблиц"
что же тут можно почерпнуть...
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.