Topic đóng góp Snippet và System

  • Thread starter Thread starter dh-g
  • Ngày gửi Ngày gửi
gone it
 
Chỉnh sửa cuối:
Reality System 1.4c
19101994
Mã:
/*
=============================================================================
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
=============================================================================

||==||   ||=====     //\\     ||      II ======== \\  //
||  ||   ||         //  \\    ||      II    ||     \\//
||==\\   ||=====  =//====\\=  ||      II    ||      //
||   \\  ||       //      \\  ||      II    ||     //
||    \\ ||===== //        \\ ||===== II    ||    //            1.4c

                                        ||=====|| \\  // ||=====||
                                        ||         \\//  ||
                                        ||=====||   //   ||=====||
                                               ||  //           ||
                                        ||=====|| //     ||=====||

=============================================================================
oO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*Oo
=============================================================================
||  M A K E     B Y     1 9 1 0 1 9 9 4
||          Update 16/5/2013
||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
||      Requires:
||          Newgen 5d+
||          Warcraft 1.24e+
||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
||      Instal:
||          + Copy Code
||          + goto trigger */RSmain/*
||              remove one */"/"/* of */"///! external ObjectMerger"/*
||              save map
||              close map
||              open map and  add */"/"/* back
=============================================================================
oO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*OoO*Oo
=============================================================================
*/

P O S I T I O N
    +- position.create(real x, real y, real z)                              //-create a position with x,y,z
    |   +- return lastCreatedPosition3D
    |
    +- position.GetUnitPos(unit whichUnit)                                  //-create a position with x,y,z
    |   +- return lastCreatedPosition3D                                     //at unit-point
    |
    +- position.GetLocPos(location whichLoc)                                //-create a position at location
    |   +- return lastCreatedPosition3D
    |
    +- .move(real x, real y, real z)                                        //-move a position to new x,y,z
    |
    +- .destroy()                                                           //-destroy a position
    |
    +- .x                                                                   //-get x of position
    |
    +- .y                                                                   //-get y of position
    |
    +- .z                                                                   //-get z of position
    |
    +- .x=                                                                  //-set x of position
    |
    +- .y=                                                                  //-set y of position
    |
    +- .z=                                                                  //-set z of position
    
A N G L E 3 D
    +- angle3d.create(position pos1, position pos2)                         //-create a angle3d : pos1 -> pos2
    |   +- return lastCreatedAngle3D
    |
    +- angle3d.GetUnitAngle3D(unit whichUnit)                               //-create a angle3d for unit
    |   +- return lastCreatedAngle3D
    |
    +- angle3d.Angle3DBetweenPoints(location loc1,location loc2)            //-create a angle3d : loc1 -> loc2
    |   +- return lastCreatedAngle3D
    |
    +- .destroy()                                                           //-destroy a angle3d
    |
    +- .alpha                                                               //-get angle in Oxy
    |
    +- .beta                                                                //-get angle in Oxz or Oyz
    |
    +- .alpha=                                                              //-set angle in Oxy
    |
    +- .beta=                                                               //-set angle in Oxz or Oyz
    
U N I T 3 D
    +- unit3d.CreateAtPosition(player id, integer unitid, position pos, real angle)
    |   +- return lastCreatedUnit3D                                         //-create a unit3d at position
    |
    +- unit3d.create(player id, integer unitid, real x, real y, real z, real angle)
    |   +- return lastCreatedUnit3D                                         //-create a unit3d with x,y,z
    |
    +- unit3d.CreateAtOffset(real x, real y)                                //-create a unit3d on surface with x,y
    |   +- return lastCreatedUnit3D
    |
    +- unit3d.getStructId(unit whichUnit)                                   //-get struct when you just know unit
    |   +- return integer
    |
    +- .Move(position pos)                                                  //-move unit of unit3d to the position
    |
    +- .move(real x, real y, real z)                                        //-move path of effect3d to x,y,z
    |
    +- .remove()                                                            //-remove unit of unit3d and destroy(unit3d)
    |
    +- .destroy()                                                           //-just destroy(unit3d), not remove unit
    |
    +- .getPos                                                              //-get position of unit3d
    |   +- return position
    |
    +- .getPath                                                             //-get unit of unit3d
    |   +- return unit
    |
    +- .CustomValue             /*default: 0*/                              //-get custom value of unit3d
    |                                                                       //you can use it for something
    |
    +- .CustomValue=                                                        //-set custom value of unit3d
    |
    +- .created                                                             //-check: if struct is created => return true
    |   +- return boolean
    |
    +- .x                                                                   //-get x of unit of unit3d
    |
    +- .y                                                                   //-get y of unit of unit3d
    |
    +- .z                                                                   //-get z of unit of unit3d
    
E F F E C T 3 D
    +- effect3d.CreateAtPosition(position pos)                              //-create a effect3d at position
    |   +- return lastCreatedEffect3D
    |
    +- effect3d.CreateAtUnit(unit)                                          //-create a effect3d at unit
    |   +- return lastCreatedEffect3D
    |
    +- effect3d.CreateAtOffset(real x, real y)                              //-create a unit3d on surface with x,y
    |   +- return lastCreatedEffect3D
    |
    +- effect3d.create(real x, real y, real z)                              //-create a effect3d with x,y,z
    |   +- return lastCreatedEffect3D
    |
    +- effect3d.getStructId(unit whichUnit)                                 //-get struct when you just know path (it's a unit) of effect3d
    |   +- return integer
    |
    +- .add(string modelName, string attachPointName)                       //-add effect to path
    |   +- return bj_lastCreatedEffect
    |
    +- .Move(position pos)                                                  //-move path of effect3d to the position
    |
    +- .move(real x, real y, real z)                                        //-move path of effect3d to x,y,z
    |
    +- .scale(real scaleX, real scaleY, real scaleZ)                        //-you can change scale of effects on path by changing scale of path
    |
    +- .getPos                                                              //-get position of unit3d
    |   +- return position
    |
    +- .remove()                                                            //-remove path of effect3d and destroy(effect3d)
    |
    +- .destroy()                                                           //-just destroy(effect3d), not remove path
    |
    +- .getPath                                                             //-get path of effect3d
    |   +- return unit
    |
    +- .CustomValue             /*default: 0*/                              //-get custom value of unit3d
    |                                                                       //you can use it for something
    |
    +- .CustomValue=                                                        //-set custom value of unit3d
    |
    +- .setTimedLife=                                                       //-set TimedLife for effect3d
    |                                                                       //auto remove and destroy
    |
    +- .created                                                             //-check: if struct is created => return true
    |   +- return boolean
    |
    +- .x                                                                   //-get x of path of effect3d
    |
    +- .y                                                                   //-get y of path of effect3d
    |
    +- .z                                                                   //-get z of path of effect3d
    
