Topic post, bàn luận, đóng góp ý kiến, thắc mắc, giải đáp, bình phẩm về Custom Spell.

  • Thread starter Thread starter raivor
  • Ngày gửi Ngày gửi
Cần giúp!Ai có thể làm giùm mình 4 kỹ năng tương tự vầy dc ko?(có map demo càng tốt)

1)Khi kích hoạt thì hero sẽ lướt tới lần lượt 5 unit gần đó(ưu tiên hero nếu dc) gây 1000/3500/5700/7400/8900 sát thương lên chúng,càng về sau càng mạnh (nghĩa là sát thương lên con phía sau sẽ mạh hơn con phía trước)

2)Khi bật chiêu lên,hero sẽ đứng yên và hồi một lượng máu tương đương với số giáp hiên có trong 10 giây.

3)Chiêu này khi bật lên thì sẽ nhận dc thêm 1000/1300/1700/1900/2000 dâmge và 10%/12%/15%/18%/20% tốc độ đánh trong vòng 7 giây

4)Chiêu này khi bật lên thì nhận dc 40%/50%/60% tốc độ chạy,40%/45%/50% tốc độ đánh,miễn kháng tấc cả các hiêu ứng trong 10 giây

Ai chơi LOL thì đây là chiêu của thằng Master Yi đó.Làm dc yc hang thì càng tốt,mình thanks trước.
 
t.jpg

Mã:
scope FireMassing initializer init
//>>>>>>>>>>>>>>>>>>>>>>>>>SETUP<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//
//Đây là phần cài đặt cho spell:
globals
    private constant integer SPELL_ID = 'A001'//ID của dummy ability mà bạn dùng, phải là 1 abi target ground hoặc target unit
    private constant integer DUMMY_UNIT_ID = 'e000'//cái này hình như thừa... cứ thử bỏ đi xem. Tại spell làm lâu rồi cũng chẳng nhớ LOL
    private constant integer EFF_UNIT_ID = 'e002'//Unit đóng vai trò missle
    private constant string EFF = "Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"//Hiệu ứng đặc biệt khi tên chạm enemy hoặc đã bay hết quãng đg cho phép
                                //"Abilities\\Weapons\\Rifle\\RifleImpact.mdl"
                                //"Abilities\\Spells\\Human\\SpellSteal\\SpellStealMissile.mdl"
                                //"Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl"
                                //"Abilities\\Spells\\Other\\Doom\\DoomDeath.mdl"
    
endglobals
//Advance:
private function speed takes nothing returns real
    return 0.01 //lager value, more slower (tốc độ của mũi tên, vì là time out của timer nên càng nhỏ thì mũi tên bay càng nhanh)
endfunction

private function range takes nothing returns real
    return 1500.00 //quãng đường tối đa ma mũi tên có thể bay
endfunction

private function radius takes nothing returns real
    return 100.00 //the radius for detecting collision (Bán kính phát hiện va chạm AOE/2 đó :)) )
endfunction

private function amount takes nothing returns integer
    return 10 //the numbers of arrow per cast (số lượng mũi tên)
endfunction

private function dam takes integer aLevel returns real
    return 100.00 * aLevel//dam per arrow (hàm tính dam dựa theo lvl skill)
endfunction

private function addOn takes unit trigUnit, unit dam2Unit returns nothing
    //this option is for advance user, you can add your code here to Make
    //more effect when the projectile impact to enemy. ex: knock back, dam over time... 

   // hàm này được gọi khi mũi tên va chạm với enemy, hàm này hiện để trống, muốn thêm cái gì vào đây thì thêm
   //à quên trigUnit là caster, dam2Unit là unit bị bắn trúng
endfunction

//>>>>>>>>>>>>>>>>>>>>>>>ENDSETUP<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<//

//=================Confuse zone==============//
//Dont edit this bunk of code unless you
//really wanna do
//Phần dưới này để thư thư rồi giải thích tiếp nhé :D
//===========================================//
globals
    private constant real MOVE = 10.0 //distance that the projectile will move Per
                                      //*speed()* . You should'nt change this
    private constant real deviation = 10.0 //deviation between projectile
endglobals




private struct Projectile
    unit u//projectile
    unit uT// trigger unit
    real angle
    real moved = 0
    
    boolean stop = false
    
    method control takes nothing returns nothing
        local location moveLoc = PolarProjectionBJ(GetUnitLoc(.u), MOVE, .angle)
        //valriable for collision detect:
        local group cGrp = GetUnitsInRangeOfLocAll(radius(),moveLoc)
        local unit uDam
        
        //move the unit(projectile)
        call SetUnitPositionLoc(.u,moveLoc)
        
        //collision detect and dam enemy:
        set uDam = FirstOfGroup(cGrp)
        if uDam != null then
        
            loop
                exitwhen uDam == null
                if IsUnitEnemy(uDam,GetOwningPlayer(.uT)) and IsUnitAliveBJ(uDam) then 
                    
                    call UnitDamageTargetBJ(.uT, uDam, dam(GetUnitAbilityLevel(.uT,SPELL_ID)),ATTACK_TYPE_MAGIC,DAMAGE_TYPE_MAGIC)
                    call addOn(.uT,uDam)
                    set .stop = true//need improve
                endif
                
                call GroupRemoveUnit(cGrp,uDam)
                
                set uDam = FirstOfGroup(cGrp)
            endloop
            
            
        endif
        
        
        //out of range detect:
        if .moved < range() then
            set .moved = .moved + MOVE//if still in range, then set the .moved value go up
        else 
            set .stop = true
        endif
        
        //play animation
        if .stop then
            call DestroyEffect(AddSpecialEffectLoc(EFF,moveLoc))
        endif
        
        //remove leak
        call RemoveLocation(moveLoc)
        call DestroyGroup(cGrp)
        set moveLoc = null
        set cGrp = null
        set uDam = null
    endmethod
    
    
