wands rework, aoe wand + boost wand + push wand (missing textures), fix projectile model offset

This commit is contained in:
Jenny 2025-04-19 18:17:37 +02:00
parent 9af5c7b6bd
commit abe16dc0d3
Signed by: Jenny
GPG Key ID: 4A98012FB1C39311
20 changed files with 368 additions and 146 deletions

View File

@ -0,0 +1,42 @@
package com.jenny.magic.entities;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
import org.jetbrains.annotations.NotNull;
abstract class AreaProjectile extends BaseWandProjectile {
private float range;
protected AreaProjectile(EntityType<? extends AbstractArrow> pEntityType, Level pLevel, float range) {
super(pEntityType, pLevel);
this.range = range;
}
@Override
protected void onHitEntity(@NotNull EntityHitResult pResult) {
hit();
}
protected void hit() {
for (Entity entity : level().getEntitiesOfClass(LivingEntity.class, new AABB(position().subtract(range, range, range), position().add(range, range, range)))) {
hitLivingEntity(new EntityHitResult(entity));
if (level().isClientSide) {
hitParticles(entity);
}
}
}
@Override
protected void onHitBlock(@NotNull BlockHitResult pResult) {
hitBlock(pResult);
hit();
super.onHitBlock(pResult);
}
}

View File

@ -1,11 +1,15 @@
package com.jenny.magic.entities; package com.jenny.magic.entities;
import com.jenny.magic.sounds.sounds; import com.jenny.magic.sounds.sounds;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.sounds.SoundEvent; import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.EntityHitResult;
@ -25,6 +29,7 @@ public abstract class BaseWandProjectile extends AbstractArrow {
Vec3 pos = pShooter.position().add(delta.scale(0.3).add(0, pShooter.getEyeHeight(), 0)); Vec3 pos = pShooter.position().add(delta.scale(0.3).add(0, pShooter.getEyeHeight(), 0));
this.setDeltaMovement(delta); this.setDeltaMovement(delta);
this.setPos(pos); this.setPos(pos);
this.setOwner(pShooter);
} }
public void tick() { public void tick() {
@ -33,7 +38,7 @@ public abstract class BaseWandProjectile extends AbstractArrow {
} }
super.tick(); super.tick();
if (level().isClientSide) { if (level().isClientSide) {
spawnParticles(); flyingParticles();
} }
} }
@ -42,7 +47,7 @@ public abstract class BaseWandProjectile extends AbstractArrow {
if (level().isClientSide) { if (level().isClientSide) {
hitParticles(); hitParticles();
} }
hitEntity(pResult); hitLivingEntity(pResult);
} }
@Override @Override
@ -50,33 +55,79 @@ public abstract class BaseWandProjectile extends AbstractArrow {
if (level().isClientSide) { if (level().isClientSide) {
hitParticles(); hitParticles();
} }
hitBlock(pResult);
super.onHitBlock(pResult); super.onHitBlock(pResult);
} }
protected Vec3 particlePos(double dist) { protected Vec3 particlePos(double dist) {
return new Vec3( return new Vec3(
level().getRandom().nextIntBetweenInclusive(-100, 100), level().getRandom().nextFloat(),
level().getRandom().nextIntBetweenInclusive(-100, 100), level().getRandom().nextFloat(),
level().getRandom().nextIntBetweenInclusive(-100, 100) level().getRandom().nextFloat()
).normalize().scale(dist + ((double) level().getRandom().nextIntBetweenInclusive(0, 100) / 100)).add(position()); ).normalize().scale(dist * (level().getRandom().nextFloat() - 0.5f) * 2);
} }
public void spawnParticles() { public void flyingParticles() {
if (particleFlying() != null) {
for (int i = 0; i < 5; i++) {
Vec3 pos = particlePos(0.5).add(position());
this.level().addParticle(particleFlying(), pos.x, pos.y, pos.z, 0, 0, 0);
}
}
} }
protected void hitEntity(EntityHitResult pResult) { public void hitParticles() {
hitParticles(position());
}
public void hitParticles(Vec3 origin) {
if (particleHit() != null) {
for (int i = 0; i < 20; i++) {
Vec3 particlePos = particlePos(0.5).add(origin);
level().addParticle(particleHit(), particlePos.x, particlePos.y, particlePos.z, 0, 0, 0);
}
}
}
public void hitParticles(Entity entity) {
hitParticles(entity.getBoundingBox().getCenter());
}
protected void hitLivingEntity(EntityHitResult pResult) {
} }
protected void hitBlock(BlockHitResult pResult) { protected void hitBlock(BlockHitResult pResult) {
} }
public void hitParticles() {
}
public abstract String name();
@Override @Override
protected @NotNull SoundEvent getDefaultHitGroundSoundEvent() { protected @NotNull SoundEvent getDefaultHitGroundSoundEvent() {
return sounds.TEST.get(); return sounds.TEST.get();
} }
public ParticleOptions particleFlying() {
return null;
}
public ParticleOptions particleHit() {
return null;
}
@Override
protected ItemStack getPickupItem() {
return ItemStack.EMPTY;
}
protected DamageSource getDamageSource(EntityHitResult entityHitResult) {
Entity owner = this.getOwner();
DamageSource damagesource;
if (owner == null) {
damagesource = this.damageSources().arrow(this, this);
} else {
damagesource = this.damageSources().arrow(this, owner);
if (owner instanceof LivingEntity lOwner) {
lOwner.setLastHurtMob(entityHitResult.getEntity());
}
}
return damagesource;
}
} }

