Skip to content

Commit

Permalink
make the MinecartController system a little more sane
Browse files Browse the repository at this point in the history
 fixes issues with minecarts
  • Loading branch information
TropheusJ committed Jul 17, 2023
1 parent cf18c19 commit 7a260c3
Show file tree
Hide file tree
Showing 13 changed files with 64 additions and 149 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,13 @@ protected void tickContraption() {
tickActors();
boolean isStalled = isStalled();

LazyOptional<MinecartController> capability;
MinecartController capability = null;
if(riding instanceof AbstractMinecart minecart)
capability = minecart.lazyController();
else
capability = LazyOptional.empty();
if (capability.isPresent()) {
capability = minecart.create$getController();

if (capability != null) {
if (!level().isClientSide())
capability.orElse(null)
capability
.setStalledExternally(isStalled);
} else {
if (isStalled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,9 @@ public class CouplingHandler {

public static boolean preventEntitiesFromMoutingOccupiedCart(Entity vehicle, Entity passenger) {
if (vehicle instanceof AbstractMinecart cart) {
LazyOptional<MinecartController> optional = cart.lazyController();
if (!optional.isPresent())
return true;
if (passenger instanceof AbstractContraptionEntity)
return true;
MinecartController controller = optional.orElse(null);
MinecartController controller = cart.create$getController();
if (controller.isCoupledThroughContraption()) {
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,7 @@ public static InteractionResult handleInteractionWithMinecart(Player player, Lev
AbstractMinecart minecart = (AbstractMinecart) interacted;
if (player == null)
return InteractionResult.PASS;
LazyOptional<MinecartController> capability = minecart.lazyController();
if (!capability.isPresent())
return InteractionResult.PASS;
MinecartController controller = capability.orElse(null);
MinecartController controller = minecart.create$getController();

ItemStack heldItem = player.getItemInHand(hand);
if (AllItems.MINECART_COUPLING.isIn(heldItem)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ public static boolean canAddMotion(AbstractMinecart c) {
if (c instanceof MinecartFurnace)
return Mth.equal(((MinecartFurnace) c).xPush, 0)
&& Mth.equal(((MinecartFurnace) c).zPush, 0);
LazyOptional<MinecartController> capability = c.lazyController();
if (capability.isPresent() && capability.orElse(null)
if (c.create$getController()
.isStalled())
return false;
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public static void tick(Level world) {

cartsWithCoupling.remove(uniqueID);

MinecartController controller = cart.getController();
MinecartController controller = cart.create$getController();
// capability.addListener(new MinecartRemovalListener(world, cart)); // fabric: handled via AbstractMinecartMixin
carts.put(uniqueID, controller);

Expand Down Expand Up @@ -195,55 +195,14 @@ public static MinecartController getIfPresent(Level world, UUID cartId) {
return carts.get(cartId);
}

/* Capability management */

// public static Capability<MinecartController> MINECART_CONTROLLER_CAPABILITY =
// CapabilityManager.get(new CapabilityToken<>() {
// });

public static void attach(AbstractMinecart entity) {
CapabilityMinecartController capability = new CapabilityMinecartController((AbstractMinecart) entity);
// ResourceLocation id = Create.asResource("minecart_controller");
((AbstractMinecartExtensions) entity).setCap(capability);
// ((AbstractMinecartExtensions) entity).addListener((cart) -> { // fabric: handled via AbstractMinecartMixin
// if (capability.cap.isPresent())
// capability.cap.invalidate();
// });
queuedAdditions.get(entity.getCommandSenderWorld())
.add((AbstractMinecart) entity);
.add(entity);
}

public static void startTracking(Entity entity) {
if (!(entity instanceof AbstractMinecart cart))
return;
cart.getController().sendData();
cart.create$getController().sendData();
}

/* Capability provider */

public final LazyOptional<MinecartController> cap;
public MinecartController handler;

public CapabilityMinecartController(AbstractMinecart minecart) {
handler = new MinecartController(minecart);
cap = LazyOptional.of(() -> handler);
}

// @Override
// public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
// if (cap == MINECART_CONTROLLER_CAPABILITY)
// return this.cap.cast();
// return LazyOptional.empty();
// }

@Override
public CompoundTag serializeNBT() {
return handler.serializeNBT();
}

@Override
public void deserializeNBT(CompoundTag nbt) {
handler.deserializeNBT(nbt);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,7 @@ private void handleCL() {
Entity entityByID = world.getEntity(entityID);
if (entityByID == null)
return;
((AbstractMinecart) entityByID).lazyController()
.ifPresent(mc -> mc.deserializeNBT(nbt));
((AbstractMinecart) entityByID).create$getController().deserializeNBT(nbt);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,7 @@ protected void assemble(Level world, BlockPos pos, AbstractMinecart cart) {
.isEmpty())
return;

LazyOptional<MinecartController> optional = cart.lazyController();
if (optional.isPresent() && optional.orElse(null)
if (cart.create$getController()
.isCoupledThroughContraption())
return;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,11 @@
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.CameraAngleAnimationService;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.foundation.utility.fabric.AbstractMinecartExtensions;
import com.simibubi.create.foundation.utility.worldWrappers.WrappedClientWorld;
import com.simibubi.create.infrastructure.config.AllConfigs;
import com.simibubi.create.infrastructure.gui.OpenCreateMenuButton;

import io.github.fabricators_of_create.porting_lib.client_events.event.client.RenderArmCallback;
import io.github.fabricators_of_create.porting_lib.entity.events.EntityDataEvents;
import io.github.fabricators_of_create.porting_lib.entity.events.EntityMountEvents;
import io.github.fabricators_of_create.porting_lib.entity.events.player.PlayerTickEvents;
import io.github.fabricators_of_create.porting_lib.event.client.CameraSetupCallback;
Expand All @@ -86,7 +84,6 @@
import io.github.fabricators_of_create.porting_lib.event.client.InteractEvents;
import io.github.fabricators_of_create.porting_lib.event.client.ParticleManagerRegistrationCallback;
import io.github.fabricators_of_create.porting_lib.event.client.RenderHandCallback;
import io.github.fabricators_of_create.porting_lib.event.client.RenderHandCallback.RenderHandEvent;
import io.github.fabricators_of_create.porting_lib.event.client.RenderTickStartCallback;
import io.github.fabricators_of_create.porting_lib.event.client.RenderTooltipBorderColorCallback;
import io.github.fabricators_of_create.porting_lib.event.common.AttackAirCallback;
Expand Down Expand Up @@ -421,8 +418,6 @@ public static void register() {

// External Events

ClientEntityEvents.ENTITY_LOAD.register(AbstractMinecartExtensions::minecartSpawn);
ClientEntityEvents.ENTITY_UNLOAD.register(AbstractMinecartExtensions::minecartRemove);
ClientTickEvents.END_CLIENT_TICK.register(SymmetryHandler::onClientTick);
WorldRenderEvents.AFTER_TRANSLUCENT.register(SymmetryHandler::render);
UseBlockCallback.EVENT.register(ArmInteractionPointHandler::rightClickingBlocksSelectsThem);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
import com.simibubi.create.foundation.recipe.RecipeFinder;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.foundation.utility.WorldAttached;
import com.simibubi.create.foundation.utility.fabric.AbstractMinecartExtensions;
import com.simibubi.create.infrastructure.command.AllCommands;

import io.github.fabricators_of_create.porting_lib.event.common.BlockEvents;
Expand Down Expand Up @@ -180,9 +179,9 @@ public static void onUnloadWorld(Executor executor, LevelAccessor world) {
}

// handled by AbstractMinecartMixin
public static void attachCapabilities(AbstractMinecart cart) {
CapabilityMinecartController.attach(cart);
}
// public static void attachCapabilities(AbstractMinecart cart) {
// CapabilityMinecartController.attach(cart);
// }

public static void startTracking(Entity target, ServerPlayer player) {
CapabilityMinecartController.startTracking(target);
Expand Down Expand Up @@ -268,10 +267,6 @@ public static void register() {
BlockEvents.AFTER_PLACE.register(SuperGlueHandler::glueListensForBlockPlacement);
EntityEvents.PROJECTILE_IMPACT.register(BlazeBurnerHandler::onThrowableImpact);
EntityDataEvents.LOAD.register(ExtendoGripItem::addReachToJoiningPlayersHoldingExtendo);
ServerEntityEvents.ENTITY_LOAD.register(AbstractMinecartExtensions::minecartSpawn);
EntityDataEvents.LOAD.register(AbstractMinecartExtensions::minecartRead);
EntityDataEvents.SAVE.register(AbstractMinecartExtensions::minecartWrite);
ServerEntityEvents.ENTITY_UNLOAD.register(AbstractMinecartExtensions::minecartRemove);
PlayerBlockBreakEvents.BEFORE.register(SymmetryHandler::onBlockDestroyed);
}
}
Original file line number Diff line number Diff line change
@@ -1,37 +1,49 @@
package com.simibubi.create.foundation.mixin.fabric;

import com.simibubi.create.content.contraptions.minecart.capability.CapabilityMinecartController;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;

import com.simibubi.create.content.contraptions.minecart.capability.CapabilityMinecartController;
import com.simibubi.create.content.contraptions.minecart.capability.MinecartController;
import com.simibubi.create.foundation.utility.fabric.AbstractMinecartExtensions;

import io.github.fabricators_of_create.porting_lib.util.LazyOptional;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.level.Level;

@Mixin(AbstractMinecart.class)
public abstract class AbstractMinecartMixin implements AbstractMinecartExtensions {
@Unique
public CapabilityMinecartController create$controllerCap = null;

@Override
public CapabilityMinecartController getCap() {
return create$controllerCap;
private MinecartController controller;

@Inject(method = "<init>(Lnet/minecraft/world/entity/EntityType;Lnet/minecraft/world/level/Level;)V", at = @At("RETURN"))
private void initController(EntityType<?> entityType, Level level, CallbackInfo ci) {
this.controller = new MinecartController((AbstractMinecart) (Object) this);
if (level != null) { // don't trust modders
CapabilityMinecartController.attach((AbstractMinecart) (Object) this);
}
}

@Override
public void setCap(CapabilityMinecartController cap) {
this.create$controllerCap = cap;
@Inject(method = "readAdditionalSaveData", at = @At("HEAD"))
private void loadController(CompoundTag compound, CallbackInfo ci) {
if (compound.contains(CAP_KEY, Tag.TAG_COMPOUND))
controller.deserializeNBT(compound.getCompound(CAP_KEY));
}

@Override
public LazyOptional<MinecartController> lazyController() {
return create$controllerCap.cap;
@Inject(method = "addAdditionalSaveData", at = @At("HEAD"))
private void saveController(CompoundTag compound, CallbackInfo ci) {
compound.put(CAP_KEY, controller.serializeNBT());
}

@Override
public MinecartController getController() {
return create$controllerCap.handler;
public MinecartController create$getController() {
return controller;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.simibubi.create.foundation.mixin.fabric;

import com.google.common.collect.ImmutableList;
import com.simibubi.create.content.contraptions.minecart.capability.CapabilityMinecartController;
import com.simibubi.create.foundation.ponder.PonderWorld;

import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Entity.RemovalReason;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.border.WorldBorder;
import net.minecraft.world.phys.AABB;
Expand All @@ -14,8 +17,10 @@
import io.github.fabricators_of_create.porting_lib.mixin.accessors.common.accessor.EntityAccessor;

import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import javax.annotation.Nullable;
Expand All @@ -24,6 +29,18 @@

@Mixin(Entity.class)
public abstract class EntityMixin {
@Shadow
public abstract Level level();

// AbstractMinecart does not override remove, so we have to inject here.
@Inject(method = "remove", at = @At("HEAD"))
private void removeMinecartController(RemovalReason reason, CallbackInfo ci) {
//noinspection ConstantValue
if ((Object) this instanceof AbstractMinecart cart) {
CapabilityMinecartController.onCartRemoved(level(), cart);
}
}

/**
* @author AeiouEnigma
* @reason We stan Lithium's collision optimizations but need to ensure they aren't applied in Create's PonderWorld.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,9 @@
package com.simibubi.create.foundation.utility.fabric;

import com.simibubi.create.content.contraptions.minecart.capability.CapabilityMinecartController;
import com.simibubi.create.content.contraptions.minecart.capability.MinecartController;

import io.github.fabricators_of_create.porting_lib.util.LazyOptional;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.vehicle.AbstractMinecart;
import net.minecraft.world.level.Level;

public interface AbstractMinecartExtensions {
CapabilityMinecartController getCap();

void setCap(CapabilityMinecartController cap);

LazyOptional<MinecartController> lazyController();

MinecartController getController();
MinecartController create$getController();

String CAP_KEY = "Controller";

static void minecartSpawn(Entity entity, Level level) {
if (entity instanceof AbstractMinecart cart)
CapabilityMinecartController.attach(cart);
}

static void minecartRead(Entity entity, CompoundTag data) {
if (entity instanceof AbstractMinecart cart && data.contains(CAP_KEY)) {
CompoundTag cap = data.getCompound(CAP_KEY);
cart.getCap().deserializeNBT(cap);
}
}

static void minecartWrite(Entity entity, CompoundTag data) {
if (entity instanceof AbstractMinecart cart && cart.getCap() != null) {
CompoundTag capTag = cart.getCap().serializeNBT();
data.put(CAP_KEY, capTag);
}
}

static void minecartRemove(Entity entity, Level level) {
if (entity instanceof AbstractMinecart cart) {
CapabilityMinecartController.onCartRemoved(level, cart);
cart.lazyController().invalidate();
}
}
}
Loading

0 comments on commit 7a260c3

Please sign in to comment.