Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
vJass
Тип:
Способность
Версия Warcraft:
1.26
В текущей карте продемонстрированы следующие способности:
"Пыл" ("Fervor") - Воин, освоивший эту способность, увеличивает скорость атаки за каждую атаку по врагу, однако если атаковать другую цель счетчик обнуляется. Реализована с помощью хеш-таблицы.
Fervor
globals
//============================
//      Настройки. Читать.
//---------------------------------------------
//Для работы этой способности необходим триггер [InitAttackTrigger]. Необходимо просто скопировать триггер.
//Для работы этой способности необходима библиотека [setAttribute]. Необходимо просто скопировать библиотеку (триггер).
    constant integer	Fervor_Ability='ferv'
//Сюда вбить код способности (Ctrl+D в ObjectEditor)
    constant real	    Fervor_DataA1=10.
//Кол-во дополнительной скорости атаки за удар на первом уровне (вбивать так, как написано в описании, без расчетов)
    constant real       Fervor_DataA2=10.
//Кол-во дополнительной скорости атаки за удар за уровень

//Pасчет делается так: (А1)+(А2)*(уровень-1)
//Пример:
//Уровень=4
//А1=10
//А2=10
//Percent=A1+A2*(уровень-1)=10+10*(4-1)=40
//На четвертом уровне способности кол-во дополнительной скорости атаки за удар будет равен 40%.

    constant real	    Fervor_DataB1=4.
//Максимально допустимое кол-во ударов на первом уровне (вбивать так как написано в описании, без расчетов)
    constant real       Fervor_DataB2=1.
//Максимально допустимое кол-во ударов за уровень
    constant integer	Fervor_KEY_Source='feu0'
//Ключ для хеш-таблицы, не должен совпадать со следующими ключами, что используются в этой способности
    constant integer	Fervor_KEY_Target='feu1'
//Ключ для хеш-таблицы
    constant integer	Fervor_KEY_Stack='fei0'
//Ключ для хеш-таблицы
    constant integer	Fervor_KEY_Speed='fei1' 
//Ключ для хеш-таблицы
    constant integer	Fervor_KEY_Timer='fet0'
//Ключ для хеш-таблицы

endglobals
//                  Конец установкам способности
//===========================================

function Fervor_Func_Second takes nothing returns boolean
    local timer t=GetExpiredTimer()
    local unit u=LoadUnitHandle(Hash,GetHandleId(t),Fervor_KEY_Source)
    local integer id=GetHandleId(u)
    local real i0=LoadReal(Hash,id,Fervor_KEY_Speed)

    call AddUnitAttackSpeed(u,-i0)
    call SaveReal(Hash,id,Fervor_KEY_Speed,0)
    call SaveReal(Hash,id,Fervor_KEY_Stack,0)
    call FlushChildHashtable(Hash,GetHandleId(t))
    call DestroyTimer(t)

    set u=null
    set t=null
    return false
endfunction

function Fervor_Func_Main takes nothing returns boolean
    local unit u=GetAttacker()
    local unit t=GetTriggerUnit()
    local integer level=GetUnitAbilityLevel(u,Fervor_Ability)
    local integer id=GetHandleId(u)
    local timer tr=LoadTimerHandle(Hash,id,Fervor_KEY_Timer)
    local real dataA=Fervor_DataA1+Fervor_DataA2*(level-1)
    local real dataB=Fervor_DataB1+Fervor_DataB2*(level-1)
    
    if level!=0 and not IsUnitType(t,UNIT_TYPE_STRUCTURE) then
        if t!=LoadUnitHandle(Hash,id,Fervor_KEY_Target) then
            call AddUnitAttackSpeed(u,-LoadReal(Hash,id,Fervor_KEY_Speed))
            call SaveReal(Hash,id,Fervor_KEY_Stack,0)
            call SaveReal(Hash,id,Fervor_KEY_Speed,0)
        endif
        if tr==null then
            set tr=CreateTimer()
            call SaveTimerHandle(Hash,id,Fervor_KEY_Timer,tr)
        endif
        call TimerStart(tr,2.5,false,function Fervor_Func_Second)
        call SaveUnitHandle(Hash,id,Fervor_KEY_Target,t)
        if LoadReal(Hash,id,Fervor_KEY_Stack)<dataB then
            call SaveReal(Hash,id,Fervor_KEY_Speed,LoadReal(Hash,id,Fervor_KEY_Speed)+dataA)
            call SaveReal(Hash,id,Fervor_KEY_Stack,LoadReal(Hash,id,Fervor_KEY_Stack)+1)
            call AddUnitAttackSpeed(u,dataA)
        endif
        call SaveUnitHandle(Hash,GetHandleId(tr),Fervor_KEY_Source,u)
    endif
    
    set t=null
    set u=null
    set tr=null
    return false
