Topic hỏi đáp về cách làm map | version 9

Status
Không mở trả lời sau này.
EnchantTotemAttack
Events
Unit - A unit Is attacked
Conditions
((Attacking unit) has buff Enchant Totem ) Equal to True
Actions
Wait 1.00 seconds
Unit - Remove Enchant Totem buff from (Attacking unit)
base từ roar đấy =))
demo anh tom làm =)),1s sau khi phang vào người nó thì remove,còn không sẽ tồn tại trong 15s rồi sau đó remove theo mặc định của spell

Spell này đã được IF cải tiến lại rùi, là chừng nào target nhận hẳn damage mới remove buff

Cách trên trước đây IF đã từng áp dụng, nhưng hiệu quả không cao nếu Hero bị disable khi đang attack, hoặc mất target khi đang attack thì cũng sẽ bị remove buff...
 
@KuKulKan:
Bạn có thể hướng dẫn giúp cách lấy damage base của hero ko ??
 
@KuKulKan:
Bạn có thể hướng dẫn giúp cách lấy damage base của hero ko ??

À để Kan làm cái demo rùi up lên, cũng chẳng có gì đâu dùng system thôi...
 
Cho em hỏi về Fatal Error từ EGUI (sr ko onl thường xuyên nên post ngắt quãng ) :Những system nào bị lỗi hay ko dùng vậy mọi người , mình hiện chỉ dùng Recipe ,Knock ,Jump , nếu trong mấy cái này có cái ko dùng đc thì thay bằng sys nào ạ ?
Có sys nào hạn chế đc Fatal Error ko , hoặc có cách nào phát hiện nó lỗi code ở trigger nào ko ?
 
Bạn hướng dẫn cụ thể dùm mình được không?
Giờ mình down font về rồi làm gì nữa. Chỉ mình chi tiết luôn nhé. Mấy cái đường dẫn đến font trong Jassnewgen bạn cũng chỉ rõ luôn nhé.

bạn add yahoo mình đi. windy_angel3
 
em có 1 skill dùng dummy tấn công creep
Vấn đề nảy sinh là: Dummy mà giết creep đó thì mình không được bounty từ creep,vậy muốn đựoc tiền thì làm thế nào ?
 
em có 1 skill dùng dummy tấn công creep
Vấn đề nảy sinh là: Dummy mà giết creep đó thì mình không được bounty từ creep,vậy muốn đựoc tiền thì làm thế nào ?

Câu hỏi: Chiêu thức gì nhờ dummy giết creep?Cậu không tự gây dam cho nó được à?
 
Tunghamtien: thay sys KnockBack của bạn bằng cái này thử được k?
Mã:
//******************************************************************************
//*                                                                            *
//*                             K N O C K B A C K                              *
//*                                Actual Code                                 *
//*                                   v1.06                                    *
//*                                                                            *
//*                              By: Rising_Dusk                               *
//*                                                                            *
//******************************************************************************

library Knockback initializer Init needs TerrainPathability, GroupUtils, UnitIndexingUtils, LastOrder
globals
    //*********************************************************
    //* These are the configuration constants for the system
    //*
    //* EFFECT_ATTACH_POINT:  Where on the unit the effect attaches
    //* EFFECT_PATH_WATER:    What special effect to attach over water
    //* EFFECT_PATH_GROUND:   What special effect to attach over ground
    //* DEST_RADIUS:          Radius around which destructs die
    //* DEST_RADIUS_SQUARED:  Radius squared around which destructs die
    //* ADJACENT_RADIUS:      Radius for knocking back adjacent units
    //* ADJACENT_FACTOR:      Factor for collision speed transfers
    //* TIMER_INTERVAL:       The interval for the timer that gets run
    //* ISSUE_LAST_ORDER:     A boolean to issue last orders or not
    //*
    private constant string         EFFECT_ATTACH_POINT = "origin"
    private constant string         EFFECT_PATH_WATER   = "MDX\\KnockbackWater.mdx"
    private constant string         EFFECT_PATH_GROUND  = "MDX\\KnockbackDust.mdx"
    private constant real           DEST_RADIUS         = 180.
    private constant real           DEST_RADIUS_SQUARED = DEST_RADIUS*DEST_RADIUS
    private constant real           ADJACENT_RADIUS     = 180.
    private constant real           ADJACENT_FACTOR     = 0.75
    private constant real           TIMER_INTERVAL      = 0.05
    private constant boolean        ISSUE_LAST_ORDER    = true
    
    //*********************************************************
    //* These are static constants used by the system and shouldn't be changed
    //*
    //* Timer:                The timer that runs all of the effects for the spell
    //* Counter:              The counter for how many KB instances exist
    //* HitIndex:             Indexes for a given unit's knockback
    //* Knockers:             The array of all struct instances that exist
    //* Entries:              Counters for specific unit instances in system
    //* ToClear:              How many instances to remove on next run
    //* DesBoolexpr:          The check used for finding destructables
    //* AdjBoolexpr:          The check for picking adjacent units to knockback
    //* DestRect:             The rect used to check for destructables
    //*
    private          timer          Timer               = CreateTimer()
    private          integer        Counter             = 0
    private          integer  array HitIndex
    private          integer  array Knockers
    private          integer  array Entries
    private          integer  array ToClear
    private          boolexpr       DesBoolexpr         = null
    private          boolexpr       AdjBoolexpr         = null
    private          rect           DestRect            = Rect(0,0,1,1)
    
    //* Temporary variables used by the system
    private          real           TempX               = 0.
    private          real           TempY               = 0.
    private          unit           TempUnit1           = null
    private          unit           TempUnit2           = null
