• Chào bạn, hãy đăng ký hoặc đăng nhập để tham gia cùng bọn mình và sử dụng được đầy đủ chức năng của diễn đàn :).
anhcraft

Hướng dẫn Code Plugin - Tạo Killmark

anhcraft

Thành viên BQT
DEVELOPER
THÀNH VIÊN
Tham gia
18/09/2016
Bài viết
3,165
Đây là code Killmark (DoubleKills,..vv) dành cho ai chưa biết :D

Cách hoạt động:
- Sự kiện: Xảy ra khi người chơi giết người chơi =))
- Lưu trữ lượt giết của người giết trong một hashmap
- Boardcast (hoặc title,..) khi đạt First kill, DoubleKills, TripleKills,..
- Gửi yêu cầu reset sau ... giây
+ Số lần giết gửi kèm khi gọi hàm resetKills đúng bằng với lượt kills trong HashMap ta sẽ biết rằng từ lúc gọi hàm này đến khi scheduler xong người đó vẫn chưa có lượt giết nào mới cả, vì thế ta sẽ reset lượt kills :v
+ Số lần giết gửi kèm khi gọi hàm resetKills khác với lượt kills trong HashMap ta sẽ biết rằng từ lúc gọi hàm này đến khi scheduler xong người đó đã giết thêm một lượt nữa, vì thế ta sẽ ko reset <(")

* Code dey, nhớ thay chỗ mình in đậm
Mã:
public class Kills implements Listener {
    // thời gian reset lại lượt giết (tính theo giây)
    private int reset_time = 2;

    // hashmap chứa người giết & số lần giết
    private HashMap<Player, Integer> kills = new HashMap<>();
  
    // hàm reset lại kills
    private void resetKills(Player p, int currentKills){
[INDENT]new BukkitRunnable() {
    @Override
    public void run() {
       // nếu số lần giết hiện tại đúng bằng lượt giết khi request
      // vì trong khi scheduler, rất có thể người chơi này đã kills thêm 1 lần nữa, vì thế ta không thể reset
       if(kills.get(p) == currentKills){
          kills.put(p, 0);
       }
    }
}.runTaskLaterAsynchronously(this, reset_time * 20);[/INDENT]
    }

    // tăng kills cho người chơi
    private void newKill(Player p){
        if(kills.containsKey(p)){
            kills.put(p, kills.get(p)+1);
        } else {
            kills.put(p, 1);
        }
    }

    @EventHandler
    public void damage(EntityDamageByEntityEvent ev){
        // kiểm tra entity giết & entity tạo ra sát thương đều là Player
        if(ev.getDamager() instanceof Player && ev.getEntity() instanceof Player) {
            Player a = (Player) ev.getDamager();
            Player b = (Player) ev.getEntity();
            // máu của người nhận sát thương (sau khi đã nhận damage) bé hơn 0 (tức là bị chết)
            if(b.getHealth()-ev.getDamage() < 1) {
                // tăng lượt giết người
                newKill(a);
                // lấy lượt giết người hiện tại
                int c = kills.get(a);
              
                if(c == 1) {
                    Bukkit.getServer().broadcastMessage("⚙ " + a.getName() + " đã đạt First Kills");
                } else if(c == 2) {
                    Bukkit.getServer().broadcastMessage("⚙ " + a.getName() + " đã đạt Double Kills");
                } else if(c == 3) {
                    Bukkit.getServer().broadcastMessage("⚙ " + a.getName() + " đã đạt Triple Kills");
                } else if(c == 4) {
                    Bukkit.getServer().broadcastMessage("⚙ " + a.getName() + " đã đạt Quadra Kills");
                } else if(c == 5) {
                    Bukkit.getServer().broadcastMessage("⚙ " + a.getName() + " đã đạt Penta Kills");
                } else if(c == 6) {
                    Bukkit.getServer().broadcastMessage("⚙ " + a.getName() + " đã đạt Unstopvable");
                } else if(c == 7) {
                    Bukkit.getServer().broadcastMessage("⚙ " + a.getName() + " đã đạt Monster Kills");
                } else if(c == 8) {
                    Bukkit.getServer().broadcastMessage("⚙ " + a.getName() + " đã đạt Rampage");
                }
                // gửi yêu cầu reset
                resetKills(a, c);
            }
        }
    }
}
 
Sửa lần cuối:
if(b.getHealth()-ev.getDamage() < 1)
Cái này có nghĩa là sao?
1 mình nó giết sẽ được đếm hay nó ks được đếm?
Nếu ks được đếm thì ngon (y)
 
if(b.getHealth()-ev.getDamage() < 1)
Cái này có nghĩa là sao?
1 mình nó giết sẽ được đếm hay nó ks được đếm?
Nếu ks được đếm thì ngon (y)
chắc có ngĩa là 1 + 1 dạng như lol giết 1 đứa kho 2 đứa hiện double 3 đứa hiện tripkill v.v
 
tai eclipse ?
 
if(b.getHealth()-ev.getDamage() 1)
Cái này có nghĩa là sao?
1 mình nó giết sẽ được đếm hay nó ks được đếm?
Nếu ks được đếm thì ngon (y)
b.getHealth() trả về máu của nạn nhân, (máu trước khi bị đánh)
ev.getDamage() trả về sát thương do người đánh gây nên
Code này là nếu máu nạn nhân sau khi nhận damage < 1 (chết) thì thực hiện code bên trong
 
:v
 
Đây là code Killmark (DoubleKills,..vv) dành cho ai chưa biết :D

Cách hoạt động:
- Sự kiện: Xảy ra khi người chơi giết người chơi =))
- Lưu trữ lượt giết của người giết trong một hashmap
- Boardcast (hoặc title,..) khi đạt First kill, DoubleKills, TripleKills,..
- Gửi yêu cầu reset sau ... giây
+ Số lần giết gửi kèm khi gọi hàm resetKills đúng bằng với lượt kills trong HashMap ta sẽ biết rằng từ lúc gọi hàm này đến khi scheduler xong người đó vẫn chưa có lượt giết nào mới cả, vì thế ta sẽ reset lượt kills :v
+ Số lần giết gửi kèm khi gọi hàm resetKills khác với lượt kills trong HashMap ta sẽ biết rằng từ lúc gọi hàm này đến khi scheduler xong người đó đã giết thêm một lượt nữa, vì thế ta sẽ ko reset <(")

* Code dey, nhớ thay chỗ mình in đậm
Mã:
public class Kills implements Listener {
    // thời gian reset lại lượt giết (tính theo giây)
    private int reset_time = 2;

    // hashmap chứa người giết & số lần giết
    private HashMap<Player, Integer> kills = new HashMap<>();
  
    // hàm reset lại kills
    private void resetKills(Player p, int currentKills){
        Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(Kills.plugin, new Runnable() {
            @Override
            public void run() {
                // nếu số lần giết hiện tại đúng bằng lượt giết khi request
                // vì trong khi scheduler, rất có thể người chơi này đã kills thêm 1 lần nữa, vì thế ta không thể reset
                if(kills.get(p) == currentKills){
                    kills.put(p, 0);
                }
            }
            // nhân cho 20 (1 giây = 20 ticks)
        }, reset_time * 20, reset_time * 20);
    }

    // tăng kills cho người chơi
    private void newKill(Player p){
        if(kills.containsKey(p)){
            kills.put(p, kills.get(p)+1);
        } else {
            kills.put(p, 1);
        }
    }

    @EventHandler
    public void damage(EntityDamageByEntityEvent ev){
        // kiểm tra entity giết & entity tạo ra sát thương đều là Player
        if(ev.getDamager() instanceof Player && ev.getEntity() instanceof Player) {
            Player a = (Player) ev.getDamager();
            Player b = (Player) ev.getEntity();
            // máu của người nhận sát thương (sau khi đã nhận damage) bé hơn 0 (tức là bị chết)
            if(b.getHealth()-ev.getDamage() < 1) {
                // tăng lượt giết người
                newKill(a);
                // lấy lượt giết người hiện tại
                int c = kills.get(a);
              
                if(c == 1) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt First Kills");
                } else if(c == 2) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Double Kills");
                } else if(c == 3) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Triple Kills");
                } else if(c == 4) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Quadra Kills");
                } else if(c == 5) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Penta Kills");
                } else if(c == 6) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Unstopvable");
                } else if(c == 7) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Monster Kills");
                } else if(c == 8) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Rampage");
                }
                // gửi yêu cầu reset
                resetKills(a, c);
            }
        }
    }
}
Ba cái if xài switch case thì trông nó đẹp với "clean" hơn đấy
 