endfunction

//===========================================================================
function InitTrig_Fervor takes nothing returns nothing
    call TriggerAddCondition(EVENT_PLAYER_UNIT_ATTACKED_TRIGGER,Condition(function Fervor_Func_Main))
endfunction
"Смертельный удар" ("Critical Strike") - Воин, освоивший эту способность, получает шанс нанести дополнительный урон при каждой атаке. Реализована с помощью хеш-таблицы.
Critical Strike
globals
//==============================================
//                               Настройки. Читать.
//------------------------------------------------------------------
// Для работы этой способности необходим триггер [InitAttackTrigger]. Необходимо просто скопировать триггер.
// В нестандартном коде карты так же имеется кусочек кода (функция [UnitDamageTargetEx]) для работы способности. Обязательно к копированию!
    constant integer	CriticalStrike_Ability='crit'
//Сюда вбить код способности (Ctrl+D в ObjectEditor)
    constant real	    CriticalStrike_DataA1=30.
//Шанс успеха на первом уровне (вбивать так, как написано в описании, без расчетов)
    constant real	    CriticalStrike_DataA2=.0
//Шанс успеха за уровень
//  Pасчет делается так: (А1)+(А2)*(уровень-1)
//  Пример:
// Уровень=4
// А1=30
// А2=5
// Chance=A1+A2*(уровень-1)=30+5*(4-1)=45
// На четвертом уровне способности шанс успеха будет равен 45%.
    constant real	    CriticalStrike_DataB1=2.
//Множитель урона на первом уровне (вбивать так как написано в описании, без расчетов)
    constant real	    CriticalStrike_DataB2=.5
//Множитель урона за уровень
    constant string	    CriticalStrike_DataC1="slam"
//Анимация во время успеха
    constant string	    CriticalStrike_DataC2="stand, ready"
//Анимация во время удара (нанесения урона)
    constant integer	CriticalStrike_KEY_Source=0
//Ключ для хеш-таблицы, не должен совпадать со следующими ключами, что используются в этой способности
    constant integer	CriticalStrike_KEY_Target=1
//Ключ для хеш-таблицы
    constant boolean    CriticalStrike_DMG_Data_Attack=true
//Опция для урона от успешной атаки. Урон проходит как атака?
    constant boolean    CriticalStrike_DMG_Data_Ranged=false
//Опция для урона от успешной атаки. Урон проходит от дальнего боя? (можно оставить, если даже способность используется дальним боем)
    constant attacktype CriticalStrike_DMG_Data_AttackType=ATTACK_TYPE_NORMAL
//Опция для урона от успешной атаки. Какой тип атаки использовать для нанесения урона?
    constant damagetype CriticalStrike_DMG_Data_DamageType=DAMAGE_TYPE_NORMAL
//Опция для урона от успешной атаки. Какой тип урона использовать для нанесения урона?
    constant weapontype CriticalStrike_DMG_Data_WeaponType=null
//Опция для урона от успешной атаки. Какой тип оружия использовать для нанесения урона? (играет роль только для озвучивания урона, тем типом оружия, что вписан здесь)

endglobals
//                       Конец установкам способности
//================================================