endglobals

//* Functions for the destructable destruction
private function KillDests_Check takes nothing returns boolean
    local real x = GetDestructableX(GetFilterDestructable())
    local real y = GetDestructableY(GetFilterDestructable())
    return (TempX-x)*(TempX-x) + (TempY-y)*(TempY-y) <= DEST_RADIUS_SQUARED
endfunction

private function KillDests takes nothing returns nothing
    call KillDestructable(GetEnumDestructable())
endfunction

//* Functions for knocking back adjacent units
private function KnockAdj_Check takes nothing returns boolean
    return TempUnit2 != GetFilterUnit() and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(TempUnit1)) and IsUnitType(GetFilterUnit(), UNIT_TYPE_GROUND) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_MECHANICAL) and GetWidgetLife(GetFilterUnit()) > 0.405 and GetUnitAbilityLevel(GetFilterUnit(), 'Avul') <= 0
endfunction

//******************************************************************************
//* Some additional functions that can be used
function KnockbackStop takes unit targ returns boolean
    local integer id = GetUnitId(targ)
    set ToClear[id] = Entries[id]
    return ToClear[id] > 0
endfunction
function IsKnockedBack takes unit targ returns boolean
    return Entries[GetUnitId(targ)] > 0
endfunction

//* Struct for the system, I recommend leaving it alone
private struct knocker
    unit Source      = null
    unit Target      = null
    group HitGroup   = null
    effect KBEffect  = null
    integer FXMode   = 0
    boolean KillDest = false
    boolean KnockAdj = false
    boolean ChainAdj = false
    real Decrement   = 0.
    real Displace    = 0.
    real CosA        = 0.
    real SinA        = 0.
    
    public method checkterrain takes knocker n returns integer
        local real x = GetUnitX(n.Target)
        local real y = GetUnitY(n.Target)
        if IsTerrainPathingType(x, y, TERRAIN_PATHING_LAND) then
            return 1
        endif
        if IsTerrainPathingType(x, y, TERRAIN_PATHING_SHALLOW) then
            return 2
        endif
        return 0
    endmethod
    static method create takes unit source, unit targ, real angle, real disp, real dec, boolean killDestructables, boolean knockAdjacent, boolean chainAdjacent returns knocker
        local knocker n = knocker.allocate()
        set n.Target    = targ
        set n.Source    = source
        set n.FXMode    = n.checkterrain(n)
        set n.HitGroup  = NewGroup()
        set n.KillDest  = killDestructables
        set n.KnockAdj  = knockAdjacent
        set n.ChainAdj  = chainAdjacent
        set n.Decrement = dec
        set n.Displace  = disp
        set n.CosA      = Cos(angle)
        set n.SinA      = Sin(angle)
        
        if n.FXMode == 1 then
            set n.KBEffect = AddSpecialEffectTarget(EFFECT_PATH_GROUND, n.Target, EFFECT_ATTACH_POINT)
        elseif n.FXMode == 2 then
            set n.KBEffect = AddSpecialEffectTarget(EFFECT_PATH_WATER, n.Target, EFFECT_ATTACH_POINT)
        debug else
            debug call BJDebugMsg(SCOPE_PREFIX+" Error (On Create): Unknown Terrain Type")
        endif
        
        return n
    endmethod
    private method onDestroy takes nothing returns nothing
        local integer id = GetUnitId(this.Target)
        set Entries[id] = Entries[id] - 1
        if GetWidgetLife(this.Target) > 0.405 and Entries[id] <= 0 and ISSUE_LAST_ORDER then
            call IssueLastOrder(this.Target)
        endif
        call DestroyEffect(this.KBEffect)
        call ReleaseGroup(this.HitGroup)
    endmethod
endstruct

