所以我有一个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;
}
}
答案 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.
}
}
希望我能很好地解释自己。如果您还有任何疑问,请随时提出!