function CriticalStrike_Func_Second takes nothing returns boolean
    local trigger tr=GetTriggeringTrigger()
    local texttag tt
    local integer id=GetHandleId(tr)
    local unit u=LoadUnitHandle(Hash,id,CriticalStrike_KEY_Source)
    local unit t=LoadUnitHandle(Hash,id,CriticalStrike_KEY_Target)
    local integer level=GetUnitAbilityLevel(u,CriticalStrike_Ability)
    local real data=CriticalStrike_DataB1+CriticalStrike_DataB2*(level-1)
    local real dmg=GetEventDamage()
    if GetTriggerEventId()==EVENT_UNIT_DAMAGED and (dmg>1. and u==GetEventDamageSource() and t==GetTriggerUnit() and RegisterDamage) then
        call QueueUnitAnimation(u,CriticalStrike_DataC2)
        call DisableTrigger(tr)
        set dmg=dmg*data
        set tt=CreateTextTag()
        call SetTextTagText(tt,I2S(R2I(dmg))+"!",0.025)
        call SetTextTagPos(tt,GetUnitX(u),GetUnitY(u),0)
        call SetTextTagColor(tt,255,0,0,255)
        call SetTextTagVelocity(tt,0,0.03)
        call SetTextTagVisibility(tt,true)
        call SetTextTagFadepoint(tt,2)
        call SetTextTagLifespan(tt,3)
        call SetTextTagPermanent(tt,false)
        call SetTextTagSuspended(tt,false)
        set tt=null
        call UnitDamageTargetEx(u,t,dmg-GetEventDamage(),CriticalStrike_DMG_Data_Attack,CriticalStrike_DMG_Data_Ranged,CriticalStrike_DMG_Data_AttackType,CriticalStrike_DMG_Data_DamageType,CriticalStrike_DMG_Data_WeaponType)
        call FlushChildHashtable(Hash,id)
        call DestroyTrigger(tr)
    else
        call FlushChildHashtable(Hash,id)
        call DestroyTrigger(tr)
    endif
    set t=null
    set u=null
    set tr=null
    set tt=null
    return false
endfunction

function CriticalStrike_Func_Main takes nothing returns boolean
    local unit u=GetAttacker()
    local unit t=GetTriggerUnit()
    local integer id
    local integer level=GetUnitAbilityLevel(u,CriticalStrike_Ability)
    local real data=CriticalStrike_DataA1+CriticalStrike_DataA2*(level-1)
    local trigger tr=null
    if level!=0 and GetRandomReal(.0,100.)<=data and RegisterDamage then
        set tr=CreateTrigger()
        set id=GetHandleId(tr)
        call SaveUnitHandle(Hash,id,CriticalStrike_KEY_Source,u)
        call SaveUnitHandle(Hash,id,CriticalStrike_KEY_Target,t)
        call SetUnitAnimation(u,CriticalStrike_DataC1)
        call TriggerRegisterTimerEvent(tr,2.5,false)
        call TriggerRegisterUnitEvent(tr,t,EVENT_UNIT_DAMAGED)
        call TriggerRegisterUnitEvent(tr,u,EVENT_UNIT_ISSUED_TARGET_ORDER)
        call TriggerRegisterUnitEvent(tr,u,EVENT_UNIT_ISSUED_POINT_ORDER)
        call TriggerRegisterUnitEvent(tr,u,EVENT_UNIT_ISSUED_ORDER)
        call TriggerAddCondition(tr,Condition(function CriticalStrike_Func_Second))
    endif
    set t=null
    set u=null
    set tr=null
    return false
endfunction

//===========================================================================
function InitTrig_CriticalStrike takes nothing returns nothing
    call TriggerAddCondition(EVENT_PLAYER_UNIT_ATTACKED_TRIGGER,Condition(function CriticalStrike_Func_Main))
endfunction
"Уворот" ("Evade") - Воин, освоивший эту способность, получает шанс уклониться от атаки противника. Реализована с помощью хеш-таблицы.
Evade
globals
//=======================================
//                              Настройки. Читать.
//-----------------------------------------------------------------
// Для работы этой способности необходим триггер [InitAttackTrigger]. Необходимо просто скопировать триггер.
    constant integer	Evade_Ability='evad'
//  Сюда вбить код способности (Ctrl+D в ObjectEditor)
    constant real	    Evade_DataA1=25.
//  Шанс успеха на первом уровне (вбивать так, как написано в описании, без расчетов)
    constant real       Evade_DataA2=5.5
//  Шанс успеха за уровнь
//  Pасчет делается так: (А1)+(А2)*(уровень-1)
//  Пример:
//      Уровень=4
//      А1=25
//      А2=5.5
//      Chance=A1+A2*(уровень-1)=25+5.5*(4-1)=41.5
//  На четвертом уровне способности шанс успеха будет равен 41,5%.
    constant string     Evade_DataB1="промах"
//  Текст всплывающий над врагом, что промахнулся
    constant string     Evade_DataB2="Abilities\\Spells\\Orc\\MirrorImage\\MirrorImageCaster.mdl"
