datagen owo?
|
@ -270,7 +270,14 @@ d06214a759ea5db686cdc5982baa74e1bd678815 assets/hexcasting/models/item/slate.jso
|
|||
e7aa1f9b9eaf20cbeb19eaf9cb96f3276eca6dfd assets/hexcasting/models/item/slate_blank.json
|
||||
cc66962ddeef9b9c3a623eef178b352605f1c922 assets/hexcasting/models/item/slate_block.json
|
||||
1b61e7b2d78d4c8a2f1af6fb5c69ac4ac55abd50 assets/hexcasting/models/item/slate_written.json
|
||||
9a5f23f59453dc27233decd6110fbe9feab07a9d assets/hexcasting/models/item/spellbook.json
|
||||
7a8c14020214d280f6e74a676ce85fd34309123a assets/hexcasting/models/item/spellbook.json
|
||||
3693e033ab6a97c6daa3ef9ad874ac19a12e4830 assets/hexcasting/models/item/spellbook_double.json
|
||||
3cb2d9a21e2e563ae312122d4782f853bb02d546 assets/hexcasting/models/item/spellbook_empty.json
|
||||
2efe8bf6d19e69678947a0671eda4602f8a6e9be assets/hexcasting/models/item/spellbook_entity.json
|
||||
340f709290da53ba7df45aae868b39cc24c0ca7b assets/hexcasting/models/item/spellbook_list.json
|
||||
433e3374ba42e36c3a407bc2ab6c8a963d222946 assets/hexcasting/models/item/spellbook_pattern.json
|
||||
a217793791eba1fe7ee7512c3937a85cd1add8aa assets/hexcasting/models/item/spellbook_vec3.json
|
||||
7244ab0561bdd370cbd88c0d3dae3b49a3819b2a assets/hexcasting/models/item/spellbook_widget.json
|
||||
4a33e6984bdf63dc4b7a5da5643bb1155b62b636 assets/hexcasting/models/item/sub_sandwich.json
|
||||
3b1f2d0b315e8117f4c5fe593bd3ae028617b413 assets/hexcasting/models/item/trinket.json
|
||||
eeaa26fe380975188cd2d6a93bd5e324dc509767 assets/hexcasting/models/item/trinket_filled.json
|
||||
|
@ -466,9 +473,6 @@ d14cf2f8f0895a5b6dc09b7582c0abf1c2514adf data/hexcasting/recipes/sub_sandwich.js
|
|||
0521d57838cb3e9795fc02ce47aa58db3b0188f9 data/hexcasting/recipes/wand.json
|
||||
f3c6b6917e504e1c3d5d8875f7cce6f311e791d2 data/hexcasting/tags/blocks/akashic_logs.json
|
||||
b596d96eebb4f7bad5930f4eebc589f292b59c98 data/hexcasting/tags/blocks/akashic_planks.json
|
||||
f3c6b6917e504e1c3d5d8875f7cce6f311e791d2 data/hexcasting/tags/items/akashic_logs.json
|
||||
b596d96eebb4f7bad5930f4eebc589f292b59c98 data/hexcasting/tags/items/akashic_planks.json
|
||||
f930dbc5b41d42150d388e39b29b940229658809 data/minecraft/tags/blocks/crystal_sound_blocks.json
|
||||
556d2e6068965e90c307a435b372ae761cd1c606 data/minecraft/tags/blocks/doors.json
|
||||
c25784941d6416744fb2ca2d43a3203e5c3e7c8a data/minecraft/tags/blocks/leaves.json
|
||||
f3c6b6917e504e1c3d5d8875f7cce6f311e791d2 data/minecraft/tags/blocks/logs.json
|
||||
|
|
|
@ -1,6 +1,46 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/spellbook"
|
||||
}
|
||||
"overrides": [
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": -0.01
|
||||
},
|
||||
"model": "hexcasting:item/spellbook_empty"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 0.99
|
||||
},
|
||||
"model": "hexcasting:item/spellbook_entity"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 1.99
|
||||
},
|
||||
"model": "hexcasting:item/spellbook_double"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 2.99
|
||||
},
|
||||
"model": "hexcasting:item/spellbook_vec3"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 3.99
|
||||
},
|
||||
"model": "hexcasting:item/spellbook_widget"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 4.99
|
||||
},
|
||||
"model": "hexcasting:item/spellbook_list"
|
||||
},
|
||||
{
|
||||
"predicate": {
|
||||
"hexcasting:datatype": 5.99
|
||||
},
|
||||
"model": "hexcasting:item/spellbook_pattern"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/spellbook_double"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/spellbook_empty"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/spellbook_entity"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/spellbook_list"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/spellbook_pattern"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/spellbook_vec3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "hexcasting:item/spellbook_widget"
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
"replace": false,
|
||||
"values": [
|
||||
"hexcasting:conjured",
|
||||
"hexcasting:conjured_block",
|
||||
"hexcasting:amethyst_tiles",
|
||||
"hexcasting:amethyst_sconce"
|
||||
]
|
||||
|
|
|
@ -14,10 +14,7 @@ import at.petrak.hexcasting.common.blocks.HexBlocks;
|
|||
import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf;
|
||||
import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicRecord;
|
||||
import at.petrak.hexcasting.common.entities.HexEntities;
|
||||
import at.petrak.hexcasting.common.items.HexItems;
|
||||
import at.petrak.hexcasting.common.items.ItemFocus;
|
||||
import at.petrak.hexcasting.common.items.ItemScroll;
|
||||
import at.petrak.hexcasting.common.items.ItemSlate;
|
||||
import at.petrak.hexcasting.common.items.*;
|
||||
import at.petrak.hexcasting.common.items.magic.ItemManaBattery;
|
||||
import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell;
|
||||
import at.petrak.hexcasting.common.particles.HexParticles;
|
||||
|
@ -57,8 +54,9 @@ public class RegisterClientStuff {
|
|||
var tag = stack.getOrCreateTag();
|
||||
var isSealed = tag.getBoolean(ItemFocus.TAG_SEALED);
|
||||
var baseNum = isSealed ? 100f : 0f;
|
||||
if (stack.hasTag()) {
|
||||
var typename = tag.getCompound(ItemFocus.TAG_DATA).getAllKeys().iterator().next();
|
||||
var datum = HexItems.FOCUS.get().readDatumTag(stack);
|
||||
if (datum != null) {
|
||||
var typename = datum.getAllKeys().iterator().next();
|
||||
return baseNum + switch (typename) {
|
||||
case SpellDatum.TAG_ENTITY -> 1f;
|
||||
case SpellDatum.TAG_DOUBLE -> 2f;
|
||||
|
@ -72,6 +70,25 @@ public class RegisterClientStuff {
|
|||
return baseNum;
|
||||
}
|
||||
});
|
||||
ItemProperties.register(HexItems.SPELLBOOK.get(), ItemSpellbook.DATATYPE_PRED,
|
||||
(stack, level, holder, holderID) -> {
|
||||
var tag = stack.getOrCreateTag();
|
||||
var datum = HexItems.SPELLBOOK.get().readDatumTag(stack);
|
||||
if (datum != null) {
|
||||
var typename = datum.getAllKeys().iterator().next();
|
||||
return switch (typename) {
|
||||
case SpellDatum.TAG_ENTITY -> 1f;
|
||||
case SpellDatum.TAG_DOUBLE -> 2f;
|
||||
case SpellDatum.TAG_VEC3 -> 3f;
|
||||
case SpellDatum.TAG_WIDGET -> 4f;
|
||||
case SpellDatum.TAG_LIST -> 5f;
|
||||
case SpellDatum.TAG_PATTERN -> 6f;
|
||||
default -> 0f; // uh oh
|
||||
};
|
||||
} else {
|
||||
return 0f;
|
||||
}
|
||||
});
|
||||
for (RegistryObject<Item> packager : new RegistryObject[]{
|
||||
HexItems.CYPHER,
|
||||
HexItems.TRINKET,
|
||||
|
@ -107,7 +124,8 @@ public class RegisterClientStuff {
|
|||
});
|
||||
|
||||
for (var cutout : new Block[]{
|
||||
HexBlocks.CONJURED.get(),
|
||||
HexBlocks.CONJURED_LIGHT.get(),
|
||||
HexBlocks.CONJURED_BLOCK.get(),
|
||||
HexBlocks.AKASHIC_DOOR.get(),
|
||||
HexBlocks.AKASHIC_TRAPDOOR.get(),
|
||||
HexBlocks.SCONCE.get(),
|
||||
|
|
|
@ -3,6 +3,7 @@ package at.petrak.hexcasting.client.gui
|
|||
import at.petrak.hexcasting.HexUtils
|
||||
import at.petrak.hexcasting.HexUtils.TAU
|
||||
import at.petrak.hexcasting.client.RenderLib
|
||||
import at.petrak.hexcasting.client.sound.GridSoundInstance
|
||||
import at.petrak.hexcasting.common.casting.ControllerInfo
|
||||
import at.petrak.hexcasting.common.casting.ResolvedPattern
|
||||
import at.petrak.hexcasting.common.casting.ResolvedPatternValidity
|
||||
|
@ -44,7 +45,7 @@ class GuiSpellcasting(private val handOpenedWith: InteractionHand,
|
|||
private var drawState: PatternDrawState = PatternDrawState.BetweenPatterns
|
||||
private val usedSpots: MutableSet<HexCoord> = HashSet()
|
||||
|
||||
private var ambianceSoundInstance: AbstractSoundInstance? = null
|
||||
private var ambianceSoundInstance: GridSoundInstance? = null
|
||||
|
||||
init {
|
||||
for ((pattern, origin) in patterns) {
|
||||
|
@ -63,9 +64,14 @@ class GuiSpellcasting(private val handOpenedWith: InteractionHand,
|
|||
|
||||
if (!info.wasPrevPatternInvalid) {
|
||||
Minecraft.getInstance().soundManager.play(
|
||||
SimpleSoundInstance.forUI(
|
||||
SimpleSoundInstance(
|
||||
HexSounds.ADD_PATTERN.get(),
|
||||
1f + (Math.random().toFloat() - 0.5f) * 0.1f
|
||||
SoundSource.PLAYERS,
|
||||
1f,
|
||||
1f + (Math.random().toFloat() - 0.5f) * 0.1f,
|
||||
this.ambianceSoundInstance!!.x,
|
||||
this.ambianceSoundInstance!!.y,
|
||||
this.ambianceSoundInstance!!.z,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -75,20 +81,21 @@ class GuiSpellcasting(private val handOpenedWith: InteractionHand,
|
|||
val minecraft = Minecraft.getInstance()
|
||||
val soundManager = minecraft.soundManager
|
||||
soundManager.stop(HexSounds.CASTING_AMBIANCE.id, null)
|
||||
this.ambianceSoundInstance = SimpleSoundInstance(
|
||||
HexSounds.CASTING_AMBIANCE.get().location,
|
||||
SoundSource.PLAYERS,
|
||||
1f,
|
||||
1f,
|
||||
true,
|
||||
0,
|
||||
SoundInstance.Attenuation.NONE,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
true // this means is it relative to the *player's ears*, not to a given point, thanks mojank
|
||||
)
|
||||
soundManager.play(this.ambianceSoundInstance!!)
|
||||
val player = minecraft.player
|
||||
if (player != null) {
|
||||
this.ambianceSoundInstance = GridSoundInstance(player)
|
||||
soundManager.play(this.ambianceSoundInstance!!)
|
||||
}
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
val minecraft = Minecraft.getInstance()
|
||||
val player = minecraft.player
|
||||
if (player != null) {
|
||||
val heldItem = player.getItemInHand(handOpenedWith)
|
||||
if (heldItem.isEmpty || heldItem.item !is ItemWand)
|
||||
onClose()
|
||||
}
|
||||
}
|
||||
|
||||
override fun mouseClicked(mxOut: Double, myOut: Double, pButton: Int): Boolean {
|
||||
|
@ -103,9 +110,14 @@ class GuiSpellcasting(private val handOpenedWith: InteractionHand,
|
|||
if (!this.usedSpots.contains(coord)) {
|
||||
this.drawState = PatternDrawState.JustStarted(coord)
|
||||
Minecraft.getInstance().soundManager.play(
|
||||
SimpleSoundInstance.forUI(
|
||||
SimpleSoundInstance(
|
||||
HexSounds.START_PATTERN.get(),
|
||||
1f
|
||||
SoundSource.PLAYERS,
|
||||
1f,
|
||||
1f,
|
||||
this.ambianceSoundInstance!!.x,
|
||||
this.ambianceSoundInstance!!.y,
|
||||
this.ambianceSoundInstance!!.z,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -171,9 +183,14 @@ class GuiSpellcasting(private val handOpenedWith: InteractionHand,
|
|||
|
||||
if (playSound) {
|
||||
Minecraft.getInstance().soundManager.play(
|
||||
SimpleSoundInstance.forUI(
|
||||
HexSounds.ADD_LINE.get(),
|
||||
1f + (Math.random().toFloat() - 0.5f) * 0.1f
|
||||
SimpleSoundInstance(
|
||||
HexSounds.START_PATTERN.get(),
|
||||
SoundSource.PLAYERS,
|
||||
1f,
|
||||
1f + (Math.random().toFloat() - 0.5f) * 0.1f,
|
||||
this.ambianceSoundInstance!!.x,
|
||||
this.ambianceSoundInstance!!.y,
|
||||
this.ambianceSoundInstance!!.z,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -237,6 +254,9 @@ class GuiSpellcasting(private val handOpenedWith: InteractionHand,
|
|||
override fun render(poseStack: PoseStack, pMouseX: Int, pMouseY: Int, pPartialTick: Float) {
|
||||
super.render(poseStack, pMouseX, pMouseY, pPartialTick)
|
||||
|
||||
this.ambianceSoundInstance?.mousePosX = pMouseX / this.width.toDouble()
|
||||
this.ambianceSoundInstance?.mousePosY = pMouseX / this.width.toDouble()
|
||||
|
||||
val mat = poseStack.last().pose()
|
||||
val prevShader = RenderSystem.getShader()
|
||||
RenderSystem.setShader(GameRenderer::getPositionColorShader)
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package at.petrak.hexcasting.client.sound
|
||||
|
||||
import at.petrak.hexcasting.client.gui.GuiSpellcasting
|
||||
import at.petrak.hexcasting.common.lib.HexSounds
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.resources.sounds.AbstractTickableSoundInstance
|
||||
import net.minecraft.client.resources.sounds.SoundInstance
|
||||
import net.minecraft.sounds.SoundSource
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import net.minecraftforge.api.distmarker.Dist
|
||||
import net.minecraftforge.api.distmarker.OnlyIn
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
class GridSoundInstance(val player: Player) : AbstractTickableSoundInstance(HexSounds.CASTING_AMBIANCE.get(), SoundSource.PLAYERS) {
|
||||
var mousePosX: Double = 0.5
|
||||
var mousePosY: Double = 0.5
|
||||
|
||||
init {
|
||||
val lookVec = player.lookAngle
|
||||
this.x = player.x + lookVec.x
|
||||
this.y = player.y + lookVec.y
|
||||
this.z = player.z + lookVec.z
|
||||
this.attenuation = SoundInstance.Attenuation.LINEAR
|
||||
this.looping = true
|
||||
this.delay = 0
|
||||
this.relative = false
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
val minecraft = Minecraft.getInstance()
|
||||
val screen = minecraft.screen
|
||||
if (screen !is GuiSpellcasting)
|
||||
stop()
|
||||
else {
|
||||
val horizontalPlanarVector = calculateVectorFromPitchAndYaw(player.xRot + 90, player.yRot)
|
||||
val verticalPlanarVector = calculateVectorFromPitchAndYaw(player.xRot, player.yRot + 90)
|
||||
val normalVector = calculateVectorFromPitchAndYaw(player.xRot, player.yRot)
|
||||
val newPos = player.position()
|
||||
.add(normalVector)
|
||||
.add(horizontalPlanarVector.scale(4 * (mousePosX - 0.5)))
|
||||
.add(verticalPlanarVector.scale(4 * (mousePosY - 0.5)))
|
||||
this.x = newPos.x
|
||||
this.y = newPos.y
|
||||
this.z = newPos.z
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateVectorFromPitchAndYaw(pitch: Float, yaw: Float): Vec3 {
|
||||
val radiansPitch = pitch * (Math.PI.toFloat() / 180f)
|
||||
val radiansYaw = -yaw * (Math.PI.toFloat() / 180f)
|
||||
val xComponent = Mth.cos(radiansYaw).toDouble()
|
||||
val zComponent = Mth.sin(radiansYaw).toDouble()
|
||||
val azimuthHorizontal = Mth.cos(radiansPitch).toDouble()
|
||||
val azimuthVertical = Mth.sin(radiansPitch).toDouble()
|
||||
return Vec3(zComponent * azimuthHorizontal, -azimuthVertical, xComponent * azimuthHorizontal)
|
||||
}
|
||||
}
|
|
@ -2,51 +2,40 @@ package at.petrak.hexcasting.common.blocks;
|
|||
|
||||
import at.petrak.hexcasting.common.casting.colors.FrozenColorizer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.SpawnPlacements;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker;
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.Shapes;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class BlockConjured extends Block implements SimpleWaterloggedBlock, EntityBlock {
|
||||
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
|
||||
public static final BooleanProperty LIGHT = BooleanProperty.create("light");
|
||||
private static final VoxelShape LIGHT_SHAPE = Block.box(5.0D, 5.0D, 5.0D, 11.0D, 11.0D, 11.0D);
|
||||
public class BlockConjured extends Block implements EntityBlock {
|
||||
|
||||
public BlockConjured(BlockBehaviour.Properties properties) {
|
||||
public BlockConjured(Properties properties) {
|
||||
super(properties);
|
||||
this.registerDefaultState(this.stateDefinition.any().setValue(LIGHT, false).setValue(WATERLOGGED, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playerWillDestroy(Level pLevel, BlockPos pPos, BlockState pState, Player pPlayer) {
|
||||
super.playerWillDestroy(pLevel, pPos, pState, pPlayer);
|
||||
// For some reason the block doesn't play breaking noises. So we fix that!
|
||||
pPlayer.playSound(SoundEvents.GLASS_BREAK, 1f, 1f);
|
||||
pPlayer.playSound(SoundEvents.AMETHYST_BLOCK_BREAK, 1f, 1f);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -67,18 +56,16 @@ public class BlockConjured extends Block implements SimpleWaterloggedBlock, Enti
|
|||
}
|
||||
|
||||
@Override
|
||||
public void stepOn(Level pLevel, @NotNull BlockPos pPos, @NotNull BlockState pState, @NotNull Entity pEntity) {
|
||||
BlockEntity tile = pLevel.getBlockEntity(pPos);
|
||||
if (tile instanceof BlockEntityConjured bec && !bec.getBlockState().getValue(LIGHT)) {
|
||||
bec.walkParticle(pEntity);
|
||||
}
|
||||
super.stepOn(pLevel, pPos, pState, pEntity);
|
||||
public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter level, BlockPos pos, Player player) {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.@NotNull Builder<Block, BlockState> builder) {
|
||||
super.createBlockStateDefinition(builder);
|
||||
builder.add(LIGHT, WATERLOGGED);
|
||||
public void stepOn(Level pLevel, @NotNull BlockPos pPos, @NotNull BlockState pState, @NotNull Entity pEntity) {
|
||||
BlockEntity tile = pLevel.getBlockEntity(pPos);
|
||||
if (tile instanceof BlockEntityConjured bec) {
|
||||
bec.walkParticle(pEntity);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -101,17 +88,6 @@ public class BlockConjured extends Block implements SimpleWaterloggedBlock, Enti
|
|||
super.onPlace(pState, pLevel, pPos, pOldState, pIsMoving);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull VoxelShape getShape(@NotNull BlockState state, @NotNull BlockGetter level, @NotNull BlockPos pos,
|
||||
@NotNull CollisionContext context) {
|
||||
return state.getValue(LIGHT) ? LIGHT_SHAPE : super.getShape(state, level, pos, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PushReaction getPistonPushReaction(@NotNull BlockState state) {
|
||||
return state.getValue(LIGHT) ? PushReaction.DESTROY : super.getPistonPushReaction(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean propagatesSkylightDown(@NotNull BlockState pState, @NotNull BlockGetter pLevel,
|
||||
@NotNull BlockPos pPos) {
|
||||
|
@ -119,25 +95,7 @@ public class BlockConjured extends Block implements SimpleWaterloggedBlock, Enti
|
|||
}
|
||||
|
||||
@Override
|
||||
public int getLightEmission(BlockState state, BlockGetter world, BlockPos pos) {
|
||||
return state.getValue(LIGHT) ? 15 : 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos,
|
||||
@Nullable Direction direction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type,
|
||||
EntityType<?> entityType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull VoxelShape getVisualShape(@NotNull BlockState pState, @NotNull BlockGetter pLevel,
|
||||
@NotNull BlockPos pPos, @NotNull CollisionContext pContext) {
|
||||
public @NotNull VoxelShape getVisualShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
|
||||
return Shapes.empty();
|
||||
}
|
||||
|
||||
|
@ -151,14 +109,9 @@ public class BlockConjured extends Block implements SimpleWaterloggedBlock, Enti
|
|||
return RenderShape.INVISIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull VoxelShape getCollisionShape(@NotNull BlockState state, @NotNull BlockGetter pLevel,
|
||||
@NotNull BlockPos pPos, @NotNull CollisionContext pContext) {
|
||||
return state.getValue(LIGHT) ? Shapes.empty() : super.getCollisionShape(state, pLevel, pPos, pContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void spawnDestroyParticles(Level pLevel, Player pPlayer, BlockPos pPos, BlockState pState) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package at.petrak.hexcasting.common.blocks;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.StateDefinition;
|
||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
import net.minecraft.world.level.material.Fluids;
|
||||
import net.minecraft.world.level.material.PushReaction;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class BlockConjuredLight extends BlockConjured implements SimpleWaterloggedBlock {
|
||||
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
|
||||
private static final VoxelShape SHAPE = Block.box(5.0D, 5.0D, 5.0D, 11.0D, 11.0D, 11.0D);
|
||||
|
||||
public BlockConjuredLight(BlockBehaviour.Properties properties) {
|
||||
super(properties);
|
||||
this.registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void createBlockStateDefinition(StateDefinition.@NotNull Builder<Block, BlockState> builder) {
|
||||
builder.add(WATERLOGGED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean propagatesSkylightDown(BlockState state, @Nonnull BlockGetter reader, @Nonnull BlockPos pos) {
|
||||
return !state.getValue(WATERLOGGED);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public FluidState getFluidState(BlockState state) {
|
||||
return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
|
||||
FluidState fluidState = pContext.getLevel().getFluidState(pContext.getClickedPos());
|
||||
return defaultBlockState().setValue(WATERLOGGED, fluidState.is(FluidTags.WATER) && fluidState.getAmount() == 8);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, @Nonnull Direction facing, @Nonnull BlockState facingState, @Nonnull LevelAccessor level, @Nonnull BlockPos pos, @Nonnull BlockPos facingPos) {
|
||||
if (state.getValue(WATERLOGGED)) {
|
||||
level.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(level));
|
||||
}
|
||||
|
||||
return super.updateShape(state, facing, facingState, level, pos, facingPos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull VoxelShape getShape(@NotNull BlockState state, @NotNull BlockGetter level, @NotNull BlockPos pos,
|
||||
@NotNull CollisionContext context) {
|
||||
return SHAPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stepOn(Level pLevel, @NotNull BlockPos pPos, @NotNull BlockState pState, @NotNull Entity pEntity) {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull PushReaction getPistonPushReaction(@NotNull BlockState state) {
|
||||
return PushReaction.DESTROY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addLandingEffects(BlockState state1, ServerLevel worldserver, BlockPos pos, BlockState state2,
|
||||
LivingEntity entity, int numberOfParticles) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ public class BlockEntityConjured extends PaucalBlockEntity {
|
|||
}
|
||||
|
||||
public void walkParticle(Entity pEntity) {
|
||||
if (getBlockState().getBlock() instanceof BlockConjured) {
|
||||
if (getBlockState().getBlock() instanceof BlockConjured conjured && !(conjured instanceof BlockConjuredLight)) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
int color = this.colorizer.getColor(pEntity.tickCount, pEntity.position()
|
||||
.add(new Vec3(RANDOM.nextFloat(), RANDOM.nextFloat(), RANDOM.nextFloat()).scale(
|
||||
|
@ -45,7 +45,7 @@ public class BlockEntityConjured extends PaucalBlockEntity {
|
|||
new Vec3(RANDOM.nextFloat(), RANDOM.nextFloat(), RANDOM.nextFloat()).scale(
|
||||
RANDOM.nextFloat() * 3));
|
||||
assert level != null;
|
||||
if (getBlockState().getValue(BlockConjured.LIGHT)) {
|
||||
if (getBlockState().getBlock() instanceof BlockConjuredLight) {
|
||||
if (RANDOM.nextFloat() < 0.5) {
|
||||
level.addParticle(new ConjureParticleOptions(color, true),
|
||||
(double) getBlockPos().getX() + 0.45D + (RANDOM.nextFloat() * 0.1D),
|
||||
|
@ -70,7 +70,7 @@ public class BlockEntityConjured extends PaucalBlockEntity {
|
|||
}
|
||||
|
||||
public void landParticle(Entity entity, int number) {
|
||||
if (getBlockState().getBlock() instanceof BlockConjured) {
|
||||
if (getBlockState().getBlock() instanceof BlockConjuredLight) {
|
||||
for (int i = 0; i < number * 2; i++) {
|
||||
int color = this.colorizer.getColor(entity.tickCount, entity.position()
|
||||
.add(new Vec3(RANDOM.nextFloat(), RANDOM.nextFloat(), RANDOM.nextFloat()).scale(
|
||||
|
|
|
@ -18,7 +18,7 @@ public class HexBlockEntities {
|
|||
|
||||
public static final RegistryObject<BlockEntityType<BlockEntityConjured>> CONJURED_TILE = BLOCK_ENTITIES.register(
|
||||
"conjured_tile",
|
||||
() -> BlockEntityType.Builder.of(BlockEntityConjured::new, HexBlocks.CONJURED.get()).build(null));
|
||||
() -> BlockEntityType.Builder.of(BlockEntityConjured::new, HexBlocks.CONJURED_LIGHT.get(), HexBlocks.CONJURED_BLOCK.get()).build(null));
|
||||
|
||||
public static final RegistryObject<BlockEntityType<BlockEntityAkashicBookshelf>> AKASHIC_BOOKSHELF_TILE = BLOCK_ENTITIES.register(
|
||||
"akashic_bookshelf_tile",
|
||||
|
|
|
@ -32,16 +32,29 @@ import java.util.function.Supplier;
|
|||
public class HexBlocks {
|
||||
public static final DeferredRegister<Block> BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, HexMod.MOD_ID);
|
||||
|
||||
public static final RegistryObject<Block> CONJURED = blockItem("conjured",
|
||||
() -> new BlockConjured(
|
||||
BlockBehaviour.Properties.of(Material.AMETHYST, MaterialColor.DIAMOND)
|
||||
public static final RegistryObject<Block> CONJURED_LIGHT = blockNoItem("conjured",
|
||||
() -> new BlockConjuredLight(
|
||||
BlockBehaviour.Properties.of(Material.GLASS, MaterialColor.DIAMOND)
|
||||
.sound(SoundType.AMETHYST)
|
||||
.lightLevel((state) -> 15)
|
||||
.noDrops()
|
||||
.isValidSpawn(HexBlocks::never)
|
||||
.instabreak()
|
||||
.noCollission()
|
||||
.isSuffocating(HexBlocks::never)
|
||||
.isViewBlocking(HexBlocks::never)));
|
||||
|
||||
public static final RegistryObject<Block> CONJURED_BLOCK = blockNoItem("conjured_block",
|
||||
() -> new BlockConjured(
|
||||
BlockBehaviour.Properties.of(Material.GLASS, MaterialColor.DIAMOND)
|
||||
.sound(SoundType.AMETHYST)
|
||||
.lightLevel((state) -> 2)
|
||||
.noDrops()
|
||||
.isValidSpawn(HexBlocks::never)
|
||||
.instabreak()
|
||||
.noOcclusion()
|
||||
.isSuffocating(HexBlocks::never)
|
||||
.isViewBlocking(HexBlocks::never)),
|
||||
new Item.Properties());
|
||||
.isViewBlocking(HexBlocks::never)));
|
||||
|
||||
private static BlockBehaviour.Properties slateish() {
|
||||
return BlockBehaviour.Properties
|
||||
|
@ -163,6 +176,10 @@ public class HexBlocks {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static <T extends Block> RegistryObject<T> blockNoItem(String name, Supplier<T> block) {
|
||||
return BLOCKS.register(name, block);
|
||||
}
|
||||
|
||||
private static <T extends Block> RegistryObject<T> blockItem(String name, Supplier<T> block) {
|
||||
return blockItem(name, block, HexItems.props());
|
||||
}
|
||||
|
@ -173,5 +190,6 @@ public class HexBlocks {
|
|||
HexItems.ITEMS.register(name, () -> new BlockItem(out.get(), props));
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,7 +45,8 @@ public class BlockEntityAkashicRecord extends PaucalBlockEntity {
|
|||
* Will never clobber anything.
|
||||
*/
|
||||
public @Nullable BlockPos addNewDatum(HexPattern key, SpellDatum<?> datum) {
|
||||
if (this.entries.containsKey(key.anglesSignature())) {
|
||||
String entryKey = getKey(key);
|
||||
if (this.entries.containsKey(entryKey)) {
|
||||
return null; // would clobber
|
||||
}
|
||||
|
||||
|
@ -56,7 +57,7 @@ public class BlockEntityAkashicRecord extends PaucalBlockEntity {
|
|||
var tile = (BlockEntityAkashicBookshelf) this.level.getBlockEntity(openPos);
|
||||
tile.setNewData(this.getBlockPos(), key, datum.getType());
|
||||
|
||||
this.entries.put(key.anglesSignature(), new Entry(openPos, key.startDir(), datum.serializeToNBT()));
|
||||
this.entries.put(entryKey, new Entry(openPos, key.startDir(), datum.serializeToNBT()));
|
||||
this.sync();
|
||||
|
||||
return openPos;
|
||||
|
@ -65,8 +66,15 @@ public class BlockEntityAkashicRecord extends PaucalBlockEntity {
|
|||
}
|
||||
}
|
||||
|
||||
private String getKey(HexPattern key) {
|
||||
String angles = key.anglesSignature();
|
||||
if (angles.isEmpty())
|
||||
return "empty"; // contains non-angle characters, so can't occur any way other than this
|
||||
return angles;
|
||||
}
|
||||
|
||||
public @Nullable SpellDatum<?> lookupPattern(HexPattern key, ServerLevel slevel) {
|
||||
var entry = this.entries.get(key.anglesSignature());
|
||||
var entry = this.entries.get(getKey(key));
|
||||
if (entry == null) {
|
||||
return null;
|
||||
} else {
|
||||
|
@ -75,7 +83,7 @@ public class BlockEntityAkashicRecord extends PaucalBlockEntity {
|
|||
}
|
||||
|
||||
public Component getDisplayAt(HexPattern key) {
|
||||
var entry = this.entries.get(key.anglesSignature());
|
||||
var entry = this.entries.get(getKey(key));
|
||||
if (entry != null) {
|
||||
return SpellDatum.DisplayFromTag(entry.datum);
|
||||
} else {
|
||||
|
@ -105,7 +113,9 @@ public class BlockEntityAkashicRecord extends PaucalBlockEntity {
|
|||
var bs = this.level.getBlockState(neighbor);
|
||||
if (BlockAkashicFloodfiller.canItBeFloodedThrough(neighbor, bs, this.level)) {
|
||||
todo.add(neighbor);
|
||||
if (this.level.getBlockEntity(neighbor) instanceof BlockEntityAkashicBookshelf)
|
||||
if (this.level.getBlockEntity(neighbor) instanceof BlockEntityAkashicBookshelf &&
|
||||
bs.hasProperty(BlockAkashicBookshelf.DATUM_TYPE) &&
|
||||
bs.getValue(BlockAkashicBookshelf.DATUM_TYPE) != DatumType.EMPTY)
|
||||
validPoses.add(neighbor);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ class MishapBadOffhandItem(val item: ItemStack, val wanted: Component) : Mishap(
|
|||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun of(item: ItemStack, stub: String): MishapBadOffhandItem {
|
||||
return MishapBadOffhandItem(item, TranslatableComponent("hexcasting.mishap.bad_item.$stub"))
|
||||
fun of(item: ItemStack, stub: String, vararg args: Any): MishapBadOffhandItem {
|
||||
return MishapBadOffhandItem(item, TranslatableComponent("hexcasting.mishap.bad_item.$stub", *args))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package at.petrak.hexcasting.common.casting.mishaps
|
||||
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.casting.Widget
|
||||
import at.petrak.hexcasting.common.casting.colors.FrozenColorizer
|
||||
import at.petrak.hexcasting.common.lib.HexDamageSources
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.world.item.DyeColor
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class MishapDivideByZero(val operand1: Component, val operand2: Component, val suffix: String = "divide") : Mishap() {
|
||||
|
||||
override fun accentColor(ctx: CastingContext, errorCtx: Context): FrozenColorizer =
|
||||
dyeColor(DyeColor.RED)
|
||||
|
||||
override fun execute(ctx: CastingContext, errorCtx: Context, stack: MutableList<SpellDatum<*>>) {
|
||||
stack.add(SpellDatum.make(Widget.GARBAGE))
|
||||
ctx.caster.hurt(HexDamageSources.OVERCAST, ctx.caster.health / 2)
|
||||
}
|
||||
|
||||
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component {
|
||||
return error("divide_by_zero.$suffix", operand1, operand2)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PREFIX = "hexcasting.mishap.divide_by_zero"
|
||||
|
||||
@JvmStatic
|
||||
fun of(operand1: Any, operand2: Any, suffix: String = "divide"): MishapDivideByZero {
|
||||
if (suffix == "exponent")
|
||||
return MishapDivideByZero(translate(operand1), powerOf(operand2), suffix)
|
||||
return MishapDivideByZero(translate(operand1), translate(operand2), suffix)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
val zero get() = TranslatableComponent("$PREFIX.zero")
|
||||
@JvmStatic
|
||||
val zerothPower get() = TranslatableComponent("$PREFIX.zero.power")
|
||||
@JvmStatic
|
||||
val zeroVector get() = TranslatableComponent("$PREFIX.zero.vec")
|
||||
|
||||
@JvmStatic
|
||||
fun powerOf(power: Component) = TranslatableComponent("$PREFIX.power", power)
|
||||
|
||||
@JvmStatic
|
||||
fun powerOf(datum: Any) = when (datum) {
|
||||
0.0 -> zerothPower
|
||||
else -> powerOf(SpellDatum.make(datum).display())
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun translate(datum: Any): Component = when (datum) {
|
||||
0.0 -> zero
|
||||
Vec3.ZERO -> zeroVector
|
||||
else -> SpellDatum.make(datum).display()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,5 +18,5 @@ class MishapLocationInWrongDimension(val properDimension: ResourceLocation) : Mi
|
|||
|
||||
override fun errorMessage(ctx: CastingContext, errorCtx: Context): Component =
|
||||
error("wrong_dimension", actionName(errorCtx.action!!), properDimension.toString(),
|
||||
ctx.world.dimension().registryName.toString())
|
||||
ctx.world.dimension().location().toString())
|
||||
}
|
||||
|
|
|
@ -22,13 +22,10 @@ object OpWrite : SpellOperator {
|
|||
val tag = handStack.orCreateTag
|
||||
val datum = args[0]
|
||||
|
||||
val canWrite = if (handItem is DataHolder) {
|
||||
handItem.canWrite(tag, datum)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
if (!canWrite)
|
||||
if (handItem !is DataHolder)
|
||||
throw MishapBadOffhandItem.of(handStack, "iota.write")
|
||||
else if (!handItem.canWrite(tag, datum))
|
||||
throw MishapBadOffhandItem.of(handStack, "iota.readonly", datum.display())
|
||||
|
||||
val trueName = MishapOthersName.getTrueNameFromDatum(datum, ctx.caster)
|
||||
if (trueName != null)
|
||||
|
|
|
@ -8,6 +8,7 @@ import at.petrak.hexcasting.api.spell.SpellOperator
|
|||
import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicRecord
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.casting.mishaps.MishapNoAkashicRecord
|
||||
import at.petrak.hexcasting.common.casting.mishaps.MishapOthersName
|
||||
import at.petrak.hexcasting.common.lib.HexCapabilities
|
||||
import at.petrak.hexcasting.common.lib.HexSounds
|
||||
import at.petrak.hexcasting.hexmath.HexPattern
|
||||
|
@ -32,6 +33,10 @@ object OpAkashicWrite : SpellOperator {
|
|||
throw MishapNoAkashicRecord(bpos)
|
||||
}
|
||||
|
||||
val trueName = MishapOthersName.getTrueNameFromDatum(datum, ctx.caster)
|
||||
if (trueName != null)
|
||||
throw MishapOthersName(trueName)
|
||||
|
||||
return Triple(
|
||||
Spell(tile, key, datum),
|
||||
10_000,
|
||||
|
@ -58,4 +63,4 @@ object OpAkashicWrite : SpellOperator {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import at.petrak.hexcasting.api.spell.ConstManaOperator
|
|||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.casting.mishaps.MishapDivideByZero
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
object OpDivCross : ConstManaOperator {
|
||||
|
@ -17,14 +18,27 @@ object OpDivCross : ConstManaOperator {
|
|||
return spellListOf(
|
||||
lhs.map({ lnum ->
|
||||
rhs.map(
|
||||
{ rnum -> lnum / rnum }, { rvec -> Vec3(lnum / rvec.x, lnum / rvec.y, lnum / rvec.z) }
|
||||
{ rnum ->
|
||||
if (rnum == 0.0)
|
||||
throw MishapDivideByZero.of(lnum, rnum)
|
||||
lnum / rnum
|
||||
},
|
||||
{ rvec ->
|
||||
if (rvec.x == 0.0 || rvec.y == 0.0 || rvec.z == 0.0)
|
||||
throw MishapDivideByZero.of(lnum, rvec)
|
||||
Vec3(lnum / rvec.x, lnum / rvec.y, lnum / rvec.z)
|
||||
}
|
||||
)
|
||||
}, { lvec ->
|
||||
rhs.map(
|
||||
{ rnum -> lvec.scale(1.0 / rnum) },
|
||||
{ rnum ->
|
||||
if (lvec == Vec3.ZERO)
|
||||
throw MishapDivideByZero.of(lvec, rnum)
|
||||
lvec.scale(1.0 / rnum)
|
||||
},
|
||||
{ rvec -> lvec.cross(rvec) }
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import at.petrak.hexcasting.api.spell.ConstManaOperator
|
|||
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.casting.mishaps.MishapDivideByZero
|
||||
import net.minecraft.network.chat.TranslatableComponent
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import kotlin.math.pow
|
||||
|
||||
|
@ -18,14 +20,30 @@ object OpPowProj : ConstManaOperator {
|
|||
return spellListOf(
|
||||
lhs.map({ lnum ->
|
||||
rhs.map(
|
||||
{ rnum -> lnum.pow(rnum) }, { rvec -> Vec3(lnum.pow(rvec.x), lnum.pow(rvec.y), lnum.pow(rvec.z)) }
|
||||
{ rnum ->
|
||||
if (rnum == 0.0 && lnum == 0.0)
|
||||
throw MishapDivideByZero.of(lnum, rnum, "exponent")
|
||||
lnum.pow(rnum)
|
||||
}, { rvec ->
|
||||
if (lnum == 0.0 && (rvec.x == 0.0 || rvec.y == 0.0 || rvec.z == 0.0))
|
||||
throw MishapDivideByZero.of(lnum, rvec, "exponent")
|
||||
Vec3(lnum.pow(rvec.x), lnum.pow(rvec.y), lnum.pow(rvec.z))
|
||||
}
|
||||
)
|
||||
}, { lvec ->
|
||||
rhs.map(
|
||||
{ rnum -> Vec3(lvec.x.pow(rnum), lvec.y.pow(rnum), lvec.z.pow(rnum)) },
|
||||
{ rvec -> rvec.scale(lvec.dot(rvec) / rvec.dot(rvec)) }
|
||||
{ rnum ->
|
||||
if (rnum == 0.0 && (lvec.x == 0.0 || lvec.y == 0.0 || lvec.z == 0.0))
|
||||
throw MishapDivideByZero.of(lvec, rnum, "exponent")
|
||||
Vec3(lvec.x.pow(rnum), lvec.y.pow(rnum), lvec.z.pow(rnum))
|
||||
},
|
||||
{ rvec ->
|
||||
if (rvec == Vec3.ZERO)
|
||||
throw MishapDivideByZero.of(lvec, rvec, "project")
|
||||
rvec.scale(lvec.dot(rvec) / rvec.dot(rvec))
|
||||
}
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,15 @@ import at.petrak.hexcasting.api.spell.RenderedSpell
|
|||
import at.petrak.hexcasting.api.spell.SpellDatum
|
||||
import at.petrak.hexcasting.api.spell.SpellOperator
|
||||
import at.petrak.hexcasting.common.blocks.BlockConjured
|
||||
import at.petrak.hexcasting.common.blocks.BlockConjuredLight
|
||||
import at.petrak.hexcasting.common.blocks.HexBlocks
|
||||
import at.petrak.hexcasting.common.casting.CastingContext
|
||||
import at.petrak.hexcasting.common.casting.mishaps.MishapBadBlock
|
||||
import at.petrak.hexcasting.common.lib.HexCapabilities
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.item.context.DirectionalPlaceContext
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
class OpConjure(val light: Boolean) : SpellOperator {
|
||||
|
@ -30,22 +35,26 @@ class OpConjure(val light: Boolean) : SpellOperator {
|
|||
|
||||
private data class Spell(val target: Vec3, val light: Boolean) : RenderedSpell {
|
||||
override fun cast(ctx: CastingContext) {
|
||||
if (ctx.world.getBlockState(BlockPos(target)).isAir) {
|
||||
var state = HexBlocks.CONJURED.get().defaultBlockState()
|
||||
if (this.light) {
|
||||
state = state.setValue(BlockConjured.LIGHT, true)
|
||||
}
|
||||
ctx.world.setBlock(BlockPos(target), state, 2)
|
||||
val pos = BlockPos(target)
|
||||
val placeContext = DirectionalPlaceContext(ctx.world, pos, Direction.DOWN, ItemStack.EMPTY, Direction.UP)
|
||||
|
||||
val maybeCap = ctx.caster.getCapability(HexCapabilities.PREFERRED_COLORIZER).resolve()
|
||||
if (!maybeCap.isPresent)
|
||||
return
|
||||
val cap = maybeCap.get()
|
||||
val worldState = ctx.world.getBlockState(pos)
|
||||
if (worldState.canBeReplaced(placeContext)) {
|
||||
val block = if (this.light) HexBlocks.CONJURED_LIGHT else HexBlocks.CONJURED_BLOCK
|
||||
val state = block.get().getStateForPlacement(placeContext)
|
||||
if (state != null) {
|
||||
ctx.world.setBlock(pos, state, 2)
|
||||
|
||||
if (ctx.world.getBlockState(BlockPos(target)).block is BlockConjured) {
|
||||
BlockConjured.setColor(ctx.world, BlockPos(target), cap.colorizer)
|
||||
val maybeCap = ctx.caster.getCapability(HexCapabilities.PREFERRED_COLORIZER).resolve()
|
||||
if (!maybeCap.isPresent)
|
||||
return
|
||||
val cap = maybeCap.get()
|
||||
|
||||
if (ctx.world.getBlockState(pos).block is BlockConjured) {
|
||||
BlockConjured.setColor(ctx.world, pos, cap.colorizer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ object OpDestroySentinel : SpellOperator {
|
|||
val maybeCap = ctx.caster.getCapability(HexCapabilities.SENTINEL).resolve()
|
||||
maybeCap.ifPresent {
|
||||
if (it.dimension != ctx.world.dimension())
|
||||
throw MishapLocationInWrongDimension(it.dimension.registryName)
|
||||
throw MishapLocationInWrongDimension(it.dimension.location())
|
||||
particles.add(ParticleSpray.Cloud(it.position, 2.0))
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ object OpGetSentinelPos : ConstManaOperator {
|
|||
|
||||
val cap = maybeCap.get()
|
||||
if (cap.dimension != ctx.world.dimension())
|
||||
throw MishapLocationInWrongDimension(cap.dimension.registryName)
|
||||
throw MishapLocationInWrongDimension(cap.dimension.location())
|
||||
return spellListOf(
|
||||
if (cap.hasSentinel)
|
||||
cap.position
|
||||
|
|
|
@ -22,7 +22,7 @@ object OpGetSentinelWayfind : ConstManaOperator {
|
|||
|
||||
val cap = maybeCap.get()
|
||||
if (cap.dimension != ctx.world.dimension())
|
||||
throw MishapLocationInWrongDimension(cap.dimension.registryName)
|
||||
throw MishapLocationInWrongDimension(cap.dimension.location())
|
||||
|
||||
val sentinelPos = if (!cap.hasSentinel)
|
||||
return spellListOf(Widget.NULL)
|
||||
|
|
|
@ -60,9 +60,6 @@ public class ItemSlate extends BlockItem implements DataHolder {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!tag.contains("BlockEntityTag")) {
|
||||
return false;
|
||||
}
|
||||
var beTag = tag.getCompound("BlockEntityTag");
|
||||
return !beTag.contains(BlockEntitySlate.TAG_PATTERN);
|
||||
}
|
||||
|
@ -72,6 +69,7 @@ public class ItemSlate extends BlockItem implements DataHolder {
|
|||
if (this.canWrite(tag, datum) && datum.getPayload() instanceof HexPattern pat) {
|
||||
var beTag = tag.getCompound("BlockEntityTag");
|
||||
beTag.put(BlockEntitySlate.TAG_PATTERN, pat.serializeToNBT());
|
||||
tag.put("BlockEntityTag", beTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package at.petrak.hexcasting.common.items;
|
||||
|
||||
import at.petrak.hexcasting.HexMod;
|
||||
import at.petrak.hexcasting.api.item.DataHolder;
|
||||
import at.petrak.hexcasting.api.spell.SpellDatum;
|
||||
import net.minecraft.ChatFormatting;
|
||||
|
@ -8,6 +9,7 @@ import net.minecraft.nbt.Tag;
|
|||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.TextComponent;
|
||||
import net.minecraft.network.chat.TranslatableComponent;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
@ -19,6 +21,8 @@ import java.util.List;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
public class ItemSpellbook extends Item implements DataHolder {
|
||||
public static final ResourceLocation DATATYPE_PRED = new ResourceLocation(HexMod.MOD_ID, "datatype");
|
||||
|
||||
public static String TAG_SELECTED_PAGE = "page_idx";
|
||||
// this is a CompoundTag of string numerical keys to SpellData
|
||||
// it is 1-indexed, so that 0/0 can be the special case of "it is empty"
|
||||
|
@ -52,6 +56,8 @@ public class ItemSpellbook extends Item implements DataHolder {
|
|||
tooltip.add(new TranslatableComponent("hexcasting.tooltip.spellbook.empty").withStyle(ChatFormatting.GRAY));
|
||||
}
|
||||
|
||||
DataHolder.appendHoverText(this, stack, tooltip, isAdvanced);
|
||||
|
||||
super.appendHoverText(stack, level, tooltip, isAdvanced);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ package at.petrak.hexcasting.common.lib;
|
|||
import net.minecraft.world.damagesource.DamageSource;
|
||||
|
||||
public class HexDamageSources {
|
||||
public static final DamageSource OVERCAST = new DamageSource("hexcasting.overcast").bypassArmor()
|
||||
public static final DamageSource OVERCAST = new DamageSource("hexcasting.overcast")
|
||||
.bypassArmor()
|
||||
.bypassMagic()
|
||||
.setMagic();
|
||||
}
|
||||
|
|
|
@ -7,7 +7,11 @@ import net.minecraftforge.api.distmarker.OnlyIn;
|
|||
|
||||
public record GuiOpener(MsgOpenSpellGuiAck msg) {
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
<<<<<<< HEAD
|
||||
public void open() {
|
||||
=======
|
||||
public void openGui() {
|
||||
>>>>>>> aae172093c4a71951f424ef3c6f21c5924cb72a7
|
||||
var mc = Minecraft.getInstance();
|
||||
mc.setScreen(new GuiSpellcasting(msg.hand(), msg.patterns(), msg.components()));
|
||||
}
|
||||
|
|
|
@ -57,7 +57,11 @@ public record MsgOpenSpellGuiAck(InteractionHand hand, List<ResolvedPattern> pat
|
|||
public void handle(Supplier<NetworkEvent.Context> ctx) {
|
||||
ctx.get().enqueueWork(() -> {
|
||||
GuiOpener opener = new GuiOpener(this);
|
||||
<<<<<<< HEAD
|
||||
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> opener::open);
|
||||
=======
|
||||
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> opener::openGui);
|
||||
>>>>>>> aae172093c4a71951f424ef3c6f21c5924cb72a7
|
||||
});
|
||||
ctx.get().setPacketHandled(true);
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class HexBlockTagProvider extends BlockTagsProvider {
|
|||
.add(HexBlocks.AKASHIC_LEAVES1.get(), HexBlocks.AKASHIC_LEAVES2.get(), HexBlocks.AKASHIC_LEAVES3.get());
|
||||
|
||||
tag(BlockTags.CRYSTAL_SOUND_BLOCKS)
|
||||
.add(HexBlocks.CONJURED.get(), HexBlocks.AMETHYST_TILES.get(), HexBlocks.SCONCE.get());
|
||||
.add(HexBlocks.CONJURED_LIGHT.get(), HexBlocks.CONJURED_BLOCK.get(), HexBlocks.AMETHYST_TILES.get(), HexBlocks.SCONCE.get());
|
||||
|
||||
tag(HexBlockTags.AKASHIC_LOGS)
|
||||
.add(HexBlocks.AKASHIC_LOG.get(), HexBlocks.AKASHIC_LOG_STRIPPED.get(),
|
||||
|
|
|
@ -2,10 +2,7 @@ package at.petrak.hexcasting.datagen;
|
|||
|
||||
import at.petrak.hexcasting.HexMod;
|
||||
import at.petrak.hexcasting.common.blocks.HexBlocks;
|
||||
import at.petrak.hexcasting.common.items.HexItems;
|
||||
import at.petrak.hexcasting.common.items.ItemFocus;
|
||||
import at.petrak.hexcasting.common.items.ItemScroll;
|
||||
import at.petrak.hexcasting.common.items.ItemSlate;
|
||||
import at.petrak.hexcasting.common.items.*;
|
||||
import at.petrak.hexcasting.common.items.magic.ItemManaBattery;
|
||||
import at.petrak.hexcasting.common.items.magic.ItemPackagedSpell;
|
||||
import at.petrak.paucal.api.datagen.PaucalItemModelProvider;
|
||||
|
@ -25,7 +22,6 @@ public class HexItemModels extends PaucalItemModelProvider {
|
|||
|
||||
@Override
|
||||
protected void registerModels() {
|
||||
simpleItem(HexItems.SPELLBOOK.get());
|
||||
simpleItem(HexItems.AMETHYST_DUST.get());
|
||||
simpleItem(HexItems.CHARGED_AMETHYST.get());
|
||||
simpleItem(HexItems.SUBMARINE_SANDWICH.get());
|
||||
|
@ -47,24 +43,36 @@ public class HexItemModels extends PaucalItemModelProvider {
|
|||
|
||||
simpleItem(modLoc("patchouli_book"));
|
||||
|
||||
String[] focusTypes = new String[]{
|
||||
String[] datumStoredTypes = new String[]{
|
||||
"empty", "entity", "double", "vec3", "widget", "list", "pattern"
|
||||
};
|
||||
// For stupid bad reasons we need to do this in ascending order.
|
||||
for (int sealedIdx = 0; sealedIdx <= 1; sealedIdx++) {
|
||||
var sealed = sealedIdx == 1;
|
||||
for (int i = 0, stringsLength = focusTypes.length; i < stringsLength; i++) {
|
||||
var type = focusTypes[i];
|
||||
var name = "focus_" + type + (sealed ? "_sealed" : "");
|
||||
simpleItem(modLoc(name));
|
||||
for (int i = 0, stringsLength = datumStoredTypes.length; i < stringsLength; i++) {
|
||||
var type = datumStoredTypes[i];
|
||||
|
||||
var focusName = "focus_" + type + (sealed ? "_sealed" : "");
|
||||
simpleItem(modLoc(focusName));
|
||||
getBuilder(HexItems.FOCUS.get().getRegistryName().getPath())
|
||||
.override()
|
||||
.predicate(ItemFocus.DATATYPE_PRED, -0.01f + i + (sealed ? 100 : 0))
|
||||
.model(new ModelFile.UncheckedModelFile(modLoc("item/" + name)))
|
||||
.model(new ModelFile.UncheckedModelFile(modLoc("item/" + focusName)))
|
||||
.end();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0, stringsLength = datumStoredTypes.length; i < stringsLength; i++) {
|
||||
var type = datumStoredTypes[i];
|
||||
|
||||
var spellbookName = "spellbook_" + type;
|
||||
simpleItem(modLoc(spellbookName));
|
||||
getBuilder(HexItems.SPELLBOOK.get().getRegistryName().getPath())
|
||||
.override()
|
||||
.predicate(ItemSpellbook.DATATYPE_PRED, -0.01f + i)
|
||||
.model(new ModelFile.UncheckedModelFile(modLoc("item/" + spellbookName)))
|
||||
.end();
|
||||
}
|
||||
|
||||
Pair<RegistryObject<Item>, String>[] packagers = new Pair[]{
|
||||
new Pair(HexItems.CYPHER, "cypher"),
|
||||
|
|
|
@ -307,6 +307,7 @@
|
|||
"hexcasting.mishap.bad_item.iota": "a place to store iotas",
|
||||
"hexcasting.mishap.bad_item.iota.read": "a place to read iotas from",
|
||||
"hexcasting.mishap.bad_item.iota.write": "a place to write iotas to",
|
||||
"hexcasting.mishap.bad_item.iota.readonly": "a place that will accept %s",
|
||||
"hexcasting.mishap.bad_item.mana": "a media-containing item",
|
||||
"hexcasting.mishap.bad_item.only_one": "exactly one item",
|
||||
"hexcasting.mishap.bad_item.eraseable": "an eraseable item",
|
||||
|
@ -318,6 +319,13 @@
|
|||
"hexcasting.mishap.already_brainswept": "The villager has already been used",
|
||||
"hexcasting.mishap.no_spell_circle": "%s requires a spell circle",
|
||||
"hexcasting.mishap.others_name": "Tried to invade %s's privacy",
|
||||
"hexcasting.mishap.divide_by_zero.divide": "Attempted to divide %s by %s",
|
||||
"hexcasting.mishap.divide_by_zero.project": "Attempted to project %s onto %s",
|
||||
"hexcasting.mishap.divide_by_zero.exponent": "Attempted to raise %s to the %s",
|
||||
"hexcasting.mishap.divide_by_zero.zero": "zero",
|
||||
"hexcasting.mishap.divide_by_zero.zero.power": "zeroth power",
|
||||
"hexcasting.mishap.divide_by_zero.zero.vec": "the zero vector",
|
||||
"hexcasting.mishap.divide_by_zero.power": "power of %s",
|
||||
"hexcasting.mishap.no_akashic_record": "No akashic record at %s",
|
||||
|
||||
"hexcasting.landing": "I seem to have discovered a new method of magical arts, in which one draws patterns strange and wild onto a hexagonal grid. It fascinates me. I've decided to start a journal of my thoughts and findings.$(br2)$(l:https://discord.gg/4xxHGYteWk)Discord Server Link/$",
|
||||
|
|
Before Width: | Height: | Size: 460 B After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 469 B After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 506 B After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 445 B After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 456 B After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 455 B After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 437 B |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 444 B |
After Width: | Height: | Size: 528 B |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 542 B |
After Width: | Height: | Size: 564 B |
After Width: | Height: | Size: 560 B |