/*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.l2jserver.gameserver.model.actor.instance;
import java.util.concurrent.Future;
import java.util.logging.Level;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.idfactory.IdFactory;
import com.l2jserver.gameserver.model.actor.stat.ControllableAirShipStat;
import com.l2jserver.gameserver.network.SystemMessageId;
import com.l2jserver.gameserver.network.serverpackets.DeleteObject;
import com.l2jserver.gameserver.network.serverpackets.MyTargetSelected;
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
import com.l2jserver.gameserver.templates.chars.L2CharTemplate;
public class L2ControllableAirShipInstance extends L2AirShipInstance
{
private static final int HELM = 13556;
private static final int LOW_FUEL = 40;
private int _fuel = 0;
private int _maxFuel = 0;
private int _ownerId;
private int _helmId;
private L2PcInstance _captain = null;
private Future<?> _consumeFuelTask;
private Future<?> _checkTask;
public L2ControllableAirShipInstance(int objectId, L2CharTemplate template, int ownerId)
{
super(objectId, template);
setInstanceType(InstanceType.L2ControllableAirShipInstance);
_ownerId = ownerId;
_helmId = IdFactory.getInstance().getNextId(); // not forget to release !
}
@Override
public ControllableAirShipStat getStat()
{
return (ControllableAirShipStat)super.getStat();
}
@Override
public void initCharStat()
{
setStat(new ControllableAirShipStat(this));
}
@Override
public boolean canBeControlled()
{
return super.canBeControlled() && !isInDock();
}
@Override
public boolean isOwner(L2PcInstance player)
{
if (_ownerId == 0)
return false;
return player.getClanId() == _ownerId || player.getObjectId() == _ownerId;
}
@Override
public int getOwnerId()
{
return _ownerId;
}
@Override
public boolean isCaptain(L2PcInstance player)
{
return _captain != null && player == _captain;
}
@Override
public int getCaptainId()
{
return _captain != null ? _captain.getObjectId() : 0;
}
@Override
public int getHelmObjectId()
{
return _helmId;
}
@Override
public int getHelmItemId()
{
return HELM;
}
@Override
public boolean setCaptain(L2PcInstance player)
{
if (player == null)
_captain = null;
else
{
if (_captain == null && player.getAirShip() == this)
{
final int x = player.getInVehiclePosition().getX() - 0x16e;
final int y = player.getInVehiclePosition().getY();
final int z = player.getInVehiclePosition().getZ() - 0x6b;
if (x * x + y * y + z * z > 2500)
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.CANT_CONTROL_TOO_FAR));
return false;
}
//TODO: Missing message ID: 2739 Message: You cannot control the helm because you do not meet the requirements.
else if (player.isInCombat())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_IN_A_BATTLE));
return false;
}
else if (player.isSitting())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_IN_A_SITTING_POSITION));
return false;
}
else if (player.isParalyzed())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_YOU_ARE_PETRIFIED));
return false;
}
else if (player.isCursedWeaponEquipped())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_A_CURSED_WEAPON_IS_EQUIPPED));
return false;
}
else if (player.isFishing())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_FISHING));
return false;
}
else if (player.isDead() || player.isFakeDeath())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHEN_YOU_ARE_DEAD));
return false;
}
else if (player.isCastingNow())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_USING_A_SKILL));
return false;
}
else if (player.isTransformed())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_TRANSFORMED));
return false;
}
else if (player.isCombatFlagEquipped())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_HOLDING_A_FLAG));
return false;
}
else if (player.isInDuel())
{
player.sendPacket(SystemMessage.getSystemMessage(SystemMessageId.YOU_CANNOT_CONTROL_THE_HELM_WHILE_IN_A_DUEL));
return false;
}
_captain = player;
player.broadcastUserInfo();
}
else
return false;
}
updateAbnormalEffect();
return true;
}
@Override
public int getFuel()
{
return _fuel;
}
@Override
public void setFuel(int f)
{
final int old = _fuel;
if (f < 0)
_fuel = 0;
else if (f > _maxFuel)
_fuel = _maxFuel;
else
_fuel = f;
if (_fuel == 0 && old > 0)
broadcastToPassengers(SystemMessage.getSystemMessage(SystemMessageId.THE_AIRSHIP_FUEL_RUN_OUT));
else if (_fuel < LOW_FUEL)
broadcastToPassengers(SystemMessage.getSystemMessage(SystemMessageId.THE_AIRSHIP_FUEL_SOON_RUN_OUT));
}
@Override
public int getMaxFuel()
{
return _maxFuel;
}
@Override
public void setMaxFuel(int mf)
{
_maxFuel = mf;
}
@Override
public void oustPlayer(L2PcInstance player)
{
if (player == _captain)
setCaptain(null); // no need to broadcast userinfo here
super.oustPlayer(player);
}
@Override
public void onAction(L2PcInstance player, boolean interact)
{
player.sendPacket(new MyTargetSelected(_helmId, 0));
super.onAction(player, interact);
}
@Override
public void onSpawn()
{
super.onSpawn();
_checkTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new CheckTask(), 60000, 10000);
_consumeFuelTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new ConsumeFuelTask(), 60000, 60000);
}
@Override
public void deleteMe()
{
super.deleteMe();
if (_checkTask != null)
{
_checkTask.cancel(false);
_checkTask = null;
}
if (_consumeFuelTask != null)
{
_consumeFuelTask.cancel(false);
_consumeFuelTask = null;
}
try
{
broadcastPacket(new DeleteObject(_helmId));
}
catch (Exception e)
{
_log.log(Level.SEVERE, "Failed decayMe():"+e.getMessage());
}
}
@Override
public void refreshID()
{
super.refreshID();
IdFactory.getInstance().releaseId(_helmId);
_helmId = IdFactory.getInstance().getNextId();
}
@Override
public void sendInfo(L2PcInstance activeChar)
{
super.sendInfo(activeChar);
if (_captain != null)
_captain.sendInfo(activeChar);
}
private final class ConsumeFuelTask implements Runnable
{
public void run()
{
int fuel = getFuel();
if (fuel > 0)
{
fuel -= 10;
if (fuel < 0)
fuel = 0;
setFuel(fuel);
updateAbnormalEffect();
}
}
}
private final class CheckTask implements Runnable
{
public void run()
{
if (isVisible()
&& isEmpty()
&& !isInDock())
// deleteMe() can't be called from CheckTask because task should not cancel itself
ThreadPoolManager.getInstance().executeTask(new DecayTask());
}
}
private final class DecayTask implements Runnable
{
public void run()
{
deleteMe();
}
}
}