//  Модель эффекта, что срабатывает во время восстановления здоровья
    constant string     Evade_DataB3="origin"
//  К какой кости прикрепить эффект?
    constant integer	Evade_KEY_Source=0
//  Ключ для хеш-таблицы, не должен совпадать со следующими ключами, что используются в этой способности
    constant integer	Evade_KEY_Target=1
//  Ключ для хеш-таблицы
endglobals
//                     Конец установкам способности
//=========================================

function Evade_Func_Timer takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local integer id=GetHandleId(t)
    local unit u=LoadUnitHandle(Hash,id,Evade_KEY_Source)
    local real r=LoadReal(Hash,id,Evade_KEY_Target)
    
    call SetWidgetLife(u,GetWidgetLife(u)+r)
    call DestroyEffect(AddSpecialEffectTarget(Evade_DataB2,u,Evade_DataB3))
    set RegisterDamage=true
    
    call FlushChildHashtable(Hash,id)
    call DestroyTimer(t)
    set t=null
endfunction

function Evade_Func_Second takes nothing returns boolean
    local trigger tr=GetTriggeringTrigger()
    local integer id=GetHandleId(tr)
    local unit u=LoadUnitHandle(Hash,id,Evade_KEY_Source)
    local unit t=LoadUnitHandle(Hash,id,Evade_KEY_Target)
    local timer ti
    local real dmg=GetEventDamage()
    local boolean b=false
    if GetTriggerEventId()==EVENT_UNIT_DAMAGED and (dmg>1. and u==GetEventDamageSource() and t==GetTriggerUnit() and RegisterDamage) then
        call DisableTrigger(tr)
        set ti=CreateTimer()
        call SaveUnitHandle(Hash,GetHandleId(ti),Evade_KEY_Source,t)
        call SaveReal(Hash,GetHandleId(ti),Evade_KEY_Target,dmg)
        call TimerStart(ti,.0,false,function Evade_Func_Timer)
        set RegisterDamage=false
        call FlushChildHashtable(Hash,id)
        call DestroyTrigger(tr)
    else
        call FlushChildHashtable(Hash,id)
        call DestroyTrigger(tr)
    endif
    set t=null
    set u=null
    set tr=null
    set ti=null
    return false
endfunction

function Evade_Func_Main takes nothing returns boolean
    local unit u=GetAttacker()
    local unit t=GetTriggerUnit()
    local trigger tr
    local texttag tt
    local integer id
    local integer level=GetUnitAbilityLevel(t,Evade_Ability)
    local real data=Evade_DataA1+Evade_DataA2*(level-1)

    if level!=0 and GetRandomReal(.0,100.)<=data then
        set tr=CreateTrigger()
        set id=GetHandleId(tr)
        call SaveUnitHandle(Hash,id,Evade_KEY_Source,u)
        call SaveUnitHandle(Hash,id,Evade_KEY_Target,t)
        call TriggerRegisterTimerEvent(tr,2.5,false)
        call TriggerRegisterUnitEvent(tr,t,EVENT_UNIT_DAMAGED)
        call TriggerRegisterUnitEvent(tr,u,EVENT_UNIT_ISSUED_TARGET_ORDER)
        call TriggerRegisterUnitEvent(tr,u,EVENT_UNIT_ISSUED_POINT_ORDER)
        call TriggerRegisterUnitEvent(tr,u,EVENT_UNIT_ISSUED_ORDER)
        call TriggerAddCondition(tr,Condition(function Evade_Func_Second))
        set tt=CreateTextTag()
        call SetTextTagText(tt,Evade_DataB1,0.022)
        call SetTextTagPos(tt,GetUnitX(u),GetUnitY(u),0)
        call SetTextTagColor(tt,255,0,0,255)
        call SetTextTagVelocity(tt,0,0.03)
        call SetTextTagVisibility(tt,true)
        call SetTextTagFadepoint(tt,2)
        call SetTextTagLifespan(tt,3)
        call SetTextTagPermanent(tt,false)
        call SetTextTagSuspended(tt,false)
    endif

    set t=null
    set u=null
    set tr=null
    set tt=null
    return false
endfunction

//===========================================================================
function InitTrig_Evade takes nothing returns nothing
    call TriggerAddCondition(EVENT_PLAYER_UNIT_ATTACKED_TRIGGER,Condition(function Evade_Func_Main))
