Added Chilling Breath spell

This commit is contained in:
Sollace 2022-09-11 15:42:26 +02:00
parent 0db98b8048
commit 22ada528fd
12 changed files with 184 additions and 15 deletions

View file

@ -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;
}
}

View file

@ -45,13 +45,14 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
public static final SpellType<AbstractDisguiseSpell> CHANGELING_DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, SpellTraits.EMPTY, DispersableDisguiseSpell::new); public static final SpellType<AbstractDisguiseSpell> CHANGELING_DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, SpellTraits.EMPTY, DispersableDisguiseSpell::new);
public static final SpellType<RainboomAbilitySpell> RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, SpellTraits.EMPTY, RainboomAbilitySpell::new); public static final SpellType<RainboomAbilitySpell> RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, SpellTraits.EMPTY, RainboomAbilitySpell::new);
public static final SpellType<IceSpell> FROST = register("frost", Affinity.GOOD, 0xFAEAFA, true, IceSpell.DEFAULT_TRAITS, IceSpell::new); public static final SpellType<IceSpell> FROST = register("frost", Affinity.GOOD, 0xEABBFF, true, IceSpell.DEFAULT_TRAITS, IceSpell::new);
public static final SpellType<ChillingBreathSpell> CHILLING_BREATH = register("chilling_breath", Affinity.NEUTRAL, 0xFFEAFF, true, ChillingBreathSpell.DEFAULT_TRAITS, ChillingBreathSpell::new);
public static final SpellType<ScorchSpell> SCORCH = register("scorch", Affinity.BAD, 0xF8EC1F, true, ScorchSpell.DEFAULT_TRAITS, ScorchSpell::new); public static final SpellType<ScorchSpell> SCORCH = register("scorch", Affinity.BAD, 0xF8EC1F, true, ScorchSpell.DEFAULT_TRAITS, ScorchSpell::new);
public static final SpellType<FireSpell> FLAME = register("flame", Affinity.GOOD, 0xFFBB99, true, FireSpell.DEFAULT_TRAITS, FireSpell::new); public static final SpellType<FireSpell> FLAME = register("flame", Affinity.GOOD, 0xFFBB99, true, FireSpell.DEFAULT_TRAITS, FireSpell::new);
public static final SpellType<InfernoSpell> INFERNAL = register("infernal", Affinity.BAD, 0xFFAA00, true, InfernoSpell.DEFAULT_TRAITS, InfernoSpell::new); public static final SpellType<InfernoSpell> INFERNAL = register("infernal", Affinity.BAD, 0xFFAA00, true, InfernoSpell.DEFAULT_TRAITS, InfernoSpell::new);
public static final SpellType<ShieldSpell> SHIELD = register("shield", Affinity.NEUTRAL, 0x66CDAA, true, ShieldSpell.DEFAULT_TRAITS, ShieldSpell::new); public static final SpellType<ShieldSpell> SHIELD = register("shield", Affinity.NEUTRAL, 0x66CDAA, true, ShieldSpell.DEFAULT_TRAITS, ShieldSpell::new);
public static final SpellType<AttractiveSpell> VORTEX = register("vortex", Affinity.NEUTRAL, 0x4CDEE7, true, AttractiveSpell.DEFAULT_TRAITS, AttractiveSpell::new); public static final SpellType<AttractiveSpell> VORTEX = register("vortex", Affinity.NEUTRAL, 0xFFEA88, true, AttractiveSpell.DEFAULT_TRAITS, AttractiveSpell::new);
public static final SpellType<DarkVortexSpell> DARK_VORTEX = register("dark_vortex", Affinity.BAD, 0, true, DarkVortexSpell.DEFAULT_TRAITS, DarkVortexSpell::new); public static final SpellType<DarkVortexSpell> DARK_VORTEX = register("dark_vortex", Affinity.BAD, 0xA33333, true, DarkVortexSpell.DEFAULT_TRAITS, DarkVortexSpell::new);
public static final SpellType<NecromancySpell> NECROMANCY = register("necromancy", Affinity.BAD, 0xFA3A3A, true, NecromancySpell::new); public static final SpellType<NecromancySpell> NECROMANCY = register("necromancy", Affinity.BAD, 0xFA3A3A, true, NecromancySpell::new);
public static final SpellType<SiphoningSpell> SIPHONING = register("siphoning", Affinity.NEUTRAL, 0xFFA3AA, true, SiphoningSpell::new); public static final SpellType<SiphoningSpell> SIPHONING = register("siphoning", Affinity.NEUTRAL, 0xFFA3AA, true, SiphoningSpell::new);
public static final SpellType<DisperseIllusionSpell> REVEALING = register("reveal", Affinity.GOOD, 0xFFFFAF, true, DisperseIllusionSpell::new); public static final SpellType<DisperseIllusionSpell> REVEALING = register("reveal", Affinity.GOOD, 0xFFFFAF, true, DisperseIllusionSpell::new);

View file