D U M M Y
    +- effect3d.CreateAtPosition(position pos)                              //-create a dummy at position
    |   +- return lastCreatedDummy
    |
    +- effect3d.CreateAtUnit(unit)                                          //-create a dummy at unit
    |   +- return lastCreatedDummy
    |
    +- effect3d.CreateAtOffset(real x, real y)                              //-create a dummy on surface with x,y
    |   +- return lastCreatedDummy
    |
    +- effect3d.create(real x, real y, real z)                              //-create a dummy with x,y,z
    |   +- return lastCreatedDummy
    |
    +- effect3d.getStructId(unit whichUnit)                                 //-get struct when you just know path (it's a unit) of dummy
    |   +- return integer
    |
    +- .add(string modelName, string attachPointName)                       //-add effect to unit of dummy
    |   +- return bj_lastCreatedEffect
    |
    +- .Move(position pos)                                                  //-move unit of dummy to the position
    |
    +- .move(real x, real y, real z)                                        //-move unit of dummy to x,y,z
    |
    +- .scale(real scaleX, real scaleY, real scaleZ)                        //-change scale of unit of dummy
    |                                                                       //note: scale of effect is attached on unit will change too
    |
    +- .getPos                                                              //-get position of dummy
    |   +- return position
    |
    +- .destroy()                                                           //-remove and destroy all
    |
    +- .getPath                                                             //-get unit of dummy
    |   +- return unit
    |
    +- .getEfx                                                              //-get effect is attached
    |   +- return effect
    |
    +- .CustomValue             /*default: 0*/                              //-get custom value of dummy
    |                                                                       //you can use it for something
    |
    +- .CustomValue=                                                        //-set custom value of dummy
    |
    +- .setTimedLife=                                                       //-set TimedLife for dummy
    |                                                                       //auto destroy
    |
    +- .created                                                             //-check: if struct is created => return true
    |   +- return boolean
    |
    +- .x                                                                   //-get x of unit of dummy
    |
    +- .y                                                                   //-get y of unit of dummy
    |
    +- .z                                                                   //-get z of unit of dummy
    
O T H E R S
    +- PolarProjection3D(position pos, real dist, angle3d ang)              //-Polar 3D
    |   +- return position
    |
    +- DistanceBetweenPositions(position pos1, position pos2)               //-Distance: Pos1 -> Pos2
    |   +- return real
    |
    +- DistanceBetweenUnits(unit a, unit b)                                 //-Distance: UnitA -> UnitB
    |   +- return real                                                      //just x,y
    |
    +- Distance3DBetweenUnits(unit a, unit b)                               //-Distance: UnitA -> UnitB
    |   +- return real                                                      //3D with x,y,z
    |
    +- DistanceBetweenUnit3Ds(unit3d a, unit3d b)                           //-Distance: Unit3D_A -> Unit3D_B
    |   +- return real                                                      //3D
    |
    +- DistanceBetweenEffect3Ds(effect3d a, effect3d b)                     //-Distance: Effect3D_A -> Effect3D_B
    |   +- return real                                                      //3D
    |
    +- DistanceBetweenUnit3DAndEffect3D(unit3d a, effect3d b)               //-Distance: Unit3D_A -> Effect3D_B
        +- return real                                                      //3D

Một số công dụng:

1. Cho phép tính góc trong Oxyz (3D) từ đó lấy Polar 3D. Dễ hiểu hơn là so sánh với angle có sẵn của warcraft thì chỉ có thể lấy góc từ vị trí A -> B trong Oxy (2D), angle3d của sys cho phép lấy góc từ A -> B nhưng trong Oxyz.
=> nếu A ở vị trí thấp hơn B thì lấy Polar 3D với distance (tự cho) góc angle3d từ A->B thì ta sẽ được các điểm đi từ A -> B NHƯNG là đường thẳng trên không nối liền 2 điểm A, B chứ KHÔNG PHẢI là các điểm từ A -> B trên mặt đất như khi lấy Polar của war.
Từ đó mở rộng ra ta có thể làm các hiệu ứng đi kèm như:
- Knock back chéo lên trời hay văng vào ngọn núi nào đó >:D<
- Tạo các spell hoành tráng có effect trên không bắn vào target

2. unit3d cho phép tạo unit trong Oxyz (bình thường thì phải tạo rùi add/remove CROWFORM rùi nâng FlyHeight), quản lí type: "unit3d" như type: "unit".

3. effect3d cho phép tạo effect trên không (thường thì tạo unit rùi attach model vào), một effect3d có thể chứa nhiều model effect (tìm hiểu hàm .add), move trong hệ trục Oxyz, chỉnh kích cỡ effect (hàm .scale), hẹn time remove effect (hàm .setTimedLife).

4. dummy cũng như unit3d nhưng tại sao phải tách riêng? Đơn giản là tôi muốn quản lí dễ dàng hơn. Đồng thời kết hợp khả năng của 2 thằng unit3d và effect3d lại.

5. position (3D) thay thế location (2D)

6. angle3d tính góc trong Oxyz (chéo lên, chéo xuống, hướng nào cũng được tất)

7. đi kèm 1 số hàm tính distance 3D nếu xài distance của war thì khi 2 unit A(0,0) và B(0,100) thì distance sẽ cho ra 100 dù cho B ở vị trí cao hơn A cả ngàn thước đi chăng nữa =)) vì vậy mà mềnh làm mí cái distance 3D là zậy.

Và còn cách công dụng khác tùy cách bạn sử dụng nó :D

Link down:
http://www.mediafire.com/?v7gg02b9kyufgdw

P/s: kiểm duyệt sản phẩm trước khi ấn bản nào :))
 
. .
 
Chỉnh sửa cuối:
. .
 
Chỉnh sửa cuối:
RepeatData32 version 7b

