package com.austinv11.peripheralsplusplus.tiles;
import com.austinv11.peripheralsplusplus.PeripheralsPlusPlus;
import com.austinv11.peripheralsplusplus.reference.Config;
import com.austinv11.peripheralsplusplus.utils.ChatUtil;
import com.austinv11.peripheralsplusplus.utils.Util;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.turtle.ITurtleAccess;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.EntityDamageSource;
import net.minecraft.util.Vec3;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import java.util.HashMap;
public class TileEntityChatBox extends MountedTileEntity {
public static String publicName = "chatBox";
private String name = "tileEntityChatBox";
private HashMap<IComputerAccess,Boolean> computers = new HashMap<IComputerAccess,Boolean>();
private static final int TICKER_INTERVAL = 20;
private int ticker = 0;
private int subticker = 0;
private ITurtleAccess turtle;
public TileEntityChatBox() {
super();
}
public TileEntityChatBox(ITurtleAccess turtle) {
this.xCoord = turtle.getPosition().posX;
this.yCoord = turtle.getPosition().posY;
this.zCoord = turtle.getPosition().posZ;
this.setWorldObj(turtle.getWorld());
this.turtle = turtle;
}
public String getName() {
return name;
}
@Override
public void readFromNBT(NBTTagCompound nbttagcompound) {
super.readFromNBT(nbttagcompound);
}
@Override
public void writeToNBT(NBTTagCompound nbttagcompound) {
super.writeToNBT(nbttagcompound);
}
@Override
public void updateEntity() {
if (subticker > 0)
subticker--;
if (subticker == 0 && ticker != 0)
ticker = 0;
}
public void updateEntity(boolean turtle) {
if (turtle) {
this.xCoord = this.turtle.getPosition().posX;
this.yCoord = this.turtle.getPosition().posY;
this.zCoord = this.turtle.getPosition().posZ;
}
updateEntity();
}
public void onChat(EntityPlayer player, String message) {
for (IComputerAccess computer : computers.keySet())
computer.queueEvent("chat", new Object[]{player.getDisplayName(), message});
}
public void onDeath(EntityPlayer player, DamageSource source) {
String killer = null;
if (source instanceof EntityDamageSource) {
Entity ent = source.getEntity();
if (ent != null)
killer = ent.getCommandSenderName();
}
for (IComputerAccess computer : computers.keySet())
computer.queueEvent("death", new Object[] {player.getDisplayName(), killer, source.damageType});
}
public void onCommand(EntityPlayerMP player, String message) {
for (IComputerAccess computer : computers.keySet())
computer.queueEvent("command", new Object[] {player.getDisplayName(), Util.arrayToMap(message.split(" "))});
}
@Override
public String getType() {
return publicName;
}
@Override
public String[] getMethodNames() {
return new String[] {"say", "tell"};
}
@Override
public Object[] callMethod(IComputerAccess computer, ILuaContext context, int method, Object[] arguments) throws LuaException, InterruptedException {
//try {
if (Config.enableChatBox) {
if (method == 0) {
if (arguments.length < 1)
throw new LuaException("Too few arguments");
if (!(arguments[0] instanceof String))
throw new LuaException("Bad argument #1 (expected string)");
if (arguments.length > 1 && !(arguments[1] instanceof Double))
throw new LuaException("Bad argument #2 (expected number)");
if (arguments.length > 2 && !(arguments[2] instanceof Boolean))
throw new LuaException("Bad argument #3 (expected boolean)");
if (arguments.length > 3) {
if(!(arguments[3] instanceof String)) {
throw new LuaException("Bad argument #4 (expected string)");
}
}
if (ticker == Config.sayRate) {
throw new LuaException("Please try again later, you are sending messages too often");
}
String message;
if (Config.logCoords) {
message = ChatUtil.getCoordsPrefix(this) + arguments[0];
}else if (!Config.logCoords && arguments.length > 3) {
message = "[" + arguments[3] + "] " + arguments[0];
}else {
message ="[@] " + arguments[0];
}
double range = Config.sayRange;
if (Config.sayRange < 0) {
range = Double.MAX_VALUE;
} else if (arguments.length > 1) {
if ((Double) arguments[1] < 0) {
if (Config.sayRange < 0) {
range = Double.MAX_VALUE;
}
} else if ((Double) arguments[1] < Config.sayRange) {
range = (Double) arguments[1];
}
}
synchronized (this) {
ChatUtil.sendMessage(this, message, range, (arguments.length > 2 && (Boolean) arguments[2] && Config.allowUnlimitedVertical));
subticker = TICKER_INTERVAL;
ticker++;
}
return new Object[]{true};
} else if (method == 1) {
if (arguments.length < 2)
throw new LuaException("Too few arguments");
if (!(arguments[0] instanceof String))
throw new LuaException("Bad argument #1 (expected string)");
if (!(arguments[1] instanceof String))
throw new LuaException("Bad argument #2 (expected string)");
else if (arguments.length > 2 && !(arguments[2] instanceof Double))
throw new LuaException("Bad argument #3 (expected number)");
else if (arguments.length > 3 && !(arguments[3] instanceof Boolean))
throw new LuaException("Bad argument #4 (expected boolean)");
if (arguments.length > 4) {
if (Config.logCoords) {
throw new LuaException("Coordinate logging is enabled, disable this to enable naming");
} else if (!(arguments[4] instanceof String)) {
throw new LuaException("Bad argument #5 (expected string)");
}
}
if (ticker == Config.sayRate) {
throw new LuaException("Please try again later, you are sending messages too often");
}
String message;
if (Config.logCoords) {
message = ChatUtil.getCoordsPrefix(this) + arguments[1];
} else if (!Config.logCoords && arguments.length > 4) {
message = "[" + arguments[4] + "] " + arguments[1];
} else {
message = "[@] " + arguments[1];
}
double range = Config.sayRange < 0 ? Double.MAX_VALUE : Config.sayRange;
if (arguments.length > 2)
range = (Double) arguments[2];
synchronized (this) {
subticker = TICKER_INTERVAL;
ticker++;
ChatUtil.sendMessage((String) arguments[0], this, message, range, (arguments.length > 3 && (Boolean) arguments[3] && Config.allowUnlimitedVertical));
}
return new Object[]{true};
}
}else {
throw new LuaException("Chat boxes have been disabled");
}
//} catch (Exception e) {
// e.printStackTrace();
//}
return new Object[0];
}
@Override
public void attach(IComputerAccess computer) {
if (computers.size() == 0)
ChatListener.chatBoxMap.put(this, true);
computers.put(computer, true);
super.attach(computer);
}
@Override
public void detach(IComputerAccess computer) {
computers.remove(computer);
if (computers.size() == 0)
ChatListener.chatBoxMap.remove(this);
super.detach(computer);
}
@Override
public boolean equals(IPeripheral other) {
return (other == this);
}
public static class ChatListener {
private static HashMap<TileEntityChatBox,Boolean> chatBoxMap = new HashMap<TileEntityChatBox, Boolean>();
@SubscribeEvent(priority = EventPriority.LOWEST)
public void onChat(ServerChatEvent event) {
if (!event.isCanceled()) {
if (Config.enableChatBox) {
String commandPrefix = Config.chatboxCommandPrefix.trim();
if (!commandPrefix.equals("") && !commandPrefix.equals(" ") && event.message.startsWith(commandPrefix)) {
event.setCanceled(true);
for (TileEntityChatBox box : chatBoxMap.keySet()) {
if (Config.readRange < 0 || Vec3.createVectorHelper(box.xCoord, box.yCoord, box.zCoord).distanceTo(event.player.getPosition(1.0f)) <= Config.readRange)
box.onCommand(event.player, event.message.replace(commandPrefix, ""));
}
} else {
for (TileEntityChatBox box : chatBoxMap.keySet()) {
if (Config.readRange < 0 || Vec3.createVectorHelper(box.xCoord, box.yCoord, box.zCoord).distanceTo(event.player.getPosition(1.0f)) <= Config.readRange) {
box.onChat(event.player, event.message);
}
}
}
}
}
}
@SubscribeEvent(priority = EventPriority.LOWEST)
public void onDeath(LivingDeathEvent event) {
if (!event.isCanceled()) {
if (Config.enableChatBox) {
if (event.entity instanceof EntityPlayer) {
for (TileEntityChatBox box : chatBoxMap.keySet()) {
if (Config.readRange < 0 || Vec3.createVectorHelper(box.xCoord, box.yCoord, box.zCoord).distanceTo(((EntityPlayer) event.entity).getPosition(1.0f)) <= Config.readRange)
box.onDeath((EntityPlayer) event.entity, event.source);
}
}
}
}
}
}
}