Thread: NPC dies, and nobody can login any more / account already logged in bug

Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 26
  1. #11  
    Donator

    Jason's Avatar
    Join Date
    Aug 2009
    Posts
    6,092
    Thanks given
    2,402
    Thanks received
    2,823
    Rep Power
    4550
    provide any and all code that is referenced when the dog dies.
    Reply With Quote  
     

  2. #12  
    Banned
    Join Date
    Oct 2017
    Posts
    31
    Thanks given
    3
    Thanks received
    1
    Rep Power
    0
    Quote Originally Posted by Jason View Post
    provide any and all code that is referenced when the dog dies.
    I know from printing shit out that the Player constructor is called for some reason, which is being triggered by "player.getLogin().handleLogin(player, player.getInData());" if I remember correctly. And that is called from handleIncomingData, which is called by run() in DedicatedReactor and also by cycle() in Server.

    Npc:

    Code:
     package com.asgarniars.rs2.model.npcs;
    
    import com.asgarniars.rs2.content.combat.Combat;
    import com.asgarniars.rs2.content.skills.Skill;
    import com.asgarniars.rs2.model.Entity;
    import com.asgarniars.rs2.model.Position;
    import com.asgarniars.rs2.model.World;
    import com.asgarniars.rs2.task.impl.DeathTask;
    import com.asgarniars.rs2.util.Misc;
    import com.asgarniars.rs2.util.clip.PathFinder;
    
    /**
     * A non-player-character.
     * 
     * // Timers: Hidden = how long does it to perform actions such as drop loot //
     * Respawn = how long does it take to respawn this npc again to its //
     * spawnPosition
     */
    public class Npc extends Entity
    {
    
        private NpcDefinition definition;
    
        // These are used for npc spawn loader
    
        private int npcId;
        // Most top right coord -- If WalkType is WALK
        private Position maxWalk;
        // The spawn pos -- Most bottom left coord, if you're using WalkType Walk
        // and setting maxium walking area to most top right pos.
        private Position spawnPosition;
        // The face direction upon spawning --- if WalkType is STAND -- 0 North, 1
        // East, 2 South, 3 West
        private int faceType;
    
        // The walking type, is the npc allowed to walk?
        private WalkType walkType = WalkType.STAND;
    
        /**
         * Create a new Npc
         */
        public Npc(int npcId)
        {
    
            // -- Grab the npc definition via NPC_ID and initialize the attributes
            this.definition = NpcLoader.getDefinition(npcId);
            initAttributes();
    
            this.npcId = npcId;
    
            // -- Update the appareance
            getUpdateFlags().setUpdateRequired(true);
    
            // -- Set the npc's hp
            setAttribute("current_hp", getDefinition().getCombatLevel(3));
        }
    
        /**
         * Call this after World.register(npc)
         */
        public void actions_after_spawn()
        {
            // Facing.
            if (walkType == WalkType.STAND)
                getUpdateFlags().sendFaceToDirection(new Position(getSpawnPosition().getX() + (faceType == 1 ? 1 : (faceType == 3 ? -1 : 0)), getSpawnPosition().getY() + (faceType == 0 ? 1 : (faceType == 2 ? -1 : 0))));
        }
    
        @Override
        public void initAttributes()
        {
        }
    
        @Override
        public void process()
        {
    
            if (getWalkType() == WalkType.WALK && getAttribute("IS_BUSY") == null)
            {
                if (Misc.random(10) == 0)
                {
                    int x = spawnPosition.getX() + Misc.random(1 + maxWalk.getX());
                    int y = spawnPosition.getY() + Misc.random(1 + maxWalk.getY());
                    PathFinder.getSingleton().findRoute(this, x, y, true, 1, 1);
                }
            }
    
            getMovementHandler().process();
            Combat.getInstance().combatTick(this);
        }
    
        @Override
        public void reset()
        {
            getUpdateFlags().reset();
            removeAttribute("transform_update");
            removeAttribute("primary_dir");
        }
    
        @Override
        public void hit(int damage, int hitType, boolean isSpecial)
        {
    
            if (getAttribute("isDead") != null && !isSpecial)
                return;
    
            if (damage > (Integer) getAttribute("current_hp"))
                damage = (Integer) getAttribute("current_hp");
    
            setAttribute("current_hp", ((Integer) getAttribute("current_hp") - damage));
    
            if (!getUpdateFlags().isHitUpdate())
            {
                getUpdateFlags().setDamage(damage);
                getUpdateFlags().setHitType(hitType);
                getUpdateFlags().setHitUpdate(true);
            }
            else
            {
                getUpdateFlags().setDamage2(damage);
                getUpdateFlags().setHitType2(hitType);
                getUpdateFlags().setHitUpdate2(true);
            }
    
            setHitType(hitType);
    
            if (getAttribute("isDead") == null && (Integer) getAttribute("current_hp") <= 0)
            {
                setAttribute("isDead", (byte) 0);
                World.submit(new DeathTask(this));
            }
        }
    
        public void sendTransform(int transformId)
        {
            // -- Flag the update
            setAttribute("transform_update", 0);
            setAttribute("transform_id", transformId);
            setNpcId(transformId);
            getUpdateFlags().setUpdateRequired(true);
        }
    
        public Position getMaxWalkingArea()
        {
            return maxWalk;
        }
    
        public void setMaxWalkingArea(Position maxWalk)
        {
            this.maxWalk = maxWalk;
        }
    
        public WalkType getWalkType()
        {
            return walkType;
        }
    
        public void setWalkType(WalkType walkType)
        {
            this.walkType = walkType;
        }
    
        public NpcDefinition getDefinition()
        {
            return definition;
        }
    
        public void setSpawnPosition(Position pos)
        {
            this.spawnPosition = pos;
            this.getPosition().setAs(pos);
        }
    
        public Position getSpawnPosition()
        {
            return spawnPosition;
        }
    
        public enum WalkType
        {
            STAND, WALK
        }
    
        public void setNpcId(int npcId)
        {
            this.npcId = npcId;
        }
    
        public int getNpcId()
        {
            return npcId;
        }
    
        public void setFaceType(int faceType)
        {
            this.faceType = faceType;
        }
    
        public int getFacingDirection()
        {
            return faceType;
        }
    
        @Override
        public Skill getSkill()
        {
            return null;
        }
    }
    DeathTask:

    Code:
    package com.asgarniars.rs2.task.impl;
    
    import com.asgarniars.rs2.content.combat.util.Prayer;
    import com.asgarniars.rs2.listeners.impl.DefaultDeathSituation;
    import com.asgarniars.rs2.model.Entity;
    import com.asgarniars.rs2.model.npcs.Npc;
    import com.asgarniars.rs2.model.players.Player;
    import com.asgarniars.rs2.task.Task;
    
    public class DeathTask extends Task
    {
    
        /**
         * The entity who get's killed.
         */
        public Entity entity;
    
        private byte applyDeathTimer = 6;
    
        /**
         * Creates the event to cycle every cycle.
         */
        public DeathTask(Entity entity)
        {
            super(true);
            this.entity = entity;
        }
    
        @Override
        protected void execute()
        {
            // <AkZu> I clear this at dead method so we can process alot of stuff
            // with this as combating entity is set to null after a while
            // of not in combat
    
            if (applyDeathTimer == 6)
            {
                if (entity.getCombatingEntity() != null)
                    entity.getCombatingEntity().setCombatTimer(0);
                entity.setAttribute("combat_opponent", entity.getCombatingEntity());
                entity.getUpdateFlags().faceEntity(65535);
            }
    
            if (applyDeathTimer > -1)
                applyDeathTimer--;
    
            if (applyDeathTimer == 3)
            {
                entity.getUpdateFlags().sendAnimation(entity.isPlayer() ? 836 : ((Npc) entity).getDefinition().getDeathAnimation(), entity.isNpc() ? ((Npc) entity).getDefinition().getDeathAnimDelay() : 0);
            }
            else if (applyDeathTimer == 1)
            {
                if (entity.isPlayer())
                    Prayer.getInstance().applyRetributionPrayer(((Player) entity));
            }
            else if (applyDeathTimer == 0)
            {
                new DefaultDeathSituation(entity).die();
                this.stop();
            }
        }
    }
    DefaultDeathSituation:

    Code:
    package com.asgarniars.rs2.listeners.impl;
    
    import com.asgarniars.rs2.Constants;
    import com.asgarniars.rs2.content.minigame.ItemSafety;
    import com.asgarniars.rs2.model.Entity;
    import com.asgarniars.rs2.model.Position;
    import com.asgarniars.rs2.model.players.Player;
    
    /**
     * This is your default death situation, determining what occurs when you die
     * normally.
     * 
     * @author Joshua Barry
     * 
     */
    public class DefaultDeathSituation extends DeathSituation
    {
    
        private Entity entity;
    
        public DefaultDeathSituation(Entity entity)
        {
            this.entity = entity;
        }
    
        @Override
        protected Entity getEntity()
        {
            return entity;
        }
    
        @Override
        protected Object[] getRespawnPosition()
        {
            // -- Use minigame specific
            if (((Player) entity).getMinigame() != null)
            {
                return new Object[]
                { ((Player) entity).getMinigame().getEndPosition()[0], ((Player) entity).getMinigame().getEndPosition()[1], ((Player) entity).getMinigame().getEndPosition()[2], ((Player) entity).getMinigame().getEndPosition()[3] };
            }
            else
                return new Object[]
                { new Position(Constants.START_X, Constants.START_Y, Constants.START_Z), 0, 2, 2 };
        }
    
        @Override
        protected ItemSafety getItemSafety()
        {
            return (entity.isPlayer() && ((Player) entity).getMinigame() != null ? ((Player) entity).getMinigame().getItemSafety() : ItemSafety.UNSAFE);
        }
    
        @Override
        protected String getDeadMessage()
        {
            return (entity.isPlayer() && ((Player) entity).getMinigame() != null && ((Player) entity).getMinigame().getDeadMessage() != null ? (((Player) entity).getMinigame().getDeadMessage()) : "Oh dear, you have died!");
        }
    
    }
    DeathSituation:

    Code:
    package com.asgarniars.rs2.listeners.impl;
    
    import com.asgarniars.rs2.Constants;
    import com.asgarniars.rs2.content.combat.Combat;
    import com.asgarniars.rs2.content.combat.util.Poison;
    import com.asgarniars.rs2.content.combat.util.Prayer;
    import com.asgarniars.rs2.content.minigame.ItemSafety;
    import com.asgarniars.rs2.listeners.DeathListener;
    import com.asgarniars.rs2.model.Entity;
    import com.asgarniars.rs2.model.Position;
    import com.asgarniars.rs2.model.World;
    import com.asgarniars.rs2.model.items.ItemManager;
    import com.asgarniars.rs2.model.npcs.Npc;
    import com.asgarniars.rs2.model.npcs.Npc.WalkType;
    import com.asgarniars.rs2.model.npcs.NpcLoot;
    import com.asgarniars.rs2.model.players.Player;
    import com.asgarniars.rs2.task.Task;
    import com.asgarniars.rs2.util.Misc;
    
    /**
     * This is a skeletal death situation, it is the back bone to all other death
     * situations, taking the combined data and producing the result.
     * 
     * @author Joshua Barry
     * 
     */
    public abstract class DeathSituation implements DeathListener
    {
    
        protected abstract Entity getEntity();
    
        protected abstract Object[] getRespawnPosition();
    
        protected abstract String getDeadMessage();
    
        protected abstract ItemSafety getItemSafety();
    
        @Override
        public void die()
        {
    
            // -- The killer who killed this entity.
            final Entity killer = getEntity().getAttribute("combat_opponent");
    
            // -- TODO: Npcs death.....
            if (getEntity().isNpc())
            {
    
                final Npc npc = (Npc) getEntity();
    
                // Wait untill hidden timer is complete
                World.submit(new Task(npc.getDefinition().getHiddenTimer())
                {
                    @Override
                    protected void execute()
                    {
    
                        // -- Drop the loot..
                        if (killer != null && killer.isPlayer())
                        {
    
                            // -- First remove the invalid entries from players who
                            // has hit
                            // this npc, so only latest hits with most damage
                            // dealt will
                            // get loot.
                            npc.getCombatState().getDamageMap().removeInvalidEntries();
    
                            final Player looter = (Player) ((npc.getCombatState().getDamageMap().highestDamage() != null) ? npc.getCombatState().getDamageMap().highestDamage() : null);
    
                            if (looter != null)
                            {
                                final NpcLoot constantDrops = npc.getDefinition().getConstantDrops();
                                final NpcLoot[] randomDrops = npc.getDefinition().getRandomDrops();
                                final Position loot_position = new Position(npc.getPosition().getX(), npc.getPosition().getY(), npc.getPosition().getZ());
    
                                // -- Drop the items that should always be dropped
                                if (constantDrops != null)
                                {
                                    World.submit(new Task(1)
                                    {
                                        @Override
                                        protected void execute()
                                        {
                                            for (int i = 0; i < constantDrops.getItems().length; i++)
                                                ItemManager.getInstance().createGroundItem(looter, looter.getUsername(), constantDrops.getItems()[i], loot_position, Constants.GROUND_START_TIME_DROP);
                                            this.stop();
                                        }
                                    });
                                }
    
                                // -- Drop item(s) randomly from the drop table..
                                if (randomDrops != null)
                                {
                                    if (randomDrops.length > 0)
                                    {
                                        NpcLoot drop = null;
    
                                        while (drop == null)
                                        {
                                            NpcLoot randomDrop = randomDrops[Misc.random.nextInt(randomDrops.length)];
                                            if (Misc.random.nextDouble() < randomDrop.getFrequency())
                                                drop = randomDrop;
                                        }
    
                                        final NpcLoot final_drop = drop;
    
                                        World.submit(new Task(1)
                                        {
                                            @Override
                                            protected void execute()
                                            {
                                                for (int i = 0; i < final_drop.getItems().length; i++)
                                                    ItemManager.getInstance().createGroundItem(looter, looter.getUsername(), final_drop.getItems()[i], loot_position, Constants.GROUND_START_TIME_DROP);
                                                this.stop();
                                            }
                                        });
                                    }
                                }
                            }
                        }
    
                        // -- Npc doesn't respawn anymore --- kill it.
                        if (npc.getDefinition().getRespawnTimer() == 0)
                        {
                            World.unregister(npc);
                            return;
                        }
    
                        // -- Teleport the npc away from sight for a while << TODO:
                        // If
                        // re-spawnable
                        npc.teleport(new Position(0, 0, 0));
    
                        // Remove some more attributes
                        npc.getCombatState().getDamageMap().reset(); // Clear the
                                                                     // damage map.
                        npc.removeAttribute("isFrozen");
                        npc.removeAttribute("cantBeFrozen");
                        Poison.appendPoison(npc, false, 0);
                        npc.setCombatTimer(0);
                        npc.getUpdateFlags().sendAnimation(65535, 0);
                        npc.setCanWalk(true);
    
                        // -- Reset combat
                        Combat.getInstance().resetCombat(npc);
    
                        // Restore skills TODO
                        npc.setAttribute("current_hp", npc.getDefinition().getCombatLevel(3));
    
                        // Respawn the npc
                        World.submit(new Task(npc.getDefinition().getRespawnTimer())
                        {
                            @Override
                            protected void execute()
                            {
                                npc.removeAttribute("isDead");
    
                                if (npc.getWalkType() == WalkType.WALK)
                                    npc.clipTeleport(new Position(npc.getSpawnPosition().getX(), npc.getSpawnPosition().getY(), npc.getSpawnPosition().getZ()), 0, npc.getMaxWalkingArea().getX(), npc.getMaxWalkingArea().getY());
                                else
                                    npc.teleport(npc.getSpawnPosition());
    
                                // -- Finally...
                                npc.removeAttribute("combat_opponent");
                                npc.actions_after_spawn();
                                this.stop();
                            }
                        });
                        this.stop();
                    }
                });
            }
    
            // TODO: Players death...
            if (getEntity().isPlayer())
            {
    
                final Player player = (Player) getEntity();
    
                if (player.getMinigame() != null && killer != null && killer.isPlayer())
                    player.getMinigame().defeatListener(player, killer);
    
                // Send kill messages if you're not inside minigame
                if (player.getMinigame() == null && killer != null && killer.isPlayer())
                {
                    Player otherPlayer = (Player) killer;
    
                    String[] randomKillMessages =
                    { "You have defeated " + player.getUsername() + "!", player.getUsername() + " won't cross your path again!", "Good fight, " + player.getUsername() + ".", player.getUsername() + " will feel that in Lumbridge.", "Can anyone defeat you? Certainly not " + player.getUsername() + ".", player.getUsername() + " falls before your might.", "A humiliating defeat for " + player.getUsername() + ".", "You were clearly a better fighter than " + player.getUsername() + ".", player.getUsername() + " has won a free ticket to Lumbridge.", "It's all over for " + player.getUsername() + ".", "With a crushing blow you finish " + player.getUsername() + ".", player.getUsername() + " regrets the day they met you in combat.", player.getUsername() + " didn't stand a chance against you." };
    
                    otherPlayer.getActionSender().sendMessage(randomKillMessages[Misc.random(randomKillMessages.length)]);
                    Combat.getInstance().resetCombat(otherPlayer);
                }
    
                // Drop loot if it's allowed
                if (getItemSafety() == ItemSafety.UNSAFE)
                {
    
                    // -- First remove the invalid entries from players who has hit
                    // this player, so only latest hits with most damage dealt will
                    // get loot.
                    player.getCombatState().getDamageMap().removeInvalidEntries();
    
                    final Entity looter = (Entity) (player.getCombatState().getDamageMap().highestDamage() != null ? player.getCombatState().getDamageMap().highestDamage() : player);
    
                    player.dropLoot(looter.isNpc() ? null : ((Player) looter));
                }
    
                Combat.getInstance().fixAttackStyles(player, player.getEquipment().get(3));
                player.getActionSender().sendMessage(getDeadMessage());
                player.getCombatState().getDamageMap().reset(); // Clear the damage
                                                                // map.
                Combat.getInstance().resetCombat(player);
    
                player.setSpecialAttackActive(false);
                player.setSpecialAmount(10);
                player.setCombatTimer(0);
                player.setCanWalk(true);
                player.removeAttribute("isFrozen");
                player.removeAttribute("teleBlocked");
                player.removeAttribute("charge");
                player.removeAttribute("cant_teleport");
                player.removeAttribute("chargeCoolDown");
                player.setSkulled(false);
                Poison.appendPoison(player, false, 0);
                Prayer.getInstance().resetAll(player);
                player.getUpdateFlags().sendAnimation(65535, 0);
                player.getActionSender().sendWalkableInterface(-1);
                player.getSkill().normalize();
                player.removeAttribute("isDead");
    
                // -- Teleport the player
                player.clipTeleport((Position) getRespawnPosition()[0], (Integer) getRespawnPosition()[1], (Integer) getRespawnPosition()[2], (Integer) getRespawnPosition()[3]);
    
                // Null the player's minigame (if any) as he died!!
                if (player.getMinigame() != null && !player.getMinigame().getGameName().equals("Fight Pits"))
                    player.setMinigame(null);
    
                // Null the combating entity, that's used for death method thingies
                player.removeAttribute("combat_opponent");
            }
        }
    }
    PacketManager:

    Code:
    package com.asgarniars.rs2.network.packet;
    
    import java.io.IOException;
    import java.nio.channels.SelectionKey;
    import java.util.logging.Logger;
    
    import com.asgarniars.rs2.Constants;
    import com.asgarniars.rs2.model.players.Player;
    import com.asgarniars.rs2.model.players.Player.LoginStages;
    import com.asgarniars.rs2.network.DedicatedReactor;
    import com.asgarniars.rs2.network.packet.packets.*;
    
    public class PacketManager
    {
    
        public static final int SIZE = 256;
    
        private final static Logger logger = Logger.getLogger(PacketManager.class.getName());
        private static PacketHandler[] packets = new PacketHandler[SIZE];
    
        private static DefaultPacketHandler silent = new DefaultPacketHandler();
        private static WalkPacketHandler walking = new WalkPacketHandler();
        private static ObjectPacketHandler object = new ObjectPacketHandler();
        private static ItemPacketHandler item = new ItemPacketHandler();
        private static ChatInterfacePacketHandler chatInterface = new ChatInterfacePacketHandler();
        private static PrivateMessagingPacketHandler pm = new PrivateMessagingPacketHandler();
        private static NpcPacketHandler npc = new NpcPacketHandler();
        private static PlayerOptionPacketHandler playerOption = new PlayerOptionPacketHandler();
        private static MagicPacketHandler magic = new MagicPacketHandler();
    
        public static void loadPackets()
        {
            packets[WalkPacketHandler.MINI_MAP_WALK] = walking;
            packets[WalkPacketHandler.MAIN_WALK] = walking;
            packets[WalkPacketHandler.OTHER_WALK] = walking;
            packets[ObjectPacketHandler.ITEM_ON_OBJECT] = object;
            packets[ObjectPacketHandler.FIRST_CLICK] = object;
            packets[ObjectPacketHandler.SECOND_CLICK] = object;
            packets[ObjectPacketHandler.THIRD_CLICK] = object;
            packets[ItemPacketHandler.ITEM_OPERATE] = item;
            packets[ItemPacketHandler.DROP_ITEM] = item;
            packets[ItemPacketHandler.PICKUP_ITEM] = item;
            packets[ItemPacketHandler.HANDLE_OPTIONS] = item;
            packets[ItemPacketHandler.PACKET_145] = item;
            packets[ItemPacketHandler.PACKET_117] = item;
            packets[ItemPacketHandler.PACKET_43] = item;
            packets[ItemPacketHandler.PACKET_129] = item;
            packets[ItemPacketHandler.EQUIP_ITEM] = item;
            packets[ItemPacketHandler.USE_ITEM_ON_ITEM] = item;
            packets[ItemPacketHandler.FIRST_CLICK_ITEM] = item;
            packets[ItemPacketHandler.THIRD_CLICK_ITEM] = item;
            packets[LoadRegionPacketHandler.LOAD_REGION] = new LoadRegionPacketHandler();
            packets[AppearancePacketHandler.APPEARANCE] = new AppearancePacketHandler();
            packets[CommandPacketHandler.COMMAND] = new CommandPacketHandler();
            packets[IdleLogoutPacketHandler.IDLELOGOUT] = new IdleLogoutPacketHandler();
            packets[PrivateMessagingPacketHandler.ADD_FRIEND] = pm;
            packets[PrivateMessagingPacketHandler.REMOVE_FRIEND] = pm;
            packets[PrivateMessagingPacketHandler.ADD_IGNORE] = pm;
            packets[PrivateMessagingPacketHandler.REMOVE_IGNORE] = pm;
            packets[PrivateMessagingPacketHandler.SEND_PM] = pm;
            packets[NpcPacketHandler.FIRST_CLICK] = npc;
            packets[NpcPacketHandler.SECOND_CLICK] = npc;
            packets[NpcPacketHandler.ATTACK] = npc;
            packets[NpcPacketHandler.ITEM_ON_NPC] = npc;
            packets[ChatInterfacePacketHandler.DIALOGUE] = chatInterface;
            packets[ChatInterfacePacketHandler.SHOW_ENTER_X] = chatInterface;
            packets[ChatInterfacePacketHandler.ENTER_X] = chatInterface;
            packets[ButtonPacketHandler.BUTTON] = new ButtonPacketHandler();
            packets[ChatPacketHandler.CHAT] = new ChatPacketHandler();
            packets[PlayerOptionPacketHandler.SLOT_1] = playerOption;
            packets[PlayerOptionPacketHandler.SLOT_2] = playerOption;
            packets[PlayerOptionPacketHandler.SLOT_3] = playerOption;
            packets[PlayerOptionPacketHandler.SLOT_4] = playerOption;
            packets[PlayerOptionPacketHandler.SLOT_5] = playerOption;
            packets[PlayerOptionPacketHandler.USE_ITEM_ON_PLAYER] = playerOption;
    
            packets[MagicPacketHandler.MAGIC_ON_ITEM] = magic;
            packets[MagicPacketHandler.MAGIC_ON_NPC] = magic;
            packets[MagicPacketHandler.MAGIC_ON_PLAYER] = magic;
    
            packets[CloseInterfacePacketHandler.CLOSE_INTERFACE] = new CloseInterfacePacketHandler();
            packets[0] = silent;
            packets[241] = silent;
            packets[86] = silent;
            packets[3] = silent;
            packets[77] = silent;
            packets[210] = silent;
            packets[78] = silent;
            packets[226] = silent;
            int count = 0;
            for (int i = 0; i < packets.length; i++)
            {
                if (packets[i] != null)
                {
                    count++;
                }
            }
            logger.info("Loaded " + count + " packets.");
        }
    
        public static void handlePacket(Player player, Packet packet)
        {
            PacketHandler packetHandler = packets[packet.getOpcode()];
            if (packetHandler == null)
            {
                logger.info("Unhandled packet opcode = " + packet.getOpcode() + " length = " + packet.getPacketLength());
                return;
            }
            try
            {
                if (player.getAttribute("isDead") == null)
                    packetHandler.handlePacket(player, packet);
            }
            catch (Exception e)
            {
                e.printStackTrace();
                player.disconnect();
            }
        }
    
        public static final void flushOutBuffer(Player player)
        {
            try
            {
                synchronized (player.getOutData())
                {
                    player.getOutData().flip();
                    player.getSocketChannel().write(player.getOutData());
    
                    // Check if all the data was sent.
                    if (!player.getOutData().hasRemaining())
                    {
                        // Yep, remove write interest.
                        synchronized (DedicatedReactor.getInstance())
                        {
                            DedicatedReactor.getInstance().getSelector().wakeup();
                            player.getKey().interestOps(player.getKey().interestOps() & ~SelectionKey.OP_WRITE);
                        }
    
                        // And clear the buffer.
                        player.getOutData().clear();
                    }
                    else
                    {
                        // Not all data was sent - compact it!
                        player.getOutData().compact();
                    }
                }
            }
            catch (IOException ex)
            {
                player.disconnect();
            }
        }
    
        public static final void handleIncomingData(Player player)
        {
            try
            {
                // Read the incoming data.
                if (player.getInData() == null)
                {
                    return;
                }
                if (player.getLoginStage() != LoginStages.LOGGING_OUT && player.getSocketChannel().read(player.getInData()) == -1)
                {
                    System.out.println("Player " + player + " disconnected for having 'invalid' packet");
                    player.disconnect();
                    return;
                }
                // Handle the received data.
                player.getTimeoutStopwatch().reset();
                player.getInData().flip();
                int loops = 0;
                while (player.getInData().hasRemaining())
                {
                    // if logged out, don't read any data
                    if (player.getLoginStage() == LoginStages.LOGGING_OUT)
                        break;
    
                    if (loops++ >= 25)
                    {
                        System.out.println("Player " + player + " disconnected for spamming packets");
                        player.disconnect();
                        break;
                    }
    
                    // Handle login if we need to.
                    if (player.getLoginStage() != LoginStages.LOGGED_IN)
                    {
                        player.getLogin().handleLogin(player, player.getInData());
                        break;
                    }
    
                    // Decode the packet opcode.
                    if (player.getOpcode() == -1)
                    {
                        player.setOpcode(player.getInData().get() & 0xff);
                        player.setOpcode(player.getOpcode() - player.getDecryptor().getNextValue() & 0xff);
                    }
    
                    // Check the packets OP code that it's in valid range
                    if (player.getOpcode() < 0 || player.getOpcode() > 256)
                    {
                        player.disconnect();
                        return;
                    }
    
                    // Decode the packet length.
                    if (player.getPacketLength() == -1)
                    {
                        player.setPacketLength(Constants.PACKET_LENGTHS[player.getOpcode()]);
                        if (player.getPacketLength() == -1)
                        {
                            if (!player.getInData().hasRemaining())
                            {
                                player.getInData().compact();
                                return;
                            }
                            player.setPacketLength(player.getInData().get() & 0xff);
                        }
                    }
    
                    // Decode the packet payload.
                    if (player.getInData().remaining() >= player.getPacketLength())
                    {
                        int position = player.getInData().position();
                        player.handlePacket();
                        player.getInData().position(position + player.getPacketLength());
    
                        // Reset for the next packet.
                        player.setOpcode(-1);
                        player.setPacketLength(-1);
                    }
                    else
                    {
                        player.getInData().compact();
                        return;
                    }
                    if (!player.isLoggedIn())
                        break;
                }
    
                // Clear everything for the next read.
                player.getInData().clear();
            }
            catch (Exception ex)
            {
                // ex.printStackTrace();
                player.disconnect();
            }
        }
    
        public static void setPackets(PacketHandler[] packets)
        {
            PacketManager.packets = packets;
        }
    
        public static PacketHandler[] getPackets()
        {
            return packets;
        }
    
        public static void setWalking(WalkPacketHandler walking)
        {
            PacketManager.walking = walking;
        }
    
        public static WalkPacketHandler getWalking()
        {
            return walking;
        }
    
        public static void setItem(ItemPacketHandler item)
        {
            PacketManager.item = item;
        }
    
        public static ItemPacketHandler getItem()
        {
            return item;
        }
    
        public static void setChatInterface(ChatInterfacePacketHandler chatInterface)
        {
            PacketManager.chatInterface = chatInterface;
        }
    
        public static ChatInterfacePacketHandler getChatInterface()
        {
            return chatInterface;
        }
    
        public static void setPm(PrivateMessagingPacketHandler pm)
        {
            PacketManager.pm = pm;
        }
    
        public static PrivateMessagingPacketHandler getPm()
        {
            return pm;
        }
    
        public static void setNpc(NpcPacketHandler npc)
        {
            PacketManager.npc = npc;
        }
    
        public static NpcPacketHandler getNpc()
        {
            return npc;
        }
    
        public interface PacketHandler
        {
    
            public void handlePacket(Player player, Packet packet);
        }
    
    }
    Login:

    Code:
    package com.asgarniars.rs2.network;
    
    import java.math.BigInteger;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.security.SecureRandom;
    import java.util.logging.Logger;
    
    import com.asgarniars.rs2.Constants;
    import com.asgarniars.rs2.HostGateway;
    import com.asgarniars.rs2.Server;
    import com.asgarniars.rs2.model.players.Player;
    import com.asgarniars.rs2.model.players.Player.LoginStages;
    import com.asgarniars.rs2.util.Misc;
    import com.asgarniars.rs2.util.NameUtility;
    
    /**
     * 
     * @author Joshua Barry <Sneakyhearts>
     *
     */
    public class Login
    {
    
    	private static final BigInteger RSA_MODULUS = new BigInteger("removed");
    
    	private static final BigInteger RSA_EXPONENT = new BigInteger("removed");
    
        /* 337  VW GTI */
        private static final int UID = 337;
        
        public void handleLogin(Player player, ByteBuffer inData) throws Exception
        {
            switch (player.getLoginStage())
            {
            case CONNECTED:
                if (inData.remaining() < 2)
                {
                    inData.compact();
                    return;
                }
    
                // Validate the request.
                int request = inData.get() & 0xff;
                inData.get(); // Name hash.
                if (request != 14)
                {
                	System.out.println("Invalid login request: " + request);
                    Logger.getAnonymousLogger().severe("Invalid login request: " + request);
                    player.disconnect();
                    return;
                }
    
                // Write the response.
                StreamBuffer.OutBuffer out = StreamBuffer.newOutBuffer(17);
                out.writeLong(0); // First 8 bytes are ignored by the client.
    
                // -- Check if login attempts aren't full
                if (!HostGateway.attempt(player.getHost()))
                {
                    out.writeByte(Constants.LOGIN_RESPONSE_LOGIN_ATTEMPTS_EXCEEDED);
                    player.send(out.getBuffer());
                    player.disconnect();
                    break;
                }
    
                out.writeByte(0); // The response opcode, 0 for logging in.
                out.writeLong(new SecureRandom().nextLong()); // SSK.
                player.send(out.getBuffer());
    
                player.setLoginStage(LoginStages.LOGGING_IN);
                break;
            case LOGGING_IN:
                if (inData.remaining() < 2)
                {
                    inData.compact();
                    return;
                }
    
                // Validate the login type.
                int loginType = inData.get();
                if (loginType != 16 && loginType != 18)
                {
                	System.out.println("Invalid login type: " + loginType);
                    Logger.getAnonymousLogger().severe("Invalid login type: " + loginType);
                    player.disconnect();
                    return;
                }
    
                // Ensure that we can read all of the login block.
                int blockLength = inData.get() & 0xFF;
                int loginEncryptSize = blockLength - (36 + 1 + 1 + 2);
                if (loginEncryptSize <= 0)
                {
                    inData.flip();
                    inData.compact();
                    return;
                }
    
                // Read the login block.
                StreamBuffer.InBuffer in = StreamBuffer.newInBuffer(inData);
    
                /* The magic id (255) */
                int magicID = in.readByte(false);
                if (magicID != 255)
                {
                    player.disconnect();
                    return;
                }
    
                // Validate the client version.
                int clientVersion = in.readShort();
                if (clientVersion != 317)
                {
                	System.out.println("Invalid client version: " + clientVersion);
                    Logger.getAnonymousLogger().severe("Invalid client version: " + clientVersion);
                    player.disconnect();
                    return;
                }
    
                /* If the client is in low memory mode. */
                in.readByte();
    
                // Skip the CRC keys.
                for (int i = 0; i < 9; i++)
                {
                    in.readInt();
                }
    
                loginEncryptSize--;
                int reportedSize = inData.get() & 0xFF;
                if (reportedSize != loginEncryptSize)
                {
                	System.out.println("Encrypted packet size zero or negative : " + loginEncryptSize);
                    Logger.getAnonymousLogger().severe("Encrypted packet size zero or negative : " + loginEncryptSize);
                    player.disconnect();
                    return;
                }
                byte[] encryptionBytes = new byte[loginEncryptSize];
                inData.get(encryptionBytes);
                ByteBuffer rsaBuffer = ByteBuffer.wrap(new BigInteger(encryptionBytes).modPow(RSA_EXPONENT, RSA_MODULUS).toByteArray());
    
                // Validate that the RSA block was decoded properly.
                int rsaOpcode = rsaBuffer.get() & 0xFF;
                if (rsaOpcode != 10)
                {
                	System.out.println("Unable to decode RSA block properly!");
                    Logger.getAnonymousLogger().severe("Unable to decode RSA block properly!");
                    player.disconnect();
                    return;
                }
    
                // Set up the ISAAC ciphers.
                long clientHalf = rsaBuffer.getLong();
                long serverHalf = rsaBuffer.getLong();
                int[] isaacSeed =
                { (int) (clientHalf >> 32), (int) clientHalf, (int) (serverHalf >> 32), (int) serverHalf };
                player.setDecryptor(new ISAACCipher(isaacSeed));
                for (int i = 0; i < isaacSeed.length; i++)
                {
                    isaacSeed[i] += 50;
                }
                player.setEncryptor(new ISAACCipher(isaacSeed));
    
                /* The client unique ID. */
                int uniqueId = rsaBuffer.getInt();
                
                if (uniqueId != UID)
                {
                    player.disconnect();
                    return;
                }
    
                String username = NameUtility.getRS2String(rsaBuffer);
                String password = NameUtility.getRS2String(rsaBuffer);
    
                username = username.replaceAll("[^A-z 0-9]", " ").trim();
                password = password.replaceAll("[^A-z 0-9]", " ").trim();
    
                if (username.length() < 1 || password.length() < 4 || password.length() > 20 || username.length() > 12)
                {
                    player.setReturnCode(Constants.LOGIN_RESPONSE_INVALID_CREDENTIALS);
                    player.sendLoginResponse();
                    player.disconnect();
                    return;
                }
    
                player.setUsername(Misc.capitalize(username));
                player.setTempPassword(password);
                player.setUsernameAsLong(NameUtility.nameToLong(player.getUsername().toLowerCase()));
                player.setLoginStage(LoginStages.AWAITING_LOGIN_COMPLETE);
    
                if (player.beginLogin() && player.getLoginStage() == LoginStages.AWAITING_LOGIN_COMPLETE)
                {
                    // Switch the player to the cycled reactor.
                    synchronized (DedicatedReactor.getInstance())
                    {
                        DedicatedReactor.getInstance().getSelector().wakeup();
                        player.getKey().interestOps(player.getKey().interestOps() & ~SelectionKey.OP_READ);
                        player.getSocketChannel().register(Server.getSingleton().getSelector(), SelectionKey.OP_READ, player);
                    }
                }
                break;
            case AWAITING_LOGIN_COMPLETE:
                break;
            case LOGGED_IN:
                break;
            case LOGGED_OUT:
                break;
            case LOGGING_OUT:
                break;
            default:
                break;
            }
        }
    }
    Player:

    Code:
    package com.asgarniars.rs2.model.players;
    
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.SocketChannel;
    import java.util.ArrayDeque;
    import java.util.Deque;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Queue;
    import java.util.concurrent.ConcurrentLinkedQueue;
    import java.util.logging.Logger;
    
    import com.asgarniars.rs2.Constants;
    import com.asgarniars.rs2.HostGateway;
    import com.asgarniars.rs2.Server;
    import com.asgarniars.rs2.content.BankPin;
    import com.asgarniars.rs2.content.WelcomeScreen;
    import com.asgarniars.rs2.content.book.Book;
    import com.asgarniars.rs2.content.book.Page;
    import com.asgarniars.rs2.content.combat.Combat;
    import com.asgarniars.rs2.content.combat.magic.Magic;
    import com.asgarniars.rs2.content.combat.util.Poison;
    import com.asgarniars.rs2.content.combat.util.Prayer;
    import com.asgarniars.rs2.content.dialogue.Dialogue;
    import com.asgarniars.rs2.content.duel.DuelArena;
    import com.asgarniars.rs2.content.minigame.Minigame;
    import com.asgarniars.rs2.content.minigame.barrows.Brother;
    import com.asgarniars.rs2.content.minigame.impl.FightPits;
    import com.asgarniars.rs2.content.mta.AlchemistPlayground;
    import com.asgarniars.rs2.content.mta.Arena;
    import com.asgarniars.rs2.content.mta.EnchantmentChamber;
    import com.asgarniars.rs2.content.quest.Quest;
    import com.asgarniars.rs2.content.quest.QuestRepository;
    import com.asgarniars.rs2.content.quest.QuestStorage;
    import com.asgarniars.rs2.content.skills.Skill;
    import com.asgarniars.rs2.content.skills.magic.Teleother;
    import com.asgarniars.rs2.io.AccountManager;
    import com.asgarniars.rs2.model.Entity;
    import com.asgarniars.rs2.model.Position;
    import com.asgarniars.rs2.model.World;
    import com.asgarniars.rs2.model.area.Area;
    import com.asgarniars.rs2.model.area.Areas;
    import com.asgarniars.rs2.model.items.Item;
    import com.asgarniars.rs2.model.items.ItemManager;
    import com.asgarniars.rs2.model.npcs.Npc;
    import com.asgarniars.rs2.model.players.container.Container;
    import com.asgarniars.rs2.model.players.container.ContainerType;
    import com.asgarniars.rs2.network.ActionSender;
    import com.asgarniars.rs2.network.DedicatedReactor;
    import com.asgarniars.rs2.network.ISAACCipher;
    import com.asgarniars.rs2.network.Login;
    import com.asgarniars.rs2.network.StreamBuffer;
    import com.asgarniars.rs2.network.packet.Packet;
    import com.asgarniars.rs2.network.packet.PacketManager;
    import com.asgarniars.rs2.task.Task;
    import com.asgarniars.rs2.task.impl.DeathTask;
    import com.asgarniars.rs2.task.impl.RunRestore;
    import com.asgarniars.rs2.task.impl.SkillEquilizer;
    import com.asgarniars.rs2.task.impl.SkullTimerTask;
    import com.asgarniars.rs2.task.impl.SpecialRefillTask;
    import com.asgarniars.rs2.util.ScriptManager;
    import com.asgarniars.rs2.util.TimeUtility;
    import com.asgarniars.rs2.util.Misc.Stopwatch;
    import com.asgarniars.rs2.util.TraversableList;
    
    /**
     * Represents a logged-in player.
     * 
     * @author blakeman8192
     * @author BFMV
     * @author Joshua Barry <Sneakyhearts>
     */
    @SuppressWarnings("unused")
    public class Player extends Entity
    {
    
        /**
         * The logging utility for this class.
         */
        private static final Logger logger = Logger.getAnonymousLogger();
    
        private Book book;
    
        /* some 1337 code */
        private TraversableList<Page> pages;
    
        /**
         * The current opened dialogue.
         */
        private Dialogue currentDialogue = null;
    
        /**
         * The queue of dialogues that follow one another
         */
        private Deque<Dialogue> dialogues = new ArrayDeque<Dialogue>();
    
        /**
         * The walkToAction task.
         */
        private Task walkToAction;
    
        /**
         * The prayer draining task.
         */
        private Task prayerDrainTask;
    
        /**
         * The prayer draining task.
         */
        private Task skullTimerTask;
    
        /**
         * The special energy restore task.
         */
        private Task specialRefillTask;
    
        /**
         * The privileges/rights of this player.
         */
        private Rights rights;
    
        /**
         * The selection key created for this channel.
         */
        private final SelectionKey key;
    
        /**
         * The incoming packet data.
         */
        private final ByteBuffer inData;
    
        /**
         * The outgoing packet data
         */
        private final ByteBuffer outData;
    
        /**
         * The socket channel bound to this player's connection.
         */
        private SocketChannel socketChannel;
    
        /**
         * The ISAAC cipher for outgoing packets.
         */
        private ISAACCipher encryptor;
    
        /**
         * The ISAAC cipher for incoming packets.
         */
        private ISAACCipher decryptor;
    
        /**
         * The last received packet's opcode.
         */
        private short opcode = -1;
    
        /**
         * The last received packet's length.
         */
        private short packetLength = -1;
    
        private LoginStages loginStage = LoginStages.CONNECTED;
    
        /**
         * This player's username.
         */
        private String username;
    
        /**
         * This player's password.
         */
        private String password;
    
        /**
         * This player's temporary password, used for password changing.
         */
        private String tempPassword;
    
        /**
         * This player's host/address.
         */
        private String host;
    
        /**
         * The player's username as a 64-bit long.
         */
        private long usernameAsLong;
    
        private byte gender = 0;
        private final short[] appearance = new short[7];
        private final byte[] colors = new byte[5];
    
        private final Stopwatch timeoutStopwatch = new Stopwatch();
    
        private final Deque<Player> players = new ArrayDeque<Player>();
        private final Deque<Npc> npcs = new ArrayDeque<Npc>();
    
        // TODO make some of these with instances
        private Inventory inventory = new Inventory(this);
        private Equipment equipment = new Equipment(this);
        private PrivateMessaging privateMessaging = new PrivateMessaging(this);
        private Skill skill = new Skill(this);
        private ActionSender actionSender = new ActionSender(this);
        private TradeManager trading = new TradeManager();
        private BankPin bankPin = new BankPin(this);
        private Login login = new Login();
        private Minigame<Entity> minigame;
    
        private int chatColor;
        private byte[] chatText;
        private Container bank = new Container(ContainerType.ALWAYS_STACK, BankManager.SIZE);
        private Container trade = new Container(ContainerType.STANDARD, Inventory.SIZE);
        private Container duel_inventory = new Container(ContainerType.STANDARD, Inventory.SIZE);
        private short clickX;
        private short clickY;
        private short clickId;
        private short npcClickIndex;
        private short enterXId;
        private short enterXSlot;
        private short enterXInterfaceId;
        private short questPoints;
        private int shopId;
    
        private Map<Integer, Integer> bonuses = new HashMap<Integer, Integer>();
    
        private QuestStorage questStorage = new QuestStorage();
    
        private long[] friends = new long[200];
        private long[] ignores = new long[100];
    
        private int currentDialogueId;
        private int currentOptionId;
        private int optionClickId;
        private int currentGloryId;
    
        private int alchemyPizazz = 0;
        private int enchantPizazz = 0;
        private int gravePizazz = 0;
        private int telePizazz = 0;
    
        private byte returnCode = 2;
    
        private TradeStage tradeStage = TradeStage.WAITING;
        private TeleotherStage teleotherStage = TeleotherStage.WAITING;
    
        private boolean usingShop = false;
    
        /**
         * The flag indicating whether the player needs placement or not?
         */
        private boolean needsPlacement;
    
        /**
         * Whether to reset the movement queue or not.
         */
        private boolean resetMovementQueue;
    
        /**
         * Whether we need an appearance update for this player or not.
         */
        private boolean appearanceUpdateRequired;
    
        /**
         * The prayer icon's id.
         */
        private int prayerIcon = -1;
    
        /**
         * The skull icon's id.
         */
        private int skullIcon = -1;
    
        /**
         * The array that holds the data for whether a prayer is being used or not.
         */
        private boolean[] isUsingPrayer = new boolean[24];
    
        /**
         * The type of the currently opened spellbook.
         */
        private MagicBookTypes magicBookType = MagicBookTypes.MODERN;
    
        /**
         * The flag that determines whether the player automatically retaliates in
         * combat or not.
         */
        private boolean autoRetaliate = false;
    
        /**
         * The flag that determines whether the player has an overhead skull or not.
         */
        private boolean isSkulled = false;
    
        /**
         * The timer for player skulls.
         */
        private int skullTimer = 0;
    
        /**
         * Whether the special attack is active or not.
         */
        private boolean specialAttackActive = false;
    
        /**
         * The amount of special attack energy left.
         */
        private double specialAmount = 10.0;
    
        /**
         * Welcome screen stuff
         */
        private String lastLoginDay = "";
    
        /**
         * The last address this player connected from.
         */
        private String lastIp = "0.0.0.0";
    
        /**
         * PNPC
         */
        private int humanToNpc = -1;
    
        @Override
        public void reset()
        {
            getUpdateFlags().reset();
            removeAttribute("primary_dir");
            removeAttribute("secondary_dir");
            setAppearanceUpdateRequired(false);
            setResetMovementQueue(false);
            setNeedsPlacement(false);
        }
        
        public void resetCombatStuff() {
            getCombatState().getDamageMap().reset();
            Combat.getInstance().resetCombat(this);
            setSpecialAttackActive(false);
            setSpecialAmount(10);
            setCombatTimer(0);
            setCanWalk(true);
            removeAttribute("isFrozen");
            removeAttribute("teleBlocked");
            Poison.appendPoison(this, false, 0);
            Prayer.getInstance().resetAll(this);
            getUpdateFlags().sendAnimation(65535, 0);
            getSkill().normalize();
        }
    
        @Override
        public void initAttributes()
        {
            setAttribute("bonesCollected", 0);
    
            // -- Barrows attributes
            setAttribute("hidden_tomb", Brother.GUTHAN);
    
            // -- Dueling attributes
            setAttribute("duel_button_config", 0);
            setAttribute("duel_equipment_req_space", 0);
            setAttribute("duel_partner", -1);
            setAttribute("duel_stage", "WAITING");
    
            // -- Settings
            setAttribute("mouseButtons", (byte) 0);
            setAttribute("chatEffects", (byte) 0);
            setAttribute("splitPrivate", (byte) 1);
            setAttribute("acceptAid", (byte) 0);
    
            // -- Player variables
            setAttribute("runEnergy", (double) 100);
            setAttribute("canRestoreEnergy", (byte) 0);
            setAttribute("weight", 0.0);
    
            setAttribute("canCastMagicOnItems", true);
        }
    
        public Container[] getItemsKeptOnDeath()
        {
            int count = 3;
    
            if (getActivePrayers()[Prayer.PROTECT_ITEM])
                count++;
    
            if (isSkulled())
                count -= 3;
    
            Container topItems = new Container(ContainerType.NEVER_STACK, count);
            Container temporaryInventory = new Container(ContainerType.STANDARD, Inventory.SIZE);
            Container temporaryEquipment = new Container(ContainerType.STANDARD, Equipment.SIZE);
    
            // Add all of our items with their designated slots.
    
            for (byte i = 0; i < Inventory.SIZE; i++)
            {
                Item item = getInventory().get(i);
                if (item != null)
                    temporaryInventory.add(item);
            }
    
            for (byte i = 0; i < Equipment.SIZE; i++)
            {
                Item item = getEquipment().get(i);
                if (item != null)
                    temporaryEquipment.add(item);
            }
    
            /*
             * Checks our inventory and equipment for any items that can be added to
             * the top list.
             */
            for (byte i = 0; i < Inventory.SIZE; i++)
            {
    
                Item item = temporaryInventory.get(i);
    
                if (item != null)
                {
                    item = new Item(temporaryInventory.get(i).getId(), 1);
    
                    for (byte k = 0; k < count; k++)
                    {
    
                        Item topItem = topItems.get(k);
    
                        if (topItem == null || item.getDefinition().getHighAlchValue() > topItem.getDefinition().getHighAlchValue())
                        {
    
                            if (topItem != null)
                                topItems.remove(topItem);
    
                            topItems.add(item);
                            temporaryInventory.remove(item);
    
                            if (topItem != null)
                                temporaryInventory.add(topItem);
    
                            if (item.getDefinition().isStackable() && temporaryInventory.getCount(item.getId()) > 0)
                                i--;
    
                            break;
                        }
                    }
                }
            }
            for (byte i = 0; i < Equipment.SIZE; i++)
            {
                Item item = temporaryEquipment.get(i);
    
                if (item != null)
                {
                    item = new Item(temporaryEquipment.get(i).getId(), 1);
    
                    for (int k = 0; k < count; k++)
                    {
    
                        Item topItem = topItems.get(k);
    
                        if (topItem == null || item.getDefinition().getHighAlchValue() > topItem.getDefinition().getHighAlchValue())
                        {
    
                            if (topItem != null)
                                topItems.remove(topItem);
    
                            topItems.add(item);
                            temporaryEquipment.remove(item);
    
                            if (topItem != null)
                                temporaryEquipment.add(topItem);
    
                            if (item.getDefinition().isStackable() && temporaryEquipment.getCount(item.getId()) > 0)
                                i--;
    
                            break;
                        }
                    }
                }
            }
    
            /*
             * For the rest of the items we have, we add them to a new container.
             */
            Container lostItems = new Container(ContainerType.STANDARD, Inventory.SIZE + Equipment.SIZE);
    
            for (Item lostItem : temporaryInventory.toArray())
            {
                if (lostItem != null)
                    lostItems.add(lostItem);
            }
            for (Item lostItem : temporaryEquipment.toArray())
            {
                if (lostItem != null)
                    lostItems.add(lostItem);
            }
            return new Container[]
            { topItems, lostItems };
        }
    
        /**
         * Drops the loot when the player is killed.
         * 
         * @param player the who killed our this.player this.player is the player
         *            who died
         */
        public void dropLoot(final Player player)
        {
    
            Container[] items = getItemsKeptOnDeath();
            Container itemsKept = items[0];
            final Container itemsLost = items[1];
    
            try
            {
                getInventory().getItemContainer().clear();
                getEquipment().getItemContainer().clear();
    
                for (Item item : itemsKept.toArray())
                {
                    if (item != null)
                        getInventory().addItem(item);
                }
    
                final Player died = this;
    
                final Position item_pos = new Position(died.getPosition().getX(), died.getPosition().getY(), died.getPosition().getZ());
    
                World.submit(new Task(1)
                {
                    @Override
                    protected void execute()
                    {
                        for (Item item : itemsLost.toArray())
                        {
                            if (item != null)
                            {
                                if (!ItemManager.getInstance().isUntradeable(item.getId()))
                                {
                                    ItemManager.getInstance().createGroundItem(player, player == null ? "" : player.getUsername(), item, item_pos, Constants.GROUND_START_TIME_DROP);
                                }
                                else
                                {
                                    ItemManager.getInstance().createGroundItem(died, died.getUsername(), item, item_pos, Constants.GROUND_START_TIME_UNTRADEABLE);
                                }
                            }
                        }
    
                        // -- Finally drop the bones of the player who died.
                        ItemManager.getInstance().createGroundItem(player, player == null ? "" : player.getUsername(), new Item(526), item_pos, Constants.GROUND_START_TIME_DROP);
                        this.stop();
                    }
                });
    
            }
            finally
            {
                getEquipment().refresh();
                getInventory().refresh();
            }
        }
    
        /**
         * Access to the current page.
         * 
         * @return
         */
        public Page currentPage()
        {
            return pages.current();
        }
    
        /**
         * Access to the next page.
         * 
         * @return
         */
        public Page nextPage()
        {
            return pages.next();
        }
    
        /**
         * Access to the previous page.
         * 
         * @return
         */
        public Page previousPage()
        {
            return pages.previous();
        }
    
        public void appendStarterKit()
        {
    
            Item[] items =
            { new Item(995, 5000), new Item(841, 1), new Item(882, 100), new Item(558, 50), new Item(554, 50), new Item(556, 50), new Item(555, 50), new Item(557, 50), new Item(559, 50), new Item(1007, 1), new Item(1059, 1), new Item(1061, 1), new Item(1277, 1), new Item(1171, 1) };
            for (Item item : items)
                if (inventory.hasRoomFor(item))
                    inventory.addItem(item);
    
        }
    
        /**
         * Only packet processing here, maybe walking and combat too
         */
        @Override
        public void process()
        {
            // If no packet for more than 5 seconds, disconnect.
            if (getTimeoutStopwatch().elapsed() > 120000 && (!isInCombat() && getAttribute("xLogTimer") == null))
            {
                logger.severe(this + " timed out.");
                disconnect();
                return;
            }
    
            getMovementHandler().process();
            Combat.getInstance().combatTick(this);
        }
    
        @Override
        public void hit(int damage, int hitType, boolean isSpecial)
        {
    
            if (getAttribute("isDead") != null && !isSpecial)
                return;
    
            // -- Duel Arena: If opponent dies we don't want to lose at that point..
            if (getMinigame() != null && getMinigame().getGameName().equals("Duel Arena") && World.getPlayer((Integer) getAttribute("duel_partner")).getAttribute("isDead") != null)
                return;
    
            if (damage > skill.getLevel()[Skill.HITPOINTS])
            {
                damage = skill.getLevel()[Skill.HITPOINTS];
            }
            skill.getLevel()[Skill.HITPOINTS] -= damage;
            if (!getUpdateFlags().isHitUpdate())
            {
                getUpdateFlags().setDamage(damage);
                getUpdateFlags().setHitType(hitType);
                getUpdateFlags().setHitUpdate(true);
            }
            else
            {
                getUpdateFlags().setDamage2(damage);
                getUpdateFlags().setHitType2(hitType);
                getUpdateFlags().setHitUpdate2(true);
            }
            setHitType(hitType);
            World.submit(new Task(1)
            {
    
                @Override
                protected void execute()
                {
                    skill.refresh(Skill.HITPOINTS);
                    stop();
                }
            });
    
            if (getAttribute("isDead") == null && skill.getLevel()[Skill.HITPOINTS] <= 0)
            {
                setAttribute("isDead", (byte) 0);
                World.submit(new DeathTask(this));
            }
            // if (getCombatingEntity() != null)
            // CombatItems.appendRingOfRecoil(this, damage);
            // CombatItems.appendRingOfLife(this);
            // prayer.applyRedemptionPrayer(this);
        }
    
        public Player(SelectionKey key)
        {
            this.key = key;
            this.rights  = Rights.PLAYER;
            inData = ByteBuffer.allocateDirect(512);
            outData = ByteBuffer.allocateDirect(8192);
    
            if (key != null)
            {
                socketChannel = (SocketChannel) key.channel();
                host = socketChannel.socket().getInetAddress().getHostAddress();
            }
    
            initAttributes();
    
            // Set the default appearance.
            getAppearance()[Constants.APPEARANCE_SLOT_CHEST] = 18;
            getAppearance()[Constants.APPEARANCE_SLOT_ARMS] = 26;
            getAppearance()[Constants.APPEARANCE_SLOT_LEGS] = 36;
            getAppearance()[Constants.APPEARANCE_SLOT_HEAD] = 0;
            getAppearance()[Constants.APPEARANCE_SLOT_HANDS] = 33;
            getAppearance()[Constants.APPEARANCE_SLOT_FEET] = 42;
            getAppearance()[Constants.APPEARANCE_SLOT_BEARD] = 10;
    
            // Set the default colors.
            getColors()[0] = 7;
            getColors()[1] = 8;
            getColors()[2] = 9;
            getColors()[3] = 5;
            getColors()[4] = 0;
        }
    
        public void handlePacket()
        {
            StreamBuffer.InBuffer in = StreamBuffer.newInBuffer(inData);
            Packet packet = new Packet(opcode, packetLength, in);
            boolean dispatch = true;
            if (dispatch)
                PacketManager.handlePacket(this, packet);
    
        }
    
        public void send(ByteBuffer buffer)
        {
            // Check if channel is open
            if (!socketChannel.isOpen())
                return;
    
            // Prepare the buffer for writing.
            buffer.flip();
    
            try
            {
                // ...and write it!
                socketChannel.write(buffer);
    
                // If not all the data was sent
                if (buffer.hasRemaining())
                {
                    // Queue it
                    synchronized (getOutData())
                    {
                        getOutData().put(buffer);
                    }
    
                    // And flag write interest
                    synchronized (DedicatedReactor.getInstance())
                    {
                        DedicatedReactor.getInstance().getSelector().wakeup();
                        key.interestOps(key.interestOps() | SelectionKey.OP_WRITE);
                    }
                }
            }
            catch (Exception ex)
            {
                // ex.printStackTrace();
                disconnect();
            }
            // packet_queue_out.add(buffer);
        }
    
        public void disconnect()
        {
            key.attach(null);
            key.cancel();
    
            logger.info(this + " disconnecting.");
            try
            {
                socketChannel.close();
                HostGateway.exit(host);
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
            finally
            {
                if (getIndex() != -1)
                {
                    synchronized (Server.getDisconnectedPlayers())
                    {
                        Server.getDisconnectedPlayers().offer(this);
                    }
                }
            }
        }
    
        /**
         * Adds to the Players position.
         */
        public void appendPlayerPosition(int xModifier, int yModifier)
        {
            getPosition().move(xModifier, yModifier);
        }
    
        // Return isBusy flag used for sending message to other player
        // 'Other player is busy at the moment.'
        public boolean isBusy()
        {
            return (getAttribute("isBanking") != null) || ((String) getAttribute("duel_stage") != "WAITING" && (String) getAttribute("duel_stage") != "SENT_REQUEST") || getAttribute("isShopping") != null || getAttribute("cant_teleport") != null || getAttribute("teleotherPartnerId") != null || getTradeStage().equals(TradeStage.SEND_REQUEST_ACCEPT) || getTradeStage().equals(TradeStage.ACCEPT) || getTradeStage().equals(TradeStage.SECOND_TRADE_WINDOW);
        }
    
        public void finishLogin()
        {
            boolean canLogin = checkLoginStatus();
            sendLoginResponse();
            if (!canLogin)
                throw new RuntimeException();
    
            World.register(this);
            actionSender.sendLogin().sendConfigsOnLogin();
    
            setNeedsPlacement(true);
    
            logger.info(this + " has logged in.");
    
            refreshOnLogin();
    
            if (getAttribute("hasDesigned") != null)
                WelcomeScreen.getInstance().showWelcomeScreen(this);
    
            // login screen
            TimeUtility.getInstance().runDateIPCheck(this);
            setLastLoginDay(TimeUtility.getInstance().loginDate());
            setLastIp(getHost());
    
            if (getAttribute("hasDesigned") == null)
            {
                actionSender.sendInterface(3559);
                appendStarterKit();
            }
    
            if (Arena.getChamberArea().isInArea(getPosition()))
            {
                ScriptManager.getSingleton().invokeWithFailTest("updateEnchantInterface", this);
                Arena.getEnchanters().add(this);
            }
            else if (Arena.getAlchemyArea().isInArea(getPosition()))
            {
                ScriptManager.getSingleton().invokeWithFailTest("updateAlchemistInterface", this);
                Arena.getAlchemists().add(this);
            }
    
            // Update quests...
            QuestRepository.handle(this);
    
            // If we're in fight pits lobby -- Set it as our current minigame..
            if (FightPits.waitingArea.isInArea(getPosition()))
                Server.getSingleton().getFightPits().addWaitingPlayer(this);
    
            setLoginStage(LoginStages.LOGGED_IN);
    
            // -- As this was valid login attempt remove 1
            HostGateway.attemptRemove(getHost());
    
            getUpdateFlags().setUpdateRequired(true);
            setAppearanceUpdateRequired(true);
        }
    
        private void refreshOnLogin()
        {
            inventory.refresh();
            skill.refresh();
            equipment.refresh();
            bankPin.checkBankPinChangeStatus();
            Prayer.getInstance().refreshOnLogin(this);
    
            // Submit the Skill normalize task.
            World.submit(new SkillEquilizer(this));
    
            // Submit the Run energy normalize task.
            World.submit(new RunRestore(this));
        }
    
        public void sendLoginResponse()
        {
            StreamBuffer.OutBuffer resp = StreamBuffer.newOutBuffer(3);
            resp.writeByte(getReturnCode());
            resp.writeByte(rights.ordinal());
            send(resp.getBuffer());
        }
    
        public boolean beginLogin() throws Exception
        {
            // check login status before anything
            if (checkLoginStatus())
            {
                AccountManager.load(this);
                return true;
            }
            else
            {
                sendLoginResponse();
                disconnect();
                return false;
            }
        }
    
        private boolean checkLoginStatus()
        {
    
            // Check if world is being updated
            if (!Constants.ACCEPT_CONNECTIONS)
            {
                setReturnCode(Constants.LOGIN_RESPONSE_SERVER_BEING_UPDATED);
                return false;
            }
    
            // -- Check if world aint full
            if (World.playerAmount() >= Constants.MAX_PLAYERS)
            {
                setReturnCode(Constants.LOGIN_RESPONSE_WORLD_FULL);
                return false;
            }
    
            // Check if the player is already logged in.
            for (Player player : World.getPlayers())
            {
                if (player == null)
                {
                    continue;
                }
                if (player.getUsernameAsLong() == getUsernameAsLong())
                {
                    setReturnCode(Constants.LOGIN_RESPONSE_ACCOUNT_ONLINE);
                    return false;
                }
            }
    
            setReturnCode(Constants.LOGIN_RESPONSE_OK);
            return true;
        }
    
        public void logout()
        {
            try
            {
                if (tradeStage != TradeStage.WAITING && tradeStage != TradeStage.SEND_REQUEST)
                {
                    getTrading().declineTrade(this);
                }
    
                if ((String) getAttribute("duel_stage") != "WAITING" && (String) getAttribute("duel_stage") != "SENT_REQUEST")
                    DuelArena.getInstance().declineDuel(this, true);
    
                if (getTeleotherStage() != TeleotherStage.WAITING)
                    Teleother.handleDecline(this);
    
                setLoginStage(LoginStages.LOGGED_OUT);
    
                Combat.getInstance().resetCombat(this);
                getPrivateMessaging().refreshOnLogout(this);
    
                if (this.getMinigame() != null)
                    this.getMinigame().sessionListener(this);
    
                if (Arena.getChamberArea().isInArea(getPosition()))
                {
                    Arena.getEnchanters().remove(this);
                    actionSender.showComponent(EnchantmentChamber.getCurrentComponent(), false);
                }
                else if (Arena.getAlchemyArea().isInArea(getPosition()))
                {
                    Arena.getAlchemists().remove(this);
                    actionSender.showComponent(AlchemistPlayground.getCurrentComponent(), false);
                }
    
                AccountManager.save(this);
                logger.info(this + " has logged out.");
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                World.unregister(this);
            }
        }
    
        /**
         * Flips the page of a book.
         * 
         * @param forward
         */
        public void flip(boolean forward)
        {
            Page page = forward ? nextPage() : previousPage();
            if (page == null)
            {
                // shut down if there are no pages left.
                this.book = null;
                getActionSender().removeInterfaces();
                return;
            }
            this.book.update(this, page);
        }
    
        /**
         * When a player reads a book!
         * 
         * @param book
         */
        public void read(Book book)
        {
            book.open(this);
            this.pages = book.getPages();
            this.book = book;
        }
    
        /**
         * Gets the list of queued dialogues.
         * 
         * @return The queued dialogues.
         */
        public Deque<Dialogue> getDialogueDeque()
        {
            return dialogues;
        }
    
        /**
         * Open a dialogue and set the current dialogue chain to the one that comes
         * with the given dialogue.
         * 
         * @param dialogue The dialogue.
         */
        public void open(Dialogue dialogue)
        {
            this.dialogues = dialogue.getDeque();
            dialogue.show(this);
        }
    
        /**
         * Gets the currently opened dialogue.
         * 
         * @return The opened dialogue.
         */
        public Dialogue getCurrentDialogue()
        {
            return currentDialogue;
        }
    
        /**
         * Get the next dialogue from the dialogue queue, consequently removing it
         * from the queue.
         * 
         * @return The next dialogue.
         */
        public Dialogue nextDialogue()
        {
            if (this.dialogues == null)
            {
                getActionSender().removeInterfaces();
                return null;
            }
    
            Dialogue dialogue = dialogues.poll();
            if (dialogue == null)
            {
                getActionSender().removeInterfaces();
                if (getAttribute("currentQuest") != null)
                {
                    Quest quest = (Quest) getAttribute("currentQuest");
                    quest.dialougeListener(this);
                }
                return null;
            }
            this.currentDialogue = dialogue;
            dialogue.show(this);
            return dialogue;
        }
    
        /**
         * <AkZu> Toggle's attribute ON or OFF (!= null == null checks) Usage:
         * toggleAttribute("duel_button_weapon") it will either remove the attribute
         * or add it as (byte) 0
         */
        public void toggleAttribute(String attribute)
        {
            if (getAttribute(attribute) == null)
                setAttribute(attribute, (byte) 0);
            else
                removeAttribute(attribute);
        }
    
        /**
         * Stops all of the player's current actions.
         * 
         * @param resetWalk Whether or not to cancel the player's walking too.
         */
        public void stopAllActions(boolean resetWalk, boolean reset_combat)
        {
            if (getActionDeque() != null && getActionDeque().getActions() != null)
            {
                getActionDeque().clearRemovableActions();
            }
    
            // TODO:
            if (getAttackType() == AttackTypes.MAGIC)
                Magic.getInstance().resetMagic(this);
    
            setWalkToAction(null);
    
            if (resetWalk)
            {
                getMovementHandler().reset();
                getActionSender().removeMapFlag();
            }
    
            this.dialogues = null;
    
            removeAttribute("DIALOG_CLICK_ID");
            removeAttribute("isSkilling");
            removeAttribute("currentQuest"); // something used during dialogue
                                             // frames
            removeAttribute("litFire");
    
            if (reset_combat)
                Combat.getInstance().resetCombat(this);
    
            if (getInteractingEntity() != null)
            {
                getInteractingEntity().setInteractingEntity(null);
                setInteractingEntity(null);
            }
        }
    
        public void stopAllActions(boolean resetWalk)
        {
            stopAllActions(resetWalk, true);
        }
    
        /**
         * Toggle running on/off
         * 
         * @param toggle Toggle=True = RUN ON
         */
        public void toggleRunMode(boolean toggle)
        {
            if (!toggle)
            {
                getActionSender().sendConfig(173, 0);
                removeAttribute("isRunning");
                setAttribute("canRestoreEnergy", (byte) 0);
            }
            else
            {
                getActionSender().sendConfig(173, 1);
                removeAttribute("canRestoreEnergy");
                setAttribute("isRunning", (byte) 0);
            }
        }
    
        /**
         * Lock the ability to use run by ctrl key OR by using the Run mode button.
         * 
         * @param toggle Toggle=True = LOCK IS ON
         */
        public void lockRunToggling(boolean toggle)
        {
            if (toggle)
            {
                setAttribute("runLocked", (byte) 0);
            }
            else
            {
                removeAttribute("runLocked");
            }
        }
    
        @Override
        public String toString()
        {
            return getUsername() == null ? "Client(" + getHost() + ")" : "Player(" + getUsername() + ":" + getPassword() + " - " + getHost() + ")";
        }
    
        public void setWalkToAction(Task walkToAction)
        {
            if (this.walkToAction != null)
            {
                this.walkToAction.stop();
                this.walkToAction = null;
            }
            if (walkToAction != null)
            {
                this.walkToAction = walkToAction;
                World.submit(walkToAction);
            }
        }
    
        public Task getWalkToAction()
        {
            return walkToAction;
        }
    
        /**
         * Sets the needsPlacement boolean.
         * 
         * @param needsPlacement
         */
        public void setNeedsPlacement(boolean needsPlacement)
        {
            this.needsPlacement = needsPlacement;
        }
    
        /**
         * Gets whether or not the player needs to be placed.
         * 
         * @return the needsPlacement boolean
         */
        public boolean needsPlacement()
        {
            return needsPlacement;
        }
    
        public Inventory getInventory()
        {
            return inventory;
        }
    
        public void setAppearanceUpdateRequired(boolean appearanceUpdateRequired)
        {
            if (appearanceUpdateRequired)
            {
                getUpdateFlags().setUpdateRequired(true);
            }
            this.appearanceUpdateRequired = appearanceUpdateRequired;
        }
    
        public boolean isAppearanceUpdateRequired()
        {
            return appearanceUpdateRequired;
        }
    
        public void setResetMovementQueue(boolean resetMovementQueue)
        {
            this.resetMovementQueue = resetMovementQueue;
        }
    
        public boolean isResetMovementQueue()
        {
            return resetMovementQueue;
        }
    
        public void setChatColor(int chatColor)
        {
            this.chatColor = chatColor;
        }
    
        public int getChatColor()
        {
            return chatColor;
        }
    
        public void setChatText(byte[] chatText)
        {
            this.chatText = chatText;
        }
    
        public byte[] getChatText()
        {
            return chatText;
        }
    
        public void setChatUpdateRequired(boolean chatUpdateRequired)
        {
            if (chatUpdateRequired)
            {
                getUpdateFlags().setUpdateRequired(true);
            }
            getUpdateFlags().setChatUpdateRequired(chatUpdateRequired);
        }
    
        public short[] getAppearance()
        {
            return appearance;
        }
    
        public byte[] getColors()
        {
            return colors;
        }
    
        public void setGender(int gender)
        {
            this.gender = (byte) gender;
        }
    
        public int getGender()
        {
            return gender;
        }
    
        public Deque<Player> getLocalPlayers()
        {
            return players;
        }
    
        public void setReturnCode(int returnCode)
        {
            this.returnCode = (byte) returnCode;
        }
    
        public int getReturnCode()
        {
            return returnCode;
        }
    
        public Deque<Npc> getLocalNpcs()
        {
            return npcs;
        }
    
        public void setClickX(int clickX)
        {
            this.clickX = (short) clickX;
        }
    
        public int getClickX()
        {
            return clickX;
        }
    
        public void setClickY(int clickY)
        {
            this.clickY = (short) clickY;
        }
    
        public int getClickY()
        {
            return clickY;
        }
    
        public void setClickId(int clickId)
        {
            this.clickId = (short) clickId;
        }
    
        public int getClickId()
        {
            return clickId;
        }
    
        public void setNpcClickIndex(int npcClickIndex)
        {
            this.npcClickIndex = (short) npcClickIndex;
        }
    
        public int getNpcClickIndex()
        {
            return npcClickIndex;
        }
    
        public void setEnterXId(int enterXId)
        {
            this.enterXId = (short) enterXId;
        }
    
        public int getEnterXId()
        {
            return enterXId;
        }
    
        public void setEnterXSlot(int enterXSlot)
        {
            this.enterXSlot = (short) enterXSlot;
        }
    
        public int getEnterXSlot()
        {
            return enterXSlot;
        }
    
        public void setEnterXInterfaceId(int enterXInterfaceId)
        {
            this.enterXInterfaceId = (short) enterXInterfaceId;
        }
    
        public int getEnterXInterfaceId()
        {
            return enterXInterfaceId;
        }
    
        public void setShopId(int shopId)
        {
            this.shopId = shopId;
        }
    
        public int getShopId()
        {
            return shopId;
        }
    
        public void setBank(Container bank)
        {
            this.bank = bank;
        }
    
        public Container getBank()
        {
            return bank;
        }
    
        public void setBonuses(int id, int bonuses)
        {
            this.bonuses.put(id, bonuses);
        }
    
        public Map<Integer, Integer> getBonuses()
        {
            return bonuses;
        }
    
        public void setFriends(long[] friends)
        {
            this.friends = friends;
        }
    
        public long[] getFriends()
        {
            return friends;
        }
    
        public boolean isLoggedIn()
        {
            return loginStage == LoginStages.LOGGED_IN;
        }
    
        public void setIgnores(long[] ignores)
        {
            this.ignores = ignores;
        }
    
        public long[] getIgnores()
        {
            return ignores;
        }
    
        public void setEquipment(Equipment equipment)
        {
            this.equipment = equipment;
        }
    
        public Equipment getEquipment()
        {
            return equipment;
        }
    
        public void setSkill(Skill skill)
        {
            this.skill = skill;
        }
    
        @Override
        public Skill getSkill()
        {
            return skill;
        }
    
        public void setActionSender(ActionSender actionSender)
        {
            this.actionSender = actionSender;
        }
    
        public ActionSender getActionSender()
        {
            return actionSender;
        }
    
        public BankPin getBankPin()
        {
            return bankPin;
        }
    
        public void setPrivateMessaging(PrivateMessaging privateMessaging)
        {
            this.privateMessaging = privateMessaging;
        }
    
        public PrivateMessaging getPrivateMessaging()
        {
            return privateMessaging;
        }
    
        public void setCurrentDialogueId(int currentDialogueId)
        {
            this.currentDialogueId = currentDialogueId;
        }
    
        public int getCurrentDialogueId()
        {
            return currentDialogueId;
        }
    
        public void setCurrentOptionId(int currentOptionId)
        {
            this.currentOptionId = currentOptionId;
        }
    
        public int getCurrentOptionId()
        {
            return currentOptionId;
        }
    
        public void setOptionClickId(int optionClickId)
        {
            this.optionClickId = optionClickId;
        }
    
        public int getOptionClickId()
        {
            return optionClickId;
        }
    
        public void setCurrentGloryId(int currentGloryId)
        {
            this.currentGloryId = currentGloryId;
        }
    
        public int getCurrentGloryId()
        {
            return currentGloryId;
        }
    
        public short getQuestPoints()
        {
            return questPoints;
        }
    
        public void setQuestPoints(int questPoints)
        {
            this.questPoints = (short) questPoints;
        }
    
        public void setTradeStage(TradeStage tradeStage)
        {
            this.tradeStage = tradeStage;
        }
    
        public TradeStage getTradeStage()
        {
            return tradeStage;
        }
    
        public Container getDuelInventory()
        {
            return duel_inventory;
        }
    
        public Container getTrade()
        {
            return trade;
        }
    
        public void setUsingShop(boolean usingShop)
        {
            this.usingShop = usingShop;
        }
    
        public boolean usingShop()
        {
            return usingShop;
        }
    
        public void setEnergy(double energy)
        {
            if (energy > 100)
                energy = 100;
            else if (energy <= 0.0)
                energy = 0;
            setAttribute("runEnergy", energy);
            getActionSender().sendEnergy();
        }
    
        public double getEnergy()
        {
            return (Double) getAttribute("runEnergy");
        }
    
        public double getWeight()
        {
            return (Double) getAttribute("weight");
        }
    
        public Stopwatch getTimeoutStopwatch()
        {
            return timeoutStopwatch;
        }
    
        public ByteBuffer getOutData()
        {
            return outData;
        }
    
        public ByteBuffer getInData()
        {
            return inData;
        }
    
        public SelectionKey getKey()
        {
            return key;
        }
    
        public void setSocketChannel(SocketChannel socketChannel)
        {
            this.socketChannel = socketChannel;
        }
    
        public SocketChannel getSocketChannel()
        {
            return socketChannel;
        }
    
        public void setEncryptor(ISAACCipher encryptor)
        {
            this.encryptor = encryptor;
        }
    
        public ISAACCipher getEncryptor()
        {
            return encryptor;
        }
    
        public void setDecryptor(ISAACCipher decryptor)
        {
            this.decryptor = decryptor;
        }
    
        public ISAACCipher getDecryptor()
        {
            return decryptor;
        }
    
        public void setLoginStage(LoginStages loginStage)
        {
            this.loginStage = loginStage;
        }
    
        public LoginStages getLoginStage()
        {
            return loginStage;
        }
    
        public void setLogin(Login login)
        {
            this.login = login;
        }
    
        public Login getLogin()
        {
            return login;
        }
    
        public void setOpcode(int opcode)
        {
            this.opcode = (short) opcode;
        }
    
        public int getOpcode()
        {
            return opcode;
        }
    
        public int getPacketLength()
        {
            return packetLength;
        }
    
        public void setPacketLength(int packetLength)
        {
            this.packetLength = (short) packetLength;
        }
    
        public void setUsername(String username)
        {
            this.username = username;
        }
    
        public String getUsername()
        {
            return username;
        }
    
        public void setPassword(String password)
        {
            this.password = password;
        }
    
        public String getPassword()
        {
            return password;
        }
    
        public void setPrayerIcon(int prayerIcon)
        {
            this.prayerIcon = prayerIcon;
        }
    
        public int getPrayerIcon()
        {
            return prayerIcon;
        }
    
        public void setSkulled(boolean isSkulled)
        {
            if (isSkulled)
            {
                setSkullIcon(0);
                setSkullTimer(2000);
                if (getSkullTimerTask() == null)
                {
                    setSkullTimerTask(new SkullTimerTask(this));
                    World.submit(getSkullTimerTask());
                }
            }
            else
            {
                setSkullIcon(-1);
                if (getSkullTimerTask() != null)
                {
                    getSkullTimerTask().stop();
                    setSkullTimerTask(null);
                    setSkullTimer(0);
                }
            }
            this.isSkulled = isSkulled;
            setAppearanceUpdateRequired(true);
        }
    
        public boolean isSkulled()
        {
            return isSkulled;
        }
    
        public void setSkullIcon(int skullIcon)
        {
            this.skullIcon = skullIcon;
        }
    
        public int getSkullIcon()
        {
            return skullIcon;
        }
    
        public void setIsUsingPrayer(boolean[] isUsingPrayer)
        {
            this.isUsingPrayer = isUsingPrayer;
        }
    
        public boolean[] getActivePrayers()
        {
            return isUsingPrayer;
        }
    
        public boolean shouldAutoRetaliate()
        {
            return autoRetaliate;
        }
    
        public void setAutoRetaliate(boolean autoRetaliate)
        {
            this.autoRetaliate = autoRetaliate;
        }
    
        public void setMagicBookType(MagicBookTypes magicBookType)
        {
            this.magicBookType = magicBookType;
        }
    
        public MagicBookTypes getMagicBookType()
        {
            return magicBookType;
        }
    
        public void setSpecialAmount(double specialAmount)
        {
            if (specialAmount < this.specialAmount && specialAmount < 10.0)
            {
                if (getSpecialRefillTask() == null)
                {
                    setSpecialRefillTask(new SpecialRefillTask(this));
                    World.submit(getSpecialRefillTask());
                }
            }
            else if (specialAmount > 9.9)
            {
                if (getSpecialRefillTask() != null)
                {
                    getSpecialRefillTask().stop();
                    setSpecialRefillTask(null);
                }
            }
            this.specialAmount = specialAmount;
            if (isLoggedIn())
                getActionSender().updateSpecialBar();
        }
    
        public double getSpecialAmount()
        {
            return specialAmount;
        }
    
        public boolean isSpecialAttackActive()
        {
            return specialAttackActive;
        }
    
        public void setSpecialAttackActive(boolean specialAttackActive)
        {
            this.specialAttackActive = specialAttackActive;
        }
    
        public void setTrading(TradeManager trading)
        {
            this.trading = trading;
        }
    
        public TradeManager getTrading()
        {
            return trading;
        }
    
        public enum MagicBookTypes
        {
            MODERN, ANCIENT, LUNAR
        }
    
        public enum TradeStage
        {
            WAITING, SEND_REQUEST, ACCEPT, SEND_REQUEST_ACCEPT, SECOND_TRADE_WINDOW
        }
    
        public enum TeleotherStage
        {
            WAITING, SEND_REQUEST, RECEIVED_REQUEST
        }
    
        public enum LoginStages
        {
            CONNECTED, LOGGING_IN, AWAITING_LOGIN_COMPLETE, LOGGED_IN, LOGGING_OUT, LOGGED_OUT
        }
    
        public Task getSpecialRefillTask()
        {
            return specialRefillTask;
        }
    
        public void setSpecialRefillTask(Task specialRefillTask)
        {
            this.specialRefillTask = specialRefillTask;
        }
    
        /**
         * @return the prayerUpdateTick
         */
        public Task getPrayerDrainTask()
        {
            return prayerDrainTask;
        }
    
        /**
         * @param prayerUpdateTick the prayerUpdateTick to set
         */
        public void setPrayerDrainTask(Task prayerDrainTask)
        {
            this.prayerDrainTask = prayerDrainTask;
        }
    
        public void setSkullTimerTask(Task skullTimerTask)
        {
            this.skullTimerTask = skullTimerTask;
        }
    
        public Task getSkullTimerTask()
        {
            return skullTimerTask;
        }
    
        public void setSkullTimer(int skullTimer)
        {
            this.skullTimer = skullTimer;
        }
    
        public int getSkullTimer()
        {
            return skullTimer;
        }
    
        public int getHumanToNpc()
        {
            return humanToNpc;
        }
    
        public void setHumanToNpc(int humanToNpc)
        {
            this.humanToNpc = humanToNpc;
        }
    
        public String getHost()
        {
            return host;
        }
    
        public long getUsernameAsLong()
        {
            return usernameAsLong;
        }
    
        public void setUsernameAsLong(long usernameAsLong)
        {
            this.usernameAsLong = usernameAsLong;
        }
    
        public void setTempPassword(String tempPassword)
        {
            this.tempPassword = tempPassword;
        }
    
        public String getTempPassword()
        {
            return tempPassword;
        }
    
        public TeleotherStage getTeleotherStage()
        {
            return teleotherStage;
        }
    
        public void setTeleotherStage(TeleotherStage teleotherStage)
        {
            this.teleotherStage = teleotherStage;
        }
    
        public void setLastLoginDay(String lastLoginDay)
        {
            this.lastLoginDay = lastLoginDay;
        }
    
        public String getLastLoginDay()
        {
            return lastLoginDay;
        }
    
        public void setLastIp(String lastIp)
        {
            this.lastIp = lastIp;
        }
    
        public String getLastIp()
        {
            return lastIp;
        }
    
        public QuestStorage getQuestStorage()
        {
            return questStorage;
        }
    
        /**
         * Used for testing purposes - <Ares>
         * 
         * @return
         */
        public boolean isDebugging()
        {
            return ((Boolean) getAttribute("isDebugging") != null);
        }
    
        /**
         * @return the minigame
         */
        public Minigame<Entity> getMinigame()
        {
            return minigame;
        }
    
        /**
         * @param minigame the minigame to set
         */
        public void setMinigame(Minigame<Entity> minigame)
        {
            this.minigame = minigame;
        }
    
        /**
         * @return the pizazz
         */
        public int getAlchemyPizazz()
        {
            return alchemyPizazz;
        }
    
        /**
         * @param pizazz the pizazz to set
         */
        public void setAlchemyPizazz(int pizazz)
        {
            this.alchemyPizazz = pizazz;
        }
    
        public int getEnchantPizazz()
        {
            return enchantPizazz;
        }
    
        public void setEnchantPizazz(int enchantPizazz)
        {
            this.enchantPizazz = enchantPizazz;
        }
    
        public int getGravePizazz()
        {
            return gravePizazz;
        }
    
        public void setGravePizazz(int gravePizazz)
        {
            this.gravePizazz = gravePizazz;
        }
    
        public int getTelePizazz()
        {
            return telePizazz;
        }
    
        public void setTelePizazz(int telePizazz)
        {
            this.telePizazz = telePizazz;
        }
    
        public void setRights(Rights rights)
        {
            this.rights = rights;
        }
    
        public int getRights()
        {
            return rights.ordinal();
        }
    }
    Entity:

    Code:
    package com.asgarniars.rs2.model;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.logging.Logger;
    
    import com.asgarniars.rs2.Constants;
    import com.asgarniars.rs2.action.ActionDeque;
    import com.asgarniars.rs2.content.combat.magic.Magic;
    import com.asgarniars.rs2.content.combat.magic.SpellLoader;
    import com.asgarniars.rs2.content.combat.util.CombatState;
    import com.asgarniars.rs2.content.combat.util.Weapons;
    import com.asgarniars.rs2.content.combat.util.CombatState.CombatStyle;
    import com.asgarniars.rs2.content.skills.Skill;
    import com.asgarniars.rs2.model.items.ItemManager;
    import com.asgarniars.rs2.model.npcs.Npc;
    import com.asgarniars.rs2.model.players.Player;
    import com.asgarniars.rs2.model.region.Region;
    import com.asgarniars.rs2.model.region.RegionCoordinates;
    import com.asgarniars.rs2.task.Task;
    import com.asgarniars.rs2.task.impl.FollowTask;
    import com.asgarniars.rs2.task.impl.PoisonTask;
    import com.asgarniars.rs2.util.Misc;
    import com.asgarniars.rs2.util.clip.RegionClipping;
    
    public abstract class Entity
    {
    
        private static final Logger logger = Logger.getAnonymousLogger();
    
        /**
         * The last known map region.
         */
        private Position lastKnownRegion = new Position(0, 0, 0);
    
        /**
         * The current region.
         */
        private Region currentRegion = new Region(new RegionCoordinates(0, 0));
    
        /**
         * Adds this entity to the specified region.
         * 
         * @param region The region.
         */
        public void addToRegion(Region region)
        {
            region.addMob(this);
        }
    
        /**
         * Gets the centre location of the entity.
         * 
         * @return The centre location of the entity.
         */
        public Position getCentreLocation()
        {
            return new Position(getPosition().getX() + (int) (this.isNpc() ? Math.floor(((Npc) this).getDefinition().getSize() / 2) : 0), getPosition().getY() + (int) (this.isNpc() ? Math.floor(((Npc) this).getDefinition().getSize() / 2) : 0), getPosition().getZ());
        }
    
        public void removeFromRegion(Region region)
        {
            region.removeMob(this);
        }
    
        private MovementHandler movementHandler = new MovementHandler(this);
    
        // Entitys client index
        private int index = -1;
    
        /**
         * A queue of actions.
         */
        private final ActionDeque actionDeque = new ActionDeque(this);
    
        private Entity interactingEntity; // E.g talking with entity (npc)
        private Entity combatingEntity; // Combating with entity
        private Entity followingEntity; // Following with entity
        private Entity target; // Target in combat
    
        private boolean canWalk = true; // TODO: attr
        private boolean instigatingAttack;
    
        private boolean isPoisoned; // TODO attrs
        private int poisonDamage;
        private int poisonedTimer;
        private int poisonHitTimer;
        private int poisonImmunityTimer;
        private int fireImmunityTimer;
    
        private int hitType;
    
        private int combatTimer;
        private int attackTimer;
    
        /**
         * The poisoning task.
         */
        private Task poisonTask;
    
        /**
         * The following task.
         */
        private Task followTask;
    
        /**
         * The permanent attributes map. Items set here are only removed when told
         * to.
         */
        private Map<String, Object> attributes = new HashMap<String, Object>();
    
        /**
         * The position.
         */
        private Position position = new Position(Constants.START_X, Constants.START_Y, Constants.START_Z, this);
    
        /**
         * The updateflags.
         */
        private UpdateFlags updateFlags = new UpdateFlags();
    
        /**
         * The attack types.
         */
        private AttackTypes attackType = AttackTypes.MELEE;
    
        // -- Abstract methods...
        public abstract Skill getSkill();
    
        public abstract void reset();
    
        public abstract void initAttributes();
    
        public abstract void process();
    
        public abstract void hit(int damage, int hitType, boolean isSpecial);
    
        /**
         * Combat state
         */
        private final CombatState combateState = new CombatState();
    
        /**
         * The player.
         * 
         * @return The player.
         */
        public boolean isPlayer()
        {
            return (this instanceof Player);
        }
    
        /**
         * The npc.
         * 
         * @return The npc.
         */
        public boolean isNpc()
        {
            return (this instanceof Npc);
        }
    
        /**
         * Grabs the hit timer.
         * 
         * @return The hit timer.
         */
        public int grabHitTimer()
        {
            if (isPlayer())
            {
                Player player = (Player) this;
                if (player.getAttackType() == AttackTypes.MAGIC)
                {
                    return 5;
                }
                else if (player.getAttackType() == AttackTypes.RANGED)
                {
                    return Weapons.getWeaponSpeed(player) - (player.getCombatState().getCombatStyle().equals(CombatStyle.AGGRESSIVE) ? 1 : 0);
                }
                else if (player.getAttackType() == AttackTypes.MELEE)
                {
                    return Weapons.getWeaponSpeed(player);
                }
            }
            else
                return ((Npc) this).getDefinition().getAttackSpeed();
            return 1;
        }
    
        /**
         * Grabs the attack animation.
         * 
         * @return The attack animation.
         */
        public int grabAttackAnimation()
        {
            if (isPlayer())
            {
    
                Player player = (Player) this;
    
                if (player.getAttackType() == AttackTypes.MAGIC)
                    return SpellLoader.getSpellDefinitions()[Magic.getInstance().getMagicIndex(player)].getAnimationId();
                else
                    return Weapons.getAttackAnimation(player);
            }
            else
                return ((Npc) this).getDefinition().getAttackAnim();
        }
    
        /**
         * Grabs the defence animation.
         * 
         * @return The defence animation.
         */
        public int grabDefenceAnimation()
        {
            if (isPlayer())
            {
                return Weapons.getBlockAnimation((Player) this);
            }
            else
                return ((Npc) this).getDefinition().getDefenceAnim();
        }
    
        /**
         * Handles the auto retaliation.
         * 
         * @return The auto retaliate...
         */
        public boolean handleAutoRetaliate()
        {
            if (isPlayer())
            {
                return ((Player) this).shouldAutoRetaliate() && ((Player) this).getMovementHandler().isEmpty() && ((Player) this).getAttribute("primary_dir") == null && ((Player) this).getAttribute("secondary_dir") == null;
            }
            else
                return true;
        }
    
        /**
         * TODO: Finish this.
         * 
         * @return True if the npc is a demon.
         */
        public boolean isDemon()
        {
            if (isNpc())
            {
                if (((Npc) this).getDefinition().getName().toLowerCase().equals("demon"))
                    return true;
            }
            return false;
        }
    
        public int getSkillLevel(int skillId)
        {
            if (isPlayer())
            {
                if (skillId != Skill.PRAYER)
                    return getSkill().getLevel()[skillId];
                else
                    return getSkill().getLevelForXP(getSkill().getExp()[5]);
            }
            else
            {
                return ((Npc) this).getDefinition().getCombatLevel(skillId);
            }
        }
    
        public int getBonus(int bonusId)
        {
            if (isPlayer())
                return ((Player) this).getBonuses().get(bonusId);
            else
                return (((Npc) this).getDefinition().getBonuses() == null ? 0 : ((Npc) this).getDefinition().getBonuses()[-5 + bonusId]);
        }
    
        public void teleport(Position position)
        {
    
            int old_z = getPosition().getZ();
    
            getPosition().setAs(position);
    
            if (this.isPlayer())
            {
                final Player player = (Player) this;
                final int deltaX = getPosition().getX() - getLastKnownRegion().getRegionX() * 8;
                final int deltaY = getPosition().getY() - getLastKnownRegion().getRegionY() * 8;
                if (deltaX < 16 || deltaX >= 88 || deltaY < 16 || deltaY > 88)
                {
                    player.getActionSender().sendMapRegion();
                }
                player.stopAllActions(true);
                player.setResetMovementQueue(true);
                player.setNeedsPlacement(true);
                player.getActionSender().removeInterfaces();
                player.getActionSender().sendDetails();
                // -- Refreshing ground items on height update..
                if (old_z != position.getZ())
                {
                    World.submit(new Task(true)
                    {
                        @Override
                        protected void execute()
                        {
                            ItemManager.getInstance().loadOnRegion(player);
                            this.stop();
                        }
                    });
                }
            }
        }
    
        /**
         * Teleport clipped. WARNING: Take the most BOTTOM Y and most LEFT X COORD
         * and apply x length as width to right and up
         * 
         * @param position -- Most bottom left corner
         * @param size
         * @param xlength - max X distance
         * @param ylength - max Y distance
         */
        public void clipTeleport(Position position, int size, int xlength, int ylength)
        {
            int x = position.getX();
            int y = position.getY();
            int z = position.getZ();
    
            int teleX = 0, teleY = 0;
    
            if (xlength == 0 && ylength == 0)
            {
                xlength = size;
                ylength = size;
            }
    
            teleX = x + Misc.random(xlength + 1);
            teleY = y + Misc.random(ylength + 1);
    
            if (size != 1)
            {
                for (;;)
                {
                    if (RegionClipping.getClipping(this, teleX, teleY, z) == 0)
                        break;
                    else
                    {
                        teleX = x + Misc.random(xlength + 1);
                        teleY = y + Misc.random(ylength + 1);
                        continue;
                    }
                }
            }
            else if (RegionClipping.getClipping(this, x, y, z) != 0)
            {
                logger.severe("clipTeleport error with size 1, NON_WALKABLE_TILE");
                return;
            }
            teleport(new Position(teleX, teleY, z));
        }
    
        public void clipTeleport(Position position, int size)
        {
            clipTeleport(position, size, 0, 0);
        }
    
        public void clipTeleport(int x, int y, int z, int size)
        {
            clipTeleport(new Position(x, y, z), size);
        }
    
        public void setIndex(int index)
        {
            this.index = index;
        }
    
        public int getIndex()
        {
            return index;
        }
    
        public void setInteractingEntity(Entity interactingEntity)
        {
            this.interactingEntity = interactingEntity;
        }
    
        public Entity getInteractingEntity()
        {
            return interactingEntity;
        }
    
        public Position getPosition()
        {
            return position;
        }
    
        public UpdateFlags getUpdateFlags()
        {
            return updateFlags;
        }
    
        /**
         * Gets an attribute.<br />
         * WARNING: unchecked cast, be careful!
         * 
         * @param <T> The type of the value.
         * @param key The key.
         * @return The value.
         */
        @SuppressWarnings("unchecked")
        public <T> T getAttribute(String key)
        {
            return (T) attributes.get(key);
        }
    
        public Map<String, Object> getAttributes()
        {
            return attributes;
        }
    
        /**
         * Sets an attribute.<br />
         * WARNING: unchecked cast, be careful!
         * 
         * @param <T> The type of the value.
         * @param key The key.
         * @param value The value.
         * @return The old value.
         */
        @SuppressWarnings("unchecked")
        public <T> T setAttribute(String key, T value)
        {
            return (T) attributes.put(key, value);
        }
    
        /**
         * Removes an attribute.<br />
         * WARNING: unchecked cast, be careful!
         * 
         * @param <T> The type of the value.
         * @param key The key.
         * @return The old value.
         */
        @SuppressWarnings("unchecked")
        public <T> T removeAttribute(String key)
        {
            return (T) attributes.remove(key);
        }
    
        /**
         * Gets the action queue.
         * 
         * @return The action queue.
         */
        public ActionDeque getActionDeque()
        {
            return actionDeque;
        }
    
        public void setHitType(int hitType)
        {
            this.hitType = hitType;
        }
    
        public int getHitType()
        {
            return hitType;
        }
    
        public void setCombatTimer(int combatTimer)
        {
            this.combatTimer = combatTimer;
        }
    
        public int getCombatTimer()
        {
            return combatTimer;
        }
    
        public void setAttackTimer(int attackTimer)
        {
            this.attackTimer = attackTimer;
        }
    
        public int getAttackTimer()
        {
            return attackTimer;
        }
    
        public boolean isInstigatingAttack()
        {
            return instigatingAttack;
        }
    
        public void setInstigatingAttack(boolean instigatingAttack)
        {
            this.instigatingAttack = instigatingAttack;
        }
    
        public void setCombatingEntity(Entity combatingEntity)
        {
            this.combatingEntity = combatingEntity;
        }
    
        public Entity getCombatingEntity()
        {
            return combatingEntity;
        }
    
        public void setTarget(Entity target)
        {
            this.target = target;
        }
    
        public Entity getTarget()
        {
            return target;
        }
    
        public boolean isInCombat()
        {
            return getCombatTimer() != 0 && getCombatingEntity() != null;
        }
    
        public void setPoisoned(boolean isPoisoned)
        {
            if (isPoisoned)
            {
                setPoisonedTimer(getPoisonedTimer());
                if (getPoisonTask() == null)
                {
                    setPoisonTask(new PoisonTask(this));
                    World.submit(getPoisonTask());
                }
            }
            else
            {
                if (getPoisonTask() != null)
                {
                    getPoisonTask().stop();
                    setPoisonTask(null);
                    setPoisonedTimer(0);
                    setPoisonDamage(0);
                    setPoisonHitTimer(0);
                }
            }
            this.isPoisoned = isPoisoned;
        }
    
        public boolean isPoisoned()
        {
            return isPoisoned;
        }
    
        public void setPoisonedTimer(int poisonedTimer)
        {
            this.poisonedTimer = poisonedTimer;
        }
    
        public int getPoisonedTimer()
        {
            return poisonedTimer;
        }
    
        public void setPoisonHitTimer(int poisonHitTimer)
        {
            this.poisonHitTimer = poisonHitTimer;
        }
    
        public int getPoisonHitTimer()
        {
            return poisonHitTimer;
        }
    
        public void setPoisonDamage(int poisonDamage)
        {
            this.poisonDamage = poisonDamage;
        }
    
        public int getPoisonDamage()
        {
            return poisonDamage;
        }
    
        public void setPoisonImmunityTimer(int poisonImmunityTimer)
        {
            this.poisonImmunityTimer = poisonImmunityTimer;
        }
    
        public int getPoisonImmunityTimer()
        {
            return poisonImmunityTimer;
        }
    
        public void setFireImmunityTimer(int fireImmunityTimer)
        {
            this.fireImmunityTimer = fireImmunityTimer;
        }
    
        public int getFireImmunityTimer()
        {
            return fireImmunityTimer;
        }
    
        public void setAttackType(AttackTypes attackType)
        {
            this.attackType = attackType;
        }
    
        public AttackTypes getAttackType()
        {
            return attackType;
        }
    
        public void setFollowingEntity(Entity followingEntity)
        {
            if (followingEntity != null)
            {
                if (getFollowTask() == null)
                {
                    setFollowTask(new FollowTask(this));
                    World.submit(getFollowTask());
                }
            }
            else
            {
                if (getFollowTask() != null)
                {
                    getFollowTask().stop();
                    setFollowTask(null);
                }
            }
            this.followingEntity = followingEntity;
        }
    
        public Entity getFollowingEntity()
        {
            return followingEntity;
        }
    
        public enum AttackTypes
        {
            MELEE, RANGED, MAGIC, SPECIAL
        }
    
        public CombatState getCombatState()
        {
            return combateState;
        }
    
        public void setPoisonTask(Task poisonTask)
        {
            this.poisonTask = poisonTask;
        }
    
        public Task getPoisonTask()
        {
            return poisonTask;
        }
    
        public void setFollowTask(Task followTask)
        {
            this.followTask = followTask;
        }
    
        public Task getFollowTask()
        {
            return followTask;
        }
    
        public void setCanWalk(boolean canWalk)
        {
            this.canWalk = canWalk;
        }
    
        public boolean canWalk()
        {
            return canWalk;
        }
    
        public MovementHandler getMovementHandler()
        {
            return movementHandler;
        }
    
        public void setRegion(Region currentRegion)
        {
            this.currentRegion = currentRegion;
        }
    
        public Region getRegion()
        {
            return currentRegion;
        }
    
        public Position getLastKnownRegion()
        {
            return lastKnownRegion;
        }
    
        public void setLastKnownRegion(Position pos)
        {
            this.lastKnownRegion = pos;
        }
    }
    UpdateFlags:

    Code:
    package com.asgarniars.rs2.model;
    
    public class UpdateFlags
    {
    
        private boolean isUpdateRequired;
        private boolean chatUpdateRequired;
        private boolean isForceChatUpdate;
        private String forceChatMessage;
        private boolean graphicsUpdateRequired;
        private int graphicsId;
        private int graphicsDelay;
        private boolean animationUpdateRequired;
        private int animationId;
        private int animationDelay;
        private boolean entityFaceUpdate;
        private int entityFaceIndex = -1;
        private boolean faceToDirection;
        private Position face;
        private int faceDirection;
        private boolean hitUpdate;
        private boolean forceMovementUpdate;
        private boolean hitUpdate2;
        private int damage;
        private int damage2;
        private int hitType;
        private int hitType2;
        private int forceMovementEndX, forceMovementEndY, forceMovementSpeed1, forceMovementSpeed2, forceMovementDirection;
    
        /**
         * 
         * @param x The x you end to
         * @param y The y you end to
         * @param speed1 Speed1
         * @param speed2 Speed2
         * @param direction Dir you want face to
         */
        public void sendForceMovement(final int x, final int y, final int speed1, final int speed2, final int direction)
        {
            this.setForceMovementEndX(x);
            this.setForceMovementEndY(y);
            this.setForceMovementSpeed1(speed1);
            this.setForceMovementSpeed2(speed2);
            this.setForceMovementDirection(direction);
            forceMovementUpdate = true;
            isUpdateRequired = true;
        }
    
        public void resetForceMovement()
        {
            setForceMovementEndX(setForceMovementEndY(setForceMovementSpeed1(setForceMovementSpeed2(setForceMovementDirection(0)))));
        }
    
        public void sendGraphic(int graphicsId)
        {
            this.graphicsId = graphicsId;
            graphicsUpdateRequired = true;
            isUpdateRequired = true;
        }
    
        public void sendGraphic(UpdateFlags graphicsId)
        {
            graphicsUpdateRequired = true;
            isUpdateRequired = true;
        }
    
        public void sendGraphic(int graphicsId, int graphicsDelay)
        {
            this.graphicsId = graphicsId;
            this.graphicsDelay = graphicsDelay;
            graphicsUpdateRequired = true;
            isUpdateRequired = true;
        }
    
        public void sendGraphic(int graphicsId, int graphicsDelay, int height)
        {
            this.graphicsId = graphicsId;
            this.graphicsDelay = (65536 * height) + graphicsDelay;
            graphicsUpdateRequired = true;
            isUpdateRequired = true;
        }
    
        public void sendAnimation(int animationId)
        {
            this.animationId = animationId;
            this.animationDelay = 0;
            animationUpdateRequired = true;
            isUpdateRequired = true;
        }
    
        public void sendAnimation(UpdateFlags animation)
        {
            animationUpdateRequired = true;
            isUpdateRequired = true;
        }
    
        public void sendAnimation(int animationId, int animationDelay)
        {
            this.animationId = animationId;
            this.animationDelay = animationDelay;
            animationUpdateRequired = true;
            isUpdateRequired = true;
        }
    
        public void faceEntity(int entityFaceIndex)
        {
            this.entityFaceIndex = entityFaceIndex;
            entityFaceUpdate = true;
            isUpdateRequired = true;
        }
    
        public void sendFaceToDirection(Position face)
        {
            this.face = face;
            faceToDirection = true;
            isUpdateRequired = true;
        }
    
        public void sendHit(int damage, int hitType)
        {
            this.damage = damage;
            this.hitType = hitType;
            hitUpdate = true;
            isUpdateRequired = true;
        }
    
        public void sendForceMessage(String forceChatMessage)
        {
            this.forceChatMessage = forceChatMessage;
            isForceChatUpdate = true;
            isUpdateRequired = true;
        }
    
        public void reset()
        {
            isForceChatUpdate = false;
            chatUpdateRequired = false;
            graphicsUpdateRequired = false;
            animationUpdateRequired = false;
            entityFaceUpdate = false;
            faceToDirection = false;
            forceMovementUpdate = false;
            hitUpdate = false;
            hitUpdate2 = false;
        }
    
        public void setUpdateRequired(boolean isUpdateRequired)
        {
            this.isUpdateRequired = isUpdateRequired;
        }
    
        public boolean isUpdateRequired()
        {
            return isUpdateRequired;
        }
    
        public void setChatUpdateRequired(boolean chatUpdateRequired)
        {
            this.chatUpdateRequired = chatUpdateRequired;
        }
    
        public boolean isChatUpdateRequired()
        {
            return chatUpdateRequired;
        }
    
        public void setForceChatUpdate(boolean isForceChatUpdate)
        {
            this.isForceChatUpdate = isForceChatUpdate;
        }
    
        public boolean isForceChatUpdate()
        {
            return isForceChatUpdate;
        }
    
        public void setForceChatMessage(String forceChatMessage)
        {
            this.forceChatMessage = forceChatMessage;
        }
    
        public String getForceChatMessage()
        {
            return forceChatMessage;
        }
    
        public void setGraphicsUpdateRequired(boolean graphicsUpdateRequired)
        {
            this.graphicsUpdateRequired = graphicsUpdateRequired;
        }
    
        public boolean isGraphicsUpdateRequired()
        {
            return graphicsUpdateRequired;
        }
    
        public void setGraphicsId(int graphicsId)
        {
            this.graphicsId = graphicsId;
        }
    
        public int getGraphicsId()
        {
            return graphicsId;
        }
    
        public void setGraphicsDelay(int graphicsDelay)
        {
            this.graphicsDelay = graphicsDelay;
        }
    
        public int getGraphicsDelay()
        {
            return graphicsDelay;
        }
    
        public void setAnimationUpdateRequired(boolean animationUpdateRequired)
        {
            this.animationUpdateRequired = animationUpdateRequired;
        }
    
        public boolean isAnimationUpdateRequired()
        {
            return animationUpdateRequired;
        }
    
        public void setAnimationId(int animationId)
        {
            this.animationId = animationId;
        }
    
        public int getAnimationId()
        {
            return animationId;
        }
    
        public void setAnimationDelay(int animationDelay)
        {
            this.animationDelay = animationDelay;
        }
    
        public int getAnimationDelay()
        {
            return animationDelay;
        }
    
        public void setEntityFaceUpdate(boolean entityFaceUpdate)
        {
            this.entityFaceUpdate = entityFaceUpdate;
        }
    
        public boolean isEntityFaceUpdate()
        {
            return entityFaceUpdate;
        }
    
        public void setEntityFaceIndex(int entityFaceIndex)
        {
            this.entityFaceIndex = entityFaceIndex;
        }
    
        public int getEntityFaceIndex()
        {
            return entityFaceIndex;
        }
    
        public void setFaceToDirection(boolean faceToDirection)
        {
            this.faceToDirection = faceToDirection;
        }
    
        public boolean isFaceToDirection()
        {
            return faceToDirection;
        }
    
        public void setFace(Position face)
        {
            this.face = face;
        }
    
        public Position getFace()
        {
            return face;
        }
    
        public void setHitUpdate(boolean hitUpdate)
        {
            this.hitUpdate = hitUpdate;
        }
    
        public boolean isHitUpdate()
        {
            return hitUpdate;
        }
    
        public void setHitUpdate2(boolean hitUpdate2)
        {
            this.hitUpdate2 = hitUpdate2;
        }
    
        public boolean isForceMovementUpdateRequired()
        {
            return forceMovementUpdate;
        }
    
        public boolean isHitUpdate2()
        {
            return hitUpdate2;
        }
    
        public void setDamage(int damage)
        {
            this.damage = damage;
        }
    
        public int getDamage()
        {
            return damage;
        }
    
        public void setDamage2(int damage2)
        {
            this.damage2 = damage2;
        }
    
        public int getDamage2()
        {
            return damage2;
        }
    
        public void setHitType(int hitType)
        {
            this.hitType = hitType;
        }
    
        public int getHitType()
        {
            return hitType;
        }
    
        public void setHitType2(int hitType2)
        {
            this.hitType2 = hitType2;
        }
    
        public int getHitType2()
        {
            return hitType2;
        }
    
        public void setFaceDirection(int faceDirection)
        {
            this.faceDirection = faceDirection;
        }
    
        public int getFaceDirection()
        {
            return faceDirection;
        }
    
        public void setForceMovementEndX(int forceMovementEndX)
        {
            this.forceMovementEndX = forceMovementEndX;
        }
    
        public int getForceMovementEndX()
        {
            return forceMovementEndX;
        }
    
        public int setForceMovementEndY(int forceMovementEndY)
        {
            this.forceMovementEndY = forceMovementEndY;
            return forceMovementEndY;
        }
    
        public int getForceMovementEndY()
        {
            return forceMovementEndY;
        }
    
        public int setForceMovementSpeed1(int forceMovementSpeed1)
        {
            this.forceMovementSpeed1 = forceMovementSpeed1;
            return forceMovementSpeed1;
        }
    
        public int getForceMovementSpeed1()
        {
            return forceMovementSpeed1;
        }
    
        public int setForceMovementSpeed2(int forceMovementSpeed2)
        {
            this.forceMovementSpeed2 = forceMovementSpeed2;
            return forceMovementSpeed2;
        }
    
        public int getForceMovementSpeed2()
        {
            return forceMovementSpeed2;
        }
    
        public int setForceMovementDirection(int forceMovementDirection)
        {
            this.forceMovementDirection = forceMovementDirection;
            return forceMovementDirection;
        }
    
        public int getForceMovementDirection()
        {
            return forceMovementDirection;
        }
    
    }
    DedicatedReactor:

    Code:
    package com.asgarniars.rs2.network;
    
    import java.io.IOException;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    
    import com.asgarniars.rs2.Server;
    import com.asgarniars.rs2.model.players.Player;
    import com.asgarniars.rs2.network.packet.PacketManager;
    
    /**
     * A dedicated network reactor thread for low-latency network operations.
     * 
     * @author blakeman8192
     */
    public class DedicatedReactor extends Thread
    {
    
        /** The singleton instance. */
        private static DedicatedReactor instance;
    
        /** The selector instance. */
        private final Selector selector;
    
        /**
         * Instantiates a new {@code DedicatedReactor}.
         * 
         * @param selector The selector to perform readiness selection with
         */
        public DedicatedReactor(Selector selector)
        {
            this.selector = selector;
        }
    
        @Override
        public void run()
        {
            Thread.currentThread().setName("DedicatedReactor");
            while (!Thread.interrupted())
            {
                synchronized (DedicatedReactor.getInstance())
                {
                    // Guard lock - wait here for modifications to complete
                }
                try
                {
                    selector.select();
                    for (SelectionKey key : selector.selectedKeys())
                    {
                        if (key.isValid() && key.isAcceptable())
                        {
                            Server.accept(key);
                        }
                        else
                        {
                            Player player = (Player) key.attachment();
                            if (key.isValid() && key.isReadable())
                            {
                                PacketManager.handleIncomingData(player);
                            }
                            if (key.isValid() && key.isWritable())
                            {
                                PacketManager.flushOutBuffer(player);
                            }
                        }
                    }
                    selector.selectedKeys().clear();
                }
                catch (IOException ex)
                {
                    ex.printStackTrace();
                }
            }
        }
    
        /**
         * Gets the selector.
         * 
         * @return The selector
         */
        public Selector getSelector()
        {
            return selector;
        }
    
        /**
         * Gets the singleton instance.
         * 
         * @return The instance
         */
        public static DedicatedReactor getInstance()
        {
            return instance;
        }
    
        /**
         * Sets the singleton instance.
         * 
         * @param instance The instance to set
         * @throws IllegalStateException If the instance is not null
         */
        public static void setInstance(DedicatedReactor instance)
        {
            if (getInstance() != null)
            {
                throw new IllegalStateException("Instance already set");
            }
            DedicatedReactor.instance = instance;
        }
    
    }
    Code:
    package com.asgarniars.rs2;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Iterator;
    import java.util.concurrent.BlockingDeque;
    import java.util.concurrent.LinkedBlockingDeque;
    import java.util.logging.Logger;
    
    import com.asgarniars.rs2.content.minigame.impl.CastleWars;
    import com.asgarniars.rs2.content.minigame.impl.FightPits;
    import com.asgarniars.rs2.content.minigame.zombies.Zombies;
    import com.asgarniars.rs2.content.mta.AlchemistPlayground;
    import com.asgarniars.rs2.content.mta.Arena;
    import com.asgarniars.rs2.content.mta.EnchantmentChamber;
    import com.asgarniars.rs2.content.mta.EventRoom;
    import com.asgarniars.rs2.io.XStreamController;
    import com.asgarniars.rs2.model.World;
    import com.asgarniars.rs2.model.items.ItemManager;
    import com.asgarniars.rs2.model.players.Equipment;
    import com.asgarniars.rs2.model.players.Player;
    import com.asgarniars.rs2.network.DedicatedReactor;
    import com.asgarniars.rs2.network.packet.PacketManager;
    import com.asgarniars.rs2.task.Task;
    import com.asgarniars.rs2.task.TaskScheduler;
    import com.asgarniars.rs2.task.impl.ShopNormalizationTask;
    import com.asgarniars.rs2.util.ScriptManager;
    import com.asgarniars.rs2.util.ShutDownListener;
    import com.asgarniars.rs2.util.clip.ObjectDefinition;
    import com.asgarniars.rs2.util.clip.RegionClipping;
    
    /**
     * The main core of RuneSource.
     * 
     * @author blakeman8192
     * @author Joshua Barry
     */
    public class Server implements Runnable
    {
    
        /**
         * global access to the server.
         */
        private static Server singleton;
    
        /**
         * A simple logger.
         */
        private static final Logger logger = Logger.getAnonymousLogger();
    
        /**
         * A linked blocking deque.
         */
        private final BlockingDeque<Player> loginDeque = new LinkedBlockingDeque<Player>();
    
        /**
    	 * 
    	 */
        private static final BlockingDeque<Player> disconnectedPlayers = new LinkedBlockingDeque<Player>();
    
        private Selector selector;
        private InetSocketAddress address;
        private ServerSocketChannel channel;
        private static final TaskScheduler scheduler = new TaskScheduler();
    
        /**
         * Minigames
         */
        private CastleWars castleWars;
    
        private FightPits fightPits;
    	
    	//private Zombies zombies;
    
        private EventRoom playground;
    
        private EventRoom chamber;
    
        /**
         * The main method.
         * 
         * @param args
         */
        public static void main(String[] args)
        {
            setSingleton(new Server());
            new Thread(getSingleton()).start();
        }
    
        public static BlockingDeque<Player> getDisconnectedPlayers()
        {
            return disconnectedPlayers;
        }
    
        public void appendLoginDeque(Player player)
        {
            loginDeque.add(player);
        }
    
        @Override
        public void run()
        {
            try
            {
                long time = System.currentTimeMillis();
                Thread.currentThread().setName("GameEngine");
    
                address = new InetSocketAddress("", 43594);
                logger.info("Starting " + Constants.SERVER_NAME + " on " + address + "...");
    
                // Loading the shutdown hook
                Thread shutdownListener = new ShutDownListener();
                Runtime.getRuntime().addShutdownHook(shutdownListener);
                logger.info("Shutdown hook enabled...");
    
                PacketManager.loadPackets();
    
                // Load configuration.
                Equipment.sortEquipmentSlotDefinitions();
    
                // load all xstream related files.
                XStreamController.loadAllFiles();
    
                // load item spawns
                ItemManager.getInstance().spawnGroundItems();
    
                // load clipping stuff
                ObjectDefinition.load();
                RegionClipping.load();
    
                castleWars = new CastleWars();
                fightPits = new FightPits();
    			//zombies = new Zombies();
                playground = new AlchemistPlayground();
                chamber = new EnchantmentChamber();
                Arena.init(playground.getEventCycle(), chamber.getEventCycle());
    
                scheduler.submit(new ShopNormalizationTask());
    
                // Init world attributes - Akzu
                World.getInstance().initAttributes();
    
                // load script manager - Josh
                ScriptManager.getSingleton().loadScripts(Constants.SCRIPT_DIRECTORY);
    
                // ScriptManager.getSingleton().invokeWithFailTest("distribute",
                // 100);
    
                // Start up and get a'rollin!
                startup();
                logger.info("Online! Load time : " + (System.currentTimeMillis() - time) + "ms");
                scheduler.submit(new Task()
                {
    
                    @Override
                    protected void execute()
                    {
                        // long time = System.currentTimeMillis();
                        cycle();
                        // System.err.println("Task amt: " +
                        // scheduler.getTasks().size() + " Cycle: " +
                        // (System.currentTimeMillis() - time));
                    }
                });
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
        }
    
        /**
         * Starts the server up.
         * 
         * @throws IOException
         */
        private void startup() throws IOException
        {
    
            // Initialize the networking objects.
            selector = Selector.open();
            channel = ServerSocketChannel.open();
            DedicatedReactor.setInstance(new DedicatedReactor(Selector.open()));
            DedicatedReactor.getInstance().start();
    
            // ... and configure them!
            channel.configureBlocking(false);
            channel.socket().bind(address);
    
            synchronized (DedicatedReactor.getInstance())
            {
                DedicatedReactor.getInstance().getSelector().wakeup();
                channel.register(DedicatedReactor.getInstance().getSelector(), SelectionKey.OP_ACCEPT);
            }
        }
    
        /**
         * Accepts any incoming connections.
         * 
         * @throws IOException
         */
        public static void accept(SelectionKey key) throws IOException
        {
            ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
    
            // Accept the socket channel.
            SocketChannel channel = serverChannel.accept();
            if (channel == null)
            {
                return;
            }
    
            // Make sure we can allow this connection.
            if (!HostGateway.enter(channel.socket().getInetAddress().getHostAddress()))
            {
                channel.close();
                return;
            }
    
            // Set up the new connection.
            channel.configureBlocking(false);
            SelectionKey newKey = channel.register(key.selector(), SelectionKey.OP_READ);
            Player player = new Player(newKey);
            newKey.attach(player);
        }
    
        private void cycle()
        {
            int loggedIn = 0;
            while (!loginDeque.isEmpty() && loggedIn++ < 50)
            {
                Player player = loginDeque.poll();
                try
                {
                    player.finishLogin();
                }
                catch (Exception ex)
                {
                    ex.printStackTrace();
                    player.disconnect();
                }
            }
            try
            {
                selector.selectNow();
                for (SelectionKey selectionKey : selector.selectedKeys())
                {
                    if (selectionKey.isValid())
                    {
                        if (selectionKey.isReadable())
                        {
                            // Tell the client to handle the packet.
                            PacketManager.handleIncomingData((Player) selectionKey.attachment());
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
            try
            {
                World.process();
            }
            catch (Exception ex)
            {
                ex.printStackTrace();
            }
            synchronized (disconnectedPlayers)
            {
                for (Iterator<Player> players = disconnectedPlayers.iterator(); players.hasNext();)
                {
                    Player player = players.next();
                    if (player.isInCombat())
                    {
                        player.setAttribute("xLogTimer", System.currentTimeMillis());
                        continue;
                    }
                    else if (player.getAttribute("xLogTimer") != null && (System.currentTimeMillis() - (Long) player.getAttribute("xLogTimer")) < 10000)
                        continue;
    
                    player.logout();
                    players.remove();
                }
            }
        }
    
        /**
         * Set a singleton of this server model, if one has not been already set.
         * 
         * @param singleton an instance of the server model.
         */
        public static void setSingleton(Server singleton)
        {
            if (Server.singleton != null)
            {
                throw new IllegalStateException("Singleton already set!");
            }
            Server.singleton = singleton;
        }
    
        public static Server getSingleton()
        {
            return singleton;
        }
    
        public Selector getSelector()
        {
            return selector;
        }
    
        public static TaskScheduler getScheduler()
        {
            return scheduler;
        }
    
        public CastleWars getCastleWars()
        {
            return castleWars;
        }
    
        public FightPits getFightPits()
        {
            return fightPits;
        }
    	
    	/*public Zombies getZombies()
    	{
    		return zombies;
    	}*/
    
    }
    Reply With Quote  
     

  3. #13  
    Donator

    Jason's Avatar
    Join Date
    Aug 2009
    Posts
    6,092
    Thanks given
    2,402
    Thanks received
    2,823
    Rep Power
    4550
    Any code specifically relating to the NPC id? It's likely you're doing a unique operation for that specific mob.
    Reply With Quote  
     

  4. #14  
    Banned
    Join Date
    Oct 2017
    Posts
    31
    Thanks given
    3
    Thanks received
    1
    Rep Power
    0
    Quote Originally Posted by Jason View Post
    Any code specifically relating to the NPC id? It's likely you're doing a unique operation for that specific mob.
    When I do a file search in eclipse for 1593 (the npc id) I only get like 3 results and none of them are related to an npc. Even searching the x and the y coordinates separately doesn't show anything.

    Also I can kill other dogs of the same npc id without the bug occuring, just not the one that spawns at (2676, 9556).
    Reply With Quote  
     

  5. #15  
    Registered Member Rememberm3's Avatar
    Join Date
    Aug 2013
    Posts
    1,716
    Thanks given
    56
    Thanks received
    108
    Rep Power
    129
    Quote Originally Posted by Oprah Rich View Post
    When I do a file search in eclipse for 1593 (the npc id) I only get like 3 results and none of them are related to an npc. Even searching the x and the y coordinates separately doesn't show anything.

    Also I can kill other dogs of the same npc id without the bug occuring, just not the one that spawns at (2676, 9556).
    What happens when you remove that npc from the spawn list and kill the npc that is next on the list? If that npc also gives that problem, then it probably has something to do with that specific spawn
    Attached image
    Reply With Quote  
     

  6. #16  
    Banned
    Join Date
    Oct 2017
    Posts
    31
    Thanks given
    3
    Thanks received
    1
    Rep Power
    0
    Quote Originally Posted by RememberM3 View Post
    What happens when you remove that npc from the spawn list and kill the npc that is next on the list? If that npc also gives that problem, then it probably has something to do with that specific spawn
    Well that made me realize the NPCID has nothing to do with it. I changed it to 82 (lesser demon) and the same thing happened. Does anyone see anything wrong with the npcdef?

    Code:
    	<npc>
    		<npcId>82</npcId>
    		<spawnPosition>
    			<x>2676</x>
    			<y>9556</y>
    			<z>0</z>
    		</spawnPosition>
    		<maxWalk>
    			<x>0</x>
    			<y>0</y>
    			<z>0</z>
    		</maxWalk>
    	</npc>
    This is one that is not bugged:

    Code:
    	<npc>
    		<npcId>1593</npcId>
    		<spawnPosition>
    			<x>2679</x>
    			<y>9559</y>
    			<z>0</z>
    		</spawnPosition>
    		<maxWalk>
    			<x>2</x>
    			<y>4</y>
    			<z>0</z>
    		</maxWalk>
    	</npc>
    Reply With Quote  
     

  7. #17  
    Registered Member Rememberm3's Avatar
    Join Date
    Aug 2013
    Posts
    1,716
    Thanks given
    56
    Thanks received
    108
    Rep Power
    129
    Quote Originally Posted by Oprah Rich View Post
    Well that made me realize the NPCID has nothing to do with it. I changed it to 82 (lesser demon) and the same thing happened. Does anyone see anything wrong with the npcdef?

    Code:
    <npc>
    <npcId>82</npcId>
    <spawnPosition>
    <x>2676</x>
    <y>9556</y>
    <z>0</z>
    </spawnPosition>
    <maxWalk>
    <x>0</x>
    <y>0</y>
    <z>0</z>
    </maxWalk>
    </npc>
    Maybe it has to do with that instance of an NPC
    Attached image
    Reply With Quote  
     

  8. #18  
    Banned
    Join Date
    Oct 2017
    Posts
    31
    Thanks given
    3
    Thanks received
    1
    Rep Power
    0
    Quote Originally Posted by RememberM3 View Post
    Maybe it has to do with that instance of an NPC
    But how, if all of the other npcs are working? Where should I look to debug it?
    Reply With Quote  
     

  9. #19  
    Community Veteran


    Arch337's Avatar
    Join Date
    Sep 2008
    Posts
    2,950
    Thanks given
    210
    Thanks received
    349
    Rep Power
    1376
    Quote Originally Posted by Oprah Rich View Post
    But how, if all of the other npcs are working? Where should I look to debug it?
    Try and remove the spawn to see if the spawn above corrupt too, if it does there is something in your code that makes the last spawn corrupt.
    If it does not, you might need to extend the limit on your spawns.


    "A fail act is something you do regular, but a dumb act is something you can learn from"
    Spoiler for Problem?:
    Reply With Quote  
     

  10. #20  
    Banned
    Join Date
    Oct 2017
    Posts
    31
    Thanks given
    3
    Thanks received
    1
    Rep Power
    0
    Quote Originally Posted by arch337 View Post
    Try and remove the spawn to see if the spawn above corrupt too, if it does there is something in your code that makes the last spawn corrupt.
    If it does not, you might need to extend the limit on your spawns.
    The spawn is located near the middle of the file. When I comment the spawn that bugs out, the spawns directly above and below it in the spawns file don't bug when I kill them.

    Update: I moved the spawn one position west away from the wall, and it doesn't bug now... But I'd still like to know why this happens.
    Reply With Quote  
     

Page 2 of 3 FirstFirst 123 LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Server Offline nobody can login
    By Billanderson in forum Help
    Replies: 4
    Last Post: 03-10-2012, 11:57 PM
  2. Replies: 8
    Last Post: 02-01-2012, 04:15 PM
  3. Replies: 4
    Last Post: 07-15-2011, 09:12 AM
  4. Replies: 0
    Last Post: 12-19-2010, 05:05 PM
  5. [508] Change login threshold (how long your logged in)
    By Thedudewithnoname in forum Help
    Replies: 0
    Last Post: 07-12-2009, 11:01 PM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •