package net.aufdemrand.denizen.npc.traits;
import net.aufdemrand.denizen.nms.interfaces.FakeArrow;
import net.aufdemrand.denizen.utilities.DenizenAPI;
import net.aufdemrand.denizen.utilities.Utilities;
import net.aufdemrand.denizen.utilities.entity.DenizenEntityType;
import net.aufdemrand.denizencore.objects.Mechanism;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.vehicle.VehicleExitEvent;
import java.util.ArrayList;
public class SittingTrait extends Trait implements Listener {
@Persist("sitting")
private boolean sitting = false;
@Persist("chair location")
private Location chairLocation = null;
@Override
public void run() {
if (!npc.isSpawned() || chairLocation == null) {
return;
}
if (!Utilities.checkLocation((LivingEntity) npc.getEntity(), chairLocation, 1)) {
stand();
}
}
@Override
public void onSpawn() {
if (sitting) {
sit();
}
}
@Override
public void onDespawn() {
if (npc == null || npc.getEntity() == null) {
// Wat.
return;
}
if (npc.getEntity().getVehicle() != null) {
npc.getEntity().getVehicle().setPassenger(null);
}
}
// <--[action]
// @Actions
// sit
//
// @Triggers when the NPC sits down.
//
// @Context
// None
//
// -->
/**
* Makes the NPC sit
*/
public void sit() {
DenizenAPI.getDenizenNPC(npc).action("sit", null);
if (npc.getEntity().getType() != EntityType.PLAYER) {
return;
}
sitInternal();
chairLocation = npc.getEntity().getLocation().clone();
}
private void sitInternal() {
DenizenEntityType.getByName("FAKE_ARROW").spawnNewEntity(npc.getEntity().getLocation(),
new ArrayList<Mechanism>()).setPassenger(npc.getEntity());
//PlayerAnimation.SIT.play((Player)npc.getEntity());
//eh.getDataWatcher().watch(0, (byte) 0x04);
sitting = true;
}
private void standInternal() {
Entity vehicle = npc.getEntity().getVehicle();
npc.despawn();
npc.spawn(npc.getStoredLocation().clone().add(0, 0.5, 0));
if (vehicle != null && vehicle.isValid()) {
vehicle.setPassenger(null);
vehicle.remove();
}
//PlayerAnimation.STOP_SITTING.play((Player)npc.getEntity());
//eh.getDataWatcher().watch(0, (byte) 0x00);
sitting = false;
}
/**
* Makes the NPC sit at the specified location
*
* @param location where to sit
*/
public void sit(Location location) {
DenizenAPI.getDenizenNPC(npc).action("sit", null);
if (npc.getEntity().getType() != EntityType.PLAYER) {
return;
}
/*
* Teleport NPC to the location before
* sending the sit packet to the clients.
*/
// TODO: Make this work better.
npc.teleport(location.clone().add(0, 0.5, 0), PlayerTeleportEvent.TeleportCause.PLUGIN);
sitInternal();
chairLocation = location;
}
// <--[action]
// @Actions
// stand
//
// @Triggers when the NPC stands up.
//
// @Context
// None
//
// -->
/**
* Makes the NPC stand
*/
public void stand() {
DenizenAPI.getDenizenNPC(npc).action("stand", null);
standInternal();
standInternal();
chairLocation = null;
}
/**
* Checks if the NPC is currently sitting
*
* @return boolean
*/
public boolean isSitting() {
return true; // If the trait is attached, let's assume the NPC is sitting
}
/**
* Gets the chair the NPC is sitting on
* Returns null if the NPC isnt sitting
*
* @return Location
*/
public Location getChair() {
return chairLocation;
}
/**
* If someone tries to break the poor
* NPC's chair, we need to stop them!
*/
@EventHandler(ignoreCancelled = true)
public void onBlockBreak(BlockBreakEvent event) {
if (chairLocation == null) {
return;
}
if (event.getBlock().getLocation().equals(chairLocation)) {
event.setCancelled(true);
}
}
@EventHandler
public void arrowDismount(final VehicleExitEvent event) {
// TODO: Move elsewhere so not multi-firing?
if (event.getVehicle() instanceof FakeArrow) {
Bukkit.getScheduler().runTaskLater(DenizenAPI.getCurrentInstance(), new Runnable() {
@Override
public void run() {
if (event.getVehicle().isValid()) {
event.getVehicle().remove();
}
}
}, 1);
}
}
public SittingTrait() {
super("sitting");
}
}