Deterministic dungeon containers
This commit is contained in:
parent
7857b8821e
commit
fc6938fc35
18
ADDITIONS.md
18
ADDITIONS.md
@ -1,7 +1,7 @@
|
||||
|
||||
# Modding changes
|
||||
# Modding and behavior changes
|
||||
|
||||
This document briefly documents what have been added (or removed) regarding modding capabilities
|
||||
This document briefly documents what have been added (or removed) regarding modding capabilities or engine behavior(s)
|
||||
|
||||
## JSON additions
|
||||
|
||||
@ -35,7 +35,6 @@ This document briefly documents what have been added (or removed) regarding modd
|
||||
* Original engine always generates two tree types when processing placeable items, new engine however, allows to generate any number of trees.
|
||||
|
||||
#### Dungeons
|
||||
* All brushes are now deterministic, and will produce _exact_ results given same seed (this fixes dungeons being generated differently on each machine despite players visiting exactly same coordinates in universe)
|
||||
* `front` and `back` brushes now can properly accept detailed data as json object on second position (e.g. `["front", { "material": ... }]`), with following structure (previously, due to oversight in code, it was impossible to specify this structure through any means, because brush definition itself can't be an object):
|
||||
```kotlin
|
||||
val material: Registry.Ref<TileDefinition> = BuiltinMetaMaterials.EMPTY.ref
|
||||
@ -101,4 +100,15 @@ val color: TileColor = TileColor.DEFAULT
|
||||
* Added `animator.sounds(): List<string>`
|
||||
* Added `animator.effects(): List<string>`
|
||||
* Added `animator.hasEffect(effect: string): boolean`
|
||||
* Added `animator.parts(): List<string>`
|
||||
* Added `animator.parts(): List<string>`
|
||||
|
||||
## Behavior
|
||||
|
||||
---------------
|
||||
|
||||
### Worldgen
|
||||
* Major dungeon placement on planets is now deterministic
|
||||
* Container item population in dungeons is now deterministic and is based on dungeon seed
|
||||
|
||||
#### Dungeons
|
||||
* All brushes are now deterministic
|
||||
|
@ -484,7 +484,7 @@ class DungeonWorld(val parent: ServerWorld, val random: RandomGenerator, val mar
|
||||
|
||||
val placedObjects = placedObjects.entries
|
||||
.map { (pos, data) ->
|
||||
WorldObject.create(data.prototype, pos, data.parameters) to data.direction
|
||||
WorldObject.create(data.prototype, pos, data.parameters).also { it?.randomize(random) } to data.direction
|
||||
}
|
||||
.filter { it.first != null }
|
||||
|
||||
|
@ -35,6 +35,7 @@ import ru.dbotthepony.kstarbound.world.World
|
||||
import ru.dbotthepony.kstarbound.world.entities.ItemDropEntity
|
||||
import java.io.DataInputStream
|
||||
import java.io.DataOutputStream
|
||||
import java.util.random.RandomGenerator
|
||||
|
||||
class ContainerObject(config: Registry.Entry<ObjectDefinition>) : WorldObject(config) {
|
||||
var opened by networkedSignedInt().also { networkGroup.upstream.add(it) }
|
||||
@ -109,6 +110,45 @@ class ContainerObject(config: Registry.Entry<ObjectDefinition>) : WorldObject(co
|
||||
return data
|
||||
}
|
||||
|
||||
private fun randomizeContents(random: RandomGenerator) {
|
||||
var level = world.template.threatLevel
|
||||
level = lookupProperty("level") { JsonPrimitive(level) }.asDouble
|
||||
level += lookupProperty("levelAdjustment") { JsonPrimitive(0.0) }.asDouble
|
||||
|
||||
val initialItems = lookupProperty("initialItems")
|
||||
|
||||
if (!initialItems.isJsonNull) {
|
||||
for (item in initialItems.asJsonArray) {
|
||||
items.add(ItemDescriptor(item).build(level, random.nextLong(), random))
|
||||
}
|
||||
}
|
||||
|
||||
val treasurePools = lookupProperty("treasurePools")
|
||||
|
||||
if (!treasurePools.isJsonNull) {
|
||||
val get = treasurePools.asJsonArray.random(random).asString
|
||||
val treasurePool = Registries.treasurePools[get]
|
||||
|
||||
if (treasurePool == null) {
|
||||
LOGGER.error("Unknown treasure pool $get! Can't generate container contents at $tilePosition.")
|
||||
} else {
|
||||
for (item in treasurePool.value.evaluate(random, level)) {
|
||||
val leftover = items.add(item)
|
||||
|
||||
if (leftover.isNotEmpty) {
|
||||
LOGGER.warn("Tried to overfill container at $tilePosition")
|
||||
lostItems.add(leftover)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun randomize(random: RandomGenerator) {
|
||||
super.randomize(random)
|
||||
randomizeContents(random)
|
||||
}
|
||||
|
||||
override fun onJoinWorld(world: World<*, *>) {
|
||||
if (!isRemote)
|
||||
isInteractive = true
|
||||
@ -119,38 +159,12 @@ class ContainerObject(config: Registry.Entry<ObjectDefinition>) : WorldObject(co
|
||||
if (isInitialized) return
|
||||
isInitialized = true
|
||||
|
||||
var level = world.template.threatLevel
|
||||
val seed = lookupProperty("treasureSeed") { JsonPrimitive(world.random.nextLong()) }.asLong
|
||||
level = lookupProperty("level") { JsonPrimitive(level) }.asDouble
|
||||
level += lookupProperty("levelAdjustment") { JsonPrimitive(0.0) }.asDouble
|
||||
val seed = lookupProperty("treasureSeed")
|
||||
|
||||
val initialItems = lookupProperty("initialItems")
|
||||
|
||||
if (!initialItems.isJsonNull) {
|
||||
for (item in initialItems.asJsonArray) {
|
||||
items.add(ItemDescriptor(item).build(level, seed))
|
||||
}
|
||||
}
|
||||
|
||||
val treasurePools = lookupProperty("treasurePools")
|
||||
|
||||
if (!treasurePools.isJsonNull) {
|
||||
val random = random(seed)
|
||||
val get = treasurePools.asJsonArray.random(random).asString
|
||||
val treasurePool = Registries.treasurePools[get]
|
||||
|
||||
if (treasurePool == null) {
|
||||
LOGGER.error("Unknown treasure pool $get! Can't generate container contents at $tilePosition.")
|
||||
} else {
|
||||
for (item in treasurePool.value.evaluate(random, level)) {
|
||||
val leftover = items.add(item)
|
||||
|
||||
if (leftover.isNotEmpty) {
|
||||
LOGGER.warn("Tried to overfill container at $tilePosition")
|
||||
lostItems.add(leftover)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (seed.isJsonNull) {
|
||||
randomizeContents(world.random)
|
||||
} else {
|
||||
randomizeContents(random(seed.asLong))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ import ru.dbotthepony.kstarbound.world.entities.Animator
|
||||
import ru.dbotthepony.kstarbound.world.entities.wire.WireConnection
|
||||
import java.io.DataOutputStream
|
||||
import java.util.HashMap
|
||||
import java.util.random.RandomGenerator
|
||||
|
||||
open class WorldObject(val config: Registry.Entry<ObjectDefinition>) : TileEntity() {
|
||||
open fun deserialize(data: JsonObject) {
|
||||
@ -134,6 +135,13 @@ open class WorldObject(val config: Registry.Entry<ObjectDefinition>) : TileEntit
|
||||
return into
|
||||
}
|
||||
|
||||
/**
|
||||
* called by DungeonWorld to deterministically randomize parameters
|
||||
*/
|
||||
open fun randomize(random: RandomGenerator) {
|
||||
|
||||
}
|
||||
|
||||
protected val orientationLazies = ArrayList<ManualLazy<*>>()
|
||||
protected val parametersLazies = ArrayList<ManualLazy<*>>()
|
||||
protected val spacesLazies = ArrayList<ManualLazy<*>>()
|
||||
|
Loading…
Reference in New Issue
Block a user