随着时间的推移运行任务?

时间:2013-08-08 21:05:05

标签: java time task schedule

所以我有一个NPC,如果你是一个特殊的玩家,我希望它在5分钟或10分钟内改变它的外观。 NPC改变两次然后完全自我消除。一旦玩家死亡,NPC将被置于当前位置。 NPC然后在5分钟内开始降级,然后最终自行消除。该NPC允许玩家在计时器用完之前抓住丢失的物品。当NPC在那里时,其他玩家可以选择重置计时器,以便他们有更多时间到达那里。我能够降低它并向他们发送一条消息,说明他们离开的时间让他们的物品回来了。在它破坏之前,唯一的问题是在最后发生的。它不断向播放器发送一条消息,说明他们离开的时间而不是一次,而且永远不会被删除。这是我的代码:

package com.rs.game.npc.others;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;

import com.rs.game.item.Item;
import com.rs.game.npc.NPC;
import com.rs.game.player.Player;
import com.rs.game.player.Skills;
import com.rs.utils.Logger;

public class Gravestone extends NPC implements Serializable {

    private static final long serialVersionUID = -3293609625562930841L;
    private transient Player player;
    private long BEGIN_TIME;
    private int currentGrave;
    private final CopyOnWriteArrayList<Item> container;
    private int MAX_TIME = 6*60000;//60000ms = 1 min
    private int INTERFACE = 272;
    private long timeLeft = (long) (System.currentTimeMillis() - BEGIN_TIME);
    private int minutes;

    public Gravestone(Player player, CopyOnWriteArrayList<Item> containedItems) {
        super(6601, player, -1, false, false);
        this.player = player;
        this.BEGIN_TIME = System.currentTimeMillis();
        if (player.isDonator())
            this.MAX_TIME *= player.getDonator();

        this.currentGrave = 6601;
        this.container = containedItems;
        setName(player.getDisplayName()+ "'s Gravestone");
        player.sm("A gravestone has been left in the place you died to receive your items click on it.");
    }

    public Gravestone(Player player, CopyOnWriteArrayList<Item> containedItems, long time, int npcId) {
        super(npcId, player, -1, false);
        this.player = player;
        this.container = containedItems;
        setName(player.getDisplayName()+ "'s Gravestone");

    }

    public String getName() {
        return player.getDisplayName()+ "'s Gravestone";
    }
    public void processNPC() {
        if (hasFinished())
            return;
        setName(getName());
        long timeElapsed =  System.currentTimeMillis( ) - BEGIN_TIME;
        int minute = 60000;
        int minutesElapsed = (int) (timeElapsed / minute);
        int maxMinutes = MAX_TIME / minute;
        minutes = maxMinutes - minutesElapsed;
        boolean pause = false;
        if (!pause && (minutes == 5 && getId() == 6601 //first - degrade at 5 minutes stop and wait til unpause
                || minutes == 3 && getId() == 6602 //second - degrade at 3 minutes
                || minutes <= 0 && getId() == 6603)){ //third - degrade at 1 minute
                degradeGraveStone();
                pause = true;
        } else if (pause && (minutes == 4 && getId() == 6602 //second
                    || minutes == 2 && getId() == 6603)) //third
            pause = false;
        Logger.log("GraveStone", "Player "+ player.getDisplayName() +" time elapsed "+ timeElapsed +" minutes left "+ minutes +" Pause? "+pause);
    }

    public void handleOptions(Player p, int id, int npcId) {
        switch (id) {
            case 1:
                sendMemorial(p);
                break;
            case 2:
                if (npcId == 6601)
                    demolishGraveStone(p);
                else 
                    repairGraveStone(p);
                break;
            case 3:
                    blessGraveStone(p);
                break;
            case 4:
                demolishGraveStone(p);
                break;
        }
    }

    private void degradeGraveStone() {
        if (currentGrave < 6603) { 
            graveStoneDegrade(currentGrave + 1);
        } else {
            demolishGraveStone(player);
            return;
        }
        setName(player.getDisplayName()+ "'s Gravestone");
        player.sm("Your gravestone slighlty degrades, you have" + minutes + " minutes to get your items back!");
    }

    private void demolishGraveStone(Player p) {
        if (player != p) {
            p.sm("You cannot destroy a grave that isn't yours!");
            return;
        }
        player.sm("Your gravestone has been destroyed.");
        player.sm("Your items have been added to your bank.");
        for (Item item : container)
            player.getBank().addItem(item.getId(), item.getAmount(), true);

        finish();
    }

    private void blessGraveStone(Player p) {
        if (p.getSkills().getLevel(Skills.PRAYER) < 90){
            p.sm("You need a prayer level of at least 90 to bless this Grave Stone.");
            return;
        }

        p.sm("You bless " + player.getDisplayName() + "'s Grave Stone.");
        player.sm(p.getDisplayName() + " has blessed your GraveStone.");
        graveStoneDegrade(6601);
        setName(player.getDisplayName()+ "'s Gravestone");
        BEGIN_TIME = System.currentTimeMillis();
    }

    private void repairGraveStone(Player p) {
        if (p.getSkills().getLevel(Skills.CRAFTING) < 75){
            p.sm("You need a crafting level of at least 75 to repair this Grave Stone.");
            return;
        }
        p.sm("You repair " + player.getDisplayName() + "'s Grave Stone.");
        player.sm(p.getDisplayName() + " has repaired your GraveStone.");
        graveStoneDegrade(this.getId() - 1);
        setName(player.getDisplayName()+ "'s Gravestone");
        BEGIN_TIME = System.currentTimeMillis();
    }