endfunction
InitAttackTrigger
// НЕОБХОДИМ ДЛЯ РАБОТЫ СПОСОБНОСТЕЙ!
globals
    boolean RegisterDamage=true
    trigger EVENT_PLAYER_UNIT_ATTACKED_TRIGGER=CreateTrigger()
    hashtable Hash=InitHashtable()
endglobals

//===========================================================================
function InitTrig_InitAttackTrigger takes nothing returns nothing
    local integer i=0
    loop
        exitwhen i==16
        call TriggerRegisterPlayerUnitEvent(EVENT_PLAYER_UNIT_ATTACKED_TRIGGER,Player(i),EVENT_PLAYER_UNIT_ATTACKED,Filter(function GroupFilter))
        set i=i+1
    endloop
endfunction
// НЕОБХОДИМ ДЛЯ РАБОТЫ СПОСОБНОСТЕЙ!
Нестандартный участок кода
function GroupFilter takes nothing returns boolean
return GetWidgetLife(GetFilterUnit())>.405 and GetUnitAbilityLevel(GetFilterUnit(),'Aloc')==0
endfunction

function UnitDamageTargetEx takes unit whichUnit, widget target, real amount, boolean attack, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns nothing
set RegisterDamage=false
call UnitDamageTarget(whichUnit,target,amount,attack,ranged,attackType,damageType,weaponType)
set RegisterDamage=true
endfunction
А так же системы:
"CreepRespawnSystem" - после смерти воина идёт отсчет времени. По истечении отсчета будет создан враг того же типа, что и погибший на изначальном появлении последнего. Так же и герои. Герои будут воскрешены на месте стартовой локации игрока. Реализована с помощью переменных.
CreepRespawnSystem
globals
    constant real RespawnSystem_Interval=0.03125
    constant string RespawnSystem_SE_Death="Abilities\\Spells\\NightElf\\Blink\\BlinkTarget.mdl"
    constant string RespawnSystem_SE_Resp="Abilities\\Spells\\NightElf\\Blink\\BlinkCaster.mdl"

    integer array RespawnSystem_UnitId
    integer array RespawnSystem_Data
    unit array RespawnSystem_Hero
    player array RespawnSystem_Owner
    real array RespawnSystem_Time
    real array RespawnSystem_X
    real array RespawnSystem_Y
    real array RespawnSystem_Face
    integer RespawnSystem_MAX=0
    timer RespawnSystem_Timer=CreateTimer()

    real array RS_X
    real array RS_Y
    real array RS_F
    integer RS_I=0
endglobals

function RespawnSystem_Periodic takes nothing returns nothing
    local integer i=0
    local unit u=null
    local group g=null
    local integer count=0
    local unit t=null
        loop
            exitwhen i == RespawnSystem_MAX
            if RespawnSystem_Time[i]>0.0 and (RespawnSystem_Hero[i]!=null or RespawnSystem_UnitId[i]!=0) then
                set g=CreateGroup()
                call GroupEnumUnitsInRange(g,RespawnSystem_X[i],RespawnSystem_Y[i],1200,Filter(function GroupFilter))
                loop
                    set t=FirstOfGroup(g)
                    exitwhen t==null
                    if IsUnitEnemy(t,RespawnSystem_Owner[i]) and IsUnitType(t,UNIT_TYPE_STRUCTURE) then
                        set count=count+1
                    endif
                    call GroupRemoveUnit(g,t)
                endloop
                if count==0 then
                    set RespawnSystem_Time[i]=RespawnSystem_Time[i] - RespawnSystem_Interval
                endif
                set count=0
                call DestroyGroup(g)
                set g=null
            else
                if RespawnSystem_Hero[i]!=null then
                    call ReviveHero(RespawnSystem_Hero[i],RespawnSystem_X[i],RespawnSystem_Y[i],true)
                else
                    set u=CreateUnit(RespawnSystem_Owner[i],RespawnSystem_UnitId[i],RespawnSystem_X[i],RespawnSystem_Y[i],RespawnSystem_Face[i])
                    call SetUnitUserData(u, RespawnSystem_Data[i])
                    call DestroyEffect(AddSpecialEffect(RespawnSystem_SE_Resp,RespawnSystem_X[i],RespawnSystem_Y[i]))
                endif
                set RespawnSystem_MAX = RespawnSystem_MAX - 1
                set RespawnSystem_Time[i] = RespawnSystem_Time[RespawnSystem_MAX]
                set RespawnSystem_X[i] = RespawnSystem_X[RespawnSystem_MAX]
                set RespawnSystem_Y[i] = RespawnSystem_Y[RespawnSystem_MAX]
                set RespawnSystem_Owner[i] = RespawnSystem_Owner[RespawnSystem_MAX]
                set RespawnSystem_Hero[i] = RespawnSystem_Hero[RespawnSystem_MAX]
                set RespawnSystem_UnitId[i] = RespawnSystem_UnitId[RespawnSystem_MAX]
                set RespawnSystem_Face[i] = RespawnSystem_Face[RespawnSystem_MAX]
                set RespawnSystem_Data[i] = RespawnSystem_Data[RespawnSystem_MAX]
                set RespawnSystem_Owner[RespawnSystem_MAX]=null
                set RespawnSystem_Hero[RespawnSystem_MAX]=null
                set RespawnSystem_UnitId[RespawnSystem_MAX]=0
                set RespawnSystem_Time[RespawnSystem_MAX]=.0
                set RespawnSystem_X[RespawnSystem_MAX]=.0
                set RespawnSystem_Y[RespawnSystem_MAX]=.0
                set RespawnSystem_Face[RespawnSystem_MAX]=.0
                set RespawnSystem_Data[RespawnSystem_MAX]=0
                set i = i - 1
                if (0 == RespawnSystem_MAX) then
                    call PauseTimer(RespawnSystem_Timer)
                endif
            endif
            set i = i + 1
        endloop
        
    set u=null
    set t=null