Mã:
library RepeatData //version 0.7b by Daric & imp by dhguardianes, 19101994
//***************************************************************************************************
//*             ____                       _   ____        _          _________  
//*            |  _ \ ___ _ __   ___  __ _| |_|  _ \  __ _| |_ __ _  |___ /___ \ 
//*            | |_) / _ \ '_ \ / _ \/ _` | __| | | |/ _` | __/ _` |   |_ \ __) |
//*            |  _ <  __/ |_) |  __/ (_| | |_| |_| | (_| | || (_| |  ___) / __/ 
//*            |_| \_\___| .__/ \___|\__,_|\__|____/ \__,_|\__\__,_| |____/_____|
//*                      |_| 
//* This system similar to T32 but has been improve  it's easy and convenient to use
//* 
//*  R32_Tick is count number of iterations in cycle.
//*  - Easy to use
//*  - MUI for spell
//*  - Store data by Struct
//*  
//*  - method onStart takes nothing returns nothing
//*  - method onLoop takes nothing returns nothing
//*  - method onEnd takes nothing returns nothing
//***************************************************************************************************
    globals
                            integer     R32_Tick    = 0 //very useful.
        constant            real        R32_PERIOD  = .031250000
        private             integer     tT          = 0
        private             timer       rTimer      = CreateTimer()
        private constant    boolean     TestMode    = true
    endglobals

    private interface RepeatFace
        method onStart takes nothing returns nothing defaults nothing
        method onLoop  takes nothing returns nothing defaults nothing
        method onEnd   takes nothing returns nothing defaults nothing
    endinterface
    
struct RepeatData extends RepeatFace
    public integer rpt
    public real rL
    public integer rtik
    public integer mtik
    
    private thistype next
    private thistype prev
    
    private static thistype head=0
    private static thistype tail=0
    static method create takes real Loop, real maxLoop returns thistype
        local thistype this = thistype.allocate()
        if .tail==0 then
            set .tail=this
        endif
        //
        if .head==0 then
            call TimerStart(rTimer,R32_PERIOD,true,function thistype.rpLoop)
        endif
        //
            set this.next=.head
            set this.prev=0
            if .head!=0 then
                set .head.prev=this
            endif
            set .head=this
            //
            set this.rL=Loop
            if Loop==0 then
                set this.mtik=0
            else
                if maxLoop==0 then
                    set this.mtik=999999
                else
                    set this.mtik=R2I(maxLoop/R32_PERIOD) + tT
                endif
            endif
            set this.rpt=0
            set this.rtik=R2I(Loop/R32_PERIOD) + tT
        return this
    endmethod
    
    method stop takes nothing returns nothing
        set this.mtik=0
        static if TestMode then
            call BJDebugMsg("R32 Release: "+I2S(this))
        endif
    endmethod
    
    method onDestroy takes nothing returns nothing
        if this.prev==0 then
            set this.next.prev=0
            set .head=this.next
        else
            set this.next.prev=this.prev
        endif
        if this.next==0 then
            set this.prev.next=0
            set .tail=this.prev
        else
            set this.prev.next=this.next
        endif
    endmethod
    
    static method rpLoop takes nothing returns nothing
        local thistype this=.head
        local thistype nex=0
        set tT=tT+1
        loop
            exitwhen this==0
            if this.rpt==0 then
                call this.onStart()
            endif
            if this.rtik<=tT then
                set this.rpt=this.rpt+1
                set R32_Tick=this.rpt
                static if TestMode then
                    debug call BJDebugMsg("R32 S: "+I2S(this)+ " T: "+I2S(R32_Tick))
                endif
                call this.onLoop()
                if this.mtik<=tT then
                    call this.onEnd()
                    set nex=this.next
                    call this.destroy()
                    set this=nex
                else
                    set this.rtik=R2I(this.rL/R32_PERIOD) + tT
                    set this=this.next
                endif
            else
                set this=this.next
            endif
        endloop
        if .head==0 then
            set tT=0
            call PauseTimer(rTimer)
        endif
    endmethod
endstruct
endlibrary

Cách thức sử dụng giữ nguyên.
Viết lại code hoàn toàn, tốc độ xấp xĩ T32 (theo dh-gà test)
 
gone it
 
Chỉnh sửa cuối:
RandomSeed

PHP:
library RandomSeed initializer Init
globals
    private constant integer MAX_SEED   =999
    private          integer MAX_CHANGE =5

    private timer T
    private integer Seed
    
    private real    array PeriodTime
    private integer array PlusSeed
    private integer TimerCount
    
    private integer i=0
    private integer TempInt =0
    private real    TempReal=0
endglobals
private function ChangeSeed takes nothing returns nothing
    if Seed<MAX_SEED then
        set i=GetRandomInt(0,2)
        set Seed=Seed+PlusSeed[i]
        
        set TempInt=PlusSeed[i]
        set PlusSeed[i]=PlusSeed[MAX_CHANGE]
        set PlusSeed[MAX_CHANGE]=TempInt
    else
        set Seed=1
    endif
    call SetRandomSeed(Seed)
    
    call TimerStart(T, PeriodTime[TimerCount],false, function ChangeSeed)
    set TempReal=PeriodTime[TimerCount]
    set PeriodTime[TimerCount]=PeriodTime[MAX_CHANGE]
    set PeriodTime[MAX_CHANGE]=TempReal
    if TimerCount==0 then
        set TimerCount=MAX_CHANGE
    else
        set TimerCount=TimerCount-1
    endif
endfunction

function IsSuccess takes integer percent returns boolean
    return percent>=GetRandomInt(0,100)
endfunction

private function Init takes nothing returns nothing
set i=0
set MAX_CHANGE=MAX_CHANGE-1
loop
    set PeriodTime[i]=I2R(i+1)/10.
    set PlusSeed[i]  =i+1
    exitwhen i==MAX_CHANGE
    set i=i+1
endloop

    set T=CreateTimer()
    call TimerStart(T, PeriodTime[i],false, function ChangeSeed)
    
    set Seed=GetRandomInt(1,MAX_SEED)
    call SetRandomSeed(Seed)
    
    set TimerCount=GetRandomInt(0,MAX_CHANGE)
endfunction
endlibrary

Cách hoạt động của hàm Random?
Hiểu sơ bộ thì là truyền vào 1 cái gọi là nhân (seed).
Hàm random sẽ dùng cái nhân đó để tính toán ra cái gì sẽ đi ra.
Bản thân hàm random cũng nhận thêm 2 đối số nữa để giới hạn kết quả đầu ra (min và max có thể random ra được)
Tóm lại kết quả của hàm random tùy vào 3 giá trị seed, min và max

