com.l2jfree.gameserver.gameobjects.instance.L2BoatInstance.java Source code

Java tutorial

Introduction

Here is the source code for com.l2jfree.gameserver.gameobjects.instance.L2BoatInstance.java

Source

/*
 * 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.l2jfree.gameserver.gameobjects.instance;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.LineNumberReader;
import java.util.Collection;
import java.util.Map;
import java.util.StringTokenizer;

import javolution.util.FastMap;

import org.apache.commons.io.IOUtils;

import com.l2jfree.Config;
import com.l2jfree.gameserver.ThreadPoolManager;
import com.l2jfree.gameserver.gameobjects.L2Creature;
import com.l2jfree.gameserver.gameobjects.L2Player;
import com.l2jfree.gameserver.gameobjects.ai.L2CreatureAI;
import com.l2jfree.gameserver.gameobjects.knownlist.BoatKnownList;
import com.l2jfree.gameserver.gameobjects.knownlist.CreatureKnownList;
import com.l2jfree.gameserver.gameobjects.templates.L2CreatureTemplate;
import com.l2jfree.gameserver.instancemanager.GameTimeManager;
import com.l2jfree.gameserver.model.L2CharPosition;
import com.l2jfree.gameserver.model.items.L2ItemInstance;
import com.l2jfree.gameserver.network.SystemChatChannelId;
import com.l2jfree.gameserver.network.packets.server.CreatureSay;
import com.l2jfree.gameserver.network.packets.server.InventoryUpdate;
import com.l2jfree.gameserver.network.packets.server.PlaySound;
import com.l2jfree.gameserver.network.packets.server.VehicleCheckLocation;
import com.l2jfree.gameserver.network.packets.server.VehicleDeparture;
import com.l2jfree.gameserver.network.packets.server.VehicleInfo;
import com.l2jfree.gameserver.network.packets.server.VehicleStarted;
import com.l2jfree.gameserver.taskmanager.MovementController;
import com.l2jfree.gameserver.util.Util;

/**
 * @author Maktakien
 */
public class L2BoatInstance extends L2Creature {
    public float boatSpeed;

    private class L2BoatTrajet {
        private Map<Integer, L2BoatPoint> _path;

        public int idWaypoint1;
        public int idWTicket1;
        public int ntx1;
        public int nty1;
        public int ntz1;
        public int max;
        public String boatName;
        public String npc1;
        public String sysmess10_1;
        public String sysmess5_1;
        public String sysmess1_1;
        public String sysmessb_1;
        public String sysmess0_1;

        protected class L2BoatPoint {
            public int speed1;
            public int speed2;
            public int x;
            public int y;
            public int z;
            public int time;
        }

        /**
         * @param pIdWaypoint1
         * @param pIdWTicket1
         * @param pNtx1
         * @param pNty1
         * @param pNtz1
         * @param pNpc1
         * @param pSysmess10_1
         * @param pSysmess5_1
         * @param pSysmess1_1
         * @param pSysmess0_1
         * @param pSysmessb_1
         * @param pBoatname
         */
        public L2BoatTrajet(int pIdWaypoint1, int pIdWTicket1, int pNtx1, int pNty1, int pNtz1, String pNpc1,
                String pSysmess10_1, String pSysmess5_1, String pSysmess1_1, String pSysmess0_1, String pSysmessb_1,
                String pBoatname) {
            idWaypoint1 = pIdWaypoint1;
            idWTicket1 = pIdWTicket1;
            ntx1 = pNtx1;
            nty1 = pNty1;
            ntz1 = pNtz1;
            npc1 = pNpc1;
            sysmess10_1 = pSysmess10_1;
            sysmess5_1 = pSysmess5_1;
            sysmess1_1 = pSysmess1_1;
            sysmessb_1 = pSysmessb_1;
            sysmess0_1 = pSysmess0_1;
            boatName = pBoatname;
            loadBoatPath();
        }