View File

@ -1,14 +1,11 @@
package com.jenny.magic.entities; package com.jenny.magic.entities;
import net.minecraft.core.particles.ParticleTypes; import com.jenny.magic.particles.particles;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class HurtfulProjectile extends BaseWandProjectile { public class HurtfulProjectile extends BaseWandProjectile {
@ -20,38 +17,21 @@ public class HurtfulProjectile extends BaseWandProjectile {
super(entities.PROJECTILE_HURTFUL.get(), pLevel); super(entities.PROJECTILE_HURTFUL.get(), pLevel);
} }
public String name() {
return "hurtful_projectile";
}
@Override @Override
protected void hitEntity(@NotNull EntityHitResult pResult) { protected void hitLivingEntity(@NotNull EntityHitResult pResult) {
if (pResult.getEntity() instanceof LivingEntity) { if (pResult.getEntity() instanceof LivingEntity pLivng) {
Entity owner = this.getOwner(); pResult.getEntity().hurt(getDamageSource(pResult), 3);
DamageSource damagesource; this.doPostHurtEffects(pLivng);
if (owner == null) {
damagesource = this.damageSources().arrow(this, this);
} else {
damagesource = this.damageSources().arrow(this, owner);
if (owner instanceof LivingEntity) {
((LivingEntity) owner).setLastHurtMob(pResult.getEntity());
}
}
pResult.getEntity().hurt(this.damageSources().arrow(this, this.getOwner()), 5);
this.doPostHurtEffects((LivingEntity) pResult.getEntity());
} }
} }
@Override @Override
public void hitParticles() { public ParticleOptions particleFlying() {
for (int i = 0; i < 20; i++) { return particles.PARTICLE_FLYING_RED.get();
Vec3 particlePos = particlePos(2);
level().addParticle(ParticleTypes.LAVA, particlePos.x, particlePos.y, particlePos.z, 0, 0, 0);
}
} }
@Override @Override
protected ItemStack getPickupItem() { public ParticleOptions particleHit() {
return ItemStack.EMPTY; return particles.PARTICLE_HIT_RED.get();
} }
} }

View File

