ShadowNinja, координаты мышки можно отловить только на мемхаке/южапи, во втором случае оно даже сразу засинханным будет, на ванилке разве что с помощью пкм управлять направлением луча
Shermanator00, есть всё на ванилке. Если я предлагаю какие-то варианты недоступные стандартными методами, я говорю, что данный метод нестандартный
Я пытался прикрепить эффекты юниту, но мне не удалось прикрепить туда, где я ожидал их увидеть, ни на правой руке, ни на оружии, а значит, соответствующих аттачментов нет
Мне, как спеллмейкеру, звуки в модели порой мешают. Я хочу сам решать какой звук создавать и какой громкости
Shermanator00, есть ещё 2 варианта, это переделать не под "юнит атакован", а "юнит получает урон", но в данном случае уклонение уже не сработает вроде, только блокирование урона, при этом, не будет казусов, учитывающих факторы старта вылета снаряда и скорость снаряда (потому что абилка срабатывает, когда снаряд ещё даже не появился, при запахе атакующего)
Да, во время рывка ты слышишь какой-то лишний звук, во время критического удара то же самое, точек крепления будто вовсе нет, хотел эффект прикрепить к оружию/правой руке. Но мне уже всё равно даже если исправленную модель зальют
Shermanator00, не вижу во втором варианте что-то связанное с блокированием урона. Только перемещение влево/вправо и добавление критического шанса для следующей автоатаки. Есть 2 варианта, либо заблокировать урон с автоатаки во время рывка, либо добавить 100% уклонение на время рывка, что подходит?
скопировать папку Initialization и вставить в свою карту, копировать элементы из редактора объектов и вставлять в свою карту
всё остальное гуишное, думаю разберёшься, (указать в триггерах абилки из ро, ну и можешь с параметрами побаловаться, вроде скорости уворота, дальности, угла)
на видео демонстрация 100% уворота, чтобы не дожидаться выпадения шансов (в карте 15/20/25%)
кроме этого, длительность уворота поставил не 1.20, а 0.50, потому что ну это капес перебор дружище, впрочем, всё в твоих руках, угол настроил не под 90 градусов, а 50, чтобы кружился вокруг атакующего противника и делал нырки при беге к дальнику ближе к его стороне, но опять же, всё настраиваемо
кроме того, пока юнит не нанесёт критический удар, он добавлен в группу для проверки, планировал это делать только на время самого уворота, но понял, что слишком большая потеря контроля происходит, если тебя устраивает шанс того, что игрок может всё время в уворотах находиться на поле боя и не иметь возможности убежать/ударить - убери всё, что связано с TempGroup
SebastianCarrey, прочитай инструкцию по импорту хотя бы.. я зря её написал что ли
То, что ты показал на скрине, обведено комментарием с помощью /* */, это значит, что при компиляции этот код удаляется. Убери просто вначале слэш со звездой и в конце звезду со слэшем
скопировать папку Initialization и вставить в свою карту, копировать элементы из редактора объектов и вставлять в свою карту
всё остальное гуишное, думаю разберёшься, (указать в триггерах абилки из ро, ну и можешь с параметрами побаловаться, вроде скорости переката и времени для баффов)
чисто из спеллмейкерского рационализма, я бы всё же добавил учёт преград для переката и сделал скорость переката (и анимации соответственно) в зависимости от скорости бега, а то глупо выглядит, когда бегает быстрее чем перекатывается, ну, и добавил бы минимальную дистанцию для переката, впрочем, прикладываю ещё одну версию с более быстрым перекатом (0.50 сек вместо 1.00)
ShadowNinja, идея не самая оригинальная, в морозко делал уже подобное для босса, но пока делал именно этот заказ, появилась идея чтобы око саргараса спавнить над головой кастера и создавать такой же луч, который будет учитывать сферические координаты и направлен под наклоном в землю соответственно, клик правой кнопкой мыши позволит перенаправить такой луч на новую точку, но чтобы такое сделать нужен мемхак/южапи, поскольку требуется динамическое управление ориентацией модели, можно и на ванилке через кость и SetUnitLookAt, но не хочу этими костылями мазаться, тем более вне заказа
скопировать папку Initialization и вставить в свою карту
перекопировать редактор объектов и вставить в свою карту
настроить равкоды (кроме BTLF) в триггере Spell в соответствии с редактором
всё остальное, что нужно/можно отредактировать помечено комментариями, на остальное нужны базовые знания джасса
Код
AllGlobals
library AllGlobalsLib
globals
constant hashtable H = InitHashtable( )
constant location LFZ = Location( 0.00, 0.00 )
private real MaxX
private real MinX
private real MaxY
private real MinY
endglobals
native UnitAlive takes unit id returns boolean
function GetCorX takes real x returns real
if x > MaxX then
return MaxX
elseif x < MinX then
return MinX
endif
return x
endfunction
function GetCorY takes real y returns real
if y > MaxY then
return MaxY
elseif y < MinY then
return MinY
endif
return y
endfunction
function GetLocZ takes real x, real y returns real
call MoveLocation( LFZ, x, y )
return GetLocationZ( LFZ )
endfunction
struct vector
real x
real y
real z
method length takes nothing returns real
return SquareRoot( x * x + y * y + z * z )
endmethod
method normalize takes nothing returns nothing
local real l = length( )
if l == 0.00 then
set l = 1.00
endif
set x = x / l
set y = y / l
set z = z / l
endmethod
static method create takes real x, real y, real z returns thistype
local thistype this = thistype.allocate( )
set this.x = x
set this.y = y
set this.z = z
return this
endmethod
endstruct
//===========================================================================
function InitTrig_AllGlobals takes nothing returns nothing
//set gg_trg_AllGlobals = CreateTrigger( )
local rect r = GetWorldBounds( )
set MaxX = GetRectMaxX( r )
set MinX = GetRectMinX( r )
set MaxY = GetRectMaxY( r )
set MinY = GetRectMinY( r )
call RemoveRect( r )
set r = null
endfunction
endlibrary
Spell
library SpellLib
globals
private constant group TempGroup = CreateGroup( )
private constant group TempGroup1 = CreateGroup( )
private unit TempUnit = null
endglobals
struct SpellS
timer t
player p
unit caster
unit target
unit eye
unit field
unit laser
unit laserBig
vector l
vector array v[4]
integer lvl
real radius
real radiusEnd
real damage
real damagePeriodic
real distance
real time
real timeMax
attacktype attackType
damagetype damageType
weapontype weaponType
endstruct
private function Rotation takes nothing returns nothing
local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
local real ax
local real ay
local real d
local unit u
if GetUnitCurrentOrder( A.caster ) == OrderId( "channel" ) then
set A.time = A.time + 0.01
set A.timeMax = A.timeMax + 0.01
call SetUnitFacing( A.caster, Atan2( GetUnitY( A.target ) - A.l.y, GetUnitX( A.target ) - A.l.x ) * bj_RADTODEG )
set d = GetUnitFacing( A.caster )
set ax = Cos( d * bj_DEGTORAD )
set ay = Sin( d * bj_DEGTORAD )
call SetUnitX( A.eye, A.l.x + 275.00 * ax )
call SetUnitY( A.eye, A.l.y + 275.00 * ay )
call SetUnitX( A.field, A.l.x + 125.00 * ax )
call SetUnitY( A.field, A.l.y + 125.00 * ay )
call SetUnitFacing( A.eye, d )
call SetUnitFacing( A.laser, d )
call SetUnitFacing( A.laserBig, d )
if A.time == 1.15 then
set A.laser = CreateUnit( A.p, 'u005', A.l.x + 100.00 * ax, A.l.y + 100.00 * ay, d )
call SetUnitX( A.laser, A.l.x + 100.00 * ax )
call SetUnitY( A.laser, A.l.y + 100.00 * ay )
call SetUnitFlyHeight( A.laser, 80.00, 0.00 )
call UnitApplyTimedLife( A.laser, 'BTLF', 3.00 )
endif
if A.time >= 1.50 then
set A.time = 0.00
call SetUnitAnimation( A.field, "birth" )
call QueueUnitAnimation( A.field, "stand" )
set A.laser = CreateUnit( A.p, 'u007', A.l.x, A.l.y, d )
call SetUnitFlyHeight( A.laser, 80.00, 0.00 )
call SetUnitAnimation( A.laser, "death" )
call UnitApplyTimedLife( A.laser, 'BTLF', 5.00 )
set A.laser = CreateUnit( A.p, 'u001', A.l.x + 125.00 * ax, A.l.y + 125.00 * ay, d )
call SetUnitX( A.laser, A.l.x + 125.00 * ax )
call SetUnitY( A.laser, A.l.y + 125.00 * ay )
call SetUnitFlyHeight( A.laser, 80.00, 0.00 )
call UnitApplyTimedLife( A.laser, 'BTLF', 3.00 )
endif
if A.timeMax >= A.damagePeriodic then
set A.timeMax = 0.00
set d = 0.00
loop
call GroupEnumUnitsInRange( TempGroup, A.l.x + d * ax, A.l.y + d * ay, A.radius - ( A.radius - A.radiusEnd ) * ( d / A.distance ) + 200.00, null )
loop
set u = FirstOfGroup( TempGroup )
exitwhen u == null
call GroupRemoveUnit( TempGroup, u )
if not IsUnitInGroup( u, TempGroup1 ) then
if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then // условия для нанесения урона
if IsUnitInRangeXY( u, A.l.x + d * ax, A.l.y + d * ay, A.radius - ( A.radius - A.radiusEnd ) * ( d / A.distance ) ) then
call SetUnitAbilityLevel( TempUnit, 'A001', A.lvl )
call IssueTargetOrder( TempUnit, "slow", u )
call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\CarrionSwarm\\CarrionSwarmDamage.mdl", u, "origin" ) )
call UnitDamageTarget( A.caster, u, A.damage, false, false, A.attackType, A.damageType, A.weaponType )
call GroupAddUnit( TempGroup1, u )
endif
endif
endif
endloop
if d + 32.00 > A.distance then
set d = A.distance
else
set d = d + 32.00
endif
exitwhen d >= A.distance
endloop
call GroupClear( TempGroup1 )
endif
else
call PauseTimer( A.t )
call FlushChildHashtable( H, GetHandleId( A.t ) )
call DestroyTimer( A.t )
call SetUnitAnimation( A.eye, "death" )
call UnitApplyTimedLife( A.eye, 'BTLF', 3.00 )
call SetUnitAnimation( A.field, "death" )
call UnitApplyTimedLife( A.field, 'BTLF', 5.00 )
call SetUnitAnimation( A.laserBig, "death" )
call UnitApplyTimedLife( A.laserBig, 'BTLF', 6.00 )
set A.t = null
set A.eye = null
set A.field = null
set A.laser = null
set A.laserBig = null
set A.caster = null
set A.target = null
call A.l.destroy( )
call A.destroy( )
endif
endfunction
private function CreateEye takes nothing returns nothing
local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
local SpellS B = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 1 )
local integer k = 0
local integer i
local real array x
local real array y
local real array z
local real array x1
local real array y1
local real array z1
local unit u
set A.time = A.time + 0.01 / A.timeMax
if A.time > 1.00 then
set A.time = 1.00
endif
loop
set x[k] = A.v[k].x
set y[k] = A.v[k].y
set z[k] = A.v[k].z
set x1[k] = B.v[k].x
set y1[k] = B.v[k].y
set z1[k] = B.v[k].z
set k = k + 1
exitwhen k >= 4
endloop
set k = 0
loop
set i = 0
loop
set x[i] = ( 1.00 - A.time ) * x[i] + A.time * x[i + 1]
set y[i] = ( 1.00 - A.time ) * y[i] + A.time * y[i + 1]
set z[i] = ( 1.00 - A.time ) * z[i] + A.time * z[i + 1]
set x1[i] = ( 1.00 - A.time ) * x1[i] + A.time * x1[i + 1]
set y1[i] = ( 1.00 - A.time ) * y1[i] + A.time * y1[i + 1]
set z1[i] = ( 1.00 - A.time ) * z1[i] + A.time * z1[i + 1]
set i = i + 1
exitwhen i > 4 - k
endloop
set k = k + 1
exitwhen k >= 4 - 1
endloop
set x[0] = GetCorX( x[0] )
set y[0] = GetCorY( y[0] )
call SetUnitX( A.eye, x[0] )
call SetUnitY( A.eye, y[0] )
call SetUnitFlyHeight( A.eye, z[0] - GetLocZ( x[0], y[0] ), 0.00 )
set x1[0] = GetCorX( x1[0] )
set y1[0] = GetCorY( y1[0] )
call SetUnitX( B.eye, x1[0] )
call SetUnitY( B.eye, y1[0] )
call SetUnitFlyHeight( B.eye, z1[0] - GetLocZ( x1[0], y1[0] ), 0.00 )
if A.time >= 1.00 then
call PauseTimer( A.t )
call KillUnit( A.eye )
call KillUnit( B.eye )
set A.v[3].z = GetUnitFacing( A.caster )
set A.eye = CreateUnit( A.p, 'u003', A.v[3].x, A.v[3].y, A.v[3].z )
call UnitAddAbility( A.eye, 'Arav' )
call SetUnitX( A.eye, A.v[3].x )
call SetUnitY( A.eye, A.v[3].y )
call SetUnitFlyHeight( A.eye, 80.00, 0.00 )
call KillUnit( A.eye )
set A.eye = CreateUnit( A.p, 'u004', A.v[3].x, A.v[3].y, A.v[3].z )
call UnitAddAbility( A.eye, 'Arav' )
call SetUnitX( A.eye, A.v[3].x )
call SetUnitY( A.eye, A.v[3].y )
call SetUnitFlyHeight( A.eye, 80.00, 0.00 )
call KillUnit( A.eye )
set A.field = CreateUnit( A.p, 'u006', A.v[3].x, A.v[3].y, A.v[3].z )
call SetUnitX( A.field, A.v[3].x )
call SetUnitY( A.field, A.v[3].y )
call SetUnitAnimation( A.field, "birth" )
call QueueUnitAnimation( A.field, "stand" )
set A.laserBig = CreateUnit( A.p, 'u007', A.l.x, A.l.y, A.v[3].z )
call SetUnitX( A.laserBig, A.l.x )
call SetUnitY( A.laserBig, A.l.y )
call SetUnitFlyHeight( A.laserBig, 80.00, 0.00 )
call SetUnitAnimation( A.laserBig, "birth" )
call QueueUnitAnimation( A.laserBig, "stand" )
set A.v[3].x = A.v[3].x + 150.00 * Cos( A.v[3].z * bj_DEGTORAD )
set A.v[3].y = A.v[3].y + 150.00 * Sin( A.v[3].z * bj_DEGTORAD )
set A.eye = CreateUnit( A.p, 'u000', A.v[3].x, A.v[3].y, A.v[3].z )
call SetUnitX( A.eye, A.v[3].x )
call SetUnitY( A.eye, A.v[3].y )
call SetUnitFlyHeight( A.eye, 80.00, 0.00 )
call SetUnitAnimation( A.eye, "birth" )
call QueueUnitAnimation( A.eye, "stand" )
set i = 0
loop
call A.v[i].destroy( )
call B.v[i].destroy( )
set i = i + 1
exitwhen i >= 4
endloop
call B.destroy( )
set A.time = 1.50
call TimerStart( A.t, 0.01, true, function Rotation )
endif
endfunction
function Spell_Actions takes nothing returns nothing
local SpellS A = SpellS.create( )
local SpellS B = SpellS.create( )
local real a
set A.t = CreateTimer( )
set A.caster = GetTriggerUnit( )
set A.target = GetSpellTargetUnit( )
set A.p = GetOwningPlayer( A.caster )
set A.l = vector.create( GetUnitX( A.caster ), GetUnitY( A.caster ), 0.00 )
set A.lvl = GetUnitAbilityLevel( A.caster, GetSpellAbilityId( ) )
if A.lvl == 1 then // уровень абилки
set A.damage = 10.00 // урон
elseif A.lvl == 2 then
set A.damage = 25.00
else
set A.damage = 40.00
endif
set A.damagePeriodic = 0.30 // периодичность урона
set A.distance = 900.00 // дистанция
set A.radius = 200.00 // начальный радиус
set A.radiusEnd = 50.00 // конечный радиус
set A.attackType = null // тип атаки
set A.damageType = null // тип урона
set A.weaponType = null // тип оружия (звук)
set A.time = 0.00
set A.timeMax = 0.80
set A.v[0] = vector.create( A.l.x, A.l.y, 0.00 )
set A.v[0].z = GetLocZ( A.l.x, A.l.y ) + GetUnitFlyHeight( A.caster ) + 50.00
set a = Atan2( GetUnitY( A.target ) - A.l.y, GetUnitX( A.target ) - A.l.x )
set A.v[1] = vector.create( A.v[0].x - 500.00 * Cos( a - bj_PI * 0.15 ), A.v[0].y - 500.00 * Sin( a - bj_PI * 0.15 ), A.v[0].z + 200.00 )
set A.v[2] = vector.create( A.v[0].x - 100.00 * Cos( a - bj_PI * 0.15 ), A.v[0].y - 100.00 * Sin( a - bj_PI * 0.15 ), A.v[0].z + 200.00 )
set A.v[3] = vector.create( A.v[0].x + 125.00 * Cos( a ), A.v[0].y + 125.00 * Sin( a ), 0.00 )
set A.v[3].z = GetLocZ( A.v[3].x, A.v[3].y ) + 75.00
set A.eye = CreateUnit( A.p, 'u002', A.v[0].x, A.v[0].y, a * bj_RADTODEG )
call UnitAddAbility( A.eye, 'Arav' )
call SetUnitX( A.eye, A.v[0].x )
call SetUnitY( A.eye, A.v[0].y )
call SetUnitFlyHeight( A.eye, 50.00, 0.00 )
call SetUnitAnimation( A.eye, "birth" )
call QueueUnitAnimation( A.eye, "stand" )
set B.v[0] = vector.create( A.l.x, A.l.y, A.l.z )
set B.v[1] = vector.create( B.v[0].x - 500.00 * Cos( a + bj_PI * 0.15 ), B.v[0].y - 500.00 * Sin( a + bj_PI * 0.15 ), A.v[1].z )
set B.v[2] = vector.create( B.v[0].x - 100.00 * Cos( a + bj_PI * 0.15 ), B.v[0].y - 100.00 * Sin( a + bj_PI * 0.15 ), A.v[2].z )
set B.v[3] = vector.create( A.v[3].x, A.v[3].y, A.v[3].z )
set B.eye = CreateUnit( A.p, 'u002', B.v[0].x, B.v[0].y, a * bj_RADTODEG )
call SetUnitX( B.eye, B.v[0].x )
call SetUnitY( B.eye, B.v[0].y )
call UnitAddAbility( B.eye, 'Arav' )
call SetUnitFlyHeight( B.eye, 50.00, 0.00 )
call SetUnitAnimation( B.eye, "birth" )
call QueueUnitAnimation( B.eye, "stand" )
call SaveInteger( H, GetHandleId( A.t ), 0, A )
call SaveInteger( H, GetHandleId( A.t ), 1, B )
call TimerStart( A.t, 0.01, true, function CreateEye )
endfunction
//===========================================================================
function Spell_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
function InitTrig_Spell takes nothing returns nothing
set gg_trg_Spell = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Spell, Condition( function Spell_Conditions ) )
call TriggerAddAction( gg_trg_Spell, function Spell_Actions )
set TempUnit = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u008', 0.00, 0.00, 0.00 )
endfunction
endlibrary
Shermanator00, и заказы, пожалуйста, отдельным комментарием, а не в ветке ответов, потому что другие не увидят этот заказ, если не полезут сюда в ответы
Shermanator00, как долго длится усиление крита во втором варианте после уворота? Пока не будет нанесена автоатака? На ванилке, заставить сделать автоатаку можно только приказом, а значит, её можно будет отменить. После уворота атаковать ближнюю цель или того, кто атаковал?
» WarCraft 3 / Способности и алгоритмы на заказ
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
Ред. rsfghd
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
Ред. rsfghd
» WarCraft 3 / Заклинания на заказ
Заклинание готово!
Dodge (второй вариант)
всё остальное гуишное, думаю разберёшься, (указать в триггерах абилки из ро, ну и можешь с параметрами побаловаться, вроде скорости уворота, дальности, угла)
кроме этого, длительность уворота поставил не 1.20, а 0.50, потому что ну это капес перебор дружище, впрочем, всё в твоих руках, угол настроил не под 90 градусов, а 50, чтобы кружился вокруг атакующего противника и делал нырки при беге к дальнику ближе к его стороне, но опять же, всё настраиваемо
кроме того, пока юнит не нанесёт критический удар, он добавлен в группу для проверки, планировал это делать только на время самого уворота, но понял, что слишком большая потеря контроля происходит, если тебя устраивает шанс того, что игрок может всё время в уворотах находиться на поле боя и не иметь возможности убежать/ударить - убери всё, что связано с TempGroup
Ред. rsfghd
» WarCraft 3 / Как вывести Jass на новый уровень? Jass.
Правда новичков такое наверное отпугивать будет, что не совсем желательно
» WarCraft 3 / процентное увеличение маг урона как сделать?
» WarCraft 3 / Способности и алгоритмы на заказ
То, что ты показал на скрине, обведено комментарием с помощью /* */, это значит, что при компиляции этот код удаляется. Убери просто вначале слэш со звездой и в конце звезду со слэшем
» WarCraft 3 / Способности и алгоритмы на заказ
» WarCraft 3 / Способности и алгоритмы на заказ
» WarCraft 3 / Заклинания на заказ
Заклинание готово!
Dodge (первый вариант)
ускоренная: xgm.guru/files/100/341434/comments/543747/Spell[speed].w3x
всё остальное гуишное, думаю разберёшься, (указать в триггерах абилки из ро, ну и можешь с параметрами побаловаться, вроде скорости переката и времени для баффов)
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
Заклинание готово!
перекопировать редактор объектов и вставить в свою карту
настроить равкоды (кроме BTLF) в триггере Spell в соответствии с редактором
всё остальное, что нужно/можно отредактировать помечено комментариями, на остальное нужны базовые знания джасса
Код
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ
» WarCraft 3 / Заклинания на заказ