Vấn đề
Có thể có những lúc bạn thấy việc Random của war3 hơi điêu :-s Mình cũng có thằng bạn chơi war3 kêu vậy và bản thân mình cũng mới gặp điều này.

Cách giải quyết vấn đề này?
Min và max thì sẽ do bạn, người làm map quyết định tùy theo việc bạn định làm là gì
Seed thì theo như mặc định sẽ chỉ được thiết lập 1 lần khi khởi tạo map

May mắn thay Blizzard cho phép ta có thể thay đổi cái seed này
Vậy nếu bản thân cái seed này cũng random và thay đổi liên tục theo thời gian thì chúng ta có thể yên tâm hàm random sẽ cho ra kết quả "bất ổn định" hơn (Thứ ta cần đây :)) )
Đây cũng chính là những gì code này thực hiện!

Cách dùng system?
Chỉ phải nhét code vào map thôi là xong :D Tự nó chạy mà @@

Bonus
function IsSuccess takes integer percent returns boolean
- percent = xác suất, tỉ lệ thành công tính = %
- Trả về true nếu thành công và ngược lại trả ra false

Note
- Code này trong map sẽ có tác dụng cho cả hàm random của GUI nữa!
- Tớ đã test thử trong 1 map hẳn hoi rồi & tự cảm thấy hài lòng (Ko phải quảng cáo đâu >,<)
 
Chỉnh sửa cuối:

MISC
19101994

Mã:
[COLOR="#FF8C00"]/*====================================================================================================
            M A K E   B Y   1 9 1 0 1 9 9 4
                Update: 16/5/2013
    Instal:
        Just Copy code
    Requires:
        Newgen or X Design
        Warcraft 1.24e+
====================================================================================================
                                    F U N C T I O N S
            PolarX                      (real x, real dist, real angle)                                 ->  real
            PolarY                      (real y, real dist, real angle)                                 ->  real
            PolarProjection             (real x, real y, real dist, real angle)
                |___    You can use Misc_X1 and Misc_Y1 <=> returns of PolarX and PolarY
            RAbs                        (real)                                                          ->  real
            IAbs                        (integer)                                                       ->  integer
            Distance                    (real x1, real y1, real x2, real y2)                            ->  real
            Angle                       (real x1, real y1, real x2, real y2)                            ->  real
            Fibonacci                   (integer)                                                       ->  integer
            UnitHasItemId               (unit whichUnit, integer itemId)                                ->  integer
                |___    It count and return num.Item
            ParabolZ                    (real distance, real dist_run, real height)                     ->  real
            LineZ                       (real dist_run, real alpha)                                     ->  real
            CircleZ                     (real distance, real dist_run)                                  ->  real
            HeartY                      (real a, real MaxSize, real x)
                |___    return Y1 and Y2
            SpecialEffect_Heart         (real X, real Y, real aoe, real d, string sfx, real angle)
            UnitsInGroup                (group)                                                         ->  integer
            AddGroup                    (group dest, group source)
            RemoveGroup                 (group dest, group source)
constant    ConvertATtoINT              (attacktype)                                                    ->  integer
constant    ConvertDTtoINT              (damagetype)                                                    ->  integer
            GetRectFromCircle           (real x, real y, real aoe returns rect)
            EnumDestructablesInCircle   (real x, real y, real radius, code actionFunc)
            GetMinimumInteger           (integer x, integer LIMIT)
            GetMinimumReal              (real x, real LIMIT)
            GetMaximumInteger           (integer x, integer LIMIT)
            GetMaximumReal              (real x, real LIMIT)
            PauseAllUnits               (boolean pause)
            OpenGate                    (destructable whichGate)
            CloseGate                   (destructable whichGate)
            DestroyGate                 (destructable whichGate)
            CountPlayersInForce         (force whichForce)
            GetUnitLevelFromId          (integer unitid)                                                ->  integer
constant    notI                        (integer)                                                       ->  integer
                |___    1 => 0 and 0 => 1
constant    I2B                         (integer)                                                       ->  boolean
                |___    1 => true and 0 => false
constant    B2I                         (boolean)                                                       ->  integer
                |___    false => 0 and true => 1
====================================================================================================*/[/COLOR]
library Misc
    
    globals
        public  real                    X1      =       0
        public  real                    Y1      =       0
        public  real                    X2      =       0
        public  real                    Y2      =       0
    endglobals
    
/**/function PolarX takes real x, real dist, real angle returns real
        return x + dist*Cos(angle*bj_DEGTORAD)
    endfunction
     
/**/function PolarY takes real y, real dist, real angle returns real
        return y + dist*Sin(angle*bj_DEGTORAD)
    endfunction
    
/**/function PolarProjection takes real x, real y, real dist, real angle returns nothing
        set X1 = x + dist*Cos(angle*bj_DEGTORAD)
        set Y1 = y + dist*Sin(angle*bj_DEGTORAD)
    endfunction
    
    //! textmacro Abs takes A, B
/**/function $A$ takes $B$ a returns $B$
        if a < 0 then
            return -a
        endif
        return a
    endfunction
    //! endtextmacro
    //! runtextmacro Abs("RAbs","real")
    //! runtextmacro Abs("IAbs","integer")
    