@ -0,0 +1,37 @@
package com.jenny.magic.entities;
import com.jenny.magic.particles.particles;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.EntityHitResult;
import org.jetbrains.annotations.NotNull;
public class HurtfulProjectileAOE extends AreaProjectile {
public HurtfulProjectileAOE(EntityType<? extends BaseWandProjectile> pEntityType, Level pLevel) {
super(pEntityType, pLevel, 2);
}
public HurtfulProjectileAOE(Level pLevel) {
super(entities.PROJECTILE_HURTFUL_AOE.get(), pLevel, 2);
}
@Override
protected void hitLivingEntity(@NotNull EntityHitResult pResult) {
if (pResult.getEntity() instanceof LivingEntity pLivng) {
pResult.getEntity().hurt(getDamageSource(pResult), 3);
this.doPostHurtEffects(pLivng);
}
}
@Override
public ParticleOptions particleFlying() {
return particles.PARTICLE_FLYING_RED.get();
}
@Override
public ParticleOptions particleHit() {
return particles.PARTICLE_HIT_RED.get();
}
}

View File

@ -27,6 +27,7 @@ public class BaseProjectileRenderer<T extends BaseWandProjectile> extends Entity
pPoseStack.pushPose(); pPoseStack.pushPose();
pPoseStack.mulPose(Axis.YP.rotationDegrees(-90.0F)); pPoseStack.mulPose(Axis.YP.rotationDegrees(-90.0F));
pPoseStack.scale(pEntity.getBbWidth(), pEntity.getBbHeight(), pEntity.getBbWidth()); pPoseStack.scale(pEntity.getBbWidth(), pEntity.getBbHeight(), pEntity.getBbWidth());
pPoseStack.translate(-0.5F, 0, 0.5F);
pPoseStack.mulPose(Axis.YP.rotationDegrees(90.0F)); pPoseStack.mulPose(Axis.YP.rotationDegrees(90.0F));
TntMinecartRenderer.renderWhiteSolidBlock(this.blockRenderer, block.defaultBlockState(), pPoseStack, pBuffer, pPackedLight, false); TntMinecartRenderer.renderWhiteSolidBlock(this.blockRenderer, block.defaultBlockState(), pPoseStack, pBuffer, pPackedLight, false);
pPoseStack.popPose(); pPoseStack.popPose();

View File

@ -12,6 +12,7 @@ import static com.jenny.magic.Magic.MODID;
public class ProjectileBlocks { public class ProjectileBlocks {
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID); public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MODID);
public static final RegistryObject<Block> PROJECTILE_HURTFUL = BLOCKS.register("projectile_hurtful", () -> new Block(BlockBehaviour.Properties.of())); public static final RegistryObject<Block> PROJECTILE_HURTFUL = BLOCKS.register("projectile_hurtful", () -> new Block(BlockBehaviour.Properties.of()));
public static final RegistryObject<Block> PROJECTILE_HURTFUL_AOE = BLOCKS.register("projectile_hurtful_aoe", () -> new Block(BlockBehaviour.Properties.of()));
public static void register(IEventBus bus) { public static void register(IEventBus bus) {
BLOCKS.register(bus); BLOCKS.register(bus);

View File

@ -16,15 +16,21 @@ public class entities {
public static final DeferredRegister<EntityType<?>> ENTITY_TYPES = public static final DeferredRegister<EntityType<?>> ENTITY_TYPES =
DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, MODID); DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, MODID);
public static final RegistryObject<EntityType<HurtfulProjectile>> PROJECTILE_HURTFUL = public static final RegistryObject<EntityType<BaseWandProjectile>> PROJECTILE_HURTFUL =
ENTITY_TYPES.register("projectile_hurtful", () -> EntityType.Builder.<HurtfulProjectile>of(HurtfulProjectile::new, MobCategory.MISC) ENTITY_TYPES.register("projectile_hurtful", () -> EntityType.Builder.<BaseWandProjectile>of(HurtfulProjectile::new, MobCategory.MISC)
.sized(0.3F, 0.3F).fireImmune().clientTrackingRange(8).build("projectile_hurtful")); .sized(0.3F, 0.3F).fireImmune().clientTrackingRange(8).build("projectile_hurtful"));
public static final RegistryObject<EntityType<BaseWandProjectile>> PROJECTILE_HURTFUL_AOE =
ENTITY_TYPES.register("projectile_hurtful_aoe", () -> EntityType.Builder.<BaseWandProjectile>of(HurtfulProjectileAOE::new, MobCategory.MISC)
.sized(0.3F, 0.3F).fireImmune().clientTrackingRange(8).build("projectile_hurtful_aoe"));
public static void register(IEventBus eventBus) { public static void register(IEventBus eventBus) {
ENTITY_TYPES.register(eventBus); ENTITY_TYPES.register(eventBus);
} }
public static void registerRenderers() { public static void registerRenderers() {
EntityRenderers.register(PROJECTILE_HURTFUL.get(), (context) -> new BaseProjectileRenderer<>(context, ProjectileBlocks.PROJECTILE_HURTFUL.get())); EntityRenderers.register(PROJECTILE_HURTFUL.get(), (context) -> new BaseProjectileRenderer<>(context, ProjectileBlocks.PROJECTILE_HURTFUL.get()));
EntityRenderers.register(PROJECTILE_HURTFUL_AOE.get(), (context) -> new BaseProjectileRenderer<>(context, ProjectileBlocks.PROJECTILE_HURTFUL_AOE.get()));
} }
} }

