KStarbound/src/main/kotlin/ru/dbotthepony/kstarbound/lua/bindings/MonsterBindings.kt

187 lines
5.7 KiB
Kotlin

package ru.dbotthepony.kstarbound.lua.bindings
import com.google.common.collect.ImmutableSet
import org.classdump.luna.ByteString
import org.classdump.luna.Table
import ru.dbotthepony.kommons.collect.collect
import ru.dbotthepony.kommons.collect.map
import ru.dbotthepony.kstarbound.Starbound
import ru.dbotthepony.kstarbound.defs.DamageSource
import ru.dbotthepony.kstarbound.defs.EntityDamageTeam
import ru.dbotthepony.kstarbound.defs.PhysicsForceRegion
import ru.dbotthepony.kstarbound.fromJsonFast
import ru.dbotthepony.kstarbound.lua.LuaEnvironment
import ru.dbotthepony.kstarbound.lua.from
import ru.dbotthepony.kstarbound.lua.get
import ru.dbotthepony.kstarbound.lua.iterator
import ru.dbotthepony.kstarbound.lua.luaFunction
import ru.dbotthepony.kstarbound.lua.set
import ru.dbotthepony.kstarbound.lua.stream
import ru.dbotthepony.kstarbound.lua.toJson
import ru.dbotthepony.kstarbound.lua.toJsonFromLua
import ru.dbotthepony.kstarbound.lua.toVector2d
import ru.dbotthepony.kstarbound.util.SBPattern
import ru.dbotthepony.kstarbound.util.sbIntern
import ru.dbotthepony.kstarbound.util.valueOf
import ru.dbotthepony.kstarbound.world.entities.ActorEntity
import ru.dbotthepony.kstarbound.world.entities.MonsterEntity
fun provideMonsterBindings(self: MonsterEntity, lua: LuaEnvironment) {
val callbacks = lua.newTable()
lua.globals["monster"] = callbacks
callbacks["type"] = luaFunction {
returnBuffer.setTo(self.variant.type)
}
callbacks["seed"] = luaFunction {
// what the fuck.
returnBuffer.setTo(self.variant.seed.toString())
}
callbacks["seedNumber"] = luaFunction {
returnBuffer.setTo(self.variant.seed)
}
callbacks["uniqueParameters"] = luaFunction {
returnBuffer.setTo(from(self.variant.uniqueParameters))
}
callbacks["level"] = luaFunction {
// TODO: this makes half sense
returnBuffer.setTo(self.monsterLevel ?: 0.0)
}
callbacks["setDamageOnTouch"] = luaFunction { damage: Boolean ->
self.damageOnTouch = damage
}
callbacks["setDamageSources"] = luaFunction { sources: Table? ->
self.customDamageSources.clear()
if (sources != null) {
for ((_, v) in sources) {
self.customDamageSources.add(Starbound.gson.fromJson((v as Table).toJson(), DamageSource::class.java))
}
}
}
callbacks["setDamageParts"] = luaFunction { parts: Table? ->
if (parts == null) {
self.animationDamageParts.clear()
} else {
val strings = parts.stream().map { (_, v) -> v.toString() }.collect(ImmutableSet.toImmutableSet())
self.animationDamageParts.removeIf { it !in strings }
for (v in strings) {
if (v !in self.animationDamageParts) {
self.animationDamageParts.add(v)
}
}
}
}
callbacks["setAggressive"] = luaFunction { isAggressive: Boolean ->
self.isAggressive = isAggressive
}
callbacks["setActiveSkillName"] = luaFunction { name: ByteString ->
self.activeSkillName = name.decode().sbIntern()
}
callbacks["setDropPool"] = luaFunction { pool: Any ->
self.dropPool = Starbound.gson.fromJsonFast(toJsonFromLua(pool))
}
callbacks["toAbsolutePosition"] = luaFunction { position: Table ->
returnBuffer.setTo(from(self.movement.getAbsolutePosition(toVector2d(position))))
}
callbacks["mouthPosition"] = luaFunction {
returnBuffer.setTo(from(self.mouthPosition))
}
// This callback is registered here rather than in
// makeActorMovementControllerCallbacks
// because it requires access to world
callbacks["flyTo"] = luaFunction { position: Table ->
self.movement.controlFly = self.world.geometry.diff(toVector2d(position), self.movement.position)
}
callbacks["setDeathParticleBurst"] = luaFunction { value: ByteString? ->
self.deathParticlesBurst = value?.decode()?.sbIntern() ?: ""
}
callbacks["setDeathSound"] = luaFunction { value: ByteString? ->
self.deathSound = value?.decode()?.sbIntern() ?: ""
}
callbacks["setPhysicsForces"] = luaFunction { forces: Table? ->
if (forces == null) {
self.forceRegions.clear()
} else {
self.forceRegions.clear()
for ((_, v) in forces) {
self.forceRegions.add(Starbound.gson.fromJsonFast(toJsonFromLua(v), PhysicsForceRegion::class.java))
}
}
}
callbacks["setName"] = luaFunction { name: ByteString? ->
self.networkName = name?.decode()
}
callbacks["setDisplayNametag"] = luaFunction { shouldDisplay: Boolean ->
self.displayNameTag = shouldDisplay
}
callbacks["say"] = luaFunction { line: ByteString, tags: Table? ->
var actualLine = line.decode()
if (tags != null) {
actualLine = SBPattern.of(actualLine).resolveOrSkip({ tags[it]?.toString() })
}
if (actualLine.isNotBlank()) {
self.addChatMessage(actualLine.sbIntern())
}
returnBuffer.setTo(actualLine.isNotBlank())
}
callbacks["sayPortrait"] = luaFunction { line: ByteString, portrait: ByteString, tags: Table? ->
var actualLine = line.decode()
if (tags != null) {
actualLine = SBPattern.of(actualLine).resolveOrSkip({ tags[it]?.toString() })
}
if (actualLine.isNotBlank()) {
self.addChatMessage(actualLine.sbIntern(), portrait.decode().sbIntern())
}
returnBuffer.setTo(actualLine.isNotBlank())
}
callbacks["setDamageTeam"] = luaFunction { team: Any ->
self.team.accept(Starbound.gson.fromJsonFast(toJsonFromLua(team), EntityDamageTeam::class.java))
}
callbacks["setUniqueId"] = luaFunction { name: ByteString? ->
self.uniqueID.accept(name?.decode()?.sbIntern())
}
callbacks["setDamageBar"] = luaFunction { type: ByteString ->
self.damageBarType = ActorEntity.DamageBarType.entries.valueOf(type.decode())
}
callbacks["setInteractive"] = luaFunction { isInteractive: Boolean ->
self.isInteractive = isInteractive
}
callbacks["setAnimationParameter"] = luaFunction { name: ByteString, value: Any? ->
self.scriptedAnimationParameters[name.decode().sbIntern()] = toJsonFromLua(value)
}
}