Skip to content

Commit 2b94c5c

Browse files
committed
Implement ADIotaHolder for SplicingTableBlockEntity to add support for Chronicler
1 parent b1d6449 commit 2b94c5c

File tree

2 files changed

+72
-24
lines changed

2 files changed

+72
-24
lines changed

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

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package gay.`object`.hexdebug.blocks.splicing
22

3+
import at.petrak.hexcasting.api.addldata.ADIotaHolder
4+
import at.petrak.hexcasting.api.block.HexBlockEntity
35
import at.petrak.hexcasting.api.casting.eval.ResolvedPatternType
6+
import at.petrak.hexcasting.api.casting.iota.Iota
47
import at.petrak.hexcasting.api.casting.iota.IotaType
8+
import at.petrak.hexcasting.api.casting.iota.ListIota
59
import at.petrak.hexcasting.api.casting.iota.PatternIota
610
import at.petrak.hexcasting.api.casting.math.HexPattern
711
import at.petrak.hexcasting.api.utils.extractMedia
@@ -29,20 +33,24 @@ import net.minecraft.world.entity.player.Inventory
2933
import net.minecraft.world.entity.player.Player
3034
import net.minecraft.world.inventory.SimpleContainerData
3135
import net.minecraft.world.item.ItemStack
32-
import net.minecraft.world.level.block.entity.BlockEntity
3336
import net.minecraft.world.level.block.state.BlockState
37+
import kotlin.math.max
3438
import kotlin.math.min
3539

