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.block;
019
020import net.tridentsdk.base.Position;
021import net.tridentsdk.entity.Entity;
022import net.tridentsdk.entity.block.ArmorStand;
023import net.tridentsdk.entity.block.SlotProperties;
024import net.tridentsdk.entity.living.Player;
025import net.tridentsdk.entity.types.EntityType;
026import net.tridentsdk.event.entity.EntityDamageEvent;
027import net.tridentsdk.inventory.Item;
028import net.tridentsdk.server.data.MetadataType;
029import net.tridentsdk.server.data.ProtocolMetadata;
030import net.tridentsdk.server.entity.TridentLivingEntity;
031import net.tridentsdk.util.PartRotation;
032
033import java.util.UUID;
034
035public class TridentArmorStand extends TridentLivingEntity implements ArmorStand {
036    private final SlotProperties properties;
037    /*
038     * Data as represented in protocol meta, encoded as such to save space in memory
039     *
040     * At BitMask 1, it determines if its a small armor stand or not.
041     * At BitMask 2, it states if gravity applies to this armor stand
042     * At BitMask 4, it states if the armor stand "has" arms
043     * At BitMask 8, it states if the armor stand "has" a baseplate
044     */
045    private volatile byte data;
046    private final Item[] armor;
047    private final PartRotation[] pose;
048
049    public TridentArmorStand(UUID id, Position spawnLocation, SlotProperties properties) {
050        super(id, spawnLocation);
051
052        this.properties = properties;
053        this.data = (byte) 14;
054        this.armor = new Item[4];
055        this.pose = new PartRotation[6];
056    }
057
058    @Override
059    protected void doEncodeMeta(ProtocolMetadata protocolMeta) {
060        protocolMeta.setMeta(10, MetadataType.BYTE, data);
061
062        for (int i = 1; i <= 6; i++) {
063            protocolMeta.setMeta(10 + i, MetadataType.PYR, pose[i - 1].asVector());
064        }
065    }
066
067    @Override
068    public SlotProperties slotProperties() {
069        return properties;
070    }
071
072    @Override
073    public boolean isInvisible() {
074        return false;
075    }
076
077    @Override
078    public boolean displayBaseplate() {
079        return (data & 8) == 8;
080    }
081
082    @Override
083    public boolean displayArms() {
084        return (data & 4) == 4;
085    }
086
087    @Override
088    public boolean useGravity() {
089        return (data & 2) == 2;
090    }
091
092    @Override
093    public PartRotation[] pose() {
094        return pose;
095    }
096
097    @Override
098    public boolean isTiny() {
099        return (data & 1) == 1;
100    }
101
102    @Override
103    public Item[] equipment() {
104        return armor;
105    }
106
107    @Override
108    public void setEquipment(final Item[] stack) {
109        System.arraycopy(stack, 0, armor, 0, (stack.length > 4) ? 4 : stack.length);
110    }
111
112    @Override
113    public void hide(Entity entity) {
114    }
115
116    @Override
117    public void show(Entity entity) {
118    }
119
120    @Override
121    public EntityDamageEvent lastDamageEvent() {
122        return null;
123    }
124
125    @Override
126    public Player lastPlayerDamager() {
127        return null;
128    }
129
130    @Override
131    public EntityType type() {
132        return EntityType.ARMOR_STAND;
133    }
134}