private function Update takes nothing returns nothing
    local unit u       = null
    local unit s       = null
    local rect r       = null
    local knocker n    = 0
    local knocker m    = 0
    local integer i    = Counter - 1
    local integer j    = 0
    local integer mode = 0
    local integer id   = 0
    local real xi      = 0.
    local real yi      = 0.
    local real xf      = 0.
    local real yf      = 0.
    
    loop
        exitwhen i < 0
        set n    = Knockers[i]
        set u    = n.Target
        set mode = n.FXMode
        set id   = GetUnitId(u)
        
        set xi   = GetUnitX(u)
        set yi   = GetUnitY(u)
        
        if n.Displace <= 0 or ToClear[id] > 0 then
            //* Clean up the knockback when it is over
            if ToClear[id] > 0 then
                set ToClear[id] = ToClear[id] - 1
            endif
            call n.destroy()
            set Counter = Counter - 1
            if Counter < 0 then
                call PauseTimer(Timer)
                set Counter = 0
            else
                set Knockers[i] = Knockers[Counter]
            endif
        else
            //* Propagate the knockback in space and time
            set xf = xi + n.Displace*n.CosA
            set yf = yi + n.Displace*n.SinA
            call SetUnitPosition(u, xf, yf)
            set n.FXMode = n.checkterrain(n)
            
            //* Modify the special effect if necessary
            if n.FXMode == 1 and mode == 2 then
                call DestroyEffect(n.KBEffect)
                set n.KBEffect = AddSpecialEffectTarget(EFFECT_PATH_GROUND, n.Target, EFFECT_ATTACH_POINT)
            elseif n.FXMode == 2 and mode == 1 then
                call DestroyEffect(n.KBEffect)
                set n.KBEffect = AddSpecialEffectTarget(EFFECT_PATH_WATER, n.Target, EFFECT_ATTACH_POINT)
            debug elseif n.FXMode == 0 then
                debug call BJDebugMsg(SCOPE_PREFIX+" Error (In Update): Unknown Terrain Type")
            endif
            set n.Displace = n.Displace - n.Decrement
            
            //* Destroy destructables if desired
            if n.KillDest then
                set TempX = GetUnitX(u)
                set TempY = GetUnitY(u)
                call MoveRectTo(DestRect, TempX, TempY)
                call EnumDestructablesInRect(DestRect, DesBoolexpr, function KillDests)
            endif
            
            //* Knockback nearby units if desired
            if n.KnockAdj then
                set xi         = GetUnitX(u)
                set yi         = GetUnitY(u)
                set TempUnit1  = n.Source
                set TempUnit2  = u
                call GroupEnumUnitsInRange(ENUM_GROUP, xi, yi, ADJACENT_RADIUS, AdjBoolexpr)
                loop
                    set s = FirstOfGroup(ENUM_GROUP)
                    exitwhen s == null
                    if not IsUnitInGroup(s, n.HitGroup) then
                        set xf = GetUnitX(s)
                        set yf = GetUnitY(s)
                        call GroupAddUnit(n.HitGroup, s)
                        set m = knocker.create(n.Source, s, Atan2(yf-yi, xf-xi), n.Displace*ADJACENT_FACTOR, n.Decrement, n.KillDest, n.ChainAdj, n.ChainAdj)
                        call GroupAddUnit(m.HitGroup, u)
                        set Knockers[Counter] = m
                        set Counter           = Counter + 1
                    endif
                    call GroupRemoveUnit(ENUM_GROUP, s)
                endloop
            endif
        endif
        set i = i - 1
    endloop
    
    set u = null
    set s = null
endfunction

//******************************************************************************
//* How to knockback a unit
function KnockbackTarget takes unit source, unit targ, real angle, real startspeed, real decrement, boolean killDestructables, boolean knockAdjacent, boolean chainAdjacent returns boolean
    local knocker n  = 0
    local integer id = GetUnitId(targ)
    
    //* Protect users from themselves
    if decrement <= 0. or startspeed <= 0. or targ == null then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error (On Call): Invalid Starting Conditions")
        return false
    endif
    //* Can't chain if you don't knockback adjacent units
    if not knockAdjacent and chainAdjacent then
        set chainAdjacent = false
    endif
    set n = knocker.create(source, targ, angle*bj_DEGTORAD, startspeed*TIMER_INTERVAL, decrement*TIMER_INTERVAL*TIMER_INTERVAL, killDestructables, knockAdjacent, chainAdjacent)
    if Counter == 0 then
        call TimerStart(Timer, TIMER_INTERVAL, true, function Update)
    endif
    
    set Entries[id]       = Entries[id] + 1
    set HitIndex[id]      = Counter + 1
    set Knockers[Counter] = n
    set Counter           = Counter + 1
    return true
endfunction

private function Init takes nothing returns nothing
    call SetRect(DestRect, -DEST_RADIUS, -DEST_RADIUS, DEST_RADIUS, DEST_RADIUS)
    set DesBoolexpr = Condition(function KillDests_Check)
    set AdjBoolexpr = Condition(function KnockAdj_Check)
endfunction
endlibrary

library LastOrder initializer Init needs UnitIndexingUtils
//******************************************************************************
//* BY: Rising_Dusk
//* 
//* This library has a lot of usefulness for when you want to interface with the
//* last order a unit was given. This can be useful for simulating spell errors
//* and where you'd want to give them back the order they had prior to the spell
//* cast (whereas without this library, they'd just forget their orders).
//* 
//* There are some handy interfacing options for your use here --
//*     function GetLastOrderId takes unit u returns integer
//*     function GetLastOrderString takes unit u returns string
//*     function GetLastOrderType takes unit u returns integer
//*     function GetLastOrderX takes unit u returns real
//*     function GetLastOrderY takes unit u returns real
//*     function GetLastOrderTarget takes unit u returns widget
//*     function AbortOrder takes unit u returns boolean
//*
//* There are also some order commands that can be useful --
//*     function IssueLastOrder takes unit u returns boolean
//*     function IssueSecondLastOrder takes unit u returns boolean
//*     function IsLastOrderFinished takes unit u returns boolean
//* 
//* You can access any information you'd like about the orders for your own
//* order handling needs.
//* 
globals
    //* Storage for last order
    private          integer array Order
    private          integer array Type
    private          widget  array Targ
    private          boolean array Flag
    private          real    array X
    private          real    array Y
    
    //* Storage for second last order
    private          integer array P_Order
    private          integer array P_Type
    private          widget  array P_Targ
    private          boolean array P_Flag
    private          real    array P_X
    private          real    array P_Y
    
    //* Order type variables
            constant integer       ORDER_TYPE_TARGET    = 1
            constant integer       ORDER_TYPE_POINT     = 2
            constant integer       ORDER_TYPE_IMMEDIATE = 3
    
    //* Trigger for the order catching
    private          trigger       OrderTrg             = CreateTrigger()
