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