        /**
         * @param line
         * @return
         */
        public void parseLine(String line) {
            // L2BoatPath bp = new L2BoatPath();
            _path = new FastMap<Integer, L2BoatPoint>();
            StringTokenizer st = new StringTokenizer(line, ";");
            Integer.parseInt(st.nextToken());
            max = Integer.parseInt(st.nextToken());
            for (int i = 0; i < max; i++) {
                L2BoatPoint bp = new L2BoatPoint();
                bp.speed1 = Integer.parseInt(st.nextToken());
                bp.speed2 = Integer.parseInt(st.nextToken());
                bp.x = Integer.parseInt(st.nextToken());
                bp.y = Integer.parseInt(st.nextToken());
                bp.z = Integer.parseInt(st.nextToken());
                bp.time = Integer.parseInt(st.nextToken());
                _path.put(i, bp);
            }
        }

        /**
         *
         */
        private void loadBoatPath() {
            LineNumberReader lnr = null;
            try {
                File doorData = new File(Config.DATAPACK_ROOT, "data/boatpath.csv");
                lnr = new LineNumberReader(new BufferedReader(new FileReader(doorData)));

                String line = null;
                while ((line = lnr.readLine()) != null) {
                    if (line.trim().length() == 0 || !line.startsWith(idWaypoint1 + ";"))
                        continue;
                    parseLine(line);
                    return;
                }
                _log.warn("No path for boat " + boatName + " !!!");
            } catch (FileNotFoundException e) {
                _log.warn("boatpath.csv is missing in data folder", e);
            } catch (Exception e) {
                _log.warn("error while creating boat table ", e);
            } finally {
                IOUtils.closeQuietly(lnr);
            }
        }

        /**
         * @param state
         * @return
         */
        public int state(int state, L2BoatInstance _boat) {
            if (state < max) {
                L2BoatPoint bp = _path.get(state);
                double dx = (_boat.getX() - bp.x);
                double dy = (_boat.getY() - bp.y);
                double distance = Math.sqrt(dx * dx + dy * dy);
                double cos;
                double sin;
                sin = dy / distance;
                cos = dx / distance;

                _boat.getPosition().setHeading(Util.calculateHeadingFrom(cos, sin));

                _boat._vd = new VehicleDeparture(_boat, bp.speed1, bp.speed2, bp.x, bp.y, bp.z);
                // _boat.getTemplate().baseRunSpd = bp.speed1;
                boatSpeed = bp.speed1;
                _boat.moveToLocation(bp.x, bp.y, bp.z, (float) bp.speed1);
                if (bp.time == 0)
                    bp.time = 1;

                Collection<L2Player> knownPlayers = _boat.getKnownList().getKnownPlayers().values();
                if (knownPlayers != null && !knownPlayers.isEmpty()) {
                    for (L2Player player : knownPlayers) {
                        player.sendPacket(_boat._vd);
                    }
                }
                return bp.time;
            }

            return 0;
        }
    }

    private final String _name;
    protected L2BoatTrajet _t1;
    protected L2BoatTrajet _t2;
    protected int _cycle = 0;
    protected VehicleDeparture _vd = null;
    private Map<Integer, L2Player> _inboat;
    private boolean _inCycle = true;

    public int getSizeInside() {
        return _inboat == null ? 0 : _inboat.size();
    }

    public String getBoatName() {
        return _name;
    }

    public int getCycle() {
        return _cycle;
    }

    public boolean isInCycle() {
        return _inCycle;
    }

    public void stopCycle() {
        _inCycle = false;
        stopMove(new L2CharPosition(getX(), getY(), getZ(), getPosition().getHeading()));
    }

    public void startCycle() {
        _inCycle = true;
        _cycle = 1;
        beginCycle();
    }

    public void reloadPath() {
        _t1.loadBoatPath();
        _t2.loadBoatPath();
        _cycle = 0;
        stopCycle();
        startCycle();
    }

