Skip to content

Commit 5acf196

Browse files
authored
Merge pull request #129 from pylonmc/idras-random-fixes
Idras random fixes
2 parents 6a7bc51 + e41eaec commit 5acf196

13 files changed

Lines changed: 141 additions & 27 deletions

File tree

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/BlockListener.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ internal object BlockListener : Listener {
4949
val pylonItem = PylonItem.fromStack(item)
5050
val context = BlockCreateContext.PlayerPlace(player, item)
5151

52-
val pylonBlock = pylonItem?.schema?.place(context, event.block)
52+
val pylonBlock = pylonItem?.place(context, event.block)
5353
if (pylonItem != null && pylonBlock == null) {
5454
event.isCancelled = true
5555
}

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/BlockStorage.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,10 @@ object BlockStorage : Listener {
184184
val schema = PylonRegistry.BLOCKS[key]
185185
require(schema != null) { "Block $key does not exist" }
186186

187+
if (context !is BlockCreateContext.PlayerPlace) {
188+
blockPosition.block.type = schema.material
189+
}
190+
187191
@Suppress("UNCHECKED_CAST") // The cast will work - this is checked in the schema constructor
188192
val block = schema.create(blockPosition.block, context)
189193
val event = PrePylonBlockPlaceEvent(blockPosition.block, block, context)

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/PylonBlock.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,14 @@ open class PylonBlock protected constructor(val block: Block) {
6767

6868
private val wailaWarningsSupressed: MutableSet<NamespacedKey> = mutableSetOf()
6969

70-
fun checkWaila(schema: PylonBlockSchema) {
70+
private fun checkWaila(schema: PylonBlockSchema) {
7171
val translator = AddonTranslator.translators[schema.addon]
7272
check(translator != null) {
7373
"Addon does not have a translator; did you forget to call registerWithPylon()?"
7474
}
7575

76-
7776
for (locale in schema.addon.languages) {
78-
val translationKey = "pylon.${schema.key.namespace}.block.${schema.key.key}"
77+
val translationKey = "pylon.${schema.key.namespace}.item.${schema.key.key}.waila"
7978
if (!translator.translationKeyExists(translationKey, locale)) {
8079
PylonCore.logger.warning("${schema.key.namespace} is missing a WAILA translation key for block ${schema.key} (locale: ${locale.displayName} | expected translation key: $translationKey")
8180
}
@@ -152,6 +151,7 @@ open class PylonBlock protected constructor(val block: Block) {
152151
PylonCore.logger.severe("Error while loading block $key at $position")
153152
t.printStackTrace()
154153
return if (key != null && position != null) {
154+
PylonBlockSchema.schemaCache[position] = PhantomBlock.schema
155155
PhantomBlock(pdc, key, position.block)
156156
} else {
157157
null

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/TickManager.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import kotlinx.coroutines.Job
1616
import kotlinx.coroutines.cancel
1717
import kotlinx.coroutines.delay
1818
import kotlinx.coroutines.withContext
19+
import org.bukkit.Bukkit
1920
import org.bukkit.Color.RED
2021
import org.bukkit.entity.BlockDisplay
2122
import org.bukkit.event.EventHandler
@@ -93,7 +94,9 @@ object TickManager : Listener {
9394
display.glowColorOverride = RED
9495
display.isGlowing = true
9596
pylonBlock.errorBlock = display
97+
}
9698

99+
if (errors >= PylonConfig.allowedBlockErrors) {
97100
cancel()
98101
}
99102
}

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/block/base/PylonFluidBlock.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ interface PylonFluidBlock {
88
* Returns a map of fluid types - and their corresponding amounts - that can be supplied by
99
* a particular connection point. deltaSeconds is the time since the last fluid tick.
1010
*
11-
* This is per tick, so if you have a machine that can supply up to 100 fluid per second,
12-
* it should supply 100 of that fluid
11+
* If you have a machine that can supply up to 100 fluid per second, it should supply
12+
* 100*deltaSeconds of that fluid
1313
*
1414
* Any implementation of this method must NEVER call the same method for another connection
1515
* point, otherwise you risk creating infinite loops.
@@ -21,8 +21,8 @@ interface PylonFluidBlock {
2121
* a particular connection point. For example, a tank should request enough fluid to fill up
2222
* to capacity.
2323
*
24-
* This is per second, so if you have a machine that consumes 100 fluid per second,
25-
* it should request 100 of that fluid
24+
* If you have a machine that consumes 100 fluid per second, it should request
25+
* 100*deltaSeconds of that fluid
2626
*
2727
* Any implementation of this method must NEVER call the same method for another connection
2828
* point, otherwise you risk creating infinite loops.

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/entity/EntityStorage.kt

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import org.bukkit.event.world.EntitiesLoadEvent
2121
import java.util.UUID
2222
import java.util.concurrent.ConcurrentHashMap
2323
import java.util.concurrent.locks.ReentrantReadWriteLock
24+
import java.util.function.Consumer
2425
import kotlin.random.Random
2526

2627

@@ -29,6 +30,7 @@ object EntityStorage : Listener {
2930
private val entities: MutableMap<UUID, PylonEntity<*>> = ConcurrentHashMap()
3031
private val entitiesByKey: MutableMap<NamespacedKey, MutableSet<PylonEntity<*>>> = ConcurrentHashMap()
3132
private val entityAutosaveTasks: MutableMap<UUID, Job> = ConcurrentHashMap()
33+
private val whenEntityLoadsTasks: MutableMap<UUID, MutableSet<Consumer<PylonEntity<*>>>> = ConcurrentHashMap()
3234

3335
val loadedEntities: Collection<PylonEntity<*>>
3436
get() = entities.values
@@ -64,6 +66,7 @@ object EntityStorage : Listener {
6466
inline fun <reified T> getAs(entity: Entity): T?
6567
= getAs(T::class.java, entity)
6668

69+
@JvmStatic
6770
fun getByKey(key: NamespacedKey): Collection<PylonEntity<*>> =
6871
if (key in PylonRegistry.ENTITIES) {
6972
lockEntityRead {
@@ -73,6 +76,47 @@ object EntityStorage : Listener {
7376
emptySet()
7477
}
7578

79+
/**
80+
* Schedules a task to run when the entity with id [uuid] is loaded, or runs the task immediately
81+
* if the entity is already loaded
82+
*/
83+
@JvmStatic
84+
fun whenEntityLoads(uuid: UUID, consumer: Consumer<PylonEntity<*>>) {
85+
val pylonEntity = get(uuid)
86+
if (pylonEntity != null) {
87+
consumer.accept(pylonEntity)
88+
} else {
89+
whenEntityLoadsTasks.getOrPut(uuid) { mutableSetOf() }.add {
90+
consumer.accept(it)
91+
}
92+
}
93+
94+
}
95+
96+
/**
97+
* Schedules a task to run when the entity with id [uuid] is loaded, or runs the task immediately
98+
* if the entity is already loaded
99+
*/
100+
@JvmStatic
101+
fun <T: PylonEntity<*>> whenEntityLoads(uuid: UUID, clazz: Class<T>, consumer: Consumer<T>) {
102+
val pylonEntity = getAs(clazz, uuid)
103+
if (pylonEntity != null) {
104+
consumer.accept(pylonEntity)
105+
} else {
106+
whenEntityLoadsTasks.getOrPut(uuid) { mutableSetOf() }.add {
107+
consumer.accept(getAs(clazz, uuid) ?: throw IllegalStateException("Entity $uuid was not of expected type ${clazz.simpleName}"))
108+
}
109+
}
110+
}
111+
112+
/**
113+
* Schedules a task to run when the entity with id [uuid] is loaded, or runs the task immediately
114+
* if the entity is already loaded
115+
*/
116+
@JvmStatic
117+
inline fun <reified T: PylonEntity<*>> whenEntityLoads(uuid: UUID, crossinline consumer: (T) -> Unit)
118+
= whenEntityLoads(uuid, T::class.java) { t -> consumer(t) }
119+
76120
@JvmStatic
77121
fun isPylonEntity(uuid: UUID): Boolean
78122
= get(uuid) != null
@@ -108,6 +152,19 @@ object EntityStorage : Listener {
108152
for (entity in event.entities) {
109153
val pylonEntity = PylonEntity.deserialize(entity) ?: continue
110154
add(pylonEntity)
155+
156+
val tasks = whenEntityLoadsTasks[pylonEntity.uuid]
157+
if (tasks != null) {
158+
for (task in tasks) {
159+
try {
160+
task.accept(pylonEntity)
161+
} catch (t: Throwable) {
162+
t.printStackTrace()
163+
}
164+
}
165+
whenEntityLoadsTasks.remove(pylonEntity.uuid)
166+
}
167+
111168
PylonEntityLoadEvent(pylonEntity).callEvent()
112169
}
113170
}

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/entity/display/BlockDisplayBuilder.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class BlockDisplayBuilder() {
1717
private var blockData: BlockData? = null
1818
private var transformation: Matrix4f? = null
1919
private var glowColor: Color? = null
20-
private var brightness: Int? = null
20+
private var brightness: Brightness? = null
2121
private var viewRange: Float? = null
2222
private var interpolationDelay: Int? = null
2323
private var interpolationDuration: Int? = null
@@ -41,7 +41,8 @@ class BlockDisplayBuilder() {
4141
fun blockData(blockData: BlockData?): BlockDisplayBuilder = apply { this.blockData = blockData }
4242
fun transformation(transformation: Matrix4f?): BlockDisplayBuilder = apply { this.transformation = transformation }
4343
fun transformation(builder: TransformBuilder): BlockDisplayBuilder = apply { this.transformation = builder.buildForBlockDisplay() }
44-
fun brightness(brightness: Int): BlockDisplayBuilder = apply { this.brightness = brightness }
44+
fun brightness(brightness: Brightness): BlockDisplayBuilder = apply { this.brightness = brightness }
45+
fun brightness(brightness: Int): BlockDisplayBuilder = brightness(Brightness(0, brightness))
4546
fun glow(glowColor: Color?): BlockDisplayBuilder = apply { this.glowColor = glowColor }
4647
fun viewRange(viewRange: Float): BlockDisplayBuilder = apply { this.viewRange = viewRange }
4748
fun interpolationDelay(interpolationDelay: Int): BlockDisplayBuilder = apply { this.interpolationDelay = interpolationDelay }
@@ -69,7 +70,7 @@ class BlockDisplayBuilder() {
6970
display.glowColorOverride = glowColor
7071
}
7172
if (brightness != null) {
72-
display.brightness = Brightness(brightness!!, 0)
73+
display.brightness = brightness
7374
}
7475
if (viewRange != null) {
7576
display.viewRange = viewRange!!

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/entity/display/ItemDisplayBuilder.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class ItemDisplayBuilder() {
1717

1818
var itemStack: ItemStack? = null
1919
var transformation: Matrix4f? = null
20-
var brightness: Int? = null
20+
var brightness: Brightness? = null
2121
var glowColor: Color? = null
2222
var billboard: Display.Billboard? = null
2323
var viewRange: Float? = null
@@ -39,7 +39,8 @@ class ItemDisplayBuilder() {
3939
fun itemStack(itemStack: ItemStack?): ItemDisplayBuilder = apply { this.itemStack = itemStack }
4040
fun transformation(transformation: Matrix4f?): ItemDisplayBuilder = apply { this.transformation = transformation }
4141
fun transformation(builder: TransformBuilder): ItemDisplayBuilder = apply { this.transformation = builder.buildForItemDisplay() }
42-
fun brightness(brightness: Int): ItemDisplayBuilder = apply { this.brightness = brightness }
42+
fun brightness(brightness: Brightness): ItemDisplayBuilder = apply { this.brightness = brightness }
43+
fun brightness(brightness: Int): ItemDisplayBuilder = brightness(Brightness(0, brightness))
4344
fun glow(glowColor: Color?): ItemDisplayBuilder = apply { this.glowColor = glowColor }
4445
fun billboard(billboard: Billboard?): ItemDisplayBuilder = apply { this.billboard = billboard }
4546
fun viewRange(viewRange: Float): ItemDisplayBuilder = apply { this.viewRange = viewRange }
@@ -68,7 +69,7 @@ class ItemDisplayBuilder() {
6869
display.glowColorOverride = glowColor
6970
}
7071
if (brightness != null) {
71-
display.brightness = Brightness(brightness!!, 0)
72+
display.brightness = brightness
7273
}
7374
if (billboard != null) {
7475
display.billboard = billboard!!

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/entity/display/TextDisplayBuilder.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class TextDisplayBuilder() {
1616

1717
private var text: Component? = null
1818
private var transformation: Matrix4f? = null
19-
private var brightness: Int? = null
19+
private var brightness: Brightness? = null
2020
private var glowColor: Color? = null
2121
private var viewRange: Float? = null
2222
private var billboard: Billboard? = null
@@ -42,7 +42,8 @@ class TextDisplayBuilder() {
4242
fun text(text: Component?): TextDisplayBuilder = apply { this.text = text }
4343
fun transformation(transformation: Matrix4f?): TextDisplayBuilder = apply { this.transformation = transformation }
4444
fun transformation(builder: TransformBuilder): TextDisplayBuilder = apply { this.transformation = builder.buildForTextDisplay() }
45-
fun brightness(brightness: Int): TextDisplayBuilder = apply { this.brightness = brightness }
45+
fun brightness(brightness: Brightness): TextDisplayBuilder = apply { this.brightness = brightness }
46+
fun brightness(brightness: Int): TextDisplayBuilder = brightness(Brightness(0, brightness))
4647
fun glow(glowColor: Color?): TextDisplayBuilder = apply { this.glowColor = glowColor }
4748
fun viewRange(viewRange: Float): TextDisplayBuilder = apply { this.viewRange = viewRange }
4849
fun billboard(billboard: Billboard?): TextDisplayBuilder = apply { this.billboard = billboard }
@@ -67,7 +68,7 @@ class TextDisplayBuilder() {
6768
display.setTransformationMatrix(transformation!!)
6869
}
6970
if (brightness != null) {
70-
display.brightness = Brightness(brightness!!, 0)
71+
display.brightness = brightness
7172
}
7273
if (glowColor != null) {
7374
display.isGlowing = true

pylon-core/src/main/kotlin/io/github/pylonmc/pylon/core/fluid/FluidConnectionPoint.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import java.util.*
1010
*
1111
* The FluidConnectionPoint class is created in memory for every loaded point. FluidConnectionPoints
1212
* are persisted when unloaded, but do not store the segment UUID - this is decided at runtime.
13-
*
14-
* The flow rate of a segment is the lowest maxFlowRate of any point in the segment.
1513
*/
1614
data class FluidConnectionPoint(
1715
val id: UUID,
@@ -25,6 +23,14 @@ data class FluidConnectionPoint(
2523
constructor(block: Block, name: String, type: Type)
2624
: this (UUID.randomUUID(), block.position, name, type, mutableSetOf())
2725

26+
override fun hashCode(): Int {
27+
return id.hashCode()
28+
}
29+
30+
override fun equals(other: Any?): Boolean {
31+
return other is FluidConnectionPoint && other.id == id
32+
}
33+
2834
enum class Type {
2935
INPUT, // input to the attached machine
3036
OUTPUT, // output from the attached machine

0 commit comments

Comments
 (0)