Skip to content

Commit e56c02e

Browse files
committed
Implement splicing table read/write actions
1 parent 2b94c5c commit e56c02e

File tree

12 files changed

+369
-21
lines changed

12 files changed

+369
-21
lines changed

Common/src/main/kotlin/gay/object/hexdebug/blocks/splicing/SplicingTableBlockEntity.kt

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import net.minecraft.world.entity.player.Inventory
3333
import net.minecraft.world.entity.player.Player
3434
import net.minecraft.world.inventory.SimpleContainerData
3535
import net.minecraft.world.item.ItemStack
36+
import net.minecraft.world.level.Level
3637
import net.minecraft.world.level.block.state.BlockState
3738
import kotlin.math.max
3839
import kotlin.math.min
@@ -49,7 +50,7 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) :
4950
private var staffStack by SplicingTableItemSlot.STAFF.delegate
5051

5152
private val listHolder get() = IXplatAbstractions.INSTANCE.findDataHolder(listStack)
52-
private val clipboardHolder get() = IXplatAbstractions.INSTANCE.findDataHolder(clipboardStack)
53+
val clipboardHolder get() = IXplatAbstractions.INSTANCE.findDataHolder(clipboardStack)
5354

5455
private val containerData = SimpleContainerData(SplicingTableDataSlot.size)
5556

@@ -61,22 +62,39 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) :
6162
index3 = SplicingTableDataSlot.MEDIA_3.index,
6263
)
6364

64-
private var selection by ContainerDataSelectionDelegate(
65+
var selection by ContainerDataSelectionDelegate(
6566
containerData,
6667
fromIndex = SplicingTableDataSlot.SELECTION_FROM.index,
6768
toIndex = SplicingTableDataSlot.SELECTION_TO.index,
6869
)
70+
private set
6971

70-
private var viewStartIndex by ContainerDataDelegate(
72+
var viewStartIndex by ContainerDataDelegate(
7173
containerData,
7274
index = SplicingTableDataSlot.VIEW_START_INDEX.index,
7375
)
76+
private set
7477

7578
val analogOutputSignal get() = if (!listStack.isEmpty) 15 else 0
7679

7780
// TODO: save?
7881
private val undoStack = UndoStack()
7982

83+
fun getList(level: ServerLevel) =
84+
listHolder?.let { it.readIota(level) as? ListIota }?.list
85+
86+
// for use by actions
87+
// can't be called setSelection because that conflicts with the property setter
88+
fun writeSelection(selection: Selection?) {
89+
this.selection = selection
90+
clampView(level)
91+
}
92+
93+
fun writeViewStartIndex(viewStartIndex: Int) {
94+
this.viewStartIndex = viewStartIndex
95+
clampView(level)
96+
}
97+
8098
override fun loadModData(tag: CompoundTag) {
8199
ContainerHelper.loadAllItems(tag, stacks)
82100
media = tag.getLong("media")
@@ -147,7 +165,7 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) :
147165
selection = null
148166
viewStartIndex = 0
149167
} else {
150-
(level as? ServerLevel)?.let { clampView(it, null) }
168+
clampView(level)
151169
}
152170
}
153171

@@ -287,11 +305,15 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) :
287305
}
288306
}
289307