View File

@ -1,8 +1,11 @@
package com.jenny.magic.items; package com.jenny.magic.items;
import com.jenny.magic.entities.entities;
import com.jenny.magic.items.amulets.*; import com.jenny.magic.items.amulets.*;
import com.jenny.magic.items.scrolls.*; import com.jenny.magic.items.scrolls.*;
import com.jenny.magic.items.wands.WandHurtful; import com.jenny.magic.items.wands.ProjectileWand;
import com.jenny.magic.items.wands.WandBoost;
import com.jenny.magic.items.wands.WandPush;
import com.jenny.magic.items.wands.WandVacuum; import com.jenny.magic.items.wands.WandVacuum;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.world.effect.MobEffects; import net.minecraft.world.effect.MobEffects;
@ -17,8 +20,13 @@ import static com.jenny.magic.Magic.MODID;
public class items { public class items {
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID); public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID);
public static final RegistryObject<Item> WAND_HURTFUL = ITEMS.register("wand_hurtful", () -> new WandHurtful(new Item.Properties())); // WANDS
public static final RegistryObject<Item> WAND_VAUUM = ITEMS.register("wand_vacuum", () -> new WandVacuum(new Item.Properties().stacksTo(1))); public static final RegistryObject<Item> WAND_HURTFUL = ITEMS.register("wand_hurtful", () -> new ProjectileWand(new Item.Properties(), entities.PROJECTILE_HURTFUL));
public static final RegistryObject<Item> WAND_HURTFUL_AOE = ITEMS.register("wand_hurtful_aoe", () -> new ProjectileWand(new Item.Properties(), entities.PROJECTILE_HURTFUL_AOE));
public static final RegistryObject<Item> WAND_VAUUM = ITEMS.register("wand_vacuum", () -> new WandVacuum(new Item.Properties()));
public static final RegistryObject<Item> WAND_BOOST = ITEMS.register("wand_boost", () -> new WandBoost(new Item.Properties()));
public static final RegistryObject<Item> WAND_PUSH = ITEMS.register("wand_push", () -> new WandPush(new Item.Properties()));
// SCROLLS
public static final RegistryObject<Item> SCROLL_TELEPORT = ITEMS.register("scroll_teleport", () -> new ScrollTeleportPersistent(new Item.Properties().stacksTo(1))); public static final RegistryObject<Item> SCROLL_TELEPORT = ITEMS.register("scroll_teleport", () -> new ScrollTeleportPersistent(new Item.Properties().stacksTo(1)));
public static final RegistryObject<Item> SCROLL_TELEPORT_BRITTLE = ITEMS.register("scroll_teleport_brittle", () -> new ScrollTeleportConsumable(new Item.Properties().stacksTo(16))); public static final RegistryObject<Item> SCROLL_TELEPORT_BRITTLE = ITEMS.register("scroll_teleport_brittle", () -> new ScrollTeleportConsumable(new Item.Properties().stacksTo(16)));
public static final RegistryObject<Item> SCROLL_TELEPORT_RANDOM = ITEMS.register("scroll_teleport_random", () -> new TeleportScrollRandom(new Item.Properties().stacksTo(1))); public static final RegistryObject<Item> SCROLL_TELEPORT_RANDOM = ITEMS.register("scroll_teleport_random", () -> new TeleportScrollRandom(new Item.Properties().stacksTo(1)));
@ -26,6 +34,7 @@ public class items {
public static final RegistryObject<Item> SCROLL_HEALTH = ITEMS.register("scroll_health", () -> new ScrollHealth(new Item.Properties().stacksTo(16))); public static final RegistryObject<Item> SCROLL_HEALTH = ITEMS.register("scroll_health", () -> new ScrollHealth(new Item.Properties().stacksTo(16)));
public static final RegistryObject<Item> SCROLL_REPEL = ITEMS.register("scroll_repel", () -> new ScrollRepel(new Item.Properties().stacksTo(16))); public static final RegistryObject<Item> SCROLL_REPEL = ITEMS.register("scroll_repel", () -> new ScrollRepel(new Item.Properties().stacksTo(16)));
public static final RegistryObject<Item> SCROLL_BONEMEAL = ITEMS.register("scroll_bonemeal", () -> new ScrollBonemeal(new Item.Properties().stacksTo(16))); public static final RegistryObject<Item> SCROLL_BONEMEAL = ITEMS.register("scroll_bonemeal", () -> new ScrollBonemeal(new Item.Properties().stacksTo(16)));
// AMULETS
public static final RegistryObject<Item> AMULET_REPAIR = ITEMS.register("amulet_repair", () -> new AmuletRepair(new Item.Properties())); public static final RegistryObject<Item> AMULET_REPAIR = ITEMS.register("amulet_repair", () -> new AmuletRepair(new Item.Properties()));
public static final RegistryObject<Item> AMULET_BREATHING = ITEMS.register("amulet_breathing", () -> new AmuletEffect(new Item.Properties(), MobEffects.WATER_BREATHING, 200, 500, 1)); public static final RegistryObject<Item> AMULET_BREATHING = ITEMS.register("amulet_breathing", () -> new AmuletEffect(new Item.Properties(), MobEffects.WATER_BREATHING, 200, 500, 1));
public static final RegistryObject<Item> AMULET_NIGHTVISION = ITEMS.register("amulet_nightvision", () -> new AmuletEffect(new Item.Properties(), MobEffects.NIGHT_VISION, 200, 500, 1)); public static final RegistryObject<Item> AMULET_NIGHTVISION = ITEMS.register("amulet_nightvision", () -> new AmuletEffect(new Item.Properties(), MobEffects.NIGHT_VISION, 200, 500, 1));

View File

@ -1,16 +1,12 @@
package com.jenny.magic.items.wands; package com.jenny.magic.items.wands;
import com.jenny.magic.config.ConfigServer; import com.jenny.magic.config.ConfigServer;
import com.jenny.magic.entities.BaseWandProjectile;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.MutableComponent;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -22,37 +18,17 @@ import static com.jenny.magic.Magic.MODID;
public abstract class BaseWand extends Item { public abstract class BaseWand extends Item {
public BaseWand(Item.Properties properties) { public BaseWand(Item.Properties properties) {
super(properties.stacksTo(1).durability(100)); super(properties.durability(100));
} }
@Override public static boolean tryUse(ItemStack itemStack, Player player) {
public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level pLevel, Player pPlayer, @NotNull InteractionHand pUsedHand) { if (!ConfigServer.C_PREVENT_BREAKING.get() || itemStack.getMaxDamage() - itemStack.getDamageValue() > 1) {
ItemStack itemstack = pPlayer.getItemInHand(pUsedHand); itemStack.hurtAndBreak(1, player, (player2) -> player2.broadcastBreakEvent(player2.getUsedItemHand()));
if (!ConfigServer.C_PREVENT_BREAKING.get() || itemstack.getMaxDamage() - itemstack.getDamageValue() > 1) {
BaseWandProjectile projectile = newProjectile(pLevel);
projectile.shootFromRotation(pPlayer, pPlayer.getXRot(), pPlayer.getYRot(), 0.0F, 2.0F);
pLevel.addFreshEntity(projectile);
itemstack.hurtAndBreak(1, pPlayer, (player) -> player.broadcastBreakEvent(pPlayer.getUsedItemHand()));
return InteractionResultHolder.success(itemstack);
}
return InteractionResultHolder.pass(itemstack);
}
@Override
public boolean isValidRepairItem(@NotNull ItemStack pStack, @NotNull ItemStack pRepairCandidate) {
if (pRepairCandidate.getItem().getDescriptionId().equals(Items.DIAMOND.getDescriptionId())) {
while (pRepairCandidate.getCount() >= 1 && pStack.isDamaged()) {
pRepairCandidate.shrink(1);
pStack.setDamageValue(pStack.getDamageValue() - 20);
}
return true; return true;
} else {
return false;
} }
return false;
} }
abstract BaseWandProjectile newProjectile(Level level);
@Override @Override
public void appendHoverText(@NotNull ItemStack pStack, @Nullable Level pLevel, @NotNull List<Component> pTooltipComponents, @NotNull TooltipFlag pIsAdvanced) { public void appendHoverText(@NotNull ItemStack pStack, @Nullable Level pLevel, @NotNull List<Component> pTooltipComponents, @NotNull TooltipFlag pIsAdvanced) {
String key = String.format("tooltip.%s.%s", MODID, this); String key = String.format("tooltip.%s.%s", MODID, this);

View File

@ -0,0 +1,50 @@
package com.jenny.magic.items.wands;
import com.jenny.magic.entities.BaseWandProjectile;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraftforge.registries.RegistryObject;
import org.jetbrains.annotations.NotNull;
public class ProjectileWand extends BaseWand {
private RegistryObject<EntityType<BaseWandProjectile>> projectile;
public ProjectileWand(Properties p_41383_, RegistryObject<EntityType<BaseWandProjectile>> projectile) {
super(p_41383_);
this.projectile = projectile;
}
@Override
public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level pLevel, Player pPlayer, @NotNull InteractionHand pUsedHand) {
ItemStack itemstack = pPlayer.getItemInHand(pUsedHand);
if (tryUse(itemstack, pPlayer)) {
BaseWandProjectile projectile = newProjectile(pLevel);
projectile.shootFromRotation(pPlayer, pPlayer.getXRot(), pPlayer.getYRot(), 0.0F, 2.0F);
pLevel.addFreshEntity(projectile);
return InteractionResultHolder.success(itemstack);
}
return InteractionResultHolder.pass(itemstack);
}
@Override
public boolean isValidRepairItem(@NotNull ItemStack pStack, @NotNull ItemStack pRepairCandidate) {
if (pRepairCandidate.getItem().getDescriptionId().equals(Items.DIAMOND.getDescriptionId())) {
while (pRepairCandidate.getCount() >= 1 && pStack.isDamaged()) {
pRepairCandidate.shrink(1);
pStack.setDamageValue(pStack.getDamageValue() - 20);
}
return true;
} else {
return false;
}
}
BaseWandProjectile newProjectile(Level level) {
return (BaseWandProjectile) projectile.get().create(level);
}
}

View File

@ -0,0 +1,58 @@
package com.jenny.magic.items.wands;
import com.jenny.magic.config.ConfigServer;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.UseAnim;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
public class WandBoost extends BaseWand {
public WandBoost(Properties pProperties) {
super(pProperties);
}
protected static @NotNull Vec3 directionPlayer(@NotNull LivingEntity livingEntity) {
float x = livingEntity.getXRot();
float y = livingEntity.getYRot();
float f = -Mth.sin(y * ((float) Math.PI / 180F)) * Mth.cos(x * ((float) Math.PI / 180F));
float f1 = -Mth.sin(x * ((float) Math.PI / 180F));
float f2 = Mth.cos(y * ((float) Math.PI / 180F)) * Mth.cos(x * ((float) Math.PI / 180F));
return new Vec3(f, f1, f2).normalize();
}
public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level pLevel, Player pPlayer, @NotNull InteractionHand pHand) {
ItemStack itemStack = pPlayer.getItemInHand(pHand);
if (tryUse(itemStack, pPlayer)) {
pPlayer.startUsingItem(pHand);
return InteractionResultHolder.consume(itemStack);
}
return InteractionResultHolder.fail(itemStack);
}
@Override
public void releaseUsing(@NotNull ItemStack itemStack, @NotNull Level level, @NotNull LivingEntity livingEntity, int pTimeLeft) {
if (!ConfigServer.C_PREVENT_BREAKING.get() || itemStack.getMaxDamage() - itemStack.getDamageValue() > 1) {
livingEntity.addDeltaMovement(directionPlayer(livingEntity).scale(getBoostPower(pTimeLeft)));
itemStack.hurtAndBreak(1, livingEntity, (player) -> player.broadcastBreakEvent(player.getUsedItemHand()));
}
}
protected float getBoostPower(int pTimeLeft) {
int timeUsed = Math.min(60, 72000 - pTimeLeft);
return (float) timeUsed / 60 * 2;
}
public int getUseDuration(@NotNull ItemStack pStack) {
return 72000;
}
public @NotNull UseAnim getUseAnimation(@NotNull ItemStack pStack) {
return UseAnim.BOW;
}
}

View File

@ -1,17 +0,0 @@
package com.jenny.magic.items.wands;
import com.jenny.magic.entities.BaseWandProjectile;
import com.jenny.magic.entities.HurtfulProjectile;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.Level;
public class WandHurtful extends BaseWand {
public WandHurtful(Item.Properties p_41383_) {
super(p_41383_);
}
@Override
BaseWandProjectile newProjectile(Level level) {
return new HurtfulProjectile(level);
}
}

View File

@ -0,0 +1,52 @@
package com.jenny.magic.items.wands;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class WandPush extends BaseWand {
public WandPush(Properties properties) {
super(properties);
}
private static @Nullable LivingEntity lookingAtClosest(@NotNull Player player) {
LivingEntity closest = null;
for (LivingEntity e : player.level().getEntitiesOfClass(LivingEntity.class,
new AABB(player.position().subtract(10, 10, 10), player.position().add(10, 10, 10)))) {
if (!e.is(player) && lookingAtEntity(e, player)) {
if (closest == null || closest.distanceTo(player) > e.distanceTo(player)) {
closest = e;
}
}
}
return closest;
}
private static boolean lookingAtEntity(Entity e, Player p) {
Vec3 vec3 = p.getViewVector(1.0F).normalize();
Vec3 vec31 = new Vec3(e.getX() - p.getX(), e.getEyeY() - p.getEyeY(), e.getZ() - p.getZ());
double d0 = vec31.length();
vec31 = vec31.normalize();
double d1 = vec3.dot(vec31);
return d1 > (double) 1.0F - 0.025 / d0 && p.hasLineOfSight(e);
}
public @NotNull InteractionResultHolder<ItemStack> use(@NotNull Level pLevel, Player pPlayer, @NotNull InteractionHand pHand) {
ItemStack itemStack = pPlayer.getItemInHand(pHand);
LivingEntity target = lookingAtClosest(pPlayer);
if (target != null && tryUse(itemStack, pPlayer)) {
target.addDeltaMovement(target.position().subtract(pPlayer.position()).normalize().scale(2));
return InteractionResultHolder.consume(itemStack);
}
return InteractionResultHolder.fail(itemStack);
}
}

View File

@ -0,0 +1,12 @@
package com.jenny.magic.particles;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.SpriteSet;
public class FallingParticle extends BasicParticle {
FallingParticle(ClientLevel pLevel, double pX, double pY, double pZ, double pXSpeed, double pYSpeed, double pZSpeed, SpriteSet pSprites) {
super(pLevel, pX, pY, pZ, pXSpeed, pYSpeed, pZSpeed, pSprites);
this.hasPhysics = true;
this.gravity = 10f;
}
}

View File

@ -1,52 +0,0 @@
package com.jenny.magic.particles;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.ParticleProvider;
import net.minecraft.client.particle.ParticleRenderType;
import net.minecraft.client.particle.SpriteSet;
import net.minecraft.client.particle.TextureSheetParticle;
import net.minecraft.core.particles.SimpleParticleType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull;
public class Particle extends TextureSheetParticle {
private final float quadSizeStart;
protected Particle(ClientLevel level, double xCoord, double yCoord, double zCoord,
SpriteSet spriteSet, double xd, double yd, double zd) {
super(level, xCoord, yCoord, zCoord, xd, yd, zd);
this.friction = 0.8F;
this.xd = xd;
this.yd = yd;
this.zd = zd;
this.quadSizeStart = this.quadSize;
this.lifetime = 40;
this.setSpriteFromAge(spriteSet);
this.rCol = 1f;
this.gCol = 1f;
this.bCol = 1f;
}
@Override
@NotNull
public ParticleRenderType getRenderType() {
return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
}
@OnlyIn(Dist.CLIENT)
public static class Provider implements ParticleProvider<SimpleParticleType> {
private final SpriteSet sprites;
public Provider(SpriteSet spriteSet) {
this.sprites = spriteSet;
}
public net.minecraft.client.particle.Particle createParticle(@NotNull SimpleParticleType particleType, @NotNull ClientLevel level,
double x, double y, double z,
double dx, double dy, double dz) {
return new Particle(level, x, y, z, this.sprites, dx, dy, dz);
}
}
}

View File

@ -19,6 +19,10 @@ public class particles {
public static final RegistryObject<SimpleParticleType> PARTICLE_HEALTH = public static final RegistryObject<SimpleParticleType> PARTICLE_HEALTH =
PARTICLES.register("particle_health", () -> new SimpleParticleType(true)); PARTICLES.register("particle_health", () -> new SimpleParticleType(true));
public static final RegistryObject<SimpleParticleType> PARTICLE_FLYING_RED =
PARTICLES.register("particle_flying_red", () -> new SimpleParticleType(true));
public static final RegistryObject<SimpleParticleType> PARTICLE_HIT_RED =
PARTICLES.register("particle_hit_red", () -> new SimpleParticleType(true));
public static void register(IEventBus bus) { public static void register(IEventBus bus) {
PARTICLES.register(bus); PARTICLES.register(bus);
@ -27,5 +31,7 @@ public class particles {
@SubscribeEvent @SubscribeEvent
public static void registerParticleFactories(final RegisterParticleProvidersEvent event) { public static void registerParticleFactories(final RegisterParticleProvidersEvent event) {
Minecraft.getInstance().particleEngine.register(PARTICLE_HEALTH.get(), BasicParticle.Provider::new); Minecraft.getInstance().particleEngine.register(PARTICLE_HEALTH.get(), BasicParticle.Provider::new);
Minecraft.getInstance().particleEngine.register(PARTICLE_FLYING_RED.get(), FallingParticle.Provider::new);
Minecraft.getInstance().particleEngine.register(PARTICLE_HIT_RED.get(), FallingParticle.Provider::new);
} }
} }

View File

@ -0,0 +1,5 @@
{
"textures": [
"magic:particle_flying_red"
]
}

View File

@ -0,0 +1,5 @@
{
"textures": [
"magic:particle_hit_red"
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B