endfunction

function Trig_Creep_Respawn_Actions takes nothing returns nothing
    local unit u=GetTriggerUnit()
    
    if GetUnitAbilityLevel(u,'Aloc')==0 then
        if RespawnSystem_MAX==0 then
            call TimerStart(RespawnSystem_Timer,RespawnSystem_Interval, true, function RespawnSystem_Periodic)
        endif
        if IsUnitType(u,UNIT_TYPE_HERO) then
            set RespawnSystem_Hero[RespawnSystem_MAX]=u
            set RespawnSystem_X[RespawnSystem_MAX]=GetStartLocationX(GetPlayerStartLocation(GetOwningPlayer(u)))
            set RespawnSystem_Y[RespawnSystem_MAX]=GetStartLocationY(GetPlayerStartLocation(GetOwningPlayer(u)))
        else
            set RespawnSystem_UnitId[RespawnSystem_MAX]=GetUnitTypeId(u)
            set RespawnSystem_Owner[RespawnSystem_MAX]=GetOwningPlayer(u)
            set RespawnSystem_Data[RespawnSystem_MAX]=GetUnitUserData(u)
            set RespawnSystem_Face[RespawnSystem_MAX]=RS_F[GetUnitUserData(u)]
            set RespawnSystem_X[RespawnSystem_MAX]=RS_X[GetUnitUserData(u)]
            set RespawnSystem_Y[RespawnSystem_MAX]=RS_Y[GetUnitUserData(u)]
            call DestroyEffect(AddSpecialEffect(RespawnSystem_SE_Death,GetUnitX(u),GetUnitY(u)))
        endif
        set RespawnSystem_Time[RespawnSystem_MAX]=15.
        set RespawnSystem_MAX=RespawnSystem_MAX+1
    endif
    
    set u=null
endfunction

function Trig_Init_CreepRespawnSystem takes nothing returns nothing
    call SetUnitUserData(GetEnumUnit(),RS_I)
    set RS_X[RS_I]=GetUnitX(GetEnumUnit())
    set RS_Y[RS_I]=GetUnitY(GetEnumUnit())
    set RS_F[RS_I]=GetUnitFacing(GetEnumUnit())
    set RS_I=RS_I+1
endfunction
//===========================================================================
function InitTrig_CreepRespawnSystem takes nothing returns nothing
    local integer index=0
    local group g=CreateGroup()
    set RS_I=0
    
    call GroupEnumUnitsOfPlayer(g,Player(1),Filter(function GroupFilter))
    call ForGroup(g,function Trig_Init_CreepRespawnSystem)
    set gg_trg_CreepRespawnSystem=CreateTrigger()
    loop
        call TriggerRegisterPlayerUnitEvent(gg_trg_CreepRespawnSystem,Player(index),EVENT_PLAYER_UNIT_DEATH,null)
        set index=index+1
        exitwhen index == 16
    endloop
    call TriggerAddAction(gg_trg_CreepRespawnSystem, function Trig_Creep_Respawn_Actions)
    
    call DestroyGroup(g)
    set g=null
