|
|
|
|
Волна
|
|
Smartaros | Дата: Воскресенье, 18 Ноября 2012, 14:28:21 | Сообщение # 1 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| Делаю волну, т.е. есть юнит который движется, каждое смещение вокруг него наносится урон врагам с условием что они не в такой то группе, тех кому нанес урон заношу в эту группу, но урон все равно проходит по ним снова, помню тут решали эту проблему, ток не нашел
|
|
|
|
SirNikolas | Дата: Воскресенье, 18 Ноября 2012, 15:13:47 | Сообщение # 2 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Возможно, группа уничтожается или не создается. Или еще что-нибудь. Без кода долго гадать будем.
|
|
|
|
Smartaros | Дата: Воскресенье, 18 Ноября 2012, 18:23:03 | Сообщение # 3 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| не, группа глобальная, по истечению движения чистится
|
|
|
|
Ty3uK | Дата: Воскресенье, 18 Ноября 2012, 18:28:51 | Сообщение # 4 |
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
| Smartaros, я делал иначе - в таймере пикал юнитов вокруг, если буль ложна (а при загрузке у нас будет null - false) - наношу урон и сохраняю true. Мне так пришлось делать для спеллов, которые наносили урон по пути вперед и возвращались назад. Это менее ресурсозатратно, нежели работа с группой
|
|
|
|
Smartaros | Дата: Воскресенье, 18 Ноября 2012, 18:42:36 | Сообщение # 5 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| так это придется на хэндл каждого юнита сохранять свой буль?
|
|
|
|
Ty3uK | Дата: Воскресенье, 18 Ноября 2012, 19:06:46 | Сообщение # 6 |
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
| Smartaros, да
|
|
|
|
Smartaros | Дата: Воскресенье, 18 Ноября 2012, 19:20:13 | Сообщение # 7 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| Ty3uK, запусти эту волну два раза подряд и жопа
|
|
|
|
Ty3uK | Дата: Воскресенье, 18 Ноября 2012, 19:21:20 | Сообщение # 8 |
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
| Smartaros, то есть по-твоему я пишу тебе решение, ни разу его не проверив? В моей карте так сделаны два спелла - все работает отлично, видимо кривожопая реализация тебя подвела
|
|
|
|
Smartaros | Дата: Воскресенье, 18 Ноября 2012, 19:47:32 | Сообщение # 9 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| летит первая волна, задамажила юнита и сохранила на его хендл тру, тут сразу же в этот момент летит вторая и не дамажит, т.к. весит тру, ты мне сказал так, если ты имеешь в виду одно, а на деле у тебя другое то поясняй заранее, а не предлагай фондю своих фикалий прекрывающее твой гнев
|
|
|
|
SirNikolas | Дата: Воскресенье, 18 Ноября 2012, 19:56:34 | Сообщение # 10 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Ну так сохранять нужно не как попало, а на уникальный идентификатор каста.
|
|
|
|
Ty3uK | Дата: Воскресенье, 18 Ноября 2012, 19:58:58 | Сообщение # 11 |
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
| Smartaros, фекалий, висит Граммар нацци.
Вот мой говнокод, написанный достаточно давно - все работает: Code scope ShadowSuriken {
#include "cj_types_priv.j" bool KillDestructablesInRect_Act() { KillDestructable(GetFilterDestructable()); return false; } void KillDestructablesInRect(rect r) { EnumDestructablesInRect(r, Filter(function KillDestructablesInRect_Act), null); } private void Timer() { var t = GetExpiredTimer(); var hid = GetHandleId(t); var caster = LoadUnitHandle(hash, hid, 0); var dummy = LoadUnitHandle(hash, hid, 1); var angle = LoadReal(hash, hid, 2); var dist = LoadReal(hash, hid, 3) / 9.; var x = GetWidgetX(dummy) + dist * Cos(angle); var y = GetWidgetY(dummy) + dist * Sin(angle); SetUnitPosition(dummy, x, y); SaveReal(hash, hid, 2, angle + .25); for(unit target; UnitsInRange(x, y, 80.) use temp) { if (IsUnitEnemy(target, GetOwningPlayer(caster)) && !LoadBoolean(hash, GetHandleId(target), hid)) { UnitDamageTarget(caster, target, 100., true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS); free AddSpecialEffectTarget("Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", target, "origin"); SaveBoolean(hash, GetHandleId(target), hid, true); } } MoveRectTo(tmpR, x, y); KillDestructablesInRect(tmpR); if (angle >= LoadReal(hash, hid, 5) + 6.12) { PauseTimer(t); free t, dummy; FlushChildHashtable(hash, hid); } flush t, caster, dummy; } callback onUnitSpellEffect('A006') { new timer t; global rect tmpR; var hid = GetHandleId(t); var caster = GetTriggerUnit(); var x = GetWidgetX(caster); var y = GetWidgetY(caster); var dummy = CreateDummy(GetTriggerPlayer(), "BS_Suriken.mdx", 1.5, x, y, 100., 0.); var angle = Atan2(GetSpellTargetY() - y, GetSpellTargetX() - x) - 1.02; tmpR = Rect(-30, -30, 30., 30.); SetUnitVertexColor(dummy, 0, 0, 0, 255); SaveAgentHandle(hash, hid, 0, caster); SaveAgentHandle(hash, hid, 1, dummy); SaveReal(hash, hid, 2, angle); SaveReal(hash, hid, 3, VectorGetLength(GetSpellTargetX(), GetSpellTargetY(), 0., x, y, 0.)); SaveReal(hash, hid, 5, angle); SaveAgentHandle(hash, hid, -1, AddSpecialEffectTarget("Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl", dummy, "origin")); SaveAgentHandle(hash, hid, -2, AddSpecialEffectTarget("Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl", dummy, "origin")); TimerStart(t, .04, true, function Timer); flush t, caster, dummy; }
}
|
|
|
|
SirNikolas | Дата: Воскресенье, 18 Ноября 2012, 20:10:51 | Сообщение # 12 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Quote (Ty3uK) SaveBoolean(hash, GetHandleId(target), hid, true); Quote (SirNikolas) сохранять нужно не как попало, а на уникальный идентификатор каста. Добавлено (18 Ноября 2012, 20:10:51) --------------------------------------------- Кстати, а где ты эти були чистишь?
|
|
|
|
Ty3uK | Дата: Воскресенье, 18 Ноября 2012, 20:15:13 | Сообщение # 13 |
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
| SirNikolas, Quote (Ty3uK) Вот мой говнокод, написанный достаточно давно нигде
Первая цитата к тому, что я прав?
Сообщение отредактировал Ty3uK - Воскресенье, 18 Ноября 2012, 20:15:43 |
|
|
|
Smartaros | Дата: Воскресенье, 18 Ноября 2012, 20:54:21 | Сообщение # 14 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| Quote (SirNikolas) Ну так сохранять нужно не как попало, а на уникальный идентификатор каста. не знал, как это делать?
Сообщение отредактировал Smartaros - Воскресенье, 18 Ноября 2012, 20:55:22 |
|
|
|
Ty3uK | Дата: Воскресенье, 18 Ноября 2012, 21:09:51 | Сообщение # 15 |
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
| Тебе цитату на кусок моего кода дали - сохраняй на хэндл таймера. И не забудь подчистить були через RemoveSavedBoolean(), а то я забыл
|
|
|
|
Smartaros | Дата: Воскресенье, 18 Ноября 2012, 23:21:33 | Сообщение # 16 |
9 уровень
Группа: Проверенные
Сообщений: 810
Награды: 0
Репутация: 135
Блокировки:
| вот код, почему наносится многократно Code scope Sotryasenie {
include "cj_types_priv.j"
define { private ABILITY = 'A011' private ABILITY_STUN = 'A010' private STUN_BUFF = 'B00B' private DUMMY = 'n009' private STUN(lvl) = 1.0 + 0.5 * lvl private DAMAGE(lvl) = 40. + 60. * lvl } private void Timer() { timer t = GetExpiredTimer() unit c = LoadUnitHandle(udg_Hash, GetHandleId(t), 0) UnitRemoveAbility(c, STUN_BUFF) DestroyTimer(t) FlushChildHashtable(udg_Hash, GetHandleId(t)) flush locals } private void Shaking() { timer t = GetExpiredTimer() unit c = LoadUnitHandle(udg_Hash, GetHandleId(t), 0) unit u = LoadUnitHandle(udg_Hash, GetHandleId(t), 6) int i = LoadInteger(udg_Hash, GetHandleId(t), 1) float a = LoadReal(udg_Hash, GetHandleId(t), 2) float d = LoadReal(udg_Hash, GetHandleId(t), 3) float x = GetWidgetX(c) + Cos(a) * d float y = GetWidgetY(c) + Sin(a) * d group g = new group group g2 = LoadGroupHandle(udg_Hash, GetHandleId(t), 4) unit p = null float damage = LoadReal(udg_Hash, GetHandleId(t), 5) int id = GetPlayerId(GetOwningPlayer(u)) if i != 0 { SafeMove(c, x, y) SaveInteger(udg_Hash, GetHandleId(t), 1, i - 1) SaveReal(udg_Hash, GetHandleId(t), 3, d - 10.0) GroupEnumUnitsInRange(g, GetWidgetX(c), GetWidgetY(c), 100.0, null) loop { p = FirstOfGroup(g) exitwhen p == null if ChekSpellUnit(u, p) == true || IsUnitInGroup(p, g2) == false { UnitDamageTargetByType(u, p, damage, DAMAGE_TYPE_MAGIC) GroupAddUnit(g2, p) } GroupRemoveUnit(g, p) } DestroyGroup(g) } else { SetUnitPathing(c, true) DestroyGroup(g2) DestroyTimer(t) FlushChildHashtable(udg_Hash, GetHandleId(t)) } flush locals }
callback onUnitSpellEffect(ABILITY) { unit u = GetTriggerUnit(); unit c = GetSpellTargetUnit() unit d = CreateUnit(GetOwningPlayer(u), DUMMY, GetWidgetX(c), GetWidgetY(c), 0) int level = GetUnitAbilityLevel(u, ABILITY) int str = GetHeroStr(c, true) float strx = I2R(GetHeroStr(c, true)) * 0.01 float stun = STUN(level) float damage = DAMAGE(level); float damageX = (damage + GetHeroStr(u, true)) / 2 timer t = new timer; timer t2 = new timer group g = new group; group g2 = new group unit p = null int id = GetPlayerId(GetOwningPlayer(u)) if IsUnitType(c, UNIT_TYPE_HERO) == true { if strx >= stun { stun = 0.01 } else { stun -= strx } if str >= damage { damage = 0.0 } else { damage -= str } } SaveUnitHandle(udg_Hash, GetHandleId(t), 0, c) SaveUnitHandle(udg_Hash, GetHandleId(t2), 0, c) SaveInteger(udg_Hash, GetHandleId(t2), 1, 4) SaveReal(udg_Hash, GetHandleId(t2), 2, GetUnitFacing(u) * .017) SaveReal(udg_Hash, GetHandleId(t2), 3, 50.0) TimerStart(t, stun, false, function Timer) TimerStart(t2, 0.04, true, function Shaking) UnitAddAbility(d, ABILITY_STUN) UnitApplyTimedLife(d, 'BTLF', 1.0) IssueTargetOrderById(d, order_thunderbolt, c) UnitDamageTargetByType(u, c, damage + GetHeroStr(u, true), DAMAGE_TYPE_MAGIC) PlaySoundOnUnit(gg_snd_Sotryasenie, u) PlaySoundOnUnit(gg_snd_Sotryasenie2, c) SetUnitPathing(c, false) SafeMove(c, GetWidgetX(c) + Cos(GetUnitFacing(u) * .017) * 60.0, GetWidgetY(c) + Sin(GetUnitFacing(u) * .017) * 60.0) GroupEnumUnitsInRange(g, GetWidgetX(c), GetWidgetY(c), 100.0, null) loop { p = FirstOfGroup(g) exitwhen p == null if ChekSpellUnit(u, p) == true || IsUnitInGroup(p, g2) == false { UnitDamageTargetByType(u, p, damageX, DAMAGE_TYPE_MAGIC) GroupAddUnit(g2, p) } GroupRemoveUnit(g, p) } DestroyGroup(g) SaveGroupHandle(udg_Hash, GetHandleId(t2), 4, g2) SaveReal(udg_Hash, GetHandleId(t2), 5, damageX) SaveUnitHandle(udg_Hash, GetHandleId(t2), 6, u) flush locals } }
|
|
|
|
SirNikolas | Дата: Понедельник, 19 Ноября 2012, 12:26:56 | Сообщение # 17 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Quote (Ty3uK) Первая цитата к тому, что я прав? Да, и при том решение оригинальнее, чем то, которое придумал я. Quote (Ty3uK) И не забудь подчистить були через RemoveSavedBoolean(), а то я забыл Вот с этим возникнут проблемы. Как ты определишь юнитов, попавших под воздействие данной волны? Надо сохранять не на [GetHandleId(target), hid], а на [hid, GetHandleId(target)]. Тогда просто флашим ключ и все.
|
|
|
|
Ty3uK | Дата: Понедельник, 19 Ноября 2012, 13:06:34 | Сообщение # 18 |
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
| Точно! А какое решение пришло в голову тебе?
|
|
|
|
SirNikolas | Дата: Понедельник, 19 Ноября 2012, 16:47:04 | Сообщение # 19 |
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
| Завести глобальную переменную, задать ей какое-нибудь начальное значение (какое - не важно). При каждом касте плюсовать ее и вешать на таймер. Тогда каждая волна будет иметь свой номер. Но с ID таймера интереснее.
|
|
|
|
Ty3uK | Дата: Понедельник, 19 Ноября 2012, 16:54:26 | Сообщение # 20 |
Группа: Ветераны
Сообщений: 6125
Награды: 2
Репутация: 1617
Блокировки:
|
|
|
|
|
|
|
|
|
|
|
|