308+
private fun clampView(level: Level?) {
309+
(level as? ServerLevel)?.let { clampView(it, null) }
310+
}
311+
290312
private fun clampView(level: ServerLevel, data: SplicingTableData?) {
291313
val list = if (data != null) {
292314
data.list
293315
} else {
294-
listHolder?.let { it.readIota(level) as? ListIota }?.list?.toMutableList()
316+
getList(level)?.toMutableList()
295317
}
296318

297319
if (list != null) {
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package gay.`object`.hexdebug.casting.actions.splicing
2+
3+
import at.petrak.hexcasting.api.casting.castables.ConstMediaAction
4+
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
5+
import at.petrak.hexcasting.api.casting.getBlockPos
6+
import at.petrak.hexcasting.api.casting.iota.Iota
7+
import at.petrak.hexcasting.api.casting.mishaps.MishapBadBlock
8+
import gay.`object`.hexdebug.blocks.splicing.SplicingTableBlockEntity
9+
10+
object OpReadClipboard : ConstMediaAction {
11+
override val argc = 1
12+
13+
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
14+
val pos = args.getBlockPos(0, OpReadSelection.argc)
15+
env.assertPosInRange(pos)
16+
17+
val table = env.world.getBlockEntity(pos) as? SplicingTableBlockEntity
18+
?: throw MishapBadBlock.of(pos, "splicing_table")
19+
20+
val clipboardHolder = table.clipboardHolder
21+
?: throw MishapBadBlock.of(pos, "splicing_table.clipboard.read")
22+
23+
val datum = clipboardHolder.readIota(env.world)
24+
?: clipboardHolder.emptyIota()
25+
?: throw MishapBadBlock.of(pos, "splicing_table.clipboard.read")
26+
27+
return listOf(datum)
28+
}
29+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package gay.`object`.hexdebug.casting.actions.splicing
2+
3+
import at.petrak.hexcasting.api.casting.castables.ConstMediaAction
4+
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
5+
import at.petrak.hexcasting.api.casting.getBlockPos
6+
import at.petrak.hexcasting.api.casting.iota.DoubleIota
7+
import at.petrak.hexcasting.api.casting.iota.Iota
8+
import at.petrak.hexcasting.api.casting.mishaps.MishapBadBlock
9+
import at.petrak.hexcasting.api.casting.orNull
10+
import gay.`object`.hexdebug.blocks.splicing.SplicingTableBlockEntity
11+
12+
object OpReadSelection : ConstMediaAction {
13+
override val argc = 1
14+
15+
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
16+
val pos = args.getBlockPos(0, argc)
17+
env.assertPosInRange(pos)
18+
19+
val table = env.world.getBlockEntity(pos) as? SplicingTableBlockEntity
20+
?: throw MishapBadBlock.of(pos, "splicing_table")
21+
22+
return listOf(
23+
table.selection?.start.doubleOrNull(),
24+
table.selection?.end?.plus(1).doubleOrNull(), // return the exclusive end index
25+
)
26+
}
27+
}
28+
29+
private fun Int?.doubleOrNull() = this?.let { DoubleIota(it.toDouble()) }.orNull()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package gay.`object`.hexdebug.casting.actions.splicing
2+
3+
import at.petrak.hexcasting.api.casting.asActionResult
4+
import at.petrak.hexcasting.api.casting.castables.ConstMediaAction
5+
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
6+
import at.petrak.hexcasting.api.casting.getBlockPos
7+
import at.petrak.hexcasting.api.casting.iota.Iota
8+
import at.petrak.hexcasting.api.casting.mishaps.MishapBadBlock
9+
import gay.`object`.hexdebug.blocks.splicing.SplicingTableBlockEntity
10+
11+
object OpReadViewIndex : ConstMediaAction {
12+
override val argc = 1
13+
14+
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
15+
val pos = args.getBlockPos(0, OpReadSelection.argc)
16+
env.assertPosInRange(pos)
17+
18+
val table = env.world.getBlockEntity(pos) as? SplicingTableBlockEntity
19+
?: throw MishapBadBlock.of(pos, "splicing_table")
20+
21+
return table.viewStartIndex.asActionResult
22+
}
23+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package gay.`object`.hexdebug.casting.actions.splicing
2+
3+
import at.petrak.hexcasting.api.casting.asActionResult
4+
import at.petrak.hexcasting.api.casting.castables.ConstMediaAction
5+
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
6+
import at.petrak.hexcasting.api.casting.getBlockPos
7+
import at.petrak.hexcasting.api.casting.iota.Iota
8+
import gay.`object`.hexdebug.blocks.splicing.SplicingTableBlockEntity
9+
10+
object OpReadableClipboard : ConstMediaAction {
11+
override val argc = 1
12+
13+
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
14+
val pos = args.getBlockPos(0, OpReadSelection.argc)
15+
env.assertPosInRange(pos)
16+
17+
val table = env.world.getBlockEntity(pos) as? SplicingTableBlockEntity
18+
?: return false.asActionResult
19+
20+
val clipboardHolder = table.clipboardHolder
21+
?: return false.asActionResult
22+
23+
clipboardHolder.readIota(env.world)
24+
?: clipboardHolder.emptyIota()
25+
?: return false.asActionResult
26+
27+
return true.asActionResult
28+
}
29+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package gay.`object`.hexdebug.casting.actions.splicing
2+
3+
import at.petrak.hexcasting.api.casting.asActionResult
4+
import at.petrak.hexcasting.api.casting.castables.ConstMediaAction
5+
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
6+
import at.petrak.hexcasting.api.casting.getBlockPos
7+
import at.petrak.hexcasting.api.casting.iota.Iota
8+
import gay.`object`.hexdebug.blocks.splicing.SplicingTableBlockEntity
9+
10+
object OpWritableClipboard : ConstMediaAction {
11+
override val argc = 1
12+
13+
override fun execute(args: List<Iota>, env: CastingEnvironment): List<Iota> {
14+
val pos = args.getBlockPos(0, OpReadSelection.argc)
15+
env.assertPosInRange(pos)
16+
17+
val table = env.world.getBlockEntity(pos) as? SplicingTableBlockEntity
18+
?: return false.asActionResult
19+
20+
val clipboardHolder = table.clipboardHolder
21+
?: return false.asActionResult
22+
23+
return clipboardHolder.writeable().asActionResult
24+
}
25+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package gay.`object`.hexdebug.casting.actions.splicing
2+
3+
import at.petrak.hexcasting.api.addldata.ADIotaHolder
4+
import at.petrak.hexcasting.api.casting.ParticleSpray
5+
import at.petrak.hexcasting.api.casting.RenderedSpell
6+
import at.petrak.hexcasting.api.casting.castables.SpellAction
7+
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
8+
import at.petrak.hexcasting.api.casting.getBlockPos
9+
import at.petrak.hexcasting.api.casting.iota.Iota
10+
import at.petrak.hexcasting.api.casting.mishaps.MishapBadBlock
11+
import at.petrak.hexcasting.api.casting.mishaps.MishapOthersName
12+
import gay.`object`.hexdebug.blocks.splicing.SplicingTableBlockEntity
13+
import net.minecraft.world.phys.Vec3
14+
15+
object OpWriteClipboard : SpellAction {
16+
override val argc = 2
17+
18+
override fun execute(args: List<Iota>, env: CastingEnvironment): SpellAction.Result {
19+
val pos = args.getBlockPos(0, OpReadSelection.argc)
20+
val datum = args[1]
21+
22+
env.assertPosInRangeForEditing(pos)
23+
24+
val table = env.world.getBlockEntity(pos) as? SplicingTableBlockEntity
25+
?: throw MishapBadBlock.of(pos, "splicing_table")
26+
27+
val clipboardHolder = table.clipboardHolder
28+
?: throw MishapBadBlock.of(pos, "splicing_table.clipboard.write")
29+
30+
if (!clipboardHolder.writeIota(datum, true)) {
31+
throw MishapBadBlock.of(pos, "splicing_table.clipboard.write")
32+
}
33+
34+
MishapOthersName.getTrueNameFromDatum(datum, null)?.let {
35+
throw MishapOthersName(it)
36+
}
37+
38+
return SpellAction.Result(
39+
Spell(clipboardHolder, datum),
40+
0,
41+
listOf(ParticleSpray(pos.center, Vec3(1.0, 0.0, 0.0), 0.25, 3.14, 40))
42+
)
43+
}
44+
45+
private data class Spell(val clipboardHolder: ADIotaHolder, val datum: Iota) : RenderedSpell {
46+
override fun cast(env: CastingEnvironment) {
47+
clipboardHolder.writeIota(datum, false)
48+
}
49+
}
50+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package gay.`object`.hexdebug.casting.actions.splicing
2+
3+
import at.petrak.hexcasting.api.casting.ParticleSpray
4+
import at.petrak.hexcasting.api.casting.RenderedSpell
5+
import at.petrak.hexcasting.api.casting.castables.SpellAction
6+
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
7+
import at.petrak.hexcasting.api.casting.getBlockPos
8+
import at.petrak.hexcasting.api.casting.iota.Iota
9+
import at.petrak.hexcasting.api.casting.mishaps.MishapBadBlock
10+
import gay.`object`.hexdebug.blocks.splicing.SplicingTableBlockEntity
11+
import gay.`object`.hexdebug.splicing.Selection
12+
import gay.`object`.hexdebug.utils.getPositiveIntOrNull
13+
import net.minecraft.world.phys.Vec3
14+
import kotlin.math.max
15+
import kotlin.math.min
16+
17+
object OpWriteSelection : SpellAction {
18+
override val argc = 3
19+
20+
override fun execute(args: List<Iota>, env: CastingEnvironment): SpellAction.Result {
21+
val pos = args.getBlockPos(0, argc)
22+
val from = args.getPositiveIntOrNull(1, argc)
23+
val to = args.getPositiveIntOrNull(2, argc)
24+
25+
env.assertPosInRangeForEditing(pos)
26+
27+
val table = env.world.getBlockEntity(pos) as? SplicingTableBlockEntity
28+
?: throw MishapBadBlock.of(pos, "splicing_table")
29+
30+
// both null: remove selection
31+
// to null: select edge
32+
// neither null: select range (convert end index to inclusive)
33+
val selection = when {
34+
from == null -> null
35+
to == null -> Selection.edge(from)
36+
else -> Selection.range(min(from, to), max(from, to) - 1)
37+
}
38+
39+
return SpellAction.Result(
40+
Spell(table, selection),
41+
0,
42+
listOf(ParticleSpray(pos.center, Vec3(1.0, 0.0, 0.0), 0.25, 3.14, 40))
43+
)
44+
}
45+
46+
private data class Spell(val table: SplicingTableBlockEntity, val selection: Selection?) : RenderedSpell {
47+
override fun cast(env: CastingEnvironment) {
48+
table.writeSelection(selection)
49+
}
50+
}
51+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package gay.`object`.hexdebug.casting.actions.splicing
2+
3+
import at.petrak.hexcasting.api.casting.ParticleSpray
4+
import at.petrak.hexcasting.api.casting.RenderedSpell
5+
import at.petrak.hexcasting.api.casting.castables.SpellAction
6+
import at.petrak.hexcasting.api.casting.eval.CastingEnvironment
7+
import at.petrak.hexcasting.api.casting.getBlockPos
8+
import at.petrak.hexcasting.api.casting.getPositiveInt
9+
import at.petrak.hexcasting.api.casting.iota.Iota
10+
import at.petrak.hexcasting.api.casting.mishaps.MishapBadBlock
11+
import gay.`object`.hexdebug.blocks.splicing.SplicingTableBlockEntity
12+
import net.minecraft.world.phys.Vec3
13+
14+
object OpWriteViewIndex : SpellAction {
15+
override val argc = 2
16+
17+
override fun execute(args: List<Iota>, env: CastingEnvironment): SpellAction.Result {
18+
val pos = args.getBlockPos(0, argc)
19+
val index = args.getPositiveInt(1, argc)
20+
21+
env.assertPosInRangeForEditing(pos)
22+
23+
val table = env.world.getBlockEntity(pos) as? SplicingTableBlockEntity
24+
?: throw MishapBadBlock.of(pos, "splicing_table")
25+
26+
return SpellAction.Result(
27+
Spell(table, index),
28+
0,
29+
listOf(ParticleSpray(pos.center, Vec3(1.0, 0.0, 0.0), 0.25, 3.14, 40))
30+
)
31+
}
32+
33+
private data class Spell(val table: SplicingTableBlockEntity, val index: Int) : RenderedSpell {
34+
override fun cast(env: CastingEnvironment) {
35+
table.writeViewStartIndex(index)
36+
}
37+
}
38+
}

Common/src/main/kotlin/gay/object/hexdebug/registry/HexDebugActions.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import at.petrak.hexcasting.common.lib.hex.HexActions
1212
import gay.`object`.hexdebug.casting.actions.OpBreakpoint
1313
import gay.`object`.hexdebug.casting.actions.OpIsDebugging
1414
import gay.`object`.hexdebug.casting.actions.OpNextEvalIndex
15+
import gay.`object`.hexdebug.casting.actions.splicing.*
1516
import gay.`object`.hexdebug.casting.iotas.CognitohazardIota
1617

18+
@Suppress("unused")
1719
object HexDebugActions : HexDebugRegistrar<ActionRegistryEntry>(HexRegistries.ACTION, { HexActions.REGISTRY }) {
1820
val COGNITOHAZARD = make("const/cognitohazard", HexDir.NORTH_WEST, "wdeaqqdqeedqadqeedqaeadeaqqeadeaqqdqdeaqqeaeedqaw") {
1921
Action.makeConstantOp(CognitohazardIota())
@@ -29,6 +31,19 @@ object HexDebugActions : HexDebugRegistrar<ActionRegistryEntry>(HexRegistries.AC
2931
OpMakePackagedSpell(HexDebugItems.DEBUGGER.value as ItemPackagedHex, 10 * MediaConstants.CRYSTAL_UNIT)
3032
}
3133

34+
// splicing table
35+
36+
val READ_SELECTION = make("splicing/selection/read", HexDir.NORTH_WEST, "wqaeaqweeeedq", OpReadSelection)
37+
val WRITE_SELECTION = make("splicing/selection/write", HexDir.SOUTH_WEST, "wedqdewqqqqae", OpWriteSelection)
38+
39+
val READ_VIEW_INDEX = make("splicing/view_index/read", HexDir.NORTH_WEST, "wqaeaqwdwaqaw", OpReadViewIndex)
40+
val WRITE_VIEW_INDEX = make("splicing/view_index/write", HexDir.SOUTH_WEST, "wedqdewawdedw", OpWriteViewIndex)
41+
42+
val READ_CLIPBOARD = make("splicing/clipboard/read", HexDir.NORTH_WEST, "wqaeaqweeeedw", OpReadClipboard)
43+
val WRITE_CLIPBOARD = make("splicing/clipboard/write", HexDir.SOUTH_WEST, "wedqdewqqqqaw", OpWriteClipboard)
44+
val READABLE_CLIPBOARD = make("splicing/clipboard/readable", HexDir.NORTH_WEST, "wqaeaqweeeedww", OpReadableClipboard)
45+
val WRITABLE_CLIPBOARD = make("splicing/clipboard/writable", HexDir.SOUTH_WEST, "wedqdewqqqqaww", OpWritableClipboard)
46+
3247
private fun make(name: String, startDir: HexDir, signature: String, action: Action) =
3348
make(name, startDir, signature) { action }
3449

0 commit comments

Comments
 (0)