Đây là code Killmark (DoubleKills,..vv) dành cho ai chưa biết :D

Cách hoạt động:
- Sự kiện: Xảy ra khi người chơi giết người chơi =))
- Lưu trữ lượt giết của người giết trong một hashmap
- Boardcast (hoặc title,..) khi đạt First kill, DoubleKills, TripleKills,..
- Gửi yêu cầu reset sau ... giây
+ Số lần giết gửi kèm khi gọi hàm resetKills đúng bằng với lượt kills trong HashMap ta sẽ biết rằng từ lúc gọi hàm này đến khi scheduler xong người đó vẫn chưa có lượt giết nào mới cả, vì thế ta sẽ reset lượt kills :v
+ Số lần giết gửi kèm khi gọi hàm resetKills khác với lượt kills trong HashMap ta sẽ biết rằng từ lúc gọi hàm này đến khi scheduler xong người đó đã giết thêm một lượt nữa, vì thế ta sẽ ko reset <(")

* Code dey, nhớ thay chỗ mình in đậm
Mã:
public class Kills implements Listener {
    // thời gian reset lại lượt giết (tính theo giây)
    private int reset_time = 2;

    // hashmap chứa người giết & số lần giết
    private HashMap<Player, Integer> kills = new HashMap<>();
  
    // hàm reset lại kills
    private void resetKills(Player p, int currentKills){
        Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(Kills.plugin, new Runnable() {
            @Override
            public void run() {
                // nếu số lần giết hiện tại đúng bằng lượt giết khi request
                // vì trong khi scheduler, rất có thể người chơi này đã kills thêm 1 lần nữa, vì thế ta không thể reset
                if(kills.get(p) == currentKills){
                    kills.put(p, 0);
                }
            }
            // nhân cho 20 (1 giây = 20 ticks)
        }, reset_time * 20, reset_time * 20);
    }

    // tăng kills cho người chơi
    private void newKill(Player p){
        if(kills.containsKey(p)){
            kills.put(p, kills.get(p)+1);
        } else {
            kills.put(p, 1);
        }
    }

    @EventHandler
    public void damage(EntityDamageByEntityEvent ev){
        // kiểm tra entity giết & entity tạo ra sát thương đều là Player
        if(ev.getDamager() instanceof Player && ev.getEntity() instanceof Player) {
            Player a = (Player) ev.getDamager();
            Player b = (Player) ev.getEntity();
            // máu của người nhận sát thương (sau khi đã nhận damage) bé hơn 0 (tức là bị chết)
            if(b.getHealth()-ev.getDamage() < 1) {
                // tăng lượt giết người
                newKill(a);
                // lấy lượt giết người hiện tại
                int c = kills.get(a);
              
                if(c == 1) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt First Kills");
                } else if(c == 2) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Double Kills");
                } else if(c == 3) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Triple Kills");
                } else if(c == 4) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Quadra Kills");
                } else if(c == 5) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Penta Kills");
                } else if(c == 6) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Unstopvable");
                } else if(c == 7) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Monster Kills");
                } else if(c == 8) {
                    Bukkit.getServer().broadcastMessage("&b&l⚙ " + a.getName() + " đã đạt Rampage");
                }
                // gửi yêu cầu reset
                resetKills(a, c);
            }
        }
    }
}
Code khá kém hiệu quả
Mã:
    private void resetKills(Player p, int currentKills){
        Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(Kills.plugin, new Runnable() {
            @Override
            public void run() {
                // nếu số lần giết hiện tại đúng bằng lượt giết khi request
                // vì trong khi scheduler, rất có thể người chơi này đã kills thêm 1 lần nữa, vì thế ta không thể reset
                if(kills.get(p) == currentKills){
                    kills.put(p, 0);
                }
            }
            // nhân cho 20 (1 giây = 20 ticks)
        }, reset_time * 20, reset_time * 20);
    }