    public L2BoatInstance(int objectId, L2CreatureTemplate template, String name) {
        super(objectId, template);
        getKnownList();
        getAI();
        _name = name;
    }

    @Override
    protected CreatureKnownList initKnownList() {
        return new BoatKnownList(this);
    }

    @Override
    public BoatKnownList getKnownList() {
        return (BoatKnownList) _knownList;
    }

    /**
     * @param x
     * @param y
     * @param z
     */
    public void moveToLocation(int x, int y, int z, float speed) {
        final int curX = getX();
        final int curY = getY();

        // Calculate distance (dx,dy) between current position and destination
        final int dx = (x - curX);
        final int dy = (y - curY);
        double distance = Math.sqrt(dx * dx + dy * dy);

        if (_log.isDebugEnabled())
            _log.debug("distance to target:" + distance);

        // Define movement angles needed
        // ^
        // | X (x,y)
        // | /
        // | /distance
        // | /
        // |/ angle
        // X ---------->
        // (curx,cury)

        double cos;
        double sin;
        sin = dy / distance;
        cos = dx / distance;
        // Create and Init a MoveData object
        MoveData m = new MoveData();

        // Calculate the Nb of ticks between the current position and the destination
        int ticksToMove = (int) (GameTimeManager.TICKS_PER_SECOND * distance / speed);

        // Calculate and set the heading of the L2Creature
        int heading = (int) (Math.atan2(-sin, -cos) * 10430.378350470452724949566316381);
        heading += 32768;
        getPosition().setHeading(heading);

        if (_log.isDebugEnabled())
            _log.debug("dist:" + distance + "speed:" + speed + " ttt:" + ticksToMove + " heading:" + heading);

        m._xDestination = x;
        m._yDestination = y;
        m._zDestination = z; // this is what was requested from client
        m._heading = 0; // initial value for coordinate sync
        m.onGeodataPathIndex = -1; // Initialize not on geodata path
        m._moveStartTime = GameTimeManager.getGameTicks();

        if (_log.isDebugEnabled())
            _log.debug("time to target:" + ticksToMove);

        // Set the L2Creature _move object to MoveData object
        _move = m;

        MovementController.getInstance().add(this, ticksToMove);
    }

    private class BoatCaptain implements Runnable {
        private final int _state;
        private final L2BoatInstance _boat;

        /**
         * @param i
         * @param instance
         */
        public BoatCaptain(int i, L2BoatInstance instance) {
            _state = i;
            _boat = instance;
        }

        @Override
        public void run() {
            if (!_inCycle)
                return;
            if (_boat.getId() == 5) // Rune <-> Primeval Isle
            {
                switch (_state) {
                case 1:
                    _boat.say(-1);
                    _boat.begin();
                    break;
                }
            } else {
                BoatCaptain bc;
                switch (_state) {
                case 1:
                    _boat.say(5);
                    bc = new BoatCaptain(2, _boat);
                    ThreadPoolManager.getInstance().scheduleGeneral(bc, 240000);
                    break;
                case 2:
                    _boat.say(1);
                    bc = new BoatCaptain(3, _boat);
                    ThreadPoolManager.getInstance().scheduleGeneral(bc, 40000);
                    break;
                case 3:
                    _boat.say(0);
                    bc = new BoatCaptain(4, _boat);
                    ThreadPoolManager.getInstance().scheduleGeneral(bc, 20000);
                    break;
                case 4:
                    _boat.say(-1);
                    _boat.begin();
                    break;
                }
            }
        }
    }

    private class Boatrun implements Runnable {
        private int _state;
        private final L2BoatInstance _boat;

        /**
         * @param i
         * @param instance
         */
        public Boatrun(int i, L2BoatInstance instance) {
            _state = i;
            _boat = instance;
        }

