From 2c77cfb4c34791e7c82c6e61f2312b7333ee2541 Mon Sep 17 00:00:00 2001 From: Sollace Date: Sun, 27 Mar 2022 16:02:14 +0200 Subject: [PATCH] Added muffins --- .../magic/spell/AbstractDelegatingSpell.java | 6 +- .../ability/magic/spell/ProjectileSpell.java | 2 +- .../magic/spell/effect/DarkVortexSpell.java | 4 +- .../unicopia/client/URenderers.java | 1 + .../entity/PhysicsBodyProjectileEntity.java | 147 ++++++++++++++++++ .../unicopia/entity/UEntities.java | 4 + .../unicopia/item/FilledJarItem.java | 19 +-- .../unicopia/item/HeavyProjectileItem.java | 66 ++++++++ .../minelittlepony/unicopia/item/JarItem.java | 60 ++----- .../unicopia/item/MuffinItem.java | 8 + .../unicopia/item/ProjectileItem.java | 75 +++++++++ .../minelittlepony/unicopia/item/UItems.java | 3 +- .../projectile/MagicProjectileEntity.java | 13 +- .../projectile/ProjectileDelegate.java | 7 +- .../unicopia/projectile/ProjectileUtil.java | 4 + .../resources/assets/unicopia/lang/en_us.json | 1 + .../assets/unicopia/models/item/muffin.json | 6 + .../assets/unicopia/textures/item/muffin.png | Bin 0 -> 389 bytes 18 files changed, 358 insertions(+), 68 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/entity/PhysicsBodyProjectileEntity.java create mode 100644 src/main/java/com/minelittlepony/unicopia/item/HeavyProjectileItem.java create mode 100644 src/main/java/com/minelittlepony/unicopia/item/MuffinItem.java create mode 100644 src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java create mode 100644 src/main/resources/assets/unicopia/models/item/muffin.json create mode 100644 src/main/resources/assets/unicopia/textures/item/muffin.png diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java index eeb6a7e8..79879fba 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractDelegatingSpell.java @@ -87,17 +87,19 @@ public abstract class AbstractDelegatingSpell implements ProjectileSpell { return execute(getDelegates().stream(), spell -> spell.tick(source, situation)); } + @SuppressWarnings("unchecked") @Override public void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) { getDelegates().stream().filter(a -> a instanceof ProjectileDelegate).forEach(a -> { - ((ProjectileDelegate)a).onImpact(projectile, pos, state); + ((ProjectileDelegate)a).onImpact(projectile, pos, state); }); } + @SuppressWarnings("unchecked") @Override public void onImpact(MagicProjectileEntity projectile, Entity entity) { getDelegates().stream().filter(a -> a instanceof ProjectileDelegate).forEach(a -> { - ((ProjectileDelegate)a).onImpact(projectile, entity); + ((ProjectileDelegate)a).onImpact(projectile, entity); }); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ProjectileSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ProjectileSpell.java index cbfade3e..8efd680c 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ProjectileSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ProjectileSpell.java @@ -10,7 +10,7 @@ import net.minecraft.util.math.BlockPos; /** * Magic effects that can be thrown. */ -public interface ProjectileSpell extends Spell, ProjectileDelegate { +public interface ProjectileSpell extends Spell, ProjectileDelegate { @Override default void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java index 99bdf55b..9ed429d1 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/DarkVortexSpell.java @@ -24,6 +24,7 @@ import net.minecraft.entity.FallingBlockEntity; import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.PersistentProjectileEntity; +import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.item.Item; import net.minecraft.nbt.NbtCompound; import net.minecraft.particle.ParticleTypes; @@ -197,6 +198,7 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileSpell return 10 + Math.min(15, Math.min(0.5F + pulse, (float)Math.exp(age) / 8F - 90) + accumulatedMass / 10F) + pulse; } + @SuppressWarnings("unchecked") @Override protected void applyRadialEffect(Caster source, Entity target, double distance, double radius) { @@ -213,7 +215,7 @@ public class DarkVortexSpell extends AttractiveSpell implements ProjectileSpell if (target instanceof MagicProjectileEntity) { Item item = ((MagicProjectileEntity)target).getStack().getItem(); if (item instanceof ProjectileDelegate && master != null) { - ((ProjectileDelegate) item).onImpact(((MagicProjectileEntity)target), master); + ((ProjectileDelegate) item).onImpact(((ProjectileEntity)target), master); } } else if (target instanceof PersistentProjectileEntity) { if (master != null) { diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index 1abfbacc..5f23d4b6 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -71,6 +71,7 @@ public interface URenderers { AccessoryFeatureRenderer.register(BatWingsFeatureRenderer::new); EntityRendererRegistry.register(UEntities.THROWN_ITEM, FlyingItemEntityRenderer::new); + EntityRendererRegistry.register(UEntities.MUFFIN, FlyingItemEntityRenderer::new); EntityRendererRegistry.register(UEntities.MAGIC_BEAM, MagicBeamEntityRenderer::new); EntityRendererRegistry.register(UEntities.BUTTERFLY, ButterflyEntityRenderer::new); EntityRendererRegistry.register(UEntities.FLOATING_ARTEFACT, FloatingArtefactEntityRenderer::new); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/PhysicsBodyProjectileEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/PhysicsBodyProjectileEntity.java new file mode 100644 index 00000000..89f42530 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/PhysicsBodyProjectileEntity.java @@ -0,0 +1,147 @@ +package com.minelittlepony.unicopia.entity; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.UTags; +import com.minelittlepony.unicopia.ability.magic.Caster; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.FlyingItemEntity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MovementType; +import net.minecraft.entity.data.DataTracker; +import net.minecraft.entity.data.TrackedData; +import net.minecraft.entity.data.TrackedDataHandlerRegistry; +import net.minecraft.entity.projectile.PersistentProjectileEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.sound.SoundEvents; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.GameRules; +import net.minecraft.world.World; +import net.minecraft.world.event.GameEvent; + +public class PhysicsBodyProjectileEntity extends PersistentProjectileEntity implements FlyingItemEntity { + + private static final TrackedData ITEM = DataTracker.registerData(PhysicsBodyProjectileEntity.class, TrackedDataHandlerRegistry.ITEM_STACK); + private static final TrackedData BOUNCY = DataTracker.registerData(PhysicsBodyProjectileEntity.class, TrackedDataHandlerRegistry.BOOLEAN); + + public PhysicsBodyProjectileEntity(EntityType type, World world) { + super(type, world); + } + + public PhysicsBodyProjectileEntity(World world) { + this(UEntities.MUFFIN, world); + } + + public PhysicsBodyProjectileEntity(World world, @Nullable LivingEntity thrower) { + super(UEntities.MUFFIN, thrower, world); + } + + @Override + protected void initDataTracker() { + super.initDataTracker(); + getDataTracker().startTracking(ITEM, ItemStack.EMPTY); + getDataTracker().startTracking(BOUNCY, false); + } + + public void setStack(ItemStack stack) { + getDataTracker().set(ITEM, stack); + } + + @Override + public ItemStack getStack() { + return getDataTracker().get(ITEM); + } + + @Override + protected ItemStack asItemStack() { + return getStack(); + } + + public void setBouncy() { + getDataTracker().set(BOUNCY, true); + } + + public boolean isBouncy() { + return getDataTracker().get(BOUNCY); + } + + @Override + public void tick() { + super.tick(); + if (inGround) { + Vec3d vel = getVelocity(); + vel = vel.multiply(0, 1, 0); + + move(MovementType.SELF, vel); + + setVelocity(vel.multiply(0.3)); + addVelocity(0, -0.025, 0); + } + } + + @Override + protected void onBlockHit(BlockHitResult hit) { + BlockState state = world.getBlockState(hit.getBlockPos()); + + if (getVelocity().length() > 0.2F) { + boolean ownerCanModify = Caster.of(getOwner()).filter(pony -> pony.canModifyAt(hit.getBlockPos())).isPresent(); + + if (ownerCanModify && world.getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING)) { + if ((!isBouncy() || world.random.nextInt(200) == 0) && state.isIn(UTags.FRAGILE)) { + world.breakBlock(hit.getBlockPos(), true); + } + } + + if (isBouncy()) { + Direction.Axis side = hit.getSide().getAxis(); + + if (side == Direction.Axis.X) { + setVelocity(getVelocity().multiply(-0.4, 0.3, 0.3)); + } + + if (side == Direction.Axis.Y) { + setVelocity(getVelocity().multiply(0.3, -0.4, 0.3)); + } + + if (side == Direction.Axis.Z) { + setVelocity(getVelocity().multiply(0.3, 0.3, -0.4)); + } + } else { + super.onBlockHit(hit); + } + } else { + super.onBlockHit(hit); + } + + setSound(state.getSoundGroup().getStepSound()); + world.playSoundFromEntity(null, this, state.getSoundGroup().getStepSound(), SoundCategory.BLOCKS, 1, 1); + emitGameEvent(GameEvent.STEP); + } + + @Override + protected SoundEvent getHitSound() { + return isBouncy() ? SoundEvents.BLOCK_NOTE_BLOCK_BANJO : SoundEvents.BLOCK_STONE_HIT; + } + + @Override + public void writeCustomDataToNbt(NbtCompound nbt) { + super.writeCustomDataToNbt(nbt); + ItemStack stack = getStack(); + if (!stack.isEmpty()) { + nbt.put("Item", stack.writeNbt(new NbtCompound())); + } + } + + @Override + public void readCustomDataFromNbt(NbtCompound nbt) { + super.readCustomDataFromNbt(nbt); + setStack(ItemStack.fromNbt(nbt.getCompound("Item"))); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/UEntities.java b/src/main/java/com/minelittlepony/unicopia/entity/UEntities.java index 620de519..a537fa87 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/UEntities.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/UEntities.java @@ -25,6 +25,10 @@ public interface UEntities { .trackRangeBlocks(100) .trackedUpdateRate(2) .dimensions(EntityDimensions.fixed(0.25F, 0.25F))); + EntityType MUFFIN = register("muffin", FabricEntityTypeBuilder.create(SpawnGroup.MISC, PhysicsBodyProjectileEntity::new) + .trackRangeBlocks(100) + .trackedUpdateRate(2) + .dimensions(EntityDimensions.fixed(0.25F, 0.25F))); EntityType MAGIC_BEAM = register("magic_beam", FabricEntityTypeBuilder.create(SpawnGroup.MISC, MagicProjectileEntity::new) .trackRangeBlocks(100) .trackedUpdateRate(2) diff --git a/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java b/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java index dc856e94..60338d85 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/FilledJarItem.java @@ -1,7 +1,6 @@ package com.minelittlepony.unicopia.item; import com.minelittlepony.unicopia.entity.IItemEntity; -import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; import net.minecraft.block.Block; import net.minecraft.block.Blocks; @@ -10,10 +9,12 @@ import net.minecraft.enchantment.Enchantments; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityGroup; import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.FlyingItemEntity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.attribute.EntityAttributeInstance; import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.entity.damage.DamageSource; +import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.item.ItemStack; import net.minecraft.particle.ParticleTypes; import net.minecraft.server.world.ServerWorld; @@ -50,14 +51,14 @@ public class FilledJarItem extends JarItem implements ChameleonItem { } @Override - public void onImpact(MagicProjectileEntity projectile, Entity entity) { + public void onImpact(ProjectileEntity projectile, Entity entity) { super.onImpact(projectile, entity); - if (!entity.isAttackable()) { + if (!entity.isAttackable() || !(projectile instanceof FlyingItemEntity)) { return; } - ItemStack stack = getAppearanceStack(projectile.getStack()); + ItemStack stack = getAppearanceStack(((FlyingItemEntity)projectile).getStack()); boolean onFire = false; @@ -119,12 +120,12 @@ public class FilledJarItem extends JarItem implements ChameleonItem { } @Override - protected void onImpact(MagicProjectileEntity projectile) { - ItemStack stack = getAppearanceStack(projectile.getStack()); + protected void onImpact(ProjectileEntity projectile) { + if (!(projectile instanceof FlyingItemEntity)) { + return; + } + ItemStack stack = getAppearanceStack(((FlyingItemEntity)projectile).getStack()); stack.damage(1, projectile.world.random, null); - - - projectile.dropStack(stack); projectile.world.syncWorldEvent(WorldEvents.BLOCK_BROKEN, projectile.getBlockPos(), Block.getRawIdFromState(Blocks.GLASS.getDefaultState())); } diff --git a/src/main/java/com/minelittlepony/unicopia/item/HeavyProjectileItem.java b/src/main/java/com/minelittlepony/unicopia/item/HeavyProjectileItem.java new file mode 100644 index 00000000..fe15a05b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/HeavyProjectileItem.java @@ -0,0 +1,66 @@ +package com.minelittlepony.unicopia.item; + +import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.UTags; +import com.minelittlepony.unicopia.entity.PhysicsBodyProjectileEntity; + +import net.minecraft.block.BlockState; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.dispenser.ProjectileDispenserBehavior; +import net.minecraft.entity.FlyingItemEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.PersistentProjectileEntity; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.sound.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Position; +import net.minecraft.world.GameRules; +import net.minecraft.world.World; + +public class HeavyProjectileItem extends ProjectileItem { + + public HeavyProjectileItem(Settings settings, float projectileDamage) { + super(settings, projectileDamage); + DispenserBlock.registerBehavior(this, new ProjectileDispenserBehavior(){ + @Override + protected ProjectileEntity createProjectile(World world, Position position, ItemStack stack) { + ProjectileEntity projectile = HeavyProjectileItem.this.createProjectile(stack, world, null); + projectile.setPosition(position.getX(), position.getY(), position.getZ()); + return projectile; + } + }); + } + + @Override + protected ProjectileEntity createProjectile(ItemStack stack, World world, PlayerEntity player) { + PhysicsBodyProjectileEntity projectile = player == null ? new PhysicsBodyProjectileEntity(world) : new PhysicsBodyProjectileEntity(world, player); + if (player != null) { + projectile.setVelocity(player, player.getPitch(), player.getYaw(), 0, 1.5F, 1); + } + projectile.pickupType = PersistentProjectileEntity.PickupPermission.ALLOWED; + projectile.setStack(stack.copy()); + if (this == UItems.MUFFIN) { + projectile.setBouncy(); + } + return projectile; + } + + @Override + protected SoundEvent getThrowSound(ItemStack stack) { + return USounds.ENTITY_JAR_THROW; + } + + @Override + public void onImpact(ProjectileEntity projectile, BlockPos pos, BlockState state) { + if (projectile.world.getGameRules().getBoolean(GameRules.DO_MOB_GRIEFING)) { + float damage = projectile instanceof FlyingItemEntity ? getProjectileDamage(((FlyingItemEntity)projectile).getStack()) : 0; + + if (damage > 0 && projectile.world.random.nextInt(90) == 0) { + if (state.isIn(UTags.FRAGILE)) { + projectile.world.breakBlock(pos, true); + } + } + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/JarItem.java b/src/main/java/com/minelittlepony/unicopia/item/JarItem.java index 94b42db1..e6225acb 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/JarItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/JarItem.java @@ -6,9 +6,6 @@ import com.minelittlepony.unicopia.entity.IItemEntity; import com.minelittlepony.unicopia.entity.ItemImpl; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.particle.UParticles; -import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; -import com.minelittlepony.unicopia.projectile.ProjectileDelegate; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -16,67 +13,31 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.entity.ItemEntity; import net.minecraft.entity.LightningEntity; +import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.entity.Entity.RemovalReason; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.server.world.ServerWorld; -import net.minecraft.sound.SoundCategory; -import net.minecraft.stat.Stats; +import net.minecraft.sound.SoundEvent; import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.TypedActionResult; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkSectionPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.Heightmap; -import net.minecraft.world.World; import net.minecraft.world.WorldEvents; -public class JarItem extends Item implements ProjectileDelegate, ItemImpl.GroundTickCallback { +public class JarItem extends ProjectileItem implements ItemImpl.GroundTickCallback { private final boolean rain; private final boolean thunder; private final boolean lightning; public JarItem(Settings settings, boolean rain, boolean thunder, boolean lightning) { - super(settings); + super(settings, 0.5F); this.rain = rain; this.thunder = thunder; this.lightning = lightning; } - @Override - public TypedActionResult use(World world, PlayerEntity player, Hand hand) { - ItemStack stack = player.getStackInHand(hand); - - world.playSound(null, player.getX(), player.getY(), player.getZ(), - USounds.ENTITY_JAR_THROW, SoundCategory.NEUTRAL, - 0.5F, - 0.4F / (world.random.nextFloat() * 0.4F + 0.8F)); - - if (!world.isClient) { - MagicProjectileEntity projectile = new MagicProjectileEntity(world, player); - projectile.setItem(stack); - projectile.setThrowDamage(getProjectileDamage(stack)); - projectile.setVelocity(player, player.getPitch(), player.getYaw(), 0, 1.5F, 1); - - world.spawnEntity(projectile); - } - - player.incrementStat(Stats.USED.getOrCreateStat(this)); - - if (!player.getAbilities().creativeMode) { - stack.decrement(1); - } - - return TypedActionResult.success(stack, world.isClient()); - } - - protected float getProjectileDamage(ItemStack stack) { - return 0.5F; - } - @Override public ActionResult onGroundTick(IItemEntity item) { ItemEntity entity = item.get().getMaster(); @@ -115,17 +76,22 @@ public class JarItem extends Item implements ProjectileDelegate, ItemImpl.Ground } @Override - public void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) { + protected SoundEvent getThrowSound(ItemStack stack) { + return USounds.ENTITY_JAR_THROW; + } + + @Override + public void onImpact(ProjectileEntity projectile, BlockPos pos, BlockState state) { onImpact(projectile); } @Override - public void onImpact(MagicProjectileEntity projectile, Entity entity) { + public void onImpact(ProjectileEntity projectile, Entity entity) { onImpact(projectile); } - protected void onImpact(MagicProjectileEntity projectile) { - if (!projectile.isClient()) { + protected void onImpact(ProjectileEntity projectile) { + if (!projectile.world.isClient()) { ServerWorld world = (ServerWorld)projectile.world; if (rain || thunder) { diff --git a/src/main/java/com/minelittlepony/unicopia/item/MuffinItem.java b/src/main/java/com/minelittlepony/unicopia/item/MuffinItem.java new file mode 100644 index 00000000..c441abce --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/MuffinItem.java @@ -0,0 +1,8 @@ +package com.minelittlepony.unicopia.item; + +public class MuffinItem extends HeavyProjectileItem { + + public MuffinItem(Settings settings, float projectileDamage) { + super(settings, projectileDamage); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java b/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java new file mode 100644 index 00000000..01e11646 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java @@ -0,0 +1,75 @@ +package com.minelittlepony.unicopia.item; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.unicopia.projectile.MagicProjectileEntity; +import com.minelittlepony.unicopia.projectile.ProjectileDelegate; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvent; +import net.minecraft.stat.Stats; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.world.World; + +abstract class ProjectileItem extends Item implements ProjectileDelegate { + + private final float projectileDamage; + + public ProjectileItem(Settings settings, float projectileDamage) { + super(settings); + this.projectileDamage = projectileDamage; + } + + @Override + public TypedActionResult use(World world, PlayerEntity player, Hand hand) { + + if (isFood() && !player.isSneaking()) { + TypedActionResult eaten = super.use(world, player, hand); + + if (eaten.getResult().isAccepted()) { + return eaten; + } + } + + ItemStack stack = player.getStackInHand(hand); + + world.playSound(null, player.getX(), player.getY(), player.getZ(), + getThrowSound(stack), SoundCategory.NEUTRAL, + 0.5F, + 0.4F / (world.random.nextFloat() * 0.4F + 0.8F)); + + if (!world.isClient) { + world.spawnEntity(createProjectile(stack, world, player)); + } + + player.incrementStat(Stats.USED.getOrCreateStat(this)); + + if (!player.getAbilities().creativeMode) { + stack.decrement(1); + } + + return TypedActionResult.success(stack, world.isClient()); + } + + protected ProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) { + MagicProjectileEntity projectile = player == null ? new MagicProjectileEntity(world) : new MagicProjectileEntity(world, player); + projectile.setItem(stack); + projectile.setThrowDamage(getProjectileDamage(stack)); + if (player != null) { + projectile.setVelocity(player, player.getPitch(), player.getYaw(), 0, 1.5F, 1); + } + return projectile; + } + + protected abstract SoundEvent getThrowSound(ItemStack stack); + + protected float getProjectileDamage(ItemStack stack) { + return projectileDamage; + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 2afc77b6..a4896fac 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -67,9 +67,10 @@ public interface UItems { Item HAY_BURGER = register("hay_burger", new Item(new Item.Settings().group(ItemGroup.FOOD).maxCount(1).food(UFoodComponents.HAY_BURGER))); Item HAY_FRIES = register("hay_fries", new Item(new Item.Settings().group(ItemGroup.FOOD).maxCount(16).food(UFoodComponents.HAY_FRIES))); Item WHEAT_WORMS = register("wheat_worms", new Item(new Item.Settings().group(ItemGroup.MISC).maxCount(16).food(UFoodComponents.INSECTS))); + Item MUFFIN = register("muffin", new MuffinItem(new Item.Settings().group(ItemGroup.FOOD).maxCount(32).food(FoodComponents.BREAD), 0)); Item PEBBLES = register("pebbles", new RacePredicatedAliasedBlockItem(UBlocks.ROCKS, new Item.Settings().group(ItemGroup.MATERIALS), Race::canUseEarth)); - Item ROCK = register("rock", new Item(new Item.Settings().group(ItemGroup.MATERIALS))); + Item ROCK = register("rock", new HeavyProjectileItem(new Item.Settings().group(ItemGroup.MATERIALS), 3)); Item WEIRD_ROCK = register("weird_rock", new Item(new Item.Settings().group(ItemGroup.MATERIALS))); Item ROCK_STEW = register("rock_stew", new Item(new Item.Settings().group(ItemGroup.FOOD).food(FoodComponents.MUSHROOM_STEW))); diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java index c0318b3f..4d8c6c30 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java @@ -69,7 +69,11 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster
  • consumer) { + @SuppressWarnings("unchecked") + protected void forEachDelegates(Consumer> consumer) { getSpellSlot().forEach(spell -> { if (SpellPredicate.HAS_PROJECTILE_EVENTS.test(spell)) { - consumer.accept((ProjectileDelegate)spell); + consumer.accept((ProjectileDelegate)spell); } return Operation.SKIP; }, true); if (getItem().getItem() instanceof ProjectileDelegate) { - consumer.accept(((ProjectileDelegate)getItem().getItem())); + consumer.accept(((ProjectileDelegate)getItem().getItem())); } } diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileDelegate.java b/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileDelegate.java index 7bd80e3c..c1654713 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileDelegate.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileDelegate.java @@ -2,16 +2,17 @@ package com.minelittlepony.unicopia.projectile; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; +import net.minecraft.entity.projectile.ProjectileEntity; import net.minecraft.util.math.BlockPos; -public interface ProjectileDelegate { +public interface ProjectileDelegate { /** * Called once the projectile lands either hitting the ground or an entity. */ - default void onImpact(MagicProjectileEntity projectile, BlockPos pos, BlockState state) {} + default void onImpact(T projectile, BlockPos pos, BlockState state) {} /** * Called once the projectile lands either hitting the ground or an entity. */ - default void onImpact(MagicProjectileEntity projectile, Entity entity) {} + default void onImpact(T projectile, Entity entity) {} } diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileUtil.java b/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileUtil.java index 1d7543e1..2fb16e4e 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileUtil.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/ProjectileUtil.java @@ -55,6 +55,10 @@ public interface ProjectileUtil { /** * Reverses a projectile's direction to deflect it off a surface. + * + * @param projectile The projectile to deflect + * @param post The position the projectile must be deflected away from + * @param absorbtionRate Percentage of the projectile velocity to absorb. */ static void ricochet(Entity projectile, Vec3d pos, float absorbtionRate) { Vec3d position = projectile.getPos(); diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 027da2f1..fdef1163 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -59,6 +59,7 @@ "item.unicopia.hay_burger": "Hay Burger", "item.unicopia.hay_fries": "Hay Fries", "item.unicopia.wheat_worms": "Wheat Worms", + "item.unicopia.muffin": "Muffin", "item.unicopia.pegasus_amulet": "Wings of Icarus", "item.unicopia.pegasus_amulet.lore": "Grants temporary flight to whoever wears it", diff --git a/src/main/resources/assets/unicopia/models/item/muffin.json b/src/main/resources/assets/unicopia/models/item/muffin.json new file mode 100644 index 00000000..19192a75 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/muffin.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/muffin" + } +} diff --git a/src/main/resources/assets/unicopia/textures/item/muffin.png b/src/main/resources/assets/unicopia/textures/item/muffin.png new file mode 100644 index 0000000000000000000000000000000000000000..cf7041d00a891d56778dd1b7970f97f64abca6cb GIT binary patch literal 389 zcmV;00eb$4P)aFIxD@7=`-e@)t9FN(_ulNx!XIH|18%nwRV!tE55B$u=-hu8MFdCLV#{_4m0bE! z5m6~yET!Om^oo=MDFtfcBc;Hy9W2|y?KYx9f+Q|lEqykdbpWIk09dxe~9J@xfDxeF