[Hướng Dẫn] [Hướng dẫn] Công thức đặc biệt

TkTsTkTs Posts: 482Registered
<<Xem thêm công thức Bổ sung>>

Nội dung của hướng dẫn này là gì? Công thức đặc biệt là sao? Ví dụ như mỗi actor đều có món 
ăn ưa thích của họ, và khi họ dùng item đúng với sở thích thì sẽ được hồi máu nhiều hơn người 
khác.

Đầu tiên là bạn cần biết đến nó, mở Database (F9) lên và chuyển sang tab Skill, tìm phần 
giống trong hình:
zcuVM87.png

Ví dụ ta có một vật phẩm hồi máu, nếu vật phẩm này được Eric dùng (actor mặc định của ACE) 
thì Eric sẽ được hồi 500 HP, còn nếu người khác dùng thì chỉ hồi 100 HP thôi. Kế tiếp là chuyển những lời nói phía trên thành một công thức mà ACE có thể hiểu được, có hai cách để viết như sau:
if b.id == 1; 500; else; 100; end;

b.id == 1 ? 500 : 100

Cả hai công thức trên đều có cùng một nhiệm vụ, là kiểm tra điều kiện sau:
b.id == 1

Nếu như bạn rê chuột vào khung công thức, nó sẽ hiện ra ý nghĩa của các từ viết tắt. Ta chỉ cần biết đến angười sử dụng kỹ năng hoặc vật phẩm, bđối tượng bị ảnh hưởng bởi kỹ năng hoặc vật phẩm. Vì đây là một vật phẩm nên b sẽ luôn luôn là một actor nào đó. Theo như ví dụ trên thì ta sẽ phải kiểm tra xem ai là người sẽ được dùng vật phẩm đó.

Giờ hãy xem phần còn lại của công thức.
if b.id == 1; 500; else; 100; end;

Nếu bạn đã từng làm quen với ngôn ngữ lập trình cơ bản thì bạn sẽ dễ dàng nhận ra đây là hàm điều kiện cơ bản. Nếu bạn không hiểu thì hãy xem dưới đây:

if b.id == 1

500

else

100

end


Vậy ý nghĩa của nó là, khi id của actor bằng 1 (Eric đó) thì hồi 500 HP, còn không thì chỉ hồi 100 HP. Cách viết kia cũng đem lại kết quả tương tự nhưng nó được viết ngắn hơn theo phong cách Ruby:
b.id == 1 ? 500 : 100

Cấu trúc của nó là:
[b]điều kiện[/b] ? [b]đúng[/b] : [b]sai[/b]

Sau cùng là hai điều quan trọng. Thứ nhất là khung công thức có giới hạn về kí tự và nếu như công thức của bạn sai hoặc vô lý quá thì kỹ năng hoặc vật phẩm sẽ MISS liên tục.

Sau đây là vài ví dụ để bạn hiểu rõ hơn về Công thức đặc biệt.

Ví dụ: Một nữa đồng đội của bạn là robot hoặc quỷ và cần các vật phẩm hồi phục nhất định. 
(b.id==1 or b.id==3 or b.id==4) ? 500 : 0

Ví dụ: Có một actor thích ăn kem nhưng một actor khác thì bị dị ứng với kem.
Mặc định là Eric sẽ được hồi 100 HP khi ăn kem, nhưng khi Natalie ăn kem thì bị trúng độc.
if b.id==1;200;elsif b.id==2;b.add_state(2);0;else;100;end;
Lần này phức tạp hơn, lệnh elsif là một cách để kiểm tra điều kiện nếu điều kiện đầu không thỏa mãn. Ý nghĩa của nó là nếu Eric thì hồi 200 HP, nếu là Natalie thì thêm status có id là 2 (Poison) vào, những người khác thì hồi 100 HP.

Ví dụ: Một kỹ năng sấm sét sẽ gây thêm sát thương nếu ở ngoài trời, bạn có thể kiểm tra bằng 
switch.
$game_switches[x] ? 500 :  200 

Ví dụ: Một kỹ năng gây sát thương dựa trên một biến nào đó.
$game_variables[x] * 10
Kỹ năng này sẽ gây 10 lần x sát thương.