        @Override
        public void run() {
            if (!_inCycle)
                return;
            _boat._vd = null;
            _boat.needOnVehicleCheckLocation = false;
            if (_boat._cycle == 1) {
                int time = _boat._t1.state(_state, _boat);
                if (time > 0) {
                    _state++;
                    Boatrun bc = new Boatrun(_state, _boat);
                    ThreadPoolManager.getInstance().scheduleGeneral(bc, time);

                } else if (time == 0) {
                    _boat._cycle = 2;
                    _boat.say(10);
                    BoatCaptain bc = new BoatCaptain(1, _boat);
                    ThreadPoolManager.getInstance().scheduleGeneral(bc, 300000);
                } else {
                    _boat.needOnVehicleCheckLocation = true;
                    _state++;
                    _boat._runstate = _state;
                }
            } else if (_boat._cycle == 2) {
                int time = _boat._t2.state(_state, _boat);
                if (time > 0) {
                    _state++;
                    Boatrun bc = new Boatrun(_state, _boat);
                    ThreadPoolManager.getInstance().scheduleGeneral(bc, time);
                } else if (time == 0) {
                    _boat._cycle = 1;
                    _boat.say(10);
                    BoatCaptain bc = new BoatCaptain(1, _boat);
                    ThreadPoolManager.getInstance().scheduleGeneral(bc, 300000);
                } else {
                    _boat.needOnVehicleCheckLocation = true;
                    _state++;
                    _boat._runstate = _state;
                }
            }
        }
    }

    public int _runstate = 0;

    /**
     *
     */
    public void evtArrived() {

        if (_runstate != 0) {
            // _runstate++;
            Boatrun bc = new Boatrun(_runstate, this);
            ThreadPoolManager.getInstance().scheduleGeneral(bc, 10);
            _runstate = 0;
        }
    }

    /**
     * @return
     */
    public int getId() {
        return _id;
    }

    /**
     * @param activeChar
     */
    public void sendVehicleDeparture(L2Player activeChar) {
        if (_vd != null) {
            activeChar.sendPacket(_vd);
        }
    }

    public VehicleDeparture getVehicleDeparture() {
        return _vd;
    }

    public void beginCycle() {
        _inCycle = true;
        say(10);
        BoatCaptain bc = new BoatCaptain(1, this);
        if (getId() == 5)
            ThreadPoolManager.getInstance().scheduleGeneral(bc, 180000);
        else
            ThreadPoolManager.getInstance().scheduleGeneral(bc, 300000);
    }

    /**
     * @param destination
     * @param destination2
     * @param destination3
     */
    private int lastx = -1;
    private int lasty = -1;
    protected boolean needOnVehicleCheckLocation = false;
    private int _id;

    public void updatePeopleInTheBoat(int x, int y, int z) {
        if (_inboat != null) {
            boolean check = false;
            if ((lastx == -1) || (lasty == -1)) {
                check = true;
                lastx = x;
                lasty = y;
            } else if ((x - lastx) * (x - lastx) + (y - lasty) * (y - lasty) > 2250000) // 1500 sq
            {
                check = true;
                lastx = x;
                lasty = y;
            }
            for (int i = 0; i < _inboat.size(); i++) {
                L2Player player = _inboat.get(i);
                if (player != null && player.isInBoat() && player.getBoat() == this) {
                    // player.getKnownList().addKnownObject(this);
                    player.getPosition().setXYZ(x, y, z);
                    player.revalidateZone(false);
                }
                if (check) {
                    if (needOnVehicleCheckLocation && player != null) {
                        VehicleCheckLocation vcl = new VehicleCheckLocation(this, x, y, z);
                        player.sendPacket(vcl);
                    }
                }
            }
        }

    }

