Playtest Issues, Part IV

- Added null-safety in in-world item processing handlers
- Fixed basin-based components not resetting when their speed reaches 0
- Fan-based recipes now scale processing time based on stacksize of the input
- Belts now automatically search for attachments on load
- Removed duplicate recipe
This commit is contained in:
simibubi 2020-03-17 14:25:40 +01:00
parent f26c80560d
commit 4eaa077390
6 changed files with 94 additions and 98 deletions

View file

@ -38,10 +38,10 @@ import net.minecraftforge.common.Tags;
public class AirCurrent { public class AirCurrent {
private static DamageSource damageSourceFire = new DamageSource("create.fan_fire").setDifficultyScaled() private static DamageSource damageSourceFire =
.setFireDamage(); new DamageSource("create.fan_fire").setDifficultyScaled().setFireDamage();
private static DamageSource damageSourceLava = new DamageSource("create.fan_lava").setDifficultyScaled() private static DamageSource damageSourceLava =
.setFireDamage(); new DamageSource("create.fan_lava").setDifficultyScaled().setFireDamage();
public final EncasedFanTileEntity source; public final EncasedFanTileEntity source;
public AxisAlignedBB bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0); public AxisAlignedBB bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
@ -84,12 +84,12 @@ public class AirCurrent {
Vec3d previousMotion = entity.getMotion(); Vec3d previousMotion = entity.getMotion();
float maxAcceleration = 5; float maxAcceleration = 5;
double xIn = MathHelper.clamp(flow.getX() * acceleration - previousMotion.x, -maxAcceleration, double xIn =
maxAcceleration); MathHelper.clamp(flow.getX() * acceleration - previousMotion.x, -maxAcceleration, maxAcceleration);
double yIn = MathHelper.clamp(flow.getY() * acceleration - previousMotion.y, -maxAcceleration, double yIn =
maxAcceleration); MathHelper.clamp(flow.getY() * acceleration - previousMotion.y, -maxAcceleration, maxAcceleration);
double zIn = MathHelper.clamp(flow.getZ() * acceleration - previousMotion.z, -maxAcceleration, double zIn =
maxAcceleration); MathHelper.clamp(flow.getZ() * acceleration - previousMotion.z, -maxAcceleration, maxAcceleration);
entity.setMotion(previousMotion.add(new Vec3d(xIn, yIn, zIn).scale(1 / 8f))); entity.setMotion(previousMotion.add(new Vec3d(xIn, yIn, zIn).scale(1 / 8f)));
entity.fallDistance = 0; entity.fallDistance = 0;
@ -99,29 +99,36 @@ public class AirCurrent {
entityDistance -= .5f; entityDistance -= .5f;
InWorldProcessing.Type processingType = getSegmentAt((float) entityDistance); InWorldProcessing.Type processingType = getSegmentAt((float) entityDistance);
if (entity instanceof ItemEntity) { if (processingType != null) {
InWorldProcessing.spawnParticlesForProcessing(world, entity.getPositionVec(), processingType); if (entity instanceof ItemEntity) {
if (InWorldProcessing.canProcess(((ItemEntity) entity), processingType)) InWorldProcessing.spawnParticlesForProcessing(world, entity.getPositionVec(), processingType);
InWorldProcessing.applyProcessing((ItemEntity) entity, processingType); if (InWorldProcessing.canProcess(((ItemEntity) entity), processingType))
InWorldProcessing.applyProcessing((ItemEntity) entity, processingType);
} else { } else {
if (processingType == InWorldProcessing.Type.SMOKING) { switch (processingType) {
entity.setFire(2); case BLASTING:
entity.attackEntityFrom(damageSourceFire, 2); entity.setFire(10);
} entity.attackEntityFrom(damageSourceLava, 4);
if (processingType == InWorldProcessing.Type.BLASTING) { break;
entity.setFire(10); case SMOKING:
entity.attackEntityFrom(damageSourceLava, 4); entity.setFire(2);
} entity.attackEntityFrom(damageSourceFire, 2);
if (processingType == InWorldProcessing.Type.SPLASHING) { break;
if (entity.isBurning()) { case SPLASHING:
if (!entity.isBurning())
break;
entity.extinguish(); entity.extinguish();
world.playSound(null, entity.getPosition(), SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE, world.playSound(null, entity.getPosition(), SoundEvents.ENTITY_GENERIC_EXTINGUISH_FIRE,
SoundCategory.NEUTRAL, 0.7F, SoundCategory.NEUTRAL, 0.7F,
1.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.4F); 1.6F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.4F);
break;
default:
break;
} }
} }
} }
} }
tickBelts(); tickBelts();
@ -169,11 +176,11 @@ public class AirCurrent {
} }
for (Vec3d offset : offsets) { for (Vec3d offset : offsets) {
Vec3d rayStart = VecHelper.getCenterOf(currentPos).subtract(directionVec.scale(.5f + 1 / 32f)) Vec3d rayStart =
.add(offset); VecHelper.getCenterOf(currentPos).subtract(directionVec.scale(.5f + 1 / 32f)).add(offset);
Vec3d rayEnd = rayStart.add(directionVec.scale(1 + 1 / 32f)); Vec3d rayEnd = rayStart.add(directionVec.scale(1 + 1 / 32f));
BlockRayTraceResult blockraytraceresult = world.rayTraceBlocks(rayStart, rayEnd, currentPos, voxelshape, BlockRayTraceResult blockraytraceresult =
state); world.rayTraceBlocks(rayStart, rayEnd, currentPos, voxelshape, state);
if (blockraytraceresult == null) if (blockraytraceresult == null)
continue Outer; continue Outer;
@ -240,20 +247,20 @@ public class AirCurrent {
affectedBelts.clear(); affectedBelts.clear();
for (int i = 0; i < maxDistance + 1; i++) { for (int i = 0; i < maxDistance + 1; i++) {
Type type = getSegmentAt(i); Type type = getSegmentAt(i);
if (type != null) { if (type == null)
BlockPos pos = start.offset(direction, i); continue;
TileEntity te = world.getTileEntity(pos); BlockPos pos = start.offset(direction, i);
if (te != null && (te instanceof BeltTileEntity)) TileEntity te = world.getTileEntity(pos);
affectedBelts.add(Pair.of((BeltTileEntity) te, type)); if (te != null && (te instanceof BeltTileEntity))
if (direction.getAxis().isVertical())
continue;
pos = pos.down();
te = world.getTileEntity(pos);
if (te == null || !(te instanceof BeltTileEntity))
continue;
affectedBelts.add(Pair.of((BeltTileEntity) te, type)); affectedBelts.add(Pair.of((BeltTileEntity) te, type));
} if (direction.getAxis().isVertical())
continue;
pos = pos.down();
te = world.getTileEntity(pos);
if (te == null || !(te instanceof BeltTileEntity))
continue;
affectedBelts.add(Pair.of((BeltTileEntity) te, type));
} }
} }

View file

@ -315,6 +315,9 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
protected void basinRemoved() { protected void basinRemoved() {
pressedItems.clear(); pressedItems.clear();
super.basinRemoved(); super.basinRemoved();
running = false;
runningTicks = 0;
sendData();
} }
} }

