Skip to content

Commit

Permalink
#788 levita rail
Browse files Browse the repository at this point in the history
  • Loading branch information
MBatt1 committed Nov 6, 2024
1 parent d7ed242 commit 79b6559
Show file tree
Hide file tree
Showing 35 changed files with 391 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ private static Settings cherineTorch() {
public static final FoodBowlBlock FOOD_BOWL = add("food_bowl", new FoodBowlBlock(create().mapColor(MapColor.DULL_RED).strength(2.5f).sounds(BlockSoundGroup.WOOD).nonOpaque()), cutoutMippedRenderLayer);
public static final Block TREE_TAP = add("tree_tap", new TreeTapBlock(create().mapColor(MapColor.SPRUCE_BROWN).strength(2.5f).sounds(BlockSoundGroup.WOOD).nonOpaque().ticksRandomly()), cutoutRenderLayer);
public static final NitraBlock NITRA_BUNCH = add("nitra_bunch", new NitraBlock(create().mapColor(MapColor.PALE_YELLOW).strength(0.5f).sounds(BlockSoundGroup.WET_GRASS)));
public static final Block LEVITA_RAIL = add("levita_rail", new LevitaRailBlock(create().noCollision().strength(0.7F).sounds(BlockSoundGroup.METAL)), cutoutMippedRenderLayer);

public static void init() {
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package net.id.paradiselost.blocks.mechanical;

import net.id.paradiselost.component.ParadiseLostComponents;
import net.id.paradiselost.entities.ParadiseLostEntityExtensions;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.PoweredRailBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.world.World;

import java.util.List;
import java.util.function.Predicate;

public class LevitaRailBlock extends PoweredRailBlock {

public LevitaRailBlock(AbstractBlock.Settings settings) {
super(settings);
}

@Override
protected void onEntityCollision(BlockState state, World world, BlockPos pos, Entity entity) {
if (!world.isClient) {
List<AbstractMinecartEntity> list = this.getCarts(world, pos, AbstractMinecartEntity.class, e -> true);
for (AbstractMinecartEntity cart : list) {
var floatingComponent = ParadiseLostComponents.FLOATING_KEY.get(cart);
floatingComponent.startFloating();
ParadiseLostComponents.FLOATING_KEY.sync(cart);
}
}
}

private <T extends AbstractMinecartEntity> List<T> getCarts(World world, BlockPos pos, Class<T> entityClass, Predicate<Entity> entityPredicate) {
return world.getEntitiesByClass(entityClass, this.getCartDetectionBox(pos), entityPredicate);
}

private Box getCartDetectionBox(BlockPos pos) {
double radius = 0.4;
return new Box(
pos.getX() + radius,
pos.getY(),
pos.getZ() + radius,
pos.getX() + 1 - radius,
pos.getY() + 1 - radius,
pos.getZ() + 1 - radius
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package net.id.paradiselost.client.rendering.particle;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.particle.ParticleFactory;
import net.minecraft.client.particle.ParticleTextureSheet;
import net.minecraft.client.particle.SpriteBillboardParticle;
import net.minecraft.client.particle.SpriteProvider;
import net.minecraft.client.particle.SuspendParticle;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.particle.SimpleParticleType;

/*
* Basically just a SuspendParticle, but that particle isn't public :I
* These are bigger than normal suspend particles though
*/
public class LevitaBloopParticle extends SpriteBillboardParticle {

LevitaBloopParticle(ClientWorld clientWorld, double d, double e, double f, double g, double h, double i) {
super(clientWorld, d, e, f, g, h, i);
float j = this.random.nextFloat() * 0.1F + 0.2F;
this.red = j;
this.green = j;
this.blue = j;
this.setBoundingBoxSpacing(0.02F, 0.02F);
this.scale = this.scale * (this.random.nextFloat() * 0.7F + 1.1F);
this.velocityX *= 0.02F;
this.velocityY *= 0.02F;
this.velocityZ *= 0.02F;
this.maxAge = (int)(20.0 / (Math.random() * 0.8 + 0.2));
}

@Override
public ParticleTextureSheet getType() {
return ParticleTextureSheet.PARTICLE_SHEET_OPAQUE;
}

@Override
public void move(double dx, double dy, double dz) {
this.setBoundingBox(this.getBoundingBox().offset(dx, dy, dz));
this.repositionFromBoundingBox();
}

@Override
public void tick() {
this.prevPosX = this.x;
this.prevPosY = this.y;
this.prevPosZ = this.z;
if (this.maxAge-- <= 0) {
this.markDead();
} else {
this.move(this.velocityX, this.velocityY, this.velocityZ);
this.velocityX *= 0.99;
this.velocityY *= 0.99;
this.velocityZ *= 0.99;
}
}

@Environment(EnvType.CLIENT)
public static class DefaultFactory implements ParticleFactory<SimpleParticleType> {
private final SpriteProvider spriteProvider;

public DefaultFactory(SpriteProvider spriteProvider) {
this.spriteProvider = spriteProvider;
}

public Particle createParticle(SimpleParticleType simpleParticleType, ClientWorld clientWorld, double d, double e, double f, double g, double h, double i) {
LevitaBloopParticle suspendParticle = new LevitaBloopParticle(clientWorld, d, e, f, g, h, i);
suspendParticle.setColor(0.5F, 0.45F, 1.0F);
suspendParticle.setSprite(this.spriteProvider);
suspendParticle.setAlpha(1.0F - clientWorld.random.nextFloat() * 0.7F);
suspendParticle.setMaxAge(suspendParticle.getMaxAge() / 2);
return suspendParticle;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.id.paradiselost.ParadiseLost;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleType;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
Expand All @@ -23,6 +24,7 @@ public class ParadiseLostParticles {
public static SimpleParticleType MOTHER_AUREL_LEAF = register("golden_leaf");
public static SimpleParticleType FALLING_ORANGE_PETAL = register("falling_orange_petal");
public static SimpleParticleType CHERINE_FLAME = register("cherine_flame");
public static SimpleParticleType LEVITA_BLOOP = register("levita_bloop");

/**
* Registers a simple particle type.
Expand Down Expand Up @@ -52,6 +54,7 @@ public static void init() {
register(MOTHER_AUREL_LEAF, MotherAurelLeafParticle.DefaultFactory::new);
register(FALLING_ORANGE_PETAL, FallingOrangePetalParticle.DefaultFactory::new);
register(CHERINE_FLAME, CherineFlameParticle.DefaultFactory::new);
register(LEVITA_BLOOP, LevitaBloopParticle.DefaultFactory::new);
}

/**
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/net/id/paradiselost/component/FloatingComponent.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package net.id.paradiselost.component;

import net.minecraft.nbt.NbtCompound;
import net.minecraft.registry.RegistryWrapper;
import org.ladysnake.cca.api.v3.component.sync.AutoSyncedComponent;

public class FloatingComponent implements AutoSyncedComponent {

private static final int FLOAT_SECONDS = 4;
private boolean floating = false;
private int floatTime = 0;

@Override
public void readFromNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
floating = tag.getBoolean("floating");
floatTime = tag.getInt("floatTime");
}

@Override
public void writeToNbt(NbtCompound tag, RegistryWrapper.WrapperLookup registryLookup) {
tag.putBoolean("floating", floating);
tag.putInt("floatTime", floatTime);
}

public boolean getFloating() {
return floating;
}

public int getFloatTime() {
return floatTime;
}

public void startFloating() {
floating = true;
floatTime = 20 * FLOAT_SECONDS;
}

public void tick() {
floatTime--;
if (floatTime == 0) {
floating = false;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import net.id.paradiselost.ParadiseLost;
import net.id.paradiselost.entities.passive.moa.MoaEntity;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import org.ladysnake.cca.api.v3.component.ComponentKey;
import org.ladysnake.cca.api.v3.component.ComponentRegistry;
import org.ladysnake.cca.api.v3.entity.EntityComponentFactoryRegistry;
Expand All @@ -10,9 +11,11 @@
public class ParadiseLostComponents implements EntityComponentInitializer {

public static final ComponentKey<MoaGenes> MOA_GENETICS_KEY = ComponentRegistry.getOrCreate(ParadiseLost.locate("moa_genetics"), MoaGenes.class);
public static final ComponentKey<FloatingComponent> FLOATING_KEY = ComponentRegistry.getOrCreate(ParadiseLost.locate("minecart_float"), FloatingComponent.class);

@Override
public void registerEntityComponentFactories(EntityComponentFactoryRegistry registry) {
registry.registerFor(MoaEntity.class, MOA_GENETICS_KEY, moa -> new MoaGenes());
registry.registerFor(AbstractMinecartEntity.class, FLOATING_KEY, cart -> new FloatingComponent());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ public class ParadiseLostItemGroups {
entries.add(AMADRYS_BUNDLE);
entries.add(NITRA_BUNCH);
entries.add(LEVITATOR);
entries.add(LEVITA_RAIL);
entries.add(INCUBATOR);
entries.add(FOOD_BOWL);
entries.add(TREE_TAP);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ private static Settings food(FoodComponent foodComponent) {
public static final BlockItem FOOD_BOWL = add(ParadiseLostBlocks.FOOD_BOWL, fuel(300));
public static final BlockItem TREE_TAP = add(ParadiseLostBlocks.TREE_TAP, fuel(300));
public static final BlockItem NITRA_BUNCH = add(ParadiseLostBlocks.NITRA_BUNCH, fuel(3200));
public static final BlockItem LEVITA_RAIL = add(ParadiseLostBlocks.LEVITA_RAIL);

public static final AurelBucketItem AUREL_BUCKET = add("aurel_bucket", new AurelBucketItem(new Settings().maxCount(16)), fuel(200), emptyBucketBehavior);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package net.id.paradiselost.mixin.entity;

import net.id.paradiselost.client.rendering.particle.ParadiseLostParticles;
import net.id.paradiselost.component.ParadiseLostComponents;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.MovementType;
import net.minecraft.entity.vehicle.AbstractMinecartEntity;
import net.minecraft.entity.vehicle.VehicleEntity;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
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;

@Mixin(AbstractMinecartEntity.class)
public abstract class AbstractMinecartEntityMixin extends VehicleEntity {

public AbstractMinecartEntityMixin(EntityType<?> entityType, World world) {
super(entityType, world);
}

@Shadow
private boolean onRail;

@Shadow
protected abstract double getMaxSpeed();

@Inject(method = "moveOffRail", at = @At("HEAD"), cancellable = true)
protected void moveOffRail(CallbackInfo ci) {
var floatingComponent = ParadiseLostComponents.FLOATING_KEY.get(this);
if (!this.isOnGround() && floatingComponent.getFloating() && floatingComponent.getFloatTime() > 0) {
double d = this.getMaxSpeed();
Vec3d vec3d = this.getVelocity();
this.setVelocity(MathHelper.clamp(vec3d.x, -d, d), 0, MathHelper.clamp(vec3d.z, -d, d));
this.move(MovementType.SELF, this.getVelocity());
// decrement
floatingComponent.tick();
ParadiseLostComponents.FLOATING_KEY.sync(this);
ci.cancel();
}
}

@Inject(method = "tick", at = @At("HEAD"))
public void tick(CallbackInfo ci) {
var floatingComponent = ParadiseLostComponents.FLOATING_KEY.get(this);
if (this.getWorld().isClient && !this.onRail && floatingComponent.getFloating()) {
var pos = this.getPos();
var rightParticlePos = pos.add(this.getVelocity().normalize().multiply(0.35F).rotateY(1.57F));
var leftParticlePos = pos.add(this.getVelocity().normalize().multiply(0.35F).rotateY(-1.57F));
this.getWorld().addParticle(ParadiseLostParticles.LEVITA_BLOOP, rightParticlePos.getX(), this.getY(), rightParticlePos.getZ(), 0, 0, 0);
this.getWorld().addParticle(ParadiseLostParticles.LEVITA_BLOOP, leftParticlePos.getX(), this.getY(), leftParticlePos.getZ(), 0, 0, 0);
}
}
}
27 changes: 0 additions & 27 deletions src/main/java/net/id/paradiselost/mixin/entity/EntityMixin.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"variants": {
"powered=false,shape=ascending_east": {
"model": "paradise_lost:block/levita_rail_raised_ne",
"y": 90
},
"powered=false,shape=ascending_north": {
"model": "paradise_lost:block/levita_rail_raised_ne"
},
"powered=false,shape=ascending_south": {
"model": "paradise_lost:block/levita_rail_raised_sw"
},
"powered=false,shape=ascending_west": {
"model": "paradise_lost:block/levita_rail_raised_sw",
"y": 90
},
"powered=false,shape=east_west": {
"model": "paradise_lost:block/levita_rail",
"y": 90
},
"powered=false,shape=north_south": {
"model": "paradise_lost:block/levita_rail"
},
"powered=true,shape=ascending_east": {
"model": "paradise_lost:block/levita_rail_on_raised_ne",
"y": 90
},
"powered=true,shape=ascending_north": {
"model": "paradise_lost:block/levita_rail_on_raised_ne"
},
"powered=true,shape=ascending_south": {
"model": "paradise_lost:block/levita_rail_on_raised_sw"
},
"powered=true,shape=ascending_west": {
"model": "paradise_lost:block/levita_rail_on_raised_sw",
"y": 90
},
"powered=true,shape=east_west": {
"model": "paradise_lost:block/levita_rail_on",
"y": 90
},
"powered=true,shape=north_south": {
"model": "paradise_lost:block/levita_rail_on"
}
}
}
1 change: 1 addition & 0 deletions src/main/resources/assets/paradise_lost/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@
"block.paradise_lost.food_bowl": "Feeding Trough",
"block.paradise_lost.tree_tap": "Tree Tap",
"block.paradise_lost.nitra_bunch": "Nitra Bunch",
"block.paradise_lost.levita_rail": "Levita Rail",


"container.paradise_lost.moa": "Moa",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"parent": "minecraft:block/rail_flat",
"textures": {
"rail": "paradise_lost:block/levita_rail"
}
}
Loading

0 comments on commit 79b6559

Please sign in to comment.