[system] unit properties bonus extras

Thảo luận trong 'World Editor' bắt đầu bởi GrudgeBoy, 31/1/12.

  1. GrudgeBoy

    GrudgeBoy Youtube Master Race

    Tham gia ngày:
    19/2/07
    Bài viết:
    80
    UNIT PROPERTIES BONUS EXTRAS SYSTEM ( UPBE )


    Version : BETA
    Creator : Kr.Linh

    I./ Lời nói đầu :
    Mấy ngày qua post cái Dynamic Group System và Items Limiter System không được mọi người ủng hộ cho lắm.:)
    Hôm nay mạo muội post thêm 1 system nữa ( không biết gọi là system có đúng không, nếu có gì sai an hem thẳng thắng góp ý nha ).
    Đối với dân làm map chắc hẳn trước đây các bạn cũng đã biết về EGUI ( giao diện đồ họa nâng cao ). Trong đó mình đã tìm thấy một vài thư viện như là : Bonus, UnitProperties,… chứa các hàm có chức năng “cộng” hoặc “trừ” các thông số thuộc tính của heroes ( Damage, Armor, Strength, Agility, Intelligence, Max Life, Max Mana, Attack Speed, Movement Speed ) là các thuộc tính không thể dùng trigger để chỉnh sửa trực tiếp được.
    Tuy nhiên khi sử dụng các hàm như BonusDamage, Armor… thì con số Bonus mình đưa vào khi cho ra thì lại không như mình mong muốn ( ra 1 số khác, cái này có lẽ do mình không biết xài ^^ ) hoặc là bị giới hạn. Nói chung là hệ thống Bonus đó không đủ tiêu chuẩn cho việc làm Map.
    Nhân lúc mình đang có 1 project thiết kế 1 map, để phục vụ cho nhu cầu, mình đã viết ra hẳn 1 hệ thống Bonus hoàn toàn mới ( tất nhiên cách thức thì vẫn dựa trên các Abilities trong Object Editor để thực hiện việc “cộng” hoặc “trừ” Bonus – cái này mình vẫn phải cám ơn các bác ở nước ngoài đã nãy ra ý tưởng này cho các hậu bối như em học hỏi và phát triển ).

    Trong phần file đính kèm có hình ảnh minh họa, bạn hãy click để xem thử nha.

    Tuy nhiên trong quá trình thiết kế hệ thống này, mình phát hiện nếu bắt chước các bác tiền bối – người sáng tạo ra Bonus trước đây sử dụng các đoạn external commands tự định sẵn thì nếu gặp người chỉ có nhu cầu sử dụng Bonus thấp hoặc chỉ một vài loại Bonus nhất định thì sẽ làm tốn thời gian load map bởi các Object được tạo ra quá nhiều mà không cần sử dụng tới. Đó là nguyên nhân mình bắt đầu thiết kế ra 1 công cụ ( ứng dụng phần mềm chạy trên nền .NET ) có khả năng tự động tạo ra các chuỗi external tùy theo số lượng Bonus người dùng muốn và tùy theo từng loại Bonus đính kèm Hướng dẫn cài đặt hệ thống cho map luôn :

    UNIT PROPERTIES BONUS EXTRAS – OBJECT CREATOR version BETA
    Tuy nhiên tool này được viết trên nền .NET 3.5 nên máy bạn phải cài .NET framework 3.5 mới chạy được. Đây là link download .NET framework 3.5 :
    http://download.microsoft.com/download/6/0/f/60fc5854-3cb8-4892-b6db-bd4f42510f28/dotnetfx35.exe

    II./ Ưu Nhược điểm :

    - Ưu :
    + Làm việc với các loại Bonus : Damage, Armor, Strength, Agility, Intelligence, Max Life, Max Mana, Attack Speed, Movement Speed.
    + Có khả năng add ( cộng ), subtract ( trừ ), Modify ( thay đổi, chỉnh sửa ), GetBonusValue ( Bonus được “cộng” hoặc “trừ” bởi chính hệ thống này, các Bonus khác thì không thể lấy được ), Clear, Clear All các loại Bonus trên.
    + Khả năng chính xác 100% ( map-maker cho add nhiêu sẽ ra bấy nhiêu, không nhiều hơn cũng không ít hơn ).
    + Sử dụng UPBE - Object Creator có khả năng tùy biến giới hạn bonus tùy theo map-maker giúp giảm thời gian load map.
    + Bonus Damage, Armor, Str, Agi, Int, Att-Speed có khả năng làm việc chính xác trên số Bonus lớn mà không phải sử dụng quá nhiều Ability Objects ( giảm thời gian load map )
    - Nhược :
    + Max Life + Max Mana + MoveSpeed vì các loại abilities dùng cho hệ thống không có khả năng thiết lập cấp độ trên unit ( Max Life, Max Mana ) và không có khả năng xếp chồng ( non-Stackable ) nên để chính xác 100% phải sử dụng khá nhiều Abilities cùng loại. Điều này khiến Map load rất lâu. Nên khi sử dụng phải chú ý sử dụng giới hạn vừa đủ.
    + Attack Speed và Movement Speed thì có thể được cộng bao nhiêu cũng được nhưng bị giới hạn bởi war như Move Speed Maximum luôn là 522.

    III./ Cài đặt và sử dụng :
    - Phần hướng dẫn cài đặt và sử dụng đã được đính kèm theo chương trình UPBE – OBJECT CREATOR bằng tiếng Việt. Có thể vừa làm vừa xem hướng dẫn luôn.
    - Còn nếu không mở chương trình mà muốn sử dụng luôn các external commands có sẵn thì chỉ cần bước sau :
    -> Mở file “UnitPropertiesBonusEx.w3x” bằng Jassnewgenpack5d ( yêu cầu có jasshelper 0.A.2.B )
    -> Copy "UnitPropertiesBonusExBase Category" và Copy luôn con unit Preloader trong Object Editor
    -> Mở map bạn ra, dán tất cả vào đó ( kể cả con dummy Preloader ), Save lại
    -> tạo 1 trigger bất kì
    -> convert sang custom script
    -> copy tất cả các đoạn external commands từ templates dán vào đó -> Save lại lần nữa ( lần này save map sẽ hơi lâu hơn lần trước )
    -> Close map
    -> Mở lại map
    -> Disable cái trigger chứa các external commands lúc nãy đi
    -> save lại lần nữa.
    -> cuối cùng mở lại map “UnitPropertiesBonusEx.w3x”, xem ở thư mục “Trigger for User Copies” có chứa các thư viện Bonus cho từng loại. Bạn muốn dùng loại nào hay nhiều loại thì cứ copy cái mình cần dán vào map của bạn, chỉnh sửa lại các giá trị trong thẻ globals...endglobals cho phù hợp ( có hướng dẫn trong chương trình UPBE - Object Creator, và các giá trị định sẵn trong các file trong thư mục Object Templates ), save lại rồi thưởng thức ^^.
    - Trong "UnitPropertiesBonusExBase Category” có phần functions tutorial, vào đó xem hướng dẫn sử dụng các hàm.


    File đã được đính kèm bên dưới. Nếu bạn nào không chạy được UPBE - Object Creator và làm biếng download .NET framework 3.5 thì mở thư mục Object Templates copy mấy dòng external save vào map và chỉnh sửa các biến giá trị cho phù hợp trong cặp thẻ globals...endglobals
     

    Các file đính kèm:

  2. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    Với max HP và max MP, đúng là có bug với 2 ability trên, tuy nhiên có thể lợi dụng được: http://www.thehelper.net/forums/showthread.php/81466-Set-Unit-Maximum-HP-and-Mana
    chỉ cần 1 max HP ability và 1 max MP ability
    ---
    với move speed thì: 23 ability, mỗi ability có 50 level :o
    522 speed rồi còn vừa đủ sao nữa?

    dùng cái này cho move speed:
    http://www.thehelper.net/forums/showthread.php/169030-SpeedMod
    http://www.thehelper.net/forums/showthread.php/133708-MoveSpeedX (có thể qua cả max 522)
    thì tốt hơn
    ---
    attack speed min là -80%, max là +400%
    nhưng system làm thừa ra một chút không sao vì khó có thể bắt user hoàn toàn sử dụng system để tăng/giảm AS

    ----------

    Về độ chính xác của BonusMod trong EGUI thì tôi không có ý kiến vì tôi không dùng EGUI.

    Về giới hạn thì tôi chắc chắn có thể tăng/giảm, có lẽ bạn chưa tìm hiểu kỹ.

    hai điều trên có lẽ phải đợi người sử dụng EGUI/BonusMod vào xác minh.
     
    Chỉnh sửa cuối: 31/1/12
  3. dh-g

    dh-g Fire in the hole!

    Tham gia ngày:
    29/8/09
    Bài viết:
    2,654
    Nơi ở:
    Q1 TP.HCM
    tớ nghĩ là không cần .NET 3.5 tại vì tớ vào folder Object Templates\Creating Agility Objects.rtf thấy trong file đó nó chỉ là //! external ObjectMerger w3a Aamk AG01 anam "Bonus Agility" aher 0 aite 1 alev 9 arac "other" Ihid 1 1 Istr 1 0 Iint 1 0 Ihid 2 1 Istr 2 0 Iint 2 0 Ihid 3 1 Istr 3 0 Iint 3 0 Ihid 4 1 Istr 4 0 Iint 4 0 Ihid 5 1 Istr 5 0 Iint 5 0 Ihid 6 1 Istr 6 0 Iint 6 0 Ihid 7 1 Istr 7 0 Iint 7 0 Ihid 8 1 Istr 8 0 Iint 8 0 Ihid 9 1 Istr 9 0 Iint 9 0 Iagi 1 1 Iagi 2 2 Iagi 3 3 Iagi 4 4 Iagi 5 5 Iagi 6 6 Iagi 7 7 Iagi 8 8 Iagi 9 9 ansf "(decimal 1)" vụ này mình có thể import trực tiếp trên map và chạy ví dụ trong hướng dẫn của tớ , tại tớ nghĩ rằng không cần phải cài đặt bên ngoài như thế :|

    còn BonusMod thì thật sự là không hoạt động được.(đã thử trong EGUI) còn về system của cậu tớ cảm thấy nó rất là rắc rối(có thể tại vì nó nhiều raw id chăng?).
     
    Chỉnh sửa cuối: 31/1/12
  4. zollback

    zollback Youtube Master Race

    Tham gia ngày:
    16/5/10
    Bài viết:
    88
    confirm là bonus mod có thể thay đổi giới hạn đc. cái movespeedx tom post ko có bản sử dụng autoindex nhỉ, ko biết đổi require thành autoindex có đc ko :s
     
    S.Dentatus thích bài này.
  5. dh-g

    dh-g Fire in the hole!

    Tham gia ngày:
    29/8/09
    Bài viết:
    2,654
    Nơi ở:
    Q1 TP.HCM
    vì AIDS thịnh hành hơn autoindex ấy mà =]], (tất nhiên là có thể! tớ tin cậu làm dc đấy :-?) hay cậu có thể sử dụng sys này

    Mã:
    library MoveSpeedXGUI /* v1.0.0.1
    *************************************************************************************
    * by Purgeandfire
    *   This library allows you to set unit movement speeds beyond 522 without bugs.
    *   This is an extension of the library MoveSpeedX, but is formatted for GUI use.
    *
    ************************************************************************************
    *
    *   SETTINGS
    
    Exemple
    Custom script:   set i = GetUnitMoveSpeedX(u)
    
    */
    globals
        private constant real PERIOD = 0.03125
            //  This is the period on which all units will be run.
            // If you lower this value, movement bonuses will be smoother,
            // but will require more processing power (lag more).
            //  Also, the lower this is, the higher the move speed can be
            // before it starts bugging on waypoints. The lowest valid
            // period is 0.00125. A period of 0.00625 is very robust.
        private constant real MARGIN = 0.01
            // This is the margin of approximation when comparing reals.
            // You will most likely not need to change this.
    endglobals
    /*
    ************************************************************************************
    *
    *    Functions
    *
    *        function GetUnitMoveSpeedX takes unit whichUnit returns real
    *           - Returns a unit movement speed. The GUI function will
    *           - not return the correct value. This function will always
    *           - return the correct value regardless of whether the unit
    *           - has a movement speed beyond 522.
    *
    ************************************************************************************
    *       
    *   HOW TO IMPLEMENT
    *   
    *       1.  Copy the trigger MoveSpeedXGUI.
    *       2.  Paste it into your map.
    *       3.  Open "Advanced -> Gameplay Constants".
    *       4.  Checkmark "Use Custom Gameplay Constants".
    *       5.  Find the field, "Movement - Unit Speed - Maximum", change
    *           that to 522.
    *       6.  Find the field, "Movement - Unit Speed - Minimum", hold
    *           shift and click, and change it to 0.
    *       7.  Read HOW TO USE. 
    *
    ************************************************************************************
    *
    *   HOW TO USE
    *
    *       This system will automatically work by itself. You can use the
    *       normal GUI function for modifying unit movement speeds. Simply
    *       use "Unit - Set Movement Speed", input whatever value you want,
    *       and you are good to go! It will handle values beyond 522 by itself.
    *
    *       HOWEVER, the GUI function will not return correct values if a unit
    *       has a movement speed greater than 522. To fix this, use the function
    *       GetUnitMoveSpeedX to return the correct value. A sample is given in
    *       the trigger "Speed Change" in the test map.
    *
    ************************************************************************************/
    
        private function ApproxEqual takes real A, real B returns boolean
            return (A >= (B - MARGIN)) and (A <= (B + MARGIN))
        endfunction
        
        private module M
            private static integer ic = 0
            private static integer ir = 0
        
            static hashtable hash = InitHashtable()
            
            thistype next 
            thistype prev
            
            unit curr
            real speed
            real x
            real y
            
            method destroy takes nothing returns nothing
                set this.next.prev = this.prev
                set this.prev.next = this.next
                set .prev = ir
                set ir    = this
                call RemoveSavedInteger(hash, 0, GetHandleId(.curr))
            endmethod
                
            private static method periodic takes nothing returns nothing
                local thistype this = thistype(0).next // first instance in list
                local real nx = 0 // the x-coordinate after tick
                local real ny = 0 // the y-coordinate after tick
                local real dx = 0 // distance between new-x and old-x
                local real dy = 0 // distance between new-y and old-y
                local real d  = 0 // distance between new point and old point
                local unit u // unit being affected  
                loop
                    exitwhen this == 0
                    set u  = .curr
                    set nx = GetUnitX(u)
                    set ny = GetUnitY(u)
                    if (not IsUnitPaused(u)) and GetUnitAbilityLevel(u, 'BSTN') == 0 and GetUnitAbilityLevel(u, 'BPSE') == 0 then
                        if not ApproxEqual(nx, .x) or not ApproxEqual(ny, .y) then
                            set dx = nx - .x
                            set dy = ny - .y
                            set d  = SquareRoot(dx * dx + dy * dy)
                            set .x = nx + dx / d * .speed
                            set .y = ny + dy / d * .speed
                            call SetUnitX(u, .x)
                            call SetUnitY(u, .y)
                        endif
                    endif
                    set this = this.next
                endloop
                set u = null
            endmethod
            
            static method create takes unit whichUnit, real newSpeed returns thistype
                local thistype this = ir
                if this == 0 then
                    set ic   = ic + 1
                    set this = ic
                else
                    set ir   = .prev
                endif
                set this.next = thistype(0).next
                set thistype(0).next.prev = this
                set thistype(0).next = this
                set this.prev  = 0
                set this.curr  = whichUnit
                set this.speed = (newSpeed - 522) * PERIOD
                set this.x     = GetUnitX(whichUnit)
                set this.y     = GetUnitY(whichUnit)
                call SaveInteger(hash, 0, GetHandleId(whichUnit), this)
                return this
            endmethod
            
            static method update takes unit whichUnit, real newSpeed returns nothing
                local thistype this = 0
                if HaveSavedInteger(hash, 0, GetHandleId(whichUnit)) then
                    set this = LoadInteger(hash, 0, GetHandleId(whichUnit))
                    if newSpeed > 522 then
                        set this.speed = (newSpeed-522)*PERIOD
                    else
                        call this.destroy()
                    endif
                elseif newSpeed > 522 then
                    call thistype.create(whichUnit, newSpeed)
                endif
            endmethod
        
            private static method onInit takes nothing returns nothing
                call TimerStart(CreateTimer(), PERIOD, true, function thistype.periodic)
            endmethod
        endmodule
        
        private struct MoveSpeedStruct extends array
            implement M
        endstruct
        
        function GetUnitMoveSpeedX takes unit whichUnit returns real
            if HaveSavedInteger(MoveSpeedStruct.hash, 0, GetHandleId(whichUnit)) then
                return (MoveSpeedStruct(LoadInteger(MoveSpeedStruct.hash, 0, GetHandleId(whichUnit))).speed/PERIOD)+522
            endif
            return GetUnitMoveSpeed(whichUnit)
        endfunction
        
        function SetUnitMoveSpeedX takes unit whichUnit, real newSpeed returns nothing
            call MoveSpeedStruct.update(whichUnit, newSpeed)
        endfunction
    
        hook SetUnitMoveSpeed SetUnitMoveSpeedX
    endlibrary
    
     
    Chỉnh sửa cuối: 31/1/12
  6. zollback

    zollback Youtube Master Race

    Tham gia ngày:
    16/5/10
    Bài viết:
    88
    chưa chắc là aids đã thịnh hành hơn autoindex đâu nhé :)) cậu có dùng cái buff framework nào ko? cái tốt nhất mà tớ biết yêu cầu autoindex cơ. nói trắng ra thì nó là abuff và ( hình như) cả thiên kiếm và havoc đều dùng :-j. các stuffs đến từ jesus4lyf đều tốt ngoại trừ cái buffstruct. đấy là lí do tớ chọn autoindex \m/
     
  7. dh-g

    dh-g Fire in the hole!

    Tham gia ngày:
    29/8/09
    Bài viết:
    2,654
    Nơi ở:
    Q1 TP.HCM
    vậy thì tớ chưa để ý lắm :-j tớ chỉ dùng thì dùng AIDS cả :|
     
  8. GrudgeBoy

    GrudgeBoy Youtube Master Race

    Tham gia ngày:
    19/2/07
    Bài viết:
    80
    @ Tom : thanks anh Tom vì có lẽ ở phần maxHP, maxMP, AS và MS mình làm giống như Dmg, Armor cho user tự ý muốn thêm bao nhiêu thì thêm nhưng mà mình vẫn đặt giới hạn bên trong
    mình làm theo kiểu thiết kế nội dung cách chơi cho map ấy, thí dụ creep ăn 1 cái cây thì AS, MS tăng dần nhưng tăng quá 400 là đã thấy bay vù vù rồi,
    về phần MS thì các bạn cứ đặt max là 550 cũng được, ít ai làm hơn 522 lắm ( mình để lên 900 vậy thui :D )
    Đúng là trong egui có thể tăng/giảm nhưng đối với 1 user bình thường ( chỉ biết dùng trigger và function thôi ) thì khi gọi thử 1 hàm add Bonus Damage 100 bonus chẳng hạn thì kết quả là 120, add 20 armor ra 40, vậy đối với người đó chẳng phải là quá rắc rối sao?
    còn system của mình thì add nhiêu ra nhiêu, lại còn có phần mềm cho user tuỳ biến nữa, hướng dẫn cũng đầy đủ ( chỉ thiếu demo map ), như thế chẳng phải là dễ dàng hơn với người đó rồi sao??? đọc hướng dẫn, làm theo, cài đặt xong, gọi hàm -> OK. Như vậy mà không làm được thì người đó phải học lại basic rồi.
    @ All : nhưng mình chắc chắn là ở properties Damage, Armor, Str, Agi, Int thì hoàn toàn không có giới hạn.
    @ dh_g : mình nghĩ là không có gì rắc rối hết, mình có ghi hướng dẫn khá cụ thể nếu bạn chạy được Object Creator mình viết.
    Mấy cái dòng external đó chẳng qua mình muốn user thoải mái hơn khỏi phải copy từng ability, enable cái trigger chứa external đó, save lại, close map, mở ra, disable cái trigger đó đi là xong, cài còn lại là tuỳ user muốn giới hạn bao nhiêu thì sửa ở trong cặp globals...endglobals thôi.
    còn cái gọi là import trực tiếp thì không hản như cậu nói. Như tớ đã nói thì mấy cái dòng external đó là tuỳ theo mức độ giới hạn bonus của user mà ra, giới hạn bao nhiêu thì external phải khác, mấy cái đó chỉ là ví dụ thôi.
    Còn việc nhiều rawcode id thì có lẽ bạn quan tâm quá mức rồi, mấy cái này bạn để ý làm gì, chỉ cần gọi hàm là xong, nếu thực sự phải để ý rawcode thì có lẽ tốc độ load map khi vào game sẽ thay đổi.
    cái này mình tạo ra thực sự là do nhà mình không có NET, không biết thực tế bên ngoài thế nào, nên làm luôn cái sys này tự xài cho project luôn. Sẵn tiện pót lên cho anh em dùng mà, mình nghĩ nó không phải là vô ích đâu.
     
    Chỉnh sửa cuối: 31/1/12
  9. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    đọc cho kỹ vào, màu đỏ hẳn hoi đấy:

    cài .NET framework để chạy cái exe, cái file exe là cái để tạo ra cái code external, ngoài ra có thể chỉnh giới hạn rồi mới tạo code. làm biếng download cái .NET framework thì hãy dùng cái template
    p.s: trong cái template có sẵn, mấy global có "private", cái này nếu không cho vào library/scope thì lỗi nên bỏ đi vì sợ nhiều người không biết sửa =))

    HAVOC lúc đầu sử dụng AIDS nhưng sau chuyển sang AutoIndex
    Thiên Kiếm thì không rõ.

    còn MoveSpeedX sử dụng AutoIndex, chờ đó, để tôi thử sửa xem.
    -----------

    vậy là BonusMod trong EGUI bị lỗi?
     
    Chỉnh sửa cuối: 31/1/12
  10. GrudgeBoy

    GrudgeBoy Youtube Master Race

    Tham gia ngày:
    19/2/07
    Bài viết:
    80
    không biết phải lỗi hay cho mình không biết xài hay không? nhưng mình thấy có vẻ còn rắc rối hơn cái của mình nữa. Nếu mình có gì sai mong các bác thông cảm bỏ qua. :D
     
  11. dh-g

    dh-g Fire in the hole!

    Tham gia ngày:
    29/8/09
    Bài viết:
    2,654
    Nơi ở:
    Q1 TP.HCM
    @Tom_Kazansky:

    cái này là MoveSpeedXGUI mà không cần đến autoindex hay AIDS, vậy không tiên ư :-s cần gì phải remake lại cái mới :-ss
    Mã:
    library MoveSpeedXGUI /* v1.0.0.1
    *************************************************************************************
    * by Purgeandfire
    *   This library allows you to set unit movement speeds beyond 522 without bugs.
    *   This is an extension of the library MoveSpeedX, but is formatted for GUI use.
    *
    ************************************************************************************
    *
    *   SETTINGS
    
    Exemple
    Custom script:   set i = GetUnitMoveSpeedX(u)
    
    */
    globals
        private constant real PERIOD = 0.03125
            //  This is the period on which all units will be run.
            // If you lower this value, movement bonuses will be smoother,
            // but will require more processing power (lag more).
            //  Also, the lower this is, the higher the move speed can be
            // before it starts bugging on waypoints. The lowest valid
            // period is 0.00125. A period of 0.00625 is very robust.
        private constant real MARGIN = 0.01
            // This is the margin of approximation when comparing reals.
            // You will most likely not need to change this.
    endglobals
    /*
    ************************************************************************************
    *
    *    Functions
    *
    *        function GetUnitMoveSpeedX takes unit whichUnit returns real
    *           - Returns a unit movement speed. The GUI function will
    *           - not return the correct value. This function will always
    *           - return the correct value regardless of whether the unit
    *           - has a movement speed beyond 522.
    *
    ************************************************************************************
    *       
    *   HOW TO IMPLEMENT
    *   
    *       1.  Copy the trigger MoveSpeedXGUI.
    *       2.  Paste it into your map.
    *       3.  Open "Advanced -> Gameplay Constants".
    *       4.  Checkmark "Use Custom Gameplay Constants".
    *       5.  Find the field, "Movement - Unit Speed - Maximum", change
    *           that to 522.
    *       6.  Find the field, "Movement - Unit Speed - Minimum", hold
    *           shift and click, and change it to 0.
    *       7.  Read HOW TO USE. 
    *
    ************************************************************************************
    *
    *   HOW TO USE
    *
    *       This system will automatically work by itself. You can use the
    *       normal GUI function for modifying unit movement speeds. Simply
    *       use "Unit - Set Movement Speed", input whatever value you want,
    *       and you are good to go! It will handle values beyond 522 by itself.
    *
    *       HOWEVER, the GUI function will not return correct values if a unit
    *       has a movement speed greater than 522. To fix this, use the function
    *       GetUnitMoveSpeedX to return the correct value. A sample is given in
    *       the trigger "Speed Change" in the test map.
    *
    ************************************************************************************/
    
        private function ApproxEqual takes real A, real B returns boolean
            return (A >= (B - MARGIN)) and (A <= (B + MARGIN))
        endfunction
        
        private module M
            private static integer ic = 0
            private static integer ir = 0
        
            static hashtable hash = InitHashtable()
            
            thistype next 
            thistype prev
            
            unit curr
            real speed
            real x
            real y
            
            method destroy takes nothing returns nothing
                set this.next.prev = this.prev
                set this.prev.next = this.next
                set .prev = ir
                set ir    = this
                call RemoveSavedInteger(hash, 0, GetHandleId(.curr))
            endmethod
                
            private static method periodic takes nothing returns nothing
                local thistype this = thistype(0).next // first instance in list
                local real nx = 0 // the x-coordinate after tick
                local real ny = 0 // the y-coordinate after tick
                local real dx = 0 // distance between new-x and old-x
                local real dy = 0 // distance between new-y and old-y
                local real d  = 0 // distance between new point and old point
                local unit u // unit being affected  
                loop
                    exitwhen this == 0
                    set u  = .curr
                    set nx = GetUnitX(u)
                    set ny = GetUnitY(u)
                    if (not IsUnitPaused(u)) and GetUnitAbilityLevel(u, 'BSTN') == 0 and GetUnitAbilityLevel(u, 'BPSE') == 0 then
                        if not ApproxEqual(nx, .x) or not ApproxEqual(ny, .y) then
                            set dx = nx - .x
                            set dy = ny - .y
                            set d  = SquareRoot(dx * dx + dy * dy)
                            set .x = nx + dx / d * .speed
                            set .y = ny + dy / d * .speed
                            call SetUnitX(u, .x)
                            call SetUnitY(u, .y)
                        endif
                    endif
                    set this = this.next
                endloop
                set u = null
            endmethod
            
            static method create takes unit whichUnit, real newSpeed returns thistype
                local thistype this = ir
                if this == 0 then
                    set ic   = ic + 1
                    set this = ic
                else
                    set ir   = .prev
                endif
                set this.next = thistype(0).next
                set thistype(0).next.prev = this
                set thistype(0).next = this
                set this.prev  = 0
                set this.curr  = whichUnit
                set this.speed = (newSpeed - 522) * PERIOD
                set this.x     = GetUnitX(whichUnit)
                set this.y     = GetUnitY(whichUnit)
                call SaveInteger(hash, 0, GetHandleId(whichUnit), this)
                return this
            endmethod
            
            static method update takes unit whichUnit, real newSpeed returns nothing
                local thistype this = 0
                if HaveSavedInteger(hash, 0, GetHandleId(whichUnit)) then
                    set this = LoadInteger(hash, 0, GetHandleId(whichUnit))
                    if newSpeed > 522 then
                        set this.speed = (newSpeed-522)*PERIOD
                    else
                        call this.destroy()
                    endif
                elseif newSpeed > 522 then
                    call thistype.create(whichUnit, newSpeed)
                endif
            endmethod
        
            private static method onInit takes nothing returns nothing
                call TimerStart(CreateTimer(), PERIOD, true, function thistype.periodic)
            endmethod
        endmodule
        
        private struct MoveSpeedStruct extends array
            implement M
        endstruct
        
        function GetUnitMoveSpeedX takes unit whichUnit returns real
            if HaveSavedInteger(MoveSpeedStruct.hash, 0, GetHandleId(whichUnit)) then
                return (MoveSpeedStruct(LoadInteger(MoveSpeedStruct.hash, 0, GetHandleId(whichUnit))).speed/PERIOD)+522
            endif
            return GetUnitMoveSpeed(whichUnit)
        endfunction
        
        function SetUnitMoveSpeedX takes unit whichUnit, real newSpeed returns nothing
            call MoveSpeedStruct.update(whichUnit, newSpeed)
        endfunction
    
        hook SetUnitMoveSpeed SetUnitMoveSpeedX
    endlibrary
    
    @GrudgeBoy:

    thật sự là BonusMod không thể xài được trong EGUI có thể tại nó lỗi :-ss

    P/S: trình độ em bây giờ tạm có thể nói là cao hơn 1 bậc nhờ có chú vương dạy bảo vài jass cơ bản =)) đủ khả năng make 1 system tồi chăng [-O<
     
  12. GrudgeBoy

    GrudgeBoy Youtube Master Race

    Tham gia ngày:
    19/2/07
    Bài viết:
    80
    Đúng là trong system này cái Att-S, M-S, và MaxHP, MP không pro hơn mấy cái sys khác nhưng đảm bảo rằng Damage, Armor, Hero Att rất pro, vừa sử dụng ít raw code vừa có giới hạn rất cao ( 999.999.999 ) xài đã luôn
     
  13. zollback

    zollback Youtube Master Race

    Tham gia ngày:
    16/5/10
    Bài viết:
    88
    Vậy cải thiện thêm mấy cái đấy đi bạn, cơ mà dùng ít abi mà lại có cái giới hạn khủng thế kia á :-O Mình tưởng mấy cái system kiểu này cái nào cũng giống nhau ở cái công thức "power of 2" ?!
     
  14. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    @Tom_Kazansky: vậy là BonusMod trong EGUI bị lỗi?
    BonusMod trong EGUI ko lỗi mà là lỗi của chính EGUI.

    @GrudgeBoy: Mấy ngày qua post cái Dynamic Group System và Items Limiter System không được mọi người ủng hộ cho lắm
    Cậu có nói đi thì tớ phải nói lại là ko biết mọi ng` thế nào. Nhưng mình rất ủng hộ các map maker làm jass cũng như dùng jass. Cậu làm system thực sự là 1 điều hiếm thấy của toàn bộ map maker Việt (nói ko hề có ngoa dụ) nên mình ủng hộ bằng cách góp ý cho cậu. Cậu đừng cho nó là ko ủng hộ. Nếu ko ủng hộ tớ đã chả vào comment. Tớ rất bùn vì tớ có làm vài cái system mà ko có ai báo lỗi hay góp ý cho mình về code hay thuật toán cũng như cách giải quyết cả... Còn người dùng chắc đếm trên đầu ngón tay của 1 bản tay...

    @GrudgeBoy: người sáng tạo ra Bonus trước đây sử dụng các đoạn external commands tự định sẵn thì nếu gặp người chỉ có nhu cầu sử dụng Bonus thấp hoặc chỉ một vài loại Bonus nhất định thì sẽ làm tốn thời gian load map bởi các Object được tạo ra quá nhiều mà không cần sử dụng tới.
    Nếu cậu cho rằng thừa và ko dùng đến thì có thể đơn giản là xóa cái thừa đi.

    Cùng so sánh 2 system
    Dung lượng code
    - của cậu thực ra dài hơn của BonusMod vì của tên kia còn có system hỗ trợ regen mana, hp và cả regen theo % nữa.
    Tốc độ thực thi code
    - của cậu chậm hơn của BonusMod vì cậu dùng Hashtable còn người ta dùng Indexer để lưu, bù lại vì có Indexer nên code của BonusMod lại có vẻ dài hơn. Nhưng map maker thì hầu như ai cũng dùng Indexer nên ko lo thừa code...
    - BonusMod có hỗ trợ SIGHT_RANGE còn của cậu 0

    Thuật toán:
    Cậu Bonus cho từng hàng đơn vị 1 (hàng đơn vị, hàng chục, hàng trăm,...)
    Còn BonusMod thì cộng lũy thừa của 2

    Ví dụ cụ thể với + 999 một chỉ số nào đó
    coi như việc thao tác với số bonus max là như nhau và ko tính chuyện lưu lại số bonus hiện tại cũng như số bonus trước đó = 0
    Bonus của GrudgeBoy sẽ làm như sau:
    - Loop 3 lần để biết 999 là số có 3 chữ số (trong này có phép toán chia và cộng)
    - Loop 3 lần để
    search từ 1 đến i để tìm ra ability rawid
    add ability + set ability level: add abil hàng đơn vị và set level = 9, tương tự cho các hàng đơn vị chục và trăm
    Tính trừ lấy dư cho lần lặp tiếp theo
    Bonus của Earth-Fury sẽ làm như sau:
    Nếu maxBonus là 1024 thì:
    Loop i=10: amount =999 < 1024(2^10)=powersOf2 (đã được tính từ trước)
    bỏ qua​
    Loop i=9: amount =999 > 512(2^9)
    +512(add ability)
    amount = 999-512= 487
    Loop i=8: amount =487 > 256(2^8)
    +256(add ability)
    amount = 487-256= 231
    ....
    Loop i=5: amount =39 > 32(2^5)
    +32(add ability)
    amount = 39-32= 7
    Loop i=4: amount =7 < 16(2^4)
    bỏ qua
    Loop i=4: amount =7 > 6(2^3)
    +6(add ability)
    amount = 7-6= 1
    ....
    Loop i=0: amount =1 == 1(2^0)
    +1(add ability)
    amount = 1-1= 0
    => Việc thực thi bonus có thể nhanh hơn 1 chút so với BonusMod tùy lượng bonus max và số cần bonus. Số cần bonus càng lớn thì càng nhanh hơn so với BonusMod

    Cách lưu số bonus hiện tại
    -Trừ BONUS_MANA_REGEN và BONUS_LIFE_REGEN_PERCENT do tự code nên lưu giá trị qua Indexer. BonusMod trực tiếp kiểm tra các rawid của bonus ability để lấy ra số (ngược với cách từ số ra abil ở trên)
    - Của cậu thì lưu ra hẳn 1 struct với vài cái array interger và vài cái integer count + Hashtable
    => vậy cách của cậu tốn RAM hơn và khi lấy ra với lưu vào thì chậm hơn sys BonusMod

    Về cách sử dụng
    - Để thay đổi số lượng bonus Max
    UnitPropertiesBonusEx cần dùng kèm 1 tool và phải down cả .Net framework để thay đổi số lượng max ability bonus
    BonusMod đã có code để gen ra cái và chỉ cần config lại mỗi cái Ability Count !
    - API thì có lẽ BonusMod là thân thiện hơn với tớ
    BonusMod: AddUnitBonus(unit, typeid , amount)
    UnitPropertiesBonusEx: UnitAddBonus$Type$(unit, amount)
    - Message để debug cũng như code kiểm soát hành động người dùng chắc chắn BonusMod hơn vì UnitPropertiesBonusEx ko có

    Thêm vài góp ý:
    - UnitRemoveAbility là kiểu gì nó cũng mất nên cậu ko cần phải
    UnitMakeAbilityPermanent = false
    - search từ 1 đến i để tìm ra ability rawid !? Tại sao ko lưu vào đúng level và lấy ra index như là số hàng trăm là ở index 3 số hàng nghìn ở index 4 ???

    Bonus cho ai đọc post tớ:
    -Sight range tăng theo từng 128 đơn vị 1. Tức là sight range nếu = 0 và từ từ + thêm 1 sau 1 khoảng thời gian thì tới khi sight = 128 mới rộng ra lần đầu tiên và tới 256 mới rộng ra thêm lần thứ 2
    - Ability của war3 ko hỗ trợ BONUS_MANA_REGEN và BONUS_LIFE_REGEN_PERCENT nên phải dùng code
    - BonusMod có thể được thấy ở đây
     
    Chỉnh sửa cuối: 3/2/12
  15. GrudgeBoy

    GrudgeBoy Youtube Master Race

    Tham gia ngày:
    19/2/07
    Bài viết:
    80
    @vuongkkk : rất cám ơn về comments của cậu và thực sự bài viết của cậu là một loạt các kinh nghiệm cho tôi. thú thật thì BonusMod của nước ngoài chuyên nghiệp hơn, nhưng thực sự để sử dụng được ( đối với map maker chưa có kinh nghiệm về jass + lập trình ) thì mình chắc chắn là khó sử dụng hơn vì đối với họ, họ cần sự chính xác tuyệt đối ( còn tốc độ nhanh chậm ) thì cũng ít quan tâm ( nói chung chỉ cần kết quả ), do vậy nếu họ nhập 1 số integer để bonus damage chẳng hạn, thì kết quả nhận được thấy khác thì họ đâu có nghĩ là 2 lũy thừa mấy đâu, nên mục đích thực sự khi mình make cái sys này là để dễ sử dụng và chính xác tuyệt đối ( đối với gà + pro ).
    Nhưng cậu có công nhận rằng một điều rằng BonusMod của mấy bác nước ngoài chỉ giới hạn đến 1023, nhưng của tôi tuy chậm hơn, code dài hơn, sử dụng nhiều raw code hơn nhưng giới hạn có thể lên được đến 999.999.999 điểm bonus không?
    còn về cái tool tôi làm cho user chẳng qua vì nghĩ cho user thôi, xài ít load ít ( vì cần sử dụng preloader ) nên lục load map sẽ mất nhiều thời gian hơn, nếu không tôi cho luôn giới hạn lên 999.999.999 điểm vô templates down về xài luôn khỏi mất công, cũng được vậy hi hi .
    Dù sao cũng rất thanks bài viết của cậu. vì đã ủng hộ cho tôi. &[]
     
    Chỉnh sửa cuối: 4/2/12
  16. vuongkkk

    vuongkkk T.E.T.Я.I.S

    Tham gia ngày:
    22/5/10
    Bài viết:
    588
    Nơi ở:
    Hà Nội
    Theo như thuật toán cũng như ví dụ tớ đã nêu thì cách bonus của họ sẽ ra được đúng số bonus mình cần. Nếu cậu thấy sai thì như tớ đã nói là sai do EGUI. Cậu nên down thử cái demo trong link tớ đưa ở bài trên để xác thực

    Công nhận là có lẽ cái của cậu có lẽ sẽ ít hơn hẳn về số lượng ability objects vì để BonusMod lên được tới giới hạn 1.048.576(2^20) điểm thì sẽ cần 20x2 ability(cho cả số âm nữa) thì của cậu để lên tới giới hạn 9.999.999 thì chỉ cần có 7x2 ability (cho cả số âm) mà thôi.

    - Nhưng nếu tốc độ thực thi code khá quan trọng(để tránh tình trạng sụt FPS). Đặc biệt với 1 số map có lượng code cần thực thi là liên tục và cao.
    - Mình cũng muốn cậu biết rằng tăng thêm vài object cũng ko có tăng thời gian load map nhiều lắm đâu. Map dota 6.1 chỉ load trong vòng 40s sau khi đã optimate 1 phần, trong khi chưa opt thì cần tới 5 phút.
    => Từ 2 điều này mình muốn các map maker nên biết cân bằng giữa tốc độ load map với tốc độ thực thi code

    Nhận xét cuối cùng của mình khi so sánh giữa 2 system này là độ chênh lệch về tốc độ load map, tốc độ xử lý, dung lượng code và độ ngốn ram chệnh lệch nhau rất ít (ko đủ để nhận ra) nên dùng system nào là tùy tâm.
    Được cái lợi hơn khi dùng system nước ngoài là hợp với ai thích bonus với 1 số lớn và được support = tiếng Việt :))

    Rất vui khi được đón thêm 1 jass-er về box WE >:D<
     
    Chỉnh sửa cuối: 4/2/12
  17. GrudgeBoy

    GrudgeBoy Youtube Master Race

    Tham gia ngày:
    19/2/07
    Bài viết:
    80
    @vuongkkk : như đã nói thì mình làm cái sys này chủ yếu là áp dụng cho 1 project map mình đang tiến hành, nên những gì mình làm thì mình nghĩ có lẽ chỉ phù hợp với map mình thôi ( có lẽ hơi cá nhân ), nên sẵn tiện upload lên cho anh em test và góp ý. Rất vui khi được đón nhận sản phẩm của mình.
    mà sao cái items Limiter SYS không có ai comment nhỉ? mình thấy nó cũng đâu tồi đâu ta.
     

Chia sẻ trang này