    public void begin() {
        if (!_inCycle)
            return;
        if (_cycle == 1) {
            Collection<L2Player> knownPlayers = getKnownList().getKnownPlayers().values();
            if (knownPlayers != null && !knownPlayers.isEmpty()) {
                _inboat = new FastMap<Integer, L2Player>();
                int i = 0;
                for (L2Player player : knownPlayers) {
                    if (player.isInBoat() && player.getBoat() == this) {
                        L2ItemInstance it;
                        it = player.getInventory().getItemByItemId(_t1.idWTicket1);
                        if (it != null) {
                            player.getInventory().destroyItem("Boat", it.getObjectId(), 1, player, this);
                            InventoryUpdate iu = new InventoryUpdate();
                            iu.addItem(it);
                            player.sendPacket(iu);
                            _inboat.put(i, player);
                            i++;
                        } else if (_t1.idWTicket1 == 0) {
                            _inboat.put(i, player);
                            i++;
                        } else {
                            player.teleToLocation(_t1.ntx1, _t1.nty1, _t1.ntz1, false);
                        }
                    }
                }
            }
            Boatrun bc = new Boatrun(0, this);
            ThreadPoolManager.getInstance().scheduleGeneral(bc, 0);
        } else if (_cycle == 2) {
            Collection<L2Player> knownPlayers = getKnownList().getKnownPlayers().values();
            if (knownPlayers != null && !knownPlayers.isEmpty()) {
                _inboat = new FastMap<Integer, L2Player>();
                int i = 0;
                for (L2Player player : knownPlayers) {
                    if (player.isInBoat()) {
                        L2ItemInstance it;
                        it = player.getInventory().getItemByItemId(_t2.idWTicket1);
                        if (it != null) {
                            player.getInventory().destroyItem("Boat", it.getObjectId(), 1, player, this);
                            InventoryUpdate iu = new InventoryUpdate();
                            iu.addItem(it);
                            player.sendPacket(iu);
                            _inboat.put(i, player);
                            i++;
                        } else if (_t2.idWTicket1 == 0) {
                            _inboat.put(i, player);
                            i++;
                        } else {
                            player.teleToLocation(_t2.ntx1, _t2.nty1, _t2.ntz1, false);
                        }
                    }
                }

            }
            Boatrun bc = new Boatrun(0, this);
            ThreadPoolManager.getInstance().scheduleGeneral(bc, 0);
        }
    }

