Skip to content
Open
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "hexcasting:item/neural_fiber"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_item": {
"conditions": {
"items": [
{
"items": "hexcasting:neural_fiber"
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "hexcasting:robes/boots"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_the_recipe",
"has_item"
]
],
"rewards": {
"recipes": [
"hexcasting:robes/boots"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_item": {
"conditions": {
"items": [
{
"items": "hexcasting:neural_fiber"
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "hexcasting:robes/hood"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_the_recipe",
"has_item"
]
],
"rewards": {
"recipes": [
"hexcasting:robes/hood"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_item": {
"conditions": {
"items": [
{
"items": "hexcasting:neural_fiber"
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "hexcasting:robes/legs"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_the_recipe",
"has_item"
]
],
"rewards": {
"recipes": [
"hexcasting:robes/legs"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"parent": "minecraft:recipes/root",
"criteria": {
"has_item": {
"conditions": {
"items": [
{
"items": "hexcasting:neural_fiber"
}
]
},
"trigger": "minecraft:inventory_changed"
},
"has_the_recipe": {
"conditions": {
"recipe": "hexcasting:robes/tunic"
},
"trigger": "minecraft:recipe_unlocked"
}
},
"requirements": [
[
"has_the_recipe",
"has_item"
]
],
"rewards": {
"recipes": [
"hexcasting:robes/tunic"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"type": "minecraft:crafting_shaped",
"category": "equipment",
"key": {
"B": {
"item": "minecraft:bone"
},
"F": {
"item": "hexcasting:neural_fiber"
}
},
"pattern": [
" ",
"B B",
"F F"
],
"result": {
"count": 1,
"id": "hexcasting:robes/boots"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"type": "minecraft:crafting_shaped",
"category": "equipment",
"key": {
"B": {
"item": "minecraft:bone"
},
"F": {
"item": "hexcasting:neural_fiber"
}
},
"pattern": [
"BFB",
"F F"
],
"result": {
"count": 1,
"id": "hexcasting:robes/hood"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"type": "minecraft:crafting_shaped",
"category": "equipment",
"key": {
"F": {
"item": "hexcasting:neural_fiber"
}
},
"pattern": [
"FFF",
"F F",
"F F"
],
"result": {
"count": 1,
"id": "hexcasting:robes/legs"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"type": "minecraft:crafting_shaped",
"category": "equipment",
"key": {
"F": {
"item": "hexcasting:neural_fiber"
}
},
"pattern": [
"F F",
"FFF",
"FFF"
],
"result": {
"count": 1,
"id": "hexcasting:robes/tunic"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,25 @@ public Particle createParticle(ConjureParticleOptions type, ClientLevel level,
}
}

// the code in LivingEntity that creates status effect particles hardcodes their velocity to (1,1,1) for some reason
// all the vanilla particles *used* for status effects have custom providers which completely ignore that velocity
// so we need to do that too, otherwise the particles just shoot off in a diagonal line
public static class StatusEffectProvider implements ParticleProvider<ConjureParticleOptions> {
private final SpriteSet sprite;

public StatusEffectProvider(SpriteSet pSprites) {
this.sprite = pSprites;
}

@Nullable
@Override
public Particle createParticle(ConjureParticleOptions type, ClientLevel level,
double pX, double pY, double pZ,
double pXSpeed, double pYSpeed, double pZSpeed) {
return new ConjureParticle(level, pX, pY, pZ, 0, 0, 0, this.sprite, type.color());
}
}

// https://github.com/VazkiiMods/Botania/blob/db85d778ab23f44c11181209319066d1f04a9e3d/Xplat/src/main/java/vazkii/botania/client/fx/FXWisp.java
private record ConjureRenderType() implements ParticleRenderType {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
import at.petrak.hexcasting.api.casting.getMob
import at.petrak.hexcasting.api.casting.getVec3
import at.petrak.hexcasting.api.casting.iota.Iota
import at.petrak.hexcasting.api.casting.mishaps.Mishap
import at.petrak.hexcasting.api.casting.mishaps.MishapAlreadyBrainswept
import at.petrak.hexcasting.api.casting.mishaps.MishapBadBrainsweep
import at.petrak.hexcasting.api.casting.mishaps.MishapBadLocation
import at.petrak.hexcasting.api.misc.MediaConstants
import at.petrak.hexcasting.api.mod.HexConfig
import at.petrak.hexcasting.api.mod.HexTags
import at.petrak.hexcasting.common.lib.HexDamageTypes
import at.petrak.hexcasting.common.lib.HexMobEffects
import at.petrak.hexcasting.common.recipe.BrainsweepRecipe
import at.petrak.hexcasting.common.recipe.HexRecipeStuffRegistry
import at.petrak.hexcasting.ktxt.tellWitnessesThatIWasMurdered
Expand All @@ -21,8 +25,12 @@ import at.petrak.hexcasting.xplat.IXplatAbstractions
import net.minecraft.core.BlockPos
import net.minecraft.sounds.SoundEvents
import net.minecraft.sounds.SoundSource
import net.minecraft.world.effect.MobEffectInstance
import net.minecraft.world.entity.Mob
import net.minecraft.world.entity.npc.AbstractVillager
import net.minecraft.world.entity.npc.Villager
import net.minecraft.world.level.block.Block
import net.minecraft.world.level.block.Blocks
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.Vec3

Expand Down Expand Up @@ -52,6 +60,17 @@ object OpBrainsweep : SpellAction {
if (IXplatAbstractions.INSTANCE.isBrainswept(sacrifice))
throw MishapAlreadyBrainswept(sacrifice)

// special behavior for crystallization
if (vecPos.closerThan(sacrifice.eyePosition, 0.1)
&& sacrifice.hasEffect(HexMobEffects.ENLARGE_GRID)
&& sacrifice is AbstractVillager) {
return SpellAction.Result(
AltSpell(sacrifice, pos),
MediaConstants.CRYSTAL_UNIT * 10,
listOf(ParticleSpray.burst(Vec3.atCenterOf(pos), 1.0))
)
}

val state = env.world.getBlockState(pos)

val recman = env.world.recipeManager
Expand Down Expand Up @@ -89,4 +108,26 @@ object OpBrainsweep : SpellAction {
env.world.playSound(null, sacrifice, SoundEvents.PLAYER_LEVELUP, SoundSource.AMBIENT, 0.5f, 0.8f)
}
}

private data class AltSpell(val sacrifice: Mob, val pos: BlockPos) : RenderedSpell {
override fun cast(env: CastingEnvironment) {
val amount = sacrifice.health * 0.1F
Mishap.trulyHurt(sacrifice, sacrifice.damageSources().source(HexDamageTypes.OVERCAST), amount)

val blockStateId = Block.getId(Blocks.AMETHYST_BLOCK.defaultBlockState())
env.world.levelEvent(2001, pos, blockStateId)
env.world.levelEvent(2001, pos.below(), blockStateId)

sacrifice.removeEffect(HexMobEffects.ENLARGE_GRID)
sacrifice.addEffect(MobEffectInstance(HexMobEffects.CRYSTALLIZED, -1))

HexAPI.instance().brainsweep(sacrifice)

if (sacrifice is Villager && HexConfig.server().doVillagersTakeOffenseAtMindMurder()) {
env.castingEntity?.let { sacrifice.tellWitnessesThatIWasMurdered(it) }
}

env.world.playSound(null, sacrifice, SoundEvents.ZOMBIE_VILLAGER_CURE, SoundSource.AMBIENT, 0.8f, 1f)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public static void register() {
Map.of(), // no defense here since it's specified with the other attributes in ItemRobes
ArmorMaterials.GOLD.value().enchantmentValue(),
SoundEvents.ARMOR_EQUIP_LEATHER,
() -> Ingredient.EMPTY, // TODO: repair with whatever it's crafted with
() -> Ingredient.of(HexItems.NEURAL_FIBER.get()),
List.of(new ArmorMaterial.Layer(HexAPI.modLoc("robes"))),
0, 0 // no toughness or knockback resistance
));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ public static void registerItemsForCreativeTab(ResourceKey<CreativeModeTab> tabK
IXplatAbstractions.INSTANCE.addEquipSlotFabric(EquipmentSlot.HEAD)
.stacksTo(1).attributes(ItemLens.MODIFIERS)));

public static final Supplier<ItemRobes> ROBES_HOOD = make("robes/hood", () -> new ItemRobes(ArmorItem.Type.HELMET, unstackable()));
public static final Supplier<ItemRobes> ROBES_TUNIC = make("robes/tunic", () -> new ItemRobes(ArmorItem.Type.CHESTPLATE, unstackable()));
public static final Supplier<ItemRobes> ROBES_LEGS = make("robes/legs", () -> new ItemRobes(ArmorItem.Type.LEGGINGS, unstackable()));
public static final Supplier<ItemRobes> ROBES_BOOTS = make("robes/boots", () -> new ItemRobes(ArmorItem.Type.BOOTS, unstackable()));
public static final Supplier<ItemRobes> ROBES_HOOD = make("robes/hood", () -> new ItemRobes(ArmorItem.Type.HELMET, unstackable().rarity(Rarity.UNCOMMON)));
public static final Supplier<ItemRobes> ROBES_TUNIC = make("robes/tunic", () -> new ItemRobes(ArmorItem.Type.CHESTPLATE, unstackable().rarity(Rarity.UNCOMMON)));
public static final Supplier<ItemRobes> ROBES_LEGS = make("robes/legs", () -> new ItemRobes(ArmorItem.Type.LEGGINGS, unstackable().rarity(Rarity.UNCOMMON)));
public static final Supplier<ItemRobes> ROBES_BOOTS = make("robes/boots", () -> new ItemRobes(ArmorItem.Type.BOOTS, unstackable().rarity(Rarity.UNCOMMON)));

public static final Supplier<ItemAbacus> ABACUS = make("abacus", () -> new ItemAbacus(unstackable()));
public static final Supplier<ItemThoughtKnot> THOUGHT_KNOT = make("thought_knot", () -> new ItemThoughtKnot(unstackable()));
Expand All @@ -106,6 +106,8 @@ public static void registerItemsForCreativeTab(ResourceKey<CreativeModeTab> tabK
)
);

public static final Supplier<Item> NEURAL_FIBER = make("neural_fiber", () -> new Item(props().rarity(Rarity.UNCOMMON)));

public static final Supplier<ItemScroll> SCROLL_SMOL = make("scroll_small", () -> new ItemScroll(props(), 1));
public static final Supplier<ItemScroll> SCROLL_MEDIUM = make("scroll_medium", () -> new ItemScroll(props(), 2));
public static final Supplier<ItemScroll> SCROLL_LARGE = make("scroll", () -> new ItemScroll(props(), 3));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import at.petrak.hexcasting.api.HexAPI;
import at.petrak.hexcasting.common.misc.HexMobEffect;
import at.petrak.hexcasting.common.particles.ConjureParticleOptions;
import at.petrak.hexcasting.xplat.IXplatAbstractions;
import at.petrak.hexcasting.xplat.IXplatRegister;
import net.minecraft.core.Holder;
Expand All @@ -25,4 +26,6 @@ public static void register() {
public static final Holder<MobEffect> SHRINK_GRID = REGISTER.registerHolder("shrink_grid",
() -> new HexMobEffect(MobEffectCategory.HARMFUL, 0xc0e660).addAttributeModifier(HexAttributes.GRID_ZOOM, HexAPI.modLoc("shrink_grid"),
-0.2, AttributeModifier.Operation.ADD_MULTIPLIED_TOTAL));
public static final Holder<MobEffect> CRYSTALLIZED = REGISTER.registerHolder("crystallized",
() -> new HexMobEffect(MobEffectCategory.HARMFUL, 0x8932b8, new ConjureParticleOptions(0x8932b8, true)));
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ public static void register() {
}

public static final Supplier<ConjureParticleOptions.Type> CONJURE_PARTICLE = REGISTER.register(
"conjure_particle", () -> new ConjureParticleOptions.Type(false));
"conjure_particle", () -> new ConjureParticleOptions.Type(false, false));
public static final Supplier<ConjureParticleOptions.Type> STATUS_PARTICLE = REGISTER.register(
"status_particle", () -> new ConjureParticleOptions.Type(false, true));

public static class FactoryHandler {
public interface Consumer {
Expand All @@ -31,6 +33,7 @@ <T extends ParticleOptions> void register(ParticleType<T> type,

public static void registerFactories(Consumer consumer) {
consumer.register(CONJURE_PARTICLE.get(), ConjureParticle.Provider::new);
consumer.register(STATUS_PARTICLE.get(), ConjureParticle.StatusEffectProvider::new);
}
}
}
Loading
Loading