36-
class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
37-
HexDebugBlockEntities.SPLICING_TABLE.value, pos, state
38-
), ISplicingTable, BaseContainer, MenuProvider {
40+
class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) :
41+
HexBlockEntity(HexDebugBlockEntities.SPLICING_TABLE.value, pos, state),
42+
ISplicingTable, BaseContainer, MenuProvider, ADIotaHolder
43+
{
3944
override val stacks = BaseContainer.withSize(SplicingTableItemSlot.container_size)
4045

4146
private var listStack by SplicingTableItemSlot.LIST.delegate
4247
private var clipboardStack by SplicingTableItemSlot.CLIPBOARD.delegate
4348
private var mediaStack by SplicingTableItemSlot.MEDIA.delegate
4449
private var staffStack by SplicingTableItemSlot.STAFF.delegate
4550

51+
private val listHolder get() = IXplatAbstractions.INSTANCE.findDataHolder(listStack)
52+
private val clipboardHolder get() = IXplatAbstractions.INSTANCE.findDataHolder(clipboardStack)
53+
4654
private val containerData = SimpleContainerData(SplicingTableDataSlot.size)
4755

4856
private var media by ContainerDataLongDelegate(
@@ -69,8 +77,7 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
6977
// TODO: save?
7078
private val undoStack = UndoStack()
7179

72-
override fun load(tag: CompoundTag) {
73-
super.load(tag)
80+
override fun loadModData(tag: CompoundTag) {
7481
ContainerHelper.loadAllItems(tag, stacks)
7582
media = tag.getLong("media")
7683
selection = Selection.fromRawIndices(
@@ -80,8 +87,7 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
8087
viewStartIndex = tag.getInt("viewStartIndex")
8188
}
8289

83-
override fun saveAdditional(tag: CompoundTag) {
84-
super.saveAdditional(tag)
90+
override fun saveModData(tag: CompoundTag) {
8591
ContainerHelper.saveAllItems(tag, stacks)
8692
tag.putLong("media", media)
8793
tag.putInt("selectionFrom", selection?.from ?: -1)
@@ -107,8 +113,8 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
107113
undoStack = undoStack,
108114
selection = selection,
109115
viewStartIndex = viewStartIndex,
110-
listHolder = IXplatAbstractions.INSTANCE.findDataHolder(listStack),
111-
clipboardHolder = IXplatAbstractions.INSTANCE.findDataHolder(clipboardStack),
116+
listHolder = listHolder,
117+
clipboardHolder = clipboardHolder,
112118
)
113119
}
114120

@@ -140,6 +146,8 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
140146
undoStack.clear()
141147
selection = null
142148
viewStartIndex = 0
149+
} else {
150+
(level as? ServerLevel)?.let { clampView(it, null) }
143151
}
144152
}
145153

@@ -158,6 +166,7 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
158166
override fun runAction(action: SplicingTableAction, player: ServerPlayer?) {
159167
if (media < mediaCost) return
160168
val data = getData(player) ?: return
169+
clampView(data.level, data)
161170
setupUndoStack(data)
162171
convertAndRun(action.value, data)
163172
}
@@ -176,6 +185,7 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
176185
val data = getData(player)
177186
?.let(ReadWriteList::convertOrNull)
178187
?: return ResolvedPatternType.ERRORED
188+
clampView(data.level, data)
179189
setupUndoStack(data)
180190
val result = drawPattern(pattern, data)
181191
postRunAction(data)
@@ -214,7 +224,7 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
214224
}
215225

216226
private fun selectIota(data: ReadList, index: Int, hasShiftDown: Boolean) {
217-
if (!data.isInRange(index)) return
227+
if (!isInRange(data.list, index)) return
218228

219229
val selection = selection
220230
this.selection = if (isOnlyIotaSelected(index)) {
@@ -231,7 +241,7 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
231241
}
232242

233243
private fun selectEdge(data: ReadList, index: Int, hasShiftDown: Boolean) {
234-
if (!isEdgeInRange(data, index)) return
244+
if (!isEdgeInRange(data.list, index)) return
235245

236246
val selection = selection
237247
this.selection = if (isEdgeSelected(index)) {
@@ -255,29 +265,57 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
255265
private fun isEdgeSelected(index: Int) =
256266
selection?.let { it.start == index && it.end == null } ?: false
257267

258-
private fun isEdgeInRange(data: ReadList, index: Int) =
268+
private fun isInRange(list: List<Iota>?, index: Int) =
269+
list?.let { index in it.indices } ?: false
270+
271+
private fun isEdgeInRange(list: List<Iota>, index: Int) =
259272
// cell to the right is in range
260-
data.isInRange(index)
273+
isInRange(list, index)
261274
// cell to the left is in range
262-
|| data.isInRange(index - 1)
275+
|| isInRange(list, index - 1)
263276
// allow selecting leftmost edge of empty list
264-
|| (index == 0 && data.list.size == 0)
277+
|| (index == 0 && list.isEmpty())
265278

266279
private fun postRunAction(data: SplicingTableData) {
267280
selection = data.selection
268-
269-
// if there is no list, or the list is too short to fill the screen, set the start index to 0
270-
// otherwise, clamp the start index such that the end index stays in range
271-
val lastIndex = data.list?.lastIndex ?: 0
272-
val maxStartIndex = lastIndex - VIEW_END_INDEX_OFFSET
273-
viewStartIndex = if (maxStartIndex > 0) data.viewStartIndex.coerceIn(0, maxStartIndex) else 0
281+
viewStartIndex = data.viewStartIndex
282+
clampView(data.level, data)
274283

275284
if (data.shouldConsumeMedia) {
276285
media = (media - mediaCost).coerceIn(0, maxMedia)
277286
refillMedia()
278287
}
279288
}
280289

290+
private fun clampView(level: ServerLevel, data: SplicingTableData?) {
291+
val list = if (data != null) {
292+
data.list
293+
} else {
294+
listHolder?.let { it.readIota(level) as? ListIota }?.list?.toMutableList()
295+
}
296+
297+
if (list != null) {
298+
val lastIndex = list.lastIndex
299+
val maxStartIndex = max(0, lastIndex - VIEW_END_INDEX_OFFSET)
300+
301+
// TODO: gracefully degrade rather than just wiping the whole selection?
302+
when (val selection = selection) {
303+
is Selection.Range -> if (!isInRange(list, selection.end)) {
304+
this.selection = null
305+
}
306+
is Selection.Edge -> if (!isEdgeInRange(list, selection.index)) {
307+
this.selection = null
308+
}
309+
null -> {}
310+
}
311+
312+
viewStartIndex = viewStartIndex.coerceIn(0, maxStartIndex)
313+
} else {
314+
selection = null
315+
viewStartIndex = 0
316+
}
317+
}
318+
281319
private fun refillMedia() {
282320
val mediaHolder = IXplatAbstractions.INSTANCE.findMediaHolder(mediaStack) ?: return
283321
while (media < maxMedia) {
@@ -294,6 +332,18 @@ class SplicingTableBlockEntity(pos: BlockPos, state: BlockState) : BlockEntity(
294332
}
295333
}
296334

335+
override fun readIotaTag() = listHolder?.readIotaTag()
336+
337+
override fun writeIota(iota: Iota?, simulate: Boolean): Boolean {
338+
val success = listHolder?.writeIota(iota, simulate) ?: false
339+
if (!simulate && success) {
340+
sync()
341+
}
342+
return success
343+
}
344+
345+
override fun writeable() = listHolder?.writeable() ?: false
346+
297347
companion object {
298348
private val config get() = HexDebugConfig.server
299349

Common/src/main/kotlin/gay/object/hexdebug/splicing/SplicingTableData.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ open class SplicingTableData(
6363
viewStartIndex = value - VIEW_END_INDEX_OFFSET
6464
}
6565

66-
fun isInRange(index: Int) = list?.let { index in it.indices } ?: false
67-
6866
fun pushUndoState(
6967
list: Option<List<Iota>> = None(),
7068
clipboard: Option<Iota?> = None(),

0 commit comments

Comments
 (0)