Skip to content

Commit

Permalink
initial sonic syphon implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
gliscowo committed Nov 20, 2024
1 parent e202cc1 commit 539696e
Show file tree
Hide file tree
Showing 32 changed files with 501 additions and 53 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
fabric_version=0.102.0+1.21

# Mod Properties
mod_version=0.1.5
mod_version=0.1.6
maven_group=io.wispforest
archives_base_name=affinity

Expand Down
19 changes: 19 additions & 0 deletions src/generated/assets/affinity/blockstates/sonic_syphon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"variants": {
"facing=east": {
"model": "affinity:block/sonic_syphon",
"y": 90
},
"facing=north": {
"model": "affinity:block/sonic_syphon"
},
"facing=south": {
"model": "affinity:block/sonic_syphon",
"y": 180
},
"facing=west": {
"model": "affinity:block/sonic_syphon",
"y": 270
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "affinity:item/pitcher_elixir_bottle"
}
}
3 changes: 3 additions & 0 deletions src/generated/assets/affinity/models/item/sonic_syphon.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"parent": "affinity:block/sonic_syphon"
}
8 changes: 8 additions & 0 deletions src/generated/data/affinity/tags/item/unfinished.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"values": [
"affinity:villager_arms",
"affinity:villager_armature",
"affinity:sonic_syphon",
"affinity:pitcher_elixir_bottle"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package io.wispforest.affinity.block.impl;

import com.mojang.serialization.MapCodec;
import io.wispforest.affinity.blockentity.impl.SonicSyphonBlockEntity;
import io.wispforest.affinity.blockentity.template.TickedBlockEntity;
import io.wispforest.affinity.object.AffinityBlocks;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityTicker;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.state.StateManager;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

public class SonicSyphonBlock extends HorizontalFacingBlock implements BlockEntityProvider {

public static final VoxelShape NORTH_SHAPE = VoxelShapes.union(
Block.createCuboidShape(0, 0, 8, 16, 16, 16),
Block.createCuboidShape(3, 3, 1, 13, 13, 8)
);
public static final VoxelShape SOUTH_SHAPE = VoxelShapes.union(
Block.createCuboidShape(0, 0, 0, 16, 16, 8),
Block.createCuboidShape(3, 3, 8, 13, 13, 15)
);
public static final VoxelShape EAST_SHAPE = VoxelShapes.union(
Block.createCuboidShape(0, 0, 0, 8, 16, 16),
Block.createCuboidShape(8, 3, 3, 15, 13, 13)
);
public static final VoxelShape WEST_SHAPE = VoxelShapes.union(
Block.createCuboidShape(8, 0, 0, 16, 16, 16),
Block.createCuboidShape(1, 3, 3, 8, 13, 13)
);

public SonicSyphonBlock(Settings settings) {
super(settings);
this.setDefaultState(this.getDefaultState().with(FACING, Direction.NORTH));
}

@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder);
builder.add(FACING);
}

@Override
public @Nullable BlockState getPlacementState(ItemPlacementContext ctx) {
var side = ctx.getSide();
if (side.getAxis() == Direction.Axis.Y) {
side = ctx.getHorizontalPlayerFacing().getOpposite();
}

return this.getDefaultState().with(FACING, side);
}

@Override
protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return switch (state.get(FACING)) {
case EAST -> EAST_SHAPE;
case WEST -> WEST_SHAPE;
case SOUTH -> SOUTH_SHAPE;
default -> NORTH_SHAPE;
};
}

@Override
public @Nullable BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new SonicSyphonBlockEntity(pos, state);
}

@Override
@SuppressWarnings("unchecked")
public @Nullable <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
return !world.isClient && type == AffinityBlocks.Entities.SONIC_SYPHON ? (BlockEntityTicker<T>) TickedBlockEntity.ticker() : null;
}

@Override
protected MapCodec<? extends HorizontalFacingBlock> getCodec() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package io.wispforest.affinity.blockentity.impl;

