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

Java tutorial

Introduction

Here is the source code for com.l2jfree.gameserver.gameobjects.instance.L2AirShipInstance.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.FastList;
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.AirShipKnownList;
import com.l2jfree.gameserver.gameobjects.knownlist.CreatureKnownList;
import com.l2jfree.gameserver.gameobjects.templates.L2CreatureTemplate;
import com.l2jfree.gameserver.instancemanager.AirShipManager;
import com.l2jfree.gameserver.instancemanager.GameTimeManager;
import com.l2jfree.gameserver.model.items.L2ItemInstance;
import com.l2jfree.gameserver.model.items.templates.L2Weapon;
import com.l2jfree.gameserver.network.packets.server.ExAirShipInfo;
import com.l2jfree.gameserver.network.packets.server.ExGetOffAirShip;
import com.l2jfree.gameserver.network.packets.server.ExGetOnAirShip;
import com.l2jfree.gameserver.network.packets.server.ExMoveToLocationAirShip;
import com.l2jfree.gameserver.network.packets.server.ExStopMoveAirShip;
import com.l2jfree.gameserver.taskmanager.MovementController;

/**
 * Flying airships. Very similar to Maktakien boats (see L2BoatInstance) but these do fly :P
 *
 * @author  DrHouse
 */
public final class L2AirShipInstance extends L2Creature {
    public float boatSpeed;
    protected final FastList<L2Player> _passengers = new FastList<L2Player>();

    private class L2AirShipTrajet {
        private Map<Integer, L2AirShipPoint> _path;
        public int idWaypoint;
        public int max;

        protected class L2AirShipPoint {
            public int speed1 = 350;
            //         public int speed2 = 4000;
            public int x;
            public int y;
            public int z;
            public int time;
        }

        /**
         * @param idWaypoint
            
         */
        public L2AirShipTrajet(int pIdWaypoint) {
            idWaypoint = pIdWaypoint;
            loadBoatPath();
        }

