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.entity;
019
020import net.tridentsdk.base.Position;
021import net.tridentsdk.entity.traits.WindowHolder;
022import net.tridentsdk.inventory.Inventory;
023import net.tridentsdk.inventory.Item;
024import net.tridentsdk.meta.nbt.CompoundTag;
025import net.tridentsdk.meta.nbt.ListTag;
026import net.tridentsdk.meta.nbt.NBTSerializer;
027import net.tridentsdk.meta.nbt.NBTTag;
028import net.tridentsdk.server.data.Slot;
029import net.tridentsdk.server.inventory.TridentInventory;
030import net.tridentsdk.server.packets.play.out.PacketPlayOutEntityEquipment;
031import net.tridentsdk.server.player.TridentPlayer;
032
033import java.util.UUID;
034
035/**
036 * An entity that is able to hold an inventory
037 *
038 * @author The TridentSDK Team
039 */
040public abstract class TridentInventoryHolder extends TridentLivingEntity implements WindowHolder {
041    protected volatile TridentInventory inventory;
042    private volatile int selectedSlot = 0;
043
044    /**
045     * Inherits constructor from {@link TridentLivingEntity}
046     */
047    public TridentInventoryHolder(UUID id, Position spawnLocation) {
048        super(id, spawnLocation);
049    }
050
051    @Override
052    public TridentInventory window() {
053        return this.inventory;
054    }
055
056    @Override
057    public Item heldItem() {
058        return inventory.itemAt(TridentPlayer.SLOT_OFFSET + selectedSlot);
059    }
060
061    @Override
062    public void setHeldItem(Item item) {
063        inventory.setSlot(TridentPlayer.SLOT_OFFSET + selectedSlot, item);
064        PacketPlayOutEntityEquipment packet = new PacketPlayOutEntityEquipment();
065        packet.set("entityId", entityId());
066        packet.set("slot", (short) 0);
067        packet.set("item", new Slot(item));
068
069        TridentPlayer.sendFiltered(packet, (p) -> !p.equals(TridentInventoryHolder.this));
070    }
071
072    public void setSelectedSlot(int selectedSlot) {
073        this.selectedSlot = selectedSlot;
074    }
075
076    @Override
077    public void load(CompoundTag tag) {
078        if (this instanceof TridentPlayer) {
079            return;
080        }
081
082        ListTag equipment = tag.getTagAs("Equipment");
083        int index = 0;
084
085        for (NBTTag t : equipment.listTags()) {
086            inventory.setSlot(index++, NBTSerializer.deserialize(Slot.class,
087                    t.asType(CompoundTag.class)).item());
088        }
089    }
090
091    public int selectedSlot(){
092        return selectedSlot;
093    }
094}