Добавлен , опубликован
чел попросил меня сделать какой-нибудь пример работы с библиотекой на вджассе, ну я и сделал какое-то простенькое дерьмище, на пожрать сойдёт
сам я о вджассе мало чего знаю, тем более о работе с библиотеками, так что вряд ли смог бы раскрыть все краски, карта с видосом в комментах
`
ОЖИДАНИЕ РЕКЛАМЫ...
1
27
3 года назад
1
раскрыть
library mylib initializer init // initializer (с англ.) инициализирует, в нашем случае оно инициализирует функцию init в самом низу
globals
    private constant hashtable H = InitHashtable() // константные переменные - те, что по коду не должны изменяться, то есть если где-то попытаешься задать другое значение этой переменной - выдаст ошибку
    private constant group TempG = CreateGroup()
    private group TempG1
    private real TempR
    
    private real MaxX // значения этим переменным присваиваются в функции инициализации
    private real MinX
    private real MaxY
    private real MinY
    
    // приставки private нужны, чтобы не конфликтовать с функциями извне библиотеки, удобно для импорта в чужую карту
endglobals

native UnitAlive takes unit id returns boolean // объявление нативной функции проверки жив ли юнит, находящаяся в common.j

function DBC takes real x, real y, real x1, real y1 returns real //Distance Between Coordinates (DBC)
   return SquareRoot((x-x1)*(x-x1)+(y-y1)*(y-y1)) 
endfunction

private function SetUnitPositionEx takes unit u, real x, real y returns nothing // самодельная функция перемещения юнита, тут проверяются координаты, чтобы они не выходили за границу карты и не крашнули игру
    if x > MaxX then
        set x = MaxX
    elseif x < MinX then
        set x = MinX
    endif
    if y > MaxY then
        set y = MaxY
    elseif y < MinY then
        set y = MinY
    endif
    call SetUnitX(u,x)
    call SetUnitY(u,y)
endfunction

private struct mys // структура это такая таблица данных, при компиляции это всё превращается в обычные глобальные переменные
    unit caster // применяющий
    unit dummy // дамми
    real damage // урон
    real speed // скорость
    real radius // радиус
    real angle // угол
    real distance // дистанция
    group g // группа юнитов, которые получили урон
    boolean b // нужно для разовой очистки группы получивших урон
    
    method Destroy takes nothing returns nothing // методы - функции используемые в структурах, в нашем случае при уничтожении удаляется даммик с группой и обнуляются переменные
        call KillUnit(this.dummy)
        call GroupClear(this.g)
        call DestroyGroup(this.g)
        set this.caster = null
        set this.dummy = null
        set this.g = null
        call this.destroy()
    endmethod
endstruct

private function DamageCond takes nothing returns boolean
    set bj_lastReplacedUnit = GetFilterUnit()
    if not IsUnitInGroup(bj_lastReplacedUnit,TempG1) and UnitAlive(bj_lastReplacedUnit) and IsUnitEnemy(bj_lastReplacedUnit,GetOwningPlayer(bj_lastCreatedUnit)) then
        call UnitDamageTarget(bj_lastCreatedUnit,bj_lastReplacedUnit,TempR,false,false,null,null,null)
        call DestroyEffect(AddSpecialEffectTarget("Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl",bj_lastReplacedUnit,"chest"))
        call GroupAddUnit(TempG1,bj_lastReplacedUnit)
    endif
    return false
endfunction

private function move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local mys A = LoadInteger(H,GetHandleId(t),0)
    local real x = GetUnitX(A.dummy)
    local real y = GetUnitY(A.dummy)
    
    if A.distance > 0 then // если юнит не достиг конечной точки, то двигать к ней
        set A.distance = A.distance-A.speed
    else // иначе сменить угол и двигать к кастеру
        call SetUnitFacing(A.dummy,Atan2(GetUnitY(A.caster)-y,GetUnitX(A.caster)-x)*bj_RADTODEG)
        set A.angle = GetUnitFacing(A.dummy)*bj_DEGTORAD
        
        if A.b then // очистить группу получивших урон
            set A.b = false
            call GroupClear(A.g)
        endif
    endif
    set x = x+A.speed*Cos(A.angle)
    set y = y+A.speed*Sin(A.angle)
    call SetUnitPositionEx(A.dummy,x,y)
    
    set TempG1 = A.g
    set TempR = A.damage
    set bj_lastCreatedUnit = A.caster
    call GroupEnumUnitsInRange(TempG,x,y,A.radius,Condition(function DamageCond))
    
    if A.distance <= 0 and DBC(x,y,GetUnitX(A.caster),GetUnitY(A.caster)) <= 50. then
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        call A.Destroy() // вызываем метод уничтожения этой структуры
    endif
    
    set t = null
endfunction

private function myfunc takes nothing returns nothing
    local timer t = CreateTimer()
    local mys A = mys.create() // таким образом объявляется структура. А - название, к которому мы будем обращаться, а mys - название структуры, которую хотим создать
    local integer lvl
    local real x
    local real y
    local real sc
    
    set A.g = CreateGroup()
    set A.caster = GetTriggerUnit()
    set x = GetUnitX(A.caster)
    set y = GetUnitY(A.caster)
    set A.angle = Atan2(GetSpellTargetY()-y,GetSpellTargetX()-x)
    set lvl = GetUnitAbilityLevel(A.caster,'A000')
    set A.dummy = CreateUnit(GetOwningPlayer(A.caster),'u000',x,y,A.angle*bj_RADTODEG)
    call SetUnitPathing(A.dummy,false)
    call UnitAddAbility(A.dummy,'Arav')
    call SetUnitPositionEx(A.dummy,x+50*Cos(A.angle),y+50*Sin(A.angle)) // если юниту что-то помешало заспавниться строго так, как задумано - переместить его в нужную точку
    call SetUnitFlyHeight(A.dummy,50,0)
    
    if     lvl == 1 then // в зависимости от уровня способности определить параметры
        set A.damage = 50.
        set A.speed = 10.
        set A.radius = 100.
        set A.distance = 400.
        set sc = 1.
    elseif lvl == 2 then
        set A.damage = 75.
        set A.speed = 12.
        set A.radius = 150.
        set A.distance = 500.
        set sc = 1.5
    elseif lvl == 3 then
        set A.damage = 130.
        set A.speed = 17.
        set A.radius = 225.
        set A.distance = 700.
        set sc = 2.25
    endif
    set A.damage = A.damage+GetHeroStr(A.caster,true)
    
    call SetUnitScale(A.dummy,sc,sc,sc)
    call SaveInteger(H,GetHandleId(t),0,A) // сохраняем структуру в таймер, структура на самом деле это целочисленная
    call TimerStart(t,.02,true,function move)
    set t = null
endfunction

private function mycond takes nothing returns boolean
    if GetSpellAbilityId() == 'A000' then
        call myfunc()
    endif
    return false
endfunction
private function init takes nothing returns nothing
    local trigger t = CreateTrigger()

    call TriggerRegisterPlayerUnitEvent(t,Player(0x00),EVENT_PLAYER_UNIT_SPELL_EFFECT,null)
    call TriggerAddCondition(t,Condition(function mycond))
    
    set MaxX = GetRectMaxX(GetWorldBounds()) // задаём значения глобалкам, чтобы юнит не мог вылететь за карту и не крашнул нам игру
    set MaxY = GetRectMaxY(GetWorldBounds())
    set MinX = GetRectMinX(GetWorldBounds())
    set MinY = GetRectMinY(GetWorldBounds())

    set t = null
endfunction
endlibrary

library mylib1 initializer init // либа для показа урона
globals
    private trigger trg = CreateTrigger()
endglobals
private function myfunc takes nothing returns boolean
    local texttag t = CreateTextTag()
    
    call SetTextTagText(t,I2S(R2I(GetEventDamage())),10*0.023/10)
    call SetTextTagVelocity(t,64*0.071/128*Cos(90*bj_DEGTORAD),64*0.071/128*Sin(90*bj_DEGTORAD))
    call SetTextTagColor(t,255,0,255,255)
    call SetTextTagPosUnit(t,GetTriggerUnit(),0)
    call SetTextTagPermanent(t,false)
    call SetTextTagLifespan(t,.5)
    call SetTextTagFadepoint(t,0.)
    
    set t = null
    return false
endfunction
private function mycond takes nothing returns boolean
    call TriggerRegisterUnitEvent(trg,GetFilterUnit(),EVENT_UNIT_DAMAGED)
    return false
endfunction
private function init takes nothing returns nothing
    local group g = CreateGroup()
    call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,Condition(function mycond))
    call DestroyGroup(g)
    call TriggerAddCondition(trg,Condition(function myfunc))
    set g = null
endfunction
endlibrary



library HC initializer init // счётчик хэндлов чтобы понимать наличие утечек
    globals
    private leaderboard HB
    endglobals
    private function HCU takes nothing returns nothing
        local integer i = 0
        local integer id
        local location array P
        local real result = 0
        loop
            exitwhen i >= 50
            set i = i+1
            set P[i] = Location(0,0)
            set id = GetHandleId(P[i])
            set result = result+(id-0x100000)
        endloop
        set result = result/i-i/2
        loop
            call RemoveLocation(P[i])
            set P[i] = null
            exitwhen i <= 1
            set i = i-1
        endloop
        call LeaderboardSetItemValue(HB,0,R2I(result))
    endfunction

    private function HCA takes nothing returns nothing
        set HB = CreateLeaderboard()
        call LeaderboardSetLabel(HB,"Handle Counter")
        call PlayerSetLeaderboard(GetLocalPlayer(),HB)
        call LeaderboardDisplay(HB,true)
        call LeaderboardAddItem(HB,"Handles",0,Player(0))
        call LeaderboardSetSizeByItemCount(HB,1)
        call HCU()
        call TimerStart(GetExpiredTimer(),.05,true,function HCU)
    endfunction

    private function init takes nothing returns nothing
        call TimerStart(CreateTimer(),0,false,function HCA)
    endfunction
endlibrary
Загруженные файлы
Чтобы оставить комментарий, пожалуйста, войдите на сайт.