import io.wispforest.affinity.block.impl.SonicSyphonBlock;
import io.wispforest.affinity.blockentity.template.SyncedBlockEntity;
import io.wispforest.affinity.blockentity.template.TickedBlockEntity;
import io.wispforest.affinity.misc.ServerTasks;
import io.wispforest.affinity.object.AffinityBlocks;
import io.wispforest.affinity.object.AffinityItems;
import io.wispforest.affinity.object.AffinityParticleSystems;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.PitcherCropBlock;
import net.minecraft.block.enums.DoubleBlockHalf;
import net.minecraft.entity.ItemEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;

public class SonicSyphonBlockEntity extends SyncedBlockEntity implements TickedBlockEntity {

private int time = 0;

public SonicSyphonBlockEntity(BlockPos pos, BlockState state) {
super(AffinityBlocks.Entities.SONIC_SYPHON, pos, state);
}

@Override
public void tickServer() {
this.time++;

if (this.time % 30 == 0) {
var facing = this.getCachedState().get(SonicSyphonBlock.FACING);

var potentialPodPos = this.pos.offset(facing);
var potentialPodState = this.world.getBlockState(potentialPodPos);
if (this.getPitcherAge(potentialPodState, DoubleBlockHalf.LOWER) < 4) return;

AffinityParticleSystems.DIRECTIONAL_SHRIEK.spawn(
this.world,
Vec3d.ofCenter(this.pos),
facing
);

ServerTasks.doFor((ServerWorld) this.world, 24, (tick) -> {
if (tick % 6 != 0) return true;

int targetAge = 4 - (tick / 6);

var testState = this.world.getBlockState(potentialPodPos);
if (this.getPitcherAge(testState, DoubleBlockHalf.LOWER) == targetAge + 1) {
this.world.setBlockState(potentialPodPos, testState.with(PitcherCropBlock.AGE, targetAge));
} else {
return false;
}

var upperTestState = this.world.getBlockState(potentialPodPos.up());
if (targetAge >= 2) {
if (this.getPitcherAge(upperTestState, DoubleBlockHalf.UPPER) == targetAge + 1) {
if (targetAge >= 3) {
this.world.setBlockState(potentialPodPos.up(), upperTestState.with(PitcherCropBlock.AGE, targetAge));
} else {
this.world.removeBlock(potentialPodPos.up(), false);
}
} else {
return false;
}
}

return true;
}, () -> {
var spawnPos = Vec3d.ofCenter(potentialPodPos, .75);
var item = new ItemEntity(this.world, spawnPos.x, spawnPos.y, spawnPos.z, AffinityItems.PITCHER_ELIXIR_BOTTLE.getDefaultStack());

item.setVelocity(facing.getOffsetX() * .5, facing.getOffsetY() * .5, facing.getOffsetZ() * .5);
this.world.spawnEntity(item);
});
}
}

private int getPitcherAge(BlockState state, DoubleBlockHalf half) {
return state.getBlock() == Blocks.PITCHER_CROP && state.get(PitcherCropBlock.HALF) == half
? state.get(PitcherCropBlock.AGE)
: -1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ public void onInitializeClient() {
ParticleFactoryRegistry.getInstance().register(AffinityParticleTypes.GENERIC_EMITTER, new GenericEmitterParticle.Factory());
ParticleFactoryRegistry.getInstance().register(AffinityParticleTypes.ORBITING_EMITTER, new OrbitingEmitterParticle.Factory());
ParticleFactoryRegistry.getInstance().register(AffinityParticleTypes.COLORED_FALLING_DUST, ColoredFallingDustParticleEffect.ParticleFactory::new);
ParticleFactoryRegistry.getInstance().register(AffinityParticleTypes.DIRECTIONAL_SHRIEK, DirectionalShriekParticle.Factory::new);

EntityRendererRegistry.register(AffinityEntities.INERT_WISP, WispEntityRenderer::new);
EntityRendererRegistry.register(AffinityEntities.WISE_WISP, WispEntityRenderer::new);
Expand Down Expand Up @@ -356,5 +357,6 @@ private void assignBlockRenderLayers() {
BlockRenderLayerMap.INSTANCE.putBlock(AffinityBlocks.ARCANE_TREETAP, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(AffinityBlocks.RITUAL_SOCLE_COMPOSER, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(AffinityBlocks.VOID_BEACON, RenderLayer.getCutout());
BlockRenderLayerMap.INSTANCE.putBlock(AffinityBlocks.SONIC_SYPHON, RenderLayer.getCutout());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.wispforest.affinity.client.particle;

import io.wispforest.affinity.particle.DirectionalShriekParticleEffect;
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.ShriekParticle;
import net.minecraft.client.particle.SpriteProvider;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import org.joml.Quaternionf;

public class DirectionalShriekParticle extends ShriekParticle {

private final Direction direction;

protected DirectionalShriekParticle(ClientWorld world, double x, double y, double z, int delay, Direction direction) {
super(world, x, y, z, delay);
this.direction = direction;

this.velocityX = direction.getOffsetX() * .1;
this.velocityY = direction.getOffsetY() * .1;
this.velocityZ = direction.getOffsetZ() * .1;
}

@Override
public void buildGeometry(VertexConsumer vertexConsumer, Camera camera, float tickDelta) {
if (this.delay <= 0) {
var facing = new Quaternionf(this.direction.getOpposite().getRotationQuaternion());

this.alpha = 1.0F - MathHelper.clamp(((float) this.age + tickDelta) / (float) this.maxAge, 0.0F, 1.0F);
Quaternionf quaternionf = new Quaternionf(facing);
quaternionf.rotateX(-1.0472F);
this.method_60373(vertexConsumer, camera, quaternionf, tickDelta);
quaternionf.set(facing);
quaternionf.rotateYXZ((float) -Math.PI, 1.0472F, 0.0F);
this.method_60373(vertexConsumer, camera, quaternionf, tickDelta);
}
}

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

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

public Particle createParticle(DirectionalShriekParticleEffect effect, ClientWorld clientWorld, double d, double e, double f, double g, double h, double i) {
ShriekParticle shriekParticle = new DirectionalShriekParticle(clientWorld, d, e, f, effect.delay(), effect.direction());
shriekParticle.setSprite(this.spriteProvider);
return shriekParticle;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public void generateBlockStateModels(BlockStateModelGenerator generator) {
FIELD_COHERENCE_MODULATOR, GRAVITON_TRANSDUCER, ETHEREAL_AETHUM_FLUX_NODE, LOCAL_DISPLACEMENT_GATEWAY, AZALEA_CHEST
);

generator.registerNorthDefaultHorizontalRotation(SONIC_SYPHON);
generator.registerNorthDefaultHorizontalRotation(VILLAGER_ARMATURE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void generateItemModels(ItemModelGenerator generator) {
EMERALD_NUGGET, FEATHERWEIGHT_RING, SCINTILLANT_ANTHRACITE_BLEND, UNFIRED_CLAY_CUP, CLAY_CUP, RESONANCE_CRYSTAL, SYNTHETIC_DRAGON_HEART,
ARCHETYPAL_IRON_RING, WISPEN_TESTAMENT, LAVALIERE_OF_SAFE_KEEPING, CRYSTALLIZED_EXPERIENCE, BUDDING_EXPERIENCE_CRYSTAL,
INERT_WISP_MIST, VICIOUS_WISP_MIST, WISE_WISP_MIST, ASSASSINS_QUIVER, CRYSTALLINE_WISP_MATTER_COMPOSITE, MILK_CUP,
SCULK_RESONANT_ETHEREAL_AMETHYST_SHARD, EVADE_RING, BLACKSTONE_PRISM, PHANTOM_BUNDLE
SCULK_RESONANT_ETHEREAL_AMETHYST_SHARD, EVADE_RING, BLACKSTONE_PRISM, PHANTOM_BUNDLE, PITCHER_ELIXIR_BOTTLE
);

forAll(generator, Models.HANDHELD,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ protected void configure(RegistryWrapper.WrapperLookup arg) {

this.getOrCreateTagBuilder(UnfinishedFeaturesResourceCondition.UNFINISHED_ITEMS).add(
VILLAGER_ARMS,
AffinityBlocks.VILLAGER_ARMATURE.asItem()
AffinityBlocks.VILLAGER_ARMATURE.asItem(),
AffinityBlocks.SONIC_SYPHON.asItem(),
PITCHER_ELIXIR_BOTTLE
);

this.copy(ConventionalBlockTags.ORES, ConventionalItemTags.ORES);
Expand Down
20 changes: 10 additions & 10 deletions src/main/java/io/wispforest/affinity/item/AffinityItemGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import net.minecraft.registry.Registries;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.village.VillagerData;
import net.minecraft.village.VillagerProfession;
import net.minecraft.village.VillagerType;

Expand Down Expand Up @@ -92,6 +91,7 @@ private static void initializeGroup(OwoItemGroup group) {
entries.add(VOID_RESONANT_ETHEREAL_AMETHYST_SHARD);
entries.add(ARCANE_FADE_BUCKET);
entries.add(AETHUM_FLUX_BOTTLE);
if (Affinity.config().unfinishedFeatures()) entries.add(PITCHER_ELIXIR_BOTTLE);
entries.add(EMERALD_BLOCK);
entries.add(EMERALD_INGOT);
entries.add(EMERALD_NUGGET);
Expand Down Expand Up @@ -172,11 +172,11 @@ private static void initializeGroup(OwoItemGroup group) {
entries.add(ResplendentGemItem.make(AffinityEnchantments.BASTION, wrapper));

wrapper.streamEntries()
.filter(entry -> entry.registryKey().getValue().getNamespace().equals(Affinity.MOD_ID))
.filter(enchantment -> !enchantment.value().effects().contains(AffinityEnchantmentEffectComponents.ABSOLUTE_NAME_HUE))
.map(enchantment -> new EnchantmentLevelEntry(enchantment, enchantment.value().getMaxLevel()))
.map(EnchantedBookItem::forEnchantment)
.forEach(entries::add);
.filter(entry -> entry.registryKey().getValue().getNamespace().equals(Affinity.MOD_ID))
.filter(enchantment -> !enchantment.value().effects().contains(AffinityEnchantmentEffectComponents.ABSOLUTE_NAME_HUE))
.map(enchantment -> new EnchantmentLevelEntry(enchantment, enchantment.value().getMaxLevel()))
.map(EnchantedBookItem::forEnchantment)
.forEach(entries::add);
});

context.lookup().getOptionalWrapper(RegistryKeys.POTION).ifPresent(wrapper -> {
Expand Down Expand Up @@ -248,10 +248,10 @@ private static void initializeGroup(OwoItemGroup group) {

private static void addPotions(ItemGroup.Entries entries, RegistryWrapper<Potion> registryWrapper, Item containerItem) {
registryWrapper.streamEntries()
.filter(entry -> entry.registryKey().getValue().getNamespace().equals(Affinity.MOD_ID))
.filter(entry -> !entry.matches(Potions.WATER))
.map(entry -> PotionContentsComponent.createStack(containerItem, entry))
.forEach(entries::add);
.filter(entry -> entry.registryKey().getValue().getNamespace().equals(Affinity.MOD_ID))
.filter(entry -> !entry.matches(Potions.WATER))
.map(entry -> PotionContentsComponent.createStack(containerItem, entry))
.forEach(entries::add);
}

private static boolean isChyz() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import io.wispforest.affinity.client.render.InWorldTooltipProvider;
import io.wispforest.affinity.object.AffinityItems;
import io.wispforest.affinity.object.AffinityParticleSystems;
import io.wispforest.endec.impl.KeyedEndec;
import io.wispforest.owo.ops.TextOps;
import io.wispforest.owo.particles.ClientParticles;
import io.wispforest.owo.serialization.CodecUtils;
Expand Down
Loading

0 comments on commit 539696e

Please sign in to comment.