@ -12,13 +12,7 @@ import com.minelittlepony.unicopia.client.particle.RainbowTrailParticle;
import com.minelittlepony.unicopia.client.particle.RaindropsParticle; import com.minelittlepony.unicopia.client.particle.RaindropsParticle;
import com.minelittlepony.unicopia.client.particle.RunesParticle; import com.minelittlepony.unicopia.client.particle.RunesParticle;
import com.minelittlepony.unicopia.client.particle.SphereParticle; import com.minelittlepony.unicopia.client.particle.SphereParticle;
import com.minelittlepony.unicopia.client.render.AccessoryFeatureRenderer; import com.minelittlepony.unicopia.client.render.*;
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.entity.ButterflyEntityRenderer; import com.minelittlepony.unicopia.client.render.entity.ButterflyEntityRenderer;
import com.minelittlepony.unicopia.client.render.entity.CastSpellEntityRenderer; import com.minelittlepony.unicopia.client.render.entity.CastSpellEntityRenderer;
import com.minelittlepony.unicopia.client.render.entity.FairyEntityRenderer; 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.GemstoneItem;
import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.UItems;
import com.minelittlepony.unicopia.particle.UParticles; 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;
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry.PendingParticleFactory; import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry.PendingParticleFactory;
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; 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.item.ItemRenderer;
import net.minecraft.client.render.model.json.ModelTransformation; import net.minecraft.client.render.model.json.ModelTransformation;
import net.minecraft.client.world.ClientWorld; import net.minecraft.client.world.ClientWorld;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.DyeableItem; import net.minecraft.item.DyeableItem;
import net.minecraft.particle.ParticleEffect; import net.minecraft.particle.ParticleEffect;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
@ -117,6 +114,9 @@ public interface URenderers {
ColorProviderRegistry.ITEM.register((stack, i) -> { ColorProviderRegistry.ITEM.register((stack, i) -> {
return i > 0 || !GemstoneItem.isEnchanted(stack) ? -1 : GemstoneItem.getSpellKey(stack).getColor(); return i > 0 || !GemstoneItem.isEnchanted(stack) ? -1 : GemstoneItem.getSpellKey(stack).getColor();
}, UItems.GEMSTONE); }, UItems.GEMSTONE);
// for lava boats
BlockRenderLayerMap.INSTANCE.putFluids(RenderLayers.getTranslucent(), Fluids.LAVA, Fluids.FLOWING_LAVA);
} }
static <T extends ParticleEffect> PendingParticleFactory<T> createFactory(ParticleSupplier<T> supplier) { static <T extends ParticleEffect> PendingParticleFactory<T> createFactory(ParticleSupplier<T> supplier) {

View file

@ -0,0 +1,7 @@
package com.minelittlepony.unicopia.entity;
public interface LavaAffine {
void setLavaAffine(boolean lavaAffine);
boolean isLavaAffine();
}

View file

@ -0,0 +1,7 @@
package com.minelittlepony.unicopia.entity;
import net.minecraft.entity.Entity.RemovalReason;
public interface Removeable {
void setRemovalReason(RemovalReason reason);
}

View file

@ -9,7 +9,7 @@ import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.entity.ItemWielder; import com.minelittlepony.unicopia.entity.ItemWielder;
import com.minelittlepony.unicopia.entity.player.Pony; 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 com.minelittlepony.unicopia.util.Registries;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -105,7 +105,7 @@ public class EntityBehaviour<T extends Entity> {
public void copyBaseAttributes(LivingEntity from, Entity to, Vec3d positionOffset) { public void copyBaseAttributes(LivingEntity from, Entity to, Vec3d positionOffset) {
// Set first because position calculations rely on it // Set first because position calculations rely on it
to.age = from.age; to.age = from.age;
((MixinEntity)to).setRemovalReason(from.getRemovalReason()); ((Removeable)to).setRemovalReason(from.getRemovalReason());
to.setOnGround(from.isOnGround()); to.setOnGround(from.isOnGround());
if (!from.world.isClient) { if (!from.world.isClient) {

View file

@ -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<Boolean> 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<Fluid> 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);
}
}

View file

@ -2,11 +2,26 @@ package com.minelittlepony.unicopia.mixin;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor; 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;
import net.minecraft.entity.Entity.RemovalReason; import net.minecraft.entity.Entity.RemovalReason;
@Mixin(Entity.class) @Mixin(Entity.class)
public interface MixinEntity { abstract class MixinEntity implements Removeable {
@Override
@Accessor @Accessor
void setRemovalReason(RemovalReason reason); public abstract void setRemovalReason(RemovalReason reason);
@Inject(method = "isFireImmune", at = @At("HEAD"), cancellable = true)
private void onIsFireImmune(CallbackInfoReturnable<Boolean> info) {
if (this instanceof LavaAffine e && e.isLavaAffine()) {
info.setReturnValue(true);
}
}
} }

View file

@ -134,6 +134,8 @@
"spell.unicopia.frost": "Frost", "spell.unicopia.frost": "Frost",
"spell.unicopia.frost.lore": "Chilling to the touch, this gem will freeze whatever it is used on", "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": "Scorching",
"spell.unicopia.scorch.lore": "Warm to the touch, this gem will burn organic matter", "spell.unicopia.scorch.lore": "Warm to the touch, this gem will burn organic matter",
"spell.unicopia.flame": "Flame", "spell.unicopia.flame": "Flame",

View file

@ -33,13 +33,32 @@
}, },
{ {
"title": "", "title": "",
"level": 0, "level": 3,
"elements": [ "elements": [
{ "recipe": "unicopia:spells/frost" }, { "recipe": "unicopia:spells/frost" },
"Requires:", "Requires:",
"- At least 15x cold trait" "- 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", "title": "5th Trot '12",
"level": 4, "level": 4,

View file

@ -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"
}
}

View file

@ -8,6 +8,7 @@
"MixinBlazeEntity", "MixinBlazeEntity",
"MixinBlockEntity", "MixinBlockEntity",
"MixinBlockItem", "MixinBlockItem",
"MixinBoatEntity",
"MixinBrain", "MixinBrain",
"MixinCriteria", "MixinCriteria",
"MixinDamageSource", "MixinDamageSource",