Fixed a train of cloaking issue

Fixed cloaking support on dedicated server
Fixed uncloaking with negative X or Z
Fixed cloak causing memory leak over time on client side
Fixed ghost cloaks when changing world or save
Refactored packet handler vs cloaked area
Improved general speed and memory consumption
This commit is contained in:
LemADEC 2015-08-29 21:11:49 +02:00
parent 81975d9063
commit 33577951d5
8 changed files with 323 additions and 223 deletions

View file

@ -1,37 +0,0 @@
package cr0s.warpdrive;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.world.ChunkWatchEvent;
public class CloakChunkWatcher {
//TODO: register as event receiver
public void onChunkLoaded(ChunkWatchEvent event) {
ChunkCoordIntPair chunk = event.chunk;
// Check chunk for locating in cloaked areas
WarpDrive.logger.info("onChunkLoaded " + chunk.chunkXPos + " " + chunk.chunkZPos);
WarpDrive.cloaks.onChunkLoaded(event.player, chunk.chunkXPos, chunk.chunkZPos);
/*
List<Chunk> list = new ArrayList<Chunk>();
list.add(c);
// Send obscured chunk
System.out.println("[Cloak] Sending to player " + p.username + " obscured chunk at (" + chunk.chunkXPos + "; " + chunk.chunkZPos + ")");
((EntityPlayerMP)p).playerNetServerHandler.sendPacketToPlayer(new Packet56MapChunks(list));
*/
}
@SubscribeEvent
public void onEntityJoinWorld(EntityJoinWorldEvent event){
if (!event.world.isRemote) {
if (event.entity instanceof EntityPlayerMP) {
WarpDrive.cloaks.onEntityJoinWorld((EntityPlayerMP)event.entity);
}
}
}
}

View file

@ -0,0 +1,65 @@
package cr0s.warpdrive;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerChangedDimensionEvent;
import cpw.mods.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.world.ChunkWatchEvent;
import net.minecraftforge.event.world.WorldEvent;
public class EventListeners {
//TODO: register as event receiver
public void onChunkLoaded(ChunkWatchEvent event) {
ChunkCoordIntPair chunk = event.chunk;
// Check chunk for locating in cloaked areas
WarpDrive.logger.info("onChunkLoaded " + chunk.chunkXPos + " " + chunk.chunkZPos);
WarpDrive.cloaks.onChunkLoaded(event.player, chunk.chunkXPos, chunk.chunkZPos);
/*
List<Chunk> list = new ArrayList<Chunk>();
list.add(c);
// Send obscured chunk
System.out.println("[Cloak] Sending to player " + p.username + " obscured chunk at (" + chunk.chunkXPos + "; " + chunk.chunkZPos + ")");
((EntityPlayerMP)p).playerNetServerHandler.sendPacketToPlayer(new Packet56MapChunks(list));
*/
}
// Server side
@SubscribeEvent
public void onEntityJoinWorld(EntityJoinWorldEvent event){
if (event.entity instanceof EntityPlayer) {
// WarpDrive.logger.info("onEntityJoinWorld " + event.entity);
if (!event.world.isRemote) {
WarpDrive.cloaks.onPlayerEnteringDimension((EntityPlayer)event.entity);
}
}
}
@SubscribeEvent
public void onPlayerChangedDimension(PlayerChangedDimensionEvent event) {
// WarpDrive.logger.info("onPlayerChangedDimension " + event.player.getCommandSenderName() + " " + event.fromDim + " -> " + event.toDim);
WarpDrive.cloaks.onPlayerEnteringDimension(event.player);
}
// Client side
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onClientConnectedToServer(ClientConnectedToServerEvent event) {
// WarpDrive.logger.info("onClientConnectedToServer connectionType " + event.connectionType + " isLocal " + event.isLocal);
WarpDrive.cloaks.onClientChangingDimension();
}
@SubscribeEvent
@SideOnly(Side.CLIENT)
public void onWorldUnload(WorldEvent.Unload event) {
// WarpDrive.logger.info("onWorldUnload world " + event.world);
WarpDrive.cloaks.onClientChangingDimension();
}
}

View file