    /**
     * @param i
     */
    public void say(int i) {
        Collection<L2Player> knownPlayers = getKnownList().getKnownPlayers().values();
        CreatureSay sm;
        CreatureSay sm2 = null;
        PlaySound ps;
        switch (i) {
        case 10:
            if (_cycle == 1) {
                sm = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t1.npc1, _t1.sysmess10_1);
                if (getId() == 5)
                    sm2 = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t1.npc1, _t1.sysmess5_1);
            } else {
                sm = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t2.npc1, _t2.sysmess10_1);
                if (getId() == 5)
                    sm2 = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t2.npc1, _t2.sysmess5_1);
            }
            ps = new PlaySound(0, this, 0, "itemsound.ship_arrival_departure");
            if (knownPlayers == null || knownPlayers.isEmpty())
                return;
            for (L2Player player : knownPlayers) {
                player.sendPacket(sm);
                player.sendPacket(ps);
                player.sendPacket(new VehicleStarted(this, 0));
                if (sm2 != null)
                    player.sendPacket(sm2);
            }
            break;
        case 5:
            if (_cycle == 1) {
                sm = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t1.npc1, _t1.sysmess5_1);
            } else {
                sm = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t2.npc1, _t2.sysmess5_1);
            }
            ps = new PlaySound(0, this, 0, "itemsound.ship_5min");
            if (knownPlayers == null || knownPlayers.isEmpty())
                return;
            for (L2Player player : knownPlayers) {
                player.sendPacket(sm);
                player.sendPacket(ps);
            }
            break;
        case 1:
            if (_cycle == 1) {
                sm = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t1.npc1, _t1.sysmess1_1);
            } else {
                sm = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t2.npc1, _t2.sysmess1_1);
            }
            ps = new PlaySound(0, this, 0, "itemsound.ship_1min");
            if (knownPlayers == null || knownPlayers.isEmpty())
                return;
            for (L2Player player : knownPlayers) {
                player.sendPacket(sm);
                player.sendPacket(ps);
            }
            break;
        case 0:
            if (_cycle == 1) {
                sm = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t1.npc1, _t1.sysmess0_1);
            } else {
                sm = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t2.npc1, _t2.sysmess0_1);
            }
            if (knownPlayers == null || knownPlayers.isEmpty())
                return;
            for (L2Player player : knownPlayers) {
                player.sendPacket(sm);
                // player.sendPacket(ps);
            }
            break;
        case -1:
            if (_cycle == 1) {
                sm = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t1.npc1, _t1.sysmessb_1);
            } else {
                sm = new CreatureSay(0, SystemChatChannelId.Chat_Shout, _t2.npc1, _t2.sysmessb_1);
            }
            ps = new PlaySound(0, this, 0, "itemsound.ship_arrival_departure");
            for (L2Player player : knownPlayers) {
                player.sendPacket(sm);
                player.sendPacket(ps);
            }
            break;
        }
    }

    /**
     *
     */
    public void spawn() {
        Collection<L2Player> knownPlayers = getKnownList().getKnownPlayers().values();
        _cycle = 1;
        beginCycle();
        if (knownPlayers == null || knownPlayers.isEmpty())
            return;
        VehicleInfo vi = new VehicleInfo(this);
        for (L2Player player : knownPlayers)
            player.sendPacket(vi);
    }

    /**
     * @param idWaypoint1
     * @param idWTicket1
     * @param ntx1
     * @param nty1
     * @param ntz1
     * @param idnpc1
     * @param sysmess10_1
     * @param sysmess5_1
     * @param sysmess1_1
     * @param sysmessb_1
     */
    public void setTrajet1(int idWaypoint1, int idWTicket1, int ntx1, int nty1, int ntz1, String idnpc1,
            String sysmess10_1, String sysmess5_1, String sysmess1_1, String sysmess0_1, String sysmessb_1) {
        _t1 = new L2BoatTrajet(idWaypoint1, idWTicket1, ntx1, nty1, ntz1, idnpc1, sysmess10_1, sysmess5_1,
                sysmess1_1, sysmess0_1, sysmessb_1, _name);
    }

    public void setTrajet2(int idWaypoint1, int idWTicket1, int ntx1, int nty1, int ntz1, String idnpc1,
            String sysmess10_1, String sysmess5_1, String sysmess1_1, String sysmess0_1, String sysmessb_1) {
        _t2 = new L2BoatTrajet(idWaypoint1, idWTicket1, ntx1, nty1, ntz1, idnpc1, sysmess10_1, sysmess5_1,
                sysmess1_1, sysmess0_1, sysmessb_1, _name);
    }

    /*
     * (non-Javadoc)
     *
     * @see com.l2jfree.gameserver.gameobjects.L2Creature#getLevel()
     */
    @Override
    public int getLevel() {
        // TODO Auto-generated method stub
        return 0;
    }

    /*
     * Allow setup of the boat AI only once
     */
    @Override
    protected boolean canReplaceAI() {
        return false;
    }

    @Override
    protected L2CreatureAI initAI() {
        return new L2CreatureAI(new AIAccessor());
    }

    /*
     * boat AI can't be detached
     */
    public class AIAccessor extends L2Creature.AIAccessor {
        /*@Override
        public void detachAI()
        {
        }*/
    }

    /**
     * @param id
     */
    public void setId(int id) {
        _id = id;
    }

    @Override
    public void sendInfo(L2Player activeChar) {
        if (!activeChar.isInBoat()) {
            if (this != activeChar.getBoat()) {
                activeChar.sendPacket(new VehicleInfo(this));
                sendVehicleDeparture(activeChar);
            }
        }
    }

    @Override
    public void broadcastFullInfoImpl() {
    }
}