endglobals

function GetUnitId takes handle h returns integer
    return GetHandleId(h)
endfunction

//**********************************************************
function GetLastOrderId takes unit u returns integer
    return Order[GetUnitId(u)]
endfunction
function GetLastOrderString takes unit u returns string
    return OrderId2String(Order[GetUnitId(u)])
endfunction
function GetLastOrderType takes unit u returns integer
    return Type[GetUnitId(u)]
endfunction
function GetLastOrderX takes unit u returns real
    return X[GetUnitId(u)]
endfunction
function GetLastOrderY takes unit u returns real
    return Y[GetUnitId(u)]
endfunction
function GetLastOrderTarget takes unit u returns widget
    return Targ[GetUnitId(u)]
endfunction
//**********************************************************
private function OrderExclusions takes unit u, integer id returns boolean
    //* Excludes specific orders or unit types from registering with the system
    //* 
    //* 851972: stop
    //*         Stop is excluded from the system, but you can change it by
    //*         adding a check for it below. id == 851972
    //* 
    //* 851971: smart
    //* 851986: move
    //* 851983: attack
    //* 851984: attackground
    //* 851990: patrol
    //* 851993: holdposition
    //*         These are the UI orders that are passed to the system.
    //* 
    //* >= 852055, <= 852762
    //*         These are all spell IDs from defend to incineratearrowoff with
    //*         a bit of leeway at the ends for orders with no strings.
    //* 
    return id == 851971 or id == 851986 or id == 851983 or id == 851984 or id == 851990 or id == 851993 or (id >= 852055 and id <= 852762)
endfunction
private function LastOrderFilter takes unit u returns boolean
    //* Some criteria for whether or not a unit's last order should be given
    //* 
    //* INSTANT type orders are excluded because generally, reissuing an instant
    //* order doesn't make sense. You can remove that check below if you'd like,
    //* though.
    //* 
    //* The Type check is really just to ensure that no spell recursion can
    //* occur with IssueLastOrder. The problem with intercepting the spell cast
    //* event is that it happens after the order is 'caught' and registered to
    //* this system. Therefore, to just IssueLastOrder tells it to recast the
    //* spell! That's a problem, so we need a method to eliminate it.
    //* 
    local integer id = GetUnitId(u)
    return u != null and GetWidgetLife(u) > 0.405 and Type[id] != ORDER_TYPE_IMMEDIATE
endfunction
private function SecondLastOrderFilter takes unit u returns boolean
    //* Same as above but with regard to the second last order issued
    local integer id = GetUnitId(u)
    return u != null and GetWidgetLife(u) > 0.405 and P_Type[id] != ORDER_TYPE_IMMEDIATE and P_Order[id] != Order[id]
endfunction
//**********************************************************

function IsLastOrderFinished takes unit u returns boolean
    return (GetUnitCurrentOrder(u) == 0 and Order[GetUnitId(u)] != 851972) or Flag[GetUnitId(u)]
endfunction

function IssueLastOrder takes unit u returns boolean
    local integer id = GetUnitId(u)
    if LastOrderFilter(u) and Order[id] != 0 and not Flag[id] then
        if Type[id] == ORDER_TYPE_TARGET then
            return IssueTargetOrderById(u, Order[id], Targ[id])
        endif
        if Type[id] == ORDER_TYPE_POINT then
            return IssuePointOrderById(u, Order[id], X[id], Y[id])
        endif
        if Type[id] == ORDER_TYPE_IMMEDIATE then
            return IssueImmediateOrderById(u, Order[id])
        endif
    endif
    return false
endfunction

function IssueSecondLastOrder takes unit u returns boolean
    //* This function has to exist because of spell recursion
    local integer id = GetUnitId(u)
    if SecondLastOrderFilter(u) and P_Order[id] != 0 and not P_Flag[id] then
        if P_Type[id] == ORDER_TYPE_TARGET then
            return IssueTargetOrderById(u, P_Order[id], P_Targ[id])
        endif
        if P_Type[id] == ORDER_TYPE_POINT then
            return IssuePointOrderById(u, P_Order[id], P_X[id], P_Y[id])
        endif
        if P_Type[id] == ORDER_TYPE_IMMEDIATE then
            return IssueImmediateOrderById(u, P_Order[id])
        endif
    endif
    return false