/**/function Distance takes real x1, real y1, real x2, real y2 returns real
        return SquareRoot((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
    endfunction
    
/**/function Angle takes real x1, real y1, real x2, real y2 returns real
        return bj_RADTODEG*Atan2(y2-y1,x2-x1)
    endfunction
    
/**/function ParabolZ takes real distance, real dist_run, real height returns real
        return ((4*height*dist_run)/distance)*(1-(dist_run/distance))
    endfunction
    
/**/function LineZ takes real dist_run, real alpha returns real
        return Tan(alpha*bj_DEGTORAD)*dist_run
    endfunction
    
/**/function CircleZ takes real distance, real dist_run returns real
        return SquareRoot(((distance/2)*(distance/2))-(RAbs((distance/2)-dist_run)*RAbs((distance/2)-dist_run)))
    endfunction
    
/**/function Fibonacci takes integer n returns integer
        local integer array i
        if n <= 1 then
            return n
        endif
        set i[0] = 0
        set i[1] = 1
        set i[3] = 2
        loop
            set i[2]=i[0]+i[1]
            set i[0]=i[1]
            set i[1]=i[2]
            set i[3]=i[3]+1
            exitwhen i[3]>n
        endloop
        return i[2]
    endfunction
    
/**/function HeartY takes real a, real MaxSize, real x returns nothing
        if x > RAbs(MaxSize) then
            debug call BJDebugMsg("Math Error!")
            return
        endif
        set Y1 = a*RAbs(x) + SquareRoot(MaxSize*MaxSize - x*x)
        set Y2 = a*RAbs(x) - SquareRoot(MaxSize*MaxSize - x*x)
    endfunction
    
/**/function UnitHasItemId takes unit whichUnit, integer itemId returns integer
        local integer index = 0
        set bj_forLoopAIndex = 0
        loop
            if GetItemTypeId(UnitItemInSlot(whichUnit, bj_forLoopAIndex)) == itemId then
                set index = index + 1
            endif
            set bj_forLoopAIndex = bj_forLoopAIndex + 1
            exitwhen bj_forLoopAIndex >= bj_MAX_INVENTORY
        endloop
        set whichUnit = null
        return index
    endfunction
    
/**/function SpecialEffect_Heart takes real X, real Y, real aoe, real d, string sfx, real angle returns nothing
        local real x = aoe
        local real y
        loop
            call HeartY(.75,aoe,x)
            set y = PolarY(Y,Distance(0,0,x,Y1),Angle(0,0,x,Y1))
            call DestroyEffect(AddSpecialEffect(sfx,PolarX(X,Distance(X,Y,X+x,y),Angle(X,Y,X+x,y)+angle),PolarY(Y,Distance(0,0,x,Y1),Angle(0,0,x,Y1)+angle)))
            set y = PolarY(Y,Distance(0,0,x,Y2),Angle(0,0,x,Y2))
            call DestroyEffect(AddSpecialEffect(sfx,PolarX(X,Distance(X,Y,X+x,y),Angle(X,Y,X+x,y)+angle),PolarY(Y,Distance(0,0,x,Y2),Angle(0,0,x,Y2)+angle)))
            set x = x - d
            exitwhen x < -aoe
        endloop
        set sfx = null
    endfunction
    
/**/function UnitsInGroup takes group g returns integer
        set bj_groupCountUnits = 0
        call ForGroup(g,function CountUnitsInGroupEnum)
        set g = null
        return bj_groupCountUnits
    endfunction
    
/**/function AddGroup takes group dest, group source returns nothing
        set bj_groupAddGroupDest = dest
        call ForGroup(source, function GroupAddGroupEnum)
        set source = null
        set dest = null
    endfunction
    
/**/function RemoveGroup takes group dest, group source returns nothing
        set bj_groupAddGroupDest = dest
        call ForGroup(source, function GroupAddGroupEnum)
        set source = null
        set dest = null
    endfunction
    
/**/constant function ConvertATtoINT takes attacktype at returns integer
        if at == ATTACK_TYPE_HERO then
            return 6
        elseif at == ATTACK_TYPE_MELEE then
            return 1
        elseif at == ATTACK_TYPE_PIERCE then
            return 2
        elseif at == ATTACK_TYPE_SIEGE then
            return 3
        elseif at == ATTACK_TYPE_MAGIC then
            return 4
        elseif at == ATTACK_TYPE_CHAOS then
            return 5
        endif
        return 0 //NORMAL
    endfunction
    
/**/constant function ConvertDTtoINT takes damagetype dt returns integer
        if dt == DAMAGE_TYPE_ACID then
            return 16
        elseif dt == DAMAGE_TYPE_COLD then
            return 9
        elseif dt == DAMAGE_TYPE_DEATH then
            return 18
        elseif dt == DAMAGE_TYPE_DEFENSIVE then
            return 21
        elseif dt == DAMAGE_TYPE_DEMOLITION then
            return 22
        elseif dt == DAMAGE_TYPE_DISEASE then
            return 12
        elseif dt == DAMAGE_TYPE_DIVINE then
            return 13
        elseif dt == DAMAGE_TYPE_ENHANCED then
            return 5
        elseif dt == DAMAGE_TYPE_FIRE then
            return 8
        elseif dt == DAMAGE_TYPE_FORCE then
            return 17
        elseif dt == DAMAGE_TYPE_LIGHTNING then
            return 10
        elseif dt == DAMAGE_TYPE_MAGIC then
            return 14
        elseif dt == DAMAGE_TYPE_MIND then
            return 19
        elseif dt == DAMAGE_TYPE_UNKNOWN then
            return 0
        elseif dt == DAMAGE_TYPE_PLANT then
            return 20
        elseif dt == DAMAGE_TYPE_POISON then
            return 11
        elseif dt == DAMAGE_TYPE_SHADOW_STRIKE then
            return 25
        elseif dt == DAMAGE_TYPE_SLOW_POISON then
            return 23
        elseif dt == DAMAGE_TYPE_SONIC then
            return 15
        elseif dt == DAMAGE_TYPE_SPIRIT_LINK then
            return 24
        elseif dt == DAMAGE_TYPE_UNIVERSAL then
            return 26
        endif
        return 4//NORMAL
    endfunction
    
/**/function GetRectFromCircle takes real x, real y, real aoe returns rect
        return Rect(x - aoe, y - aoe, x + aoe, y + aoe)
    endfunction
    
/**/function EnumDestructablesInCircle takes real x, real y, real radius, code actionFunc returns nothing
        local rect r
        if (radius > 0) then
            set r = GetRectFromCircle(x,y,radius)
            call EnumDestructablesInRect(r,null,actionFunc)
            call RemoveRect(r)
            set r = null
        endif
        set actionFunc = null
    endfunction
    
    //! textmacro Minimum takes A, B, C
    function GetMinimum$A$ takes $B$ returns $C$
        if a < b then
            return b
        endif
        return a
    endfunction
    //! endtextmacro
    //! runtextmacro Minimum ("Integer","integer a, integer b","integer")
    //! runtextmacro Minimum ("Real","real a, real b","real")
    
    //! textmacro Maximum takes A, B, C
    function GetMaximum$A$ takes $B$ returns $C$
        if a > b then
            return b
        endif
        return a
    endfunction
    //! endtextmacro
    //! runtextmacro Maximum ("Integer","integer a, integer b","integer")
    //! runtextmacro Maximum ("Real","real a, real b","real")
    
    function PauseAllUnits takes boolean pause returns nothing
        local group g = CreateGroup()
        local unit f
        call GroupEnumUnitsInRect(g,bj_mapInitialPlayableArea,null)
        loop
            set f = FirstOfGroup(g)
            exitwhen f==null
            call PauseUnit(f,pause)
            call GroupRemoveUnit(g,f)
        endloop
        call DestroyGroup(g)
        set g = null
    endfunction
    hook PauseAllUnitsBJ PauseAllUnits
    
    function OpenGate takes destructable d returns nothing
        call KillDestructable(d)
        call SetDestructableAnimation(d,"death alternate")
    endfunction
    
    function DestroyGate takes destructable d returns nothing
        call KillDestructable(d)
        call SetDestructableAnimation(d,"death")
    endfunction
    
    function CloseGate takes destructable d returns nothing
        call DestructableRestoreLife(d,GetDestructableMaxLife(d),true)
        call SetDestructableAnimation(d,"stand")
    endfunction
    
    function CountPlayersInForce takes force f returns integer
        set bj_forceCountPlayers = 0
        call ForForce(f, function CountPlayersInForceEnum)
        set f = null
        return bj_forceCountPlayers
    endfunction
    
    function GetUnitLevelFromId takes integer unitid returns integer
        local unit u = CreateUnit(Player(15),unitid,0,0,0)
        local integer level = GetUnitLevel(u)
        call RemoveUnit(u)
        set u = null
        return level
    endfunction
    
    constant function notI takes integer i returns integer
        if i==0 then
            return 1
        endif
        return 0
    endfunction
    
    //! textmacro IntAndBool takes A, B, C, D, E, F
    constant function $A$ takes $B$ returns $C$
        if $D$ then
            return $E$
        endif
        return $F$
    endfunction
    //! endtextmacro
    //! runtextmacro IntAndBool ("I2B","integer i","boolean","i==1","true","false")
    //! runtextmacro IntAndBool ("B2I","boolean b","integer","b==false","0","1")
endlibrary

1 cái cùi mía viết lâu rùi, up lên cho topic chui lên trên

cách xài không có, đơn giản chỉ là 1 số hàm nhỏ khá hữu dụng cho map
 
Framework 1.09 (4/7/2014)

PHP:
/*====================================================================================================
//  FrameWork   1.09    by  19101994    update  7/4/2014 (mm/dd/yyyy)
//====================================================================================================
//
//  Instal:
//      - Just copy
//
//
*/
globals//==============================C=O=N=F=I=G==============================
    constant    boolean             USE_BIG_FRAME       =       true
        /*allow use FRAME2000m  = 2.000000000
                    FRAME4000m  = 4.000000000
                    FRAME8000m  = 8.000000000*/
endglobals//====================================================================
/*
//
//
//  How to use:
//      - demo and summary





*/
// S U M M A R Y
//! novjass
library Framework
    ( N={64,32,16,08,04,02,01,2s,4s,8s} )
        note: {2s,4s,8s} are allowed when USE_BIG_FRAME = true
    VARs:
        Framework_FRAME<N> //Example Framework_FRAME01 = 1.000000000
    FUNCTIONs:
        function AddFrame<N>    takes frame f                 , boolean instant returns nothing     //add struct to frameN. Example: frame32 => loop(method update) 1/32s
        function AddFrameAuto   takes frame f,      real delay, boolean instant returns nothing     //add struct to frame?, auto select frame for delay
    
    //lvl_1 <= not delay, run every 1/32s
    //you can use tick
    public module begin
        //code
        //finish-conditions or not
        //  return true == loop
        //    return false == stop
    public module end
    
    
    //lvl_2
    //you can use tick and TickDelay = ConvertDELAYtoTICK( real delay )
    runtextmacro Framework_begin takes DELAY
        //code
    runtextmacro Framework_null
        //finish-conditions or not
        //  return true == loop
        //    return false == stop
    runtextmacro Framework_end
endlibrary
//! endnovjass
/*





*/

//====================================================================================================

//====================================================================================================

//====================================================================================================

library Framework
    interface frame
        method update   takes   real    whichFrame  returns boolean
        method end      takes   nothing             returns nothing defaults    nothing
    endinterface
    
    //! textmacro FRAMEWORK_VARIABLES takes NAME
        private integer         $NAME$_nFrame  =   0
        private frame   array   $NAME$_saver
        private timer           $NAME$_timer   =   CreateTimer()
    //! endtextmacro
    globals
        public  constant    real    FRAME64     =   0.015625000
            //! runtextmacro FRAMEWORK_VARIABLES ("FRAME64")
        public  constant    real    FRAME32     =   0.031250000
            //! runtextmacro FRAMEWORK_VARIABLES ("FRAME32")
        public  constant    real    FRAME16     =   0.062500000
            //! runtextmacro FRAMEWORK_VARIABLES ("FRAME16")
        public  constant    real    FRAME08     =   0.125000000
            //! runtextmacro FRAMEWORK_VARIABLES ("FRAME08")
        public  constant    real    FRAME04     =   0.250000000
            //! runtextmacro FRAMEWORK_VARIABLES ("FRAME04")
        public  constant    real    FRAME02     =   0.500000000
            //! runtextmacro FRAMEWORK_VARIABLES ("FRAME02")
        public  constant    real    FRAME01     =   1.000000000
            //! runtextmacro FRAMEWORK_VARIABLES ("FRAME01")
    endglobals
static if USE_BIG_FRAME then
    globals
        public  constant    real    FRAME2s  =   2.000000000
            //! runtextmacro FRAMEWORK_VARIABLES ("FRAME2s")
        public  constant    real    FRAME4s  =   4.000000000
            //! runtextmacro FRAMEWORK_VARIABLES ("FRAME4s")
        public  constant    real    FRAME8s  =   8.000000000
            //! runtextmacro FRAMEWORK_VARIABLES ("FRAME8s")
    endglobals
endif
    //! textmacro FRAMEWORK_FUNCTIONS takes TYPE
    private function DoTheLoop$TYPE$ takes nothing returns nothing
        local integer i = 0
        loop
            exitwhen i==FRAME$TYPE$_nFrame
            if FRAME$TYPE$_saver[i].update(FRAME$TYPE$) then
                set i=i+1
            else
                call FRAME$TYPE$_saver[i].end()
                set FRAME$TYPE$_nFrame=FRAME$TYPE$_nFrame-1
                if FRAME$TYPE$_nFrame==0 then
                    call PauseTimer(FRAME$TYPE$_timer)
                else
                    set FRAME$TYPE$_saver[i]=FRAME$TYPE$_saver[FRAME$TYPE$_nFrame]
                endif
            endif
        endloop
    endfunction
    function AddFrame$TYPE$ takes frame f, boolean instant returns nothing
        if FRAME$TYPE$_nFrame==0 then
            call TimerStart(FRAME$TYPE$_timer,FRAME$TYPE$,true,function DoTheLoop$TYPE$)
        endif
        set FRAME$TYPE$_saver[FRAME$TYPE$_nFrame] = f
        set FRAME$TYPE$_nFrame=FRAME$TYPE$_nFrame+1
        if instant then
            call f.update(FRAME$TYPE$)
        endif
    endfunction
    //! endtextmacro
    //! runtextmacro FRAMEWORK_FUNCTIONS ("64")
    //! runtextmacro FRAMEWORK_FUNCTIONS ("32")
    //! runtextmacro FRAMEWORK_FUNCTIONS ("16")
    //! runtextmacro FRAMEWORK_FUNCTIONS ("08")
    //! runtextmacro FRAMEWORK_FUNCTIONS ("04")
    //! runtextmacro FRAMEWORK_FUNCTIONS ("02")
    //! runtextmacro FRAMEWORK_FUNCTIONS ("01")
static if USE_BIG_FRAME then
    //! runtextmacro FRAMEWORK_FUNCTIONS ("2s")
    //! runtextmacro FRAMEWORK_FUNCTIONS ("4s")
    //! runtextmacro FRAMEWORK_FUNCTIONS ("8s")
endif
    
    function AddFrameAuto takes frame f, real delay, boolean instant returns nothing
        if false then
static if USE_BIG_FRAME then
        elseif delay/Framework_FRAME8s >= 16.00 then
            call  AddFrame8s(f,instant)
        elseif delay/Framework_FRAME4s >= 15.00 then
            call  AddFrame4s(f,instant)
        elseif delay/Framework_FRAME2s >= 14.00 then
            call  AddFrame2s(f,instant)
endif
        elseif delay/Framework_FRAME01 >= 13.00 then
            call AddFrame01(f,instant)
        elseif delay/Framework_FRAME02 >= 12.00 then
            call AddFrame02(f,instant)
        elseif delay/Framework_FRAME04 >= 11.00 then
            call AddFrame04(f,instant)
        elseif delay/Framework_FRAME08 >= 10.00 then
            call AddFrame08(f,instant)
        elseif delay/Framework_FRAME16 >= 9.00 then
            call AddFrame16(f,instant)
        elseif delay/Framework_FRAME32 >= 8.00 then
            call AddFrame32(f,instant)
        endif
            call AddFrame64(f,instant)
    endfunction
    
    
    
    
    //lvl_1
    //you can use this.Frame_tick
    public module begin
        private integer tick = 0
        method update takes real whichFrame returns boolean
            set tick = tick + 1
    endmodule
    public module end
        endmethod
    endmodule
    
    //lvl_2
    //you can use this.Frame_tick and Frame_TickDelay = ConvertDELAYtoTICK( real delay )
    //! textmacro Framework_begin takes DELAY
        private integer tick = 0
        private integer tack = 0
        method update takes real whichFrame returns boolean
            local integer TickDelay = R2I($DELAY$/whichFrame)
            set tick = tick + 1
            if ModuloInteger(tick, TickDelay) == 0 then
                set tack = tack + 1
    //! endtextmacro
    //! textmacro Framework_null
            endif
    //! endtextmacro
    //! textmacro Framework_end
        endmethod
    //! endtextmacro
endlibrary





ServerFrame 1.06 (6/7/2014)

PHP:
/*====================================================================================================
//  ServerFrame   1.06    by  19101994    update  7/6/2014 (mm/dd/yyyy)
//====================================================================================================
//
//  Instal:
//      - Just copy
*/
//! textmacro SF_Instal
        private constant    integer     MAX_CLIENT_ON_A_SERVER  =   16 //16 is best
//! endtextmacro
/*
//
//  Functions:
//      AddFrameAuto(   cframe f,     real delay,     boolean instant  )
//      AddFrame8s  (   cframe f,                     boolean instant  )
//      AddFrame4s  (   cframe f,                     boolean instant  )
//      AddFrame2s  (   cframe f,                     boolean instant  )
//      AddFrame01  (   cframe f,                     boolean instant  )
//      AddFrame02  (   cframe f,                     boolean instant  )
//      AddFrame04  (   cframe f,                     boolean instant  )
//      AddFrame08  (   cframe f,                     boolean instant  )
//      AddFrame16  (   cframe f,                     boolean instant  )
//      AddFrame32  (   cframe f,                     boolean instant  )
//      AddFrame64  (   cframe f,                     boolean instant  )
//
//
//  Demo:
*/
//! novjass
scope test initializer TEST
    struct demo extends cframe
        static method create takes nothing returns thistype
            local thistype this = allocate()
            set tick = 0
            call AddFrame64(this, true)
            return this
        endmethod
        
        private integer tick
        private method update takes real per returns boolean
            set tick = tick + 1
            return tick * per < 30.00
        endmethod
        
        private method end takes nothing returns nothing
            call destroy()
        endmethod
    endstruct
    
    private function TEST takes nothing returns nothing
        local integer i = 0
        loop
            call demo.create()
            call demo.create()
            call demo.create()
            call demo.create()
            set i = i + 1
            exitwhen i >= 800
        endloop
    endfunction
endscope
//! endnovjass
/*
//
//  How to register a client with a new server?
//
*/
//! novjass
scope test initializer TEST
    struct demo extends cframe
        static method create takes nothing returns thistype
            local thistype this = allocate()
            set tick = 0
            call s.add(this, true)
            return this
        endmethod
        
        private integer tick
        private method update takes real per returns boolean
            set tick = tick + 1
            return tick * per < 30.00
        endmethod
        
        private method end takes nothing returns nothing
            call destroy()
        endmethod
        
        private static sframe s
        private static method onInit takes nothing returns nothing
            set s = sframe.create(0.015625000)
        endmethod
    endstruct
    
    private function TEST takes nothing returns nothing
        local integer i = 0
        loop
            call demo.create()
            call demo.create()
            call demo.create()
            call demo.create()
            set i = i + 1
            exitwhen i >= 800
        endloop
    endfunction
endscope
//! endnovjass
/*
//
//  Notes:
//      You shouldn't register a client with a new server!
//
*/

library ServerFrame initializer init requires SFc
    globals
        private sframe Server_1_64
        private sframe Server_1_32
        private sframe Server_1_16
        private sframe Server_1_8
        private sframe Server_1_4
        private sframe Server_1_2
        private sframe Server_1_1
        private sframe Server_2_1
        private sframe Server_4_1
        private sframe Server_8_1
    endglobals
    
    function AddFrameAuto takes cframe f, real delay, boolean instant returns nothing
        if     delay/8.000000000 >= 19.60 then
            call Server_8_1.add(f, instant)
        elseif delay/4.000000000 >= 17.80 then
            call Server_4_1.add(f, instant)
        elseif delay/2.000000000 >= 16.10 then
            call Server_2_1.add(f, instant)
        elseif delay/1.000000000 >= 14.50 then
            call Server_1_1.add(f, instant)
        elseif delay/0.500000000 >= 13.00 then
            call Server_1_2.add(f, instant)
        elseif delay/0.250000000 >= 11.60 then
            call Server_1_4.add(f, instant)
        elseif delay/0.125000000 >= 10.30 then
            call Server_1_8.add(f, instant)
        elseif delay/0.062500000 >= 9.10 then
            call Server_1_16.add(f, instant)
        elseif delay/0.031250000 >= 8.00 then
            call Server_1_32.add(f, instant)
        else
            call Server_1_64.add(f, instant)
        endif
    endfunction
    
    //! textmacro AddFrame_Single takes NAME, NAMEs
    function AddFrame$NAME$ takes cframe f, boolean instant returns nothing
        call Server$NAMEs$.add(f, instant)
    endfunction
    //! endtextmacro
    //! runtextmacro AddFrame_Single ("8s", "_8_1")
    //! runtextmacro AddFrame_Single ("4s", "_4_1")
    //! runtextmacro AddFrame_Single ("2s", "_2_1")
    //! runtextmacro AddFrame_Single ("01", "_1_1")
    //! runtextmacro AddFrame_Single ("02", "_1_2")
    //! runtextmacro AddFrame_Single ("04", "_1_4")
    //! runtextmacro AddFrame_Single ("08", "_1_8")
    //! runtextmacro AddFrame_Single ("16", "_1_16")
    //! runtextmacro AddFrame_Single ("32", "_1_32")
    //! runtextmacro AddFrame_Single ("64", "_1_64")
    
    private function init takes nothing returns nothing
        set Server_1_64     =       sframe.create(0.015625000)
        set Server_1_32     =       sframe.create(0.031250000)
        set Server_1_16     =       sframe.create(0.062500000)
        set Server_1_8      =       sframe.create(0.125000000)
        set Server_1_4      =       sframe.create(0.250000000)
        set Server_1_2      =       sframe.create(0.500000000)
        set Server_1_1      =       sframe.create(1.000000000)
        set Server_2_1      =       sframe.create(2.000000000)
        set Server_4_1      =       sframe.create(4.000000000)
        set Server_8_1      =       sframe.create(8.000000000)
    endfunction
endlibrary

library SFc
    globals
        //! runtextmacro SF_Instal ()
    endglobals
    
    interface cframe
        method update   takes   real    whichFrame  returns boolean defaults    false
        method end      takes   nothing             returns nothing defaults    nothing
    endinterface
    
    struct sframe
        private cframe array frames [MAX_CLIENT_ON_A_SERVER]
        private integer num
        private timer t
        private real per
        
        private thistype next
        
        static method create takes real period returns thistype
            local thistype this = allocate()
            set num = 0
            set next = 0
            set t = CreateTimer()
            call SaveInteger(hash, GetHandleId(t), 0, this)
            set per = period
            return this
        endmethod
        private method onDestroy takes nothing returns nothing
            call FlushChildHashtable(hash, GetHandleId(t))
            call DestroyTimer(t)
            set t = null
            call next.destroy()
        endmethod
        
        method add takes cframe f, boolean instant returns nothing
            if num >= MAX_CLIENT_ON_A_SERVER then
                if next == 0 then
                    set next = thistype.create(per)
                endif
                call next.add(f, instant)
                return
            endif
            //
            if num == 0 then
                call TimerStart(t, per, true, function thistype.act)
            endif
            set frames[num] = f
            set num = num + 1
            if instant then
                call f.update(per)
            endif
        endmethod
        
        private static method act takes nothing returns nothing
            local thistype this = LoadInteger(hash, GetHandleId(GetExpiredTimer()), 0)
            local integer i = 0
            loop
                exitwhen i >= num
                if frames[i].update(per) then
                    set i = i + 1
                else
                    call frames[i].end()
                    set num = num - 1
                    if num == 0 then
                        call PauseTimer(t)
                    else
                        set frames[i] = frames[num]
                    endif
                endif
            endloop
        endmethod
        
        private static hashtable hash
        private static method onInit takes nothing returns nothing
            set hash = InitHashtable()
        endmethod
    endstruct
endlibrary





Link Download:
http://www.mediafire.com/download/g0a5atdbsq2bwyj/R32+and+Frame.w3m





Đánh giá:
ServerFrame chạy nhanh và tốt hơn Framework bản cũ nhiều.
Trong map có demo để test so sánh, để so sánh các bợn Enable Framework hoặc ServerFrame lên và vào test.
Bản test được test dưới tốc độ 1/64s và số lượng là 3200 vòng lặp chạy 1 lúc.




Hi vọng với sys này các bợn có thể làm spell MUI nhanh và tốt nhất có thể :)
Đây là 1 số spell mình làm = Framework: http://www.mediafire.com/download/ohlclt85cl7cel1/spell.w3x
Đây là bản convert sang ServerFrame: http://www.mediafire.com/download/m9s49vauuyyr1ja/spell+(ServerFrame).w3x
Lưu ý: spell không có dmg, và nếu ai xài (thêm dmg) thì đề nghị ghi cái credit, thanks!
 
Chỉnh sửa cuối:
Back
Top