2013-08-08 3 views
0

그래서 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

아마도'processNPC()'안에 이러한 괄호를 추가해야 할 것입니다. 그들은 읽을 수 없다. 이 메서드는 초당 몇 번 호출됩니까? –

+0

초당 한 번 나는 믿습니다. –

+0

이 코드는 여러 스레드에서 실행됩니까? NPC가 가까이에있을 때 보게되는 로그 메시지를 추가 할 수 있습니까? 왜냐하면 당신이 말하는 메시지가 'degradeGraveStone()'에있는 것이기 때문에 당신의 묘비가 떨어지면 물건을 되 찾을 x 분이 남았습니다! "나는 그것이 가능한지 모르겠다. 그리고'graveStoneDegrade()'와'hasFinished() '에 대한 코드를 추가하십시오. –

답변

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 메서드는 시간이 끝날 때 코드를 저장하는 곳입니다. 이제 5 분 동안 실행되는 새 타이머를 만들고 싶다고 가정 해 보겠습니다. 이것이 당신이하는 방법입니다.

GameTimer MyTimer = new GameTimer(10,1500); 

첫 번째 매개 변수는 타이머의 ID입니다. 숫자 10을 좋아하기 때문에 ID 10으로 지정하기로했습니다. 두 번째 매개 변수는 초 단위로 실행되는 시간입니다. 1500 초는 5 분입니다.

시작하기 전에 반드시 gravestone 클래스를 리스너로 추가하십시오. 이제

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. 
    } 
} 

희망을 잘 설명했습니다. 아직 궁금한 사항이 있으시면 언제든지 문의하십시오!

+0

제가 제공 한 코드와 함께 이것을 어떻게 사용하는지 예제를 제공해 주시겠습니까? 나는 단지 다음과 같이 행동 할까? GameTimer timer = new GameTimer (5); 잘 모르겠습니다. 도와 주시겠습니까? –

+0

편집을 통해 구현 방법을 볼 수 있습니다. D –