endfunction

function AbortOrder takes unit u returns boolean
    if IsUnitPaused(u) then
        return false
    endif
    if not IsUnitPaused(u) then
        call PauseUnit(u, true)
        call IssueImmediateOrder(u, "stop")
        call PauseUnit(u, false)
    endif
    return true
endfunction
//**********************************************************

private function Conditions takes nothing returns boolean
    return OrderExclusions(GetTriggerUnit(), GetIssuedOrderId())
endfunction

private function Actions takes nothing returns nothing
    local unit    u  = GetTriggerUnit()
    local integer id = GetUnitId(u)
    
    //* Store second to last order to eliminate spell recursion
    set P_Order[id]  = Order[id]
    set P_Targ[id]   = Targ[id]
    set P_Type[id]   = Type[id]
    set P_Flag[id]   = Flag[id]
    set P_X[id]      = X[id]
    set P_Y[id]      = Y[id]
    
    set Flag[id]     = false
    set Order[id]    = GetIssuedOrderId()
    if GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER then
        set Targ[id] = GetOrderTarget()
        set Type[id] = ORDER_TYPE_TARGET
        set X[id]    = GetWidgetX(GetOrderTarget())
        set Y[id]    = GetWidgetY(GetOrderTarget())
    elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER then
        set Targ[id] = null
        set Type[id] = ORDER_TYPE_POINT
        set X[id]    = GetOrderPointX()
        set Y[id]    = GetOrderPointY()
    elseif GetTriggerEventId() == EVENT_PLAYER_UNIT_ISSUED_ORDER then
        set Targ[id] = null
        set Type[id] = ORDER_TYPE_IMMEDIATE
        set X[id]    = GetUnitX(u)
        set Y[id]    = GetUnitY(u)
    debug else
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Order Doesn't Exist")
    endif
    
    set u = null
endfunction
//**********************************************************

private function SpellActions takes nothing returns nothing
    set Flag[GetUnitId(GetTriggerUnit())] = true
endfunction
//**********************************************************