Ví dụ: Ta có actor thích cờ bạc và có kỹ năng tung xúc sắc. Anh ta tung hai viên xúc sắc, sát thương gây ra là 100 nhân với tổng điểm hai mặt xúc sắc cộng lại. Sát thương sẽ gấp đôi nếu hai xúc sắc trùng mặt và 10000 sát thương nếu hai xúc sắc đều 1 điểm.
Công thức này hơi nhiều nên cần phải xem kĩ. Ta sẽ dùng hàm if, và hàm rand(x) sẽ trả về giá trị từ 0 đến x-1, nên ta sẽ cộng thêm 1 vào nó để tương ứng với số điểm của xúc sắc. Ta cũng cần tạo các biến tạm. Ta sẽ dùng c và d (không được dùng a và b).
c=1+rand(6);d=1+rand(6);if c==1 and d==1;10000;elsif c==d;c*400;else;(c+d)*100;end;

Ví dụ: Có một kỹ năng sẽ hồi lượng máu hiện tại của mục tiêu. Đơn giản chỉ cần lấy giá trị máu hiện tại của đối tượng.
b.hp
Ngoài ra còn các chỉ số khác mà có thể dùng trong công thức, cứ rê chuột vào khung công thức nó sẽ hiện ra.

Ví dụ: Một kỹ năng gây 1/4 sát thương.
b.hp/4

Ví dụ: Một kỹ năng có sử dụng đến chỉ số của các nhân vật khác.
$game_actors[1].atk * 4 - b.def * 2
Bạn cũng có thể thay thế chỉ số ATK bằng các chỉ số khác theo cấu trúc là
$game_actors[x].y
x là id của actor
y là chỉ số
(MHP, MMP, ATK, DEF, MAT, MDF, AGI, LUK, HIT, EVA, CRI, CEV, MEV, MRF, CNT, HRG, MRG, 
TRG, TGR, GRD, REC, PHA, MCR, TCR, PDR, MDR, FDR, EXR)

Ví dụ: Một kỹ năng sẽ gây sát thương chí mạng khi lượng MP hiện tại lớn hơn 100.
if a.mp>=100;b.result.critical=true;(a.atk*4-b.def*2)*3;else;(a.atk*4-b.def*2);end;
result.x sẽ hiển thị hiệu ứng tương ứng với x lên đối tượng , có thể thay x bằng các yếu tố 
sau (có thể tìm thấy trong script Game_ActionResult phần Public Instance Variables):
used, missed, evaded, critical, success, hp_damage, mp_damage, tp_damage, hp_drain, 
mp_drain, added_states, removed_states, added_buffs, added_debuffs, removed_buffs

Ví dụ: Một kỹ năng sẽ hao tốn 1 vật phẩm khi dùng.
$game_party.lose_item($data_items[1], 1);a.atk * 4 - b.def * 2
$game_party sẽ lấy dữ liệu từ thùng đồ, tiếp theo lệnh thực hiện gồm
+lose_item($data_x[y], z) sẽ trừ đi z vật phẩm y loại x
+gain_item($data_x[y], z) sẽ thêm vào z vật phẩm y loại x
Thay x bằng loại vật phẩm (items, weapons, armors)
Thay y bằng id của loại vật phẩm đó
Thay z bằng số lượng sẽ mất đi hoặc thêm vào

Bạn có thể tìm thêm các giá trị của $game_party trong script Game_Party.

Ví dụ: Một kỹ năng gây sát thương dựa trên thời gian bạn chơi game.
$game_system.playtime

Ví dụ: Một kỹ năng sẽ gây thêm sát thương mỗi lần thi triển, chỉ có tác dụng trong một trận 
đấu và sẽ reset lại mỗi khi bắt đầu trận đấu mới. Ta sẽ cần tạo 1 biến riêng cho kỹ năng đó và cộng dồn nó lên mỗi lần kỹ năng được dùng.
$game_variables[x] += 1;($game_variables[x] + 10)
x là id của biến.

Để reset lại biến đó, mở Database lên (F9)chuyển sang tab Troop. Trong phần Troop 
Event Page bạn chọn điều kiện là Turn No. 1, dươi đó chạy lệnh Control Variables và reset 
lại giá trị biến mà mình trong công thức lại bằng 0.
Lưu ý làm điều đó cho tất cả các troop.

Ví dụ: Một kỹ năng như trên nhưng sát thương của nó sẽ tăng theo lượt trận đấu. Ta cần tạo 1 biến riêng cho kỹ năng đó và cộng dồn mỗi lượt khi trận đấu diễn ra và reset khi bắt đầu trận đấu mới.
$game_variables[x] += 1;($game_variables[x] + 10)

