diff --git a/src/main/java/carpet/helpers/ParticleDisplay.java b/src/main/java/carpet/helpers/ParticleDisplay.java new file mode 100644 index 00000000..38f50a52 --- /dev/null +++ b/src/main/java/carpet/helpers/ParticleDisplay.java @@ -0,0 +1,73 @@ +package carpet.helpers; + +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.command.arguments.ParticleArgumentType; +import net.minecraft.particle.ParticleEffect; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.math.Vec3d; + +import java.util.HashMap; +import java.util.Map; + +public class ParticleDisplay +{ + private static Map particleCache = new HashMap<>(); + + private static ParticleEffect parseParticle(String name) + { + try + { + return ParticleArgumentType.readParameters(new StringReader(name)); + } + catch (CommandSyntaxException e) + { + throw new RuntimeException("No such particle: "+name); + } + } + private static ParticleEffect getEffect(String name) + { + if (name == null) return null; + ParticleEffect res = particleCache.get(name); + if (res != null) return res; + particleCache.put(name, parseParticle(name)); + return particleCache.get(name); + } + + public static void drawParticleLine(ServerPlayerEntity player, Vec3d from, Vec3d to,String main) + { + drawParticleLine(player, from, to, main, null, 1, 0.0); + } + + public static void drawParticleLine(ServerPlayerEntity player, Vec3d from, Vec3d to, String main, String accent, int count, double spread) + { + ParticleEffect accentParticle = getEffect(accent); + ParticleEffect mainParticle = getEffect(main); + + if (accentParticle != null) ((ServerWorld)player.world).spawnParticles( + player, + accentParticle, + true, + to.x, to.y, to.z, count, + spread, spread, spread, 0.0); + + double lineLengthSq = from.squaredDistanceTo(to); + if (lineLengthSq == 0) return; + + Vec3d incvec = to.subtract(from).normalize();// multiply(50/sqrt(lineLengthSq)); + int pcount = 0; + for (Vec3d delta = new Vec3d(0.0,0.0,0.0); + delta.lengthSquared() optional_1 = this.brain.getOptionalMemory(MemoryModuleType.GOLEM_LAST_SEEN_TIME); @@ -58,8 +83,57 @@ public abstract class VillagerEntity_aiMixin extends AbstractTraderEntity (recentlySeen?"rb ":"lb ")+time )); this.setCustomNameVisible(true); } + else if (MobAI.isTracking(this, MobAI.TrackingType.VILLAGER_BREEDING)) + { + if (age % 50 == 0 || age < 20) + { + totalFood = getAvailableFood() / 12; + hasBed = this.brain.getOptionalMemory(MemoryModuleType.HOME).isPresent(); + displayAge = getBreedingAge(); + + } + if (Math.abs(displayAge) < 100 && displayAge !=0) displayAge = getBreedingAge(); + + this.setCustomName(Messenger.c( + (hasBed?"eb ":"fb ")+"\u263d ", + (totalFood>0?"eb ":"fb ")+"\u2668",(totalFood>0?"e ":"f ")+totalFood+" ", + (displayAge==0?"eb ":"fb ")+"\u2661",(displayAge==0?"e ":"f ")+displayAge+"" + )); + this.setCustomNameVisible(true); + } } + @Inject(method = "interactMob", at = @At("HEAD"), cancellable = true) + private void onInteract(PlayerEntity playerEntity_1, Hand hand_1, CallbackInfoReturnable cir) + { + if (MobAI.isTracking(this, MobAI.TrackingType.VILLAGER_BREEDING)) + { + ItemStack itemStack_1 = playerEntity_1.getStackInHand(hand_1); + if (itemStack_1.getItem() == Items.EMERALD) + { + GlobalPos bedPos = this.brain.getOptionalMemory(MemoryModuleType.HOME).orElse(null); + if (bedPos == null || bedPos.getDimension() != dimension) + { + sayNo(); + ((ServerWorld) getEntityWorld()).spawnParticles(ParticleTypes.BARRIER, x, y + getStandingEyeHeight() + 1, z, 1, 0.1, 0.1, 0.1, 0.0); + } + else + { + + ParticleDisplay.drawParticleLine((ServerPlayerEntity) playerEntity_1, getPos(), new Vec3d(bedPos.getPos()).add(0.5, 0.5, 0.5), "dust 0 0 0 1", "happy_villager", 100, 0.2); + } + } + else if (itemStack_1.getItem() == Items.ROTTEN_FLESH) + { + while(getAvailableFood() >= 12) eatForBreeding(); + + } + cir.setReturnValue(false); + cir.cancel(); + } + } + + @Inject(method = "summonGolem", at = @At( value = "INVOKE", target = "Lnet/minecraft/util/math/Box;expand(DDD)Lnet/minecraft/util/math/Box;", @@ -67,7 +141,7 @@ public abstract class VillagerEntity_aiMixin extends AbstractTraderEntity )) private void particleIt(long long_1, int int_1, CallbackInfo ci) { - if (MobAI.isTracking(this, MobAI.TrackingType.IRON_GOLEM_SPAWNING) && !getEntityWorld().isClient()) + if (MobAI.isTracking(this, MobAI.TrackingType.IRON_GOLEM_SPAWNING)) { ((ServerWorld) getEntityWorld()).spawnParticles(ParticleTypes.BARRIER, x, y+3, z, 1, 0.1, 0.1, 0.1, 0.0); } diff --git a/src/main/java/carpet/utils/MobAI.java b/src/main/java/carpet/utils/MobAI.java index 76f94401..7e173e65 100644 --- a/src/main/java/carpet/utils/MobAI.java +++ b/src/main/java/carpet/utils/MobAI.java @@ -25,6 +25,8 @@ public class MobAI public static boolean isTracking(Entity e, TrackingType type) { + if (e.getEntityWorld().isClient()) + return false; Set currentTrackers = aiTrackers.get(e.getType()); if (currentTrackers == null) return false; @@ -72,7 +74,8 @@ public class MobAI public enum TrackingType { - IRON_GOLEM_SPAWNING("iron_golem_spawning", Sets.newHashSet(EntityType.VILLAGER)); + IRON_GOLEM_SPAWNING("iron_golem_spawning", Sets.newHashSet(EntityType.VILLAGER)), + VILLAGER_BREEDING("villager_breeding", Sets.newHashSet(EntityType.VILLAGER)); public Set types; public String name; TrackingType(String name, Set applicableTypes)