@ -170,20 +170,19 @@ public class WarpDrive implements LoadingCallback {
// Client settings
public static CreativeTabs creativeTabWarpDrive = new CreativeTabWarpDrive("Warpdrive", "Warpdrive").setBackgroundImageName("warpdrive:creativeTab");
@Instance(WarpDrive.MODID)
public static WarpDrive instance;
@SidedProxy(clientSide = "cr0s.warpdrive.client.ClientProxy", serverSide = "cr0s.warpdrive.CommonProxy")
public static CommonProxy proxy;
public static StarMapRegistry starMap;
public static JumpgatesRegistry jumpgates;
public static CloakManager cloaks;
public static CamerasRegistry cameras;
public static WarpDrivePeripheralHandler peripheralHandler = null;
public static String defHelpStr = "help(\"functionName\"): returns help for the function specified";
public static String defEnergyStr = "getEnergyLevel(): returns currently contained energy, max contained energy";
public static String defUpgradeStr = "upgrades(): returns a list of currently installed upgrades";
@ -427,14 +426,19 @@ public class WarpDrive implements LoadingCallback {
starMap = new StarMapRegistry();
jumpgates = new JumpgatesRegistry();
cloaks = new CloakManager();
cameras = new CamerasRegistry();
EventListeners watcher = new EventListeners();
MinecraftForge.EVENT_BUS.register(watcher);
FMLCommonHandler.instance().bus().register(watcher);
}
private static void initVanillaRecipes() {
itemComponent.registerRecipes();
blockDecorative.initRecipes();
itemUpgrade.initRecipes();
// WarpCore
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(blockShipCore), false, "ipi", "ici", "idi",
'i', Items.iron_ingot,
@ -877,10 +881,8 @@ public class WarpDrive implements LoadingCallback {
}
@EventHandler
public void serverLoad(FMLServerStartingEvent event) {
cloaks = new CloakManager();
MinecraftForge.EVENT_BUS.register(new CloakChunkWatcher());
public void onServerStarting(FMLServerStartingEvent event) {
WarpDrive.logger.info("onServerStarting");
event.registerServerCommand(new CommandGenerate());
event.registerServerCommand(new CommandSpace());
event.registerServerCommand(new CommandInvisible());

View file

@ -104,7 +104,9 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
setCoilsState(true);
// Register cloak
WarpDrive.cloaks.addCloakedAreaWorld(worldObj, minX, minY, minZ, maxX, maxY, maxZ, xCoord, yCoord, zCoord, tier);
WarpDrive.cloaks.updateCloakedArea(worldObj,
worldObj.provider.dimensionId, xCoord, yCoord, zCoord, tier,
minX, minY, minZ, maxX, maxY, maxZ);
if (!soundPlayed) {
soundPlayed = true;
worldObj.playSoundEffect(xCoord + 0.5f, yCoord + 0.5f, zCoord + 0.5f, "warpdrive:cloak", 4F, 1F);
@ -239,7 +241,7 @@ public class TileEntityCloakingCore extends TileEntityAbstractEnergy {
public void disableCloakingField() {
setCoilsState(false);
if (WarpDrive.cloaks.isAreaExists(worldObj, xCoord, yCoord, zCoord)) {
WarpDrive.cloaks.removeCloakedArea(worldObj, xCoord, yCoord, zCoord);
WarpDrive.cloaks.removeCloakedArea(worldObj.provider.dimensionId, xCoord, yCoord, zCoord);
if (!soundPlayed) {
soundPlayed = true;

View file

@ -2,6 +2,7 @@ package cr0s.warpdrive.data;
import java.util.LinkedList;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
@ -9,7 +10,6 @@ import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.Blocks;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import cr0s.warpdrive.WarpDrive;
@ -37,7 +37,7 @@ public class CloakManager {
continue;
}
if (area.aabb.minX <= x && area.aabb.maxX >= x && area.aabb.minY <= y && area.aabb.maxY >= y && area.aabb.minZ <= z && area.aabb.maxZ >= z) {
if (area.minX <= x && area.maxX >= x && area.minY <= y && area.maxY >= y && area.minZ <= z && area.maxZ >= z) {
return true;
}
}
@ -53,16 +53,16 @@ public class CloakManager {
}
// force refresh if the chunk overlap the cloak
if ( area.aabb.minX <= (chunkPosX << 4 + 15) && area.aabb.maxX >= (chunkPosX << 4)
&& area.aabb.minZ <= (chunkPosZ << 4 + 15) && area.aabb.maxZ >= (chunkPosZ << 4) ) {
PacketHandler.sendCloakPacket(player, area.aabb, area.tier, false);
if ( area.minX <= (chunkPosX << 4 + 15) && area.maxX >= (chunkPosX << 4)
&& area.minZ <= (chunkPosZ << 4 + 15) && area.maxZ >= (chunkPosZ << 4) ) {
PacketHandler.sendCloakPacket(player, area, false);
}
}
return false;
}
public boolean onEntityJoinWorld(EntityPlayerMP player) {
public boolean onPlayerEnteringDimension(EntityPlayer player) {
if (WarpDriveConfig.LOGGING_CLOAKING) { WarpDrive.logger.info("onEntityJoinWorld " + player); }
for (CloakedArea area : this.cloaks) {
// skip other dimensions
@ -71,10 +71,10 @@ public class CloakManager {
}
// force refresh if player is outside the cloak
if ( area.aabb.minX > player.posX || area.aabb.maxX < player.posX
|| area.aabb.minY > player.posY || area.aabb.maxY < player.posY
|| area.aabb.minZ > player.posZ || area.aabb.maxZ < player.posZ ) {
PacketHandler.sendCloakPacket(player, area.aabb, area.tier, false);
if ( area.minX > player.posX || area.maxX < player.posX
|| area.minY > player.posY || area.maxY < player.posY
|| area.minZ > player.posZ || area.maxZ < player.posZ ) {
PacketHandler.sendCloakPacket(player, area, false);
}
}
@ -85,21 +85,49 @@ public class CloakManager {
return (getCloakedArea(worldObj, x, y, z) != null);
}
public void addCloakedAreaWorld(World worldObj,
public void updateCloakedArea(
World worldObj,
final int dimensionId, final int coreX, final int coreY, final int coreZ, final byte tier,
final int minX, final int minY, final int minZ,
final int maxX, final int maxY, final int maxZ,
final int x, final int y, final int z, final byte tier) {
cloaks.add(new CloakedArea(worldObj, x, y, z, AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ), tier));
final int maxX, final int maxY, final int maxZ) {
CloakedArea newArea = new CloakedArea(worldObj, dimensionId, coreX, coreY, coreZ, tier, minX, minY, minZ, maxX, maxY, maxZ);
// find existing one
int index = -1;
for (int i = 0; i < cloaks.size(); i++) {
CloakedArea area = cloaks.get(i);
if ( area.dimensionId == worldObj.provider.dimensionId
&& area.coreX == coreX
&& area.coreY == coreY
&& area.coreZ == coreZ ) {
index = i;
break;
}
}
if (index != -1) {
cloaks.set(index, newArea);
} else {
cloaks.add(newArea);
}
if (FMLCommonHandler.instance().getEffectiveSide().isClient()) {
newArea.clientCloak();
}
WarpDrive.logger.info("Cloak count is " + cloaks.size());
}
public void removeCloakedArea(World worldObj, int x, int y, int z) {
public void removeCloakedArea(final int dimensionId, final int coreX, final int coreY, final int coreZ) {
int index = 0;
for (int i = 0; i < cloaks.size(); i++) {
if ( cloaks.get(i).coreX == x
&& cloaks.get(i).coreY == y
&& cloaks.get(i).coreZ == z
&& cloaks.get(i).dimensionId == worldObj.provider.dimensionId) {
cloaks.get(i).sendCloakPacketToPlayersEx(true); // send info about collapsing cloaking field
CloakedArea area = cloaks.get(i);
if ( area.dimensionId == dimensionId
&& area.coreX == coreX
&& area.coreY == coreY
&& area.coreZ == coreZ ) {
if (FMLCommonHandler.instance().getEffectiveSide().isClient()) {
area.clientDecloak();
} else {
area.sendCloakPacketToPlayersEx(true); // send info about collapsing cloaking field
}
index = i;
break;
}
@ -110,7 +138,7 @@ public class CloakManager {
public CloakedArea getCloakedArea(World worldObj, int x, int y, int z) {
for (CloakedArea area : cloaks) {
if (area.coreX == x && area.coreY == y && area.coreZ == z && area.dimensionId == worldObj.provider.dimensionId)
if (area.dimensionId == worldObj.provider.dimensionId && area.coreX == x && area.coreY == y && area.coreZ == z)
return area;
}
@ -136,17 +164,13 @@ public class CloakManager {
@SideOnly(Side.CLIENT)
public static boolean onBlockChange(int x, int y, int z, Block block, int metadata, int flag) {
if (block != Blocks.air) {
if (block != Blocks.air && cloaks != null) {
for (CloakedArea area : cloaks) {
if (area.isBlockWithinArea(x, y, z)) {
// WarpDrive.logger.info("CM block is inside");
if (!area.isEntityWithinArea(Minecraft.getMinecraft().thePlayer)) {
// WarpDrive.logger.info("CM player is outside");
if (area.tier == 1) {
return Minecraft.getMinecraft().theWorld.setBlock(x, y, z, WarpDrive.blockGas, 5, flag);
} else {
return Minecraft.getMinecraft().theWorld.setBlock(x, y, z, Blocks.air, 0, flag);
}
return Minecraft.getMinecraft().theWorld.setBlock(x, y, z, area.fogBlock, area.fogMetadata, flag);
}
}
}
@ -156,36 +180,34 @@ public class CloakManager {
@SideOnly(Side.CLIENT)
public static void onFillChunk(Chunk chunk) {
// WarpDrive.logger.info("CM onFillChunk " + chunk.xPosition + " " + chunk.zPosition);
int chunkXmin = chunk.xPosition << 4;
int chunkXmax = chunk.xPosition << 4 + 15;
int chunkZmin = chunk.zPosition << 4;
int chunkZmax = chunk.zPosition << 4 + 15;
if (cloaks == null) {
// WarpDrive.logger.info("CM onFillChunk (" + chunk.xPosition + " " + chunk.zPosition + ") no cloaks");
return;
}
int chunkXmin = chunk.xPosition * 16;
int chunkXmax = chunk.xPosition * 16 + 15;
int chunkZmin = chunk.zPosition * 16;
int chunkZmax = chunk.zPosition * 16 + 15;
// WarpDrive.logger.info("CM onFillChunk (" + chunk.xPosition + " " + chunk.zPosition + ") " + cloaks.size() + " cloak(s) from (" + chunkXmin + " " + chunkZmin + ") to (" + chunkXmax + " " + chunkZmax + ")");
for (CloakedArea area : cloaks) {
if ( area.aabb.minX <= chunkXmax && area.aabb.maxX >= chunkXmin
&& area.aabb.minZ <= chunkZmax && area.aabb.maxZ >= chunkZmin ) {
if ( area.minX <= chunkXmax && area.maxX >= chunkXmin
&& area.minZ <= chunkZmax && area.maxZ >= chunkZmin ) {
// WarpDrive.logger.info("CM chunk is inside");
if (!area.isEntityWithinArea(Minecraft.getMinecraft().thePlayer)) {
// WarpDrive.logger.info("CM player is outside");
int areaXmin = (int)Math.max(chunkXmin, area.aabb.minX) & 15;
int areaXmax = (int)Math.min(chunkXmax, area.aabb.maxX) & 15;
int areaZmin = (int)Math.max(chunkZmin, area.aabb.minZ) & 15;
int areaZmax = (int)Math.min(chunkZmax, area.aabb.maxZ) & 15;
Block block = Blocks.air;
int metadata = 0;
if (area.tier == 1) {
block = WarpDrive.blockGas;
metadata = 5;
}
int areaXmin = Math.max(chunkXmin, area.minX) & 15;
int areaXmax = Math.min(chunkXmax, area.maxX) & 15;
int areaZmin = Math.max(chunkZmin, area.minZ) & 15;
int areaZmax = Math.min(chunkZmax, area.maxZ) & 15;
for (int x = areaXmin; x <= areaXmax; x++) {
for (int z = areaZmin; z <= areaZmax; z++) {
for (int y = (int)area.aabb.maxY; y >= (int)area.aabb.minY; y--) {
for (int y = area.maxY; y >= area.minY; y--) {
if (chunk.getBlock(x, y, z) != Blocks.air) {
chunk.func_150807_a(x, y, z, block, metadata);
chunk.func_150807_a(x, y, z, area.fogBlock, area.fogMetadata);
}
}
@ -195,4 +217,9 @@ public class CloakManager {
}
}
}
@SideOnly(Side.CLIENT)
public void onClientChangingDimension() {
cloaks.clear();
}
}

View file

@ -3,6 +3,13 @@ package cr0s.warpdrive.data;
import java.util.LinkedList;
import java.util.List;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityClientPlayerMP;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
@ -15,38 +22,55 @@ import net.minecraft.world.World;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.network.PacketHandler;
import cr0s.warpdrive.render.EntityFXBeam;
public class CloakedArea {
public int dimensionId = -666;
public int coreX, coreY, coreZ;
public AxisAlignedBB aabb;
public int minX, minY, minZ;
public int maxX, maxY, maxZ;
private LinkedList<String> playersInArea;
public byte tier = 0;
public Block fogBlock;
public int fogMetadata;
public CloakedArea(World worldObj, final int x, final int y, final int z, AxisAlignedBB aabb, final byte tier) {
public CloakedArea(World worldObj,
final int dimensionId, final int x, final int y, final int z, final byte tier,
final int minX, final int minY, final int minZ,
final int maxX, final int maxY, final int maxZ) {
this.dimensionId = dimensionId;
this.coreX = x;
this.coreY = y;
this.coreZ = z;
this.aabb = aabb;
this.tier = tier;
this.minX = minX;
this.minY = minY;
this.minZ = minZ;
this.maxX = maxX;
this.maxY = maxY;
this.maxZ = maxZ;
this.playersInArea = new LinkedList<String>();
if (worldObj == null || aabb == null) {
return;
if (worldObj != null) {
try {
// Add all players currently inside the field
List<EntityPlayer> list = worldObj.getEntitiesWithinAABB(EntityPlayerMP.class, AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ));
for (EntityPlayer player : list) {
addPlayer(player.getCommandSenderName());
}
} catch (Exception exception) {
exception.printStackTrace();
}
}
this.dimensionId = worldObj.provider.dimensionId;
try {
// Add all players currently inside the field
List<Entity> list = worldObj.getEntitiesWithinAABB(EntityPlayerMP.class, this.aabb);
for (Entity e : list) {
if (e instanceof EntityPlayer) {
addPlayer(((EntityPlayer) e).getCommandSenderName());
}
}
} catch (Exception exception) {
exception.printStackTrace();
if (tier == 1) {
fogBlock = WarpDrive.blockGas;
fogMetadata = 5;
} else {
fogBlock = Blocks.air;
fogMetadata = 0;
}
}
@ -76,46 +100,47 @@ public class CloakedArea {
}
public boolean isEntityWithinArea(EntityLivingBase entity) {
return (aabb.minX <= entity.posX && (aabb.maxX + 1) > entity.posX
&& aabb.minY <= (entity.posY + entity.height) && (aabb.maxY + 1) > entity.posY
&& aabb.minZ <= entity.posZ && (aabb.maxZ + 1) > entity.posZ);
return (minX <= entity.posX && (maxX + 1) > entity.posX
&& minY <= (entity.posY + entity.height) && (maxY + 1) > entity.posY
&& minZ <= entity.posZ && (maxZ + 1) > entity.posZ);
}
public boolean isBlockWithinArea(final int x, final int y, final int z) {
return (aabb.minX <= x && (aabb.maxX + 1) > x
&& aabb.minY <= y && (aabb.maxY + 1) > y
&& aabb.minZ <= z && (aabb.maxZ + 1) > z);
return (minX <= x && (maxX + 1) > x
&& minY <= y && (maxY + 1) > y
&& minZ <= z && (maxZ + 1) > z);
}
// Sending only if field changes: sets up or collapsing
@SideOnly(Side.SERVER)
public void sendCloakPacketToPlayersEx(final boolean decloak) {
if (WarpDriveConfig.LOGGING_CLOAKING) {
WarpDrive.logger.info("sendCloakPacketToPlayersEx " + decloak);
}
final int RADIUS = 250;
double midX = this.aabb.minX + (Math.abs(this.aabb.maxX - this.aabb.minX) / 2);
double midY = this.aabb.minY + (Math.abs(this.aabb.maxY - this.aabb.minY) / 2);
double midZ = this.aabb.minZ + (Math.abs(this.aabb.maxZ - this.aabb.minZ) / 2);
double midX = minX + (Math.abs(maxX - minX) / 2.0D);
double midY = minY + (Math.abs(maxY - minY) / 2.0D);
double midZ = minZ + (Math.abs(maxZ - minZ) / 2.0D);
for (int j = 0; j < MinecraftServer.getServer().getConfigurationManager().playerEntityList.size(); j++) {
EntityPlayerMP entityPlayerMP = (EntityPlayerMP) MinecraftServer.getServer().getConfigurationManager().playerEntityList.get(j);
if (entityPlayerMP.dimension == dimensionId) {
double d4 = midX - entityPlayerMP.posX;
double d5 = midY - entityPlayerMP.posY;
double d6 = midZ - entityPlayerMP.posZ;
double dX = midX - entityPlayerMP.posX;
double dY = midY - entityPlayerMP.posY;
double dZ = midZ - entityPlayerMP.posZ;
if (Math.abs(d4) < RADIUS && Math.abs(d5) < RADIUS && Math.abs(d6) < RADIUS) {
if (Math.abs(dX) < RADIUS && Math.abs(dY) < RADIUS && Math.abs(dZ) < RADIUS) {
if (decloak) {
revealChunksToPlayer(entityPlayerMP);
revealEntitiesToPlayer(entityPlayerMP);
}
if (!isEntityWithinArea(entityPlayerMP) && !decloak) {
PacketHandler.sendCloakPacket(entityPlayerMP, aabb, tier, false);
PacketHandler.sendCloakPacket(entityPlayerMP, this, false);
} else if (decloak) {
PacketHandler.sendCloakPacket(entityPlayerMP, aabb, tier, true);
PacketHandler.sendCloakPacket(entityPlayerMP, this, true);
}
}
}
@ -131,7 +156,7 @@ public class CloakedArea {
addPlayer(player.getCommandSenderName());
revealChunksToPlayer(player);
revealEntitiesToPlayer(player);
PacketHandler.sendCloakPacket(player, aabb, tier, false);
PacketHandler.sendCloakPacket(player, this, false);
}
} else {
if (isPlayerListedInArea(player.getCommandSenderName())) {
@ -144,7 +169,7 @@ public class CloakedArea {
.getConfigurationManager()
.sendToAllNearExcept(player, player.posX, player.posY, player.posZ, 100, player.worldObj.provider.dimensionId,
PacketHandler.getPacketForThisEntity(player));
PacketHandler.sendCloakPacket(player, aabb, tier, false);
PacketHandler.sendCloakPacket(player, this, false);
}
}
}
@ -153,11 +178,11 @@ public class CloakedArea {
if (WarpDriveConfig.LOGGING_CLOAKING) {
WarpDrive.logger.info(this + " Revealing cloaked blocks to player " + player.getCommandSenderName());
}
int minY = (int) Math.max(0, aabb.minY);
int maxY = (int) Math.min(255, aabb.maxY);
for (int x = (int) aabb.minX; x <= (int) aabb.maxX; x++) {
for (int z = (int) aabb.minZ; z <= (int) aabb.maxZ; z++) {
for (int y = minY; y <= maxY; y++) {
int minYclamped = Math.max(0, minY);
int maxYclamped = Math.min(255, maxY);
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
for (int y = minYclamped; y <= maxYclamped; y++) {
if (!player.worldObj.getBlock(x, y, z).isAssociatedBlock(Blocks.air)) {
player.worldObj.markBlockForUpdate(x, y, z);
@ -170,20 +195,24 @@ public class CloakedArea {
/*
ArrayList<Chunk> chunksToSend = new ArrayList<Chunk>();
for (int x = (int) aabb.minX >> 4; x <= (int) aabb.maxX >> 4; x++)
for (int z = (int) aabb.minZ >> 4; z <= (int) aabb.maxZ >> 4; z++) {
for (int x = minX >> 4; x <= maxX >> 4; x++) {
for (int z = minZ >> 4; z <= maxZ >> 4; z++) {
chunksToSend.add(p.worldObj.getChunkFromChunkCoords(x, z));
}
}
//System.outprintln("[Cloak] Sending " + chunksToSend.size() + " chunks to player " + p.username);
((EntityPlayerMP) p).playerNetServerHandler.sendPacketToPlayer(new Packet56MapChunks(chunksToSend));
//System.outprintln("[Cloak] Sending decloak packet to player " + p.username); area.sendCloakPacketToPlayer(p, true); // decloak = true
//System.outprintln("[Cloak] Sending decloak packet to player " + p.username);
area.sendCloakPacketToPlayer(p, true);
// decloak = true
/**/
}
public void revealEntitiesToPlayer(EntityPlayer player) {
List<Entity> list = player.worldObj.getEntitiesWithinAABBExcludingEntity(player, aabb);
List<Entity> list = player.worldObj.getEntitiesWithinAABBExcludingEntity(player, AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX, maxY, maxZ));
for (Entity entity : list) {
Packet packet = PacketHandler.getPacketForThisEntity(entity);
@ -198,9 +227,72 @@ public class CloakedArea {
}
}
@SideOnly(Side.CLIENT)
public void clientCloak() {
EntityClientPlayerMP player = Minecraft.getMinecraft().thePlayer;
// Hide the blocks within area
if (WarpDriveConfig.LOGGING_CLOAKING) { WarpDrive.logger.info("Refreshing cloaked blocks..."); }
World worldObj = player.worldObj;
int minYmap = Math.max(0, minY);
int maxYmap = Math.min(255, maxY);
for (int y = minYmap; y <= maxYmap; y++) {
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
Block block = worldObj.getBlock(x, y, z);
if (!block.isAssociatedBlock(Blocks.air)) {
worldObj.setBlock(x, y, z, fogBlock, fogMetadata, 4);
}
}
}
}
// Hide any entities inside area
if (WarpDriveConfig.LOGGING_CLOAKING) { WarpDrive.logger.info("Refreshing cloaked entities..."); }
AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX + 1, maxY + 1, maxZ + 1);
List<Entity> list = worldObj.getEntitiesWithinAABBExcludingEntity(player, aabb);
for (Entity entity : list) {
worldObj.removeEntity(entity);
((WorldClient) worldObj).removeEntityFromWorld(entity.getEntityId());
}
}
@SideOnly(Side.CLIENT)
public void clientDecloak() {
World worldObj = Minecraft.getMinecraft().theWorld;
worldObj.markBlockRangeForRenderUpdate(minX - 1, Math.max(0, minY - 1), minZ - 1, maxX + 1, Math.min(255, maxY + 1), maxZ + 1);
// Make some graphics
int numLasers = 80 + worldObj.rand.nextInt(50);
double centerX = (minX + maxX) / 2.0D;
double centerY = (minY + maxY) / 2.0D;
double centerZ = (minZ + maxZ) / 2.0D;
double radiusX = (maxX - minX) / 2.0D + 5.0D;
double radiusY = (maxY - minY) / 2.0D + 5.0D;
double radiusZ = (maxZ - minZ) / 2.0D + 5.0D;
for (int i = 0; i < numLasers; i++) {
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new EntityFXBeam(worldObj,
new Vector3(
centerX + radiusX * worldObj.rand.nextGaussian(),
centerY + radiusY * worldObj.rand.nextGaussian(),
centerZ + radiusZ * worldObj.rand.nextGaussian()),
new Vector3(
centerX + radiusX * worldObj.rand.nextGaussian(),
centerY + radiusY * worldObj.rand.nextGaussian(),
centerZ + radiusZ * worldObj.rand.nextGaussian()),
worldObj.rand.nextFloat(), worldObj.rand.nextFloat(), worldObj.rand.nextFloat(),
60 + worldObj.rand.nextInt(60), 100));
}
}
@Override
public String toString() {
return String.format("%s @ DIM%d %d, %d, %d %s", new Object[] { getClass().getSimpleName(), Integer.valueOf(dimensionId), Integer.valueOf(coreX),
Integer.valueOf(coreY), Integer.valueOf(coreZ), aabb.toString() });
return String.format("%s @ DIM%d %d, %d, %d (%d %d %d) -> (%d %d %d)", new Object[] {
getClass().getSimpleName(), Integer.valueOf(dimensionId),
Integer.valueOf(coreX), Integer.valueOf(coreY), Integer.valueOf(coreZ),
Integer.valueOf(minX), Integer.valueOf(minY), Integer.valueOf(minZ),
Integer.valueOf(maxX), Integer.valueOf(maxY), Integer.valueOf(maxZ) });
}
}

View file

@ -1,17 +1,8 @@
package cr0s.warpdrive.network;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityClientPlayerMP;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.world.World;
import io.netty.buffer.ByteBuf;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
@ -19,11 +10,13 @@ import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.Vector3;
import cr0s.warpdrive.render.EntityFXBeam;
import cr0s.warpdrive.data.CloakedArea;
public class MessageCloak implements IMessage, IMessageHandler<MessageCloak, IMessage> {
private int coreX;
private int coreY;
private int coreZ;
private int minX;
private int minY;
private int minZ;
@ -37,19 +30,25 @@ public class MessageCloak implements IMessage, IMessageHandler<MessageCloak, IMe
// required on receiving side
}
public MessageCloak(final AxisAlignedBB aabb, final byte tier, final boolean decloak) {
this.minX = (int)aabb.minX;
this.minY = (int)aabb.minY;
this.minZ = (int)aabb.minZ;
this.maxX = (int)aabb.maxX;
this.maxY = (int)aabb.maxY;
this.maxZ = (int)aabb.maxZ;
this.tier = tier;
public MessageCloak(CloakedArea area, final boolean decloak) {
this.coreX = area.coreX;
this.coreY = area.coreY;
this.coreZ = area.coreZ;
this.minX = area.minX;
this.minY = area.minY;
this.minZ = area.minZ;
this.maxX = area.maxX;
this.maxY = area.maxY;
this.maxZ = area.maxZ;
this.tier = area.tier;
this.decloak = decloak;
}
@Override
public void fromBytes(ByteBuf buffer) {
coreX = buffer.readInt();
coreY = buffer.readInt();
coreZ = buffer.readInt();
minX = buffer.readInt();
minY = buffer.readInt();
minZ = buffer.readInt();
@ -62,6 +61,9 @@ public class MessageCloak implements IMessage, IMessageHandler<MessageCloak, IMe
@Override
public void toBytes(ByteBuf buffer) {
buffer.writeInt(coreX);
buffer.writeInt(coreY);
buffer.writeInt(coreZ);
buffer.writeInt(minX);
buffer.writeInt(minY);
buffer.writeInt(minZ);
@ -74,66 +76,12 @@ public class MessageCloak implements IMessage, IMessageHandler<MessageCloak, IMe
@SideOnly(Side.CLIENT)
private void handle(EntityClientPlayerMP player) {
// Hide the area
if (!decloak) {
if (WarpDriveConfig.LOGGING_CLOAKING) {
WarpDrive.logger.info("Received cloak packet: Removing blocks...");
}
// Hide the blocks within area
World worldObj = player.worldObj;
Block cloakBlockID = (tier == 1) ? WarpDrive.blockGas : Blocks.air;
int cloakBlockMetadata = (tier == 1) ? 5 : 0;
int minYmap = Math.max(0, minY);
int maxYmap = Math.min(255, maxY);
for (int y = minYmap; y <= maxYmap; y++) {
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
Block block = worldObj.getBlock(x, y, z);
if (!block.isAssociatedBlock(Blocks.air)) {
// 1.6.4 was skipping CC peripherals with metadata 2 and 4 here...
worldObj.setBlock(x, y, z, cloakBlockID, cloakBlockMetadata, 4);
}
}
}
}
if (WarpDriveConfig.LOGGING_CLOAKING) {
WarpDrive.logger.info("Received cloak packet: Removing entities...");
}
// Hide any entities inside area
AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(minX, minY, minZ, maxX + 1, maxY + 1, maxZ + 1);
List<Entity> list = worldObj.getEntitiesWithinAABBExcludingEntity(player, aabb);
for (Entity e : list) {
worldObj.removeEntity(e);
((WorldClient) worldObj).removeEntityFromWorld(e.getEntityId());
}
} else { // reveal the area
player.worldObj.markBlockRangeForRenderUpdate(minX - 1, Math.max(0, minY - 1), minZ - 1, maxX + 1, Math.min(255, maxY + 1), maxZ + 1);
// Make some graphics
int numLasers = 80 + player.worldObj.rand.nextInt(50);
double centerX = (minX + maxX) / 2.0D;
double centerY = (minY + maxY) / 2.0D;
double centerZ = (minZ + maxZ) / 2.0D;
double radiusX = (maxX - minX) / 2.0D + 5.0D;
double radiusY = (maxY - minY) / 2.0D + 5.0D;
double radiusZ = (maxZ - minZ) / 2.0D + 5.0D;
for (int i = 0; i < numLasers; i++) {
FMLClientHandler.instance().getClient().effectRenderer.addEffect(new EntityFXBeam(player.worldObj,
new Vector3(
centerX + radiusX * player.worldObj.rand.nextGaussian(),
centerY + radiusY * player.worldObj.rand.nextGaussian(),
centerZ + radiusZ * player.worldObj.rand.nextGaussian()),
new Vector3(
centerX + radiusX * player.worldObj.rand.nextGaussian(),
centerY + radiusY * player.worldObj.rand.nextGaussian(),
centerZ + radiusZ * player.worldObj.rand.nextGaussian()),
player.worldObj.rand.nextFloat(), player.worldObj.rand.nextFloat(), player.worldObj.rand.nextFloat(),
60 + player.worldObj.rand.nextInt(60), 100));
}
if (decloak) {
// reveal the area
WarpDrive.cloaks.removeCloakedArea(player.worldObj.provider.dimensionId, coreX, coreY, coreZ);
} else {
// Hide the area
WarpDrive.cloaks.updateCloakedArea(player.worldObj, player.worldObj.provider.dimensionId, coreX, coreY, coreZ, tier, minX, minY, minZ, maxX, maxY, maxZ);
}
}

View file

@ -22,6 +22,7 @@ import cr0s.warpdrive.network.MessageBeamEffect;
import cr0s.warpdrive.network.MessageTargeting;
import cr0s.warpdrive.WarpDrive;
import cr0s.warpdrive.config.WarpDriveConfig;
import cr0s.warpdrive.data.CloakedArea;
import cr0s.warpdrive.data.Vector3;
public class PacketHandler {
@ -111,11 +112,11 @@ public class PacketHandler {
}
// Sending cloaking area definition (server -> client)
public static void sendCloakPacket(EntityPlayer player, final AxisAlignedBB aabb, final byte tier, final boolean decloak) {
MessageCloak cloakMessage = new MessageCloak(aabb, tier, decloak);
public static void sendCloakPacket(EntityPlayer player, CloakedArea area, final boolean decloak) {
MessageCloak cloakMessage = new MessageCloak(area, decloak);
simpleNetworkManager.sendTo(cloakMessage, (EntityPlayerMP) player);
if (WarpDriveConfig.LOGGING_CLOAKING) {
WarpDrive.logger.info("Sent cloak packet (aabb " + aabb + " tier " + tier + " decloak " + decloak + ")");
WarpDrive.logger.info("Sent cloak packet (area " + area + " decloak " + decloak + ")");
}
}