View file

@ -38,6 +38,8 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
@Override @Override
public void onSpeedChanged(float prevSpeed) { public void onSpeedChanged(float prevSpeed) {
super.onSpeedChanged(prevSpeed); super.onSpeedChanged(prevSpeed);
if (getSpeed() == 0)
basinRemoved = true;
checkBasin = true; checkBasin = true;
} }
@ -66,6 +68,8 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
if (!isSpeedRequirementFulfilled()) if (!isSpeedRequirementFulfilled())
return; return;
if (getSpeed() == 0)
return;
if (!isCheckingBasin()) if (!isCheckingBasin())
return; return;
if (!checkBasin) if (!checkBasin)
@ -83,11 +87,6 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
return; return;
gatherInputs(); gatherInputs();
// if (matchBasinRecipe(lastRecipe)) {
// startProcessingBasin();
// sendData();
// return;
// }
List<IRecipe<?>> recipes = getMatchingRecipes(); List<IRecipe<?>> recipes = getMatchingRecipes();
if (recipes.isEmpty()) if (recipes.isEmpty())
return; return;
@ -96,7 +95,7 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
startProcessingBasin(); startProcessingBasin();
sendData(); sendData();
} }
protected boolean isCheckingBasin() { protected boolean isCheckingBasin() {
return true; return true;
} }
@ -121,7 +120,7 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
IItemHandlerModifiable inputs = inv.getInputHandler(); IItemHandlerModifiable inputs = inv.getInputHandler();
IItemHandlerModifiable outputs = inv.getOutputHandler(); IItemHandlerModifiable outputs = inv.getOutputHandler();
List<ItemStack> catalysts = new ArrayList<>(); List<ItemStack> catalysts = new ArrayList<>();
int buckets = 0; int buckets = 0;
Ingredients: for (Ingredient ingredient : lastRecipe.getIngredients()) { Ingredients: for (Ingredient ingredient : lastRecipe.getIngredients()) {
for (int slot = 0; slot < inputs.getSlots(); slot++) { for (int slot = 0; slot < inputs.getSlots(); slot++) {
@ -130,7 +129,7 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
ItemStack extracted = inputs.extractItem(slot, 1, false); ItemStack extracted = inputs.extractItem(slot, 1, false);
if (extracted.getItem() instanceof BucketItem) if (extracted.getItem() instanceof BucketItem)
buckets++; buckets++;
if ((lastRecipe instanceof ProcessingRecipe)) { if ((lastRecipe instanceof ProcessingRecipe)) {
ProcessingRecipe<?> pr = (ProcessingRecipe<?>) lastRecipe; ProcessingRecipe<?> pr = (ProcessingRecipe<?>) lastRecipe;
if (pr.getRollableIngredients().get(slot).remains()) if (pr.getRollableIngredients().get(slot).remains())
@ -150,7 +149,7 @@ public abstract class BasinOperatingTileEntity extends KineticTileEntity {
// Continue mixing // Continue mixing
gatherInputs(); gatherInputs();
if (matchBasinRecipe(lastRecipe)) { if (matchBasinRecipe(lastRecipe)) {
continueWithPreviousRecipe(); continueWithPreviousRecipe();
sendData(); sendData();
} }
} }

View file

@ -161,8 +161,10 @@ public enum AllBeltAttachments {
public void readAndSearch(CompoundNBT nbt, BeltTileEntity belt) { public void readAndSearch(CompoundNBT nbt, BeltTileEntity belt) {
attachments.clear(); attachments.clear();
if (!nbt.contains("HasAttachments")) if (!nbt.contains("HasAttachments")) {
findAttachments(belt);
return; return;
}
if (nbt.contains("AttachmentData")) { if (nbt.contains("AttachmentData")) {
ListNBT list = (ListNBT) nbt.get("AttachmentData"); ListNBT list = (ListNBT) nbt.get("AttachmentData");
for (INBT data : list) { for (INBT data : list) {

View file

@ -51,9 +51,7 @@ public class InWorldProcessing {
public static SplashingInv splashingInv = new SplashingInv(); public static SplashingInv splashingInv = new SplashingInv();
public enum Type { public enum Type {
SMOKING, SMOKING, BLASTING, SPLASHING
BLASTING,
SPLASHING
; ;
@ -137,7 +135,10 @@ public class InWorldProcessing {
Type type) { Type type) {
if (transported.processedBy != type) { if (transported.processedBy != type) {
transported.processedBy = type; transported.processedBy = type;
transported.processingTime = AllConfigs.SERVER.kinetics.inWorldProcessingTime.get() + 1; int timeModifierForStackSize = ((transported.stack.getCount() - 1) / 16) + 1;
int processingTime =
(int) (AllConfigs.SERVER.kinetics.inWorldProcessingTime.get() * timeModifierForStackSize) + 1;
transported.processingTime = processingTime;
if (!canProcess(transported.stack, type, belt.getWorld())) if (!canProcess(transported.stack, type, belt.getWorld()))
transported.processingTime = -1; transported.processingTime = -1;
return null; return null;
@ -215,7 +216,10 @@ public class InWorldProcessing {
if (!processing.contains("Type") || Type.valueOf(processing.getString("Type")) != type) { if (!processing.contains("Type") || Type.valueOf(processing.getString("Type")) != type) {
processing.putString("Type", type.name()); processing.putString("Type", type.name());
processing.putInt("Time", AllConfigs.SERVER.kinetics.inWorldProcessingTime.get() + 1); int timeModifierForStackSize = ((entity.getItem().getCount() - 1) / 16) + 1;
int processingTime =
(int) (AllConfigs.SERVER.kinetics.inWorldProcessingTime.get() * timeModifierForStackSize) + 1;
processing.putInt("Time", processingTime);
} }
int value = processing.getInt("Time") - 1; int value = processing.getInt("Time") - 1;
@ -273,19 +277,28 @@ public class InWorldProcessing {
} }
public static void spawnParticlesForProcessing(World world, Vec3d vec, Type type) { public static void spawnParticlesForProcessing(World world, Vec3d vec, Type type) {
if (world.rand.nextInt(4) == 0 && world.isRemote) { if (!world.isRemote)
if (type == Type.BLASTING) return;
world.addParticle(ParticleTypes.LARGE_SMOKE, vec.x, vec.y + .25f, vec.z, 0, 1 / 16f, 0); if (world.rand.nextInt(4) != 0)
if (type == Type.SMOKING) return;
world.addParticle(ParticleTypes.POOF, vec.x, vec.y + .25f, vec.z, 0, 1 / 16f, 0);
if (type == Type.SPLASHING) { switch (type) {
Vec3d color = ColorHelper.getRGB(0x0055FF); case BLASTING:
world.addParticle(new RedstoneParticleData((float) color.x, (float) color.y, (float) color.z, 1), world.addParticle(ParticleTypes.LARGE_SMOKE, vec.x, vec.y + .25f, vec.z, 0, 1 / 16f, 0);
vec.x + (world.rand.nextFloat() - .5f) * .5f, vec.y + .5f, break;
vec.z + (world.rand.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0); case SMOKING:
world.addParticle(ParticleTypes.SPIT, vec.x + (world.rand.nextFloat() - .5f) * .5f, vec.y + .5f, world.addParticle(ParticleTypes.POOF, vec.x, vec.y + .25f, vec.z, 0, 1 / 16f, 0);
vec.z + (world.rand.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0); break;
} case SPLASHING:
Vec3d color = ColorHelper.getRGB(0x0055FF);
world.addParticle(new RedstoneParticleData((float) color.x, (float) color.y, (float) color.z, 1),
vec.x + (world.rand.nextFloat() - .5f) * .5f, vec.y + .5f,
vec.z + (world.rand.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
world.addParticle(ParticleTypes.SPIT, vec.x + (world.rand.nextFloat() - .5f) * .5f, vec.y + .5f,
vec.z + (world.rand.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
break;
default:
break;
} }
} }

View file

@ -1,28 +0,0 @@
{
"type": "crafting_shaped",
"pattern": [
" B ",
"SCS"
],
"key": {
"S": {
"item": "create:shaft"
},
"B": {
"item": "create:integrated_circuit"
},
"C": {
"item": "create:brass_casing"
}
},
"result": {
"item": "create:rotation_speed_controller",
"count": 1
},
"conditions": [
{
"type": "create:module",
"module": "contraptions"
}
]
}