Добавлен , опубликован
Решил изучить сферические координаты, результатом более менее доволен, но код как всегда говно, карта с видосом в комментах
`
ОЖИДАНИЕ РЕКЛАМЫ...
10
27
3 года назад
10
говнокод

library mylib
globals
private location LFZ = Location(0,0)
private constant hashtable H = InitHashtable()
private constant real UnitHeight = 80.
private constant integer AbilityWeight = 'A001' // прочность
private constant integer AbilityWeight1 = 'A003' // вес
private constant integer WeaponNumberNot = 0 // Неиспользуемый номер оружия
private group TempG = CreateGroup()
private group TempG1 = null
private real TempR = 0.
private real TempR1 = 0.
private real TempR2 = 0.
private real TempR3 = 0.
private real TempR4 = 0.
private integer TempI = 0
private integer TempI1 = 0
private integer TempI2 = 0
endglobals
private function GetLocZ takes real x, real y returns real
    call MoveLocation(LFZ,x,y)
    return GetLocationZ(LFZ)
endfunction

private function DBC takes real x, real y, real x1, real y1 returns real
   return SquareRoot((x-x1)*(x-x1)+(y-y1)*(y-y1)) 
endfunction 

private function SetUnitPositionEx takes unit u, real x, real y returns nothing
    local item i = CreateItem('spsh',x,y)
    local real x1 = GetItemX(i)
    local real y1 = GetItemY(i)
    if DBC(x,y,x1,y1) > 10 then
        set x = x1
        set y = y1
    endif
    call SetUnitX(u,x)
    call SetUnitY(u,y)
    call RemoveItem(i)
    set i = null
endfunction
//==========================================
private struct Bullet
    unit caster
    unit bullet
    real angle
    
    real damage
    integer AttackType
    integer DamageType
    integer bulletArmCount
    integer WeaponNum
    
    real speed
    real speedz
    real distance
    
    real radius
    real radiusZ
    
    real discarding
    real tmDiscarding
    real dsPeriodic
    
    effect Effect
    group Group
endstruct
private struct BulletInfo
    unit caster
    real angle
    real dist
    real z

    real mindamage
    real maxdamage
    integer AttackType
    integer DamageType
    integer bulletCount
    integer bulletArmCount
    integer WeaponNum
    
    real speed
    real distance
    real tmPeriodic
    
    real spreading
    real spreadingZ
    
    real radius
    real radiusZ
    
    real blsPeriodic
    
    real atkOffset
    real atkOffsetZ
    real atkOffsetDist
    
    real discarding
    real tmDiscarding
    real dsPeriodic
    
    string Effect
endstruct

private function DmgCond takes nothing returns boolean
    local real fly
    local real fl
    local boolean b
    local boolean b1
    set bj_lastReplacedUnit = GetFilterUnit()
    set b1 = not IsUnitInGroup(bj_lastReplacedUnit,TempG1) and not (IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_DEAD) or GetUnitTypeId(bj_lastReplacedUnit) < 1) and IsUnitEnemy(bj_lastReplacedUnit,GetOwningPlayer(bj_lastCreatedUnit)) and TempI2 > 0
    if b1 then
        set fly = GetUnitFlyHeight(bj_lastReplacedUnit)+UnitHeight
        set fl = GetLocZ(GetUnitX(bj_lastReplacedUnit),GetUnitY(bj_lastReplacedUnit))
        if fl < 0 and IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_FLYING) then
            set fly = fly-UnitHeight+(RAbsBJ(fl)*2)
        endif
        if IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_FLYING) then
            set fly = fly-UnitHeight
        endif
        //BJDebugMsg(R2S(fly))
        //BJDebugMsg(R2S(TempR))
        set b = TempR <= fly+TempR1 and TempR >= fly-TempR1
        if b then
            set TempI2 = TempI2-GetUnitAbilityLevel(bj_lastReplacedUnit,AbilityWeight)
        endif
    endif
    return b1 and b
endfunction
private function Discarding takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local unit u = LoadUnitHandle(H,i,0)
    local real a = LoadReal(H,i,4)
    local real sp = LoadReal(H,i,1)
    local real tm = LoadReal(H,i,2)-LoadReal(H,i,3)
    
    call SetUnitPositionEx(u,GetUnitX(u)+sp*Cos(a),GetUnitY(u)+sp*Sin(a))
    
    if tm <= 0. then
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(H,i)
    else
        call SaveReal(H,i,2,tm)
    endif
    
    set t = null
    set u = null
endfunction
private function Dmg takes nothing returns nothing
    local timer t
    local integer i
    local unit u = GetEnumUnit()
    call GroupAddUnit(TempG1,u)
    call UnitDamageTarget(bj_lastCreatedUnit,u,TempR,false,false,ConvertAttackType(TempI),ConvertDamageType(TempI1),null)
    if not IsUnitType(u,UNIT_TYPE_DEAD) and TempR1 > 0. and GetUnitAbilityLevel(u,AbilityWeight1) > 0 then
        set t = CreateTimer()
        set i = GetHandleId(t)
        call SaveUnitHandle(H,i,0,u)
        call SaveReal(H,i,1,TempR1*(GetUnitAbilityLevel(u,AbilityWeight1)*.1))
        call SaveReal(H,i,2,TempR2)
        call SaveReal(H,i,3,TempR3)
        call SaveReal(H,i,4,TempR4)
        call TimerStart(t,TempR3,true,function Discarding)
        set t = null
    endif
    set u = null
endfunction

private function Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local Bullet A = LoadInteger(H,GetHandleId(t),0)
    local real x  = GetUnitX(A.bullet)
    local real y  = GetUnitY(A.bullet)
    local real z  = GetUnitFlyHeight(A.bullet)+GetLocZ(x,y)
    local real zun
    local boolexpr b = Condition(function DmgCond)
    
    set x = x+Cos(A.angle)*Cos(A.speedz)*A.speed
    set y = y+Sin(A.angle)*Cos(A.speedz)*A.speed
    set zun = (z+A.speed*Sin(A.speedz))-GetLocZ(x,y)
    
    call SetUnitX(A.bullet,x)
    call SetUnitY(A.bullet,y)
    call SetUnitFlyHeight(A.bullet,zun,0.)

    set TempR = zun
    set bj_lastCreatedUnit = A.caster
    set TempR1 = A.radiusZ
    set TempI2 = A.bulletArmCount
    set TempG1 = A.Group
    call GroupEnumUnitsInRange(TempG,x,y,A.radius,b)
    if FirstOfGroup(TempG) != null then
        set TempR = A.damage
        set TempR1 = A.discarding
        set TempR2 = A.tmDiscarding
        set TempR3 = A.dsPeriodic
        set TempR4 = A.angle
        set TempI = A.AttackType
        set TempI1 = A.DamageType
        set udg_TF = A.WeaponNum
        call ForGroup(TempG,function Dmg)
        set udg_TF = WeaponNumberNot
        call GroupClear(TempG)
    endif

    set A.distance = A.distance-A.speed
    set A.bulletArmCount = TempI2
    
    if zun <= 0.00 or A.distance <= 0. or A.bulletArmCount <= 0 or (x+A.speed >= GetRectMaxX(bj_mapInitialPlayableArea) or x-A.speed <= GetRectMinX(bj_mapInitialPlayableArea) or y+A.speed >= GetRectMaxY(bj_mapInitialPlayableArea) or y-A.speed <= GetRectMinY(bj_mapInitialPlayableArea)) then
        
        call KillUnit(A.bullet)
        call DestroyEffect(A.Effect)
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        
        call A.destroy()
        
        set A.caster = null
        set A.bullet = null
        set A.angle = 0.
    
        set A.damage = 0.
        set A.AttackType = 0
        set A.DamageType = 0
        set A.bulletArmCount = 0
        set A.WeaponNum = 0
        
        set A.speed = 0.
        set A.speedz = 0.
        set A.distance = 0.
        
        set A.radius = 0.
        set A.radiusZ = 0.
        
        set A.discarding = 0.
        set A.tmDiscarding = 0.
        set A.dsPeriodic = 0.
        
        call GroupClear(A.Group)
        call DestroyGroup(A.Group)
        set A.Group = null
    endif
    
    set t = null
    set TempG1 = null
endfunction

private function Create takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local timer t1 = CreateTimer()
    local integer i = GetHandleId(t1)
    local BulletInfo A = LoadInteger(H,GetHandleId(t),0)
    local Bullet A1 = Bullet.create()
    
    local real xu = GetUnitX(A.caster)
    local real yu = GetUnitY(A.caster)
    local real zu = GetLocZ(xu,yu)+GetUnitFlyHeight(A.caster)
   
    local real a  = A.angle+(GetRandomReal(-(A.spreading/2),A.spreading/2)*bj_DEGTORAD)
    local real xr = xu+A.atkOffsetDist*Cos(a+(A.atkOffset*bj_DEGTORAD))
    local real yr = yu+A.atkOffsetDist*Sin(a+(A.atkOffset*bj_DEGTORAD))
    local real zr = ((zu-GetLocZ(xr,yr))+A.atkOffsetZ)+GetLocZ(xr,yr)
    local real zs = Atan2(A.z-zr,A.dist)+(GetRandomReal(-(A.spreadingZ/2),A.spreadingZ/2)*bj_DEGTORAD)
    local unit r  = CreateUnit(GetOwningPlayer(A.caster),'u000',xr,yr,a*bj_RADTODEG)
    
    if zs*bj_RADTODEG > 90. then
        set zs = 90.*bj_DEGTORAD
    elseif zs*bj_RADTODEG < -90. then
        set zs = -90.*bj_DEGTORAD
    endif
    
    call SetUnitX(r,xr)
    call SetUnitY(r,yr)
    call UnitAddAbility(r,'Arav')
    call SetUnitFlyHeight(r,zr-GetLocZ(xr,yr),0.00)
    call SetUnitAnimationByIndex(r,R2I(zs*bj_RADTODEG)+90)
    
    set A1.caster = A.caster
    set A1.bullet = r
    set A1.angle = a
    
    set A1.damage = GetRandomReal(A.mindamage,A.maxdamage)
    set A1.AttackType = A.AttackType
    set A1.DamageType = A.DamageType
    set A1.bulletArmCount = A.bulletArmCount
    set A1.WeaponNum = A.WeaponNum
    
    set A1.speed = A.speed
    set A1.speedz = zs
    set A1.distance = A.distance
    
    set A1.radius = A.radius
    set A1.radiusZ = A.radiusZ
    
    set A1.discarding = A.discarding
    set A1.tmDiscarding = A.tmDiscarding
    set A1.dsPeriodic = A.dsPeriodic
    
    set A1.Effect = AddSpecialEffectTarget(A.Effect,r,"head")
    set A1.Group = CreateGroup()
    
    call SaveInteger(H,i,0,A1)
    call TimerStart(t1,A.tmPeriodic,true,function Move)
    //===================================
    set A.bulletCount = A.bulletCount-1
    
    if A.bulletCount <= 0 then
        call FlushChildHashtable(H,GetHandleId(t))
        call PauseTimer(t)
        call DestroyTimer(t)
        call A.destroy()
        
        set A.caster = null
        set A.angle = 0.
        set A.dist = 0.
        set A.z = 0.
    
        set A.mindamage = 0.
        set A.maxdamage = 0.
        set A.AttackType = 0
        set A.DamageType = 0
        set A.bulletCount = 0
        set A.bulletArmCount = 0
        set A.WeaponNum = 0
    
        set A.speed = 0.
        set A.distance = 0.
        set A.tmPeriodic = 0.
    
        set A.spreading = 0.
        set A.spreadingZ = 0.
    
        set A.radius = 0.
        set A.radiusZ = 0.
    
        set A.blsPeriodic = 0.
    
        set A.atkOffset = 0.
        set A.atkOffsetZ = 0.
        set A.atkOffsetDist = 0.
    
        set A.discarding = 0.
        set A.tmDiscarding = 0.
        set A.dsPeriodic = 0.
        
        set A.Effect = ""
    endif
    
    set r = null
    set t = null
    set t1 = null
endfunction

function Shoot takes nothing returns nothing
    local timer t = CreateTimer()
    local BulletInfo A = BulletInfo.create()
    local real x = GetSpellTargetX()
    local real y = GetSpellTargetY()
    local real z = GetLocZ(x,y)
    local real zu = GetLocZ(GetUnitX(udg_Unit[0]),GetUnitY(udg_Unit[0]))+GetUnitFlyHeight(udg_Unit[0])
    if udg_Unit[1] != null then
        set x = GetUnitX(udg_Unit[1])
        set y = GetUnitY(udg_Unit[1])
        if IsUnitType(udg_Unit[1],UNIT_TYPE_FLYING) then
            set z = GetLocZ(x,y)
            if z < 0 then
                set z = RAbsBJ(z)-UnitHeight
            else
                set z = z+UnitHeight
            endif
        else
            if z+udg_Real[9] >= zu-udg_Real[9] then
                set z = z+udg_Real[9]
            endif
        endif
        set z = z+GetUnitFlyHeight(udg_Unit[1])
    else
        if z+udg_Real[9] >= zu-udg_Real[9] then
            set z = z+udg_Real[9]
        endif
    endif
    
    set A.caster = udg_Unit[0]
    set A.angle = Atan2(y-GetUnitY(udg_Unit[0]),x-GetUnitX(udg_Unit[0]))
    set A.dist = DBC(GetUnitX(udg_Unit[0]),GetUnitY(udg_Unit[0]),x,y)
    set A.z = z
    
    set A.mindamage = udg_Real[0]
    set A.maxdamage = udg_Real[15]
    set A.AttackType = GetHandleId(udg_AttackType)
    set A.DamageType = GetHandleId(udg_DamageType)
    set A.bulletCount = udg_Int
    set A.bulletArmCount = udg_BulletArm
    set A.WeaponNum = udg_TF
    
    set A.speed = udg_Real[2]
    set A.distance = udg_Real[1]
    set A.tmPeriodic = udg_Real[5]
    
    set A.spreading = udg_Real[3]
    set A.spreadingZ = udg_Real[4]
    
    set A.radius = udg_Real[6]
    set A.radiusZ = udg_Real[7]
    
    set A.blsPeriodic = udg_Real[8]
    
    set A.atkOffset = udg_Real[11]
    set A.atkOffsetZ = udg_Real[9]
    set A.atkOffsetDist = udg_Real[10]
    
    set A.discarding = udg_Real[12]
    set A.tmDiscarding = udg_Real[13]
    set A.dsPeriodic = udg_Real[14]
    
    set A.Effect = udg_Effect
    
    call SaveInteger(H,GetHandleId(t),0,A)
    call TimerStart(t,udg_Real[8],true,function Create)
endfunction

endlibrary





library AINativesLib

native GetPlayerUnitTypeCount takes player p, integer unitid            returns integer

native GetUnitGoldCost      takes integer unitid                        returns integer
native GetUnitWoodCost      takes integer unitid                        returns integer
native GetUnitBuildTime     takes integer unitid                        returns integer

native UnitAlive            takes unit id                               returns boolean

endlibrary

library NegateDamageLib
globals
    private constant group Group = CreateGroup()
    private constant timer Timer = CreateTimer()
    
    // MUST BE SPECIFIED
    public constant integer MaxLifeBonusAbility = 'A002'
    public constant integer MaxLifeBonus = 1000000
endglobals

private function ProcessUnits takes nothing returns nothing
    local unit u
    local real life2set
    
    loop
        set u = FirstOfGroup(Group)
        exitwhen u == null
        call GroupRemoveUnit(Group, u)
        
        if UnitAlive(u) then
            set life2set = GetWidgetLife(u)
            call UnitRemoveAbility(u, MaxLifeBonusAbility)
            call SetWidgetLife(u, life2set)
        else
            call UnitRemoveAbility(u, MaxLifeBonusAbility)
        endif
    endloop
endfunction

function NegateDamage takes unit u, real negated returns nothing
    local real life = GetWidgetLife(u)
    call GroupAddUnit(Group, u)
    call UnitAddAbility(u, MaxLifeBonusAbility)
    call SetWidgetLife(u, life + negated)
    
    call TimerStart(Timer, 0., false, function ProcessUnits)
endfunction

function GetUnitMaxHealth takes unit u returns real
    return GetUnitState(u, UNIT_STATE_MAX_LIFE) - MaxLifeBonus * GetUnitAbilityLevel(u, MaxLifeBonusAbility)
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
Загруженные файлы
2
7
2 года назад
2
круто получилось
Чтобы оставить комментарий, пожалуйста, войдите на сайт.