private function Init takes nothing returns nothing
    local trigger trg = CreateTrigger()
    call TriggerAddAction(OrderTrg, function Actions)
    call TriggerAddCondition(OrderTrg, Condition(function Conditions))
    call TriggerRegisterAnyUnitEventBJ(OrderTrg, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER)
    call TriggerRegisterAnyUnitEventBJ(OrderTrg, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
    call TriggerRegisterAnyUnitEventBJ(OrderTrg, EVENT_PLAYER_UNIT_ISSUED_ORDER)
    
    call TriggerAddAction(trg, function SpellActions)
    call TriggerRegisterAnyUnitEventBJ(trg, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    
    set trg = null
endfunction
endlibrary

library UnitIndexingUtils initializer Init
//******************************************************************************
//* BY: Rising_Dusk
//* 
//* -: BLUE FLAVOR :-
//* 
//* This can be used to index units with a unique integer for use with arrays
//* and things like that. This has a limit of 8191 indexes allocated at once in
//* terms of actually being usable in arrays. It won't give you an error if you
//* exceed 8191, but that is an unrealistic limit anyways.
//* 
//* The blue flavor uses a trigger that fires on death of a unit to release the
//* indexes of units. This is useful for maps where ressurection is not an issue
//* and doesn't require an O(n) search inside of a timer callback, making it
//* potentially less taxing on the game.
//* 
//* To use, call GetUnitId on a unit to retrieve its unique integer id. This
//* library allocates a unique index to a unit the instant it is created, which
//* means you can call GetUnitId immediately after creating the unit with no
//* worry.
//* 
//* Function Listing --
//*     function GetUnitId takes unit u returns integer
//* 
private struct unitindex
endstruct

//Function to get the unit's unique integer id, inlines to getting its userdata
private function GetUnitId takes unit u returns integer
    return GetUnitUserData(u)
endfunction

//Filter for units to index 
private function UnitFilter takes nothing returns boolean
    return true
endfunction

//Filter for what units to remove indexes for on death
private function Check takes nothing returns boolean
    return not IsUnitType(GetTriggerUnit(), UNIT_TYPE_HERO)
endfunction

private function Clear takes nothing returns nothing
    local unit u = GetTriggerUnit()
    call unitindex(GetUnitId(u)).destroy()
    call SetUnitUserData(u,-1)
    set u = null
endfunction

private function Add takes nothing returns boolean
    call SetUnitUserData(GetFilterUnit(),unitindex.create())
    return true
endfunction

private function GroupAdd takes nothing returns nothing
    call SetUnitUserData(GetEnumUnit(),unitindex.create())
endfunction

private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local region  r = CreateRegion()
    local group   g = CreateGroup()
    local integer i = 0
    
    //Use a filterfunc so units are indexed immediately
    call RegionAddRect(r, bj_mapInitialPlayableArea)
    call TriggerRegisterEnterRegion(t, r, And(Condition(function UnitFilter), Condition(function Add)))
    
    //Loop and group per player to grab all units, including those with locust
    loop
        exitwhen i > 15
        call GroupEnumUnitsOfPlayer(g, Player(i), Condition(function UnitFilter))
        call ForGroup(g, function GroupAdd)
        set i = i + 1
    endloop
    
    //Set up the on-death trigger to clear custom values
    set t = CreateTrigger()
    call TriggerAddAction(t, function Clear)
    call TriggerAddCondition(t, Condition(function Check))
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_DEATH)
    
    call DestroyGroup(g)
    set r = null
    set t = null
    set g = null
endfunction
endlibrary

library TerrainPathability initializer Initialization
//******************************************************************************
//* BY: Rising_Dusk
//* 
//* This can be used to detect the type of pathing a specific point of terrain
//* is, whether land, shallow water, or deep water. This type of detection
//* should have been easy to do using natives, but the IsTerrainPathable(...)
//* native is very counterintuitive and does not permit easy detection in one
//* call. For that reason, this library was developed.
//*
//* The system requires a dummy unit of some sort. There are no real
//* requirements upon the dummy unit, but it needs a non-zero movement speed.
//* More importantly than the dummy unit, though, it needs a custom windwalk
//* based unit ability with a 0.00 duration and no fade time. Both of those
//* raw id's (for the unit and windwalk dummy) need to be configured below.
//*
//* There is an objectmerger call available for those of you too lazy to build 
//* your own windwalk based ability. Simply uncomment it below and save once,
//* then close and reopen your map and recomment the line.
//*
globals
    constant integer TERRAIN_PATHING_DEEP                           = 1
    constant integer TERRAIN_PATHING_SHALLOW                        = 2
    constant integer TERRAIN_PATHING_LAND                           = 3
    constant integer TERRAIN_PATHING_WALKABLE                       = 4
    
    private unit Dummy                                              = null
    private constant integer DUMMY_UNIT_ID                          = 'hfoo'
    private constant integer DUMMY_WINDWALK_ID                      = 'win&'
    private constant player OWNING_PLAYER                           = Player(15)
    
    //* These variables shouldn't be adjusted
    private real WorldMinX                                          = 0.
    private real WorldMinY                                          = 0.
endglobals

////! external ObjectMerger w3a ANwk win& anam "Collision Ability" ansf "" Owk3 1 0.0 Owk4 1 0 Owk2 1 0.0 Owk1 1 0.0 acdn 1 0.0 ahdu 1 0.0 adur 1 0. aher 0 amcs 1 0

function IsTerrainPathingType takes real x, real y, integer terrainPathingType returns boolean
    local boolean b = false
    if terrainPathingType == TERRAIN_PATHING_DEEP then
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
    endif
    if terrainPathingType == TERRAIN_PATHING_SHALLOW then
        return not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)
    endif
    if terrainPathingType == TERRAIN_PATHING_LAND then
        return IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY)
    endif
    if terrainPathingType == TERRAIN_PATHING_WALKABLE then
        call SetUnitPosition(Dummy, x, y)
        set b = GetUnitX(Dummy) == x and GetUnitY(Dummy) == y and not (not IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) and IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY))
        call SetUnitX(Dummy, WorldMinX)
        call SetUnitY(Dummy, WorldMinY)
    endif
    return b
endfunction

private function Initialization takes nothing returns nothing
    local rect r = GetWorldBounds()
    
    set WorldMinX = GetRectMinX(r) + 100.
    set WorldMinY = GetRectMinY(r) + 100.
    set Dummy = CreateUnit(OWNING_PLAYER, DUMMY_UNIT_ID, 0., 0., 0.)
    call UnitAddAbility(Dummy, DUMMY_WINDWALK_ID)
    call UnitAddAbility(Dummy, 'Avul')
    call IssueImmediateOrderById(Dummy, 852129)
    call SetUnitX(Dummy, WorldMinX)
    call SetUnitY(Dummy, WorldMinY)
    
    call RemoveRect(r)
    set r = null
endfunction
endlibrary

library GroupUtils
//******************************************************************************
//* BY: Rising_Dusk
//* 
//* This library is a simple implementation of a stack for groups that need to
//* be in the user's control for greater than an instant of time. Additionally,
//* this library provides a single, global group variable for use with user-end
//* enumerations. It is important to note that users should not be calling
//* DestroyGroup() on the global group, since then it may not exist for when it
//* it is next needed.
//*
//* The group stack removes the need for destroying groups and replaces it with
//* a recycling method.
//*     function NewGroup takes nothing returns group
//*     function ReleaseGroup takes group g returns boolean
//*     function GroupRefresh takes group g returns nothing
//* 
//* NewGroup grabs a currently unused group from the stack or creates one if the
//* stack is empty. You can use this group however you'd like, but always
//* remember to call ReleaseGroup on it when you are done with it. If you don't
//* release it, it will 'leak' and your stack may eventually overflow if you
//* keep doing that.
//* 
//* GroupRefresh cleans a group of any shadow references which may be clogging
//* its hash table. If you remove a unit from the game who is a member of a unit
//* group, it will 'effectively' remove the unit from the group, but leave a
//* shadow in its place. Calling GroupRefresh on a group will clean up any
//* shadow references that may exist within it.
//* 
globals
    //* Group for use with all instant enumerations
    group ENUM_GROUP = CreateGroup()
    
    //* Temporary references for GroupRefresh
    private boolean Flag                                              = false
    private group Refr                                                = null
    
    //* Assorted constants
    private constant integer MAX_HANDLE_COUNT                         = 408000
    private constant integer MIN_HANDLE_ID                            = 0x100000
    
    //* Arrays and counter for the group stack
    private group array Groups
    private integer array Status[MAX_HANDLE_COUNT]
    private integer Count                                             = 0
