Package de.kumpelblase2.remoteentities.entities

Source Code of de.kumpelblase2.remoteentities.entities.RemoteBaseEntity

package de.kumpelblase2.remoteentities.entities;

import java.util.*;
import net.minecraft.server.v1_7_R1.*;
import net.minecraft.server.v1_7_R1.World;
import org.bukkit.*;
import org.bukkit.Chunk;
import org.bukkit.block.BlockFace;
import org.bukkit.craftbukkit.v1_7_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_7_R1.entity.CraftLivingEntity;
import org.bukkit.craftbukkit.v1_7_R1.inventory.CraftInventoryPlayer;
import org.bukkit.entity.*;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.Inventory;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import de.kumpelblase2.remoteentities.EntityManager;
import de.kumpelblase2.remoteentities.api.*;
import de.kumpelblase2.remoteentities.api.events.*;
import de.kumpelblase2.remoteentities.api.features.*;
import de.kumpelblase2.remoteentities.api.thinking.*;
import de.kumpelblase2.remoteentities.nms.RemoteSpeedModifier;
import de.kumpelblase2.remoteentities.persistence.ISingleEntitySerializer;
import de.kumpelblase2.remoteentities.utilities.*;

public abstract class RemoteBaseEntity<T extends LivingEntity> implements RemoteEntity
{
  private final int m_id;
  protected Mind m_mind;
  protected FeatureSet m_features;
  protected boolean m_isStationary = false;
  protected final RemoteEntityType m_type;
  protected EntityLiving m_entity;
  protected boolean m_isPushable = true;
  protected final EntityManager m_manager;
  protected Location m_unloadedLocation;
  protected String m_nameToSpawnWith;
  protected int m_lastBouncedId;
  protected long m_lastBouncedTime;
  protected double m_speed = -1;
  protected AttributeModifier m_speedModifier;
  protected Map<EntitySound, Object> m_sounds;

  public RemoteBaseEntity(int inID, RemoteEntityType inType, EntityManager inManager)
  {
    this.m_id = inID;
    this.m_mind = new Mind(this);
    this.m_features = new FeatureSet(this);
    this.m_type = inType;
    this.m_manager = inManager;
    this.m_sounds = new EnumMap<EntitySound, Object>(EntitySound.class);
    this.setupSounds();
  }

  @Override
  public int getID()
  {
    return this.m_id;
  }

  @Override
  public EntityManager getManager()
  {
    return this.m_manager;
  }

  @Override
  public Mind getMind()
  {
    return this.m_mind;
  }

  @Override
  public FeatureSet getFeatures()
  {
    return this.m_features;
  }

  @Override
  public void setStationary(boolean inState)
  {
    this.setStationary(inState, false);
  }

  @Override
  public void setStationary(boolean inState, boolean inKeepHeadFixed)
  {
    this.m_isStationary = inState;
    if(!inKeepHeadFixed)
    {
      this.getMind().resetFixedYaw();
      this.getMind().resetFixedPitch();
    }
  }

  @Override
  public boolean isStationary()
  {
    return this.m_isStationary;
  }

  @Override
  public RemoteEntityType getType()
  {
    return this.m_type;
  }

  @Override
  public EntityLiving getHandle()
  {
    return this.m_entity;
  }

  @Override
  public T getBukkitEntity()
  {
    if(this.isSpawned())
      return (T)this.m_entity.getBukkitEntity();

    return null;
  }

  @Override
  public boolean move(Location inLocation)
  {
    return this.move(inLocation, this.getSpeed());
  }

  @Override
  public boolean move(Location inLocation, double inSpeed)
  {
    if(!this.isSpawned() || this.m_isStationary || NMSUtil.isOnLeash(this.getHandle()))
      return false;

    if(!NMSUtil.getNavigation(this.m_entity).a(inLocation.getX(), inLocation.getY(), inLocation.getZ(), inSpeed))
    {
      PathEntity path = this.m_entity.world.a(this.getHandle(), MathHelper.floor(inLocation.getX()), (int) inLocation.getY(), MathHelper.floor(inLocation.getZ()), (float)this.getPathfindingRange(), true, false, false, true);
      return this.moveWithPath(path, inSpeed);
    }
    return true;
  }