- Lập 1 repeating task như thế này trong 1 hàm như thế này mà chỉ để reset kill của 1 người chơi? Nhất là còn ko cancel nó sau khi set xong. Càng chạy nhiều task, server càng lag, cái này nhìn rõ ra sự thiếu hiệu quả của nó rồi.

Mã:
&b&l⚙
Color Code....


Mã:
b.getHealth()-ev.getDamage()
b.getHealth() - ev.getDamage() == 0.5?
Cả 2 hàm này đều trả về double
 
Code khá kém hiệu quả
Mã:
    private void resetKills(Player p, int currentKills){
        Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(Kills.plugin, new Runnable() {
            @Override
            public void run() {
                // nếu số lần giết hiện tại đúng bằng lượt giết khi request
                // vì trong khi scheduler, rất có thể người chơi này đã kills thêm 1 lần nữa, vì thế ta không thể reset
                if(kills.get(p) == currentKills){
                    kills.put(p, 0);
                }
            }
            // nhân cho 20 (1 giây = 20 ticks)
        }, reset_time * 20, reset_time * 20);
    }
- Lập 1 repeating task như thế này trong 1 hàm như thế này mà chỉ để reset kill của 1 người chơi? Nhất là còn ko cancel nó sau khi set xong. Càng chạy nhiều task, server càng lag, cái này nhìn rõ ra sự thiếu hiệu quả của nó rồi.

Mã:
&b&l⚙
Color Code....


Mã:
b.getHealth()-ev.getDamage()
b.getHealth() - ev.getDamage() == 0.5?
Cả 2 hàm này đều trả về double
cái code này viết từ đời nào r =))
1. dạo này t thay nó sang async task, hoặc là nhét vào một hashmap chứa timemillis hiện tại, cái repeat thì quên...
2. quên
3. check nó chết chưa .-., cái này test r hđ bth
 
Sửa lần cuối:
Đây là source code của Killmark MineStrike
Toàn bộ code trong các hình dưới đây đều chạy async
Hàm playeffect của game.java sẽ chạy mỗi tick trong một async task
zkHVYwQ.png

j6UWn0O.png

ThdfQYo.png
 
Cái này có 1 cách ko dùng task là Lưu hashmap kiểu <String, <Date, Int>> <(") nếu (time hiện tại - time cuối cùng trong hashmap) lớn hơn 1 khoảng gì đó thì set lại date = thời gian hiện tại còn int thì = 1 còn ngược lại thì tương tự chỉ khác là +1 lên thôi :|
 
Similar content Most view Xem thêm
Back
Top Bottom