Permalink
Browse files

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.
  • Loading branch information...
1 parent 455adec commit cb113050a7aaa8ac88e3326cf59859b33cab9e2d @Vazkii committed Jun 19, 2015
@@ -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 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 @@
* 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,14 +63,23 @@
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";
private static final String TAG_ROTATION_X = "rotationX";
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 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 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 void updateEntity() {
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 void updateEntity() {
@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 void writeCustomNBT(NBTTagCompound cmp) {
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 void readCustomNBT(NBTTagCompound cmp) {
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 void tryShootBurst() {
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 int getLastBurstDeathTick() {
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;
+ }
}
Oops, something went wrong.

2 comments on commit cb11305

@SoniEx2

I like this fix.

@bookerthegeek

Is this something I can drop on our server only to test or would players also need this?

Please sign in to comment.