  @Override
  public boolean move(LivingEntity inEntity)
  {
    return this.move(inEntity, this.getSpeed());
  }

  @Override
  public boolean move(LivingEntity inEntity, double inSpeed)
  {
    if(!this.isSpawned() || this.m_isStationary || NMSUtil.isOnLeash(this.getHandle()))
      return false;

    EntityLiving handle = ((CraftLivingEntity)inEntity).getHandle();
    if(handle == this.m_entity)
      return true;

    if(!NMSUtil.getNavigation(this.m_entity).a(handle, inSpeed))
    {
      PathEntity path = this.m_entity.world.findPath(this.getHandle(), handle, (float)this.getPathfindingRange(), true, false, false, true);
      return this.moveWithPath(path, inSpeed);
    }
    return true;
  }

  @Override
  public void setYaw(float inYaw)
  {
    this.setYaw(inYaw, false);
  }

  @Override
  public void setYaw(float inYaw, boolean inRotate)
  {
    if(!this.isSpawned())
      return;

    Location newLoc = this.getBukkitEntity().getLocation();
    newLoc.setYaw(inYaw);
    if(inRotate)
      this.move(newLoc);
    else
    {
      if(this.isStationary())
        this.getMind().fixYawAt(inYaw);

      this.m_entity.yaw = inYaw;
      this.m_entity.aO = inYaw;
    }
  }

  @Override
  public void setPitch(float inPitch)
  {
    if(!this.isSpawned())
      return;

    if(this.isStationary())
      this.getMind().fixPitchAt(inPitch);

    this.m_entity.pitch = inPitch;
  }

  @Override
  public void setHeadYaw(float inHeadYaw)
  {
    if(!this.isSpawned())
      return;

    if(this.isStationary())
      this.getMind().fixHeadYawAt(inHeadYaw);

    this.m_entity.aP = inHeadYaw;
    this.m_entity.aQ = inHeadYaw;
    if(!(this.m_entity instanceof EntityHuman))
      this.m_entity.aN = inHeadYaw;
  }

  @Override
  public void lookAt(Location inLocation)
  {
    if(!this.isSpawned())
      return;

    NMSUtil.getControllerLook(this.m_entity).a(inLocation.getX(), inLocation.getY(), inLocation.getZ(), 10, NMSUtil.getMaxHeadRotation(this.m_entity));
  }

  @Override
  public void lookAt(Entity inEntity)
  {
    if(!this.isSpawned())
      return;

    NMSUtil.getControllerLook(this.m_entity).a(((CraftEntity)inEntity).getHandle(), 10, NMSUtil.getMaxHeadRotation(this.m_entity));
  }

  @Override
  public void stopMoving()
  {
    if(this.m_entity == null)
      return;

    NMSUtil.getNavigation(this.m_entity).h();
  }

  @Override
  public void teleport(Location inLocation)
  {
    if(this.m_entity == null)
      return;

    this.getBukkitEntity().teleport(inLocation);
  }

