-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathHologramBlock.kt
166 lines (128 loc) · 5.92 KB
/
HologramBlock.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package spatialcrafting.hologram
import alexiil.mc.lib.attributes.AttributeList
import alexiil.mc.lib.attributes.AttributeProvider
import net.minecraft.block.*
import net.minecraft.block.piston.PistonBehavior
import net.minecraft.entity.EntityContext
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.inventory.SidedInventory
import net.minecraft.state.StateFactory
import net.minecraft.state.property.BooleanProperty
import net.minecraft.util.Hand
import net.minecraft.util.hit.BlockHitResult
import net.minecraft.util.math.BlockPos
import net.minecraft.util.shape.VoxelShape
import net.minecraft.util.shape.VoxelShapes
import net.minecraft.world.BlockView
import net.minecraft.world.IWorld
import net.minecraft.world.World
import spatialcrafting.crafter.assertIs
import spatialcrafting.util.kotlinwrappers.Builders
import spatialcrafting.util.kotlinwrappers.isHoldingItemIn
import spatialcrafting.util.kotlinwrappers.setBlock
import spatialcrafting.util.logDebug
private const val Unbreakable = -1.0f
private const val Indestructible = 3600000.0f
private val HologramSettings = Builders.blockSettings(
collidable = false,
materialColor = MaterialColor.WHITE,
blocksLight = false,
blocksMovement = false,
burnable = false,
hardness = Unbreakable,
resistance = Indestructible,
isLiquid = false,
isSolid = false,
pistonBehavior = PistonBehavior.IGNORE,
replaceable = false
)
val IsHidden: BooleanProperty = BooleanProperty.of("is_hidden")
object HologramBlock : Block(HologramSettings), BlockEntityProvider, AttributeProvider, InventoryProvider {
override fun getInventory(blockState: BlockState?, world: IWorld, pos: BlockPos): SidedInventory {
return HologramInventoryWrapper(world.getHologramEntity(pos).inventory)
}
override fun addAllAttributes(
world: World,
pos: BlockPos,
state: BlockState,
to: AttributeList<*>
) {
world.getBlockEntity(pos).let {
if (it is HologramBlockEntity) {
it.registerInventory(to)
}
}
}
// This must be set to false to make be able to remove an hologram
override fun createBlockEntity(var1: BlockView?) = HologramBlockEntity()
override fun appendProperties(stateFactory: StateFactory.Builder<Block, BlockState>) {
stateFactory.add(IsHidden)
}
init {
defaultState = stateFactory.defaultState.with(IsHidden, false)
}
override fun getRenderLayer(): BlockRenderLayer {
return BlockRenderLayer.TRANSLUCENT
}
override fun getOutlineShape(blockState: BlockState, blockView_1: BlockView?, blockPos_1: BlockPos?, entityContext_1: EntityContext?): VoxelShape {
return if (blockState.get(IsHidden)) VoxelShapes.empty()
else super.getOutlineShape(blockState, blockView_1, blockPos_1, entityContext_1)
}
override fun getRenderType(blockState: BlockState): BlockRenderType {
return if (blockState.get(IsHidden)) BlockRenderType.INVISIBLE else super.getRenderType(blockState)
}
override fun activate(blockState: BlockState, world: World, pos: BlockPos, player: PlayerEntity?, hand: Hand?, blockHitResult_1: BlockHitResult?): Boolean {
if (player == null || hand == null) return false
val hologramEntity = world.getHologramEntity(pos)
if (player.isHoldingItemIn(hand)) {
if (hologramEntity.isEmpty()) {
hologramEntity.insertItem(player.getStackInHand(hand))
if (!player.isCreative) player.getStackInHand(hand).count--
logDebug {
"Inserted item into hologram. New Content: " + hologramEntity.getItem()
}
}
}
return true
}
override fun onBroken(world: IWorld, pos: BlockPos, blockState: BlockState) {
// For creative mode
world.setBlock(HologramBlock, pos)
logDebug {
"Left Click on hologram in position $pos. Block Entity: ${world.getBlockEntity(pos)}"
}
super.onBroken(world, pos, blockState)
}
override fun onBreak(world: World, pos: BlockPos, blockState: BlockState?, player: PlayerEntity) {
// if(world.isServer) player.sendMessage("Pos = ${pos.xz}. BE: ${world.getBlockEntity(pos)?.let { "Not null" } ?: "NULL!!!"}")
val hologramEntity = world.getHologramEntity(pos)
// This is to make it so in creative mod you won't get unnecessary items. (onBlockRemoved is called afterwards)
val extractedItem = hologramEntity.extractItem()
// Cancel crafting if needed
if (!extractedItem.isEmpty) {
val multiblock = hologramEntity.getMultiblock()
multiblock.stopRecipeHelp(world)
multiblock.setNotCrafting(world)
// PlayerStream.watching(hologramEntity).sendPacket(Packets.CancelCraftingParticles(multiblock.crafterLocations[0]))
}
super.onBreak(world, pos, blockState, player)
}
override fun onBlockRemoved(stateBefore: BlockState, world: World, pos: BlockPos, stateAfter: BlockState, boolean_1: Boolean) {
// Only happens when the entire multiblock is destroyed or in creative mode.
if(stateBefore.block != stateAfter.block){
world.getHologramEntity(pos).dropInventory()
}
super.onBlockRemoved(stateBefore, world, pos, stateAfter, boolean_1)
}
override fun onBlockBreakStart(blockState: BlockState, world: World, pos: BlockPos, player: PlayerEntity?) {
giveItemInHologramToPlayer(player, world, pos)
}
private fun giveItemInHologramToPlayer(player: PlayerEntity?, world: World, pos: BlockPos) {
if (player == null) return
val itemInHologram = world.getHologramEntity(pos).extractItem()
player.giveItemStack(itemInHologram)
}
}
fun IWorld.getHologramEntity(pos: BlockPos): HologramBlockEntity {
return getBlockEntity(pos).assertIs(pos,this)
}