endglobals

private function H2I takes handle h returns integer
    return GetHandleId(h)
endfunction

private function AddEx takes nothing returns nothing
    if Flag then
        call GroupClear(Refr)
        set Flag = false
    endif
    call GroupAddUnit(Refr, GetEnumUnit())
endfunction
    
function GroupRefresh takes group g returns nothing
    set Flag = true
    set Refr = g
    call ForGroup(Refr, function AddEx)
    if Flag then
        call GroupClear(g)
    endif
endfunction

function NewGroup takes nothing returns group
    if Count == 0 then
        set Groups[0] = CreateGroup()
    else
        set Count = Count - 1
    endif
    set Status[H2I(Groups[Count])-MIN_HANDLE_ID] = 1
    return Groups[Count]
endfunction

function ReleaseGroup takes group g returns boolean
    local integer stat = Status[H2I(g)-MIN_HANDLE_ID]
    if g == null then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Null groups cannot be released")
        return false
    endif
    if stat == 0 then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Group not part of stack")
        return false
    endif
    if stat == 2 then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Groups cannot be multiply released")
        return false
    endif
    if Count == 8191 then
        debug call BJDebugMsg(SCOPE_PREFIX+" Error: Max groups achieved, destroying group")
        call DestroyGroup(g)
        return false
    endif
    if Count != 8191 then
        call GroupClear(g)
        set Groups[Count]                = g
        set Count                        = Count + 1
        set Status[H2I(g)-MIN_HANDLE_ID] = 2
    endif
    return true
endfunction
endlibrary
@Sky: nhiệm vụ sky giúp mình đâu rùi @@, có chưa
 
Ai có thể hưởng dẩn mình làm 2 skill này được không:
Skill 1: Tạo ra 1 cái trap cứ mỗi 0.5s thì bắn 8 mũi tên ra 8 hướng random khác nhau
Skill 2: passive cứ mỗi khi đánh 3 phát liên tiếp thì tới phát thứ 4 sẽ cộng damage với AOE 200 :D
p/s: GUI nha, mình gà JASS :D
 
Cho em hỏi về Fatal Error từ EGUI (sr ko onl thường xuyên nên post ngắt quãng ) :Những system nào bị lỗi hay ko dùng vậy mọi người , mình hiện chỉ dùng Recipe ,Knock ,Jump , nếu trong mấy cái này có cái ko dùng đc thì thay bằng sys nào ạ ?
Có sys nào hạn chế đc Fatal Error ko , hoặc có cách nào phát hiện nó lỗi code ở trigger nào ko ?

Chắc bạn sửa cái gì linh tinh trong system của EGUI rồi, mình dùng EGUI cho một số spell "hardcore" trong map mình, sử dụng rất nhiều command mà chẳng sao cả . Tốt nhất là bạn nên xoá EGUI đi và copy lại.
 
Hỏi :

Làm sao để unti chưa xuất hiện ( ko tạo trên bản đồ ) bị giết thì unti sẽ rớt ra item
 
Câu hỏi của mình hôm nay là:
1.Làm giúp mình spell Storm Bolt (GUI thôi) nhưng cái búa phải bay theo đường cong (Arc), và mình phải tự chỉnh được độ cong của có ( giống kiểu Project Arc của các Ranged Unit đó).
2.Làm giúp mình tiếp Spell chuyển STR qua AGI và ngược lại (của Morphling - Dota), nhớ là Autocast đó.
em có 1 skill dùng dummy tấn công creep
Vấn đề nảy sinh là: Dummy mà giết creep đó thì mình không được bounty từ creep,vậy muốn đựoc tiền thì làm thế nào ?

Có gì đâu, chỉ cần cho Dummy đó "Owner of Caster" là được (kiểu như Hero ko giết creep nhưng "đệ tử" của Hero giết creep thì cũng vẫn đc tiền)
 
Chỉnh sửa cuối:
Mã:
Events
    Unit - A unit Starts the effect of an abilit
Conditions
    (Ability being cast) Equal to Storm Bolt