endfunction
"setAttribute" - библиотека благодаря, которой добавляется скорость атаки для способности "Пыл". Имеется возможность добавить урон и прочие характеристики с помощью способностей предметов, но необходимо внести соответствующие изменения в библиотеку. Реализована с помощью хеш-таблицы.
setAttribute
library setAttribute initializer Initialization
    globals
//===================================
//                 Настройки. Читать.
//--------------------------------------------------
//     Библиотека предоставляет следующие возможности:
//----------------------------------------------
//
//   - Возможность контролировать скорость атаки юнитов
//     [function SetUnitAttackSpeed takes unit u, real ammount] - Задаёт скорость атаки
//     [function AddUnitAttackSpeed takes unit u, real ammount] - Добавляет скорость атаки
//     [function GetUnitAttackSpeed takes unit u, real ammount] - Возвращает скорость атаки
//
//----------------------------------
      
//  Замените [Hash] на название вашей хеш-таблицы (CTRL+H)
//	Массивы нужно настроить!!! Они находятся в блоке [Initialization] в конце этого триггера. Необходимо заменить ['as00'] и подобные на ваши коды способок с соответствующими данными:
//	['as00'] - Уровень 1 = +0.01	Уровень 2 = -0.01
//	['as01'] - Уровень 1 = +0.02	Уровень 2 = -0.02
//	['as02'] - Уровень 1 = +0.04	Уровень 2 = -0.04
//	['as03'] - Уровень 1 = +0.08	Уровень 2 = -0.08
//	и т.д.
        private constant integer HASH_ATTACK_SPEED_INDEX=1
//Данные о текущем бонусе к скорости атаки будут хранится в хэш-таблице за хендлом юнита, под этим ключём

        private integer array abilityAttackSpeed
//Массив способностей  для повышения скорости атаки

        private integer AttackSpeedMAX=0
        private integer AttackSpeedValueMAX=0
      
    endglobals

//  Узнать бонус к скорости атаки
    function GetUnitAttackSpeed takes unit u returns real
        local integer iD=GetHandleId(u)
        local real ammount=LoadReal(Hash,iD,HASH_ATTACK_SPEED_INDEX)
        return ammount
    endfunction
//   Задать скорость атаки
    function SetUnitAttackSpeed takes unit u, real ammount returns nothing
        local integer iD=GetHandleId(u)
        local integer power=AttackSpeedMAX
        local integer index=0
        local integer rest
        if ammount>AttackSpeedValueMAX then
            set ammount=AttackSpeedValueMAX
        elseif ammount<-AttackSpeedValueMAX then
            set ammount=-AttackSpeedValueMAX
        endif
        loop
            call UnitRemoveAbility(u,abilityAttackSpeed[index])
        exitwhen index==AttackSpeedMAX
            set index=index+1
        endloop
        set rest=R2I(ammount)
        if ammount<0 then
            set rest=-rest
        endif
        loop
        exitwhen rest<=0
            if R2I(Pow(2,power))>rest then
                set power=power-1
            elseif R2I(Pow(2,power))<=rest then
                call UnitAddAbility(u,abilityAttackSpeed[power])
                if ammount<0 then
                    call SetUnitAbilityLevel(u,abilityAttackSpeed[power],2)
                endif
                call UnitMakeAbilityPermanent(u,true,abilityAttackSpeed[power])
                set rest=rest-R2I(Pow(2,power))
                set power=power-1
            endif
        endloop
        call SaveReal(Hash,iD,HASH_ATTACK_SPEED_INDEX,ammount)
    endfunction
