Delete old file
This commit is contained in:
parent
4870f6921a
commit
f65a247511
@ -1,539 +0,0 @@
|
||||
package ru.dbotthepony.kstarbound.defs
|
||||
|
||||
import com.google.common.collect.ImmutableList
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.TypeAdapter
|
||||
import com.google.gson.stream.JsonReader
|
||||
import com.google.gson.stream.JsonToken
|
||||
import com.google.gson.stream.JsonWriter
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.kstarbound.Starbound
|
||||
import ru.dbotthepony.kvector.AABB
|
||||
import ru.dbotthepony.kvector.AABBi
|
||||
import ru.dbotthepony.kstarbound.math.Poly
|
||||
import ru.dbotthepony.kstarbound.math.Vector2i
|
||||
import ru.dbotthepony.kstarbound.util.Color
|
||||
import java.util.*
|
||||
|
||||
class ProjectileEffectBuilder(
|
||||
var effect: String? = null,
|
||||
var duration: Double? = null
|
||||
) {
|
||||
fun build() = ProjectileEffect(effect = effect!!, duration = duration)
|
||||
}
|
||||
|
||||
object ProjectileEffectBuilderTypeAdapter : TypeAdapter<ProjectileEffectBuilder>() {
|
||||
override fun write(out: JsonWriter?, value: ProjectileEffectBuilder?) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun read(reader: JsonReader): ProjectileEffectBuilder {
|
||||
return when (val type = reader.peek()) {
|
||||
JsonToken.STRING -> ProjectileEffectBuilder(effect = reader.nextString())
|
||||
JsonToken.BEGIN_OBJECT -> {
|
||||
reader.beginObject()
|
||||
|
||||
val obj = ProjectileEffectBuilder()
|
||||
|
||||
while (reader.hasNext()) {
|
||||
when (val key = reader.nextName()) {
|
||||
"effect" -> obj.effect = reader.nextString()
|
||||
"duration" -> obj.duration = reader.nextDouble()
|
||||
else -> throw IllegalArgumentException("Unknown projectile effect key $key")
|
||||
}
|
||||
}
|
||||
|
||||
reader.endObject()
|
||||
|
||||
checkNotNull(obj.effect) { "Effect is null" }
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
else -> throw IllegalArgumentException("Unknown projectile effect token $type")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectileDamageTeamBuilder {
|
||||
var type: String? = null
|
||||
|
||||
fun build() = ProjectileDamageTeam(type = type!!)
|
||||
}
|
||||
|
||||
class ProjectileActionOnReapTileBuilder {
|
||||
var quantity: Int? = null
|
||||
var kind: String? = null
|
||||
|
||||
fun build() = ProjectileActionOnReapTileMaterial(kind = kind!!, quantity = quantity ?: 1)
|
||||
}
|
||||
|
||||
class ProjectileActionOnReapBuilder {
|
||||
val action: String? = null
|
||||
var inheritDamageFactor: Double? = null
|
||||
var inheritSpeedFactor: Double? = null
|
||||
var angleAdjust: Double? = null
|
||||
var fuzzAngle: Double? = null
|
||||
var type: String? = null
|
||||
var direction: Vector2i? = null
|
||||
var offset: Vector2i? = null
|
||||
var config: ProjectileConfigBuilder? = null
|
||||
var file: String? = null
|
||||
|
||||
var options: Array<JsonElement>? = null
|
||||
var list: Array<ProjectileActionOnReapBuilder>? = null
|
||||
var body: Array<ProjectileActionOnReapBuilder>? = null
|
||||
var count: Int? = null
|
||||
|
||||
var color: Color? = null
|
||||
var materials: Array<JsonElement>? = null
|
||||
|
||||
val foregroundRadius: Double? = null
|
||||
val backgroundRadius: Double? = null
|
||||
val explosiveDamageAmount: Double? = null
|
||||
val delaySteps: Int? = null
|
||||
|
||||
var liquid: String? = null
|
||||
var quantity: Double? = null
|
||||
|
||||
var previousMod: String? = null
|
||||
var newMod: String? = null
|
||||
var radius: Double? = null
|
||||
|
||||
fun build(directory: String = ""): ProjectileActionOnReap {
|
||||
return when (val action = checkNotNull(action) { "actionOnReap.action is null" }) {
|
||||
"projectile" -> ProjectileActionOnReapProjectile(
|
||||
inheritDamageFactor = inheritDamageFactor,
|
||||
inheritSpeedFactor = inheritSpeedFactor,
|
||||
type = checkNotNull(type) { "actionOnReap.projectile.type is null" }.intern(),
|
||||
direction = direction,
|
||||
config = config?.buildConfig() ?: ProjectileConfig.EMPTY,
|
||||
angleAdjust = angleAdjust,
|
||||
fuzzAngle = fuzzAngle,
|
||||
)
|
||||
|
||||
"config" -> ProjectileActionOnReapConfig(
|
||||
file = ensureAbsolutePath(checkNotNull(file) { "actionOnReap.config.file is null" }, directory).also {
|
||||
require(Starbound.pathExists(it)) { "$it does not exist" }
|
||||
}
|
||||
)
|
||||
|
||||
"option" -> ProjectileActionOnReapOption(
|
||||
options = ImmutableList.copyOf(checkNotNull(options) { "actionOnReap.option.options is null" }.map { Starbound.gson.fromJson(it, ProjectileActionOnReapBuilder::class.java).build(directory) })
|
||||
)
|
||||
|
||||
"actions" -> ProjectileActionOnReapActions(
|
||||
actions = ImmutableList.copyOf(checkNotNull(list) { "actionOnReap.action.list is null" }.map { it.build(directory) })
|
||||
)
|
||||
|
||||
"sound" -> ProjectileActionOnReapSound(
|
||||
options = ImmutableList.copyOf(checkNotNull(options) { "actionOnReap.sound.options is null" }
|
||||
.map { ensureAbsolutePath((it as? JsonPrimitive)?.let { it.asString } ?: throw IllegalArgumentException("$it is not a valid sound"), directory) }
|
||||
.also {
|
||||
for (sound in it) {
|
||||
require(Starbound.pathExists(sound)) { "$it does not exist" }
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
"spawnmonster" -> ProjectileActionOnReapSpawn(
|
||||
type = checkNotNull(type) { "actionOnReap.spawnmonster.type is null" }.intern(),
|
||||
offset = offset ?: Vector2i.ZERO,
|
||||
)
|
||||
|
||||
"light" -> ProjectileActionOnReapLight(
|
||||
color = checkNotNull(color) { "actionOnReap.light.color is null" }
|
||||
)
|
||||
|
||||
"particle" -> ProjectileOnReapNothing // TODO: партикли
|
||||
|
||||
"loop" -> ProjectileActionOnReapLoop(
|
||||
body = ImmutableList.copyOf(checkNotNull(body) { "actionOnReap.loop.body is null" }.map { it.build(directory) }),
|
||||
count = checkNotNull(count) { "actionOnReap.loop.count is null" }
|
||||
)
|
||||
|
||||
"tile" -> ProjectileActionOnReapTile(
|
||||
materials = ImmutableList.copyOf(checkNotNull(materials) { "actionOnReap.tile.materials is null" }
|
||||
.map { Starbound.gson.fromJson(it, ProjectileActionOnReapTileBuilder::class.java).build() })
|
||||
)
|
||||
|
||||
"explosion" -> ProjectileActionOnReapExplosion(
|
||||
foregroundRadius = checkNotNull(foregroundRadius) { "actionOnReap.explosion.foregroundRadius is null" },
|
||||
backgroundRadius = checkNotNull(backgroundRadius) { "actionOnReap.explosion.backgroundRadius is null" },
|
||||
explosiveDamageAmount = checkNotNull(explosiveDamageAmount) { "actionOnReap.explosion.explosiveDamageAmount is null" },
|
||||
delaySteps = checkNotNull(delaySteps) { "actionOnReap.explosion.delaySteps is null" },
|
||||
)
|
||||
|
||||
"liquid" -> ProjectileActionOnReapLiquid(
|
||||
liquid = checkNotNull(liquid) { "actionOnReap.liquid.liquid is null" },
|
||||
quantity = checkNotNull(quantity) { "actionOnReap.liquid.quantity is null" },
|
||||
)
|
||||
|
||||
"applySurfaceMod" -> ProjectileActionOnReapApplySurfaceMod(
|
||||
previousMod = previousMod,
|
||||
newMod = newMod,
|
||||
radius = checkNotNull(radius) { "actionOnReap.applySurfaceMod.radius is null" },
|
||||
)
|
||||
|
||||
else -> throw IllegalArgumentException("Unknown actionOnReap action type: $action")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface ProjectileActionOnReap {
|
||||
val action: String
|
||||
}
|
||||
|
||||
object ProjectileOnReapNothing : ProjectileActionOnReap {
|
||||
override val action = "nothing"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapProjectile(
|
||||
val inheritDamageFactor: Double?,
|
||||
val inheritSpeedFactor: Double?,
|
||||
|
||||
val angleAdjust: Double?,
|
||||
val fuzzAngle: Double?,
|
||||
val direction: Vector2i?,
|
||||
|
||||
val type: String,
|
||||
val config: ProjectileConfig,
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "projectile"
|
||||
|
||||
init {
|
||||
// require(direction != null || angleAdjust != null && fuzzAngle != null) { "Projectile reap should have either angleAdjust && fuzzAngle or direction, not none" }
|
||||
require(!(direction != null && (angleAdjust != null || fuzzAngle != null))) { "Projectile reap has direction ($direction), but also has angleAdjust ($angleAdjust) or fuzzAngle ($fuzzAngle). It should have direction, or the latter" }
|
||||
}
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapConfig(
|
||||
val file: String,
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "config"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapOption(
|
||||
val options: List<ProjectileActionOnReap>,
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "option"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapLoop(
|
||||
val body: List<ProjectileActionOnReap>,
|
||||
val count: Int,
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "loop"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapTileMaterial(
|
||||
val quantity: Int,
|
||||
val kind: String,
|
||||
)
|
||||
|
||||
data class ProjectileActionOnReapTile(
|
||||
val materials: List<ProjectileActionOnReapTileMaterial>,
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "tile"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapLiquid(
|
||||
val liquid: String,
|
||||
val quantity: Double,
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "liquid"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapSound(
|
||||
val options: List<String>,
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "sound"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapSpawn(
|
||||
val type: String,
|
||||
val offset: Vector2i
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "spawnmonster"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapLight(
|
||||
val color: Color
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "light"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapActions(
|
||||
val actions: List<ProjectileActionOnReap>,
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "action"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapApplySurfaceMod(
|
||||
val previousMod: String?,
|
||||
val newMod: String?,
|
||||
val radius: Double,
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "applySurfaceMod"
|
||||
}
|
||||
|
||||
data class ProjectileActionOnReapExplosion(
|
||||
val foregroundRadius: Double,
|
||||
val backgroundRadius: Double,
|
||||
val explosiveDamageAmount: Double,
|
||||
val delaySteps: Int,
|
||||
) : ProjectileActionOnReap {
|
||||
override val action = "explosion"
|
||||
}
|
||||
|
||||
class ProjectileMovementSettingsBuilder {
|
||||
var gravityMultiplier: Double? = null
|
||||
var collisionPoly: Array<AABB>? = null
|
||||
|
||||
fun build(): ProjectileMovementSettings {
|
||||
return ProjectileMovementSettings(
|
||||
gravityMultiplier = gravityMultiplier ?: 1.0,
|
||||
collisionPoly = collisionPoly?.let { ImmutableList.copyOf(it) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class ProjectileMovementSettings(
|
||||
val gravityMultiplier: Double,
|
||||
val collisionPoly: List<AABB>?
|
||||
)
|
||||
|
||||
interface IProjectileConfig {
|
||||
val power: Double?
|
||||
val speed: Double?
|
||||
val timeToLive: Double?
|
||||
val bounces: Int?
|
||||
|
||||
val damageType: String?
|
||||
val damageKind: String?
|
||||
val damageTeam: ProjectileDamageTeam?
|
||||
|
||||
val hydrophobic: Boolean?
|
||||
val pointLight: Boolean?
|
||||
val orientationLocked: Boolean?
|
||||
}
|
||||
|
||||
/**
|
||||
* Projectile Config указывает те поля, которые можно изменить
|
||||
*/
|
||||
open class ProjectileConfigBuilder : ConfigurableDefinition() {
|
||||
var power: Double = 0.0
|
||||
var speed: Double = 0.0
|
||||
var timeToLive: Double = Double.POSITIVE_INFINITY
|
||||
var bounces: Int = -1
|
||||
|
||||
var damageType: String? = null
|
||||
var damageKind: String? = null
|
||||
var damageTeam: ProjectileDamageTeamBuilder? = null
|
||||
|
||||
var hydrophobic: Boolean = false
|
||||
var pointLight: Boolean = false
|
||||
var orientationLocked: Boolean = false
|
||||
|
||||
fun buildConfig(): ProjectileConfig {
|
||||
return ProjectileConfig(
|
||||
power = power,
|
||||
speed = speed,
|
||||
timeToLive = timeToLive,
|
||||
bounces = bounces,
|
||||
damageType = damageType,
|
||||
damageKind = damageKind,
|
||||
damageTeam = damageTeam?.build(),
|
||||
hydrophobic = hydrophobic,
|
||||
pointLight = pointLight,
|
||||
orientationLocked = orientationLocked,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectileConfig(
|
||||
json: Map<String, Any>,
|
||||
override val power: Double,
|
||||
override val speed: Double,
|
||||
override val timeToLive: Double,
|
||||
override val bounces: Int,
|
||||
override val damageType: String?,
|
||||
override val damageKind: String?,
|
||||
override val damageTeam: ProjectileDamageTeam?,
|
||||
override val hydrophobic: Boolean,
|
||||
override val pointLight: Boolean,
|
||||
override val orientationLocked: Boolean,
|
||||
) : ConfiguredDefinition(), IProjectileConfig {
|
||||
fun proxy(other: IProjectileConfig) = ProjectileConfigProxy(this, other)
|
||||
|
||||
companion object {
|
||||
val EMPTY = ProjectileConfigBuilder().buildConfig()
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectileConfigProxy(original: IProjectileConfig, private val proxied: IProjectileConfig) : IProjectileConfig {
|
||||
override val power: Double? = original.power
|
||||
get() = field ?: proxied.power
|
||||
override val speed: Double? = original.speed
|
||||
get() = field ?: proxied.speed
|
||||
override val timeToLive: Double? = original.timeToLive
|
||||
get() = field ?: proxied.timeToLive
|
||||
override val bounces: Int? = original.bounces
|
||||
get() = field ?: proxied.bounces
|
||||
override val damageType: String? = original.damageType
|
||||
get() = field ?: proxied.damageType
|
||||
override val damageKind: String? = original.damageKind
|
||||
get() = field ?: proxied.damageKind
|
||||
override val damageTeam: ProjectileDamageTeam? = original.damageTeam
|
||||
get() = field ?: proxied.damageTeam
|
||||
override val hydrophobic: Boolean? = original.hydrophobic
|
||||
get() = field ?: proxied.hydrophobic
|
||||
override val pointLight: Boolean? = original.pointLight
|
||||
get() = field ?: proxied.pointLight
|
||||
override val orientationLocked: Boolean? = original.orientationLocked
|
||||
get() = field ?: proxied.orientationLocked
|
||||
}
|
||||
|
||||
class ProjectileDefinitionBuilder : ProjectileConfigBuilder() {
|
||||
var projectileName: String? = null
|
||||
var image: String = "/assetmissing.png"
|
||||
var physics = ProjectilePhysics.DEFAULT
|
||||
var animationCycle: Double = Double.POSITIVE_INFINITY
|
||||
var animationLoops: Boolean = false
|
||||
|
||||
var frameNumber: Int = 1
|
||||
var damagePoly: Poly? = null
|
||||
var lightColor: Color? = null
|
||||
var statusEffects: Array<ProjectileEffectBuilder>? = null
|
||||
var piercing: Boolean? = null
|
||||
|
||||
var damageKindImage: String? = null
|
||||
var movementSettings: ProjectileMovementSettingsBuilder? = null
|
||||
|
||||
var actionOnReap: Array<ProjectileActionOnReapBuilder>? = null
|
||||
var emitters: Array<String>? = null
|
||||
var intangibleWindup: Boolean? = null
|
||||
var windupFrames: Int? = null
|
||||
var winddownFrames: Int? = null
|
||||
var renderLayer: String? = null
|
||||
var acceleration: Double? = null
|
||||
var supportsProcessing: Boolean? = null
|
||||
var initialVelocity: Double? = null
|
||||
|
||||
var scripts: Array<String>? = null
|
||||
var onlyHitTerrain: Int? = null
|
||||
|
||||
// TODO: Прожекталы могут иметь абсолютно случайные данные, которые нужны скриптам
|
||||
// то же самое касается и npc
|
||||
// и объектов
|
||||
// такие как chainProjectile для /scripts/projectiles/chainbullet.lua
|
||||
|
||||
fun build(directory: String = ""): ProjectileDefinition {
|
||||
return ProjectileDefinition(
|
||||
projectileName = requireNotNull(projectileName) { "projectileName is null" },
|
||||
image = IFrameGrid.loadFrameStrip(ensureAbsolutePath(requireNotNull(image) { "image is null" }, directory), weak = true),
|
||||
physics = physics ?: ProjectilePhysics.DEFAULT,
|
||||
animationCycle = animationCycle ?: Double.POSITIVE_INFINITY,
|
||||
animationLoops = animationLoops ?: false,
|
||||
frameNumber = frameNumber ?: 1,
|
||||
power = power ?: -1.0,
|
||||
speed = speed ?: 0.0,
|
||||
timeToLive = timeToLive ?: Double.POSITIVE_INFINITY,
|
||||
bounces = bounces ?: 0,
|
||||
damagePoly = damagePoly,
|
||||
statusEffects = statusEffects?.map { it.build() }?.let { Collections.unmodifiableList(it) } ?: listOf(),
|
||||
piercing = piercing ?: false,
|
||||
damageType = damageType,
|
||||
damageKind = damageKind,
|
||||
damageTeam = damageTeam?.build(),
|
||||
|
||||
lightColor = lightColor,
|
||||
|
||||
damageKindImage = damageKindImage?.let { ensureAbsolutePath(it, directory) },
|
||||
hydrophobic = hydrophobic ?: false,
|
||||
pointLight = pointLight ?: false,
|
||||
orientationLocked = orientationLocked ?: false,
|
||||
|
||||
actionOnReap = actionOnReap?.map { it.build(directory) }?.let { Collections.unmodifiableList(it) } ?: listOf(),
|
||||
emitters = emitters?.toList()?.let { Collections.unmodifiableList(it) } ?: listOf(),
|
||||
|
||||
intangibleWindup = intangibleWindup ?: false,
|
||||
windupFrames = windupFrames ?: -1,
|
||||
winddownFrames = winddownFrames ?: -1,
|
||||
renderLayer = renderLayer,
|
||||
acceleration = acceleration ?: 0.0,
|
||||
|
||||
supportsProcessing = supportsProcessing ?: false,
|
||||
initialVelocity = initialVelocity ?: 0.0,
|
||||
scripts = scripts?.map { ensureAbsolutePath(it, directory) }?.let { ImmutableList.copyOf(it) } ?: listOf(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class ProjectileEffect(
|
||||
val effect: String,
|
||||
val duration: Double?, // Если null, то стандартное время эффекта
|
||||
)
|
||||
|
||||
data class ProjectileDamageTeam(
|
||||
val type: String
|
||||
)
|
||||
|
||||
class ProjectileDefinition(
|
||||
json: Map<String, Any>,
|
||||
val projectileName: String,
|
||||
val image: FrameGridStrip,
|
||||
val damageKindImage: String?,
|
||||
val physics: ProjectilePhysics,
|
||||
val animationCycle: Double,
|
||||
val animationLoops: Boolean,
|
||||
val frameNumber: Int,
|
||||
|
||||
override val power: Double,
|
||||
override val speed: Double,
|
||||
override val timeToLive: Double,
|
||||
override val bounces: Int,
|
||||
|
||||
val damagePoly: Poly?,
|
||||
val statusEffects: List<ProjectileEffect>,
|
||||
val piercing: Boolean,
|
||||
|
||||
override val damageType: String?,
|
||||
override val damageKind: String?,
|
||||
override val damageTeam: ProjectileDamageTeam?,
|
||||
|
||||
val lightColor: Color?,
|
||||
|
||||
override val hydrophobic: Boolean,
|
||||
override val pointLight: Boolean,
|
||||
override val orientationLocked: Boolean,
|
||||
|
||||
val actionOnReap: List<ProjectileActionOnReap>,
|
||||
val emitters: List<String>,
|
||||
|
||||
val intangibleWindup: Boolean,
|
||||
val windupFrames: Int,
|
||||
val winddownFrames: Int,
|
||||
|
||||
val renderLayer: String?,
|
||||
val acceleration: Double,
|
||||
val supportsProcessing: Boolean,
|
||||
val initialVelocity: Double,
|
||||
|
||||
val scripts: List<String>,
|
||||
) : ConfiguredDefinition(json), IProjectileConfig {
|
||||
init {
|
||||
// require(frameNumber <= image.frameCount) { "Frame number ($frameNumber) exceeds amount of frames in animated image strip (${image.frameCount})" }
|
||||
|
||||
if (frameNumber != image.frameCount) {
|
||||
LOGGER.warn("{} has lesser frameNumber {} than defined in frame strip {}", projectileName, frameNumber, image.frameCount)
|
||||
}
|
||||
}
|
||||
|
||||
val unlimitedBounces get() = bounces <= -1
|
||||
|
||||
companion object {
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user