Actions
    Set target = (Target unit of ability being cast)
    Unit - Create 1 Dummy for (Owner of (Triggering unit)) at (Position of (Triggering unit)) facing Default building facing degrees
    Set Dummy = (Last created unit)
    Special Effect - Create a special effect attached to the chest of target using Abilities\Spells\Human\Thunderclap\ThunderClapCaster.mdl
    Unit - Move (Triggering unit) instantly to ((Position of target) offset by (0.00, 90.00))
    Animation - Play (Triggering unit)'s attack slam animation
    Special Effect - Destroy (Last created special effect)
    Wait 0.30 seconds
    Special Effect - Create a special effect at (Position of target) using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
    Unit - Cause (Triggering unit) to damage target, dealing 100.00 damage of attack type Spells and damage type Normal
    Special Effect - Destroy (Last created special effect)
    Wait 0.30 seconds
    Special Effect - Create a special effect at (Position of Dummy) using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
    Unit - Move (Triggering unit) instantly to ((Position of Dummy) offset by (0.00, 90.00))
    Special Effect - Destroy (Last created special effect)
    Unit - Add a 1.00 second Generic expiration timer to Dummy
    Unit - Create 1 Dummy for (Owner of (Triggering unit)) at (Position of target) facing Default building facing degrees
    Unit - Add Stun  to (Last created unit)
    Unit - Set level of Stun  for (Last created unit) to (Level of Storm Bolt for (Triggering unit))
    Unit - Order (Last created unit) to Human Mountain King - Storm Bolt target
    Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
Cho hỏi tại sao cái đoạn spell này mình làm vào test map thì thấy nó lỗi không có cooldown mặc dù trong object đã chỉnh cooldown
 
Mã:
Events
    Unit - A unit Starts the effect of an abilit
Conditions
    (Ability being cast) Equal to Storm Bolt
Actions
    Set target = (Target unit of ability being cast)
    Unit - Create 1 Dummy for (Owner of (Triggering unit)) at (Position of (Triggering unit)) facing Default building facing degrees
    Set Dummy = (Last created unit)
    Special Effect - Create a special effect attached to the chest of target using Abilities\Spells\Human\Thunderclap\ThunderClapCaster.mdl
    Unit - Move (Triggering unit) instantly to ((Position of target) offset by (0.00, 90.00))
    Animation - Play (Triggering unit)'s attack slam animation
    Special Effect - Destroy (Last created special effect)
    Wait 0.30 seconds
    Special Effect - Create a special effect at (Position of target) using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
    Unit - Cause (Triggering unit) to damage target, dealing 100.00 damage of attack type Spells and damage type Normal
    Special Effect - Destroy (Last created special effect)
    Wait 0.30 seconds
    Special Effect - Create a special effect at (Position of Dummy) using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
    Unit - Move (Triggering unit) instantly to ((Position of Dummy) offset by (0.00, 90.00))
    Special Effect - Destroy (Last created special effect)
    Unit - Add a 1.00 second Generic expiration timer to Dummy
    Unit - Create 1 Dummy for (Owner of (Triggering unit)) at (Position of target) facing Default building facing degrees
    Unit - Add Stun  to (Last created unit)
    Unit - Set level of Stun  for (Last created unit) to (Level of Storm Bolt for (Triggering unit))
    Unit - Order (Last created unit) to Human Mountain King - Storm Bolt target
    Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
Cho hỏi tại sao cái đoạn spell này mình làm vào test map thì thấy nó lỗi không có cooldown mặc dù trong object đã chỉnh cooldown

Hehe, chưa xem trigger nhưng lỗi này mình biết: đó là do Caster chưa kịp cast xong spell (sau cast point là backswing point) thì bạn đã move instantly nó nên kết quả coi như là Caster chưa cast spell, mặc dù trigger vẫn chạy => đặt thêm wait ở đầu trigger.
 
Chỉnh sửa cuối:
đặt trước move thôi (Unit - Move (Triggering unit) instantly to ((Position of target) offset by (0.00, 90.00)))
đặt ở đầu trigger thì làm sao lấy được target 8-|
 
@Sky: nhiệm vụ sky giúp mình đâu rùi @@, có chưa
Oh!Mấy ngày qua lo ôn thi nên quên rồi!
Đây,post lên đây nhá!Đây là kiến thức cơ bản làm Quest cho LAN,nếu có thắc mắc cứ hỏi nha bạn!
 
hjz, chờ sky đưa bjn làm đc ùi @@. Học ở map kt 1.3 của anh Rex, hùi đó làm lỗi quá trời h` đc rùi, nhưng dù sao cũng tks
P/s: có thể share cho bjn sys UnitClears và hướng dẫn sử dụng đc hem?
 
Chỉnh sửa cuối:
Đó thuộc loại system khi chết phân biệt giữa dummy và creep,dummy chết sau 4s remove,creep thì fade tạm đi,creep sau 10 giây remove!Vậy thôi!Đối với map mình nó rất hiệu quả(VD: RAM 200k khi remove giảm đến 100 - 50k!)
 
thế sky share cho bjn đc hem? tks nhìu

ngacnhien.gif

Chài ơi có gì mà phải share ?
dummy luôn là 1 unit nhất định chỉ add effect vô thôi. Ví dụ mã raw code của nó là '0001' thì cứ check raw code con die là '0001' là bít nó là dummy chứ gì nữa. Cho add ex timer 4s cho nó là sau 4s nó bị remove thôi.
Còn trường hợp còn lại là else ( check ko phải là hero nữa nhen ) thì nó là quái. quái thì sau 10s remove....

sad.gif
 
Status
Không mở trả lời sau này.
Back
Top