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) } }