    private void sendMemorial(Player p) {
        p.getInterfaceManager().sendInterface(INTERFACE);
        p.getPackets().sendIComponentText(INTERFACE, 16, getName());
    }

    public Player getPlayer() {
        return player;
    }

}

1 个答案:

答案 0 :(得分:0)

我快速而轻松地做到了这一点。随意使用它!

TimerID用于指示哪个计时器是停止的计时器,因此您希望拥有多个计时器。 GameTimerListener接口有两个方法。

public interface GameTimerListener {

    public void SuccessfullStop(int TimerID);
    public void AbortedStop(int TimerID);
}

这是GameTimer课程。

public class GameTimer implements Runnable{
private Thread TimerThread = new Thread(this);

private List<GameTimerListener> Listeners = new ArrayList<GameTimerListener>();

public static final int Seconds = 0,Minutes = 1,Hours = 2;

private int TimerID;
private int TimerSeconds;
private int Timeout = -1;

private boolean Ticking;
private boolean Paused;

public GameTimer(int TimerID){ this.TimerID = TimerID; }
public GameTimer(int TimerID,int SecondsToRun){ this.TimerID = TimerID; Timeout = SecondsToRun; }

public void run(){
    long Timer = System.currentTimeMillis();
    long LastTime;

    try{
        while(Ticking){
            LastTime = System.nanoTime();
            if((System.currentTimeMillis() - Timer) >= 1000){
                Timer+= 1000;

                if(!Paused){
                   TimerSeconds++;
                }

                if((Timeout - TimerSeconds) <= 0){
                    SuccessfullStop();
                    break;
                }
            }

            Thread.sleep(10);
        }
    }catch(Exception e){ e.printStackTrace(); }
}
private int[] TimeLeftGetter(){
    int Seconds = (Timeout - TimerSeconds);
    int Minutes = 0;
    int Hours = 0;

    for(int x = 0; x < (Timeout - TimerSeconds); x++){
        if(Seconds > 60){
            Minutes++;
            Seconds -= 60;

            if(Minutes >= 60){
                Hours++;
                Minutes -= 60;
            }
        }
    }

    Seconds = Seconds <= 0 ? 0 : Seconds;

    return new int[]{Seconds,Minutes,Hours};
}
public synchronized void start(){ 
    if(Timeout == 0){ return; }
    if(Ticking){ ForceStop(); }

    TimerSeconds = 0;
    Ticking = true;

    TimerThread = new Thread(this);
    TimerThread.start();
}
public void ForceStop(){
    try{
        Ticking = false;
        TimerThread.join();

        for(GameTimerListener rtl : Listeners)
            rtl.AbortedStop(TimerID);
    }catch(Exception e){ e.printStackTrace(); }
}
public String getTimeLeftByString(){
    String time = "";
    int[] Time = TimeLeftGetter();

    time = Time[Hours] + ":" + Time[Minutes] + ":" + Time[Seconds];

    return time;
}

public boolean TimeOver(){ 
    if((Timeout - TimerSeconds) <= 0) {
        return true;
    }

    return false; 
}   
private void SuccessfullStop(){ 
    Ticking = false; 

    for(GameTimerListener rtl : Listeners)
        rtl.SuccessfullStop(TimerID);
}
public void setTimeToStop(int Seconds){
    Timeout = Seconds;

    if(Ticking){ start(); }
}
public void addGameTimerListener(GameTimerListener rtl){
    if(!Listeners.contains(rtl))
        Listeners.add(rtl);
}
public void Remove(GameTimerListener rtl){
    if(Listeners.contains(rtl))
        Listeners.remove(rtl);
}
public int getTimerID(){ return TimerID; }
public int getSecondsToRun(){ return Timeout; }
public int[] getTimeLeftByInteger(){ return TimeLeftGetter(); }
public boolean NeverStops(){ return Timeout <= -1 ? true : false; }
public boolean Ticking(){ return Ticking; }
public void setPaused(boolean Value){ Paused = Value; }
}

这就是你要去实现这个的方法。 在你的墓碑类上,让它实现GameTimerListener。

   public class Gravestone extends NPC implements Serializable, GameTimeListener {

您将使用的两种方法是SuccessfullStop(int TimerID):void;和AbortedStop():void; 在方法SuccessfullStop中,您将在时间到来时放置代码。 现在,假设您要创建一个运行五分钟的新计时器。这就是你如何做到的。

GameTimer MyTimer = new GameTimer(10,1500);

第一个参数是计时器的ID。 我决定给它10作为ID,因为我喜欢10号。 第二个参数是以秒为单位运行的时间。 1500秒是5分钟。

在开始之前或之前,请务必将墓碑类添加为听众。

MyTimer.addGameTimerListener(this);

现在,只要你想启动计时器,只需调用方法:

MyTimer.start();

这将为您完成所有工作。 当计时器达到0时,它将调用您的SuccessfullStop()方法。

现在,如果您使用两个计时器怎么办?这就是使用TimerID的地方。 调用SuccessfullStop()方法时,请注意作为参数传递的Integer。

public void SuccessfullStop(int TimerID){
    if(TimerID == MyTimer.getTimerID()){
         //If the timer that stopped was MyTimer..
         //Code goes here for your desired timer.
    }
}
希望我能很好地解释自己。如果您还有任何疑问,请随时提出!