Implemented a Pinging system between mana bursts and spreaders. This should fix the issue where spreaders lose the ability to fire after a chunk/world reload. (#1105) I can't reproduce it so I it'll have to be left to player testing.

This commit is contained in:
Lizbeth Rika committed 2015-06-19 22:55:26 +01:00
1 parent 455adec13d
commit cb113050a7
7 files changed
+206 -19

No files matched your search

@@ -10,6 +10,8 @@
*/
package vazkii.botania.api.internal;
import java.util.UUID;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ChunkCoordinates;
@@ -61,5 +63,11 @@ public interface IManaBurst {
public int getTicksExisted();
public void setFake(boolean fake);
public void setShooterUUID(UUID uuid);
public UUID getShooterUIID();
public void ping();
}
@@ -0,0 +1,23 @@
/**
* This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
*
* Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php
*
* File Created @ [Jun 19, 2015, 10:05:24 PM (GMT)]
*/
package vazkii.botania.api.mana;
import java.util.UUID;
/**
* This interface marks a TileEntity that can be identified through
* an UUID. This UUID must presist between sessions.
*/
public interface IIdentifiable {
public UUID getIdentifier();
}
@@ -16,7 +16,7 @@ package vazkii.botania.api.mana;
* by which can fire mana bursts as a spreader.
*
*/
public interface IManaSpreader extends IManaBlock {
public interface IManaSpreader extends IManaBlock, IPingable {
public float getRotationX();
@@ -0,0 +1,31 @@
/**
* This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
*
* Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php
*
* File Created @ [Jun 19, 2015, 9:52:05 PM (GMT)]
*/
package vazkii.botania.api.mana;
import java.util.UUID;
import vazkii.botania.api.internal.IManaBurst;
/**
* This describes an interface of a Mana Sender block that should be able to pingbackable
* by a burst to tell it that the burst is still alive.
*/
public interface IPingable extends IIdentifiable {
/**
* Pings this object back, telling it that the burst passed in is still alive
* in the world. The UUID parameter should be the UUID with which the burst
* was created, this is used to let the object handle the check for if it's the
* correct ID internally. IManaBurst implementations should do this every tick.
*/
public void pingback(IManaBurst burst, UUID expectedIdentity);
}
@@ -11,6 +11,7 @@
package vazkii.botania.common.block.tile.mana;
import java.util.List;
import java.util.UUID;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.ScaledResolution;
@@ -62,7 +63,12 @@ public class TileSpreader extends TileSimpleInventory implements IManaCollector,
private static final int MAX_MANA = 1000;
private static final int ULTRA_MAX_MANA = 6400;
private static final int TICKS_ALLOWED_WITHOUT_PINGBACK = 20;
private static final double PINGBACK_EXPIRED_SEARCH_DISTANCE = 0.5;
private static final String TAG_HAS_IDENTITY = "hasIdentity";
private static final String TAG_UUID_MOST = "uuidMost";
private static final String TAG_UUID_LEAST = "uuidLeast";
private static final String TAG_MANA = "mana";
private static final String TAG_KNOWN_MANA = "knownMana";
private static final String TAG_REQUEST_UPDATE = "requestUpdate";
@@ -70,6 +76,10 @@ public class TileSpreader extends TileSimpleInventory implements IManaCollector,
private static final String TAG_ROTATION_Y = "rotationY";
private static final String TAG_PADDING_COLOR = "paddingColor";
private static final String TAG_CAN_SHOOT_BURST = "canShootBurst";
private static final String TAG_PINGBACK_TICKS = "pingbackTicks";
private static final String TAG_LAST_PINGBACK_X = "lastPingbackX";
private static final String TAG_LAST_PINGBACK_Y = "lastPingbackY";
private static final String TAG_LAST_PINGBACK_Z = "lastPingbackZ";
private static final String TAG_FORCE_CLIENT_BINDING_X = "forceClientBindingX";
private static final String TAG_FORCE_CLIENT_BINDING_Y = "forceClientBindingY";
@@ -105,6 +115,8 @@ public class TileSpreader extends TileSimpleInventory implements IManaCollector,
public static boolean staticDreamwood = false;
public static boolean staticUltra = false;
UUID identity;
int mana;
int knownMana = -1;
public float rotationX, rotationY;
@@ -120,7 +132,12 @@ public class TileSpreader extends TileSimpleInventory implements IManaCollector,
public boolean canShootBurst = true;
public int lastBurstDeathTick = -1;
public int burstParticleTick = 0;
public int pingbackTicks = 0;
public double lastPingbackX = 0;
public double lastPingbackY = -1;
public double lastPingbackZ = 0;
List<PositionProperties> lastTentativeBurst;
boolean invalidTentativeBurst = false;
@@ -179,8 +196,28 @@ public class TileSpreader extends TileSimpleInventory implements IManaCollector,
if(needsNewBurstSimulation())
checkForReceiver();
if(!canShootBurst)
if(pingbackTicks <= 0) {
double x = lastPingbackX;
double y = lastPingbackY;
double z = lastPingbackZ;
AxisAlignedBB aabb = AxisAlignedBB.getBoundingBox(x, y, z, x, y, z).expand(PINGBACK_EXPIRED_SEARCH_DISTANCE, PINGBACK_EXPIRED_SEARCH_DISTANCE, PINGBACK_EXPIRED_SEARCH_DISTANCE);
List<IManaBurst> bursts = worldObj.getEntitiesWithinAABB(IManaBurst.class, aabb);
IManaBurst found = null;
UUID identity = getIdentifier();
for(IManaBurst burst : bursts)
if(burst != null && identity.equals(burst.getShooterUIID())) {
found = burst;
break;
}
if(found != null)
found.ping();
else setCanShoot(true);
} else pingbackTicks--;
boolean shouldShoot = !redstone;
if(isRedstone())
shouldShoot = redstone && !redstoneLastTick;
@@ -202,12 +239,23 @@ public class TileSpreader extends TileSimpleInventory implements IManaCollector,
@Override
public void writeCustomNBT(NBTTagCompound cmp) {
super.writeCustomNBT(cmp);
UUID identity = getIdentifier();
cmp.setBoolean(TAG_HAS_IDENTITY, true);
cmp.setLong(TAG_UUID_MOST, identity.getMostSignificantBits());
cmp.setLong(TAG_UUID_LEAST, identity.getLeastSignificantBits());
cmp.setInteger(TAG_MANA, mana);
cmp.setFloat(TAG_ROTATION_X, rotationX);
cmp.setFloat(TAG_ROTATION_Y, rotationY);
cmp.setBoolean(TAG_REQUEST_UPDATE, requestsClientUpdate);
cmp.setInteger(TAG_PADDING_COLOR, paddingColor);
cmp.setBoolean(TAG_CAN_SHOOT_BURST, canShootBurst);
cmp.setInteger(TAG_PINGBACK_TICKS, pingbackTicks);
cmp.setDouble(TAG_LAST_PINGBACK_X, lastPingbackX);
cmp.setDouble(TAG_LAST_PINGBACK_Y, lastPingbackY);
cmp.setDouble(TAG_LAST_PINGBACK_Z, lastPingbackZ);
cmp.setString(TAG_INPUT_KEY, inputKey);
cmp.setString(TAG_OUTPUT_KEY, outputKey);
@@ -223,13 +271,22 @@ public class TileSpreader extends TileSimpleInventory implements IManaCollector,
cmp.setFloat(TAG_FORCED_MANA_LOSS_PER_TICK, mmForcedManaLossPerTick);
cmp.setFloat(TAG_FORCED_GRAVITY, mmForcedGravity);
cmp.setFloat(TAG_FORCED_VELOCITY_MULTIPLIER, mmForcedVelocityMultiplier);
requestsClientUpdate = false;
}
@Override
public void readCustomNBT(NBTTagCompound cmp) {
super.readCustomNBT(cmp);
if(cmp.getBoolean(TAG_HAS_IDENTITY)) {
long most = cmp.getLong(TAG_UUID_MOST);
long least = cmp.getLong(TAG_UUID_LEAST);
UUID identity = getIdentifierUnsafe();
if(identity == null || most != identity.getMostSignificantBits() || least != identity.getLeastSignificantBits())
identity = new UUID(most, least);
} else getIdentifier();
mana = cmp.getInteger(TAG_MANA);
rotationX = cmp.getFloat(TAG_ROTATION_X);
rotationY = cmp.getFloat(TAG_ROTATION_Y);
@@ -254,6 +311,11 @@ public class TileSpreader extends TileSimpleInventory implements IManaCollector,
paddingColor = cmp.getInteger(TAG_PADDING_COLOR);
if(cmp.hasKey(TAG_CAN_SHOOT_BURST))
canShootBurst = cmp.getBoolean(TAG_CAN_SHOOT_BURST);
pingbackTicks = cmp.getInteger(TAG_PINGBACK_TICKS);
lastPingbackX = cmp.getDouble(TAG_LAST_PINGBACK_X);
lastPingbackY = cmp.getDouble(TAG_LAST_PINGBACK_Y);
lastPingbackZ = cmp.getDouble(TAG_LAST_PINGBACK_Z);
if(requestsClientUpdate && worldObj != null) {
int x = cmp.getInteger(TAG_FORCE_CLIENT_BINDING_X);
@@ -344,12 +406,12 @@ public class TileSpreader extends TileSimpleInventory implements IManaCollector,
if(burst != null) {
if(!worldObj.isRemote) {
mana -= burst.getStartingMana();
burst.setShooterUUID(getIdentifier());
worldObj.spawnEntityInWorld(burst);
burst.ping();
if(!ConfigHandler.silentSpreaders)
worldObj.playSoundEffect(xCoord, yCoord, zCoord, "botania:spreaderFire", 0.05F * (paddingColor != -1 ? 0.2F : 1F), 0.7F + 0.3F * (float) Math.random());
}
canShootBurst = false;
}
}
}
@@ -628,4 +690,27 @@ public class TileSpreader extends TileSimpleInventory implements IManaCollector,
public void setLastBurstDeathTick(int i) {
lastBurstDeathTick = i;
}
@Override
public void pingback(IManaBurst burst, UUID expectedIdentity) {
if(getIdentifier().equals(expectedIdentity)) {
pingbackTicks = TICKS_ALLOWED_WITHOUT_PINGBACK;
Entity e = (Entity) burst;
lastPingbackX = e.posX;
lastPingbackY = e.posY;
lastPingbackZ = e.posZ;
setCanShoot(false);
}
}
@Override
public UUID getIdentifier() {
if(identity == null)
identity = UUID.randomUUID();
return identity;
}
public UUID getIdentifierUnsafe() {
return identity;
}
}
@@ -14,6 +14,7 @@ import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import net.minecraft.block.Block;
import net.minecraft.block.BlockBush;
@@ -42,6 +43,7 @@ import vazkii.botania.api.mana.IManaCollisionGhost;
import vazkii.botania.api.mana.IManaReceiver;
import vazkii.botania.api.mana.IManaSpreader;
import vazkii.botania.api.mana.IManaTrigger;
import vazkii.botania.api.mana.IPingable;
import vazkii.botania.api.mana.IThrottledPacket;
import vazkii.botania.common.Botania;
import vazkii.botania.common.core.handler.ConfigHandler;
@@ -64,6 +66,9 @@ public class EntityManaBurst extends EntityThrowable implements IManaBurst {
private static final String TAG_LAST_MOTION_X = "lastMotionX";
private static final String TAG_LAST_MOTION_Y = "lastMotionY";
private static final String TAG_LAST_MOTION_Z = "lastMotionZ";
private static final String TAG_HAS_SHOOTER = "hasShooter";
private static final String TAG_SHOOTER_UUID_MOST = "shooterUUIDMost";
private static final String TAG_SHOOTER_UUID_LEAST = "shooterUUIDLeast";
boolean fake = false;
@@ -74,6 +79,7 @@ public class EntityManaBurst extends EntityThrowable implements IManaBurst {
boolean fullManaLastTick = true;
UUID shooterIdentity = null;
int _ticksExisted = 0;
boolean scanBeam = false;
public List<PositionProperties> propsList = new ArrayList();
@@ -352,12 +358,8 @@ public class EntityManaBurst extends EntityThrowable implements IManaBurst {
setTicksExisted(getTicksExisted() + 1);
superUpdate();
if(!fake && !isDead) {
ChunkCoordinates coords = getBurstSourceChunkCoordinates();
TileEntity tile = worldObj.getTileEntity(coords.posX, coords.posY, coords.posZ);
if(tile != null && tile instanceof IManaSpreader)
((IManaSpreader) tile).setCanShoot(false);
}
if(!fake && !isDead)
ping();
ILensEffect lens = getLensInstance();
if(lens != null)
@@ -437,6 +439,14 @@ public class EntityManaBurst extends EntityThrowable implements IManaBurst {
par1nbtTagCompound.setDouble(TAG_LAST_MOTION_X, motionX);
par1nbtTagCompound.setDouble(TAG_LAST_MOTION_Y, motionY);
par1nbtTagCompound.setDouble(TAG_LAST_MOTION_Z, motionZ);
UUID identity = getShooterUIID();
boolean hasShooter = identity != null;
par1nbtTagCompound.setBoolean(TAG_HAS_SHOOTER, hasShooter);
if(hasShooter) {
par1nbtTagCompound.setLong(TAG_SHOOTER_UUID_MOST, identity.getMostSignificantBits());
par1nbtTagCompound.setLong(TAG_SHOOTER_UUID_LEAST, identity.getLeastSignificantBits());
}
}
@Override
@@ -467,6 +477,15 @@ public class EntityManaBurst extends EntityThrowable implements IManaBurst {
double lastMotionZ = par1nbtTagCompound.getDouble(TAG_LAST_MOTION_Z);
setMotion(lastMotionX, lastMotionY, lastMotionZ);
boolean hasShooter = par1nbtTagCompound.getBoolean(TAG_HAS_SHOOTER);
if(hasShooter) {
long most = par1nbtTagCompound.getLong(TAG_SHOOTER_UUID_MOST);
long least = par1nbtTagCompound.getLong(TAG_SHOOTER_UUID_LEAST);
UUID identity = getShooterUIID();
if(identity == null || most != identity.getMostSignificantBits() || least != identity.getLeastSignificantBits())
shooterIdentity = new UUID(most, least);
}
}
public void particles() {
@@ -626,12 +645,17 @@ public class EntityManaBurst extends EntityThrowable implements IManaBurst {
super.setDead();
if(!fake) {
ChunkCoordinates coords = getBurstSourceChunkCoordinates();
TileEntity tile = worldObj.getTileEntity(coords.posX, coords.posY, coords.posZ);
TileEntity tile = getShooter();
if(tile != null && tile instanceof IManaSpreader)
((IManaSpreader) tile).setCanShoot(true);
} else setDeathTicksForFakeParticle();
}
public TileEntity getShooter() {
ChunkCoordinates coords = getBurstSourceChunkCoordinates();
TileEntity tile = worldObj.getTileEntity(coords.posX, coords.posY, coords.posZ);
return tile;
}
@Override
protected float getGravityVelocity() {
@@ -781,20 +805,35 @@ public class EntityManaBurst extends EntityThrowable implements IManaBurst {
return x + ":" + y + ":" + z;
}
@Override
public void setShooterUUID(UUID uuid) {
shooterIdentity = uuid;
}
@Override
public UUID getShooterUIID() {
return shooterIdentity;
}
@Override
public void ping() {
TileEntity tile = getShooter();
if(tile != null && tile instanceof IPingable)
((IPingable) tile).pingback(this, getShooterUIID());
}
public boolean shouldDoFakeParticles() {
if(ConfigHandler.staticWandBeam)
return true;
ChunkCoordinates coords = getBurstSourceChunkCoordinates();
TileEntity tile = worldObj.getTileEntity(coords.posX, coords.posY, coords.posZ);
TileEntity tile = getShooter();
if(tile != null && tile instanceof IManaSpreader)
return getMana() != getStartingMana() && fullManaLastTick || Math.abs(((IManaSpreader) tile).getBurstParticleTick() - getTicksExisted()) < 4;
return false;
}
public void incrementFakeParticleTick() {
ChunkCoordinates coords = getBurstSourceChunkCoordinates();
TileEntity tile = worldObj.getTileEntity(coords.posX, coords.posY, coords.posZ);
TileEntity tile = getShooter();
if(tile != null && tile instanceof IManaSpreader) {
IManaSpreader spreader = (IManaSpreader) tile;
spreader.setBurstParticleTick(spreader.getBurstParticleTick()+2);
@@ -842,4 +881,5 @@ public class EntityManaBurst extends EntityThrowable implements IManaBurst {
return block == this.block && meta == this.meta;
}
}
}
@@ -19,7 +19,7 @@ public final class LibMisc {
public static final String MOD_NAME = MOD_ID;
public static final String BUILD = "GRADLE:BUILD";
public static final String VERSION = "GRADLE:VERSION-" + BUILD;
public static final String DEPENDENCIES = "required-after:Forge@[10.13.2.1236,);required-after:Baubles;after:Thaumcraft";
public static final String DEPENDENCIES = "required-after:Baubles;after:Thaumcraft";
// Network Contants
public static final String NETWORK_CHANNEL = MOD_ID;