Công thức giống ở trên nhưng cách tủy chỉnh ở Troop Event Page sẽ khác, ta sẽ cần 2 trang như sau:
3MbFR62.png
Mỗi khi có trận đấu mới, biến này sẽ reset lại bằng 0.
Y6eRXsN.png
Điều kiện 1+1*X sẽ diễn ra mỗi lượt (nếu là 1+3*X thì nó sẽ xảy ra ở lượt 1-3-7-...)

Ví dụ: Một kỹ năng gây sát thương ngẫu nhiên trong một khoảng ngẫu nhiên nào đó. Ta sẽ dùng đến hàm case, hàm case cho phép ta chia ra nhiều trường hợp để kiếm tra.
case rand(100);when 0;9999;when 1..29;rand(4000) + 1001;else;rand(901) + 100;end;
Đầu tiên lấy ngẫu nhiên từ 1~100, kỹ năng sẽ có 1% gây ra 9999 dmg, 29% gây ra 1001~5000 
dmg, còn lại là 100~1000 dmg.

Ví dụ: Một kỹ năng gây sát thương sẽ hao tổn một lượng máu người dùng dựa trên lượng máu hiện tại của họ.
r = a.hp*0.3;a.hp -= (a.hp*0.1).round;r - b.def/2
r = a.hp*0.3: là cách gán một công thức nào đó vào một biến tạm, để tiết kiệm không gian.
x.round: là làm tròn một giá trị x.

Ví dụ: Một kỹ năng chỉ gây 1000 dmg khi đối phương bị trúng độc, nếu không thì chỉ gây 100 dmg.
b.state?(2) ? 1000 : 100
x.state?( Y ) sẽ kiểm tra xem x đang chịu hiệu ứng y nào không, thay y bằng id của state trong Database (F9).

Ví dụ: Một kỹ năng sẽ gây sát thương và sẽ có 35% khiến đôi phương bị mini stun.
if rand(100) <= 34;b.remove_current_action;end;50
x.remove_current_action sẽ khiến x bị mất lượt hành động kế tiếp, thay x bằng a hoặc b.

Ví dụ: Một kỹ năng hồi máu sẽ hồi nhiều hơn nếu nhân vật có trang bị một vũ khí nào đó.
a.weapons.include?($data_weapons[1]) ? 1000 : 200

cấu trúc như sau:
[b]x.y.include?($data_y[z])[/b]
x là a hoặc b
y là 3 loại vật phẩm items, weapons, armors
z là id của vật phẩm tương ứng


Ví dụ: Một kỹ năng sẽ gây sát thương thêm cho mỗi trạng thái mà đối phương đang chịu.
d=4*a.atk-2*b.def;for s in [2,3,4,5];if b.state?(s);d+=100;end;end;d
Ý nghĩa của công thức:
for s in [2,3,4,5]
Ta tạo một mảng tạm chứa các id của các state ảnh hưởng và một biến s để kiểm tra mảng đó.
if b.state?(s);d+=100
Sau đó cho biến s chạy trong mảng và sẽ công thêm 100 cho mỗi trạng thái mà đối phương đang 
có. Nếu đối phương chỉ bị Poison thì chỉ thêm 100 dmg, nhưng nếu đối phương có cả Poison, 
Blind, Confuse, Sleep thì kỹ năng sẽ gây thêm 400 dmg.

[chapter]Tùy chọn[/chapter]
Nếu như bạn đã quen rồi thì bạn sẽ sớm nhận ra nhược điểm của cái Công thức đăc biệt này... chính là giới hạn ký tự của ô công thức. Nhưng đừng lo, khắc phục rất dễ, đó viết script. Viết script sẽ giải quyết được vấn đề giới hạn ký tự, chỉnh sửa dễ dàng hơn và cũng có thể cho phép bạn sáng tạo hơn về các chức năng của công thức (yêu cầu kiến thức ruby nhất định).