        /**
         * @param line
         * @return
         */
        public void parseLine(String line) {
            _path = new FastMap<Integer, L2AirShipPoint>();
            StringTokenizer st = new StringTokenizer(line, ";");
            Integer.parseInt(st.nextToken());
            max = Integer.parseInt(st.nextToken());
            for (int i = 0; i < max; i++) {
                L2AirShipPoint bp = new L2AirShipPoint();
                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/airshippath.csv");
                lnr = new LineNumberReader(new BufferedReader(new FileReader(doorData)));

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

        /**
         * @param state
         * @return
         */
        public int state(int state, L2AirShipInstance _boat) {
            if (state < max) {
                L2AirShipPoint bp = _path.get(state);

                _boat._easi = new ExMoveToLocationAirShip(L2AirShipInstance.this, bp.x, bp.y, bp.z);
                // _boat.getTemplate().baseRunSpd = bp.speed1;
                boatSpeed = bp.speed1;
                _boat.moveAirShipToLocation(bp.x, bp.y, bp.z, bp.speed1);
                Collection<L2Player> knownPlayers = _boat.getKnownList().getKnownPlayers().values();
                if (bp.time == 0) {
                    bp.time = 1;
                }
                if (knownPlayers == null || knownPlayers.isEmpty())
                    return bp.time;
                //synchronized (_boat.getKnownList().getKnownPlayers())
                {
                    for (L2Player player : knownPlayers) {
                        player.sendPacket(_boat._easi);
                    }
                }
                return bp.time;
            } else {
                return 0;
            }
        }

    }

    protected L2AirShipTrajet _t1;
    protected L2AirShipTrajet _t2;
    protected L2AirShipTrajet _t3;
    protected L2AirShipTrajet _t4;
    protected int _cycle = 0;
    protected int _runstate = 0;
    protected ExMoveToLocationAirShip _easi = null;

    public L2AirShipInstance(int objectId, L2CreatureTemplate template) {
        super(objectId, template);
        getKnownList();
        getAI();
    }

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

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

    /**
     * @param x
     * @param y
     * @param z
     */
    public void moveAirShipToLocation(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();

        // Caclulate 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;

        // Add the L2Creature to movingObjects of the GameTimeController
        // The GameTimeController manage objects movement
        MovementController.getInstance().add(this, ticksToMove);
    }

    class AirShipCaptain implements Runnable {
        private final L2AirShipInstance _airShip;

        /**
         * @param i
         * @param instance
         */
        public AirShipCaptain(L2AirShipInstance instance) {
            _airShip = instance;
        }

        @Override
        public void run() {
            _airShip.begin();
        }
    }

    class AirShiprun implements Runnable {
        private int _state;

        private final L2AirShipInstance _airShip;

        /**
         * @param i
         * @param instance
         */
        public AirShiprun(int i, L2AirShipInstance instance) {
            _state = i;
            _airShip = instance;
        }

        @Override
        public void run() {
            _airShip._easi = null;
            if (_airShip._cycle == 1) {
                int time = _airShip._t1.state(_state, _airShip);
                if (time == 0) {
                    _airShip._cycle = 2;
                    teleportAirShip(-167874, 256731, -509, 41035);
                    AirShiprun asr = new AirShiprun(0, _airShip);
                    ThreadPoolManager.getInstance().scheduleGeneral(asr, 5000);
                } else
                    _state++;
            } else if (_airShip._cycle == 2) {
                int time = _airShip._t2.state(_state, _airShip);
                if (time == 0) {
                    setIsInDock(true);
                    for (L2Player player : _passengers) {
                        if (player == null)
                            continue;
                        oustPlayer(player);
                    }
                    airShipControllerShout(32607, true);
                    AirShipCaptain asc = new AirShipCaptain(_airShip);
                    ThreadPoolManager.getInstance().scheduleGeneral(asc, 60000);
                } else
                    _state++;
            } else if (_airShip._cycle == 3) {
                int time = _airShip._t3.state(_state, _airShip);
                if (time == 0) {
                    _airShip._cycle = 4;
                    teleportAirShip(-157261, 255664, 221, 64781);
                    AirShiprun asr = new AirShiprun(0, _airShip);
                    ThreadPoolManager.getInstance().scheduleGeneral(asr, 5000);

                } else
                    _state++;
            } else if (_airShip._cycle == 4) {
                int time = _airShip._t4.state(_state, _airShip);
                if (time == 0) {
                    setIsInDock(true);
                    for (L2Player player : _passengers) {
                        if (player == null)
                            continue;
                        oustPlayer(player);
                    }
                    airShipControllerShout(32609, true);
                    AirShipCaptain asc = new AirShipCaptain(_airShip);
                    ThreadPoolManager.getInstance().scheduleGeneral(asc, 60000);
                } else
                    _state++;
            }
            _airShip._runstate = _state;
        }
    }

    /**
     * 
     */
    public void evtArrived() {
        if (_runstate != 0) {
            AirShiprun asr = new AirShiprun(_runstate, this);
            ThreadPoolManager.getInstance().executeTask(asr);
        }
    }

    public void airShipControllerShout(int npcId, boolean isArraived) {
        String message = "";
        switch (npcId) {
        case 32607:
            if (isArraived)
                message = "The regurarly scheduled airship has arrived. It will depart for the Aden continent in 1 minute. ";
            else
                message = "The regurarly scheduled airship that flies to the Aden continent has departed.";
            break;
        case 32609:
            if (isArraived)
                message = "The regurarly scheduled airship has arrived. It will depart for the Gracia continent in 1 minute. ";
            else
                message = "The regurarly scheduled airship that flies to the Gracia continent has departed.";
            break;
        default:
            _log.warn("Invalid AirShipController npcId: " + npcId);
            return;
        }
        for (L2AirShipControllerInstance asci : AirShipManager.getInstance().getATCs())
            if (asci != null && asci.getNpcId() == npcId) {
                asci.setIsBoardAllowed(isArraived);
                asci.broadcastMessage(message);
            }
    }

    public ExMoveToLocationAirShip getAirShipInfo() {
        return _easi;
    }

    public void beginCycle() {
        AirShipCaptain asc = new AirShipCaptain(this);
        ThreadPoolManager.getInstance().scheduleGeneral(asc, 60000);
    }

    /**
     * @param destination
     * @param destination2
     * @param destination3
     */
    private int lastx = -1;
    private int lasty = -1;
    private boolean _isInDock = true;

    public void updatePeopleInTheAirShip(int x, int y, int z) {
        if ((lastx == -1) || (lasty == -1)) {
            lastx = x;
            lasty = y;
        } else if ((x - lastx) * (x - lastx) + (y - lasty) * (y - lasty) > 2250000) // 1500 * 1500 =  2250000
        {
            lastx = x;
            lasty = y;
        }
        for (L2Player player : _passengers) {
            if (player != null && player.isInAirShip()) {
                if (player.getAirShip() == this) {
                    // player.getKnownList().addKnownObject(this);
                    player.getPosition().setXYZ(x, y, z);
                    player.revalidateZone(false);
                }
            }
        }
    }

    /**
     * @param i
     */
    public void begin() {
        _cycle++;
        if (_cycle == 1 || _cycle == 5) {
            _cycle = 1;
            setIsInDock(false);
            airShipControllerShout(32609, false);
            AirShiprun asr = new AirShiprun(0, this);
            ThreadPoolManager.getInstance().executeTask(asr);
        } else if (_cycle == 3) {
            setIsInDock(false);
            airShipControllerShout(32607, false);
            AirShiprun asr = new AirShiprun(0, this);
            ThreadPoolManager.getInstance().executeTask(asr);
        }
    }

    public void spawn() {
        Collection<L2Player> knownPlayers = getKnownList().getKnownPlayers().values();
        _cycle = 0;
        beginCycle();
        if (knownPlayers == null || knownPlayers.isEmpty())
            return;
        ExAirShipInfo easi = new ExAirShipInfo(this);
        for (L2Player player : knownPlayers)
            player.sendPacket(easi);
    }

    /**
     * @param idWaypoint1
     */
    public void setTrajet1(int idWaypoint1) {
        _t1 = new L2AirShipTrajet(idWaypoint1);
    }

    public void setTrajet2(int idWaypoint2) {
        _t2 = new L2AirShipTrajet(idWaypoint2);
    }

    public void setTrajet3(int idWaypoint3) {
        _t3 = new L2AirShipTrajet(idWaypoint3);
    }

    public void setTrajet4(int idWaypoint4) {
        _t4 = new L2AirShipTrajet(idWaypoint4);
    }

    public void setIsInDock(boolean val) {
        _isInDock = val;
    }

    public boolean isInDock() {
        return _isInDock;
    }

    public void onPlayerBoarding(L2Player player) {
        // cannot board
        if (!isInDock() || _passengers.contains(player))
            return;

        _passengers.add(player);
        player.setAirShip(this);
        player.broadcastPacket(new ExGetOnAirShip(player, this));
        //player.sendPacket(new ExSetCompassZoneCode(ExSetCompassZoneCode.GENERALZONE));
    }

    public void oustPlayer(L2Player player) {
        int x, y, z;
        if (_cycle == 1 || _cycle == 4) {
            x = -149379;
            y = 255246;
            z = -80;
        } else {
            x = -186563;
            y = 243590;
            z = 2608;
        }
        _passengers.remove(player);
        player.broadcastPacket(new ExGetOffAirShip(player, this, x, y, z));
        player.setAirShip(null);
    }

    public void teleportAirShip(int x, int y, int z, int heading) {
        teleToLocation(x, y, z, heading, false);
        for (L2Player player : _passengers) {
            if (player == null)
                continue;
            player.sendPacket(new ExStopMoveAirShip(this));
            player.teleToLocation(x, y, z, heading, false);
            player.sendPacket(new ExAirShipInfo(this));
        }
    }

    @Override
    public L2ItemInstance getActiveWeaponInstance() {
        return null;
    }

    @Override
    public L2Weapon getActiveWeaponItem() {
        return null;
    }

    @Override
    public L2ItemInstance getSecondaryWeaponInstance() {
        return null;
    }

    @Override
    public L2Weapon getSecondaryWeaponItem() {
        return null;
    }

    @Override
    public int getLevel() {
        return 0;
    }

    @Override
    public boolean isAutoAttackable(L2Creature attacker) {
        return false;
    }

    @Override
    protected boolean canReplaceAI() {
        return false;
    }

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

    public class AIAccessor extends L2Creature.AIAccessor {
        /*@Override
        public void detachAI()
        {
        }*/
    }

    public int getSpeed1() {
        return 300;
    }

    public int getSpeed2() {
        return 4000;
    }

    @Override
    public void sendInfo(L2Player activeChar) {
        if (this != activeChar.getAirShip()) {
            activeChar.sendPacket(new ExAirShipInfo(this));
        }
    }

    @Override
    public void broadcastFullInfoImpl() {
        // TODO Auto-generated method stub

    }
}