endstruct

globals
    private integer Total = 0
    private timer T = CreateTimer()
    private Projectile array pArr
endglobals

                                  

private function timerLoop takes nothing returns nothing
    local integer i = 0
    loop
        exitwhen(i >= Total)
     
        if pArr[i].stop then
            call KillUnit(pArr[i].u)//kill the projectile to not display it any more
            call pArr[i].destroy()//Not need this instance any more
            set Total=Total-1//degrease the Total by 1
            if Total > 0 then
                set pArr[i]=pArr[Total]
                set i=i-1//if not the loops will forget to handle the pArr[Total] ^^
            else
                call PauseTimer(T)
            endif
        else
            call pArr[i].control()
        endif
        
    
        set i = i + 1
    endloop
 
    //call BJDebugMsg("yeah")
endfunction

//extra function for formula caculate:
private function angleCalculate takes real angle, integer iAddOne returns real
    local real result = 0
    //==========for div number of *amount()*:
    local real halfDev //deviation / 2
    local real cen1
    local real cen2
    local integer cen1Index
    local integer cen2Index
    //==========for odd number of *amount()*:
    local integer cenIndex
    local real cen
    
    //div:
    if ModuloInteger(amount(),2)==0 then
        //call BJDebugMsg("so chan")
        set halfDev = deviation/2
        set cen1 = angle - halfDev
        set cen2 = angle + halfDev
        set cen1Index = amount()/2
        set cen2Index = cen1Index + 1
        
        if iAddOne == cen1Index then
            set result = cen1
        elseif iAddOne < cen1Index then
            set result = cen1 - deviation*(cen1Index - iAddOne)
        elseif iAddOne == cen2Index then
            set result = cen2
        elseif iAddOne > cen2Index then
            set result = cen2 + deviation*(iAddOne - cen2Index)
        endif
        
        
    //odd:    
    else
        //call BJDebugMsg("so le")
        set cen = angle
        set cenIndex = ((amount() - 1)/2) + 1
        
        if iAddOne == cenIndex then
            set result = angle
        elseif iAddOne > cenIndex then
            set result = cen - (deviation*(iAddOne - cenIndex))
        else
            set result = cen + (deviation*(cenIndex - iAddOne))
        endif
    endif
    
    return result
endfunction

//====================end=====================//


//Condition================================================================
private function condition takes nothing returns boolean
    return GetSpellAbilityId() == SPELL_ID
endfunction

//Actions==================================================================


private function Actions takes nothing returns nothing
    local player pT =  GetOwningPlayer(GetTriggerUnit())
    local location tar = GetSpellTargetLoc()
    local location self = GetUnitLoc(GetTriggerUnit())
    local real deg = AngleBetweenPoints(self,tar)
    local Projectile p
    //
    local integer iPlus = 1
    

    
    if Total == 0 then
        call TimerStart (T, speed(), true, function timerLoop)
    endif
   
    //
    loop
    exitwhen iPlus > amount()
        set p = Projectile.create()
        set p.u = CreateUnitAtLoc(pT,EFF_UNIT_ID,self,angleCalculate(deg,iPlus))
        set p.angle = angleCalculate(deg,iPlus)
        set p.uT = GetTriggerUnit()
        
        //call BJDebugMsg(R2S(angleCalculate(deg,iPlus)))
        //call BJDebugMsg(I2S(Total))
        
        set pArr[Total] = p
        set Total = Total + 1
    
        set iPlus = iPlus + 1
    endloop
    
    //remove leak
    set pT = null
    call RemoveLocation(tar)
    call RemoveLocation(self)
    set tar = null
    set self = null
 
endfunction

//Initializer==============================================================
private function init takes nothing returns nothing
    local trigger t = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( t, function Actions )
    call TriggerAddCondition(t,Condition(function condition))
endfunction

endscope

demo map: http://dl.dropbox.com/u/14083092/Maper/Hero_FireRanger.w3x

Spell đơn giản thôi, bắn 1 lượng cung tùy ý ra phía trước. Có thể thêm bất cứ hiệu ứng nào vào unit bị trúng tên (dam over time hay knock back.... tùy) :D
Có gì giải thích sau nhé h đang bận với cái project

Vì mình ko nghiên cứu phần kỹ năng nên cho ình hỏi tý:
Mình mún chỉnh mũi tên bắn ra là mũi tên băng hoặc thường thì làm sao?
Thêm hiệu ứng nào để khi trúng mục tiêu thì làm chậm theo kiểu bj đóng băng?
LÀm sao cho số dâmge gây ra = số damage của chiêu + 1/2 dâmge bản thân?
Mình đang rất cần chiêu này.mong các bạn chỉ dùm^^
 
Back
Top