Skip to content
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
Vazkii committed Jun 19, 2015
1 parent 455adec commit cb113050a7aaa8ac88e3326cf59859b33cab9e2d
@@ -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;
}
}

2 comments on commit cb11305

@SoniEx2

This comment has been minimized.

Copy link

@SoniEx2 SoniEx2 replied Jun 23, 2015

I like this fix.

@bookerthegeek

This comment has been minimized.

Copy link

@bookerthegeek bookerthegeek replied Jun 23, 2015

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

Please sign in to comment.