package net.sf.l2j.gameserver.instancemanager; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; import java.util.concurrent.ScheduledFuture; import net.sf.l2j.gameserver.ThreadPoolManager; import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance; import net.sf.l2j.gameserver.model.zone.ZoneType; import net.sf.l2j.gameserver.skills.Stats; import net.sf.l2j.gameserver.network.SystemMessageId; import net.sf.l2j.gameserver.network.serverpackets.SetupGauge; import net.sf.l2j.gameserver.network.serverpackets.SystemMessage; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class WaterFishingManager { protected static Log _log = LogFactory.getLog(WaterFishingManager.class.getName()); private static WaterFishingManager _instance; private int WATER_TASK_RATE = 1000; // water task rate private int WATER_COOLDOWN = 5000; // breath cooldown private Map> _waterTasks; //TODO: G1ta0 -> move fishing routine from L2PcInstance public static final WaterFishingManager getInstance() { if(_instance == null) { _log.info("Initializing WaterFishingManager"); _instance = new WaterFishingManager(); _instance.load(); } return _instance; } public WaterFishingManager() {} public void reload() { _log.info("Reloading WaterFishingManager"); load(); } private void load() { _waterTasks = Collections.synchronizedMap(new WeakHashMap>()); } // TODO: G1ta0 -> water: add dismount // TODO: G1ta0 -> water: add speed change and status update packet public void startWaterTask(L2PcInstance player) { if(player != null && !player.isDead() && !_waterTasks.containsKey(player)) _waterTasks.put(player, ThreadPoolManager.getInstance().scheduleEffectAtFixedRate(new WaterTask(player), WATER_TASK_RATE, WATER_TASK_RATE)); } public void stopWaterTask(L2PcInstance player) { if(_waterTasks.containsKey(player)) { ScheduledFuture _waterTask = _waterTasks.get(player); _waterTask.cancel(false); _waterTasks.remove(player); } } class WaterTask implements Runnable { L2PcInstance _player; private int _coolDownTime; private int _inWaterTime; private int _inWaterTotal; WaterTask(L2PcInstance player) { _player = player; _inWaterTotal = (int) player.calcStat(Stats.BREATH, 60000, player, null); _inWaterTime = _inWaterTotal; player.sendPacket(new SetupGauge(SetupGauge.CYAN, _inWaterTime)); } public void run() { if(_player == null || _player.isDead()) { if (_player != null) _player.sendPacket(new SetupGauge(SetupGauge.CYAN, 0)); stopWaterTask(_player); return; } if(_player.isInsideZone(ZoneType.Water)) { _inWaterTime -= WATER_TASK_RATE; if(_coolDownTime < WATER_COOLDOWN) { if (_inWaterTime > 0) _player.sendPacket(new SetupGauge(SetupGauge.CYAN, _inWaterTime, _inWaterTotal)); _coolDownTime = WATER_COOLDOWN; } if (_inWaterTime <= 0) { double reduceHp = _player.getMaxHp() / 100.0; if(reduceHp < 1) reduceHp = 1; _player.reduceCurrentHp(reduceHp, _player, false); SystemMessage sm = new SystemMessage(SystemMessageId.DROWN_DAMAGE_S1); sm.addNumber((int) reduceHp); _player.sendPacket(sm); } } else { // if 5 seconds outside of water, stoping task if(_coolDownTime <= 0) { stopWaterTask(_player); return; } else { _player.sendPacket(new SetupGauge(SetupGauge.CYAN, 0)); _coolDownTime -= WATER_TASK_RATE; } } } } }