Skip to content

Commit

Permalink
Add Sticky effects, make Slime and Honey usable with fluid nozzle
Browse files Browse the repository at this point in the history
  • Loading branch information
Patbox committed Dec 15, 2024
1 parent 74f1b40 commit b40a83e
Show file tree
Hide file tree
Showing 59 changed files with 502 additions and 68 deletions.
7 changes: 6 additions & 1 deletion changelog-next.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
- New block that allows you to add and remove items from Shulker Boxes, bundles and any other storage api compatible item!
- You place/remove the storage item by adding it in front/back of the block.
- All other sides can add/remove items from item's inventory.
- Made out of
- Made out of Wooden Plates, Steel Plates and a Hopper.
- Slime and Honey can now be shot out of Fluid Nozzle / Fluid Pressure Gun.
- Added Slime and Honey splashes.
- They deal no damage, instead giving player Sticky effect.
- Sticky effect makes player movement speed slower by 20%, attack speed by 15% and block breaking by 15%.
- When entity with this effect touches a wall while falling, it will slowly slide on it (similar effect to Honey Block).
- Increased damage done by Lava Splash to 2 hearts (from 0.5).
- Increased damage done by Experience Splash x2 (compared to previously).
- Recipes now use Fabric's Convention tag for Stripped Logs.
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/eu/pb4/polyfactory/ModInit.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import eu.pb4.polyfactory.block.mechanical.machines.PlanterBlock;
import eu.pb4.polyfactory.block.mechanical.source.WindmillBlock;
import eu.pb4.polyfactory.block.data.providers.TinyPotatoSpringBlock;
import eu.pb4.polyfactory.effects.FactoryEffects;
import eu.pb4.polyfactory.entity.FactoryEntities;
import eu.pb4.polyfactory.fluid.FactoryFluids;
import eu.pb4.polyfactory.item.FactoryDataComponents;
Expand Down Expand Up @@ -71,6 +72,7 @@ public void onInitialize() {
FactoryItems.register();
FactoryFluids.register();
FactoryEntities.register();
FactoryEffects.register();
FactoryNodes.register();
FactoryRecipeTypes.register();
FactoryRecipeSerializers.register();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import eu.pb4.factorytools.api.block.FactoryBlock;
import eu.pb4.factorytools.api.virtualentity.BlockModel;
import eu.pb4.factorytools.api.virtualentity.ItemDisplayElementUtil;
import eu.pb4.polyfactory.item.wrench.WrenchAction;
import eu.pb4.polyfactory.item.wrench.WrenchableBlock;
import eu.pb4.polyfactory.util.FactoryUtil;
import eu.pb4.polymer.virtualentity.api.ElementHolder;
import eu.pb4.polymer.virtualentity.api.attachment.BlockBoundAttachment;
Expand Down Expand Up @@ -37,8 +39,10 @@
import org.joml.Matrix4fStack;
import xyz.nucleoid.packettweaker.PacketContext;

import java.util.List;

public class ItemPackerBlock extends Block implements FactoryBlock, BlockEntityProvider, BarrierBasedWaterloggable, InventoryProvider {

public class ItemPackerBlock extends Block implements FactoryBlock, BlockEntityProvider, BarrierBasedWaterloggable, InventoryProvider, WrenchableBlock {
public static EnumProperty<Direction> FACING = Properties.FACING;

public ItemPackerBlock(Settings settings) {
Expand Down Expand Up @@ -136,6 +140,11 @@ public SidedInventory getInventory(BlockState state, WorldAccess world, BlockPos
return null;
}

@Override
public List<WrenchAction> getWrenchActions() {
return List.of(WrenchAction.FACING);
}

public final class Model extends BlockModel {
private final Matrix4fStack mat = new Matrix4fStack(2);
private final ItemDisplayElement mainElement;
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/eu/pb4/polyfactory/effects/FactoryEffects.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package eu.pb4.polyfactory.effects;

import eu.pb4.polyfactory.ModInit;
import eu.pb4.polyfactory.entity.DynamiteEntity;
import eu.pb4.polyfactory.entity.splash.*;
import eu.pb4.polyfactory.fluid.FactoryFluids;
import eu.pb4.polyfactory.models.FactoryModels;
import eu.pb4.polymer.core.api.entity.PolymerEntityUtils;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectCategory;
import net.minecraft.particle.BlockStateParticleEffect;
import net.minecraft.particle.ItemStackParticleEffect;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.util.Identifier;

public class FactoryEffects {
public static final RegistryEntry<StatusEffect> STICKY_SLIME = register("sticky/slime",
new StickyStatusEffect("slime", StatusEffectCategory.HARMFUL,0x73c262,
new BlockStateParticleEffect(ParticleTypes.BLOCK_CRUMBLE, Blocks.SLIME_BLOCK.getDefaultState())));

public static final RegistryEntry<StatusEffect> STICKY_HONEY = register("sticky/honey",
new StickyStatusEffect("honey", StatusEffectCategory.HARMFUL,0xfaab1c,
new BlockStateParticleEffect(ParticleTypes.BLOCK_CRUMBLE, Blocks.HONEY_BLOCK.getDefaultState())));
public static void register() {

}

public static RegistryEntry<StatusEffect> register(String path, StatusEffect effect) {
var id = Identifier.of(ModInit.ID, path);
return Registry.registerReference(Registries.STATUS_EFFECT, id, effect);
}
}
98 changes: 98 additions & 0 deletions src/main/java/eu/pb4/polyfactory/effects/StickyStatusEffect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package eu.pb4.polyfactory.effects;

import eu.pb4.polyfactory.util.FactoryUtil;
import eu.pb4.polymer.core.api.other.PolymerStatusEffect;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.AttributeContainer;
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectCategory;
import net.minecraft.network.packet.s2c.play.EntityVelocityUpdateS2CPacket;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text;
import net.minecraft.util.math.Vec3d;

import static eu.pb4.polyfactory.ModInit.id;

public class StickyStatusEffect extends StatusEffect implements PolymerStatusEffect {
//private final Multimap<RegistryEntry<EntityAttribute>, EntityAttributeModifier> wallEffects;
public StickyStatusEffect(String type, StatusEffectCategory category, int color, ParticleEffect particleEffect) {
super(category, color, particleEffect);
var attributeId = id("sticky/" + type);
this.addAttributeModifier(EntityAttributes.MOVEMENT_SPEED, attributeId, -0.2, EntityAttributeModifier.Operation.ADD_MULTIPLIED_BASE);
this.addAttributeModifier(EntityAttributes.ATTACK_SPEED, attributeId, -0.15, EntityAttributeModifier.Operation.ADD_MULTIPLIED_BASE);
this.addAttributeModifier(EntityAttributes.BLOCK_BREAK_SPEED, attributeId, -0.15, EntityAttributeModifier.Operation.ADD_MULTIPLIED_BASE);
}


@Override
public boolean applyUpdateEffect(ServerWorld world, LivingEntity entity, int amplifier) {
if (entity.isWet()) {
return false;
}

var box = entity.getBoundingBox().expand(0.01, -0.1, 0.01);
boolean active = false;
for (var voxelShape : world.getBlockCollisions(entity, box)) {
if (!voxelShape.isEmpty()) {
updateSlidingVelocity(entity);
active = true;
break;
}
}
//if (entity instanceof ServerPlayerEntity player) {
// var y = Math.abs(entity.getMovement().getY());
// player.sendMessage(Text.literal("Active: " + active + " | " + (entity.getMovement().getY() < 0 ? "-" : "+") + ((int) y) + "." + ((int) ((y - ((int) y)) * 100))), true);
//}

return super.applyUpdateEffect(world, entity, amplifier);
}

@Override
public boolean canApplyUpdateEffect(int duration, int amplifier) {
return true;
}

private void updateSlidingVelocity(Entity entity) {
Vec3d vec3d = entity instanceof ServerPlayerEntity player ? player.getMovement() : entity.getVelocity();
if (vec3d.y < 0) {
var y = speedModifier(-0.04);
entity.setVelocity(new Vec3d(vec3d.x, y, vec3d.z));

if (entity instanceof ServerPlayerEntity player) {
if (vec3d.y < y) {
player.networkHandler.sendPacket(new EntityVelocityUpdateS2CPacket(entity.getId(), entity.getVelocity()));
} else {
FactoryUtil.sendVelocityDelta(player, new Vec3d(0, y - vec3d.y + entity.getFinalGravity(), 0));
}
}

if (entity.getWorld().random.nextInt(5) == 0) {
entity.playSound(SoundEvents.BLOCK_HONEY_BLOCK_SLIDE, 1.0F, 1.0F);
if (!entity.isSilent()) {
entity.getWorld().playSound(null, entity.getX(), entity.getY(), entity.getZ(), SoundEvents.BLOCK_HONEY_BLOCK_SLIDE, entity.getSoundCategory(), 1.0F, 1.0F);
}
}

entity.onLanding();
}
}

private static double inverseSpeedModifier(double d) {
return d / 0.98F + 0.08;
}

private static double speedModifier(double d) {
return (d - 0.08) * 0.98F;
}

@Override
public void onRemoved(AttributeContainer attributeContainer) {
super.onRemoved(attributeContainer);
}
}
6 changes: 6 additions & 0 deletions src/main/java/eu/pb4/polyfactory/entity/FactoryEntities.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ public class FactoryEntities {
EntityType.Builder.create(MilkSplashEntity::new, SpawnGroup.MISC).dimensions(0.25f, 0.25f).maxTrackingRange(6).trackingTickInterval(2));
public static final EntityType<ExperienceSplashEntity> EXPERIENCE_SPLASH = register("experience_splash",
EntityType.Builder.create(ExperienceSplashEntity::new, SpawnGroup.MISC).dimensions(0.25f, 0.25f).maxTrackingRange(6).trackingTickInterval(2));

public static final EntityType<HoneySplashEntity> HONEY_SPLASH = register("honey_splash",
EntityType.Builder.create(HoneySplashEntity::new, SpawnGroup.MISC).dimensions(0.25f, 0.25f).maxTrackingRange(6).trackingTickInterval(2));

public static final EntityType<SlimeSplashEntity> SLIME_SPLASH = register("slime_splash",
EntityType.Builder.create(SlimeSplashEntity::new, SpawnGroup.MISC).dimensions(0.25f, 0.25f).maxTrackingRange(6).trackingTickInterval(2));
public static void register() {

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package eu.pb4.polyfactory.entity.splash;

import eu.pb4.polyfactory.effects.FactoryEffects;
import eu.pb4.polyfactory.fluid.FactoryFluids;
import net.minecraft.block.AbstractCandleBlock;
import net.minecraft.block.BlockState;
import net.minecraft.block.CampfireBlock;
import net.minecraft.block.FarmlandBlock;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.passive.AxolotlEntity;
import net.minecraft.entity.projectile.ProjectileEntity;
import net.minecraft.item.Items;
import net.minecraft.particle.ItemStackParticleEffect;
import net.minecraft.particle.ParticleEffect;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.Unit;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.World;
import net.minecraft.world.WorldEvents;

public class HoneySplashEntity extends SplashEntity<Unit> {
private static final ParticleEffect PARTICLE = new ItemStackParticleEffect(ParticleTypes.ITEM, Items.HONEY_BLOCK.getDefaultStack());

public HoneySplashEntity(EntityType<? extends ProjectileEntity> entityType, World world) {
super(entityType, world, FactoryFluids.HONEY);
}

@Override
protected void onBlockHit(BlockHitResult blockHitResult) {
if (!this.getWorld().isClient) {
Direction direction = blockHitResult.getSide();
BlockPos targetBlockPos = blockHitResult.getBlockPos();
BlockPos sidePos = targetBlockPos.offset(direction);
this.extinguishFire(sidePos);
this.extinguishFire(sidePos.offset(direction.getOpposite()));

for(Direction direction2 : Direction.Type.HORIZONTAL) {
this.extinguishFire(sidePos.offset(direction2));
}
}
super.onBlockHit(blockHitResult);
}
@Override
protected void onEntityHit(EntityHitResult entityHitResult) {
if (this.random.nextFloat() < 0.3) {
var entity = entityHitResult.getEntity();

if (getWorld() instanceof ServerWorld && entityHitResult.getEntity() instanceof LivingEntity livingEntity) {
if (livingEntity.isOnFire() && livingEntity.isAlive() && this.canInteractEntity(entity)) {
livingEntity.extinguishWithSound();
}
var effect = livingEntity.getStatusEffect(FactoryEffects.STICKY_HONEY);
int time = 20;
if (effect != null) {
time += effect.getDuration();
}
livingEntity.addStatusEffect(new StatusEffectInstance(FactoryEffects.STICKY_HONEY, Math.min(time, 20 * 60), 0), this); }
}
super.onEntityHit(entityHitResult);
}

@Override
public ParticleEffect getBaseParticle() {
return PARTICLE;
}

private void extinguishFire(BlockPos pos) {
if (this.random.nextFloat() < 0.1) {
if (!this.canBreakBlock(pos)) {
return;
}

BlockState blockState = this.getWorld().getBlockState(pos);
if (blockState.isIn(BlockTags.FIRE)) {
this.getWorld().breakBlock(pos, false, this);
} else if (AbstractCandleBlock.isLitCandle(blockState)) {
AbstractCandleBlock.extinguish(null, blockState, this.getWorld(), pos);
} else if (CampfireBlock.isLitCampfire(blockState)) {
this.getWorld().syncWorldEvent(null, WorldEvents.FIRE_EXTINGUISHED, pos, 0);
CampfireBlock.extinguish(this.getOwner(), this.getWorld(), pos, blockState);
this.getWorld().setBlockState(pos, blockState.with(CampfireBlock.LIT, false));
}
}
}
}
Loading

0 comments on commit b40a83e

Please sign in to comment.