Jump to content
  • 0

Remaining Time on Screen/ Event countdown


Question

Posted

Hello everybody.

Well, i've been implementing a code for a type of zone that changes every 'x' minutes.

but I want to show only to all players inside these zones the time left for this zone change using ExShowScreenMessage or another method.

I tried some stuff to make this work.

Here is the code:

 

Quote

package l2r.gameserver.instancemanager;

import java.util.logging.Logger;

import l2r.gameserver.ThreadPoolManager;
import l2r.gameserver.enums.ZoneIdType;
import l2r.gameserver.model.L2World;
import l2r.gameserver.model.Location;
import l2r.gameserver.model.SpawnLocation;
import l2r.gameserver.model.actor.instance.L2PcInstance;
import l2r.gameserver.network.serverpackets.ExShowScreenMessage;
import l2r.gameserver.util.Broadcast;
import l2r.util.Rnd;

public class ZoneRandom implements Runnable
{
    private static final Logger _log = Logger.getLogger(ZoneRandom.class.getName());
    
    public int REFRESH = 2; //for debug
    public int RANDOM_RANGE = 100;
    public int RANDOM;
    public int seconds;
    
    public int timeLeft;
    
    private static final SpawnLocation[] ZONES =
    {
        new SpawnLocation(10468, -24569, -3650, 0), // Primeval Isle Wharf.
        // new SpawnLocation(106024, 114968, -1560, 0), // Hardin's Academy.
        new SpawnLocation(52113, 83315, -3372, 0),
    
    // Elven Fortress.
    };
    
    public ZoneRandom()
    {
        _log.info("ZoneRandom: Loading zones...");
        
        ThreadPoolManager.scheduleAiAtFixedRate(this, 0, REFRESH * 1000 * 60);
        
    }
    
    @Override
    public void run()
    {
        RANDOM = Rnd.get(ZONES.length - 1);
        
        for (L2PcInstance player : L2World.getInstance().getPlayers())
        {
            if (player.isInsideZone(ZoneIdType.RANDOM_ZONE))
            {
                player.teleToLocation(getRandomZone().getX() + Rnd.get(-RANDOM_RANGE, RANDOM_RANGE), getRandomZone().getY() + Rnd.get(-RANDOM_RANGE, RANDOM_RANGE), getRandomZone().getZ(), 20);
            }
        }
        
        Broadcast.toAllOnlinePlayers("The pvp area was changed to a random.", true);
        
        Broadcast.toAllOnlinePlayers("Next random pvp area will be change after " + REFRESH + " minute(s).", true);
        Broadcast.toAllOnlinePlayers("Use ''.arenajoin'' to enter on pvp zone and ''.arenaleave'' to leave.", true);
    }
    //here i treid to show on players screen the remaining time
    public void showTimeOnScreen(L2PcInstance player)
    {
        
        if (player.isInsideZone(ZoneIdType.RANDOM_ZONE))
        {
            
            player.sendPacket(new ExShowScreenMessage("02:00", 20000));
            /*
             * ThreadPool.schedule(() -> { for (seconds = 60; seconds <= 60; seconds--) { player.sendPacket(new ExShowScreenMessage("Time left: " + String.valueOf(REFRESH) + String.valueOf(seconds), 1000)); if (seconds == 0) { REFRESH = REFRESH - 1; seconds = 60; } } }, 1000);
             */
            
        }
    }
    
    public Location getRandomZone()
    {
        return ZONES[RANDOM];
    }
    
    public static ZoneRandom getInstance()
    {
        return SingletonHolder._instance;
    }
    
    private static class SingletonHolder
    {
        protected static final ZoneRandom _instance = new ZoneRandom();
    }
}

 

9 answers to this question

Recommended Posts

  • 0
Posted (edited)

code

 

 

 

take what you need and make it work

 

edit: I made it in town zone for example... you dont have to c/p that for your event

Edited by melron
  • Like 1
  • Upvote 1
  • 0
Posted

I've solved part of problem... Now players receives packets every 1000 milliseconds for 1000 miliseconds till the counter reaches zero and then they all are teleported to a randomzone previously defined. However, when the new zone 'starts', the countdown decreases two by two seconds and not one by one like it was supposed to be.  As if it were not enough, after another zone change the countdown decreases every three by three, and so on.

 

here's the new code:

public ZoneRandom()
	{
		_log.info("ZoneRandom: Loading zones...");
		
		ThreadPoolManager.scheduleAiAtFixedRate(this, 0, REFRESH * 1000);
		
	}
	
	@Override
	public void run()
	{
		RANDOM = Rnd.get(ZONES.length - 1);
		
		for (L2PcInstance player : L2World.getInstance().getPlayers())
		{
			SECONDS = REFRESH;
			if (player.isInsideZone(ZoneIdType.RANDOM_ZONE))
			{
				player.teleToLocation(getRandomZone().getX() + Rnd.get(-RANDOM_RANGE, RANDOM_RANGE), getRandomZone().getY() + Rnd.get(-RANDOM_RANGE, RANDOM_RANGE), getRandomZone().getZ(), 20);
				
				timer = new Timer();
				
				timer.scheduleAtFixedRate(new TimerTask()
				{
					
					@Override
					public void run()
					{
						showTime(player);
					}
				}, 1000, 1000);
			}
			
		}
		
		Broadcast.toAllOnlinePlayers(new CreatureSay(1, Say2.BATTLEFIELD, "Arena Manager: ", "The pvp area was changed to a random."));
		Broadcast.toAllOnlinePlayers(new CreatureSay(1, Say2.BATTLEFIELD, "Arena Manager: ", "Next random pvp area will be change after " + REFRESH + " minute(s)."));
		Broadcast.toAllOnlinePlayers(new CreatureSay(1, Say2.BATTLEFIELD, "Arena Manager: ", "Use ''.arenajoin'' to enter on pvp zone and ''.arenaleave'' to leave."));
		
	}
	
	public static void showTime(L2PcInstance player)
	{
		SECONDS = REFRESH--;
		player.sendPacket(new ExShowScreenMessage("Time Left: " + SECONDS, 1000));
		
	}


 

  • 0
Posted
2 hours ago, Reborn12 said:

You have to use ScheduledFeature for that...

Hi , bro 

I tried this code above usind ScheduleFuture. But sometimes countdown timer don't matches with zone change time. Could you give me some light?

 

 

public ZoneRandom()
	{
		_log.info("ZoneRandom: Loading zones...");
		
		ThreadPoolManager.scheduleAiAtFixedRate(this, 0, REFRESH * 1000);
		// ThreadPoolManager.scheduleAiAtFixedRate(new TimerZoneTask(), 0, REFRESH * 1000);
		
	}

@Override
	public void run()
	{
		RANDOM = Rnd.get(ZONES.length - 1);
		
		for (L2PcInstance player : L2World.getInstance().getPlayers())
		{
			
			if (player.isInsideZone(ZoneIdType.RANDOM_ZONE))
			{
				
				player.teleToLocation(getRandomZone().getX() + Rnd.get(-RANDOM_RANGE, RANDOM_RANGE), getRandomZone().getY() + Rnd.get(-RANDOM_RANGE, RANDOM_RANGE), getRandomZone().getZ(), 20);
				
				final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
				
				final Runnable seconds = () -> player.sendPacket(new ExShowScreenMessage("Time Left: " + getSeconds(), 1000));
				
				final ScheduledFuture<?> timerHandle = scheduler.scheduleAtFixedRate(seconds, 0, 1, TimeUnit.SECONDS);
				
				final Runnable canceler = () -> timerHandle.cancel(false);
				if (getSeconds() <= 0)
				{
					timerHandle.cancel(true);
				}
				scheduler.schedule(canceler, REFRESH, TimeUnit.SECONDS);
				
			}
			
		}
		
		Broadcast.toAllOnlinePlayers(new CreatureSay(1, Say2.BATTLEFIELD, "Arena Manager: ", "The pvp area was changed to a random."));
		Broadcast.toAllOnlinePlayers(new CreatureSay(1, Say2.BATTLEFIELD, "Arena Manager: ", "Next random pvp area will be change after " + REFRESH + " minute(s)."));
		Broadcast.toAllOnlinePlayers(new CreatureSay(1, Say2.BATTLEFIELD, "Arena Manager: ", "Use ''.arenajoin'' to enter on pvp zone and ''.arenaleave'' to leave."));
		
	}

public static int getSeconds()
	{
		
		return --REFRESH;
		
	}

 

  • 0
Posted

I invite you to check some other code countdown, like Duel, Olympiad, Derby or so. It's using a countdown to display time left. 

  • 0
Posted
1 hour ago, SweeTs said:

I invite you to check some other code countdown, like Duel, Olympiad, Derby or so. It's using a countdown to display time left. 

Good idea, lemme try

  • 0
Posted

Also, don't loop all players, use ZoneManager to get only the players of RandomZone. Take a look at grand boss script, even Baium. It's using zone to broadcast various things. 

  • 0
Posted
3 hours ago, melron said:

 

take what you need and make it work

 

edit: I made it in town zone for example... you dont have to c/p that for your event

 

Now it's in full working, thank you!

Guest
This topic is now closed to further replies.


×
×
  • Create New...