001/*
002 * Trident - A Multithreaded Server Alternative
003 * Copyright 2014 The TridentSDK Team
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package net.tridentsdk.server.packets.play.in;
019
020import io.netty.buffer.ByteBuf;
021import net.tridentsdk.event.entity.PlayerToggleSprintEvent;
022import net.tridentsdk.server.event.EventProcessor;
023import net.tridentsdk.server.netty.ClientConnection;
024import net.tridentsdk.server.netty.Codec;
025import net.tridentsdk.server.netty.packet.InPacket;
026import net.tridentsdk.server.netty.packet.Packet;
027import net.tridentsdk.server.player.PlayerConnection;
028import net.tridentsdk.server.player.TridentPlayer;
029import net.tridentsdk.util.TridentLogger;
030
031/**
032 * Sent by the client when doing any of the action types below.  Note: Client will send ActionType#START_SPRINTING
033 * when "Leave bed" is clicked
034 *
035 * @see ActionType
036 */
037public class PacketPlayInEntityAction extends InPacket {
038
039    /**
040     * Entity ActionType
041     *
042     * @see ActionType
043     */
044    protected ActionType type;
045    /**
046     * Horse jump boost, mentioned if not ActionType#ON_HOURSE
047     *
048     * @see ActionType#ON_HORSE
049     */
050    protected int jumpBoost;
051
052    @Override
053    public int id() {
054        return 0x14;
055    }
056
057    @Override
058    public Packet decode(ByteBuf buf) {
059        Codec.readVarInt32(buf); // ignore entity id as its the player's
060        this.type = ActionType.action((int) buf.readUnsignedByte());
061        this.jumpBoost = Codec.readVarInt32(buf);
062
063        return this;
064    }
065
066    @Override
067    public void handleReceived(ClientConnection connection) {
068        TridentPlayer player = ((PlayerConnection) connection).player();
069
070        switch(type) {
071            case START_SPRINTING:
072            case STOP_SPRINTING:
073                PlayerToggleSprintEvent event = EventProcessor.fire(new PlayerToggleSprintEvent(player,
074                        type == ActionType.START_SPRINTING));
075
076                if(!event.isIgnored()) {
077                    player.setSprinting(event.sprintOn());
078                }
079                break;
080
081            case CROUCH:
082                player.setCrouching(true);
083                break;
084
085            case UN_CROUCH:
086                player.setCrouching(false);
087                break;
088        }
089    }
090
091    public enum ActionType {
092        CROUCH(0),
093        UN_CROUCH(1),
094        LEAVE_BED(2),
095        START_SPRINTING(3),
096        STOP_SPRINTING(4),
097        ON_HORSE(5),
098        OPEN_INVENTORY(6);
099
100        /**
101         * Id used to identify the action type
102         */
103        protected final int id;
104
105        ActionType(int id) {
106            this.id = id;
107        }
108
109        public static ActionType action(int id) {
110            for (ActionType type : ActionType.values()) {
111                if (type.id == id)
112                    return type;
113            }
114
115            TridentLogger.get().error(new IllegalArgumentException(id + " is not a valid ActionType id!"));
116            return null;
117        }
118
119        public int getId() {
120            return this.id;
121        }
122    }
123}