зачем ты ставишь 64 если оно всеравно преобразуется в 8192?
Поиск по 64 меня устраивает. И 64 так и останется 64 в моем случае. Я выделяю это пространство для юнита в этих массивах:
кат
scope UnitGroupEmulation
globals
constant integer UGEAllocatedAmountOfCells = 64//per unit
constant integer UGEOverflow = 63
constant integer UGEStartingSize = 512
constant integer UGEInitExit = 511
constant integer UGESizeOfSubArray = 8// 512/64 and round it up to 2^X
constant integer UGESizeOfSubArrayExit = 8
//integer array UGEAllocatedCells
integer array UGEIntegers[UGEStartingSize]
unit array UGEUnits[UGEStartingSize]
integer UGENext = 0//*UGEAllocatedAmountOfCells to get the variable with minimal ID of allocated part of array
integer array UGENextUnitOfThisSpace[UGESizeOfSubArray]
endglobals
function FillUGEArray takes nothing returns nothing
local integer i = 0
loop
set UGEIntegers[i] = 0
set UGEUnits[i] = null
exitwhen i == UGEInitExit
set i = i + 1
endloop
endfunction
#define UGEGetSpace( nothing ) = {
UGENext
set UGENextUnitOfThisSpace[UGENext] = UGENext * UGEAllocatedAmountOfCells
set UGENext = UGENext + 1
}
#define UGESimplyAddUnitToSpace( whichUnit, whichSpace ) = {//Base local code upon this. Would be wrong to use it raw.
set UGEUnits[UGENextUnitOfThisSpace[whichSpace]] = whichUnit
if ( UGENextUnitOfThisSpace[whichSpace] == ( whichSpace * UGEAllocatedAmountOfCells ) + UGEOverflow ) then
set UGENextUnitOfThisSpace[whichSpace] = whichSpace * UGEAllocatedAmountOfCells
endif
}
endscope
и перерабатываю его. Благо я могу делать это без проблем т.к. не пишу на вжассе (scope используется для доп. табуляции)
зачем информация о числе задеваний таргета Т1 кастами кастера C1?
У меня конец времени дебаффа отсчитывается одним из "потоков" таймера, работая аналогично твоему отсчету времени до конца дебаффа. Информация о числе задеваний нужна чтобы из группы всех юнитов, задетых кастом кастера не удалять юнита, если тот содержится еще в какой-то группе(иначе лжедебафф, по-сути, еще активен, но будет снят).
полный бред которого у меня нету и который хз зачем нужен
да и размер массива всегда фиксирован и равен 8192(2 в 13 степени)
Кто-то из нас явно понимает другого не-правильно. Либо оба :> Но я вижу в твоем описании свое решение. nvc123:
Diaboliko:
Таймер реализован как отдельный поток работы одного глобального, так что использую ресурсы, находящиеся в простОе.
это не понял вообще
сколько таймеров(игровых объектов), с каким периодом работают таймеры и каким образом ты реализуешь свои таймеры?
Ну если тебе хочется взглянуть на индусский порнокод...
1 таймер для работ с нулевым временем(захил после нанесения урона и т.п.)
scope ZeroTimeEvent
globals
constant integer ZTEArraySize = 64//Even 32 is alot, 64 is too much! Exactly what I need!
timer Zero//Used for 0. sec uses
integer ZTECurrent = 0
unit array ZTEUnits[ZTEArraySize]
integer array ZTEIntegers[ZTEArraySize]
real array ZTEReals[ZTEArraySize]
trigger array ZTETriggers[ZTEArraySize]
endglobals
function ZeroTimeEvent takes nothing returns nothing
loop
set ZTECurrent = ZTECurrent - 1
call TriggerExecute( ZTETriggers[ZTECurrent] )
exitwhen ZTECurrent == 0
endloop
endfunction
#define ZTEAddUnit(u) = {
set ZTEUnits[ZTECurrent] = u
}
#define ZTEAddInteger(i) = {
set ZTEIntegers[ZTECurrent] = i
}
#define ZTEAddReal(r) = {
set ZTEReals[ZTECurrent] = r
}
#define ConfirmZTE(trig) = {
set ZTETriggers[ZTECurrent] = trig
set ZTECurrent = ZTECurrent + 1
call TimerStart( Zero, ZeroTime, false, function ZeroTimeEvent )
}
endscope
Плюс немного отличающаяся версия(но руки не доходят один момент пофиксить), с выделением "потока" таймера пот статический, этого
ужаса
scope GlobalTimerEvent
globals
constant integer GTE002ArrayMaxSize = 64
constant integer GTE002ArrayOverflow = 63//While < then this - do stuff else - start from zero
constant integer GTE002ArrayOverflowExit = 62//If something > this, then start from zero
constant integer GTE010ArrayMaxSize = 125
constant integer GTE010ArrayOverflow = 124
constant integer GTE010ArrayOverflowInitExit = 123//Whatever you wanna call it like. Its for proper init :P
constant integer GTE010ArrayOverflowExit = 119//5 ticks per second with increment of 5 are limited at 125 variables([124])
// (starting from zero). So 124 - 5 = exit so it gets up to 124, but no more.
constant integer GTEDataArrayMaxSize = 2048
constant integer GTEDataArrayOverflow = 2047
constant integer GTEDataArrayOverflowExit = 2046
constant integer GTEDataArrayCheckOverflow = 2000//Проверка на переполнение запускается после добавления всех нужных объектов
// могут теряться до 46 переменных, но памяти на них хватит :)
constant real GlobalTimerTickRate = 0.02
constant real GlobalTimerTicksPerSecond = 50.
timer GlobalTimer
integer GTE002NextEvent = 0//Ячейка, в которую будет произведена запись
integer GTE010NextEvent = 0//Ячейка, в которую будет произведена запись
//constant integer GTE010MaxLoopStartingValue = 4
integer GTE010CurrentLoopStartingValue = 0//Why not to make it go from 4 to zero, avoiding the need of var. above?
integer TimedLoopOf3 = 0//Switches between 0,1,2 every GlobalTimer tick
integer LoopOf3 = 0//Increased whenever registering a knockback event. Switches between 1,2,3. If I'll make it to switch between 1 and 2 only, there will be no need really for local variable(its barely profitable now already)
integer GTENextVariable = 0
integer GTELoopCounter = 0
integer array GTE002Loops [GTE002ArrayMaxSize]
integer array GTE002CurrentTime [GTE002ArrayMaxSize]
integer array GTE002Timeout [GTE002ArrayMaxSize]
trigger array GTE002TriggerToExecute [GTE002ArrayMaxSize]
integer array GTE002FirstVariable [GTE002ArrayMaxSize]
integer array GTE010Loops [GTE010ArrayMaxSize]
integer array GTE010CurrentTime [GTE010ArrayMaxSize]
integer array GTE010Timeout [GTE010ArrayMaxSize]
trigger array GTE010TriggerToExecute [GTE010ArrayMaxSize]
integer array GTE010FirstVariable [GTE010ArrayMaxSize]
integer array GTEIntegers [GTEDataArrayMaxSize]
real array GTEReals [GTEDataArrayMaxSize]
//Как это устроено:
//Массив 64 переменных - для экзекута с периодом 0.02
//Массив 128 переменных - для экзекута с периодом 0.10 (делятся на 5 периодов для снижения нагрузки).
//Два массива по 1024 переменных - для сохраняемых данных.
//Массив в 1024 переменные, ссылающийся на первую ячейку в дате. По дефолту использовал столько же массивов дабы ссылались
// каждый на свой массив, но 1024 значения и так дохрена, плюс я могу использовать одновременно 2 переменные на халяву
// короче это, имхо, самый оптимальный вариант по расходу памяти, хотя и усложняет кодинг, да.
//Поскольку два массива - массивы Real и Integer, может возникнуть вопрос как же сейвить юнитов?
// Я использую базу данных, так что Integer может ссылаться на базу.
endglobals
//Эти дефайны использованы, в общем то, только потому что система переделывается 2 раз.
//Первый раз был хэштейбл.
//Второй раз были 3 массива с 3 поинтерами.
//И вот сейчас я решил сделать все ну совсем кошерно. Хотя названия все-равно оставляют желать мне пойти в задницу.
#define GTE002InitVariableAdding() = {
set GTE002FirstVariable[GTE002NextEvent] = GTENextVariable
}
#define GTE010InitVariableAdding() = {
set GTE010FirstVariable[GTE010NextEvent] = GTENextVariable
}
#define GTEIncreaseVariablePointer() = {
set GTENextVariable = GTENextVariable + 1
}
#define GTEIncreaseVariablePointer(n) = {
set GTENextVariable = GTENextVariable + n
}
#define GTEAddInteger(variable1) = {
set GTEIntegers[GTENextVariable] = variable1
}
#define GTEAddReal(variable1) = {
set GTEReals[GTENextVariable] = variable1
}
#define GTECommitVariableAdding() = {
if ( GTENextVariable > GTEDataArrayCheckOverflow ) then
set GTENextVariable = 0
endif
}
function GTE002AddEventAndCommit takes integer periods, integer timeOut, trigger triggerToExecute returns nothing
set GTE002Loops[GTE002NextEvent] = periods
set GTE002CurrentTime[GTE002NextEvent] = 0
set GTE002Timeout[GTE002NextEvent] = timeOut
set GTE002TriggerToExecute[GTE002NextEvent] = triggerToExecute
if ( GTE002NextEvent < GTE002ArrayOverflow) then
set GTE002NextEvent = GTE002NextEvent + 1
else
set GTE002NextEvent = 0
endif
set triggerToExecute = null
return
endfunction
function GTE010AddEventAndCommit takes integer periods/*AKA amount of ticks*/, integer timeOut/*AKA tickrate*/, trigger triggerToExecute returns nothing
set GTE010Loops[GTE010NextEvent] = periods
set GTE010CurrentTime[GTE010NextEvent] = 0
set GTE010Timeout[GTE010NextEvent] = timeOut
set GTE010TriggerToExecute[GTE010NextEvent] = triggerToExecute
if ( GTE010NextEvent < GTE010ArrayOverflow) then
set GTE010NextEvent = GTE010NextEvent + 1
else
set GTE010NextEvent = 0
endif
set triggerToExecute = null
return
endfunction
function GTE002Tick takes nothing returns nothing
loop
if ( GTE002Loops[GTELoopCounter] > -1 ) then
if ( GTE002CurrentTime[GTELoopCounter] < GTE002Timeout[GTELoopCounter] ) then
set GTE002CurrentTime[GTELoopCounter] = GTE002CurrentTime[GTELoopCounter] + 1
else
call TriggerExecute(GTE002TriggerToExecute[GTELoopCounter])
if ( GTE002Loops[GTELoopCounter] > 0 ) then
set GTE002CurrentTime[GTELoopCounter] = 0
set GTE002Loops[GTELoopCounter] = GTE002Loops[GTELoopCounter] - 1
else
set GTE002Loops[GTELoopCounter] = -1
endif
endif
endif
exitwhen GTELoopCounter > GTE002ArrayOverflowExit
set GTELoopCounter = GTELoopCounter + 1
endloop
return
endfunction
function GTE010Tick1 takes nothing returns nothing
loop
if ( GTE010Loops[GTELoopCounter] > -1 ) then
if ( GTE010CurrentTime[GTELoopCounter] < GTE010Timeout[GTELoopCounter] ) then
set GTE010CurrentTime[GTELoopCounter] = GTE010CurrentTime[GTELoopCounter] + 1
else
call TriggerExecute(GTE010TriggerToExecute[GTELoopCounter])
if ( GTE010Loops[GTELoopCounter] > 0 ) then
set GTE010CurrentTime[GTELoopCounter] = 0
set GTE010Loops[GTELoopCounter] = GTE010Loops[GTELoopCounter] - 1
else
set GTE010Loops[GTELoopCounter] = -1
endif
endif
endif
exitwhen GTELoopCounter > GTE010ArrayOverflowExit
set GTELoopCounter = GTELoopCounter + 5
endloop
return
endfunction
function UpdateCustomBars takes unit u returns nothing
local integer i = 0
local real maxhp = GetUnitState( u,UNIT_STATE_MAX_LIFE )
local real hp = GetWidgetLife(u)
local integer color = R2I( 100. * hp / maxhp + 0.5 )
loop
call SetUnitAnimationByIndex( UnitDBHeroHPBar[i], color )
if ( color > 50. ) then
call SetUnitVertexColor( UnitDBHeroHPBar[i], ( 100 - color ) * 6, 255, 0, 255 )
else
call SetUnitVertexColor( UnitDBHeroHPBar[i], 255, color * 6, 0, 255 )
endif
call SetUnitAnimationByIndex( UnitDBHeroMPBar[i], R2I( 100. * GetUnitState( u, UNIT_STATE_MANA )/GetUnitState( u, UNIT_STATE_MAX_MANA ) + 0.5 ) )
set hp = 100. * ( hp + UnitDBAdditionalHealth[i] ) / maxhp - 0.5//So it doesnt show up if shield = 0
if ( hp > 100. ) then
set hp = 100.
endif
call SetUnitAnimationByIndex( UnitDBHeroSPBar[i], R2I( hp ) )
exitwhen i > UnitDBPreviousHero
set i = i + 1
set u = UnitDBUnit[i]
set maxhp = GetUnitState( u,UNIT_STATE_MAX_LIFE )
set hp = GetWidgetLife(u)
set color = R2I( 100. * hp / maxhp + 0.5 )
endloop
set u = null
endfunction
function GlobalTimerTick takes nothing returns nothing
local integer i = GTE010CurrentLoopStartingValue
local unit u = UnitDBUnit[0]
set GTELoopCounter = 0
call GTE002Tick()
set GTELoopCounter = i// - 1
call GTE010Tick1()
//call GTE010Tick2()//128 is low enough to never reach stream overflow.
call ImpaleMechanicsOnTimerTick( i )
if ( GTE010CurrentLoopStartingValue > 0 ) then
set GTE010CurrentLoopStartingValue = i - 1
else
set GTE010CurrentLoopStartingValue = 4
call UpdateCustomBars( u )//its actually not for just a single unit. loop is inside of called func
endif
if ( ICTicks < ICPeriod ) then
set ICTicks = ICTicks + 1
else
set ICTicks = 0
call TriggerExecute( gg_trg_SECore )
endif
set i = 0
loop
call SetUnitX( UnitDBHeroHPBar[i], GetUnitX(u) )
call SetUnitY( UnitDBHeroHPBar[i], GetUnitY(u) )
call SetUnitX( UnitDBHeroMPBar[i], GetUnitX(u) )
call SetUnitY( UnitDBHeroMPBar[i], GetUnitY(u) )
call SetUnitX( UnitDBHeroSPBar[i], GetUnitX(u) )
call SetUnitY( UnitDBHeroSPBar[i], GetUnitY(u) )
exitwhen i > UnitDBPreviousHero
set i = i + 1
set u = UnitDBUnit[i]
endloop
if ( LoopOf3 < 2 ) then
set LoopOf3 = LoopOf3 + 1
else
set LoopOf3 = 0
endif
set u = null
return
endfunction
endscope
Понятия не имею куда заведут комментарии, поэтому предлагаю им не верить. Это было так давно что я уже и не помню как их писал. А с тех пор изменения были, да...
Эти "потоки" так или иначе сидят в простое и персонаж сам по себе ест не много этих "потоков", поэтому я их с легким сердцем пускаю в оборот.
Реализуется поток примерно так:
GTE002InitVariableAdding
GTEAddInteger( ticks )//amount of ticks(to get to target point)
set r = x * lightning_spear_projectile_speed1
GTEAddReal( r )
GTEIncreaseVariablePointer
GTEAddInteger( UGRGetGroup() )
GTEAddReal( x2 + r )
GTEIncreaseVariablePointer
GTEAddInteger( UnitDBAddDummy( CreateUnit( P, lightning_spear_projectile_unit, x2 + lightning_spear_projectile_initial_offset * x, y2 + lightning_spear_projectile_initial_offset * y, angle * RadToDeg ), i ) )
set r = y * lightning_spear_projectile_speed1
GTEAddReal( r )
GTEIncreaseVariablePointer
GTEAddInteger( GetPlayerId( P ) )
GTEAddReal( y2 + r )
GTEIncreaseVariablePointer
GTEAddInteger( i )//caster user data for lifesteal
GTEAddReal( 25. * GetUnitAbilityLevel( u, QLightningSpearId ) + GetUnitAbilityLevel( u, QLightningSpear2Id ) )//Spell damage //GTEAddReal( x2 )//Unused because of aoe-check usage
//GTEIncreaseVariablePointer
//UNUSED INT
//GTEAddReal( y2 )//Unused because of aoe-check usage
GTEIncreaseVariablePointer
GTECommitVariableAdding
call GTE002AddEventAndCommit( 9999, 0, gg_trg_Lightning_spear_on_tick )
с последующим запуском при звонке потока таймера шапки кода, выглядящей для данного примера как
local integer i = GTE002FirstVariable[GTELoopCounter]
local integer ticksRemaining = GTEIntegers[i]
local real r
//GTEReals[i] contains x offset per step
set G = UGRGroups[GTEIntegers[i + 1]]
set X2 = GTEReals[i + 1]
set U2 = UnitDBUnit[GTEIntegers[i + 2]]//dummy
//GTEReals[i + 2] contains y offset per step
set P = PlayerArray[GTEIntegers[i + 3]]
set Y2 = GTEReals[i + 3]
set U3 = UnitDBUnit[GTEIntegers[i + 4]]//caster
set R = GTEReals[i + 4]
nvc123, тогда я не понимаю почему ты назвал мое решение кривым. Каким ты увидил принцип работы?
Просто я все больше вижу в твоем решении свое. Подход немного другой, но в целом - я делаю тоже самое. Я храню в массиве из 64 элементов(сохранив ссылку на выделенное пространство там, где надо) информацию о числе задеваний таргета Т1 кастами кастера C1. Прогоняюсь через этот массив каждый раз при непосредственном задевании дабы увеличить или уменьшить счетчик, плюс при проверке на нахождение целей вблизи даммиков для нанесения урона. Уменьшаю этот счетчик при звонке таймера на окончание действие дебаффа(/жизни даммика). Считай тот же отсчет времени дебаффа. Таймер реализован как отдельный поток работы одного глобального, так что использую ресурсы, находящиеся в простОе.
преобразуется как раз в несколько параллельных массивов
и что в этом плохого?
Ятп, что предлагаемое тобой решение заключается в создании нескольких массивов чисто под этот спелл. В прочем, я не до конца понимаю во что превратятся такие структуры в конечном итоге. :>
2 содержит оставшееся время баффа, даммика который наносит урон и структуру 1 и крепится к юнитам попавшим под спелл
что здесь крепление к юнитам, попавшим под спелл, подразумевает крепление ко всем и сразу, т.е. к группе юнитов внутри структуры, а также обработки этих структур из под единственного таймера. Как раз в этой ситуации я и прибег к своим костылям. Как ты собрался удалять юнита из структуры 1, если он содержится в двух структурах 2(задет двумя кастами)? Как узнать что время действующего на него лжебаффа закончилось во всех структурах 2 типа? Только перебором.
Diaboliko, крайне кривое решение
не проще ли создать 2 структуры
1 содержит группу всех задетых юнитов и крепится к кастеру
2 содержит оставшееся время баффа, даммика который наносит урон и структуру 1 и крепится к юнитам попавшим под спелл
Что, ятп, преобразуется как раз в несколько параллельных массивов, пространство которых выделяется под юнитов, попавших под спелл.
Кто-нибудь уже объяснил зачем нужна глобальная группа?
Есть такое понятие как скоупинг. В чем проблема использовать одну группу на один каст? Я что-то не так понял?
Одна группа на один каст имеется. Глобальная группа выделяется для каждого такого юнита дабы при добавлении в первую группу, юнит также добавлялся в глобальную. При поиске целей для нанесения урона от даммика используется глобальная группа(дабы обеспечить желаемый эффект двух войд-зон, дамажащих юнитов, задетых хотя бы одним кастом своего кастера). Первая упомянутая в этом посте группа (назовем ее локальной, т.к. используется в рамках 1 каста) нужна для удаления из глобальной всех юнитов, содержащихся в ней(своего рода удаление дебаффа без использования оного).
Опять же - единственный солюшн, который я вижу - использовать 2 параллельных массива(юнит+интегер), где массив юнитов заменит глобальную группу, а параллельный этому массиву массив интегеров будет работать как счетчик. Недостаток этого метода в необходимости искать задетых каждым следующим кастом юнитов из массива юнитов. Если этого описания все еще недостаточно, то пора закрывать эту тему -_-
В общем, прибегнул к эмуляции группы юнитов через цикл + два параллельных массива, пространство которых выделяется под кастеров этого заклинания.
В первой цитате говорилось о двух разных кастерах.
Сейчас касты работают каждый сами по себе(задел кастом - даммик будет дпсить), но от задевания одним кастом, даммику, появившемуся от другого каста, ни горячо, ни холодно.
в результате D1 наносит урон T если T находится в радиусе досягаемости D1
и D2 наносит урон T если T находится в радиусе досягаемости D2
да или нет?
Это как раз тот солюшн, которого я хочу избежать. D2 не должен наносить урон T, поскольку сам каст его не задел. Такое поведение в данный момент реализовано в рамках каждого каста. Если каст задевает юнита - даммик этого каста будет наносить задетому юниту урон. Сабж в том чтобы если персонаж применяет дважды этот скилл и задевает противника T лишь одним из них, то даммики D1 и D2, созданные по итогам применения обоих кастов наносили этому юниту урон. Проблема именно в ведении счета того, сколько раз юнит был добавлен в эту "глобальную" группу, содержащую всех юнитов, которых своими кастами задел этот персонаж. В прочем, спустя два дня тыканья палкой, я уже уверен что "красивого" решения здесь нет. Разве что я что-то упускаю...
Там вроде X Y в диапазоне [0.,1.]. Отвечают за положение сообщения на экране. Однако при этом сдвигаются все существующие сообщения. Контрится чисткой экрана
При чём тут владелец
Когда урон надо наносить от определённого юнита - кастера, т.е. героя в данном случае
Proshel_Doty:
Я бы так не делал, хотя бы потому, что тогда такой предмет как Octarine Core как в доте2 (ну суть понятна - хилит от способностей) не будет просто хилить героя из-за того, что не он наносит урон.
Поскольку я знаю что даммика создал конкретный юнит под нужды нанесения урона - я утверждаю что урон, в итоге, наносит этот конкретный юнит. Если я захочу прохилить этого юнита - у меня есть ссылка на него в UnitUserData даммика. Однако я бы предпочел услышать в этом конкретном топике мысли по решению возникшей у меня задачи. Если хочется дальше поспорить о превосходстве гибкости метода нанесения всего магического урона от даммика против нанесения урона от того же юнита - пиши в ЛС.
Diaboliko:
наношу урон от даммиков
Я бы так не делал, хотя бы потому, что тогда такой предмет как Octarine Core как в доте2 (ну суть понятна - хилит от способностей) не будет просто хилить героя из-за того, что не он наносит урон.
Внезапно решается базами данных. Я храню в UnitUserData юнитов их позицию в БД, а в UnitUserData даммиков, являющихся снарядами и прочей подобной фигней - позицию в БД их создателя. Ссылка на даммиков в БД хранится в таймерах, использующих их. Для мгновенного урона также есть два даммика, которые постоянно меняют владельца перед нанесением урона. Первый - для блокируемого урона, второй - для не блокируемого.
Попытка описать дубль два:
Герой кидает молнию да, да, привет фанатам дарк соулс //
Она задевает огра мага в момент достижения указанной точки
На месте взрыва появляется даммик, к которому этот огр притягивается, при этом ему наносится урон. При текущей реализации огр будет притягиваться лишь к тем даммикам, которые, грубо говоря, задели его своим появлением(если его заденет снаряд во время полета или непосредственный взрыв). Задумка в том, чтобы подвергнуть огра эффекту двух таких даммиков, если его заденет хотя-бы один каст. Проблема реализации через баффы в том, что два и более таких персонажей, будучи союзниками, засрут все поле боя и будут держать всех противников под дебаффом.
немного не понял по поводу того что должно быть
1 каст спелла - 1 даммик?
если 2 спела одновременно попали на 1 юнита то они оба дамажат или только 1 из них?
Тогда дамажат с течением времени оба даммика. Если было бы скастованно в одну точку 2 таких скилла и лишь один из них задел бы цель - цель бы получала урон от обоих даммиков. Если ни одного - могла бы спокойно гулять возле даммиков. Если бы два разных кастера скастовали скилл в одну точку и только один из них задел бы цель - цель получала бы урон от даммика кастера, который ее задел.
Если урон от одного игрока складывается при нескольких применениях скила, то:
КОгда кастуется эта способность, делам переменную типа integer cast count = cast count +1
Юнит кастер[cast count] = GetSpellAbilityUnit()
Группа юнитов[cast count] = юниты которых надо дамажить
И в триггере с переодиком через цикл перебираем от 1 до cast count
в нём перебираем юнитов в определённой группе и в каждой группе наносим урон от кастера всем юнитам в этой группе.
В итоге: способность можно кастовать любое количество раз, разными героями, а также складывается урон от 1 перса.
Если нужно, чтобы урон не складывался, то тогда для одного героя 1 группа, или проще для игрока, так как герой такой у игрока будет 1 скорее всего Hate:
храни одну на каждого игрока
Во-первых, я с тем же успехом наношу урон от даммиков через ForGroup внутри ForGroup.
Во-вторых, суть именно том, чтобы попав под бафф такого каста юнит старался избегать созданных даммиков до окончания времени действия мнимого баффа. Мнимого - поскольку реальный бафф будет перебиваться, например, таким же юнитом союзника. Если желаемого адекватного решения возникшей проблемы не возникнет - скорее всего прибегну к этому решению. mishanka122:
nvc123, Стакающийся эффект.
разве баффы нельзя разбить на лвлы? Тогда и лвл баффа юзать как множитель.
Как упоминалось в этом посте - такой вариант реализации не желателен.
ClotPh,
Тут надо делать карту чисто для подпивасов (это не значит что она будет лёгкой), никакие глубокие механики, они не оценят. А уж про модели и ландшафт тем более.
Вообще ещё проблема тестить карту, гарена огорожена от сторонних хостботов, на одном айкапе можешь и не собрать.
Никогда не запускал WE от админа. Почему-то после определенного момента просто перестали создаваться бэкапы(возможно после некорректного завершения работы). Никто с подобным не сталкивался?
Удаление файла backupsdata эффекта не дает?
Удалил. Все ок. Вопрос в том, почему это начало происходить :)
Событие: Юнит приводит способность в действие
Условие: Примененная способность = Увечье(или что там)
Действие: Уменьшить размер цели заклинания(не имею понятия как там это будет называться, но суть такова)
Никогда не запускал WE от админа. Почему-то после определенного момента просто перестали создаваться бэкапы(возможно после некорректного завершения работы). Никто с подобным не сталкивался?
Полагаю, можно в одном из файлов архива карты накопипастить нужное количество, а затем загрузить карту в редакторе и править как душе угодно. Хотя я не представляю под какие такие нужды может не хватать ~200 юнитов.
В рамках джолли кооперейшн есть ли моделлер под работу с WC3, желающий ворваться в тему желтого электричества? Главным образом речь идет о подборе/создании/правке спецэффектов, однако правка модели, взятую за основу(ветряной элемент панды пивовара(у него куча лишних анимаций)) под нужную тематику(ретекстурирование + опциональное изменение самой модели), также имеет место быть в опциональном режиме. В рамках кооперирования также будет дискуссия на тему концепта героя(надо на победку же мутить :) ) и, если с молниями совсем уж тлен, изменения тематики(однако многие элементы уже готовы, поэтому хотелось бы подгонять тематику под скиллы, а не скиллы под тематику :>). Пока подробности не освещаю, т.к. настроение сейчас из разряда "дико в падлу", однако осознаю что в одиночку визуальную составляющую не осилю в силу отсутствия прямых рук. Прошу изъявлять желание в ЛС.
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
Отредактирован Diaboliko
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
nvc123:
Эти "потоки" так или иначе сидят в простое и персонаж сам по себе ест не много этих "потоков", поэтому я их с легким сердцем пускаю в оборот.
Отредактирован Diaboliko
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
Просто я все больше вижу в твоем решении свое. Подход немного другой, но в целом - я делаю тоже самое. Я храню в массиве из 64 элементов(сохранив ссылку на выделенное пространство там, где надо) информацию о числе задеваний таргета Т1 кастами кастера C1. Прогоняюсь через этот массив каждый раз при непосредственном задевании дабы увеличить или уменьшить счетчик, плюс при проверке на нахождение целей вблизи даммиков для нанесения урона. Уменьшаю этот счетчик при звонке таймера на окончание действие дебаффа(/жизни даммика). Считай тот же отсчет времени дебаффа. Таймер реализован как отдельный поток работы одного глобального, так что использую ресурсы, находящиеся в простОе.
Отредактирован Diaboliko
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
nvc123:
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
Отредактирован Diaboliko
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
Опять же - единственный солюшн, который я вижу - использовать 2 параллельных массива(юнит+интегер), где массив юнитов заменит глобальную группу, а параллельный этому массиву массив интегеров будет работать как счетчик. Недостаток этого метода в необходимости искать задетых каждым следующим кастом юнитов из массива юнитов.
Если этого описания все еще недостаточно, то пора закрывать эту тему -_-
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
Сейчас касты работают каждый сами по себе(задел кастом - даммик будет дпсить), но от задевания одним кастом, даммику, появившемуся от другого каста, ни горячо, ни холодно.
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
В прочем, спустя два дня тыканья палкой, я уже уверен что "красивого" решения здесь нет. Разве что я что-то упускаю...
» WarCraft 3 / native DisplayTextToPlayer takes player toPlayer, real x, real y
Отредактирован Diaboliko
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
Однако я бы предпочел услышать в этом конкретном топике мысли по решению возникшей у меня задачи. Если хочется дальше поспорить о превосходстве гибкости метода нанесения всего магического урона от даммика против нанесения урона от того же юнита - пиши в ЛС.
Отредактирован Diaboliko
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
Герой кидает молнию
да, да, привет фанатам дарк соулс //
Отредактирован Diaboliko
» WarCraft 3 / Альтернативы добавлению юнита в группу дважды(что невозможно)?
Во-вторых, суть именно том, чтобы попав под бафф такого каста юнит старался избегать созданных даммиков до окончания времени действия мнимого баффа. Мнимого - поскольку реальный бафф будет перебиваться, например, таким же юнитом союзника. Если желаемого адекватного решения возникшей проблемы не возникнет - скорее всего прибегну к этому решению.
mishanka122:
» WarCraft 3 / идексы переменных
» WarCraft 3 / Ограничение дальности атаки Героя 650. Как снять?
» WarCraft 3 / Невыделяемый юнит
» WarCraft 3 / Невыделяемый юнит
» WarCraft 3 / Конкурс карт WC3 на 50 000 рублей!
» Hanabishi's Blog / Jass New Gen Pack - Rebuild
» WarCraft 3 / Баф на уменьшение физ. размера.
Условие: Примененная способность = Увечье(или что там)
Действие: Уменьшить размер цели заклинания(не имею понятия как там это будет называться, но суть такова)
Отредактирован Diaboliko
» Hanabishi's Blog / Jass New Gen Pack - Rebuild
» WarCraft 3 / Лагает РО - войска
» WarCraft 3 / Лагает РО - войска
» Dota 2 / Конкурс героев для Dota 2
» WarCraft 3 / Блестяшки или симуляция Specular карт