Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public enum SingleOperation implements IPeripheralOperation<SingleOperationConte
SUCK(1000, 1),
USE_ON_ANIMAL(2500, 10),
CAPTURE_ANIMAL(50_000, 100),
WARP(1000, DistancePolicy.IGNORED, CountPolicy.MULTIPLY, 1, DistancePolicy.SQRT, CountPolicy.MULTIPLY);
WARP(1000, DistancePolicy.IGNORED, CountPolicy.MULTIPLY, 1, DistancePolicy.SQRT, CountPolicy.MULTIPLY),
PREPARE_PORTAL(3_000, 600),
ACTIVE_PORTAL(60_000, 1);

private final int defaultCooldown;
private final DistancePolicy distanceCooldownPolicy;
Expand All @@ -34,7 +36,7 @@ public enum SingleOperation implements IPeripheralOperation<SingleOperationConte
}

SingleOperation(int defaultCooldown, int defaultCost) {
this(defaultCooldown, DistancePolicy.IGNORED, CountPolicy.MULTIPLY, defaultCost, DistancePolicy.IGNORED, CountPolicy.MULTIPLY);
this(defaultCooldown, DistancePolicy.IGNORED, CountPolicy.IGNORED, defaultCost, DistancePolicy.IGNORED, CountPolicy.IGNORED);
}

@Override
Expand Down Expand Up @@ -88,6 +90,7 @@ public int getFactor(int distance) {
}