//  Добавить скорость атаки
    function AddUnitAttackSpeed takes unit u, real ammount returns nothing
        set ammount=ammount+GetUnitAttackSpeed(u)
        call SetUnitAttackSpeed(u,ammount)
    endfunction

    private function Initialization takes nothing returns nothing
        local unit u=CreateUnit(Player(15),'hpea',.0,.0,.0)
        local integer i
        //	Массивы нужно настроить!!!
        set abilityAttackSpeed[0]='as00'
        set abilityAttackSpeed[1]='as01'
        set abilityAttackSpeed[2]='as02'
        set abilityAttackSpeed[3]='as03'
        set abilityAttackSpeed[4]='as04'
        set abilityAttackSpeed[5]='as05'
        set abilityAttackSpeed[6]='as06'
        set abilityAttackSpeed[7]='as07'
        set abilityAttackSpeed[8]='as08'
        set abilityAttackSpeed[9]='as09'
        set AttackSpeedMAX=9
        set AttackSpeedValueMAX=1
        set i=AttackSpeedMAX
        loop
            call UnitAddAbility(u,abilityAttackSpeed[i])
            call UnitRemoveAbility(u,abilityAttackSpeed[i])
            set AttackSpeedValueMAX=AttackSpeedValueMAX+AttackSpeedValueMAX*2
            set i=i-1
            exitwhen i==0
        endloop
    
        call RemoveUnit(u)
        set u=null
    endfunction
endlibrary
`
ОЖИДАНИЕ РЕКЛАМЫ...
4
32
6 лет назад
4
Довольно интересный способ реализации детекта физ урон, правда будет баговать с абилками типа "Жар приесподней", ну и для дальнего боя приказы не применимы, в среднем 0.25-0.40 сек. задержка между замахом и вылетом снаряда.
На основе рунных браслетов более надежно.
0
4
6 лет назад
0
Добрый день. Благодарю за комментарий.
quq_CCCP:
будет баговать с абилками типа "Жар приесподней"
Дополню - баги сто пудов будут с орб эффектами и любыми способностями (эффектами) с ежесекундным уроном. Поэтому любой урон приходится делать кодом. Мне подобная "фича" известна.
За упоминание отдельное спасибо. В самой карте никак не проинформировал. Мой косяк...
ну и для дальнего боя приказы не применимы, в среднем 0.25-0.40 сек. задержка между замахом и вылетом снаряда.
Никогда не любил дальний бой за его успешное извивание от отлова урона ;)
Очень муторно искать решение проблемы и я не утруждал себя поиском решений. Думаю, в ближайшее время этим не буду заниматься.
Есть готовое решение отлова урона, которое обладает GUI помощью от автора Bribe. Он "ошивается" на сайте, да простят меня модераторы, hiveworkshop. Как раз у него отлов срабатывает через способность рунных браслетов. Признаться честно, я использовал его работу уже в своих работах давно, но, что не своё, то не радует глаз, поэтому решился и на свои наработки.
Сия карту можно использовать как для начала кодирования на vJass и Jass в целом... Хоть подобных ресурсов море, но лишним не будет подобная информация.
4
32
6 лет назад
4
Ну как по мне - детект урона рунными браслетами самое то, если не юзать мемхак.
Правда на хайве автор сделал фигню - вроде б.д резистов, бред. Вручаем рунные браслеты и смотрим на урон, если урон выше 0 - это физический урон или клиф (клиф отлавливают точно так же как и ты атака+приказы), если урон ниже нуля - он будет хилить юнита, если у юнита фулл хп, тогда можно не парится и через 1 фрейм (таймер на 0.00 сек.), иначе нам нужно снизить юниту хп на кол-во отрец урона, чтобы избавится от хила, а потом умножаем наш урона на -1.34 если цель герой чтобы получить изначальное кол-во маг урона.
Удаляем у юнита резист, ставим флаг (глобалку как у тебя) чтобы триггер не сработал на этот урон и наносим урон, потом снова врубаем резист, таким образом мы не нарушаем систему дефольтных маг резистов и маг бонусов от благословения элуны и от атсрала.
Нет никаких баз данных и прочее, при дальнем бое лучше проверять что цель умерла -TriggerRegisterDeathEvent() именно этим событием, у цели может быть крест перерождения и аналоги, а только это событие срабатывает на смерть с крестом перерождения, особенно полезно для снятия дебафов - т.к это событие сработает при падении хп до нуля, за фрейм до того как юнит умрет и станет не выбираемым и не активным.
Это событие используется во внутриигровых триггерах (все баффы\дебафы такие триггеры) чтобы снимать к примеру оглушения.
Так же на детекте урона можно сделать удобную систему снарядов, двигать дамиков мутарно а сделать им норм анимацию и параболическую траекторию и вовсе куча кода, а так берем аксид бомбу и ждем её баффа с уроном на цели от лица кастера и все =)
Удачи в начинаниях.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.