  @Override
  public void spawn(Location inLocation)
  {
    if(this.isSpawned())
      return;

    RemoteEntitySpawnEvent event = new RemoteEntitySpawnEvent(this, inLocation);
    Bukkit.getPluginManager().callEvent(event);
    if(event.isCancelled())
      return;

    inLocation = event.getSpawnLocation();

    try
    {
      EntityTypesEntry entry = EntityTypesEntry.fromEntity(this.getNativeEntityName());
      ReflectionUtil.registerEntityType(this.getType().getEntityClass(), this.getNativeEntityName(), entry.getID());
      WorldServer worldServer = ((CraftWorld)inLocation.getWorld()).getHandle();
      this.m_entity = this.m_type.getEntityClass().getConstructor(World.class, RemoteEntity.class).newInstance(worldServer, this);
      this.m_entity.setPositionRotation(inLocation.getX(), inLocation.getY(), inLocation.getZ(), inLocation.getYaw(), inLocation.getPitch());
      worldServer.addEntity(this.m_entity, SpawnReason.CUSTOM);
      entry.restore();
      LivingEntity bukkitEntity = this.getBukkitEntity();
      if(bukkitEntity != null)
      {
        bukkitEntity.setMetadata("remoteentity", new FixedMetadataValue(this.m_manager.getPlugin(), this));
        if(this.getName() != null && this.getName().length() > 0)
        {
          bukkitEntity.setCustomName(this.getName());
          bukkitEntity.setCustomNameVisible(true);
        }
        bukkitEntity.setRemoveWhenFarAway(false);
      }

      this.setHeadYaw(inLocation.getYaw());
      this.setYaw(inLocation.getYaw());
      if(!inLocation.getBlock().getRelative(BlockFace.DOWN).isEmpty())
        this.m_entity.onGround = true;

      if(this.m_speed != -1)
        this.setSpeed(this.m_speed);
      else
        this.setSpeed(0.7d);

      if(this.m_speedModifier != null)
      {
        this.addSpeedModifier(this.m_speedModifier.d(), (this.m_speedModifier.c() == 0));
        this.m_speedModifier = null;
      }
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
    this.m_unloadedLocation = null;
  }

  @Override
  public void spawn(Location inLocation, boolean inForce)
  {
    Chunk c = inLocation.getChunk();
    if(c == null)
      return;

    if(!c.isLoaded() && inForce)
    {
      if(!c.load())
        return;
    }

    this.spawn(inLocation);
  }

  @Override
  public boolean despawn(DespawnReason inReason)
  {
    RemoteEntityDespawnEvent event = new RemoteEntityDespawnEvent(this, inReason);
    Bukkit.getPluginManager().callEvent(event);
    if(event.isCancelled() && inReason != DespawnReason.PLUGIN_DISABLE)
      return false;

    if(inReason != DespawnReason.CHUNK_UNLOAD && inReason != DespawnReason.NAME_CHANGE)
    {
      for(Behavior behaviour : this.getMind().getBehaviours())
      {
        behaviour.onRemove();
      }

      this.getMind().clearBehaviours();
    }
    else
      this.m_unloadedLocation = (this.getBukkitEntity() != null ? this.getBukkitEntity().getLocation() : null);

    if(this.getBukkitEntity() != null)
      this.getBukkitEntity().remove();
    this.m_entity = null;
    return true;
  }

  @Override
  public boolean isSpawned()
  {
    return this.m_entity != null;
  }

  @Override
  public boolean isPushable()
  {
    return this.m_isPushable;
  }

  @Override
  public void setPushable(boolean inState)
  {
    this.m_isPushable = inState;
  }

  @Override
  public double getSpeed()
  {
    if(this.m_entity == null)
    {
      if(this.m_speed != -1)
        return this.m_speed;
      else
        return GenericAttributes.d.b();
    }
    else
      return this.m_entity.getAttributeInstance(GenericAttributes.d).getValue();
  }

  @Override
  public void setSpeed(double inSpeed)
  {
    if(this.m_entity == null)
      this.m_speed = inSpeed;
    else
      this.m_entity.getAttributeInstance(GenericAttributes.d).setValue(inSpeed);
  }

  @Override
  public void removeSpeedModifier()
  {
    if(this.m_entity != null)
      this.m_entity.getAttributeInstance(GenericAttributes.d).b(new RemoteSpeedModifier(0, false));
  }

  @Override
  public void addSpeedModifier(double inAmount, boolean inAdditive)
  {
    RemoteSpeedModifier modifier = new RemoteSpeedModifier(inAmount, inAdditive);
    if(this.m_entity == null)
      this.m_speedModifier = modifier;
    else
    {
      AttributeInstance instance = this.m_entity.getAttributeInstance(GenericAttributes.d);
      instance.b(modifier);
      instance.a(modifier);
    }
  }

  @Override
  public void setPathfindingRange(double inRange)
  {
    this.m_entity.getAttributeInstance(GenericAttributes.b).setValue(inRange);
  }

  @Override
  public double getPathfindingRange()
  {
    return this.m_entity.getAttributeInstance(GenericAttributes.b).getValue();
  }

  /**
   * Sets the path of the entity with a given speed.
   *
   * @param inPath  Path to follow
   * @param inSpeed  Speed to walk with
   * @return      true if it could use the path, false if not
   */
  public boolean moveWithPath(PathEntity inPath, double inSpeed)
  {
    if(this.m_entity == null || inPath == null || this.m_isStationary)
      return false;

    if(this.m_entity instanceof EntityCreature)
      ((EntityCreature)this.m_entity).setPathEntity(inPath);

    return NMSUtil.getNavigation(this.m_entity).a(inPath, inSpeed);
  }

  /**
   * Copies the inventory from the given player to the inventory of this entity.
   *
   * @param inPlayer  Player to copy inventory from
   */
  public void copyInventory(Player inPlayer)
  {
    this.copyInventory(inPlayer, false);
  }

  /**
   * Copies the inventory from the given player to the inventory of this entity.
   *
   * @param inPlayer      Player to copy inventory from
   * @param inIgnoreArmor    If armor should not be copied or if it should
   */
  public void copyInventory(Player inPlayer, boolean inIgnoreArmor)
  {
    this.copyInventory(inPlayer.getInventory());
    EntityEquipment equip = this.getBukkitEntity().getEquipment();
    if(!inIgnoreArmor)
      equip.setArmorContents(inPlayer.getInventory().getArmorContents());

    if(this.getInventory() instanceof CraftInventoryPlayer)
      ((CraftInventoryPlayer)this.getInventory()).setHeldItemSlot(inPlayer.getInventory().getHeldItemSlot());
    else
      equip.setItemInHand(inPlayer.getItemInHand());
  }

  /**
   * Copies the the contents of the given inventory to the inventory of this entity.
   *
   * @param inInventory  Inventory to copy from.
   */
  public void copyInventory(Inventory inInventory)
  {
    if(this.getInventory() != null)
      this.getInventory().setContents(inInventory.getContents());
  }

  /**
   * Gets the inventory of this entity.
   *
   * @return  Inventory
   */
  public Inventory getInventory()
  {
    if(this.getHandle() instanceof RemoteEntityHandle)
      return ((RemoteEntityHandle)this.getHandle()).getInventory();

    if(!this.getFeatures().hasFeature(InventoryFeature.class))
      return null;

    return this.getFeatures().getFeature(InventoryFeature.class).getInventory();
  }

  @Override
  public boolean save()
  {
    if(this.getManager().getSerializer() instanceof ISingleEntitySerializer)
    {
      ISingleEntitySerializer serializer = (ISingleEntitySerializer)this.getManager().getSerializer();
      serializer.save(serializer.prepare(this));
      return true;
    }

    return false;
  }

  @Override
  public String getSound(EntitySound inType)
  {
    Object sound = this.m_sounds.get(inType);
    if(sound instanceof String)
      return (String)sound;
    else
    {
      Random generator = new Random();
      Object[] values = this.m_sounds.values().toArray();
      return (String)values[generator.nextInt(values.length)];
    }
  }

  @SuppressWarnings("unchecked")
  @Override
  public String getSound(EntitySound inType, String inKey)
  {
    Object sounds = this.m_sounds.get(inType);
    if(!(sounds instanceof Map))
      return null;

    return ((Map<String, String>)sounds).get(inKey);
  }

  @SuppressWarnings("unchecked")
  @Override
  public Map<String, String> getSounds(EntitySound inType)
  {
    Object sounds = this.m_sounds.get(inType);
    if(sounds instanceof String)
    {
      Map<String, String> map = new HashMap<String, String>();
      map.put("default", (String)sounds);
      return map;
    }
    else
    {
      return (Map<String, String>)sounds;
    }
  }

  @Override
  public boolean hasSound(EntitySound inType)
  {
    return this.getSound(inType) != null;
  }

  @Override
  public boolean hasSound(EntitySound inType, String inKey)
  {
    return this.getSound(inType, inKey) != null;
  }

  @Override
  public void setSound(EntitySound inType, String inSound)
  {
    this.m_sounds.put(inType, inSound);
  }

  @SuppressWarnings("unchecked")
  @Override
  public void setSound(EntitySound inType, String inKey, String inSound)
  {
    Object sounds = this.m_sounds.get(inType);
    if(sounds instanceof String)
    {
      Map<String, String> map = new HashMap<String, String>();
      map.put(inKey, inSound);
      this.m_sounds.put(inType, map);
    }
    else
      ((Map<String, String>)sounds).put(inKey, inSound);
  }

  @Override
  public void setSounds(EntitySound inType, Map<String, String> inSounds)
  {
    this.m_sounds.put(inType, inSounds);
  }

  public String getName()
  {
    if(!this.isSpawned())
      return this.m_nameToSpawnWith;

    return this.getBukkitEntity().getCustomName();
  }

  public void setName(String inName)
  {
    if(this.isSpawned())
    {
      if(inName == null)
      {
        this.getBukkitEntity().setCustomNameVisible(false);
        this.getBukkitEntity().setCustomName(null);
      }
      else
      {
        this.getBukkitEntity().setCustomNameVisible(true);
        this.getBukkitEntity().setCustomName(inName);
      }
    }
    else
      this.m_nameToSpawnWith = inName;
  }

  /**
   * Gets the location the entity was last unloaded.
   *
   * @return  unloading location
   */
  public Location getUnloadedLocation()
  {
    return this.m_unloadedLocation;
  }

  Vector onPush(double inX, double inY, double inZ)
  {
    RemoteEntityPushEvent event = new RemoteEntityPushEvent(this, new Vector(inX, inY, inZ));
    event.setCancelled(!this.isPushable() || this.isStationary());
    Bukkit.getPluginManager().callEvent(event);

    if(!event.isCancelled())
      return event.getVelocity();
    else
      return null;
  }

  boolean onCollide(Entity inEntity)
  {
    if(this.getMind() == null)
      return true;

    if(this.m_lastBouncedId != inEntity.getEntityId() || System.currentTimeMillis() - this.m_lastBouncedTime > 1000)
    {
      RemoteEntityTouchEvent event = new RemoteEntityTouchEvent(this, inEntity);
      Bukkit.getPluginManager().callEvent(event);
      if(event.isCancelled())
        return false;

      if(inEntity instanceof Player && this.getMind().canFeel() && this.getMind().hasBehavior(TouchBehavior.class))
      {
        if(inEntity.getLocation().distanceSquared(getBukkitEntity().getLocation()) <= 1)
          this.getMind().getBehavior(TouchBehavior.class).onTouch((Player)inEntity);
      }
    }

    this.m_lastBouncedTime = System.currentTimeMillis();
    this.m_lastBouncedId = inEntity.getEntityId();
    return true;
  }

  void onDeath()
  {
    if(this.getMind().hasBehavior(DeathBehavior.class))
      this.getMind().getBehavior(DeathBehavior.class).onDeath();

    this.getMind().clearMovementDesires();
    this.getMind().clearTargetingDesires();
  }

  boolean onInteract(Player inEntity)
  {
    if(this.getFeatures().hasFeature(TradingFeature.class))
    {
      TradingFeature feature = this.getFeatures().getFeature(TradingFeature.class);
      feature.openFor(inEntity);
      return false;
    }

    if(this.getMind() == null)
      return true;

    if(this.getMind().canFeel())
    {
      RemoteEntityInteractEvent event = new RemoteEntityInteractEvent(this, inEntity);
      Bukkit.getPluginManager().callEvent(event);
      if(event.isCancelled())
        return false;

      if(this.getMind().hasBehavior(InteractBehavior.class))
        this.getMind().getBehavior(InteractBehavior.class).onInteract(inEntity);
    }
    return true;
  }

  protected abstract void setupSounds();
}
TOP

Related Classes of de.kumpelblase2.remoteentities.entities.RemoteBaseEntity

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.