public enum CountPolicy {
IGNORED(c -> 1),
MULTIPLY(c -> c);

private final UnaryOperator<Integer> factorFunction;
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
package de.srendi.advancedperipherals.common.entity;

import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.shared.computer.core.ServerComputer;
import dan200.computercraft.shared.turtle.core.TurtleBrain;
import de.srendi.advancedperipherals.AdvancedPeripherals;
import de.srendi.advancedperipherals.common.setup.APEntities;
import de.srendi.advancedperipherals.common.util.ChunkManager;
import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.projectile.ThrowableProjectile;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;

import java.util.List;
import java.util.function.Consumer;
import org.jetbrains.annotations.Nullable;

public class TurtleEnderPearl extends ThrowableProjectile {

private ITurtleAccess turtle = null;
private BlockPos spawnPos = null;
private Consumer<TurtleEnderPearl> callback = null;
private int life = 20;
private boolean changedDim = false;

public TurtleEnderPearl(EntityType<TurtleEnderPearl> type, Level world) {
super(type, world);
this.noPhysics = true;
this.setNoGravity(true);
}

public TurtleEnderPearl(ITurtleAccess turtle, @Nullable Direction direction) {
this(APEntities.TURTLE_ENDER_PEARL.get(), turtle.getLevel());
this.turtle = turtle;
this.spawnPos = turtle.getPosition();
this.setPos(Vec3.atCenterOf(this.spawnPos));
if (direction == null) {
direction = turtle.getDirection();
}
this.setDeltaMovement(Vec3.atLowerCornerOf(direction.getNormal()).scale(1 / 20.0));
}

@Nullable
public ITurtleAccess getTurtle() {
return turtle;
}

public void setCallback(Consumer<TurtleEnderPearl> callback) {
this.callback = callback;
}

@Nullable
private ServerComputer getServerComputer() {
if (this.turtle instanceof TurtleBrain turtle) {
return turtle.getOwner().createServerComputer();
}
return null;
}

@Override
public Packet<?> getAddEntityPacket() {
return new ClientboundAddEntityPacket(this);
}

@Override
public void readAdditionalSaveData(CompoundTag storage) {}

@Override
public void addAdditionalSaveData(CompoundTag storage) {}

@Override
protected void defineSynchedData() {}

@Override
public void tick() {
if (this.level.isClientSide) {
super.tick();
return;
}
if (this.turtle == null) {
this.discard();
return;
}
if (this.life < 0) {
this.life--;
// clean after 5s
if (this.life < -100) {
this.discard();
return;
}
return;
}
if (this.life == 0) {
this.life = -1;
this.setDeltaMovement(Vec3.ZERO);
this.moveTo(Vec3.atCenterOf(this.blockPosition()));
AdvancedPeripherals.debug("Turtle Ender Pearl stabled: " + this.toString());
if (this.callback != null) {
this.callback.accept(this);
}
return;
}
this.life--;
super.tick();
}

// TODO: the turtle ender pearl should have a fancy and 999w flash render
public static class Renderer extends EntityRenderer<TurtleEnderPearl> {
public Renderer(EntityRendererProvider.Context ctx) {
super(ctx);
}

@Override
public boolean shouldRender(TurtleEnderPearl entity, Frustum view, double x, double y, double z) {
return entity.turtle != null && super.shouldRender(entity, view, x, y, z);
}

@Override
public ResourceLocation getTextureLocation(TurtleEnderPearl entity) {
return null;
}
}

@Override
public void remove(Entity.RemovalReason reason) {
super.remove(reason);
if (reason.shouldDestroy()) {
if (this.callback != null) {
this.callback.accept(null);
}
}
}

@Override
public void restoreFrom(Entity entity) {
super.restoreFrom(entity);
if (!(entity instanceof TurtleEnderPearl oldPearl)) {
return;
}
this.turtle = oldPearl.turtle;
this.callback = oldPearl.callback;
this.life = oldPearl.life + 20;
this.changedDim = true;
}

@Override
public boolean canChangeDimensions() {
return !this.changedDim && super.canChangeDimensions();
}

@Override
public Entity changeDimension(ServerLevel newWorld) {
if (this.changedDim) {
return null;
}
Entity newEntity = super.changeDimension(newWorld);
this.changedDim = newEntity != null;
if (newEntity instanceof TurtleEnderPearl newPearl) {
AdvancedPeripherals.debug("Turtle Ender Pearl crossed to dimension " + newWorld.dimension().toString());
newPearl.spawnPos = newPearl.blockPosition();
ChunkManager.get(newWorld).addForceChunk(newWorld, newPearl.getUUID(), newPearl.chunkPosition());
if (newWorld.dimension() == Level.END) {
newPearl.life = 0;
// do not spawn turtle on the obsidian platform
final int maxHeight = newWorld.getMaxBuildHeight();
int lowestY = maxHeight;
for (; lowestY > newPearl.spawnPos.getY() + 2; lowestY--) {
if (!newWorld.getBlockState(newPearl.spawnPos.atY(lowestY - 1)).isAir()) {
break;
}
}
AdvancedPeripherals.debug("Turtle Ender Pearl lowest Y: " + lowestY);
for (int y = lowestY; y <= maxHeight; y++) {
BlockPos pos = newPearl.spawnPos.atY(y);
List<TurtleEnderPearl> pearlList = newWorld.<TurtleEnderPearl>getEntities(APEntities.TURTLE_ENDER_PEARL.get(), new AABB(pos), entity -> true);
if (pearlList.isEmpty()) {
AdvancedPeripherals.debug("Turtle Ender Pearl moved to " + pos);
newPearl.moveTo(Vec3.atCenterOf(pos));
break;
}
}
}
}
return newEntity;
}

@Override
protected void onHit(HitResult hit) {
if (hit.getType() == HitResult.Type.BLOCK) {
BlockHitResult blockHit = (BlockHitResult) hit;
if (this.spawnPos == null || !this.spawnPos.equals(blockHit.getBlockPos())) {
this.discard();
}
}
}

@Override
protected boolean canHitEntity(Entity entity) {
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package de.srendi.advancedperipherals.common.setup;

import de.srendi.advancedperipherals.AdvancedPeripherals;
import de.srendi.advancedperipherals.common.entity.TurtleEnderPearl;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.minecraftforge.registries.RegistryObject;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.EntityRenderersEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

@Mod.EventBusSubscriber(modid = AdvancedPeripherals.MOD_ID, value = Dist.CLIENT, bus = Mod.EventBusSubscriber.Bus.MOD)
public class APEntities {

public static final RegistryObject<EntityType<TurtleEnderPearl>> TURTLE_ENDER_PEARL = APRegistration.ENTITIES.register("turtle_ender_pearl",
() -> EntityType.Builder.<TurtleEnderPearl>of(TurtleEnderPearl::new, MobCategory.MISC)
.sized(0.5F, 0.5F)
.clientTrackingRange(4)
.updateInterval(5)
.fireImmune()
.build("turtle_ender_pearl"));

public static void register() {
}

@SubscribeEvent
public static void livingRender(EntityRenderersEvent.RegisterRenderers event) {
event.registerEntityRenderer(TURTLE_ENDER_PEARL.get(), TurtleEnderPearl.Renderer::new);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import dan200.computercraft.api.pocket.PocketUpgradeSerialiser;
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
import de.srendi.advancedperipherals.AdvancedPeripherals;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.ai.village.poi.PoiType;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.inventory.MenuType;
Expand All @@ -18,6 +19,7 @@ public class APRegistration {

public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, AdvancedPeripherals.MOD_ID);
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, AdvancedPeripherals.MOD_ID);
public static final DeferredRegister<EntityType<?>> ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, AdvancedPeripherals.MOD_ID);
public static final DeferredRegister<BlockEntityType<?>> TILE_ENTITIES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, AdvancedPeripherals.MOD_ID);
public static final DeferredRegister<MenuType<?>> CONTAINER_TYPES = DeferredRegister.create(ForgeRegistries.MENU_TYPES, AdvancedPeripherals.MOD_ID);
public static final DeferredRegister<PoiType> POI_TYPES = DeferredRegister.create(ForgeRegistries.POI_TYPES, AdvancedPeripherals.MOD_ID);
Expand All @@ -29,6 +31,7 @@ public static void register() {
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
BLOCKS.register(modEventBus);
ITEMS.register(modEventBus);
ENTITIES.register(modEventBus);
TILE_ENTITIES.register(modEventBus);
CONTAINER_TYPES.register(modEventBus);
POI_TYPES.register(modEventBus);
Expand All @@ -39,6 +42,7 @@ public static void register() {
APBlocks.register();
APBlockEntityTypes.register();
APItems.register();
APEntities.register();
APContainerTypes.register();
APVillagers.register();
CCRegistration.register();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@
import de.srendi.advancedperipherals.AdvancedPeripherals;
import de.srendi.advancedperipherals.common.configuration.APConfig;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Registry;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.nbt.*;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.ChunkPos;
import net.minecraftforge.server.ServerLifecycleHooks;
import org.apache.logging.log4j.Level;

import java.util.Map;
Expand Down Expand Up @@ -65,6 +71,18 @@ public static BlockPos blockPosFromNBT(CompoundTag nbt) {
return new BlockPos(nbt.getInt("x"), nbt.getInt("y"), nbt.getInt("z"));
}

public static Pair<net.minecraft.world.level.Level, BlockPos> levelAndBlockPosFromNBT(CompoundTag nbt) {
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
ServerLevel level = server.getLevel(ResourceKey.create(Registry.DIMENSION_REGISTRY, new ResourceLocation(nbt.getString("dim"))));
return new Pair(level, blockPosFromNBT(nbt));
}

public static CompoundTag toNBT(net.minecraft.world.level.Level level, BlockPos pos) {
CompoundTag data = toNBT(pos);
data.putString("dim", level.dimension().location().toString());
return data;
}

public static CompoundTag toNBT(ChunkPos pos) {
CompoundTag data = new CompoundTag();
data.putInt("x", pos.x);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import java.util.function.Consumer;
import java.util.function.Function;

public class Pair<T, V> {
public final class Pair<T, V> {
private final T left;
private final V right;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@ public interface IBasePeripheral<T extends IPeripheralOwner> extends IPeripheral

Iterable<IComputerAccess> getConnectedComputers();

default void queueEvent(String event, Object... args) {
for (IComputerAccess computer : getConnectedComputers()) {
computer.queueEvent(event, args);
}
}

T getPeripheralOwner();
}