[Tutorial] - Unit Positions, Fake Miss, Auto - Cast

Thảo luận trong 'World Editor' bắt đầu bởi Tom_Kazansky, 12/7/08.

  1. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    Trước khi xem tutorial này, ai xem thì nên download Jass NewGen Pack 1.5a
    Có vài vấn đề cần đến tool này để giải quyết. Thật ra ko có cũng ko sao nhg nên dùng :-j
    ---
    Trong Jass NewGen có 1 feature gọi là library (thư viện). Trong Jass, muốn gọi 1 function (hàm) nào đó thì hàm đó phải ở trên cái hàm mà chứa dòng lệnh gọi đó. Vì vậy các function trong 1 library sẽ tự động đc đặt lên trên (khi script đc kiểm tra).
    Các function cần thiết ta nên cho vào 1 library. library tương tự như map header (vào Trigger Editor, click vào tên map ở bên trái, bên phải là map header).

    Scope cũng tương tự library

    ---
    Thứ nhất Tom xin nói về vấn đề "vị trí giữa 2 unit".
    Muốn kiểm tra vị trí của 1 unit (unit A) so với 1 unit khác (unit B), ta kiểm tra góc giữa unit B và A, và góc nhìn của B.
    Để dễ dàng hơn cho việc kiểm tra, tôi sẽ coi như góc nhìn của B là 0, do vậy, góc giữa B và A cũng sẽ giảm đi một lượng = góc nhìn của B.

    Tôi có vài function như sau:
    Mã:
    scope UnitPositionChecking
    
        private function Checker takes unit b, unit a, real frontL, real frontR, real backL, real backR returns integer//position of b from a
            local real angle = bj_RADTODEG * Atan2(GetUnitY(b) - GetUnitY(a), GetUnitX(b) - GetUnitX(a))
            if angle >= 0 then
                set angle = angle-GetUnitFacing(a)
            else
                set angle = angle+360-GetUnitFacing(a)
            endif
            if angle < 0 then
                set angle = angle+360
            endif
            
            if angle <= frontL or angle >= frontR then
                return 1
            endif
            if angle >= backL and angle <= backR then
                return 2
            endif
            if angle > backR and angle < frontR then
                return 3
            endif
            if angle > frontL and angle < backL then
                return 4
            endif
            return 0
        endfunction
    
        function IsUnitInFront takes unit b, unit a returns boolean//b = infront, a = source
            return Checker(b,a,30,330,135,225) == 1
        endfunction
    
        function IsUnitBehind takes unit b, unit a returns boolean //b = behind, a = source
            return Checker(b,a,30,330,135,225) == 2
        endfunction
    
        function IsUnitAtSideRight takes unit b, unit a returns boolean//b = atside, a = source
            return Checker(b,a,30,330,135,225) == 3
        endfunction
    
        function IsUnitAtSideLeft takes unit b, unit a returns boolean//b = atside, a = source
            return Checker(b,a,30,330,135,225) == 4
        endfunction
        
    endscope
    Nếu bạn ko dùng NewGen , thì chỉ cần copy 5 function trên vào map header thôi (bỏ cái scope endscope đi)
    Cách sử dụng:
    - Jass user: gọi (call) trực tiếp function IsUnitInFront, IsUnitAtSideLeft, IsUnitAtSideRight, IsUnitBehind.

    - GUI user: tạo ra một biến boolean, ví dụ TempCheck và dùng Custom Script để gọi:
    Mã:
    Custom script:   set udg_TempCheck = IsUnitBehind( udg_TempUnit , udg_TempUnit2 )
    Custom script:   set udg_TempCheck = IsUnitInFront( udg_TempUnit , udg_TempSource )
    Custom script:   set udg_TempCheck = IsUnitAtSideLeft( udg_TempUnit , udg_TempSource )
    Custom script:   set udg_TempCheck = IsUnitAtSideRight( udg_TempUnit , udg_TempSource )
    //Source ở đây tương đương với unit B
    
    Sau đó thì kiểm tra biến TempCheck bình thường.

    + Demo spell: Kris Slice (Tom cũng ko nhớ đúng là Kris ko, nghe ở đâu rồi thì phải, chỉ là vừa mới hiện ra trong đầu, nên cứ đặt bừa :D)

    Đánh 1 mục tiêu, làm mục tiêu mất 1.5 x Agility + 100 máu.
    Nếu caster ở bên trái hoặc bên phải mục tiêu thì mục tiêu sẽ mất nhiều máu hơn
    Nếu caster ở đằng sau mục tiêu thì mục tiêu sẽ mất nhiều máu hơn và bị knock back.

    Mã:
    Kris Slice
        Events
            Unit - A unit Starts the effect of an ability
        Conditions
            (Ability being cast) Equal to Kris Slice 
        Actions
            Set TempUnit = (Triggering unit)
            Set TempInt = (Level of Kris Slice  for TempUnit)
            Set TempUnit2 = (Target unit of ability being cast)
            Set TempReal = (100.00 + (1.50 x (Real((Agility of TempUnit (Include bonuses))))))
            [B]Custom script:   set udg_TempCheck = IsUnitBehind( udg_TempUnit , udg_TempUnit2 )[/B]
            If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                If - Conditions
                    TempCheck Equal to True
                Then - Actions
                    Set TempReal = (TempReal + (75.00 + (75.00 x (Real(TempInt)))))
                    Set TempLoc = (Position of TempUnit)
                    Set TempLoc2 = (Position of TempUnit2)
                //sử dụng Slide kia để Knockback
                    Set SlideIndex = (SlideIndex + 1)
                    Set SlideUnit[SlideIndex] = TempUnit2
                    Set SlideAngle[SlideIndex] = (Angle from TempLoc to TempLoc2)
                    Set SlideTick[SlideIndex] = 20
                    Set SlideDistance[SlideIndex] = 10.00
                    Custom script:   call RemoveLocation( udg_TempLoc )
                    Custom script:   call RemoveLocation( udg_TempLoc2 )
                Else - Actions
                    [B]Custom script:   set udg_TempCheck = ( IsUnitAtLeftSide( udg_TempUnit , udg_TempUnit2 ) or IsUnitAtRightSide( udg_TempUnit , udg_TempUnit2 ) )[/B]
                    If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        If - Conditions
                            TempCheck Equal to True
                        Then - Actions
                            Set TempReal = (TempReal + (75.00 + (75.00 x (Real(TempInt)))))
                        Else - Actions
            //phần dưới là deal dam và hiên dam lên.
            Floating Text - Create floating text that reads ((String((Integer(TempReal)))) + !) above TempUnit with Z offset 0.00, using font size 10.00, color (100.00%, 0.00%, 0.00%), and 0.00% transparency
            Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
            Floating Text - Change (Last created floating text): Disable permanence
            Floating Text - Change the lifespan of (Last created floating text) to 3.00 seconds
            Floating Text - Change the fading age of (Last created floating text) to 1.00 seconds
            Unit - Cause TempUnit to damage TempUnit2, dealing TempReal damage of attack type Chaos and damage type Normal
    
    ------------------ Fake Miss -----
    Fake Miss, (miss giả) thật ra là tránh damage.

    Với 3 trigger (thật ra là 2):

    • DamageRestore Init
    • DamageRestore Add
    • DamageRestore Act

    trigger hơi dài nên các bạn mở map ra xem nhé.

    cách dùng thì:

    • Đặt 3 biến:
      • DamageRestore_Unit : unit muốn phục hồi tổn thương
      • DamageRestore_Damage : tổn thương mà unit này nhận
      • DamageRestore_Amount : số lượng máu muốn phục hồi
    • Chạy trigger DamageRestore Add


    ---
    Tạo trigger với event unit take damage (khi 1 unit bị mất máu)
    Cần 1 biến unit group, tên là TakeDamGroup.
    Và 3 trigger:

    Mã:
    UnitTakeDamageInit
        Events
            Time - Elapsed game time is 0.00 seconds
        Conditions
        Actions
            Custom script:   set bj_wantDestroyGroup = true
            Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
                Loop - Actions
                    Unit Group - Add (Picked unit) to TakeDamGroup
                    Trigger - Add to UnitTakeDamage <gen> the event (Unit - (Picked unit) Takes damage)
    
    Trigger này để add event "Specific Unit Takes Damage" đối với các unit có sẵn trên bản đồ và add unit đó vào TakeDamGroup. Lần sau nếu có add event nữa thì phải kiểm tra xem unit cần add có trong TakeDamGroup ko, nếu ko thì add, có thì thôi (nếu có mà add tiếp sẽ gây ra bug, trigger sẽ chạy 2 lần)
    ----
    Mã:
    UnitTakeDamageDetector
        Events
            Unit - A unit enters (Playable map area)
        Conditions
            ((Triggering unit) is in TakeDamGroup) Equal to False
        Actions
            Unit Group - Add (Triggering unit) to TakeDamGroup
            Trigger - Add to UnitTakeDamage <gen> the event (Unit - (Triggering unit) Takes damage)
    
    Trigger này, khi 1 unit "đi" vào "playable map area" hiểu nôm na là 1 unit xuất hiện ở bản đồ (summon, create with trigger, train,... ) thì add thêm event Unit đó take dam, và add unti đó vào TakeDamGroup.
    ----
    Mã:
    UnitTakeDamage
        Events
        Conditions
        Actions
            Trigger - Turn off (This trigger)
            -------- ---------------------- --------
            //spells, or whatever
            -------- ---------------------- --------
            Trigger - Turn on (This trigger)
    
    Khi một unit take damage, trigger này sẽ hoạt động, và để tránh 1 số bug, ta nên "tắt" trigger này đi, xong trigger sẽ "bật" lên.
    -------------
    Demo spell: Backtrack

    Hero sẽ có cơ hội tránh sát thương dưới bất kì hình thức nào.
    (ak, sát thương từ phép (magic) còn "attack" là tấn công à ? hic, dịch sao đây ::( )

    Trước hết là tạo 1 ability, base từ 1 passive skill nào đó, Vopal Blade hoặc Storm Hammer, viết tooltip, add cho hero.

    Viết thêm vào trigger UnitTakeDamage

    Mã:
    UnitTakeDamage
        Events
        Conditions
        Actions
        Trigger - Turn off (This trigger)
        -------- ---------------------- --------
        Set TempUnit = (Triggering unit)    //đây là unit bị mất máu
        Set TempUnit2 = (Damage source) //đay là unit gây ra damage
        Set TempReal = (Damage taken)   //số damage TempUnit phải chịu
        -------- Backtrack --------
        Set TempInt = (Level of Backtrack  for TempUnit)  //có ability, level > 0
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        	If - Conditions
    		TempInt Greater than 0
    		(Random integer number between 1 and 100) Less than or equal to (5 + (5 x TempInt))
    	Then - Actions
    		[COLOR="#0000FF"]Set DamageRestore_Unit = TempUnit
    		Set DamageRestore_Damage = TempReal
    		Set DamageRestore_Amount = TempReal
    		Trigger - Run DamageRestore Add <gen> (ignoring conditions)[/COLOR]
    		Special Effect - Create a special effect attached to the hand,left of TempUnit using Abilities\Weapons\WingedSerpentMissile\WingedSerpentMissile.mdl
    		Special Effect - Destroy (Last created special effect)
    		Floating Text - Create floating text that reads miss above TempUnit with Z offset 0.00, using font size 10.00, color (50.00%, 0.00%, 100.00%), and 0.00% transparency
    		Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
    		Floating Text - Change (Last created floating text): Disable permanence
    		Floating Text - Change the lifespan of (Last created floating text) to 3.00 seconds
    	Else - Actions
            -------- ---------------------- --------
            Trigger - Turn on (This trigger)
    
    các dòng màu xanh là cách dùng "DamageRestore", đã nói ở trên.

    Thế coi như xong Backtrack.
    ----- Auto Cast Spell----
    tạo 1 auto - cast spell, tât nhiên phải sử dụng system như trên.

    Impetus

    Attack của hero làm mục tiêu mất nhiều máu hơn, phụ thuộc vào khoảng cách giữa hero và mục tiêu.

    Tạo 1 auto cast ability, base từ Poison Arrows (Neutral Hostile)
    Tạo 1 buff, base từ Poison , (stacking hay non stacking đều ko sao)
    Sau khi bỏ hết các bonus của Poison Arrows, thay buff = buff mới (Poison Arrows cần 3 buff, nhg thay cả 3 bằng 1 buff mới cũng ko sao)

    Viết thêm vào trigger UnitTakeDamage

    Mã:
    Actions
        Trigger - Turn off (This trigger)
        Set TempUnit = (Triggering unit)
        Set TempUnit2 = (Damage source)
        Set TempReal = (Damage taken)
        -------- Backtrack --------
        Set TempInt = (Level of Backtrack  for TempUnit)
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            If - Conditions
    		TempInt Greater than 0
    		(Random integer number between 1 and 100) Less than or equal to (5 + (5 x TempInt))
    	Then - Actions
    		[COLOR="#0000FF"]Set DamageRestore_Unit = TempUnit
    		Set DamageRestore_Damage = TempReal
    		Set DamageRestore_Amount = TempReal
    		Trigger - Run DamageRestore Add <gen> (ignoring conditions)[/COLOR]
    		Special Effect - Create a special effect attached to the hand,left of TempUnit using Abilities\Weapons\WingedSerpentMissile\WingedSerpentMissile.mdl
    		Special Effect - Destroy (Last created special effect)
    		Floating Text - Create floating text that reads miss above TempUnit with Z offset 0.00, using font size 10.00, color (50.00%, 0.00%, 100.00%), and 0.00% transparency
    		Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
    		Floating Text - Change (Last created floating text): Disable permanence
    		Floating Text - Change the lifespan of (Last created floating text) to 3.00 seconds
    	Else - Actions
        -------- Impetus --------
        Set TempInt = (Level of Impetus  for TempUnit2)  //phải có level
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            If - Conditions
                TempInt Greater than 0
                (TempUnit has buff Impetus ) Equal to True // buff Impetus là buff vừa tạo
            Then - Actions
                Unit - Remove Impetus  buff from TempUnit //remove buff đó đi, ko cần nữa
                Set TempLoc = (Position of TempUnit2)
                Set TempLoc2 = (Position of TempUnit)
                Set TempReal = ((Distance between TempLoc and TempLoc2) x (0.04 x (Real(TempInt))))
                Floating Text - Create floating text that reads (|c0000FFFF+ + ((String((Integer(TempReal)))) + |r)) above TempUnit with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
                Floating Text - Set the velocity of (Last created floating tex00 degrees
                Floating Text - Change (Last created floating text): Disable permanence
                Floating Text - Change the lifespan of (Last created floating text) to 3.00 seconds
                Unit - Cause TempUnit2 to damage TempUnit, dealing TempReal damage of attack type Chaos and damage type Universal //thêm damage
            Else - Actions
        -------- ---------------------- --------
        Trigger - Turn on (This trigger)
    
    Vì cho dù attack hay đc cast thì ability này cũng làm mục tiêu mất máu và có buff, chỉ cần kiểm tra mục tiêu có buff hay ko, có thì xác định khoảng cách giữa 2 unit và deal thêm damage thôi.

    Từ tutorial này, các bạn có thể tạo thêm các auto cast ability khác như: Glaive of Wisdom (deal extra damage = %Int of Hero), Arcane Orb (deal extra damage = % current mana of Hero)
    ---
    Các variable:
    TempUnit, TempUnit2 - unit
    TempReal - real
    TempLoc, TempLoc2 - point

    ---
    Tom đã gửi kèm demo map ở dưới.

    do map demo đã sửa ko up đc, nên... Tom sẽ up lại sau
     

    Các file đính kèm:

    Chỉnh sửa cuối: 18/11/11
  2. Jin Axl

    Jin Axl > Draw 2 Life Moderator Lão Làng GVN

    Tham gia ngày:
    2/3/06
    Bài viết:
    8,255
    Nơi ở:
    Over the rainbow
    Hiểu :'> chết liền .... :'>
    Chắc tui học thêm 1 năm GUI nữa sẽ lên tới cái này ;))
     
  3. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    hic, ko hiểu thì cứ copy là xong thôi mà, hay ý ông là ko biết dùng ::(
     
  4. Jin Axl

    Jin Axl > Draw 2 Life Moderator Lão Làng GVN

    Tham gia ngày:
    2/3/06
    Bài viết:
    8,255
    Nơi ở:
    Over the rainbow
    học những ngôn ngữ lập trình như thế này muốn dùng tốt thì phải hiểu, chứ copy cả đoạn script vào nhỡ bị bug ko biết chỗ nào mà fix ?
    Nói chung cái này vẫn còn là loại nặng đô, ít nhất là d/v tớ :-<
     
  5. kissofaries

    kissofaries Dragon Quest

    Tham gia ngày:
    11/3/07
    Bài viết:
    1,463
    Nơi ở:
    Kalimdor
    Làm 1 spell non-auto cast thành auto cast như thế nào vậy anh tom
     
  6. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    Em hãy nói cụ thể hơn (skill nào). Nhg nói chung là ko thể.
     
  7. Jin Axl

    Jin Axl > Draw 2 Life Moderator Lão Làng GVN

    Tham gia ngày:
    2/3/06
    Bài viết:
    8,255
    Nơi ở:
    Over the rainbow
    Chỉ có thể dùng 1 skill gốc dạng autocast (Searing Arrow) rồi A bra ca da bra nó thành theo ý mình :>
     
  8. Vua_Do_Hoa

    Vua_Do_Hoa Mr & Ms Pac-Man

    Tham gia ngày:
    30/3/08
    Bài viết:
    217
    Nơi ở:
    Tp Hồ Chí Minh
    Anh Tom ơi !!! Giờ em đang muốn học những cái đơn giản của Jass trước rồi đi đến cái phức tạp . Anh có thể vào hoạt động hay là rủ anh HyatHa_dk hoạt động tiếp ở Topic Jass đc ko . Vì ảnh đang hướng dẫn dở dang thì bỏ ... Không biết phải làm sao nữa hic hic
     
  9. sukaraki

    sukaraki Donkey Kong

    Tham gia ngày:
    12/5/08
    Bài viết:
    356
    Nơi ở:
    Demonworld
    Jass thì phải viết, có thể gặp lỗi viết , còn click click thì ko gặp lỗi này, nói chung Jass ngon hơn vì ko limit như click, nhiều thứ phải dùng jass mới xong, cho nên bác nào lập lại topic hướng dẫn cặn kẽ Jass từ đầu tới cuối, em ủng hộ 2 tay 3 chân :D
     
  10. theevil2008

    theevil2008 Youtube Master Race

    Tham gia ngày:
    27/10/09
    Bài viết:
    14
    em ko biet sử dụng anh Tom ơi, copy rồi paste ở đâu. anh chỉ cụ thể dc ko
     
  11. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    thử cái quote này đã.

    vì bài trên là nhiều thứ nên có thể lẫn lộn.
     
  12. 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
    mà l, jass này là ngôn ngữ nào ?
    java? C++? C# ?
     
  13. Laiev Shadowsong

    Laiev Shadowsong C O N T R A

    Tham gia ngày:
    5/11/09
    Bài viết:
    1,561
    Là ngôn ngữ cơ bản của Warcraft III, spell làm bởi Jass mượt, remove leak hiệu quả hơn GUI


    _____________
    Maiev không chết, anh ấy chỉ bị một cú Echo Slam chí mạng mà tạm thời lên bảng thôi, anh ý sẽ sớm trở lại...
     
  14. vinhcodoc

    vinhcodoc C O N T R A

    Tham gia ngày:
    16/7/08
    Bài viết:
    1,732
    Mà cho em hỏi , nếu copy jass qua map khác , nó bị sai biến hay sai cái gì mà ko work vậy anh TOm
     
  15. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    sai biến, raw id,...
    thiếu gì thứ khiến nó ko work
     
  16. vinhcodoc

    vinhcodoc C O N T R A

    Tham gia ngày:
    16/7/08
    Bài viết:
    1,732
    Vậy cách tìm biến , cái raw ID của Unit và Ability để sửa lại thì làm sao anh ?
     
  17. Laiev Shadowsong

    Laiev Shadowsong C O N T R A

    Tham gia ngày:
    5/11/09
    Bài viết:
    1,561
    F6 Object ----> CTRL + D

    Tìm raw và đặt lại trong code jass...
     
  18. vinhcodoc

    vinhcodoc C O N T R A

    Tham gia ngày:
    16/7/08
    Bài viết:
    1,732


    Oke đã rõ vụ Raw. còn biến, chả lẻ phải mở Map ra ghi lại rùi qua map mới tạo hủm
     
  19. babymoon12345

    babymoon12345 Youtube Master Race

    Tham gia ngày:
    22/1/09
    Bài viết:
    29
    Anh Tom cho ví dụ đi ( Hình ảnh minh họa). Lý thuyết với code nhiều cũng khó hiểu lắm:(
     
  20. Tom_Kazansky

    Tom_Kazansky

    Tham gia ngày:
    28/12/06
    Bài viết:
    3,454
    Nơi ở:
    Hà Nội
    hình gì chứ, demo map to đùng ở dưới rồi 8-x
     

Chia sẻ trang này