Hãy bắt đầu bằng việc phân tích ô công thức, ta đã biết được công thức ảnh hưởng tới hai đối tượng là a là người sử dụng kỹ năng hoặc vật phẩm, b là đối tượng bị ảnh hưởng bởi kỹ năng hoặc vật phẩm. Nhưng thực chất a và b tượng trưng cho hai đối tượng của Ace là Game_ActorGame_Enemy. Bạn hãy nhìn vào hình dưới:
zhMzXte.png
Ta sẽ thấy Game_ActorGame_Enemy đều được kế thừa từ Game_Battler, và chính nó cũng kế thừa từ Game_BattlerBase.
Ta cần phải biết điều này để nắm rõ vị trí mà code ta viết sẽ có ảnh hưởng ở đâu. Sau đây là những thư viện mình khuyên bạn nên viết:
-Game_Battler
-Game_BattlerBase
-Một Module mới
Tạo một Module mới là cách tốt nhất để viết code mới, nhưng vì "chúng ta" có rất ít kinh nghiệm về ruby coding nên ta sẽ không dùng đến cách này.
Cách thích hợp nhất là 2 cách đầu tiên, ta sẽ truy cập vào hai thư viện kia.
Mở Script Editor (F11) và tìm đến khu vực ▼ Materials, tại đây bạn Insert một script mới đặt tên là My Custom Fomula và thêm các code sau:
class Game_Battler < Game_BattlerBase

end

Vậy là xong phần truy cập thư viện, giờ bạn đã có thể viết công thức để dùng trong Database (F9).

Ví dụ: Bạn có một nhân vật Healer nhưng bạn không muốn anh ta là một OP Healer, nên bạn sẽ khiến kỹ năng hồi máu của anh ta sẽ áp dụng các trạng thái xấu. Những nhân vật nào có các trạng thái xấu sẽ chỉ nhận được 1/2 lượng máu được hồi.

Đầu tiên bạn cần phải định nghĩa cho hàm bạn muốn viết:
def ophealer

end

Cấu trúc của nó là:
def tên_công_thức

end

Lưu ý luôn phải end ngay khi định nghĩa một hàm mới.
Tiếp theo là nội dung:
def ophealer
        return state?(2) || state?(3)
end

Ở đây ta kiểm tra hai trạng thái là Poison hoặc Blind và giá trị trả về là True hoặc False.
Vậy là xong phần scripting đơn giản. Nếu làm đúng thì code đầy đủ như này:
class Game_Battler < Game_BattlerBase
        def ophealer
                return state?(2) || state?(3)
        end
end

Kế tiếp là áp dụng nó vào trong Database. Mở Database lên và sang tab Skill, tạo một kỹ năng Heal cơ bản, khi dùng sẽ áp dụng 2 trạng thái xấu trên vào đối tượng.
rCNFtm0.png
Trong ô công thức ta sẽ viết như sau:
b.ophealer ? 100 : 200
Ý nghĩa của nó là, đầu tiên nó sẽ chạy hàm bạn đã viết, đó là kiểm tra xem b đang có bị Poison hay Blink không, và trả về True hoặc False.
Nếu True chỉ hồi 100 HP, còn False thì hồi 200 HP.

Bằng cách này bạn sẽ có thể tạo ra nhiều kỹ năng đặc biệt như gây thêm hiệu ứng khi mặc đủ set trang bị nào đó, hoặc các kỹ năng ảnh hưởng khác nhau đối với các thuộc tính khác nhau...vvvv

[chapter]Nguồn[/chapter]
Fomar0153

