В текущей карте продемонстрированы следующие способности:
"Пыл" ("Fervor") - Воин, освоивший эту способность, увеличивает скорость атаки за каждую атаку по врагу, однако если атаковать другую цель счетчик обнуляется. Реализована с помощью хеш-таблицы.
"Пыл" ("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" - после смерти воина идёт отсчет времени. По истечении отсчета будет создан враг того же типа, что и погибший на изначальном появлении последнего. Так же и герои. Герои будут воскрешены на месте стартовой локации игрока. Реализована с помощью переменных.
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
На основе рунных браслетов более надежно.
quq_CCCP:
За упоминание отдельное спасибо. В самой карте никак не проинформировал. Мой косяк...
Очень муторно искать решение проблемы и я не утруждал себя поиском решений. Думаю, в ближайшее время этим не буду заниматься.
Правда на хайве автор сделал фигню - вроде б.д резистов, бред. Вручаем рунные браслеты и смотрим на урон, если урон выше 0 - это физический урон или клиф (клиф отлавливают точно так же как и ты атака+приказы), если урон ниже нуля - он будет хилить юнита, если у юнита фулл хп, тогда можно не парится и через 1 фрейм (таймер на 0.00 сек.), иначе нам нужно снизить юниту хп на кол-во отрец урона, чтобы избавится от хила, а потом умножаем наш урона на -1.34 если цель герой чтобы получить изначальное кол-во маг урона.
Удаляем у юнита резист, ставим флаг (глобалку как у тебя) чтобы триггер не сработал на этот урон и наносим урон, потом снова врубаем резист, таким образом мы не нарушаем систему дефольтных маг резистов и маг бонусов от благословения элуны и от атсрала.
Нет никаких баз данных и прочее, при дальнем бое лучше проверять что цель умерла -TriggerRegisterDeathEvent() именно этим событием, у цели может быть крест перерождения и аналоги, а только это событие срабатывает на смерть с крестом перерождения, особенно полезно для снятия дебафов - т.к это событие сработает при падении хп до нуля, за фрейм до того как юнит умрет и станет не выбираемым и не активным.
Это событие используется во внутриигровых триггерах (все баффы\дебафы такие триггеры) чтобы снимать к примеру оглушения.
Так же на детекте урона можно сделать удобную систему снарядов, двигать дамиков мутарно а сделать им норм анимацию и параболическую траекторию и вовсе куча кода, а так берем аксид бомбу и ждем её баффа с уроном на цели от лица кастера и все =)
Удачи в начинаниях.