Merge branch 'gamma-delta:akashic' into akashic

This commit is contained in:
Falkory220 2022-04-07 16:43:53 +01:00 committed by GitHub
commit 233336e52f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 506 additions and 193 deletions

View file

@ -1,24 +0,0 @@
name: Java CI with Gradle
on:
push:
tags: 'v*'
branches: 'main'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
uses: gradle/gradle-build-action@v2
with:
arguments: build
- uses: actions/upload-artifact@v2
if: github.event_name != 'pull_request'
with:
name: Package
path: build/libs

View file

@ -1,25 +0,0 @@
name: Publish tag
on:
push:
tags:
- 'v*'
jobs:
build:
runs-on: ubuntu-latest
env:
TAG_NAME: ${{ github.ref_name }}
steps:
- uses: actions/checkout@v2
- name: Set up JDK
uses: actions/setup-java@v2
with:
java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
uses: gradle/gradle-build-action@v2
with:
arguments: build
- name: Release
uses: softprops/action-gh-release@v1
with:
files: build/libs/*

38
Jenkinsfile vendored Normal file
View file

@ -0,0 +1,38 @@
#!/usr/bin/env groovy
pipeline {
agent any
tools {
jdk "jdk-17.0.1"
}
environment {
discordWebhook = credentials('discordWebhook')
}
stages {
stage('Clean') {
steps {
echo 'Cleaning Project'
sh 'chmod +x gradlew'
sh './gradlew clean'
}
}
stage('Build') {
steps {
echo 'Building'
sh './gradlew build'
}
}
stage('Publish') {
when { branch 'main' }
steps {
echo 'Deploying to Maven'
sh './gradlew publish sendWebhook'
}
}
}
post {
always {
archiveArtifacts 'build/libs/**.jar'
}
}
}

View file

@ -4,14 +4,20 @@ buildscript {
maven { url = 'https://maven.minecraftforge.net' }
maven { url = 'https://maven.parchmentmc.org' }
maven { url = 'https://repo.spongepowered.org/maven' }
maven { url = 'https://maven.blamejared.com' }
mavenCentral()
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true
classpath 'org.parchmentmc:librarian:1.+'
classpath group: 'org.spongepowered', name: 'mixingradle', version: '0.7-SNAPSHOT'
classpath group: 'com.diluv.schoomp', name: 'Schoomp', version: '1.1.0'
}
}
import com.diluv.schoomp.Webhook
import com.diluv.schoomp.message.Message
apply plugin: 'net.minecraftforge.gradle'
// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
apply plugin: 'eclipse'
@ -20,11 +26,39 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.parchmentmc.librarian.forgegradle'
apply plugin: 'org.spongepowered.mixin'
version = '0.7.1'
version = '0.8.0'
group = 'at.petra-k.hexcasting' // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = 'hexcasting'
archivesBaseName = 'hexcasting-1.18.2'
if (System.getenv('TAG_NAME') != null) {
def isRelease = { ->
try {
def stdout = new ByteArrayOutputStream()
def gitHash = System.getenv('GIT_COMMIT')
def gitPrevHash = System.getenv('GIT_PREVIOUS_COMMIT')
def travisRange = System.getenv('TRAVIS_COMMIT_RANGE')
if (gitHash && gitPrevHash) {
exec {
commandLine 'git', 'log', '--pretty=tformat:- %s', '' + gitPrevHash + '...' + gitHash
standardOutput = stdout
}
return stdout.toString().toLowerCase().contains("[release")
} else if (travisRange) {
exec {
commandLine 'git', 'log', '--pretty=tformat:- %s', '' + travisRange
standardOutput = stdout
}
return stdout.toString().toLowerCase().contains("[release")
} else {
return false
}
} catch (ignored) {
return false
}
}
if (!isRelease && System.getenv('BUILD_NUMBER') != null) {
version += "-prerelease-" + System.getenv('BUILD_NUMBER')
} else if (System.getenv('TAG_NAME') != null) {
version = System.getenv('TAG_NAME').substring(1)
println 'Version overridden to tag version ' + version
}
@ -173,13 +207,6 @@ repositories {
name = "ModMaven"
url = "https://modmaven.dev"
}
maven {
url "https://cursemaven.com"
content {
includeGroup "curse.maven"
}
}
}
dependencies {
@ -199,8 +226,8 @@ dependencies {
// at runtime, use the full JEI jar
runtimeOnly fg.deobf("mezz.jei:jei-1.18.2:9.5.3.143")
compileOnly fg.deobf("curse.maven:paucal-597824:3725861")
runtimeOnly fg.deobf("curse.maven:paucal-597824:3725861")
compileOnly fg.deobf("at.petra-k.paucal:paucal-1.18.2:0.3.2")
runtimeOnly fg.deobf("at.petra-k.paucal:paucal-1.18.2:0.3.2")
}
mixin {
@ -209,6 +236,11 @@ mixin {
dumpTargetOnFailure true
}
java {
withJavadocJar()
withSourcesJar()
}
// Example for how to get properties into the manifest for reading at runtime.
jar {
manifest {
@ -230,15 +262,35 @@ jar.finalizedBy('reobfJar')
// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing
// publish.dependsOn('reobfJar')
// Disables Gradle's custom module metadata from being published to maven. The
// metadata includes mapped dependencies which are not reasonably consumable by
// other mod developers.
tasks.withType(GenerateModuleMetadata) {
enabled = false
}
publishing {
publications {
mavenJava(MavenPublication) {
artifact jar
groupId project.group
artifactId project.archivesBaseName
version project.version
from components.java
pom.withXml {
asNode().dependencies.dependency.each { dep ->
assert dep.parent().remove(dep)
}
}
}
}
repositories {
maven {
url "file://${project.projectDir}/mcmodsrepo"
url "file://" + System.getenv("local_maven")
}
}
}
@ -250,3 +302,50 @@ compileTestKotlin {
kotlinOptions {
}
}
def getGitChangelog = { ->
try {
def stdout = new ByteArrayOutputStream()
def gitHash = System.getenv('GIT_COMMIT')
def gitPrevHash = System.getenv('GIT_PREVIOUS_COMMIT')
def travisRange = System.getenv('TRAVIS_COMMIT_RANGE')
if (gitHash && gitPrevHash) {
exec {
commandLine 'git', 'log', '--pretty=tformat:> %s', '' + gitPrevHash + '...' + gitHash
standardOutput = stdout
}
return stdout.toString().trim()
} else if (travisRange) {
exec {
commandLine 'git', 'log', '--pretty=tformat:> %s', '' + travisRange
standardOutput = stdout
}
return stdout.toString().trim()
} else {
return ""
}
} catch (ignored) {
return ""
}
}
task sendWebhook {
doLast {
try {
if (System.getenv('discordWebhook') == null || System.getenv("BUILD_URL") == null) {
println "Cannot send the webhook without the webhook url or the build url"
return
}
def webhook = new Webhook(System.getenv('discordWebhook'), 'Petrak@ Patreon Gradle')
def message = new Message()
message.setUsername("Patreon Early Access")
message.setContent("New Hexcasting release! Download it here: ${System.getenv("BUILD_URL")}\nChangelog:\n${getGitChangelog()}")
webhook.sendMessage(message)
} catch (ignored) {
project.logger.error("Failed to push Discord webhook.")
}
}
}

View file

@ -28,35 +28,35 @@ aed50918bad8a7b00cd26e45d67eb509a04c9f6c assets/hexcasting/blockstates/amethyst_
77e723163f415795437b810fe87c348c96a989be assets/hexcasting/blockstates/scroll_paper_lantern.json
5cb63493ae07f5ab5d8f686e3553c97a85105931 assets/hexcasting/blockstates/slate.json
043abd5bbfd1186415049d24d185d4e4395320f9 assets/hexcasting/blockstates/slate_block.json
866dc8bd766571aec33394b4af1e6b28ceef36cb assets/hexcasting/models/block/akashic_bookshelf_double0.json
b582e7eb88a4e7cf258b903d2ba282bfa5770deb assets/hexcasting/models/block/akashic_bookshelf_double1.json
06ec37e0e3edc576713e60ea3670f208ddef8335 assets/hexcasting/models/block/akashic_bookshelf_double2.json
fa7df33096483b43d2fd5e663576d0ed6c77fd00 assets/hexcasting/models/block/akashic_bookshelf_double3.json
2fb789e8f932dff33b9dffef66a6c570cd09e593 assets/hexcasting/models/block/akashic_bookshelf_empty0.json
1bf1773a6224537b0d1cdb5ed98300094763b35e assets/hexcasting/models/block/akashic_bookshelf_entity0.json
fb06e1af5d79feae6f8826bba0fc6c57f95f32eb assets/hexcasting/models/block/akashic_bookshelf_entity1.json
cc2a9bb3c959ad313431c1476f6f3a4410aaf4d5 assets/hexcasting/models/block/akashic_bookshelf_entity2.json
339d944a1604a0949e836a412b192ef5f18a31de assets/hexcasting/models/block/akashic_bookshelf_entity3.json
609195285d8672221f3bf5d6196e2536a29e3a36 assets/hexcasting/models/block/akashic_bookshelf_list0.json
66bb6f23b7d5fdcd1bfd45cbba00c082bf328d6d assets/hexcasting/models/block/akashic_bookshelf_list1.json
8e9fabc624bd4a9171f326d1b116ddce0ac03936 assets/hexcasting/models/block/akashic_bookshelf_list2.json
b6722e6b1ed5bae988152579f925562e05c0e7ce assets/hexcasting/models/block/akashic_bookshelf_list3.json
450c52b84d0ce8db6bca9bcb0f401e4c0f64d56e assets/hexcasting/models/block/akashic_bookshelf_other0.json
c45373e6acfe8e02b892cf79b0ab90b20505a403 assets/hexcasting/models/block/akashic_bookshelf_other1.json
0bd6a902d935c54f95c403fe987d6d1d8fd4b037 assets/hexcasting/models/block/akashic_bookshelf_other2.json
df0eff5d064b1344c16a25b1f61ed8e0d1d9e93d assets/hexcasting/models/block/akashic_bookshelf_other3.json
f012cc73e966263135581f6b5559573d7027d161 assets/hexcasting/models/block/akashic_bookshelf_pattern0.json
1b0fa714816106bf800346a47558f808b614f20e assets/hexcasting/models/block/akashic_bookshelf_pattern1.json
c87db8396d3aff9de54bceaaf7005e99bc11e941 assets/hexcasting/models/block/akashic_bookshelf_pattern2.json
c97f68bfea418fc1e71e801ddb408456aaf2709b assets/hexcasting/models/block/akashic_bookshelf_pattern3.json
daa7c03501b6c416e292ee81a1086777374fb65f assets/hexcasting/models/block/akashic_bookshelf_vec0.json
77a385aef36d9ff1b8ee8c3257cf0a131c7a00bc assets/hexcasting/models/block/akashic_bookshelf_vec1.json
088749fa83b9eab81e572b93833ab31166cf54aa assets/hexcasting/models/block/akashic_bookshelf_vec2.json
2d9880c0a28e90e030b920426443e69e4bbda3d1 assets/hexcasting/models/block/akashic_bookshelf_vec3.json
2d66d2d958325c5e8afd8ded4e413a0a29d004cf assets/hexcasting/models/block/akashic_bookshelf_widget0.json
8eb8b14eb801739687ac4cdf29b959dce0b206f3 assets/hexcasting/models/block/akashic_bookshelf_widget1.json
2ceccf7ebfad7517a476978b7110875f05569506 assets/hexcasting/models/block/akashic_bookshelf_widget2.json
4511f440c9f25f6daa2bf352f192beef3088faf2 assets/hexcasting/models/block/akashic_bookshelf_widget3.json
2d15e34158cece647d497ef88e463487359f75eb assets/hexcasting/models/block/akashic_bookshelf_double0.json
632d2cddba9c17b1580d50e1995de3c44d31f542 assets/hexcasting/models/block/akashic_bookshelf_double1.json
c96c914adc33e0aede5e65c157b86d712c93fe3c assets/hexcasting/models/block/akashic_bookshelf_double2.json
d450489f48e120d19ace98d6419c30bf6d2abf57 assets/hexcasting/models/block/akashic_bookshelf_double3.json
7f0443e9859e339695dc51a17999ba464cfafd10 assets/hexcasting/models/block/akashic_bookshelf_empty0.json
697e3e12fad2fa3cbcaf65ec9e8730796762d761 assets/hexcasting/models/block/akashic_bookshelf_entity0.json
4afa26f463c514c93a7faa86834515769d14fae3 assets/hexcasting/models/block/akashic_bookshelf_entity1.json
726d6db36ec79c44c21bcb9e726ccd45d3f7603c assets/hexcasting/models/block/akashic_bookshelf_entity2.json
4eb78401ba6018230d7f2f15a4604f7f82e10288 assets/hexcasting/models/block/akashic_bookshelf_entity3.json
4160204476c68c89f49862b1239feaab7efc82af assets/hexcasting/models/block/akashic_bookshelf_list0.json
30b2da2b25229646729fc6a60bca939b17a301cb assets/hexcasting/models/block/akashic_bookshelf_list1.json
d820a4698ed10673f83fd5d3d2ba51831eed1719 assets/hexcasting/models/block/akashic_bookshelf_list2.json
16a4ac20b3342fc0551c7819f4b588f834b05240 assets/hexcasting/models/block/akashic_bookshelf_list3.json
a2c05476f6876e1d3933fbf24c7ebee6a817e4e7 assets/hexcasting/models/block/akashic_bookshelf_other0.json
e4f5dd9d9c18e8864bdb8089c5c027b961840c71 assets/hexcasting/models/block/akashic_bookshelf_other1.json
a0648b0b707cb71302c0b4c5c1d1850700049f0b assets/hexcasting/models/block/akashic_bookshelf_other2.json
da0b58413ccbe244395e576374eabf9f7f77cff5 assets/hexcasting/models/block/akashic_bookshelf_other3.json
46f14c543f573d17ce88586994b5190d49aa82e0 assets/hexcasting/models/block/akashic_bookshelf_pattern0.json
d35301dcfa6113bf18d93e3390e4f41ba82fc496 assets/hexcasting/models/block/akashic_bookshelf_pattern1.json
4fcce7cb268762cefc7aeb23857f4a8f9dd27cea assets/hexcasting/models/block/akashic_bookshelf_pattern2.json
05a5db451083e351663a3e8543de96387ccb0019 assets/hexcasting/models/block/akashic_bookshelf_pattern3.json
b40c007e6445c3651fb862a717ffcae71fa5b134 assets/hexcasting/models/block/akashic_bookshelf_vec0.json
0e5e5980be796fed69121b5afbb345a7e7f5e232 assets/hexcasting/models/block/akashic_bookshelf_vec1.json
cbda1ba469c679566ad913d02a2aa6b82d581469 assets/hexcasting/models/block/akashic_bookshelf_vec2.json
4ecb317c7f0844878ef3e507ea40fb5c02ad9325 assets/hexcasting/models/block/akashic_bookshelf_vec3.json
2430f9dcaf51c86d3413ebfc6834e3ca91e5f4aa assets/hexcasting/models/block/akashic_bookshelf_widget0.json
94e79ebb6e73ef89ec6a20d11b7ea242e6f387c3 assets/hexcasting/models/block/akashic_bookshelf_widget1.json
3b411abf79de1e2bed972a40c3338e4584719b54 assets/hexcasting/models/block/akashic_bookshelf_widget2.json
6363ddafca13522e33c94656f05d381d8cdf286f assets/hexcasting/models/block/akashic_bookshelf_widget3.json
a38a867ae86bc5da5e7abb668e6a92a7e2628279 assets/hexcasting/models/block/akashic_connector.json
f3a7403c673a4816d421f22e69a5458670694aac assets/hexcasting/models/block/akashic_door_bottom.json
8e33c5d50ab94c4996522cce88b70e5c317a3635 assets/hexcasting/models/block/akashic_door_bottom_hinge.json

View file

@ -436,7 +436,7 @@ public abstract class BlockEntityAbstractImpetus extends PaucalBlockEntity imple
if (this.trackedBlocks == null) {
return 10;
} else {
return Math.max(4, 10 - trackedBlocks.size() / 2);
return Math.max(2, 10 - trackedBlocks.size() / 3);
}
}

View file

@ -1,51 +1,42 @@
package at.petrak.hexcasting.common.items;
package at.petrak.hexcasting.api.item;
import at.petrak.hexcasting.api.spell.SpellDatum;
import at.petrak.hexcasting.common.casting.CastingContext;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.item.Item;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
import java.util.List;
abstract public class ItemDataHolder extends Item {
public ItemDataHolder(Properties pProperties) {
super(pProperties);
}
public interface DataHolder {
@Nullable CompoundTag readDatumTag(ItemStack stack);
@Nullable
public abstract CompoundTag readDatumTag(ItemStack stack);
@Nullable
public SpellDatum<?> readDatum(ItemStack stack, CastingContext ctx) {
if (!(stack.getItem() instanceof ItemDataHolder dh)) {
default SpellDatum<?> readDatum(ItemStack stack, ServerLevel world) {
if (!(stack.getItem() instanceof DataHolder dh)) {
// this should be checked via mishap beforehand
throw new IllegalArgumentException("stack's item must be an ItemDataholder but was " + stack.getItem());
}
var tag = dh.readDatumTag(stack);
if (tag != null) {
return SpellDatum.DeserializeFromNBT(tag, ctx);
return SpellDatum.DeserializeFromNBT(tag, world);
} else {
return null;
}
}
boolean canWrite(CompoundTag tag, SpellDatum<?> datum);
public abstract boolean canWrite(CompoundTag tag, SpellDatum<?> datum);
void writeDatum(CompoundTag tag, SpellDatum<?> datum);
public abstract void writeDatum(CompoundTag tag, SpellDatum<?> datum);
@Override
public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List<Component> pTooltipComponents,
static void appendHoverText(DataHolder self, ItemStack pStack, List<Component> pTooltipComponents,
TooltipFlag pIsAdvanced) {
var datumTag = this.readDatumTag(pStack);
var datumTag = self.readDatumTag(pStack);
if (datumTag != null) {
var component = SpellDatum.DisplayFromTag(datumTag);
pTooltipComponents.add(new TranslatableComponent("hexcasting.spelldata.onitem", component));

View file

@ -146,15 +146,15 @@ public class RegisterClientStuff {
var out = new ArrayList<Pair<ItemStack, Component>>();
if (tile.recordPos != null) {
var recordPos = tile.getRecordPos();
var pattern = tile.getPattern();
if (recordPos != null && pattern != null) {
out.add(new Pair<>(new ItemStack(HexBlocks.AKASHIC_RECORD.get()), new TranslatableComponent(
"hexcasting.tooltip.lens.akashic.bookshelf.location",
tile.recordPos.toShortString()
recordPos.toShortString()
)));
if (tile.pattern != null) {
if (world.getBlockEntity(tile.recordPos) instanceof BlockEntityAkashicRecord record) {
out.add(new Pair<>(new ItemStack(Items.BOOK), record.getDisplayAt(tile.pattern)));
}
if (world.getBlockEntity(recordPos) instanceof BlockEntityAkashicRecord record) {
out.add(new Pair<>(new ItemStack(Items.BOOK), record.getDisplayAt(pattern)));
}
}

View file

@ -1,9 +1,16 @@
package at.petrak.hexcasting.common.blocks.akashic;
import at.petrak.hexcasting.api.spell.DatumType;
import at.petrak.hexcasting.api.spell.SpellDatum;
import at.petrak.hexcasting.common.blocks.HexBlocks;
import at.petrak.hexcasting.common.items.ItemScroll;
import at.petrak.hexcasting.common.lib.HexSounds;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
@ -16,6 +23,7 @@ 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.DirectionProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
import net.minecraft.world.phys.BlockHitResult;
import org.jetbrains.annotations.Nullable;
public class BlockAkashicBookshelf extends BlockAkashicFloodfiller implements EntityBlock {
@ -31,21 +39,53 @@ public class BlockAkashicBookshelf extends BlockAkashicFloodfiller implements En
@Override
public @Nullable BlockPos getRecordPosition(BlockPos herePos, BlockState state, Level world) {
// time saving measure?
if (world.getBlockEntity(herePos) instanceof BlockEntityAkashicBookshelf tile &&
tile.recordPos != null && world.getBlockEntity(tile.recordPos) instanceof BlockEntityAkashicRecord) {
return tile.recordPos;
tile.getRecordPos() != null && world.getBlockEntity(
tile.getRecordPos()) instanceof BlockEntityAkashicRecord) {
return tile.getRecordPos();
}
return super.getRecordPosition(herePos, state, world);
}
@Override
public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand,
BlockHitResult pHit) {
if (pLevel.getBlockEntity(pPos) instanceof BlockEntityAkashicBookshelf shelf) {
var stack = pPlayer.getItemInHand(pHand);
if (stack.getItem() instanceof ItemScroll scroll) {
if (!pLevel.isClientSide()) {
scroll.writeDatum(stack.getOrCreateTag(), SpellDatum.make(shelf.getPattern()));
}
pLevel.playSound(pPlayer, pPos, HexSounds.SCROLL_SCRIBBLE.get(), SoundSource.BLOCKS, 1f, 1f);
return InteractionResult.sidedSuccess(pLevel.isClientSide);
} else if (pPlayer.isDiscrete() && pHand == InteractionHand.MAIN_HAND && stack.isEmpty()) {
if (!pLevel.isClientSide()) {
shelf.setNewData(null, null, DatumType.EMPTY);
var recordPos = HexBlocks.AKASHIC_BOOKSHELF.get().getRecordPosition(pPos, pState, pLevel);
if (recordPos != null &&
pLevel.getBlockEntity(recordPos) instanceof BlockEntityAkashicRecord record) {
record.revalidateAllBookshelves();
}
}
pLevel.playSound(pPlayer, pPos, HexSounds.SCROLL_SCRIBBLE.get(), SoundSource.BLOCKS,
1f, 0.8f);
return InteractionResult.sidedSuccess(pLevel.isClientSide);
}
}
return InteractionResult.PASS;
}
@Override
public void onPlace(BlockState pState, Level world, BlockPos pos, BlockState pOldState, boolean pIsMoving) {
if (world.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf tile) {
var recordPos = BlockAkashicFloodfiller.floodFillFor(pos, world,
(here, bs, level) -> bs.is(HexBlocks.AKASHIC_RECORD.get()));
if (recordPos != null) {
tile.recordPos = recordPos;
tile.setChanged();
tile.setNewData(recordPos, tile.getPattern(), DatumType.EMPTY);
}
}
}

View file

@ -1,12 +1,18 @@
package at.petrak.hexcasting.common.blocks.akashic;
import at.petrak.hexcasting.api.spell.DatumType;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayDeque;
import java.util.HashSet;
public class BlockAkashicRecord extends Block implements EntityBlock {
public BlockAkashicRecord(Properties p_49795_) {
super(p_49795_);
@ -17,4 +23,30 @@ public class BlockAkashicRecord extends Block implements EntityBlock {
public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) {
return new BlockEntityAkashicRecord(pPos, pState);
}
@Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
var seen = new HashSet<BlockPos>();
var todo = new ArrayDeque<BlockPos>();
todo.add(pPos);
// we do NOT add this position to the valid positions, because the record
// isn't flood-fillable through.
while (!todo.isEmpty()) {
var here = todo.remove();
for (var dir : Direction.values()) {
var neighbor = here.relative(dir);
if (seen.add(neighbor)) {
var bs = pLevel.getBlockState(neighbor);
if (BlockAkashicFloodfiller.canItBeFloodedThrough(neighbor, bs, pLevel)) {
todo.add(neighbor);
}
if (pLevel.getBlockEntity(pPos) instanceof BlockEntityAkashicBookshelf shelf) {
shelf.setNewData(null, null, DatumType.EMPTY);
}
}
}
}
super.onRemove(pState, pLevel, pPos, pNewState, pIsMoving);
}
}

View file

@ -20,28 +20,40 @@ import net.minecraft.nbt.NbtUtils;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec2;
import org.jetbrains.annotations.Nullable;
public class BlockEntityAkashicBookshelf extends PaucalBlockEntity {
public static final String TAG_RECORD_POS = "record_pos";
public static final String TAG_PATTERN = "pattern";
// This might actually be innacurate! It's a best-guess
public BlockPos recordPos = null;
// This might actually be inaccurate! It's a best-guess
private BlockPos recordPos = null;
// This is only not null if this stores any data.
public HexPattern pattern = null;
private HexPattern pattern = null;
public BlockEntityAkashicBookshelf(BlockPos pWorldPosition, BlockState pBlockState) {
super(HexBlockEntities.AKASHIC_BOOKSHELF_TILE.get(), pWorldPosition, pBlockState);
}
public void setNewDatum(BlockPos recordPos, HexPattern pattern, DatumType type) {
@Nullable
public BlockPos getRecordPos() {
return recordPos;
}
@Nullable
public HexPattern getPattern() {
return pattern;
}
public void setNewData(BlockPos recordPos, HexPattern pattern, DatumType type) {
this.recordPos = recordPos;
this.pattern = pattern;
this.setChanged();
var oldBs = this.getBlockState();
var newBs = oldBs.setValue(BlockAkashicBookshelf.DATUM_TYPE, type);
this.level.setBlockAndUpdate(this.getBlockPos(), newBs);
this.level.setBlock(this.getBlockPos(), newBs, 3);
this.level.sendBlockUpdated(this.getBlockPos(), oldBs, newBs, 3);
}
@ -49,7 +61,6 @@ public class BlockEntityAkashicBookshelf extends PaucalBlockEntity {
protected void saveModData(CompoundTag compoundTag) {
if (this.recordPos != null) {
compoundTag.put(TAG_RECORD_POS, NbtUtils.writeBlockPos(this.recordPos));
}
if (this.pattern != null) {
compoundTag.put(TAG_PATTERN, this.pattern.serializeToNBT());
@ -60,9 +71,13 @@ public class BlockEntityAkashicBookshelf extends PaucalBlockEntity {
protected void loadModData(CompoundTag compoundTag) {
if (compoundTag.contains(TAG_RECORD_POS)) {
this.recordPos = NbtUtils.readBlockPos(compoundTag.getCompound(TAG_RECORD_POS));
} else {
this.recordPos = null;
}
if (compoundTag.contains(TAG_PATTERN)) {
this.pattern = HexPattern.DeserializeFromNBT(compoundTag.getCompound(TAG_PATTERN));
} else {
this.pattern = null;
}
}

View file

@ -51,10 +51,10 @@ public class BlockEntityAkashicRecord extends PaucalBlockEntity {
var openPos = BlockAkashicFloodfiller.floodFillFor(this.worldPosition, this.level,
(pos, bs, world) -> world.getBlockEntity(pos) instanceof BlockEntityAkashicBookshelf tile
&& tile.pattern == null);
&& tile.getPattern() == null);
if (openPos != null) {
var tile = (BlockEntityAkashicBookshelf) this.level.getBlockEntity(openPos);
tile.setNewDatum(this.getBlockPos(), key, datum.getType());
tile.setNewData(this.getBlockPos(), key, datum.getType());
this.entries.put(key.anglesSignature(), new Entry(openPos, key.startDir(), datum.serializeToNBT()));
this.sync();
@ -87,7 +87,7 @@ public class BlockEntityAkashicRecord extends PaucalBlockEntity {
return this.entries.size();
}
private void revalidateAllBookshelves() {
public void revalidateAllBookshelves() {
// floodfill for all known positions
var validPoses = new HashSet<BlockPos>();
{
@ -120,7 +120,7 @@ public class BlockEntityAkashicRecord extends PaucalBlockEntity {
this.entries.remove(sig);
if (this.level.getBlockEntity(entry.pos) instanceof BlockEntityAkashicBookshelf shelf) {
shelf.setNewDatum(null, null, DatumType.EMPTY);
shelf.setNewData(null, null, DatumType.EMPTY);
}
}
}
@ -146,6 +146,7 @@ public class BlockEntityAkashicRecord extends PaucalBlockEntity {
protected void loadModData(CompoundTag compoundTag) {
var lookupTag = compoundTag.getCompound(TAG_LOOKUP);
this.entries.clear();
var sigs = lookupTag.getAllKeys();
for (var sig : sigs) {
var entryTag = lookupTag.getCompound(sig);

View file

@ -1,8 +1,8 @@
package at.petrak.hexcasting.common.blocks.circles.impetuses;
import at.petrak.hexcasting.api.circle.BlockAbstractImpetus;
import at.petrak.hexcasting.api.item.DataHolder;
import at.petrak.hexcasting.api.spell.SpellDatum;
import at.petrak.hexcasting.common.items.ItemDataHolder;
import at.petrak.hexcasting.common.lib.HexSounds;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerPlayer;
@ -33,7 +33,7 @@ public class BlockStoredPlayerImpetus extends BlockAbstractImpetus {
BlockHitResult pHit) {
if (pLevel.getBlockEntity(pPos) instanceof BlockEntityStoredPlayerImpetus tile) {
var usedStack = pPlayer.getItemInHand(pHand);
if (usedStack.getItem() instanceof ItemDataHolder dataer) {
if (usedStack.getItem() instanceof DataHolder dataer) {
var stored = dataer.readDatumTag(usedStack);
if (stored != null && stored.contains(SpellDatum.TAG_ENTITY)) {
var uuid = stored.getCompound(SpellDatum.TAG_ENTITY).getUUID(SpellDatum.TAG_ENTITY_UUID);

View file

@ -2,12 +2,12 @@ package at.petrak.hexcasting.common.casting
import at.petrak.hexcasting.HexConfig
import at.petrak.hexcasting.HexUtils
import at.petrak.hexcasting.api.item.DataHolder
import at.petrak.hexcasting.api.spell.Operator
import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem
import at.petrak.hexcasting.common.casting.mishaps.MishapEntityTooFarAway
import at.petrak.hexcasting.common.casting.mishaps.MishapEvalTooDeep
import at.petrak.hexcasting.common.casting.mishaps.MishapLocationTooFarAway
import at.petrak.hexcasting.common.items.ItemDataHolder
import at.petrak.hexcasting.common.lib.HexCapabilities
import at.petrak.hexcasting.common.lib.RegisterHelper.prefix
import net.minecraft.server.level.ServerLevel
@ -40,7 +40,7 @@ data class CastingContext(
fun getDataHolder(): ItemStack {
val handItem =
caster.getItemInHand(this.otherHand)
return if (handItem.item is ItemDataHolder) {
return if (handItem.item is DataHolder) {
handItem
} else {
throw MishapBadOffhandItem.of(handItem, "iota")

View file

@ -77,6 +77,8 @@ public class RegisterPatterns {
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("d", HexDir.EAST), prefix("const/null"), Widget.NULL);
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("aadaa", HexDir.EAST), prefix("duplicate"),
OpDuplicate.INSTANCE);
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("aadaadaa", HexDir.EAST), prefix("duplicate_n"),
OpDuplicateN.INSTANCE);
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("aawdd", HexDir.EAST), prefix("swap"), OpSwap.INSTANCE);
PatternRegistry.mapPattern(HexPattern.FromAnglesSig("ddad", HexDir.WEST), prefix("fisherman"),
OpFisherman.INSTANCE);

View file

@ -0,0 +1,34 @@
package at.petrak.hexcasting.common.casting.operators
import at.petrak.hexcasting.api.spell.ConstManaOperator
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.mishaps.MishapInvalidIota
import net.minecraft.network.chat.TranslatableComponent
import kotlin.math.abs
import kotlin.math.roundToInt
object OpDuplicateN : ConstManaOperator {
override val argc: Int
get() = 2
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
val countDouble = args.getChecked<Double>(1)
if (abs(countDouble.toInt() - countDouble) >= 0.05f)
throw MishapInvalidIota(
args[1],
0,
TranslatableComponent("hexcasting.mishap.invalid_value.fisherman", args.size)
)
val count = countDouble.roundToInt()
// there's gotta be a better way to do this
val out = mutableListOf<SpellDatum<*>>()
for (n in 0 until count)
out.add(args[0])
return out
}
}

View file

@ -1,10 +1,10 @@
package at.petrak.hexcasting.common.casting.operators
import at.petrak.hexcasting.api.item.DataHolder
import at.petrak.hexcasting.api.spell.ConstManaOperator
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem
import at.petrak.hexcasting.common.items.ItemDataHolder
object OpRead : ConstManaOperator {
override val argc = 0
@ -13,10 +13,10 @@ object OpRead : ConstManaOperator {
val handStack =
ctx.caster.getItemInHand(ctx.otherHand)
val handItem = handStack.item
if (handItem !is ItemDataHolder) {
if (handItem !is DataHolder) {
throw MishapBadOffhandItem.of(handStack, "iota.read")
}
val datum = handItem.readDatum(handStack, ctx) ?: throw MishapBadOffhandItem.of(handStack, "iota.read")
val datum = handItem.readDatum(handStack, ctx.world) ?: throw MishapBadOffhandItem.of(handStack, "iota.read")
return listOf(datum)
}
}

View file

@ -1,11 +1,11 @@
package at.petrak.hexcasting.common.casting.operators
import at.petrak.hexcasting.api.item.DataHolder
import at.petrak.hexcasting.api.spell.ConstManaOperator
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
import at.petrak.hexcasting.api.spell.SpellDatum
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem
import at.petrak.hexcasting.common.items.ItemDataHolder
import net.minecraft.world.entity.item.ItemEntity
object OpTheCoolerRead : ConstManaOperator {
@ -18,13 +18,13 @@ object OpTheCoolerRead : ConstManaOperator {
val target = args.getChecked<ItemEntity>(0)
val stack = target.item
val item = stack.item
if (item !is ItemDataHolder) {
if (item !is DataHolder) {
throw MishapBadOffhandItem.of(stack, "iota.read")
}
ctx.assertEntityInRange(target)
val datum = item.readDatum(stack, ctx) ?: throw MishapBadOffhandItem.of(stack, "iota.read")
val datum = item.readDatum(stack, ctx.world) ?: throw MishapBadOffhandItem.of(stack, "iota.read")
return listOf(datum)
}
}

View file

@ -1,17 +1,13 @@
package at.petrak.hexcasting.common.casting.operators
import at.petrak.hexcasting.api.item.DataHolder
import at.petrak.hexcasting.api.spell.ParticleSpray
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.circles.BlockEntitySlate
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.mishaps.MishapBadOffhandItem
import at.petrak.hexcasting.common.casting.mishaps.MishapOthersName
import at.petrak.hexcasting.common.items.HexItems
import at.petrak.hexcasting.common.items.ItemDataHolder
import at.petrak.hexcasting.common.items.ItemScroll
import at.petrak.hexcasting.hexmath.HexPattern
import net.minecraft.world.entity.player.Player
// we make this a spell cause imo it's a little ... anticlimactic for it to just make no noise
@ -26,21 +22,8 @@ object OpWrite : SpellOperator {
val tag = handStack.orCreateTag
val datum = args[0]
val canWrite = if (handItem is ItemDataHolder) {
val canWrite = if (handItem is DataHolder) {
handItem.canWrite(tag, datum)
} else if (datum.payload is HexPattern) {
if (handStack.`is`(HexItems.SCROLL.get()) && !tag.contains(ItemScroll.TAG_PATTERN)) {
true
} else if (handStack.`is`(HexItems.SLATE.get())) {
val hasBET = tag.contains("BlockEntityTag")
if (hasBET) {
tag.getCompound("BlockEntityTag").contains(BlockEntitySlate.TAG_PATTERN)
} else {
true
}
} else {
false
}
} else {
false
}
@ -62,18 +45,9 @@ object OpWrite : SpellOperator {
val handStack = ctx.caster.getItemInHand(ctx.otherHand)
val handItem = handStack.item
val tag = handStack.orCreateTag
if (handItem is ItemDataHolder) {
if (handItem is DataHolder) {
handItem.writeDatum(tag, datum)
} else if (handItem == HexItems.SCROLL.get() && !tag.contains(ItemScroll.TAG_PATTERN) && datum.payload is HexPattern) {
tag.put(ItemScroll.TAG_PATTERN, datum.payload.serializeToNBT())
} else if (handItem == HexItems.SLATE.get() && datum.payload is HexPattern) {
val bet = tag.getCompound("BlockEntityTag")
bet.put(BlockEntitySlate.TAG_PATTERN, datum.payload.serializeToNBT())
// Just in case it's brand new
tag.put("BlockEntityTag", bet)
} else {
// Fuck
}
} // else fuck
}
}

View file

@ -1,22 +1,27 @@
package at.petrak.hexcasting.common.casting.operators.akashic
import at.petrak.hexcasting.api.spell.ConstManaOperator
import at.petrak.hexcasting.api.spell.Operator.Companion.getChecked
import at.petrak.hexcasting.api.spell.Operator.Companion.spellListOf
import at.petrak.hexcasting.api.spell.ParticleSpray
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.akashic.BlockEntityAkashicRecord
import at.petrak.hexcasting.common.casting.CastingContext
import at.petrak.hexcasting.common.casting.Widget
import at.petrak.hexcasting.common.casting.mishaps.MishapNoAkashicRecord
import at.petrak.hexcasting.common.lib.HexCapabilities
import at.petrak.hexcasting.common.lib.HexSounds
import at.petrak.hexcasting.hexmath.HexPattern
import net.minecraft.core.BlockPos
import net.minecraft.sounds.SoundSource
import net.minecraft.world.phys.Vec3
object OpAkashicWrite : ConstManaOperator {
object OpAkashicWrite : SpellOperator {
override val argc = 3
override val manaCost = 10_000
override fun execute(args: List<SpellDatum<*>>, ctx: CastingContext): List<SpellDatum<*>> {
override fun execute(
args: List<SpellDatum<*>>,
ctx: CastingContext
): Triple<RenderedSpell, Int, List<ParticleSpray>> {
val pos = args.getChecked<Vec3>(0)
val key = args.getChecked<HexPattern>(1)
val datum = args[2]
@ -27,12 +32,30 @@ object OpAkashicWrite : ConstManaOperator {
throw MishapNoAkashicRecord(bpos)
}
val newPos = tile.addNewDatum(key, datum)
return spellListOf(
if (newPos == null)
Widget.NULL
else
Vec3.atCenterOf(newPos)
return Triple(
Spell(tile, key, datum),
10_000,
listOf()
)
}
private data class Spell(val record: BlockEntityAkashicRecord, val key: HexPattern, val datum: SpellDatum<*>) :
RenderedSpell {
override fun cast(ctx: CastingContext) {
record.addNewDatum(key, datum)
ctx.world.playSound(
null, record.blockPos, HexSounds.SCROLL_SCRIBBLE.get(), SoundSource.BLOCKS,
1f, 0.8f
)
ctx.caster.getCapability(HexCapabilities.PREFERRED_COLORIZER).ifPresent {
// val normal = record.blockState.getValue(BlockAkashicBookshelf.FACING).normal
// ParticleSpray(
// Vec3.atCenterOf(record.blockPos), Vec3.atBottomCenterOf(normal),
// 0.5, Math.PI / 4, 10
// ).sprayParticles(ctx.world, it.colorizer)
}
}
}
}

View file

@ -121,7 +121,7 @@ public class EntityWallScroll extends HangingEntity implements IEntityAdditional
}
this.setShowsStrokeOrder(true);
pPlayer.level.playSound(pPlayer, this, HexSounds.DUST_SCROLL.get(), SoundSource.PLAYERS, 1f, 1f);
pPlayer.level.playSound(pPlayer, this, HexSounds.SCROLL_DUST.get(), SoundSource.PLAYERS, 1f, 1f);
return InteractionResult.SUCCESS;
}
return super.interactAt(pPlayer, pVec, pHand);

View file

@ -1,18 +1,24 @@
package at.petrak.hexcasting.common.items;
import at.petrak.hexcasting.api.item.DataHolder;
import at.petrak.hexcasting.api.spell.SpellDatum;
import at.petrak.hexcasting.common.lib.HexSounds;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
public class ItemAbacus extends ItemDataHolder {
import java.util.List;
public class ItemAbacus extends Item implements DataHolder {
public static final String TAG_VALUE = "value";
public ItemAbacus(Properties pProperties) {
@ -67,4 +73,10 @@ public class ItemAbacus extends ItemDataHolder {
return InteractionResultHolder.pass(stack);
}
}
@Override
public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List<Component> pTooltipComponents,
TooltipFlag pIsAdvanced) {
DataHolder.appendHoverText(this, pStack, pTooltipComponents, pIsAdvanced);
}
}

View file

@ -1,13 +1,20 @@
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.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;
public class ItemFocus extends ItemDataHolder {
import java.util.List;
public class ItemFocus extends Item implements DataHolder {
public static final ResourceLocation DATATYPE_PRED = new ResourceLocation(HexMod.MOD_ID, "datatype");
public static final String TAG_DATA = "data";
public static final String TAG_SEALED = "sealed";
@ -40,4 +47,10 @@ public class ItemFocus extends ItemDataHolder {
tag.put(TAG_DATA, datum.serializeToNBT());
}
}
@Override
public void appendHoverText(ItemStack pStack, @Nullable Level pLevel, List<Component> pTooltipComponents,
TooltipFlag pIsAdvanced) {
DataHolder.appendHoverText(this, pStack, pTooltipComponents, pIsAdvanced);
}
}

View file

@ -1,9 +1,14 @@
package at.petrak.hexcasting.common.items;
import at.petrak.hexcasting.HexMod;
import at.petrak.hexcasting.api.item.DataHolder;
import at.petrak.hexcasting.api.spell.DatumType;
import at.petrak.hexcasting.api.spell.SpellDatum;
import at.petrak.hexcasting.common.entities.EntityWallScroll;
import at.petrak.hexcasting.hexmath.HexPattern;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
@ -14,6 +19,7 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.gameevent.GameEvent;
import org.jetbrains.annotations.Nullable;
/**
* TAG_OP_ID and TAG_PATTERN: "Ancient Scroll of %s" (Great Spells)
@ -24,7 +30,7 @@ import net.minecraft.world.level.gameevent.GameEvent;
* <br>
* TAG_OP_ID: invalid
*/
public class ItemScroll extends Item {
public class ItemScroll extends Item implements DataHolder {
public static final String TAG_OP_ID = "op_id";
public static final String TAG_PATTERN = "pattern";
public static final ResourceLocation ANCIENT_PREDICATE = new ResourceLocation(HexMod.MOD_ID, "ancient");
@ -33,6 +39,31 @@ public class ItemScroll extends Item {
super(pProperties);
}
@Override
public @Nullable CompoundTag readDatumTag(ItemStack stack) {
var stackTag = stack.getTag();
if (stackTag == null || !stackTag.contains(TAG_PATTERN)) {
return null;
}
var patTag = stackTag.getCompound(TAG_PATTERN);
var out = new CompoundTag();
out.put(SpellDatum.TAG_PATTERN, patTag);
return out;
}
@Override
public boolean canWrite(CompoundTag tag, SpellDatum<?> datum) {
return datum.getType() == DatumType.PATTERN && !tag.contains(TAG_PATTERN);
}
@Override
public void writeDatum(CompoundTag tag, SpellDatum<?> datum) {
if (this.canWrite(tag, datum) && datum.getPayload() instanceof HexPattern pat) {
tag.put(TAG_PATTERN, pat.serializeToNBT());
}
}
@Override
public InteractionResult useOn(UseOnContext ctx) {
var posClicked = ctx.getClickedPos();
@ -85,4 +116,5 @@ public class ItemScroll extends Item {
}
}
// purposely no hover text
}

View file

@ -1,15 +1,21 @@
package at.petrak.hexcasting.common.items;
import at.petrak.hexcasting.HexMod;
import at.petrak.hexcasting.api.item.DataHolder;
import at.petrak.hexcasting.api.spell.DatumType;
import at.petrak.hexcasting.api.spell.SpellDatum;
import at.petrak.hexcasting.common.blocks.circles.BlockEntitySlate;
import at.petrak.hexcasting.hexmath.HexPattern;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import org.jetbrains.annotations.Nullable;
public class ItemSlate extends BlockItem {
public class ItemSlate extends BlockItem implements DataHolder {
public static final ResourceLocation WRITTEN_PRED = new ResourceLocation(HexMod.MOD_ID, "written");
public ItemSlate(Block pBlock, Properties pProperties) {
@ -30,4 +36,42 @@ public class ItemSlate extends BlockItem {
}
return false;
}
@Override
public @Nullable CompoundTag readDatumTag(ItemStack stack) {
var stackTag = stack.getTag();
if (stackTag == null || !stackTag.contains("BlockEntityTag")) {
return null;
}
var beTag = stackTag.getCompound("BlockEntityTag");
if (!beTag.contains(BlockEntitySlate.TAG_PATTERN)) {
return null;
}
var patTag = beTag.getCompound(BlockEntitySlate.TAG_PATTERN);
var out = new CompoundTag();
out.put(SpellDatum.TAG_PATTERN, patTag);
return out;
}
@Override
public boolean canWrite(CompoundTag tag, SpellDatum<?> datum) {
if (datum.getType() != DatumType.PATTERN) {
return false;
}
if (!tag.contains("BlockEntityTag")) {
return false;
}
var beTag = tag.getCompound("BlockEntityTag");
return !beTag.contains(BlockEntitySlate.TAG_PATTERN);
}
@Override
public void writeDatum(CompoundTag tag, SpellDatum<?> datum) {
if (this.canWrite(tag, datum) && datum.getPayload() instanceof HexPattern pat) {
var beTag = tag.getCompound("BlockEntityTag");
beTag.put(BlockEntitySlate.TAG_PATTERN, pat.serializeToNBT());
}
}
}

View file

@ -1,10 +1,12 @@
package at.petrak.hexcasting.common.items;
import at.petrak.hexcasting.api.item.DataHolder;
import at.petrak.hexcasting.api.spell.SpellDatum;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
@ -13,7 +15,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.stream.Stream;
public class ItemSpellbook extends ItemDataHolder {
public class ItemSpellbook extends Item implements DataHolder {
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"

View file

@ -27,7 +27,8 @@ public class HexSounds {
public static final RegistryObject<SoundEvent> SPELL_CIRCLE_FAIL = sound("spellcircle.fail");
public static final RegistryObject<SoundEvent> SPELL_CIRCLE_CAST = sound("spellcircle.cast");
public static final RegistryObject<SoundEvent> DUST_SCROLL = sound("scroll.dust");
public static final RegistryObject<SoundEvent> SCROLL_DUST = sound("scroll.dust");
public static final RegistryObject<SoundEvent> SCROLL_SCRIBBLE = sound("scroll.scribble");
public static final RegistryObject<SoundEvent> IMPETUS_LOOK_TICK = sound("impetus.fletcher.tick");
public static final RegistryObject<SoundEvent> IMPETUS_STOREDPLAYER_DING = sound("impetus.cleric.register");

View file

@ -146,6 +146,7 @@
"hexcasting.subtitles.spellcircle.fail": "Spell circle fizzles out",
"hexcasting.subtitles.spellcircle.cast": "Spell circle casts",
"hexcasting.subtitles.scroll.dust": "Scroll covers with dust",
"hexcasting.subtitles.scroll.dust": "Scribble on Scroll",
"hexcasting.subtitles.impetus.fletcher.tick": "Fletcher Impetus ticks",
"hexcasting.subtitles.impetus.cleric.register": "Cleric Impetus dings",

View file

@ -93,6 +93,14 @@
],
"subtitle": "hexcasting.subtitles.scroll.dust"
},
"scroll.scribble": {
"sounds": [
"minecraft:item/book/open_flip1",
"minecraft:item/book/open_flip2",
"minecraft:item/book/open_flip3"
],
"subtitle": "hexcasting.subtitles.scroll.scribble"
},
"impetus.fletcher.tick": {
"sounds": [