Comments

  • dsiver144dsiver144 Posts: 1,064Registered
    Lâu rồi mới có một Tut hay thế này. :3
  • Dang_KhoaDang_Khoa Posts: 3,861Administrators
    Cái này mới biết luôn, quá đỉnh
    :D :D :D
  • David ChaseDavid Chase Posts: 1,766Registered
    Cho lên page nhé :"3??
  • hactieuho789hactieuho789 Posts: 96Registered
    :3 hàm này cơ bản, trong pascal cũng có xài nhiều
    bài viết rất hữu ích với newbie
  • Dang_KhoaDang_Khoa Posts: 3,861Administrators
    Cho lên page nhé :"3??

    Cho lên luôn em
    :cool: :cool: :cool:
  • TkTsTkTs Posts: 482Registered
    update thêm vài ví dụ
  • David ChaseDavid Chase Posts: 1,766Registered
    Good, sản phẩn đã dx lên page
  • TkTsTkTs Posts: 482Registered
    [align=center][size=x-large]<<<Bổ sung>>>[/size][/align]
    [align=center][size=x-large][chapter][/chapter][/size][/align]

    [align=left]Ví dụ: Kỹ năng gây sát thương và có xác suất gây choáng (base là 65% + phụ thuộc vào Luck của người dùng).[/align]
    -Script Editor:
    def bash_formula(a,b)
       c = 65+((a.luk/25).abs).to_i; d = a.atk*4-b.def*2; if rand(100) <= c; b.add_state(8); else; d = d+a.luk; end; d
    end
    -Formula Box:
    a.bash_formula(a,b)
    
    c là % gây choáng được tính theo 65 + 1 mỗi 25 Luck của nhân vật (.abs và .to_i dùng để tránh trường hợp ra số âm và thập phân khi chia Luck)
    d là công thức gây damage (có thể thay đổi)
    rand(100) <= c để lấy % của c (có thể thay c bằng số nhất định từ 1~100)
    b.add_state(8) để thêm state Choáng nếu thành công (thay số 8 bằng id của state tương ứng)


    Ví dụ: Kỹ năng gây sát thương và khiến kẻ địch nào có level thấp hơn nhân vật 10 level bỏ chạy khỏi trận đấu, nếu không thì dính trạng thái xấu.
    -Script Editor:
    def chargeeee_formula(a,b)
       c = a.level
       d = b.level
       if c > d && (c-d) >= 10
         return b.hide
       else
         return b.add_state(30)
       end
    end
    -Formula Box:
    a.chargeeee_formula(a,b);a.atk*0.5+a.tp
    
    c là level của nhân vật
    d là level của địch
    Sau đó so sánh c và d nếu nhân vật cấp cao hơn và hơn 10 level thì khiến địch bỏ chạy bằng hàm .hide, nếu không thì dính trạng thái xấu.
    a.atk*0.5+a.tp là công thức tính damage.


    Ví dụ: Kỹ năng gây sát thương có 50% khiến địch yểm bùa. Trong lượt sau bùa này sẽ phát nổ và gây sát thương.
    -Formula Box:
    c=rand(2)+1;d=a.atk*4-b.def*2;if c==1;b.force_action(10,-2);d;else;d;end
    
    c là một số ngẫu nhiên từ 1~2 (cấu trức từ 1~n là rand(n)+1)
    d là công thức tính damage
    .force_action(x,y) là hàm "hành động ép buộc", dùng để ép nhân vật hoặc địch dùng kỹ năng có id x lên y (y là index - cái này chưa biết phân biệt giữa party và troop thế nào, hiện tại thì có -1 là một địch ngẫu nhiên, -2 là địch bị tấn công sau cùng)
    b.force_action(10,-2) sẽ khiến địch tự dùng skill id 10 lên chính nó


    Ví dụ: Kỹ năng khi dùng lên địch sẽ hồi máu cho chúng, nhưng nếu địch có 1 state nào đó trên người như Undead chẳng hạn, thì sẽ bị sát thương thay vì hồi máu.
    -Formula Box: (nên để type là HP Recovery)
    if b.state?(32) == true; (b.hp-=(100+a.mat*2)*b.element_rate(9));c=1;else;c=100+a.mat*2;end;c
    
    State#32 là Undead, state này được add cho địch trước khi trận đấu bắt đầu.
    b.state?(x) dùng để kiểm tra trên người b có state x không, nếu có thì nó sẽ bị gây sát thương
    Sát thương được tính bằng cách lấy máu hiện tại của b trừ đi (b.hp-=) một lượng được tính bằng công thức tính damage ((100+a.mat*2)*b.element_rate(9))
    .element_rate(x) sẽ trả về các số thập phân tương ứng của thuộc tính x (nếu b có thuộc tính Holy là 150% nó sẽ trả về là 1.5)
    c là dùng để tăng tính logic
    Lưu ý nếu làm cách này thì ai dùng script có liên quan tới Damage Popup thì nó sẽ không hiển thị đúng, nhưng sát thương gây ra vẫn chính xác
  • YuuYuu Posts: 1,160Registered
    TkTs wrote:
    [align=center][size=x-large]<<<Bổ sung>>>[/size][/align]

    Bác gắn dòng này lên Post 1 nè, để nó redict xuống post này cho member khỏi phải kéo!
    [url=http://taotrochoi.com/thread-2875-post-41028.html#pid41028]Xem thêm công thức Bổ sung[/url]
    

    Test: Xem thêm công thức Bổ sung
  • dsiver144dsiver144 Posts: 1,064Registered
    Gj bro. Tôi đóan là nhiều người sử dụng RPG Maker ít thành thạo cái này. xD
  • BướmBướm Posts: 1,220Registered
    ném phoenix down vào con zombie trong FF deal 999999 damage dùng death vào thì buff cho nó 999999 HP
Sign In or Register to comment.