/*
* Copyright (C) 2016 eccentric_nz
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package me.eccentric_nz.TARDIS.rooms;
import java.util.HashMap;
import me.eccentric_nz.TARDIS.TARDIS;
import me.eccentric_nz.TARDIS.chameleon.TARDISChameleonColumn;
import me.eccentric_nz.TARDIS.database.QueryFactory;
import me.eccentric_nz.TARDIS.enumeration.COMPASS;
import me.eccentric_nz.TARDIS.enumeration.PRESET;
import me.eccentric_nz.TARDIS.utility.TARDISBlockSetters;
import me.eccentric_nz.TARDIS.utility.TARDISEntityTracker;
import me.eccentric_nz.TARDIS.utility.TARDISMessage;
import me.eccentric_nz.TARDIS.utility.TARDISNumberParsers;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
/**
*
* @author eccentric_nz
*/
public class TARDISExteriorRenderer {
private final TARDIS plugin;
public TARDISExteriorRenderer(TARDIS plugin) {
this.plugin = plugin;
}
@SuppressWarnings("deprecation")
public void render(String interior, Location exterior, int id, final Player p, final COMPASS d, long time, Biome biome) {
// construct a string for comparison
World ew = exterior.getWorld();
int epbx = exterior.getBlockX();
int epby = exterior.getBlockY();
int epbz = exterior.getBlockZ();
String isRendered = ew.getName() + ":" + epbx + ":" + epby + ":" + epbz;
String[] idata = interior.split(":");
World iw = plugin.getServer().getWorld(idata[0]);
int ipbx = TARDISNumberParsers.parseInt(idata[1]);
int ipby = TARDISNumberParsers.parseInt(idata[2]) + 2;
int ipbz = TARDISNumberParsers.parseInt(idata[3]);
final Location location = new Location(iw, ipbx, ipby, ipbz);
if (plugin.getTrackerKeeper().getRenderer().containsKey(id) && plugin.getTrackerKeeper().getRenderer().get(id).equals(isRendered)) {
TARDISMessage.send(p, "DEST_NO_CHANGE");
} else {
TARDISMessage.send(p, "RENDER_START");
int isx, isy, isz, esx, esy, esz, xx = 0, yy = 0, zz = 0;
// get interior coords
isx = ipbx - 6;
isy = ipby - 1;
isz = ipbz - 6;
// get exterior coords
esx = epbx - 6;
esy = epby - 1;
esz = epbz - 6;
// get preset bounds
int bwx = epbx - 1;
int bex = epbx + 1;
int buy = epby + 3;
int bnz = epbz - 1;
int bsz = epbz + 1;
ew.getChunkAt(exterior).load();
// loop through exterior blocks and mirror them in the interior
for (int y = esy; y < (esy + 8); y++) {
for (int x = esx; x < (esx + 13); x++) {
for (int z = esz; z < (esz + 13); z++) {
// don't do preset blocks - they'l be set to glass later
if (!(y >= epby && y <= buy && x >= bwx && x <= bex && z >= bnz && z <= bsz)) {
Block eb = ew.getBlockAt(x, y, z);
Block ib = iw.getBlockAt(isx + xx, isy + yy, isz + zz);
switch (eb.getType()) {
case WATER:
case STATIONARY_WATER:
ib.setType(Material.STAINED_GLASS);
ib.setData((byte) 3, true);
break;
case LAVA:
case STATIONARY_LAVA:
ib.setType(Material.WOOL);
ib.setData((byte) 1, true);
break;
default:
ib.setType(eb.getType());
ib.setData(eb.getData(), true);
}
}
zz++;
}
zz = 0;
xx++;
}
xx = 0;
yy++;
}
// render a glass TARDIS
// get relative locations
int x = location.getBlockX();
int plusx = (location.getBlockX() + 1);
int minusx = (location.getBlockX() - 1);
int y = location.getBlockY();
int z = (location.getBlockZ());
int plusz = (location.getBlockZ() + 1);
int minusz = (location.getBlockZ() - 1);
TARDISChameleonColumn column = plugin.getPresets().getGlass(PRESET.RENDER, d);
int px, pz;
int[][] ids = column.getId();
byte[][] data = column.getData();
for (int i = 0; i < 9; i++) {
int[] colids = ids[i];
byte[] coldatas = data[i];
switch (i) {
case 0:
px = minusx;
pz = minusz;
break;
case 1:
px = x;
pz = minusz;
break;
case 2:
px = plusx;
pz = minusz;
break;
case 3:
px = plusx;
pz = z;
break;
case 4:
px = plusx;
pz = plusz;
break;
case 5:
px = x;
pz = plusz;
break;
case 6:
px = minusx;
pz = plusz;
break;
case 7:
px = minusx;
pz = z;
break;
default:
px = x;
pz = z;
break;
}
for (int py = 0; py < 4; py++) {
TARDISBlockSetters.setBlock(iw, px, (y + py), pz, colids[py], coldatas[py]);
}
}
// change the black/blue/green wool to blue/black/ to reflect time of day and environment
byte sky;
Material base;
Material stone;
switch (biome) {
case SKY:
sky = 15;
base = Material.ENDER_STONE;
stone = Material.OBSIDIAN;
break;
case HELL:
sky = 15;
base = Material.NETHERRACK;
stone = Material.QUARTZ_ORE;
break;
default:
sky = (time > 12500) ? (byte) 15 : 3;
base = Material.DIRT;
stone = Material.STONE;
break;
}
int endx = isx + 13;
int topy = isy + 8;
int endz = isz + 13;
// change the ceiling
for (int cx = isx; cx < isx + 13; cx++) {
for (int cz = isz; cz < (isz + 13); cz++) {
iw.getBlockAt(cx, topy, cz).setData(sky);
}
}
// change the first and third walls
for (int x1 = isx - 1; x1 <= endx; x1++) {
for (int y1 = isy; y1 < topy; y1++) {
switch (iw.getBlockAt(x1, y1, isz - 1).getType()) {
case WOOL:
iw.getBlockAt(x1, y1, isz - 1).setData(sky);
break;
case DIRT:
case ENDER_STONE:
case NETHERRACK:
iw.getBlockAt(x1, y1, isz - 1).setType(base);
break;
default:
iw.getBlockAt(x1, y1, isz - 1).setType(stone);
break;
}
switch (iw.getBlockAt(x1, y1, endz).getType()) {
case WOOL:
iw.getBlockAt(x1, y1, endz).setData(sky);
break;
case DIRT:
case ENDER_STONE:
case NETHERRACK:
iw.getBlockAt(x1, y1, endz).setType(base);
break;
default:
iw.getBlockAt(x1, y1, endz).setType(stone);
break;
}
}
}
// build second and fourth walls
for (int z2 = isz - 1; z2 <= endz; z2++) {
for (int y2 = isy; y2 < topy; y2++) {
switch (iw.getBlockAt(isx - 1, y2, z2).getType()) {
case WOOL:
iw.getBlockAt(isx - 1, y2, z2).setData(sky);
break;
case DIRT:
case ENDER_STONE:
case NETHERRACK:
iw.getBlockAt(isx - 1, y2, z2).setType(base);
break;
default:
iw.getBlockAt(isx - 1, y2, z2).setType(stone);
break;
}
switch (iw.getBlockAt(endx, y2, z2).getType()) {
case WOOL:
iw.getBlockAt(endx, y2, z2).setData(sky);
break;
case DIRT:
case ENDER_STONE:
case NETHERRACK:
iw.getBlockAt(endx, y2, z2).setType(base);
break;
default:
iw.getBlockAt(endx, y2, z2).setType(stone);
break;
}
}
}
plugin.getTrackerKeeper().getRenderer().put(id, isRendered);
TARDISMessage.send(p, "RENDER_DONE");
// remove dropped items
for (Entity e : location.getChunk().getEntities()) {
if (e instanceof Item) {
e.remove();
}
}
}
// if enabled add static entities
if (plugin.getPM().isPluginEnabled("Citizens") && plugin.getConfig().getBoolean("preferences.render_entities")) {
plugin.debug("rendering entities");
new TARDISEntityTracker(plugin).addNPCs(exterior, location, p.getUniqueId());
}
// charge artron energy for the render
HashMap<String, Object> where = new HashMap<String, Object>();
where.put("tardis_id", id);
new QueryFactory(plugin).alterEnergyLevel("tardis", -plugin.getArtronConfig().getInt("render"), where, p);
// tp the player inside the room
plugin.getTrackerKeeper().getRenderRoomOccupants().add(p.getUniqueId());
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
transmat(p, d, location);
p.playSound(location, Sound.ENTITY_ENDERMEN_TELEPORT, 1.0f, 1.0f);
TARDISMessage.send(p, "RENDER_EXIT");
}
}, 10L);
}
public void transmat(Player player, COMPASS d, Location loc) {
float yaw = player.getLocation().getYaw();
float pitch = player.getLocation().getPitch();
loc.setPitch(pitch);
loc.setYaw(yaw);
// make location safe ie. outside of the bluebox
double ex = loc.getX();
double ez = loc.getZ();
switch (d) {
case NORTH:
loc.setX(ex + 0.5);
loc.setZ(ez + 2.5);
break;
case EAST:
loc.setX(ex - 1.5);
loc.setZ(ez + 0.5);
break;
case SOUTH:
loc.setX(ex + 0.5);
loc.setZ(ez - 1.5);
break;
case WEST:
loc.setX(ex + 2.5);
loc.setZ(ez + 0.5);
break;
}
player.teleport(loc);
}
}