diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ChillingBreathSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ChillingBreathSpell.java new file mode 100644 index 00000000..9b21a8aa --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/ChillingBreathSpell.java @@ -0,0 +1,34 @@ +package com.minelittlepony.unicopia.ability.magic.spell.effect; + +import com.minelittlepony.unicopia.ability.magic.Caster; +import com.minelittlepony.unicopia.ability.magic.spell.HomingSpell; +import com.minelittlepony.unicopia.ability.magic.spell.Situation; +import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; +import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; +import com.minelittlepony.unicopia.entity.LavaAffine; + +import net.minecraft.entity.Entity; + +public class ChillingBreathSpell extends AbstractSpell implements HomingSpell { + public static final SpellTraits DEFAULT_TRAITS = new SpellTraits.Builder() + .with(Trait.ICE, 15) + .build(); + + protected ChillingBreathSpell(SpellType type, SpellTraits traits) { + super(type, traits); + } + + @Override + public boolean tick(Caster source, Situation situation) { + source.subtractEnergyCost(90); + return false; + } + + @Override + public boolean setTarget(Entity target) { + if (target instanceof LavaAffine affine) { + affine.setLavaAffine(!affine.isLavaAffine()); + } + return true; + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java index 8991db26..405ab73f 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/effect/SpellType.java @@ -45,13 +45,14 @@ public final class SpellType implements Affine, SpellPredicate< public static final SpellType CHANGELING_DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, SpellTraits.EMPTY, DispersableDisguiseSpell::new); public static final SpellType RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, SpellTraits.EMPTY, RainboomAbilitySpell::new); - public static final SpellType FROST = register("frost", Affinity.GOOD, 0xFAEAFA, true, IceSpell.DEFAULT_TRAITS, IceSpell::new); + public static final SpellType FROST = register("frost", Affinity.GOOD, 0xEABBFF, true, IceSpell.DEFAULT_TRAITS, IceSpell::new); + public static final SpellType CHILLING_BREATH = register("chilling_breath", Affinity.NEUTRAL, 0xFFEAFF, true, ChillingBreathSpell.DEFAULT_TRAITS, ChillingBreathSpell::new); public static final SpellType SCORCH = register("scorch", Affinity.BAD, 0xF8EC1F, true, ScorchSpell.DEFAULT_TRAITS, ScorchSpell::new); public static final SpellType FLAME = register("flame", Affinity.GOOD, 0xFFBB99, true, FireSpell.DEFAULT_TRAITS, FireSpell::new); public static final SpellType INFERNAL = register("infernal", Affinity.BAD, 0xFFAA00, true, InfernoSpell.DEFAULT_TRAITS, InfernoSpell::new); public static final SpellType SHIELD = register("shield", Affinity.NEUTRAL, 0x66CDAA, true, ShieldSpell.DEFAULT_TRAITS, ShieldSpell::new); - public static final SpellType VORTEX = register("vortex", Affinity.NEUTRAL, 0x4CDEE7, true, AttractiveSpell.DEFAULT_TRAITS, AttractiveSpell::new); - public static final SpellType DARK_VORTEX = register("dark_vortex", Affinity.BAD, 0, true, DarkVortexSpell.DEFAULT_TRAITS, DarkVortexSpell::new); + public static final SpellType VORTEX = register("vortex", Affinity.NEUTRAL, 0xFFEA88, true, AttractiveSpell.DEFAULT_TRAITS, AttractiveSpell::new); + public static final SpellType DARK_VORTEX = register("dark_vortex", Affinity.BAD, 0xA33333, true, DarkVortexSpell.DEFAULT_TRAITS, DarkVortexSpell::new); public static final SpellType NECROMANCY = register("necromancy", Affinity.BAD, 0xFA3A3A, true, NecromancySpell::new); public static final SpellType SIPHONING = register("siphoning", Affinity.NEUTRAL, 0xFFA3AA, true, SiphoningSpell::new); public static final SpellType REVEALING = register("reveal", Affinity.GOOD, 0xFFFFAF, true, DisperseIllusionSpell::new); diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index 6eebed20..c46dcc83 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -12,13 +12,7 @@ import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle; import com.minelittlepony.unicopia.client.particle.RaindropsParticle; import com.minelittlepony.unicopia.client.particle.RunesParticle; import com.minelittlepony.unicopia.client.particle.SphereParticle; -import com.minelittlepony.unicopia.client.render.AccessoryFeatureRenderer; -import com.minelittlepony.unicopia.client.render.AmuletFeatureRenderer; -import com.minelittlepony.unicopia.client.render.BatWingsFeatureRenderer; -import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer; -import com.minelittlepony.unicopia.client.render.FloatingArtefactEntityRenderer; -import com.minelittlepony.unicopia.client.render.IcarusWingsFeatureRenderer; -import com.minelittlepony.unicopia.client.render.WingsFeatureRenderer; +import com.minelittlepony.unicopia.client.render.*; import com.minelittlepony.unicopia.client.render.entity.ButterflyEntityRenderer; import com.minelittlepony.unicopia.client.render.entity.CastSpellEntityRenderer; import com.minelittlepony.unicopia.client.render.entity.FairyEntityRenderer; @@ -29,6 +23,8 @@ import com.minelittlepony.unicopia.item.ChameleonItem; import com.minelittlepony.unicopia.item.GemstoneItem; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.particle.UParticles; + +import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry; import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry.PendingParticleFactory; import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; @@ -45,6 +41,7 @@ import net.minecraft.client.render.entity.FlyingItemEntityRenderer; import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.model.json.ModelTransformation; import net.minecraft.client.world.ClientWorld; +import net.minecraft.fluid.Fluids; import net.minecraft.item.DyeableItem; import net.minecraft.particle.ParticleEffect; import net.minecraft.util.Identifier; @@ -117,6 +114,9 @@ public interface URenderers { ColorProviderRegistry.ITEM.register((stack, i) -> { return i > 0 || !GemstoneItem.isEnchanted(stack) ? -1 : GemstoneItem.getSpellKey(stack).getColor(); }, UItems.GEMSTONE); + + // for lava boats + BlockRenderLayerMap.INSTANCE.putFluids(RenderLayers.getTranslucent(), Fluids.LAVA, Fluids.FLOWING_LAVA); } static PendingParticleFactory createFactory(ParticleSupplier supplier) { diff --git a/src/main/java/com/minelittlepony/unicopia/entity/LavaAffine.java b/src/main/java/com/minelittlepony/unicopia/entity/LavaAffine.java new file mode 100644 index 00000000..cc0d2e61 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/LavaAffine.java @@ -0,0 +1,7 @@ +package com.minelittlepony.unicopia.entity; + +public interface LavaAffine { + void setLavaAffine(boolean lavaAffine); + + boolean isLavaAffine(); +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Removeable.java b/src/main/java/com/minelittlepony/unicopia/entity/Removeable.java new file mode 100644 index 00000000..eb133988 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/entity/Removeable.java @@ -0,0 +1,7 @@ +package com.minelittlepony.unicopia.entity; + +import net.minecraft.entity.Entity.RemovalReason; + +public interface Removeable { + void setRemovalReason(RemovalReason reason); +} diff --git a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java index 4f8525c6..1372c8a6 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/behaviour/EntityBehaviour.java @@ -9,7 +9,7 @@ import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.entity.ItemWielder; import com.minelittlepony.unicopia.entity.player.Pony; -import com.minelittlepony.unicopia.mixin.MixinEntity; +import com.minelittlepony.unicopia.entity.Removeable; import com.minelittlepony.unicopia.util.Registries; import net.minecraft.entity.Entity; @@ -105,7 +105,7 @@ public class EntityBehaviour { public void copyBaseAttributes(LivingEntity from, Entity to, Vec3d positionOffset) { // Set first because position calculations rely on it to.age = from.age; - ((MixinEntity)to).setRemovalReason(from.getRemovalReason()); + ((Removeable)to).setRemovalReason(from.getRemovalReason()); to.setOnGround(from.isOnGround()); if (!from.world.isClient) { diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinBoatEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinBoatEntity.java new file mode 100644 index 00000000..8da4742b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinBoatEntity.java @@ -0,0 +1,71 @@ +package com.minelittlepony.unicopia.mixin; + +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.*; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.minelittlepony.unicopia.entity.LavaAffine; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.data.*; +import net.minecraft.entity.vehicle.BoatEntity; +import net.minecraft.fluid.Fluid; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.tag.FluidTags; +import net.minecraft.tag.TagKey; + +@Mixin(BoatEntity.class) +abstract class MixinBoatEntity extends Entity implements LavaAffine { + + private static final TrackedData IS_LAVA_BOAT = DataTracker.registerData(BoatEntity.class, TrackedDataHandlerRegistry.BOOLEAN); + + MixinBoatEntity() { super(null, null); } + + @Redirect( + method = { + "getWaterHeightBelow", + "checkBoatInWater", + "getUnderWaterLocation", + "fall", + "canAddPassenger" + }, + at = @At(value = "FIELD", target = "net/minecraft/tag/FluidTags.WATER:Lnet/minecraft/tag/TagKey;", opcode = Opcodes.GETSTATIC) + ) + private TagKey redirectFluidTag() { + return isLavaAffine() ? FluidTags.LAVA : FluidTags.WATER; + } + + @Inject(method = "copyEntityData", at = @At("HEAD")) + private void onCopyEntityData(Entity entity, CallbackInfo info) { + if (entity instanceof LavaAffine affine) { + affine.setLavaAffine(isLavaAffine()); + } + } + + @Inject(method = "writeCustomDataToNbt", at = @At("HEAD")) + private void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo info) { + nbt.putBoolean("IsLavaAffine", isLavaAffine()); + } + + @Inject(method = "readCustomDataFromNbt", at = @At("HEAD")) + private void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo info) { + setLavaAffine(nbt.getBoolean("IsLavaAffine")); + } + + @Inject(method = "initDataTracker", at = @At("HEAD")) + private void onInitDataTracker(CallbackInfo info) { + dataTracker.startTracking(IS_LAVA_BOAT, false); + } + + @Override + public void setLavaAffine(boolean lavaAffine) { + dataTracker.set(IS_LAVA_BOAT, lavaAffine); + } + + @Override + public boolean isLavaAffine() { + return dataTracker.get(IS_LAVA_BOAT); + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java index 1b96b85a..3a7bfc39 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java @@ -2,11 +2,26 @@ package com.minelittlepony.unicopia.mixin; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.minelittlepony.unicopia.entity.LavaAffine; +import com.minelittlepony.unicopia.entity.Removeable; + import net.minecraft.entity.Entity; import net.minecraft.entity.Entity.RemovalReason; @Mixin(Entity.class) -public interface MixinEntity { +abstract class MixinEntity implements Removeable { + @Override @Accessor - void setRemovalReason(RemovalReason reason); + public abstract void setRemovalReason(RemovalReason reason); + + @Inject(method = "isFireImmune", at = @At("HEAD"), cancellable = true) + private void onIsFireImmune(CallbackInfoReturnable info) { + if (this instanceof LavaAffine e && e.isLavaAffine()) { + info.setReturnValue(true); + } + } } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 092a5542..50ca91ca 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -134,6 +134,8 @@ "spell.unicopia.frost": "Frost", "spell.unicopia.frost.lore": "Chilling to the touch, this gem will freeze whatever it is used on", + "spell.unicopia.chilling_breath": "Chilling Breath", + "spell.unicopia.chilling_breath.lore": "Alters the ability of certain objects to distenguish between hot and cold", "spell.unicopia.scorch": "Scorching", "spell.unicopia.scorch.lore": "Warm to the touch, this gem will burn organic matter", "spell.unicopia.flame": "Flame", diff --git a/src/main/resources/assets/unicopia/spellbook/chapters/ice_magic.json b/src/main/resources/assets/unicopia/spellbook/chapters/ice_magic.json index d4ef1391..fc4dfcb2 100644 --- a/src/main/resources/assets/unicopia/spellbook/chapters/ice_magic.json +++ b/src/main/resources/assets/unicopia/spellbook/chapters/ice_magic.json @@ -33,13 +33,32 @@ }, { "title": "", - "level": 0, + "level": 3, "elements": [ { "recipe": "unicopia:spells/frost" }, "Requires:", "- At least 15x cold trait" ] }, + { + "title": "Chilling Breath", + "level": 0, + "elements": [ + "Alters the ability of certain objects to distenguish between hot and cold.", + "This is a very weak spell, but when used with a boat can be exceedingly useful to get out of a sticky stituation.", + { "x": 125, "y": -20, "width": 32, "height": 32, "texture": "minecraft:textures/item/boat.png" }, + { "x": 125, "y": -20, "width": 16, "height": 16, "texture": "unicopia:textures/gui/trait/ice.png" } + ] + }, + { + "title": "", + "level": 0, + "elements": [ + { "recipe": "unicopia:spells/chilling_breath" }, + "Requires:", + "- At least 5x cold trait\n- At least 15x knowleged trait" + ] + }, { "title": "5th Trot '12", "level": 4, diff --git a/src/main/resources/data/unicopia/recipes/spells/chilling_breath.json b/src/main/resources/data/unicopia/recipes/spells/chilling_breath.json new file mode 100644 index 00000000..0d41bcbb --- /dev/null +++ b/src/main/resources/data/unicopia/recipes/spells/chilling_breath.json @@ -0,0 +1,12 @@ +{ + "type": "unicopia:spellbook/crafting", + "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, + "traits": { + "ice": 15 + }, + "ingredients": [], + "result": { + "item": "unicopia:gemstone", + "spell": "unicopia:chilling_breath" + } +} \ No newline at end of file diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index bc434a41..1cbce8ea 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -8,6 +8,7 @@ "MixinBlazeEntity", "MixinBlockEntity", "MixinBlockItem", + "MixinBoatEntity", "MixinBrain", "MixinCriteria", "MixinDamageSource",