Topic hỏi đáp (tập 4) về cách làm map

Thảo luận trong 'World Editor' bắt đầu bởi Tom_Kazansky, 19/2/10.

Trạng thái chủ đề:
Không mở trả lời sau này.
  1. Espeon - cool

    Espeon - cool Donkey Kong

    Tham gia ngày:
    16/1/07
    Bài viết:
    314
    Có thể tạo 1 skill fake cleave với 0% damage cleave, cho animation của skill là attack 1
     
  2. protectq2007

    protectq2007 Donkey Kong

    Tham gia ngày:
    17/10/07
    Bài viết:
    378
    ^Không khả quan, nó choáng mất một ô, nêu làm như cách bạn trên thì nên báe từ skill lightning attack của viên ngọc sét ấy mà chỉnh lại các thông số về không hết, vì chiêu này ko có icon nên cũng dễ ;))
     
  3. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    ngọc sét để làm gì ?
    ---
    cách giải quyêt mà không edit model là:

    Mã:
    Blademaster Attack
        Events
            Unit - A unit Is attacked
        Conditions
            (Unit-type of (Attacking unit)) Equal to Blademaster
        Actions
            --------  play animation index của [B](Attacking unit)[/B] --------
    
    play animation index thế nào thì xem: Bật Animation một cách chính xác
     
    Chỉnh sửa cuối: 25/6/10
  4. protectq2007

    protectq2007 Donkey Kong

    Tham gia ngày:
    17/10/07
    Bài viết:
    378
    ^ cái skill của ngoc sét hình như chỉnh được mà a ;))
    Skill đó ko có icon :D
     
  5. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    chỉnh được cái gì ?

    "hình như" một câu nữa là 3pts spam :)>-
     
  6. protectq2007

    protectq2007 Donkey Kong

    Tham gia ngày:
    17/10/07
    Bài viết:
    378
    ^ thì chỉnh được cái animation attack 1 đó a ;))
    Làm cách đó thì dễ hơn viết trigger :D
     
  7. ZhengHe

    ZhengHe T.E.T.Я.I.S

    Tham gia ngày:
    4/1/09
    Bài viết:
    623
    Đây là Fake miss của anh Tom nhưng mình thay cái ABCT = cái Key Timer. Đây là 1 skill khi cast thì add buff vào, hero có buff này thì bị đánh không mất máu. Lỗi ở đây là khi hero có buff thì phát đầu tiên bị đánh sẽ làm nó giảm máu xuống hơn 1 nữa. Ai rành kiểm tra giùm

    Key Timers 2 System:
    Mã:
    scope DamageRestoring
        globals
            private integer LifeBonusId = 'A000'
        endglobals
        private struct data
            unit u
            real percent
        endstruct
    
        private function RestoreE takes nothing returns boolean
            local data d = KT_GetData()
            call UnitRemoveAbility(d.u, LifeBonusId)
            call SetUnitState( d.u,UNIT_STATE_LIFE, GetUnitState(d.u,UNIT_STATE_MAX_LIFE)*d.percent )
            call data.destroy(d)
            return true
        endfunction
        
        function RestoreDamage takes unit u, real damagetaken, real restoreamount returns nothing
            local real maxlife = GetUnitState(u,UNIT_STATE_MAX_LIFE)
            local real curlife = GetUnitState(u,UNIT_STATE_LIFE)
            local data d
            if curlife - (damagetaken - restoreamount) <= 0 then
            //the restore amount can't help this unit to survive, it will die so doesn't need to do anything anymore
                return
            endif
            if maxlife - curlife >= restoreamount then
                call SetUnitState( u,UNIT_STATE_LIFE,curlife + restoreamount )
                return
            endif
            set d = data.create()
            set d.u = u
            set d.percent = ( curlife - (damagetaken - restoreamount) ) / maxlife
            call UnitAddAbility( u , LifeBonusId )
            call SetUnitState( u,UNIT_STATE_LIFE, maxlife )
        endfunction
    endscope
    Kế tiếp là 2 trigger add unit vao TakeDamGroup giống của anh Tom (2 cái đó ngắn chắc không có gì)
    Mã:
    Event:
       Time - Elapsed game time is 0.00 seconds
    Conditions:
    Actions:
       Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
        Loop - Actions
            Unit Group - Add (Picked unit) to TakeDamageGroup
            Trigger - Add to TakeDamage <gen> the event (Unit - (Picked unit) Takes damage)
    Mã:
    TakeDamage
        Events
        Conditions
        Actions
            Trigger - Turn off (This trigger)
            -------- Action --------
            Set TempUnit1 = (Triggering unit)
            Set TempLoc1 = (Position of TempUnit1)
            Set TempUnit2 = (Damage source)
            Set TempLoc2 = (Position of TempUnit2)
            Set Angle = (Angle from TempLoc1 to TempLoc2)
            Set Damage = (Damage taken)
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                If - Conditions
                    (TempUnit1 has buff Iron Skin ) Equal to True
                Then - Actions
                    Custom script:   call RestoreDamage( udg_TempUnit1 , udg_Damage, udg_Damage )
                    Special Effect - Create a special effect at (TempLoc1 offset by 100.00 towards Angle degrees) using Abilities\Spells\Human\Defend\DefendCaster.mdl
                    Special Effect - Destroy (Last created special effect)
                Else - Actions
            -------- End --------
            Custom script:   call RemoveLocation (udg_TempLoc1)
            Custom script:   call RemoveLocation (udg_TempLoc2)
            Trigger - Turn on (This trigger)
    
    P/s: Cái newgen mỗi lần muốn test là phải save map lại trước àh ??
     
  8. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    chỉnh thử đi, up map demo lên xem nào

    dùng KeyTimer làm gì, dùng TimerUtils ấy.

    [spoil]
    Mã:
    library TimerUtils initializer init
    //*********************************************************************
    //* TimerUtils (red+blue+orange flavors for 1.24b+)
    //* ----------
    //*
    //*  To implement it , create a custom text trigger called TimerUtils
    //* and paste the contents of this script there.
    //*
    //*  To copy from a map to another, copy the trigger holding this
    //* library to your map.
    //*
    //* (requires vJass)   More scripts: htt://www.wc3c.net
    //*
    //* For your timer needs:
    //*  * Attaching
    //*  * Recycling (with double-free protection)
    //*
    //* set t=NewTimer()      : Get a timer (alternative to CreateTimer)
    //* ReleaseTimer(t)       : Relese a timer (alt to DestroyTimer)
    //* SetTimerData(t,2)     : Attach value 2 to timer
    //* GetTimerData(t)       : Get the timer's value.
    //*                         You can assume a timer's value is 0
    //*                         after NewTimer.
    //*
    //* Multi-flavor:
    //*    Set USE_HASH_TABLE to true if you don't want to complicate your life.
    //*
    //* If you like speed and giberish try learning about the other flavors.
    //*
    //********************************************************************
    
    //================================================================
        globals
            //How to tweak timer utils:
            // USE_HASH_TABLE = true  (new blue)
            //  * SAFEST
            //  * SLOWEST (though hash tables are kind of fast)
            //
            // USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = true  (orange)
            //  * kinda safe (except there is a limit in the number of timers)
            //  * ALMOST FAST
            //
            // USE_HASH_TABLE = false, USE_FLEXIBLE_OFFSET = false (red)
            //  * THE FASTEST (though is only  faster than the previous method
            //                  after using the optimizer on the map)
            //  * THE LEAST SAFE ( you may have to tweak OFSSET manually for it to
            //                     work)
            //
            private constant boolean USE_HASH_TABLE      = false
            private constant boolean USE_FLEXIBLE_OFFSET = false
    
            private constant integer OFFSET     = 0x100000
            private          integer VOFFSET    = OFFSET
                  
            //Timers to preload at map init:
            private constant integer QUANTITY   = 256
            
            //Changing this  to something big will allow you to keep recycling
            // timers even when there are already AN INCREDIBLE AMOUNT of timers in
            // the stack. But it will make things far slower so that's probably a bad idea...
            private constant integer ARRAY_SIZE = 8190
    
        endglobals
    
        //==================================================================================================
        globals
            private integer array data[ARRAY_SIZE]
            private hashtable     ht
        endglobals
    
        //It is dependent on jasshelper's recent inlining optimization in order to perform correctly.
        function SetTimerData takes timer t, integer value returns nothing
            static if(USE_HASH_TABLE) then
                // new blue
                call SaveInteger(ht,0,GetHandleId(t), value)
                
            elseif (USE_FLEXIBLE_OFFSET) then
                // orange
                static if (DEBUG_MODE) then
                    if(GetHandleId(t)-VOFFSET<0) then
                        call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                    endif
                endif
                set data[GetHandleId(t)-VOFFSET]=value
            else
                // new red
                static if (DEBUG_MODE) then
                    if(GetHandleId(t)-OFFSET<0) then
                        call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                    endif
                endif
                set data[GetHandleId(t)-OFFSET]=value
            endif        
        endfunction
    
        function GetTimerData takes timer t returns integer
            static if(USE_HASH_TABLE) then
                // new blue
                return LoadInteger(ht,0,GetHandleId(t) )
                
            elseif (USE_FLEXIBLE_OFFSET) then
                // orange
                static if (DEBUG_MODE) then
                    if(GetHandleId(t)-VOFFSET<0) then
                        call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                    endif
                endif
                return data[GetHandleId(t)-VOFFSET]
            else
                // new red
                static if (DEBUG_MODE) then
                    if(GetHandleId(t)-OFFSET<0) then
                        call BJDebugMsg("SetTimerData: Wrong handle id, only use SetTimerData on timers created by NewTimer")
                    endif
                endif
                return data[GetHandleId(t)-OFFSET]
            endif        
        endfunction
    
        //==========================================================================================
        globals
            private timer array tT[ARRAY_SIZE]
            private integer tN = 0
            private constant integer HELD=0x28829022
            //use a totally random number here, the more improbable someone uses it, the better.
        endglobals
    
        //==========================================================================================
        function NewTimer takes nothing returns timer
            if (tN==0) then
                //If this happens then the QUANTITY rule has already been broken, try to fix the
                // issue, else fail.
                debug call BJDebugMsg("NewTimer: Warning, Exceeding TimerUtils_QUANTITY, make sure all timers are getting recycled correctly")
                static if( not USE_HASH_TABLE) then
                    debug call BJDebugMsg("In case of errors, please increase it accordingly, or set TimerUtils_USE_HASH_TABLE to true")
                    set tT[0]=CreateTimer()
                    static if( USE_FLEXIBLE_OFFSET) then
                        if (GetHandleId(tT[0])-VOFFSET<0) or (GetHandleId(tT[0])-VOFFSET>=ARRAY_SIZE) then
                            //all right, couldn't fix it
                            call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
                            return null
                        endif
                    else
                        if (GetHandleId(tT[0])-OFFSET<0) or (GetHandleId(tT[0])-OFFSET>=ARRAY_SIZE) then
                            //all right, couldn't fix it
                            call BJDebugMsg("NewTimer: Unable to allocate a timer, you should probably set TimerUtils_USE_HASH_TABLE to true or fix timer leaks.")
                            return null
                        endif
                    endif
                endif
            else
                set tN=tN-1
            endif
            call SetTimerData(tT[tN],0)
         return tT[tN]
        endfunction
    
        //==========================================================================================
        function ReleaseTimer takes timer t returns nothing
            if(t==null) then
                debug call BJDebugMsg("Warning: attempt to release a null timer")
                return
            endif
            if (tN==ARRAY_SIZE) then
                debug call BJDebugMsg("Warning: Timer stack is full, destroying timer!!")
    
                //stack is full, the map already has much more troubles than the chance of bug
                call DestroyTimer(t)
            else
                call PauseTimer(t)
                if(GetTimerData(t)==HELD) then
                    debug call BJDebugMsg("Warning: ReleaseTimer: Double free!")
                    return
                endif
                call SetTimerData(t,HELD)
                set tT[tN]=t
                set tN=tN+1
            endif    
        endfunction
    
        private function init takes nothing returns nothing
         local integer i=0
         local integer o=-1
         local boolean oops = false
         
            static if( USE_HASH_TABLE ) then
                set ht = InitHashtable()
                loop
                    exitwhen(i==QUANTITY)
                    set tT[i]=CreateTimer()
                    call SetTimerData(tT[i], HELD)
                    set i=i+1
                endloop
                set tN = QUANTITY
            else
                loop
                    set i=0
                    loop
                        exitwhen (i==QUANTITY)
                        set tT[i] = CreateTimer()
                        if(i==0) then
                            set VOFFSET = GetHandleId(tT[i])
                            static if(USE_FLEXIBLE_OFFSET) then
                                set o=VOFFSET
                            else
                                set o=OFFSET
                            endif
                        endif
                        if (GetHandleId(tT[i])-o>=ARRAY_SIZE) then
                            exitwhen true
                        endif
                        if (GetHandleId(tT[i])-o>=0)  then
                            set i=i+1
                        endif
                    endloop
                    set tN = i
                    exitwhen(tN == QUANTITY)
                    set oops = true
                    exitwhen not USE_FLEXIBLE_OFFSET
                    debug call BJDebugMsg("TimerUtils_init: Failed a initialization attempt, will try again")               
                endloop
                
                if(oops) then
                    static if ( USE_FLEXIBLE_OFFSET) then
                        debug call BJDebugMsg("The problem has been fixed.")
                        //If this message doesn't appear then there is so much
                        //handle id fragmentation that it was impossible to preload
                        //so many timers and the thread crashed! Therefore this
                        //debug message is useful.
                    elseif(DEBUG_MODE) then
                        call BJDebugMsg("There were problems and the new timer limit is "+I2S(i))
                        call BJDebugMsg("This is a rare ocurrence, if the timer limit is too low:")
                        call BJDebugMsg("a) Change USE_FLEXIBLE_OFFSET to true (reduces performance a little)")
                        call BJDebugMsg("b) or try changing OFFSET to "+I2S(VOFFSET) )
                    endif
                endif
            endif
    
        endfunction
    
    endlibrary
    [/spoil]

    Mã:
    scope DamageRestoring
        globals
            private integer LifeBonusId = 'A000'
        endglobals
        private struct data
            unit u
            real percent
            [B]timer ti[/B]
        endstruct
    
        private function RestoreE takes nothing returns boolean
            [B]local data d = GetTimerData( GetExpiredTimer() )[/B]
            call UnitRemoveAbility(d.u, LifeBonusId)
            call SetUnitState( d.u,UNIT_STATE_LIFE, GetUnitState(d.u,UNIT_STATE_MAX_LIFE)*d.percent )
            [B]call ReleaseTimer(d.ti)[/B]
            call data.destroy(d)
            return true
        endfunction
        
        function RestoreDamage takes unit u, real damagetaken, real restoreamount returns nothing
            local real maxlife = GetUnitState(u,UNIT_STATE_MAX_LIFE)
            local real curlife = GetUnitState(u,UNIT_STATE_LIFE)
            local data d
            if curlife - (damagetaken - restoreamount) <= 0 then
            //the restore amount can't help this unit to survive, it will die so doesn't need to do anything anymore
                return
            endif
            if maxlife - curlife >= restoreamount then
                call SetUnitState( u,UNIT_STATE_LIFE,curlife + restoreamount )
                return
            endif
            set d = data.create()
            set d.u = u
            set d.percent = ( curlife - (damagetaken - restoreamount) ) / maxlife
            call UnitAddAbility( u , LifeBonusId )
            call SetUnitState( u,UNIT_STATE_LIFE, maxlife )
            [B]set d.ti = NewTimer()
            call SetTimerData( d.ti, d )
            call TimerStart( d.ti, 0.00, false, function RestoreE )[/B]
        endfunction
    endscope
    ---
    thế WE bình thường không save map mà vẫn test được à?
     
    Chỉnh sửa cuối: 25/6/10
  9. protectq2007

    protectq2007 Donkey Kong

    Tham gia ngày:
    17/10/07
    Bài viết:
    378
    ^ vừa test đúng là không chỉnh được, srr mọi người vì nói bậy ;))
    Có ai có cái minion sytem không cho em xin với :((
     
  10. ZhengHe

    ZhengHe T.E.T.Я.I.S

    Tham gia ngày:
    4/1/09
    Bài viết:
    623
    @anh Tom: cái TimerUtils khi save lại báo lỗi
    Line 2529: private outside library/scope definition
     
  11. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    copy thiếu: library TimerUtils initializer init hả ?
     
  12. ZhengHe

    ZhengHe T.E.T.Я.I.S

    Tham gia ngày:
    4/1/09
    Bài viết:
    623
    Sữa đc lỗi trên lại thêm 1 lỗi nữa chắc anh Tom phải cho em nick Y!M mới đc, kiểu này giống spam quá :(
    Line 787: Syntax error
    jass helper hiện ra cái trên còn trong library ghi thế này :
     
  13. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
  14. LeoNguyen112

    LeoNguyen112 Dragon Quest

    Tham gia ngày:
    22/5/10
    Bài viết:
    1,438
    Nơi ở:
    TP.HCM
    Cho minh` hoi xoa' leak sao vay^. Dung` call... gi` gi` chi minh` voi. Lam` trigger khong biet xoa leak
     
  15. Espeon - cool

    Espeon - cool Donkey Kong

    Tham gia ngày:
    16/1/07
    Bài viết:
    314
    Ai đó làm giúp mình demo spell Shallow Grave của Dazzle không :-/
     
  16. ZhengHe

    ZhengHe T.E.T.Я.I.S

    Tham gia ngày:
    4/1/09
    Bài viết:
    623
    Dùng cái JassNewGen + Fake miss Tom post ở trên.
     
  17. rongdoVN

    rongdoVN Space Marine Doomguy Lão Làng GVN

    Tham gia ngày:
    6/9/05
    Bài viết:
    5,667
    Nơi ở:
    TS-Pri GameVN
    Tutorial-Memory-Leaks-and-Custom-Script
    chịu khó đọc kỹ topic tổng hợp hướng dẫn nhé :|
     
  18. ZhengHe

    ZhengHe T.E.T.Я.I.S

    Tham gia ngày:
    4/1/09
    Bài viết:
    623
    Ai chỉ giúp lại cái spell này :
    Đây là hướng dẫn của Luci
    Cái hướng dẫn này xài hastable nên hơi khó hiểu ai rành cái này thì hướng dẫn cụ thể hơn chút. Thanks
     
  19. bacada

    bacada Mr & Ms Pac-Man

    Tham gia ngày:
    4/5/07
    Bài viết:
    136
    các anh ơi cho em hỏi là làm thế nào để lấy được model từ 1 map nào đó. Em có nhìu map spell mà không biết cách lấy model.
     
  20. kingwar2010

    kingwar2010 T.E.T.Я.I.S

    Tham gia ngày:
    6/11/09
    Bài viết:
    554
    Nơi ở:
    TP.HCM
    Mở map ra. Vào f12 mà lấy
    mở mdxpather xem các blp liên quan là xong
     
    Last edited by a moderator: 26/6/10
Trạng thái chủ đề:
Không mở trả lời sau này.

Chia sẻ trang này